rum 0.0.1-universal-darwin-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +3 -0
 - data/README +30 -0
 - data/Rakefile +134 -0
 - data/bin/rum-client +124 -0
 - data/doc/basic.rb +10 -0
 - data/doc/doc.html +602 -0
 - data/doc/example.rb +59 -0
 - data/doc/reference.rb +415 -0
 - data/doc/resources/bg.png +0 -0
 - data/doc/resources/bottom.png +0 -0
 - data/doc/resources/build.rb +235 -0
 - data/doc/resources/doc.haml +167 -0
 - data/doc/resources/emacs-auto-completion.png +0 -0
 - data/doc/resources/flash.png +0 -0
 - data/doc/resources/highlight.css +94 -0
 - data/doc/resources/intro.rb +17 -0
 - data/doc/resources/left.png +0 -0
 - data/doc/resources/logo.png +0 -0
 - data/doc/resources/screen.css +420 -0
 - data/doc/resources/screenshot.png +0 -0
 - data/doc/resources/top.png +0 -0
 - data/ext/mac/keyboard_hook/English.lproj/InfoPlist.strings +0 -0
 - data/ext/mac/keyboard_hook/Event.h +17 -0
 - data/ext/mac/keyboard_hook/Event.m +18 -0
 - data/ext/mac/keyboard_hook/EventTap.h +11 -0
 - data/ext/mac/keyboard_hook/EventTap.m +77 -0
 - data/ext/mac/keyboard_hook/Info.plist +26 -0
 - data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/TemplateIcon.icns +0 -0
 - data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/project.pbxproj +323 -0
 - data/ext/mac/keyboard_hook/KeyboardHook_Prefix.pch +7 -0
 - data/ext/mac/keyboard_hook/version.plist +16 -0
 - data/ext/windows/keyboard_hook/extconf.rb +2 -0
 - data/ext/windows/keyboard_hook/keyboard_hook.c +126 -0
 - data/ext/windows/system/autohotkey_stuff.c +255 -0
 - data/ext/windows/system/autohotkey_stuff.h +2 -0
 - data/ext/windows/system/clipboard_watcher.c +58 -0
 - data/ext/windows/system/clipboard_watcher.h +2 -0
 - data/ext/windows/system/extconf.rb +3 -0
 - data/ext/windows/system/input_box.c +239 -0
 - data/ext/windows/system/input_box.h +4 -0
 - data/ext/windows/system/system.c +273 -0
 - data/lib/rum.rb +4 -0
 - data/lib/rum/apps.rb +4 -0
 - data/lib/rum/barrel.rb +157 -0
 - data/lib/rum/barrel/emacs.rb +44 -0
 - data/lib/rum/barrel/emacs_client.rb +74 -0
 - data/lib/rum/core.rb +125 -0
 - data/lib/rum/dsl.rb +109 -0
 - data/lib/rum/gui.rb +93 -0
 - data/lib/rum/help.rb +128 -0
 - data/lib/rum/hotkey_core.rb +479 -0
 - data/lib/rum/mac.rb +18 -0
 - data/lib/rum/mac/app.rb +4 -0
 - data/lib/rum/mac/apps.rb +19 -0
 - data/lib/rum/mac/gui.rb +26 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Info.plist +28 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/MacOS/CocoaDialog +0 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Info.plist +28 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/InfoPlist.strings +0 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/classes.nib +51 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/info.nib +16 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/keyedobjects.nib +0 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/classes.nib +7 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/info.nib +21 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/info.nib.orig +21 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/objects.nib +0 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/objects.nib.orig +0 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/classes.nib +27 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/info.nib +16 -0
 - data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/keyedobjects.nib +0 -0
 - data/lib/rum/mac/gui/Growl.framework/Growl +0 -0
 - data/lib/rum/mac/gui/Growl.framework/Versions/A/Growl +0 -0
 - data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/Growl.h +6 -0
 - data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h +780 -0
 - data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h +575 -0
 - data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlDefines.h +348 -0
 - data/lib/rum/mac/gui/Growl.framework/Versions/A/Resources/Info.plist +24 -0
 - data/lib/rum/mac/gui/growl.rb +54 -0
 - data/lib/rum/mac/irb/completion.rb +207 -0
 - data/lib/rum/mac/keyboard_hook.rb +73 -0
 - data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/KeyboardHook +0 -0
 - data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/KeyboardHook +0 -0
 - data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/English.lproj/InfoPlist.strings +0 -0
 - data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/Info.plist +22 -0
 - data/lib/rum/mac/layouts.rb +146 -0
 - data/lib/rum/mac/system.rb +45 -0
 - data/lib/rum/remote.rb +48 -0
 - data/lib/rum/server.rb +92 -0
 - data/lib/rum/windows.rb +23 -0
 - data/lib/rum/windows/app.rb +72 -0
 - data/lib/rum/windows/apps.rb +25 -0
 - data/lib/rum/windows/gui.rb +116 -0
 - data/lib/rum/windows/keyboard.rb +80 -0
 - data/lib/rum/windows/keyboard_hook.rb +20 -0
 - data/lib/rum/windows/layouts.rb +232 -0
 - data/lib/rum/windows/system.rb +310 -0
 - data/lib/rum/windows/system_foreign_functions.rb +129 -0
 - data/rum.gemspec +14 -0
 - metadata +166 -0
 
    
        data/lib/rum.rb
    ADDED
    
    
    
        data/lib/rum/apps.rb
    ADDED
    
    
    
        data/lib/rum/barrel.rb
    ADDED
    
    | 
         @@ -0,0 +1,157 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Rum
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Path
         
     | 
| 
      
 5 
     | 
    
         
            +
                def self.contents dir
         
     | 
| 
      
 6 
     | 
    
         
            +
                  paths = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                  dir = File.join(dir, '')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  dir_dots = /(?:^|\/)\.\.?$/ # /.. or /.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  Dir.glob(dir + '**/*', File::FNM_DOTMATCH).each do |path|
         
     | 
| 
      
 10 
     | 
    
         
            +
                    sub_path = path[(dir.length)..-1].encode(Encoding::UTF_8, \
         
     | 
| 
      
 11 
     | 
    
         
            +
                                                             Encoding::ISO_8859_1)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    paths << sub_path unless sub_path =~ dir_dots
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  paths
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                
         
     | 
| 
      
 17 
     | 
    
         
            +
                def self.select dir
         
     | 
| 
      
 18 
     | 
    
         
            +
                  path = Gui.choose(nil, contents(dir))
         
     | 
| 
      
 19 
     | 
    
         
            +
                  (File.join(dir, path)) if path
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
                
         
     | 
| 
      
 22 
     | 
    
         
            +
                def self.run path
         
     | 
| 
      
 23 
     | 
    
         
            +
                  start path
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def self.select_and_run dir
         
     | 
| 
      
 27 
     | 
    
         
            +
                  path = select(dir)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  run path if path
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def self.sanitize path
         
     | 
| 
      
 32 
     | 
    
         
            +
                  path.gsub(/[\/\\|?*><":]/, '-')
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def self.normalize path
         
     | 
| 
      
 36 
     | 
    
         
            +
                  path.gsub('\\', '/')
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
              
         
     | 
| 
      
 40 
     | 
    
         
            +
              module AppDir
         
     | 
| 
      
 41 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 42 
     | 
    
         
            +
                  attr_accessor :base_dir
         
     | 
| 
      
 43 
     | 
    
         
            +
                  
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def get(exe)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    File.join(@base_dir, exe, '')
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  
         
     | 
| 
      
 48 
     | 
    
         
            +
                  def get_or_create(exe)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    dir = get(exe)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    if File.exists? dir
         
     | 
| 
      
 51 
     | 
    
         
            +
                      dir
         
     | 
| 
      
 52 
     | 
    
         
            +
                    else
         
     | 
| 
      
 53 
     | 
    
         
            +
                      prompt = "App-Dir für #{exe.capitalize} anlegen?"
         
     | 
| 
      
 54 
     | 
    
         
            +
                      if "Erzeugen" == Gui.choose(prompt, ["Erzeugen", "Nicht erzeugen"])
         
     | 
| 
      
 55 
     | 
    
         
            +
                        Dir.mkdir dir
         
     | 
| 
      
 56 
     | 
    
         
            +
                        dir
         
     | 
| 
      
 57 
     | 
    
         
            +
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def current
         
     | 
| 
      
 62 
     | 
    
         
            +
                    get_or_create(active_window.exe_name)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def visit
         
     | 
| 
      
 66 
     | 
    
         
            +
                    dir = current
         
     | 
| 
      
 67 
     | 
    
         
            +
                    Dopus.go dir if dir
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def select
         
     | 
| 
      
 71 
     | 
    
         
            +
                    dir = current
         
     | 
| 
      
 72 
     | 
    
         
            +
                    Path.select_and_run dir if dir
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 78 
     | 
    
         
            +
                class Command
         
     | 
| 
      
 79 
     | 
    
         
            +
                  def initialize(name, proc)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 81 
     | 
    
         
            +
                    @proc = proc
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 85 
     | 
    
         
            +
                    @name
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 89 
     | 
    
         
            +
                    @proc.call
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
                
         
     | 
| 
      
 93 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 94 
     | 
    
         
            +
                  attr_accessor :default_tag
         
     | 
| 
      
 95 
     | 
    
         
            +
                  attr_accessor :commands
         
     | 
| 
      
 96 
     | 
    
         
            +
                  Commands.commands = {}
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                  def command(name, *args, &block)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    args = args.first
         
     | 
| 
      
 100 
     | 
    
         
            +
                    tag = args[:tag] if args
         
     | 
| 
      
 101 
     | 
    
         
            +
                    tags = []
         
     | 
| 
      
 102 
     | 
    
         
            +
                    tags << tag if tag
         
     | 
| 
      
 103 
     | 
    
         
            +
                    tags << default_tag
         
     | 
| 
      
 104 
     | 
    
         
            +
                    tags.uniq!
         
     | 
| 
      
 105 
     | 
    
         
            +
                    
         
     | 
| 
      
 106 
     | 
    
         
            +
                    if args and (hotkey = args[:hotkey])
         
     | 
| 
      
 107 
     | 
    
         
            +
                      apps = tags.select { |tag| tag.is_a? App }
         
     | 
| 
      
 108 
     | 
    
         
            +
                      apps.each { |app| hotkey.do(app, &block) }
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 110 
     | 
    
         
            +
                    
         
     | 
| 
      
 111 
     | 
    
         
            +
                    cmd = Command.new(name, block)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    tags.each do |tag|
         
     | 
| 
      
 113 
     | 
    
         
            +
                      commands_for_tag = (commands[tag] ||= {})
         
     | 
| 
      
 114 
     | 
    
         
            +
                      commands_for_tag[name] = cmd
         
     | 
| 
      
 115 
     | 
    
         
            +
                    end
         
     | 
| 
      
 116 
     | 
    
         
            +
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                  def [] (tag=nil)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    if (cmds = @commands[tag])
         
     | 
| 
      
 120 
     | 
    
         
            +
                      cmds.values
         
     | 
| 
      
 121 
     | 
    
         
            +
                    else
         
     | 
| 
      
 122 
     | 
    
         
            +
                      []
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def select(tag=nil)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    cmd = Gui.choose(nil, self[tag])
         
     | 
| 
      
 128 
     | 
    
         
            +
                    cmd.run if cmd
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                  def for_active_window
         
     | 
| 
      
 132 
     | 
    
         
            +
                    cmds = []
         
     | 
| 
      
 133 
     | 
    
         
            +
                    exe = active_window.exe_name
         
     | 
| 
      
 134 
     | 
    
         
            +
                    app = App.for_exe(exe)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    cmds.concat self[app] if app
         
     | 
| 
      
 136 
     | 
    
         
            +
                    if (dir = AppDir.get(exe))
         
     | 
| 
      
 137 
     | 
    
         
            +
                      cmds.concat Path.contents(dir)
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
      
 139 
     | 
    
         
            +
                    if (chosen = Gui.choose(nil, cmds))
         
     | 
| 
      
 140 
     | 
    
         
            +
                      case chosen
         
     | 
| 
      
 141 
     | 
    
         
            +
                      when String
         
     | 
| 
      
 142 
     | 
    
         
            +
                        Path.run(dir + chosen)
         
     | 
| 
      
 143 
     | 
    
         
            +
                      else
         
     | 
| 
      
 144 
     | 
    
         
            +
                        chosen.run
         
     | 
| 
      
 145 
     | 
    
         
            +
                      end
         
     | 
| 
      
 146 
     | 
    
         
            +
                    end
         
     | 
| 
      
 147 
     | 
    
         
            +
                  end
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              def Commands(tag=nil, &block)
         
     | 
| 
      
 152 
     | 
    
         
            +
                Commands.default_tag = tag
         
     | 
| 
      
 153 
     | 
    
         
            +
                Commands.instance_eval(&block)
         
     | 
| 
      
 154 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 155 
     | 
    
         
            +
                Commands.default_tag = nil
         
     | 
| 
      
 156 
     | 
    
         
            +
              end
         
     | 
| 
      
 157 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rum/barrel/emacs_client'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class << Emacs
         
     | 
| 
      
 4 
     | 
    
         
            +
              attr_accessor :client, :eval_in_user_buffer
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              Emacs.client = EmacsClient.new
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def eval(elisp)
         
     | 
| 
      
 9 
     | 
    
         
            +
                # MacRuby hack
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @client.eval fails
         
     | 
| 
      
 11 
     | 
    
         
            +
                elisp = "(with-current-buffer (window-buffer) #{elisp})" if @eval_in_user_buffer
         
     | 
| 
      
 12 
     | 
    
         
            +
                Emacs.client.eval(elisp)
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def funcall(*args)
         
     | 
| 
      
 16 
     | 
    
         
            +
                eval("(#{args.join(' ')})")
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              Quoting = [["\n", '\n'],
         
     | 
| 
      
 20 
     | 
    
         
            +
                         ['"', '\\"']]
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def quote(str)
         
     | 
| 
      
 23 
     | 
    
         
            +
                str.gsub!('\\', '\\\\\\\\')
         
     | 
| 
      
 24 
     | 
    
         
            +
                Quoting.each { |from, to|  str.gsub!(from, to) }
         
     | 
| 
      
 25 
     | 
    
         
            +
                '"' << str << '"'
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def unquote(str)
         
     | 
| 
      
 29 
     | 
    
         
            +
                Quoting.reverse.each { |from, to| str.gsub!(to, from) }
         
     | 
| 
      
 30 
     | 
    
         
            +
                str.gsub('\\\\', '\\').chomp[1..-2]
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def find_file(path, line)
         
     | 
| 
      
 34 
     | 
    
         
            +
                line = if line.is_a? Fixnum
         
     | 
| 
      
 35 
     | 
    
         
            +
                         "(goto-line #{line})"
         
     | 
| 
      
 36 
     | 
    
         
            +
                       end
         
     | 
| 
      
 37 
     | 
    
         
            +
                eval("(progn (find-file \"#{path}\")#{line})")
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def open_file(path, line=nil)
         
     | 
| 
      
 41 
     | 
    
         
            +
                Emacs.activate
         
     | 
| 
      
 42 
     | 
    
         
            +
                Emacs.find_file(path, line)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'socket'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Ruby implementation of
         
     | 
| 
      
 4 
     | 
    
         
            +
            # emacs_source/lib-src/emacsclient.c
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class EmacsClient
         
     | 
| 
      
 7 
     | 
    
         
            +
              def eval(elisp)
         
     | 
| 
      
 8 
     | 
    
         
            +
                socket = connect
         
     | 
| 
      
 9 
     | 
    
         
            +
                socket.puts "-eval #{quote(elisp)}"
         
     | 
| 
      
 10 
     | 
    
         
            +
                result = unquote(socket.read)
         
     | 
| 
      
 11 
     | 
    
         
            +
                socket.close
         
     | 
| 
      
 12 
     | 
    
         
            +
                format(result)
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def format(str)
         
     | 
| 
      
 16 
     | 
    
         
            +
                str[/.*? (.*)/, 1]
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def quote str
         
     | 
| 
      
 20 
     | 
    
         
            +
                r = str.gsub(/&|^-/, '&\&').gsub("\n", '&n').gsub(' ', '&_')
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def unquote str
         
     | 
| 
      
 24 
     | 
    
         
            +
                str.gsub(/&(.)/) do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  case $1
         
     | 
| 
      
 26 
     | 
    
         
            +
                  when 'n'; "\n"
         
     | 
| 
      
 27 
     | 
    
         
            +
                  when '_'; ' '
         
     | 
| 
      
 28 
     | 
    
         
            +
                  else $1
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              if RUBY_PLATFORM =~ /mswin|mingw/
         
     | 
| 
      
 34 
     | 
    
         
            +
                attr_accessor :ip, :port, :auth_string
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @server_file = File.join(ENV['HOME'], '.emacs.d', 'server', 'server')
         
     | 
| 
      
 38 
     | 
    
         
            +
                  read_config
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                
         
     | 
| 
      
 41 
     | 
    
         
            +
                def read_config
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @server_active = File.exists? @server_file
         
     | 
| 
      
 43 
     | 
    
         
            +
                  return unless @server_active
         
     | 
| 
      
 44 
     | 
    
         
            +
                  lines = File.readlines(@server_file)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @ip, @port = lines.first.match(/(.*?):(\d+)/).captures
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @auth_string = lines.last
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def create_socket
         
     | 
| 
      
 50 
     | 
    
         
            +
                  return unless @server_active
         
     | 
| 
      
 51 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 52 
     | 
    
         
            +
                  	socket = TCPSocket.open(@ip, @port)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    socket.write "-auth #@auth_string "
         
     | 
| 
      
 54 
     | 
    
         
            +
                    socket
         
     | 
| 
      
 55 
     | 
    
         
            +
                  rescue SystemCallError
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                def connect
         
     | 
| 
      
 60 
     | 
    
         
            +
                  create_socket or (read_config and create_socket) \
         
     | 
| 
      
 61 
     | 
    
         
            +
                  or raise "Can't connect to Emacs Server."
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              else # Unix
         
     | 
| 
      
 64 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @socket_path = File.join(ENV['TMPDIR'], "emacs#{Process::Sys.geteuid}", 'server')
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def connect
         
     | 
| 
      
 69 
     | 
    
         
            +
                  UNIXSocket.open(@socket_path)
         
     | 
| 
      
 70 
     | 
    
         
            +
                rescue SystemCallError => error
         
     | 
| 
      
 71 
     | 
    
         
            +
                  raise "Can't connect to Emacs Server\n" << error.message
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rum/core.rb
    ADDED
    
    | 
         @@ -0,0 +1,125 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rum/hotkey_core'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rum/help'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rum/gui'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rum/barrel'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'thread'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            case RUBY_DESCRIPTION
         
     | 
| 
      
 8 
     | 
    
         
            +
            when /mswin|mingw/ then require 'rum/windows'
         
     | 
| 
      
 9 
     | 
    
         
            +
            when /MacRuby/     then require 'rum/mac'
         
     | 
| 
      
 10 
     | 
    
         
            +
            else raise "Platform not yet supported: #{RUBY_PLATFORM}"
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            Encoding.default_external = Encoding::UTF_8
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            module Rum
         
     | 
| 
      
 16 
     | 
    
         
            +
              autoload :Server, 'rum/server'
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 19 
     | 
    
         
            +
                attr_writer :layout
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_reader :hotkey_set, :hotkey_processor, \
         
     | 
| 
      
 21 
     | 
    
         
            +
                            :work_queue, :worker_thread
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def layout
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @layout ||= Layouts.default_layout
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
                
         
     | 
| 
      
 27 
     | 
    
         
            +
                def setup
         
     | 
| 
      
 28 
     | 
    
         
            +
                  return if setup_completed?
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @hotkey_set = HotkeySet.new(layout)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @hotkey_processor = HotkeyProcessor.new(@hotkey_set)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def setup_completed?
         
     | 
| 
      
 34 
     | 
    
         
            +
                  !!@hotkey_set
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def start
         
     | 
| 
      
 38 
     | 
    
         
            +
                  setup
         
     | 
| 
      
 39 
     | 
    
         
            +
                  Thread.abort_on_exception = true
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @work_queue = Action.work_queue = Queue.new
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @worker_thread = start_worker_thread(@work_queue)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  KeyboardHook.start &@hotkey_processor.method(:process_event)
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def stop
         
     | 
| 
      
 47 
     | 
    
         
            +
                  KeyboardHook.stop
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                def start_worker_thread(queue)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  Thread.new do
         
     | 
| 
      
 52 
     | 
    
         
            +
                    while action = queue.deq
         
     | 
| 
      
 53 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 54 
     | 
    
         
            +
                        action.call
         
     | 
| 
      
 55 
     | 
    
         
            +
                      rescue => exception
         
     | 
| 
      
 56 
     | 
    
         
            +
                        display_exception exception
         
     | 
| 
      
 57 
     | 
    
         
            +
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def display_exception(exception)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  error_message = ["#{exception.class}:", exception,
         
     | 
| 
      
 64 
     | 
    
         
            +
                                   '', *exception.backtrace].join("\n")
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  file, line = parse_stack_frame(exception.backtrace.first)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  if file
         
     | 
| 
      
 68 
     | 
    
         
            +
                    file = File.expand_path(file)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    callback = lambda do
         
     | 
| 
      
 70 
     | 
    
         
            +
                      Gui.message("Click here to jump to the last error:\n\n#{file}:#{line}") do
         
     | 
| 
      
 71 
     | 
    
         
            +
                        Gui.message error_message, :sticky
         
     | 
| 
      
 72 
     | 
    
         
            +
                        Gui.open_file file, line
         
     | 
| 
      
 73 
     | 
    
         
            +
                      end
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  
         
     | 
| 
      
 77 
     | 
    
         
            +
                  Gui.message error_message, :sticky, &callback
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def parse_stack_frame(frame)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  if match = frame.match(/^(.+?):(\d+)/)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    file, line = match.captures
         
     | 
| 
      
 83 
     | 
    
         
            +
                    # Different file names in IRB stackframes:
         
     | 
| 
      
 84 
     | 
    
         
            +
                    # Ruby 1.9.1: (eval)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    # Ruby 1.9.2: <main>
         
     | 
| 
      
 86 
     | 
    
         
            +
                    # MacRuby 0.10: /working_directory/(eval)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    if file !~ /\(eval\)$/ and file != '<main>'
         
     | 
| 
      
 88 
     | 
    
         
            +
                      [file, line.to_i]
         
     | 
| 
      
 89 
     | 
    
         
            +
                    end
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                def switch_worker_thread
         
     | 
| 
      
 94 
     | 
    
         
            +
                  return unless Thread.current == @worker_thread
         
     | 
| 
      
 95 
     | 
    
         
            +
                  old = @work_queue
         
     | 
| 
      
 96 
     | 
    
         
            +
                  new = @work_queue = Action.work_queue = Queue.new
         
     | 
| 
      
 97 
     | 
    
         
            +
                  new.enq(old.deq) until old.length == 0
         
     | 
| 
      
 98 
     | 
    
         
            +
                  @worker_thread = start_worker_thread(new)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  old.enq nil # Signal the worker thread to stop
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
              WorkingDir = Dir.pwd
         
     | 
| 
      
 104 
     | 
    
         
            +
              
         
     | 
| 
      
 105 
     | 
    
         
            +
              def restart
         
     | 
| 
      
 106 
     | 
    
         
            +
                Dir.chdir WorkingDir
         
     | 
| 
      
 107 
     | 
    
         
            +
                if Thread.current == Rum::Server.thread
         
     | 
| 
      
 108 
     | 
    
         
            +
                  Thread.new do
         
     | 
| 
      
 109 
     | 
    
         
            +
                    sleep 0.01 # Allow server to respond. Slightly hacky.
         
     | 
| 
      
 110 
     | 
    
         
            +
                    restart_platform_specific
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
                  true
         
     | 
| 
      
 113 
     | 
    
         
            +
                else
         
     | 
| 
      
 114 
     | 
    
         
            +
                  restart_platform_specific
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
              end
         
     | 
| 
      
 117 
     | 
    
         
            +
              
         
     | 
| 
      
 118 
     | 
    
         
            +
              def show
         
     | 
| 
      
 119 
     | 
    
         
            +
                System.terminal_window.show
         
     | 
| 
      
 120 
     | 
    
         
            +
              end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
              def hide
         
     | 
| 
      
 123 
     | 
    
         
            +
                System.terminal_window.hide
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rum/dsl.rb
    ADDED
    
    | 
         @@ -0,0 +1,109 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            include Rum
         
     | 
| 
      
 2 
     | 
    
         
            +
            include System
         
     | 
| 
      
 3 
     | 
    
         
            +
            include Keyboard
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Rum
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Action
         
     | 
| 
      
 7 
     | 
    
         
            +
                def register
         
     | 
| 
      
 8 
     | 
    
         
            +
                  Rum.hotkey_set.register(self)
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
                
         
     | 
| 
      
 11 
     | 
    
         
            +
                def unregister
         
     | 
| 
      
 12 
     | 
    
         
            +
                  Rum.hotkey_set.unregister(self)
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              class FileLocation
         
     | 
| 
      
 17 
     | 
    
         
            +
                def initialize(file, line)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @file = file
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @line = line
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def self.from_stack_frame(frame)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  file, line = Rum.parse_stack_frame(frame)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  if file
         
     | 
| 
      
 25 
     | 
    
         
            +
                    file = File.expand_path(file) if File.dirname(file) == '.'
         
     | 
| 
      
 26 
     | 
    
         
            +
                    new(file, line)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def show
         
     | 
| 
      
 31 
     | 
    
         
            +
                  Gui.open_file(@file, @line)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  true
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            module GuiMixin
         
     | 
| 
      
 38 
     | 
    
         
            +
              # Delegating to Gui instead of directly including Gui avoids dealing
         
     | 
| 
      
 39 
     | 
    
         
            +
              # with module hierarchy corner cases that appear when other modules
         
     | 
| 
      
 40 
     | 
    
         
            +
              # are later dynamically included into Gui via Gui.use.
         
     | 
| 
      
 41 
     | 
    
         
            +
              [:message, :alert, :read, :choose, :open_file, :browse, :goto].each do |method_name|
         
     | 
| 
      
 42 
     | 
    
         
            +
                define_method(method_name) do |*args, &block|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  Gui.send(method_name, *args, &block)
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
                private method_name
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
      
 48 
     | 
    
         
            +
            include GuiMixin
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            def wait(timeout=5, interval=0.01)
         
     | 
| 
      
 51 
     | 
    
         
            +
              start = Time.new
         
     | 
| 
      
 52 
     | 
    
         
            +
              loop do
         
     | 
| 
      
 53 
     | 
    
         
            +
                return true if yield
         
     | 
| 
      
 54 
     | 
    
         
            +
                sleep interval
         
     | 
| 
      
 55 
     | 
    
         
            +
                return false if Time.new - start > timeout
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            class String
         
     | 
| 
      
 60 
     | 
    
         
            +
              def do(*options, &action)
         
     | 
| 
      
 61 
     | 
    
         
            +
                repeated = true
         
     | 
| 
      
 62 
     | 
    
         
            +
                options.reject! do |option|
         
     | 
| 
      
 63 
     | 
    
         
            +
                  case option
         
     | 
| 
      
 64 
     | 
    
         
            +
                  when :no_repeat
         
     | 
| 
      
 65 
     | 
    
         
            +
                    repeated = false
         
     | 
| 
      
 66 
     | 
    
         
            +
                  when String
         
     | 
| 
      
 67 
     | 
    
         
            +
                    action = lambda { Keyboard.type option }
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
                if (condition = options.first) and condition.respond_to? :to_matcher
         
     | 
| 
      
 71 
     | 
    
         
            +
                  matcher = condition.to_matcher
         
     | 
| 
      
 72 
     | 
    
         
            +
                  condition = lambda { matcher.active? }
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
                location = FileLocation.from_stack_frame(caller.first)
         
     | 
| 
      
 75 
     | 
    
         
            +
                Rum.hotkey_set.add_hotkey(self, action, condition, repeated, location)
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              def unregister
         
     | 
| 
      
 79 
     | 
    
         
            +
                Rum.hotkey_set.remove_hotkey(self)
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              def translate condition=nil, to
         
     | 
| 
      
 83 
     | 
    
         
            +
                if condition and condition.respond_to? :to_matcher
         
     | 
| 
      
 84 
     | 
    
         
            +
                  matcher = condition.to_matcher
         
     | 
| 
      
 85 
     | 
    
         
            +
                  condition = lambda { matcher.active? }
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
                Rum.hotkey_set.add_translation(self, to, condition,
         
     | 
| 
      
 88 
     | 
    
         
            +
                                               FileLocation.from_stack_frame(caller.first))
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            class String
         
     | 
| 
      
 93 
     | 
    
         
            +
              # Prepare a special version of #do that is only active when the user
         
     | 
| 
      
 94 
     | 
    
         
            +
              # calls #do for the first time.
         
     | 
| 
      
 95 
     | 
    
         
            +
              # After running Rum.setup it calls and restores the default version of #do.
         
     | 
| 
      
 96 
     | 
    
         
            +
              alias :old_do :do
         
     | 
| 
      
 97 
     | 
    
         
            +
              def do(*args, &block)
         
     | 
| 
      
 98 
     | 
    
         
            +
                Rum.setup
         
     | 
| 
      
 99 
     | 
    
         
            +
                String.class_eval do
         
     | 
| 
      
 100 
     | 
    
         
            +
                  alias :do :old_do
         
     | 
| 
      
 101 
     | 
    
         
            +
                  undef_method :old_do
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
                action = self.do(*args, &block)
         
     | 
| 
      
 104 
     | 
    
         
            +
                # The original location has been invalidated by the
         
     | 
| 
      
 105 
     | 
    
         
            +
                # extra call to #do. Replace it.
         
     | 
| 
      
 106 
     | 
    
         
            +
                action.location = FileLocation.from_stack_frame(caller.first)
         
     | 
| 
      
 107 
     | 
    
         
            +
                action
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
      
 109 
     | 
    
         
            +
            end
         
     |