rum 0.0.1-x86-mswin32-60 → 0.0.3-x86-mswin32-60

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.
Files changed (49) hide show
  1. data/CHANGELOG +9 -0
  2. data/README.md +35 -0
  3. data/Rakefile +22 -19
  4. data/bin/rum-client +4 -4
  5. data/doc/basic.rb +1 -1
  6. data/doc/doc.html +619 -602
  7. data/doc/example.rb +1 -1
  8. data/doc/reference.rb +29 -16
  9. data/doc/resources/build.rb +14 -12
  10. data/doc/resources/doc.haml +8 -3
  11. data/ext/mac/keyboard_hook/EventTap.h +1 -1
  12. data/ext/mac/keyboard_hook/EventTap.m +9 -9
  13. data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/project.pbxproj +12 -9
  14. data/ext/windows/keyboard_hook/keyboard_hook.c +3 -3
  15. data/ext/windows/system/autohotkey_stuff.c +12 -10
  16. data/ext/windows/system/clipboard_watcher.c +2 -2
  17. data/ext/windows/system/extconf.rb +1 -0
  18. data/ext/windows/system/input_box.c +9 -9
  19. data/ext/windows/system/system.c +51 -46
  20. data/lib/rum/barrel.rb +46 -16
  21. data/lib/rum/barrel/emacs.rb +1 -1
  22. data/lib/rum/barrel/emacs_client.rb +32 -5
  23. data/lib/rum/core.rb +24 -22
  24. data/lib/rum/dsl.rb +15 -16
  25. data/lib/rum/gui.rb +3 -3
  26. data/lib/rum/help.rb +10 -8
  27. data/lib/rum/hotkey_core.rb +35 -25
  28. data/lib/rum/mac.rb +1 -1
  29. data/lib/rum/mac/gui.rb +1 -1
  30. data/lib/rum/mac/gui/growl.rb +3 -3
  31. data/lib/rum/mac/irb/completion.rb +13 -13
  32. data/lib/rum/mac/keyboard_hook.rb +8 -5
  33. data/lib/rum/mac/layouts.rb +4 -4
  34. data/lib/rum/mac/system.rb +2 -2
  35. data/lib/rum/remote.rb +3 -3
  36. data/lib/rum/server.rb +2 -3
  37. data/lib/rum/windows.rb +2 -1
  38. data/lib/rum/windows/app.rb +12 -7
  39. data/lib/rum/windows/apps.rb +3 -8
  40. data/lib/rum/windows/gui.rb +8 -8
  41. data/lib/rum/windows/keyboard.rb +34 -9
  42. data/lib/rum/windows/keyboard_hook.so +0 -0
  43. data/lib/rum/windows/layouts.rb +6 -6
  44. data/lib/rum/windows/system.rb +71 -28
  45. data/lib/rum/windows/system.so +0 -0
  46. data/lib/rum/windows/system_foreign_functions.rb +44 -20
  47. data/rum.gemspec +2 -2
  48. metadata +19 -21
  49. data/README +0 -30
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ = 0.0.3
2
+ === 2012/11/24
3
+ * Added Emacs 24 support in EmacsClient
4
+ * Mac: OS X 10.8 support
5
+ * Minor tweaks and fixes
6
+ = 0.0.2
7
+ === 2012/8/13
8
+ * Windows: Method 'Keyboard::type_unicode' for sending unicode keyboard input
9
+ * Windows: Add 64-bit compatibility for App paths and 'Window#exe_path/exe_name'
1
10
  = 0.0.1
2
11
  === 2011/06/4
3
12
  * Hello World!
@@ -0,0 +1,35 @@
1
+ # Rum
2
+
3
+ A cross-platform hotkey and macro utility, running on Windows and Mac
4
+ OS.
5
+
6
+ Visit http://nonsequitur.github.com/rum for examples and a detailed
7
+ reference.
8
+
9
+ ## Synopsis
10
+ require 'rum'
11
+ Rum.layout.modifier 'caps'
12
+ 'caps f1'.do { message 'foo' }
13
+ 'caps shift f1'.do { message 'bar' }
14
+ Rum.start
15
+
16
+ ## License
17
+ Rum is available under the MIT license
18
+ (http://www.opensource.org/licenses/mit-license.php)
19
+
20
+ Copyright 2010-2011, The Rum Project
21
+
22
+ ### Licenses of software that is bundled with some Rum distributions
23
+ #### CocoaDialog
24
+ CocoaDialog is Copyright © 2004, Mark A. Stratman <mark@sporkstorms.org>
25
+ It is licensed under the GNU General Public License.
26
+ http://cocoadialog.sourceforge.net/
27
+
28
+ #### Growl
29
+ Copyright (c) The Growl Project, 2004
30
+ All rights reserved.
31
+ http://growl.info/documentation/developer/bsd-license.txt
32
+
33
+ #### AutoHotkey
34
+ GNU General Public License
35
+ http://www.autohotkey.com/docs/license.htm
data/Rakefile CHANGED
@@ -5,16 +5,16 @@ CLEAN.include('ext/windows/keyboard_hook/*',
5
5
  'ext/mac/keyboard_hook/build',
6
6
  '*.gem',
7
7
  '**/.DS_Store')
8
- CLEAN.exclude('.c', '.h', 'extconf.rb')
8
+ CLEAN.exclude(/\.c$/, /\.h$/, /extconf\.rb/)
9
9
 
10
10
  CLOBBER.include('lib/rum/windows/keyboard_hook.so',
11
11
  'lib/rum/windows/system.so',
12
12
  'lib/rum/mac/keyboard_hook/KeyboardHook.framework',
13
13
  'doc/doc.html')
14
14
 
15
- MAC_BINARIES = ['lib/rum/mac/keyboard_hook/KeyboardHook.framework',
16
- 'lib/rum/mac/gui/Growl.framework',
17
- 'lib/rum/mac/gui/CocoaDialog.app']
15
+ MAC_BINARIES = [Regexp.new('lib/rum/mac/keyboard_hook/KeyboardHook.framework'),
16
+ Regexp.new('lib/rum/mac/gui/Growl.framework'),
17
+ Regexp.new('lib/rum/mac/gui/CocoaDialog.app')]
18
18
 
19
19
  WINDOWS_BINARIES = ['lib/rum/windows/keyboard_hook.so',
20
20
  'lib/rum/windows/system.so']
@@ -28,7 +28,7 @@ namespace :ext do
28
28
  'autohotkey_stuff', 'clipboard_watcher']]
29
29
 
30
30
  extensions.each do |dir, ext, *deps|
31
-
31
+
32
32
  extconf = "#{dir}/extconf.rb"
33
33
 
34
34
  deps.map! do |dependency|
@@ -40,7 +40,7 @@ namespace :ext do
40
40
  end
41
41
  source
42
42
  end
43
-
43
+
44
44
  file "#{InstallDir}/#{ext}.so" => ["#{dir}/#{ext}.c", extconf, *deps] do
45
45
  Dir.chdir(dir) do
46
46
  ruby 'extconf.rb'
@@ -52,7 +52,7 @@ namespace :ext do
52
52
  end
53
53
 
54
54
  task :keyboard_hook => 'lib/rum/windows/keyboard_hook.so'
55
- task :system => 'lib/rum/windows/system.so'
55
+ task :system => 'lib/rum/windows/system.so'
56
56
  end
57
57
  task :windows => ['windows:keyboard_hook', 'windows:system']
58
58
 
@@ -64,7 +64,7 @@ namespace :ext do
64
64
  rm_r keyboard_hook if File.exists? keyboard_hook
65
65
  cp_r xcode_output, keyboard_hook
66
66
  end
67
-
67
+
68
68
  file xcode_output => FileList['ext/mac/keyboard_hook/*.m'] do
69
69
  Dir.chdir('ext/mac/keyboard_hook') { system 'xcodebuild' }
70
70
  end
@@ -85,16 +85,19 @@ namespace :gem do
85
85
  end
86
86
 
87
87
  task :windows do
88
- common_spec do |spec|
89
- spec.files = FileList['**/*'].exclude(*CLEAN.to_a, *MAC_BINARIES)
90
- spec.add_dependency('ruby_gntp', '>= 0.3.4')
91
- spec.add_dependency('win32-api', '>= 1.4.8')
92
- spec.add_dependency('win32-clipboard', '>= 0.5.2')
93
- # mingw32 and mswin32 binaries can be used interchangeably
94
- # spec.platform = 'x86-mingw32'
95
- # build(spec)
96
- spec.platform = 'x86-mswin32-60'
97
- build(spec)
88
+ # mingw32 and mswin32 binaries can be used interchangeably
89
+ platforms = ['x86-mingw32', 'x86-mswin32-60']
90
+ files = FileList['**/*'].exclude(*CLEAN.to_a, *MAC_BINARIES)
91
+
92
+ platforms.each do |platform|
93
+ common_spec do |spec|
94
+ spec.files = files
95
+ spec.add_dependency('ruby_gntp', '>= 0.3.4')
96
+ spec.add_dependency('win32-api', '>= 1.4.8')
97
+ spec.add_dependency('win32-clipboard', '>= 0.5.2')
98
+ spec.platform = platform
99
+ build(spec)
100
+ end
98
101
  end
99
102
  end
100
103
 
@@ -107,7 +110,7 @@ namespace :gem do
107
110
  end
108
111
 
109
112
  task :publish do
110
-
113
+
111
114
  end
112
115
  end
113
116
  task :gem => ['gem:windows', 'gem:mac']
@@ -10,7 +10,7 @@ module Client
10
10
  end
11
11
 
12
12
  class NilResponse < StandardError; end
13
-
13
+
14
14
  def eval(code)
15
15
  if connect
16
16
  result = @remote.eval(code) or raise NilResponse
@@ -29,7 +29,7 @@ module RemoteIRB
29
29
  eval(Client.eval(completor_call))
30
30
  rescue Exception # Explicitly rescue Exception to catch eval errors.
31
31
  end
32
-
32
+
33
33
  def Completion.setup
34
34
  Readline.completion_proc = lambda do |input|
35
35
  candidates("IRB::InputCompletor::CompletionProc.call(#{input.dump})")
@@ -42,7 +42,7 @@ module RemoteIRB
42
42
 
43
43
  # Borrowed from Hijack
44
44
  const_set 'Workspace', Class.new(IRB::WorkSpace)
45
- Workspace.class_eval do
45
+ Workspace.class_eval do
46
46
  def evaluate(context, statements, file = __FILE__, line = __LINE__)
47
47
  if completor_call = statements[/^puts (IRB::InputCompletor.*)/, 1]
48
48
  puts Completion.candidates(completor_call)
@@ -108,7 +108,7 @@ Evaluates code from standard input if arguments are omitted.
108
108
 
109
109
  You can set the environment variable RUM_PORT to change the
110
110
  port that is used by Rum-Client and Rum-Server.'
111
-
111
+
112
112
  when '-i', '--interactive'
113
113
  switch_to_mri_ruby if RUBY_DESCRIPTION =~ /MacRuby/
114
114
  require_relative '../lib/rum/remote'
@@ -4,7 +4,7 @@ require 'rum'
4
4
 
5
5
  # If you use Emacs
6
6
  require 'rum/apps'
7
- 'shift f2'.do { Emacs.eval '(rum-client)'; Emacs.activate }
7
+ 'shift f2'.do { Emacs.eval '(rum-client)'; Emacs.activate }
8
8
 
9
9
  Rum::Server.start
10
10
  Rum.start
@@ -1,602 +1,619 @@
1
- <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
2
- <head>
3
- <title>Rum</title>
4
- <meta content='text/html;charset=utf-8' http-equiv='Content-Type' />
5
- <link href='resources/screen.css' media='screen' rel='stylesheet' type='text/css' />
6
- <link href='resources/highlight.css' media='screen' rel='stylesheet' type='text/css' />
7
- </head>
8
- <body>
9
- <img id='logo' src='resources/logo.png' />
10
- <div id='nav'>
11
- <ul>
12
- <li>
13
- <a href='#'>Intro</a>
14
- </li>
15
- <li>
16
- <a href='#installation'>Installation</a>
17
- </li>
18
- <li>
19
- <a href='#coding'>Coding</a>
20
- </li>
21
- <li>
22
- <a href='#example'>Example</a>
23
- </li>
24
- <li>
25
- <a href='#reference'>Reference</a>
26
- </li>
27
- <li>
28
- <a href='#development'>Development</a>
29
- </li>
30
- </ul>
31
- </div>
32
- <div id='wrapper'>
33
- <div id='intro'>Rum is a cross-platform Hotkey and Macro utility, built in Ruby.<br />Not yet running on Linux, it’s progressing steadily on the Mac (MacRuby) and is fully supported on Windows.</div>
34
- <img src='resources/screenshot.png' />
35
- <div id='screenshot-sub'></div>
36
- <div id='intro-code'>
37
- <div id='top'></div>
38
- <div id='content'>
39
- <img id='flash' src='resources/flash.png' />
40
- <div id='sshot-sub'>This snippet powers the above screenshot.</div>
41
- <div class="highlight"><pre>require <span class="s1">&#39;rum&#39;</span>
42
-
43
- <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;caps&#39;</span>
44
- <span class="s1">&#39;caps&#39;</span><span class="o">.</span><span class="n">do</span> <span class="s1">&#39;(cmd (tab))&#39;</span>
45
- <span class="s1">&#39;caps shift&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">active_window</span><span class="o">.</span><span class="n">close</span> <span class="p">}</span>
46
-
47
- require <span class="s1">&#39;rum/apps&#39;</span>
48
- <span class="s1">&#39;caps h&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;Hello from Rum!&#39;</span> <span class="p">}</span>
49
- <span class="s1">&#39;caps p&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Photoshop</span><span class="o">.</span><span class="n">activate</span> <span class="p">}</span>
50
- <span class="s1">&#39;caps down&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="no">Photoshop</span><span class="p">)</span> <span class="p">{</span> <span class="no">Photoshop</span><span class="o">.</span><span class="n">next_blend_mode</span> <span class="p">}</span>
51
- <span class="s1">&#39;caps b&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Chrome</span><span class="o">.</span><span class="n">activate_and_focus_address_bar</span> <span class="p">}</span>
52
- <span class="s1">&#39;caps s&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(slime-repl)&#39;</span><span class="p">;</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">activate</span> <span class="p">}</span>
53
- <span class="s1">&#39;caps c&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Clipboard</span><span class="o">.</span><span class="n">append</span> <span class="p">}</span>
54
- <span class="s1">&#39;ctrl shift h&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> type <span class="s1">&#39;hi&#39;</span> <span class="p">}</span>
55
- <span class="c1"># Caveat: Some hotkey actions are not yet available on the Mac.</span>
56
-
57
- <span class="no">Rum</span><span class="o">.</span><span class="n">start</span>
58
- </pre></div>
59
-
60
- </div>
61
- <div id='bottom'></div>
62
- <div id='intro-code-sub'>Rum configuration files are regular Ruby scripts, like the above.<br /> Running Rum is as easy as calling <span class="code">ruby my_rum_config_file.rb</span> from the command line.<br />(Or <span class="code">macruby -rubygems my_rum_config_file.rb</span> on the Mac.)</div>
63
- </div>
64
- <div id='guide'>
65
- <div id='installation'>
66
- <a name='installation'>
67
- <h1>Installation</h1>
68
- </a>
69
- <div id='gem'>
70
- <div id='regulargem'>
71
- <span class='code'>gem install rum</span>
72
- </div>
73
- <div id='macgem'>
74
- <span class='code'>macgem install rum</span>
75
- <div>
76
- </div>
77
- </div>
78
- <div class='clear'></div>
79
- </div>
80
- <p id='current_version'>
81
- Current version:
82
- 0.0.1
83
- <span id='changelog'>(<a href="https://github.com/nonsequitur/rum/blob/master/CHANGELOG">Changelog</a>)</span>
84
- </p>
85
- <div id='platforms'>
86
- <h3>Supported platforms</h3>
87
- <ul>
88
- <li>Mac OS X – MacRuby >=0.10</li>
89
- <li>
90
- 32-bit Windows XP/Vista/7 – Ruby >=1.9.1p378.<br />
91
- </li>
92
- </ul>
93
- </div>
94
- <div id='growl'>
95
- <h2>Recommended: Growl</h2>
96
- <ul>
97
- <li>Get Growl: <a href="http://growl.info/">Mac</a>, <a href="http://www.growlforwindows.com/gfw/">Windows</a></li>
98
- <li>To use Growl in Rum: Add <span class="code">Gui.use Gui::Growl</span> to your Rum config.</li>
99
- </ul>
100
- <div id='growl-explanation'>
101
- <h3>Why Growl?</h3>
102
- Notification bubbles are a convenient alternative to focus-stealing message boxes.
103
- Some higher level Rum methods only work smoothly with Growl-style notifications.
104
- Currently, Growl is the only notification system supported by Rum.
105
- </div>
106
- </div>
107
- </div>
108
- <div id='coding'>
109
- <a name='coding'>
110
- <h1>Coding in Rum</h1>
111
- </a>
112
- Rum encourages an interactive approach to coding and a fast code-and-feedback cycle.
113
- <h2>Core techniques</h2>
114
- <ul id='core-techniques'>
115
- <li>
116
- <h3>rum-client REPL</h3>
117
- <p>Add <span class="code">Rum::Server.start</span> to your Rum config.</p>
118
- <p>Call <span class="code">rum-client -i</span> from the command line to start an IRB-session inside a running Rum instance. IRB Completion is fully supported.</p>
119
- <p>Nearly all snippets in this guide can be evaluated interactively.</p>
120
- <p>Set the environment variable <span class="code">RUM_PORT</span> to change the port on which client and server connect.</p>
121
- <p>
122
- <h3>rum-client in emacs:</h3>
123
- <ul>
124
- <li>Get the latest Inf-Ruby via <a href="http://marmalade-repo.org/packages/inf-ruby">ELPA</a></li>
125
- <li>
126
- Add the following to your Emacs config:
127
- <pre id='inf_ruby_setup'>(add-to-list 'inf-ruby-implementations
128
- '("rum-client" . "rum-client -i --inf-ruby-mode")
129
- (defun rum-client ()
130
- (interactive)
131
- (inf-ruby "rum-client")))
132
- </pre>
133
- </li>
134
- <li>
135
- Run <span class="code">M-x rum-client</span>
136
- </li>
137
- </ul>
138
- <div id='auto-completion'>
139
- <h4>Auto-completion</h4>
140
- <img id='auto-completion' src='resources/emacs-auto-completion.png' />
141
- <p>
142
- Company-Mode features auto-completion for IRB sessions.<br />
143
- <a href="http://www.emacswiki.org/emacs/InfRubyCompany">See here for installation instructions</a>.
144
- </p>
145
- </div>
146
- </p>
147
- </li>
148
- <li>
149
- <h3>Rum.restart</h3>
150
- Restarts Rum.
151
- Bind it to a key, like <span class="code">'shift f1'.do { Rum.restart }</span>
152
- </li>
153
- </ul>
154
- Run Rum with this basic, REPL-enabled setup to get started:
155
- <div id='basic'><div class="highlight"><pre>require <span class="s1">&#39;rum&#39;</span>
156
-
157
- <span class="s1">&#39;shift f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">restart</span> <span class="p">}</span>
158
-
159
- <span class="c1"># If you use Emacs</span>
160
- require <span class="s1">&#39;rum/apps&#39;</span>
161
- <span class="s1">&#39;shift f2&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(rum-client)&#39;</span><span class="p">;</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">activate</span> <span class="p">}</span>
162
-
163
- <span class="no">Rum</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">start</span>
164
- <span class="no">Rum</span><span class="o">.</span><span class="n">start</span>
165
- </pre></div>
166
- </div>
167
- <div id='example'>
168
- <a name='example'>
169
- <h1>Extended Example</h1>
170
- </a>
171
- <div class="highlight"><pre><span class="c1">## A short survey of the main features</span>
172
- <span class="c1">## This file can be found at rum_dir/doc/example.rb</span>
173
-
174
- require <span class="s1">&#39;rum&#39;</span>
175
-
176
- <span class="c1"># 1. Set up additional modifiers that can then</span>
177
- <span class="c1"># be used in hotkey definitions.</span>
178
- <span class="c1"># Any key can be a modifier</span>
179
- <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;caps&#39;</span>
180
- <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;escape&#39;</span>
181
-
182
- <span class="c1"># 2. Hotkey definitions</span>
183
- <span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;foo&#39;</span> <span class="p">}</span>
184
- <span class="c1"># Hotkeys may consist solely of modifiers</span>
185
- <span class="s1">&#39;caps&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span>
186
- <span class="s1">&#39;caps ctrl&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span>
187
- <span class="c1"># Hotkey conditions</span>
188
- <span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="nb">rand</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">)</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;win!&#39;</span> <span class="p">}</span>
189
- <span class="c1"># Fuzzy hotkeys, trigger regardless of other modifiers being pressed</span>
190
- <span class="s1">&#39;* ctrl b&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;hi&#39;</span> <span class="p">}</span>
191
- <span class="c1"># Translations</span>
192
- <span class="s1">&#39;* caps j&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;down&#39;</span>
193
-
194
- <span class="c1"># 3. Gui</span>
195
- <span class="n">message</span> <span class="s1">&#39;message&#39;</span>
196
- <span class="n">read</span> <span class="s1">&#39;hi, how are you?&#39;</span> <span class="c1"># Input box</span>
197
-
198
- <span class="c1"># 4. Keyboard, send keypresses</span>
199
- type <span class="s1">&#39;hello&#39;</span>
200
- type <span class="s1">&#39;(ctrl (shift a))&#39;</span> <span class="c1"># Key combinations</span>
201
-
202
- <span class="c1"># 5. Help and introspection</span>
203
- <span class="c1"># Prompts you to enter a hotkey and then jumps to its</span>
204
- <span class="c1"># definition in your text editor.</span>
205
- <span class="s1">&#39;shift f2&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">show_hotkey</span> <span class="p">}</span>
206
-
207
- <span class="c1"># Asks you to enter an arbitrary hotkey and inserts a hotkey</span>
208
- <span class="c1"># definition snippet.</span>
209
- <span class="s1">&#39;shift f3&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">snippet</span> <span class="p">}</span>
210
-
211
- <span class="c1"># Restarts Rum.</span>
212
- <span class="s1">&#39;shift f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">restart</span> <span class="p">}</span>
213
-
214
-
215
- <span class="c1"># 6. Integrate external features</span>
216
- <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Gui</span><span class="o">::</span><span class="no">Growl</span>
217
-
218
- <span class="c1"># Set up a text-editor for opening files</span>
219
- require <span class="s1">&#39;rum/apps&#39;</span>
220
- <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Textmate</span><span class="p">,</span> <span class="ss">:open_file</span>
221
- <span class="c1"># Or</span>
222
- <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Emacs</span><span class="p">,</span> <span class="ss">:open_file</span>
223
-
224
- <span class="c1"># 7. Start the server. You can now connect to the</span>
225
- <span class="c1"># Rum process via rum-client.</span>
226
- <span class="no">Rum</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">start</span>
227
-
228
- <span class="c1"># 8. Start rum</span>
229
- <span class="no">Rum</span><span class="o">.</span><span class="n">start</span>
230
- </pre></div>
231
-
232
- </div>
233
- <a name='reference'>
234
- <h1>Reference</h1>
235
- </a>
236
- <p>
237
- This section is also available as a Ruby source file and can be
238
- conveniently viewed in a text editor.<br />
239
- Call <span class="code">Rum.reference</span> or manually open
240
- <span class="code">rum_dir/doc/reference.rb</span>.
241
- </p>
242
- </div>
243
- </div>
244
- <div id='reference_wrapper'><div id="table_of_contents"><h1>Chapters</h1><ul><li><a href="#chapter_1">1. Unicode</a></li><li><a href="#chapter_2">2. Layouts</a></li><li><a href="#chapter_3">2. Hotkeys</a></li><li><a href="#chapter_4">3. Keyboard</a></li><li><a href="#chapter_5">3. Gui</a></li><li><a href="#chapter_6">4. Get selected text</a></li><li><a href="#chapter_7">5. Clipboard</a></li><li><a href="#chapter_8">6. More methods</a></li><li><a href="#chapter_9">6. Rum's threading model</a></li><li><a href="#chapter_10">5. Help, introspection</a></li><li><a href="#chapter_11">5. Restarting, server</a></li><li><a href="#chapter_12">6. Windows</a></li><li><a href="#chapter_13">7. Apps</a></li></ul></div>
245
- <div class="chapter">
246
- <a name="chapter_1"><h1>1. Unicode</h1></a>
247
-
248
- <p>Rum is unicode-compatible. The default encoding is UTF-8.</p>
249
- </div>
250
- <div class="chapter">
251
- <a name="chapter_2"><h1>2. Layouts</h1></a>
252
-
253
- <p>Keyboard layout changes must take place before any hotkey definitions.<br /><br />Rum starts with a default QWERTY layout</p>
254
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">layout</span> <span class="c1">#=&gt; #&lt;Rum::Layout:0xb99634 ... &gt;</span></pre>
255
- <p>Changing the layout</p>
256
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">layout</span> <span class="o">=</span> <span class="no">Layouts</span><span class="o">.</span><span class="n">german</span></pre>
257
- <p>Listing available layouts</p>
258
- <pre class="highlight"><span class="no">Layouts</span><span class="o">.</span><span class="n">list</span></pre>
259
- <h2>Editing a layout</h2>
260
- <pre class="highlight"><span class="n">layout</span> <span class="o">=</span> <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span></pre>
261
- <h3>Adding a modifier.</h3>
262
- <p>Any key can be a modifier.</p>
263
- <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;escape&#39;</span></pre>
264
- <h3>Aliasing</h3>
265
- <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">alias</span> <span class="s1">&#39;escape&#39;</span><span class="p">,</span> <span class="s1">&#39;esc&#39;</span></pre>
266
- <p>The original key...</p>
267
- <pre class="highlight"><span class="n">layout</span><span class="o">[</span><span class="s1">&#39;escape&#39;</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:escape&gt;</span></pre>
268
- <p>...can now be referenced by the alias</p>
269
- <pre class="highlight"><span class="n">layout</span><span class="o">[</span><span class="s1">&#39;esc&#39;</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:escape&gt;</span></pre>
270
- <h3>Renaming</h3>
271
- <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">rename</span> <span class="s1">&#39;escape&#39;</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span>
272
- <span class="n">layout</span><span class="o">[</span><span class="s1">&#39;foo&#39;</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:foo&gt;</span></pre>
273
- <h3>Finding out the name of a key</h3>
274
- <p>All keyboard activity is reported at the terminal.<br />Switch to the Rum terminal window and press a key.</p>
275
- <h2>Advanced</h2>
276
- <h3>Adding a key</h3>
277
- <p>add name, *aliases, id</p>
278
- <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">add</span> <span class="s1">&#39;my-key&#39;</span><span class="p">,</span> <span class="mi">125</span>
279
- <span class="n">layout</span><span class="o">.</span><span class="n">add</span> <span class="s1">&#39;my-other-key&#39;</span><span class="p">,</span> <span class="s1">&#39;my-alias&#39;</span><span class="p">,</span> <span class="mi">126</span></pre>
280
- <h3>Remapping</h3>
281
- <p>Maps multiple key ids to a single key.</p>
282
- <pre class="highlight"><span class="n">layout</span><span class="o">[</span><span class="s1">&#39;lctrl&#39;</span><span class="o">].</span><span class="n">id</span> <span class="c1">#=&gt; 39</span>
283
- <span class="n">layout</span><span class="o">[</span><span class="mi">39</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:lctrl&gt;</span></pre>
284
- <p>remap from*, to</p>
285
- <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">remap</span> <span class="s1">&#39;lctrl&#39;</span><span class="p">,</span> <span class="s1">&#39;ctrl&#39;</span>
286
- <span class="n">layout</span><span class="o">[</span><span class="mi">39</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:ctrl&gt;</span></pre>
287
- <h3>Core modifiers</h3>
288
- <p>Core modifiers, unlike standard modifiers, are always passed on to the Operating System.<br />Shift, Ctrl, etc. are core modifiers.</p>
289
- <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">core_modifier</span> <span class="s1">&#39;escape&#39;</span> <span class="c1"># Sets a core modifier.</span></pre>
290
- </div>
291
- <div class="chapter">
292
- <a name="chapter_3"><h1>2. Hotkeys</h1></a>
293
-
294
- <h3>The basics</h3>
295
- <pre class="highlight"><span class="s1">&#39;modifiers hotkey&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span>
296
- <span class="s1">&#39;ctrl shift w&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">active_window</span><span class="o">.</span><span class="n">close</span> <span class="p">}</span>
297
- <span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> type <span class="s1">&#39;hello&#39;</span> <span class="p">}</span></pre>
298
- <p>The last statement can be abbreviated:</p>
299
- <pre class="highlight"><span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="s1">&#39;hello&#39;</span></pre>
300
- <h3>Hotkey conditions</h3>
301
- <p>Restrict hotkeys to trigger only when certain conditions are met.</p>
302
- <pre class="highlight"><span class="s1">&#39;hotkey&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">condition</span><span class="p">)</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span>
303
- <span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="nb">rand</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">)</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;win!&#39;</span> <span class="p">}</span></pre>
304
- <h3>Fuzzy hotkeys</h3>
305
- <p>The wildcard '*' forces a hotkey to trigger regardless of other modifiers being pressed.</p>
306
- <pre class="highlight"><span class="s1">&#39;* shift a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span> <span class="c1"># would be triggered by &#39;ctrl shift option a&#39;</span></pre>
307
- <p>Normal, non-fuzzy hotkeys take precedence over fuzzy hotkeys.</p>
308
- <h3>No-Repeat</h3>
309
- <p>Don't trigger on repetitive key-down events that are spawned when a key is held down for a certain time:</p>
310
- <pre class="highlight"><span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="ss">:no_repeat</span><span class="p">)</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span></pre>
311
- <h3>Modifier hotkeys</h3>
312
- <p>Hotkeys that consist solely of modifiers.</p>
313
- <pre class="highlight"><span class="s1">&#39;ctrl&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span>
314
- <span class="s1">&#39;ctrl shift&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span></pre>
315
- <p>The modifiers used in modifier-only hotkeys can be part of another hotkey.<br />In this case, modifier hotkeys trigger on key-up and only when no other key has been pressed in the meantime.<br />Otherwise, they trigger instantly.<br /><br />Example, assuming 'caps' is a valid modifier:</p>
316
- <pre class="highlight"><span class="s1">&#39;caps&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span> <span class="c1"># Hotkey 1) - Triggers on key-down.</span>
317
- <span class="s1">&#39;caps a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span><span class="p">}</span> <span class="c1"># Hotkey 2) - Conflicting hotkey.</span>
318
- <span class="c1"># Forces hotkey 1) to now trigger on key-up.</span></pre>
319
- <h3>Translations</h3>
320
- <p>Translations allow keys or key combinations to act as another key.</p>
321
- <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;up&#39;</span> <span class="c1"># &#39;up&#39; is pressed as soon as &#39;ctrl a&#39; is pressed.</span>
322
- <span class="c1"># &#39;up&#39; is released when either &#39;ctrl&#39; or &#39;a&#39; are released.</span></pre>
323
- <p>Translations are usually combined with fuzzy hotkeys</p>
324
- <pre class="highlight"><span class="s1">&#39;* ctrl a&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;up&#39;</span> <span class="c1"># would be triggered by e.g. &#39;ctrl shift a&#39;</span></pre>
325
- <p>Example: Move the 'up' and 'down' cursor keys to the home row</p>
326
- <pre class="highlight"><span class="s1">&#39;* caps j&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;down&#39;</span>
327
- <span class="s1">&#39;* caps k&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;up&#39;</span></pre>
328
- <h3>Unregistering and re-registering hotkeys</h3>
329
- <p>All methods concerned with registering or unregistering hotkeys return actions that can be, again, registered or unregistered.</p>
330
- <pre class="highlight"><span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">do_stuff</span> <span class="p">}</span> <span class="c1">#=&gt; #&lt;Rum::Action...&gt;</span>
331
- <span class="n">action</span><span class="o">.</span><span class="n">unregister</span> <span class="c1">#=&gt; #&lt;Rum::Action...&gt;</span>
332
- <span class="n">action</span><span class="o">.</span><span class="n">register</span> <span class="c1">#=&gt; #&lt;Rum::Action...&gt;</span></pre>
333
- <p>Unregistering the conditionless action of a hotkey</p>
334
- <pre class="highlight"><span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">unregister</span></pre>
335
- <p>Actions with conditions...</p>
336
- <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">condition</span><span class="p">)</span> <span class="p">{</span> <span class="n">do_stuff</span> <span class="p">}</span></pre>
337
- <p>... can't be unregistered this way</p>
338
- </div>
339
- <div class="chapter">
340
- <a name="chapter_4"><h1>3. Keyboard</h1></a>
341
-
342
- <h2>Caveat: Not yet available on the Mac.</h2>
343
- <p>Generates keystrokes.</p>
344
- <pre class="highlight"><span class="no">Keyboard</span><span class="o">.</span><span class="n">type</span> <span class="s1">&#39;hi&#39;</span></pre>
345
- <p>The 'Keyboard.' prefix can be omitted.</p>
346
- <pre class="highlight">type <span class="s1">&#39;hello world&#39;</span></pre>
347
- <p>Some keys have multi-character names or aliases.<br />Wrap them in parentheses.</p>
348
- <pre class="highlight">type <span class="s1">&#39;foo(tab)bar&#39;</span></pre>
349
- <p>Pause for a short while between sending characters.</p>
350
- <pre class="highlight">type <span class="s1">&#39;hello&#39;</span><span class="p">,</span> <span class="ss">:slow</span></pre>
351
- <h3>Sending key combinations</h3>
352
- <p>To send key combinations, enclose multiple keys within parentheses and nest them. (S-expressions!)</p>
353
- <pre class="highlight">type <span class="s1">&#39;(ctrl (shift hi))&#39;</span> <span class="c1"># sends ctrl-down, shift-down, hi, shift-up, ctrl-up</span></pre>
354
- <p>Backslash (\) acts as an escape character</p>
355
- <pre class="highlight">type <span class="s1">&#39;\(&#39;</span> <span class="c1"># sends a (</span></pre>
356
- <h3>Send string literally, without syntax interpretation</h3>
357
- <pre class="highlight">type<span class="o">!</span> <span class="s1">&#39;(in brackets)&#39;</span></pre>
358
- <h3>Translations</h3>
359
- <p>Some keys are translated into key combinations.</p>
360
- <pre class="highlight">type <span class="s1">&#39;A&#39;</span> <span class="c1"># sends &#39;(shift a)&#39;</span></pre>
361
- <p>See Rum.layout.translations</p>
362
- <h3>Sending single keyboard events</h3>
363
- <pre class="highlight"><span class="no">System</span><span class="o">.</span><span class="n">keydown</span> <span class="s1">&#39;a&#39;</span>
364
- <span class="no">System</span><span class="o">.</span><span class="n">keyup</span> <span class="s1">&#39;a&#39;</span></pre>
365
- <p>In a future release, this might be integrated into the main keyboard syntax, like:</p>
366
- <pre class="highlight">type <span class="s1">&#39;(keydown a)&#39;</span></pre>
367
- <h3>Auto-release</h3>
368
- <p>Pressed core modifiers are released before keyboard input is generated.<br />You can safely do the following:</p>
369
- <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> type <span class="s1">&#39;w&#39;</span> <span class="p">}</span> <span class="c1"># &#39;ctrl&#39; gets released before &#39;w&#39; is sent.</span></pre>
370
- <p>Provide the :blind flag to bypass auto-releasing</p>
371
- <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> type <span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="ss">:blind</span> <span class="p">}</span> <span class="c1"># &#39;ctrl&#39; might still be pressed when &#39;w&#39; is sent.</span></pre>
372
- <h3>Windows-specific: Extended keys</h3>
373
- <p>Sends 'alt' with the 'extended' flag set.</p>
374
- <pre class="highlight">type <span class="s1">&#39;(alt-extended)&#39;</span></pre>
375
- </div>
376
- <div class="chapter">
377
- <a name="chapter_5"><h1>3. Gui</h1></a>
378
-
379
- <h3>Messages</h3>
380
- <p>Prints a non-disruptive notification when Growl is enabled, falls back to alert (see below) otherwise</p>
381
- <pre class="highlight"><span class="n">message</span> <span class="s1">&#39;text&#39;</span>
382
- <span class="n">message</span> <span class="s1">&#39;text&#39;</span><span class="p">,</span> <span class="s1">&#39;title&#39;</span></pre>
383
- <p>Sticky: Keep the message from fading out after a few seconds</p>
384
- <pre class="highlight"><span class="n">message</span> <span class="s1">&#39;hello&#39;</span><span class="p">,</span> <span class="ss">:sticky</span></pre>
385
- <p>Callback: Do something when the user clicked on the message</p>
386
- <pre class="highlight"><span class="n">message</span><span class="p">(</span><span class="s1">&#39;click me&#39;</span><span class="p">)</span> <span class="p">{</span> <span class="n">message</span> <span class="s1">&#39;clicked!&#39;</span> <span class="p">}</span></pre>
387
- <h3>Alerts</h3>
388
- <p>Shows a focus-stealing 'ok, cancel' message box, prompting for a response</p>
389
- <pre class="highlight"><span class="n">alert</span> <span class="s1">&#39;message&#39;</span> <span class="c1"># returns true or false</span>
390
- <span class="n">alert</span> <span class="s1">&#39;message&#39;</span><span class="p">,</span> <span class="s1">&#39;title&#39;</span></pre>
391
- <h3>Input boxes</h3>
392
- <pre class="highlight"><span class="n">read</span> <span class="c1"># returns the response or an empty string</span>
393
- <span class="n">read</span> <span class="s1">&#39;hi, how are you?&#39;</span>
394
- <span class="n">read</span> <span class="n">default</span><span class="p">:</span> <span class="s1">&#39;default input&#39;</span>
395
- <span class="n">read</span> <span class="s1">&#39;hi, how are you?&#39;</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="s1">&#39;splendid&#39;</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="s1">&#39;greeting&#39;</span></pre>
396
- <h3>Choose from candidates</h3>
397
- <p>This one should launch a quicksilver-like fuzzy selection Gui.</p>
398
- <pre class="highlight"><span class="n">choose</span> <span class="s1">&#39;choose one&#39;</span><span class="p">,</span> <span class="o">[</span><span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="s1">&#39;blue&#39;</span><span class="p">,</span> <span class="s1">&#39;yellow&#39;</span><span class="o">]</span></pre>
399
- <p>TODO: Currently this is only supported via Emacs/Ido.<br />Falls back to an ugly combobox for non Emacs users.<br />Which selection GUIs are there already on the Mac and on Windows that could be harnessed?<br /><br />TODO: Emacs</p>
400
- <pre class="highlight"><span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Gui</span><span class="o">::</span><span class="no">EmacsInteraction</span></pre>
401
- <h3>Open (text) files</h3>
402
- <pre class="highlight"><span class="n">open_file</span> <span class="n">path</span></pre>
403
- <p>Using a text editor ...</p>
404
- <pre class="highlight"><span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Textmate</span><span class="p">,</span> <span class="ss">:open_file</span>
405
- <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Emacs</span><span class="p">,</span> <span class="ss">:open_file</span></pre>
406
- <p>... enables jumping to a specific line</p>
407
- <pre class="highlight"><span class="n">open_file</span> <span class="s1">&#39;foo.txt&#39;</span><span class="p">,</span> <span class="mi">24</span></pre>
408
- <p>You may re-define open_file to fit your specific needs.</p>
409
- <h3>Open URLs</h3>
410
- <pre class="highlight"><span class="n">browse</span> <span class="s1">&#39;example.com&#39;</span> <span class="c1"># HTTP is implicit, unless another protocol is specified</span></pre>
411
- <h3>Show directories or files in your file manager</h3>
412
- <pre class="highlight"><span class="n">goto</span> <span class="s1">&#39;foo&#39;</span></pre>
413
- <h3>Gui Module</h3>
414
- <p>The above methods are part of the Gui module and may also be called explicitly:</p>
415
- <pre class="highlight"><span class="no">Gui</span><span class="o">.</span><span class="n">message</span>
416
- <span class="no">Gui</span><span class="o">.</span><span class="n">read</span>
417
- <span class="o">.</span><span class="n">.</span><span class="o">.</span></pre>
418
- </div>
419
- <div class="chapter">
420
- <a name="chapter_6"><h1>4. Get selected text</h1></a>
421
-
422
- <h2>Caveat: Not yet available on the Mac.</h2>
423
- <p>Grabs the currently selected text.</p>
424
- <pre class="highlight"><span class="n">get_selection</span> <span class="c1"># returns the current selection or nil</span></pre>
425
- </div>
426
- <div class="chapter">
427
- <a name="chapter_7"><h1>5. Clipboard</h1></a>
428
-
429
- <h2>Caveat: Not yet available on the Mac.</h2>
430
- <p>Retrieves the clipboard contents as text.</p>
431
- <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1"># Always returns a string</span></pre>
432
- <p>Sets the clipboard.</p>
433
- <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">set</span> <span class="s1">&#39;hello&#39;</span></pre>
434
- <p>Sends a 'copy to clipboard' keyboard shortcut and waits until the clipboard changes.</p>
435
- <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">copy</span> <span class="c1"># returns true if successful</span></pre>
436
- <p>Sends a 'paste' keyboard shortcut.</p>
437
- <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">paste</span></pre>
438
- <p>Append the result of get_selection as a new line to the current clipboard content.</p>
439
- <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1">#=&gt; &quot;foo&quot;</span>
440
- <span class="no">Clipboard</span><span class="o">.</span><span class="n">append</span>
441
- <span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1">#=&gt; &quot;foo\nbar&quot;, assuming &#39;bar&#39; was selected.</span></pre>
442
- <p>Run a block while preserving the clipboard contents.</p>
443
- <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">set</span> <span class="s1">&#39;foo&#39;</span>
444
- <span class="no">Clipboard</span><span class="o">.</span><span class="n">preserve</span> <span class="p">{</span> <span class="no">Clipboard</span><span class="o">.</span><span class="n">set</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span>
445
- <span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1">#=&gt; &quot;foo&quot;</span></pre>
446
- </div>
447
- <div class="chapter">
448
- <a name="chapter_8"><h1>6. More methods</h1></a>
449
-
450
- <h3>Waiting</h3>
451
- <p>Wait until condition is true. Times out after 5 seconds, updates every 0.01 seconds.</p>
452
- <pre class="highlight"><span class="n">wait</span> <span class="p">{</span> <span class="n">condition</span> <span class="p">}</span> <span class="c1">#=&gt; False when timed-out. Otherwise: true</span></pre>
453
- <p>Set a 10 second timeout and a 0.5 second update interval.</p>
454
- <pre class="highlight"><span class="n">wait</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="o">.</span><span class="mi">5</span><span class="p">)</span> <span class="p">{</span> <span class="n">my_window</span><span class="o">.</span><span class="n">active?</span> <span class="p">}</span></pre>
455
- <h3>Run a command in a separate terminal window.</h3>
456
- <pre class="highlight"><span class="n">spawn_in_terminal</span> <span class="n">command</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span>
457
- <span class="n">spawn_in_terminal</span> <span class="s1">&#39;ruby&#39;</span><span class="p">,</span> <span class="s1">&#39;-e&#39;</span><span class="p">,</span> <span class="s1">&#39;puts Time.now&#39;</span></pre>
458
- <p>Close the window if the command exits without errors.</p>
459
- <pre class="highlight"><span class="n">spawn_in_terminal</span> <span class="s1">&#39;ruby&#39;</span><span class="p">,</span> <span class="s1">&#39;-e&#39;</span><span class="p">,</span> <span class="s1">&#39;puts &quot;Hello!&quot;; sleep 2&#39;</span><span class="p">,</span> <span class="ss">:close_if_successful</span></pre>
460
- <h3>Open documents, run programs</h3>
461
- <p>Wraps the 'open' command on the Mac and ShellExecute on Windows.</p>
462
- <pre class="highlight"><span class="n">start</span> <span class="n">file</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span></pre>
463
- <h3>Applescript</h3>
464
- <pre class="highlight"><span class="n">applescript</span> <span class="s1">&#39;tell application &quot;System Events&quot;</span>
465
- <span class="s1"> activate</span>
466
- <span class="s1"> display dialog &quot;Hello!&quot;</span>
467
- <span class="s1"> end tell&#39;</span></pre>
468
- <p>The last three methods are part of the System module and may be called explicitly:</p>
469
- <pre class="highlight"><span class="no">System</span><span class="o">.</span><span class="n">spawn_in_terminal</span>
470
- <span class="no">System</span><span class="o">.</span><span class="n">start</span>
471
- <span class="no">System</span><span class="o">.</span><span class="n">applescript</span></pre>
472
- </div>
473
- <div class="chapter">
474
- <a name="chapter_9"><h1>6. Rum's threading model</h1></a>
475
-
476
- <p>Rum employs one worker thread that executes all hotkey actions sequentially.<br />Errors during execution are automatically reported via Gui.message.<br /><br />If you have a long running action that may run in parallel with other actions call 'Rum.switch_worker_thread'. Action execution is then resumed on another thread.</p>
477
- <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">switch_worker_thread</span><span class="p">;</span> <span class="n">long_running_stuff</span> <span class="p">}</span></pre>
478
- <p>The following is also possible...</p>
479
- <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Thread</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="n">long_running_stuff</span> <span class="p">}</span> <span class="p">}</span></pre>
480
- <p>... but errors in 'long_running_stuff' won't be implicitly caught and reported by Rum.<br /><br />When you call Gui.read, Gui.alert or Gui.print then Rum.switch_worker_thread is automatically run.</p>
481
- </div>
482
- <div class="chapter">
483
- <a name="chapter_10"><h1>5. Help, introspection</h1></a>
484
-
485
- <p>Prompts you to enter a hotkey and then jumps to its definition via Gui.open_file.</p>
486
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">show_hotkey</span></pre>
487
- <p>(Requires you to register your text-editor, see Gui.open_file above.)<br /><br />Asks you to enter an arbitrary hotkey and inserts a hotkey definition snippet via Keyboard.type.<br />When 'shift a' is pressed, 'shift a'.do { } is inserted.</p>
488
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">snippet</span></pre>
489
- <p>Reads a hotkey and passes it to the block.<br />(Internally used by Rum.snippet)</p>
490
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">read_key</span> <span class="p">{</span> <span class="o">|</span><span class="n">hotkey</span><span class="o">|</span> <span class="n">do_stuff_with</span> <span class="n">hotkey</span> <span class="p">}</span></pre>
491
- <p>Shows information about windows as they become active.</p>
492
- <pre class="highlight"><span class="no">WindowInfo</span><span class="o">.</span><span class="n">start</span></pre>
493
- <p>Opens this reference in a text editor</p>
494
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">reference</span></pre>
495
- </div>
496
- <div class="chapter">
497
- <a name="chapter_11"><h1>5. Restarting, server</h1></a>
498
-
499
- <p>Restart the current Rum configuration.</p>
500
- <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">restart</span></pre>
501
- <p>Start the server. This allows for connections to the Rum process via rum-client.</p>
502
- <pre class="highlight"><span class="no">Rum</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">start</span></pre>
503
- </div>
504
- <div class="chapter">
505
- <a name="chapter_12"><h1>6. Windows</h1></a>
506
-
507
- <h2>Caveat: Not yet available on the Mac.</h2>
508
- <h3>Retrieving windows</h3>
509
- <pre class="highlight"><span class="n">active_window</span> <span class="c1">#=&gt; #&lt;Rum::System::Window...&gt;</span></pre>
510
- <p>Traversing all active windows:</p>
511
- <pre class="highlight"><span class="n">active_windows</span> <span class="c1">#=&gt; #&lt;Enumerator:...&gt;</span>
512
- <span class="n">active_windows</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">window</span><span class="o">|</span> <span class="n">window</span><span class="o">.</span><span class="n">close</span> <span class="k">if</span> <span class="n">window</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">empty?</span> <span class="p">}</span>
513
- <span class="n">active_windows</span><span class="o">.</span><span class="n">map</span> <span class="o">&amp;</span><span class="ss">:title</span></pre>
514
- <h3>Window Matchers</h3>
515
- <p>WindowMatchers serve as a shorthand for using active_windows.find:</p>
516
- <pre class="highlight"><span class="n">matcher</span> <span class="o">=</span> <span class="no">Window</span><span class="o">[</span><span class="n">title</span><span class="p">:</span><span class="sr"> /ruby/</span><span class="p">,</span> <span class="n">class_name</span><span class="p">:</span> <span class="s1">&#39;MozillaUIWindowClass&#39;</span><span class="o">]</span></pre>
517
- <p>or shorter:</p>
518
- <pre class="highlight"><span class="n">matcher</span> <span class="o">=</span> <span class="no">Window</span><span class="o">[/</span><span class="n">ruby</span><span class="o">/</span><span class="p">,</span> <span class="s1">&#39;MozillaUIWindowClass&#39;</span><span class="o">]</span>
519
- <span class="n">matcher</span> <span class="c1">#=&gt; #&lt;Rum::System::WindowMatcher...&gt;</span>
520
- <span class="n">matcher</span><span class="o">.</span><span class="n">find</span> <span class="c1">#=&gt; #&lt;Rum::System::Window...&gt;</span>
521
- <span class="no">Window</span><span class="o">[</span><span class="n">class_name</span><span class="p">:</span> <span class="s1">&#39;Emacs&#39;</span><span class="o">].</span><span class="n">find</span></pre>
522
- <p>The first matching window is returned.<br />WindowMatcher attributes differ between platforms.<br />The Windows version shown here supports 'title' and 'class_name'.<br />String arguments are checked for equality with the corresponding window attributes, Regex arguments require a match.</p>
523
- <h3>Window objects</h3>
524
- <pre class="highlight"><span class="n">w</span> <span class="o">=</span> <span class="n">active_window</span> <span class="c1">#=&gt; #&lt;Rum::System::Window:...&gt;</span>
525
- <span class="n">w</span> <span class="o">==</span> <span class="n">active_window</span> <span class="c1">#=&gt; true</span>
526
- <span class="n">w</span><span class="o">.</span><span class="n">show</span> <span class="c1"># returns true if successful</span>
527
- <span class="n">w</span><span class="o">.</span><span class="n">minimize</span>
528
- <span class="n">w</span><span class="o">.</span><span class="n">maximize</span>
529
- <span class="n">w</span><span class="o">.</span><span class="n">toggle_always_on_top</span>
530
- <span class="n">w</span><span class="o">.</span><span class="n">title</span> <span class="c1">#=&gt; &quot;A window title&quot;</span>
531
- <span class="n">w</span><span class="o">.</span><span class="n">class_name</span> <span class="c1">#=&gt; &quot;Chrome_WidgetWin_0&quot;</span>
532
- <span class="n">w</span><span class="o">.</span><span class="n">close</span>
533
- <span class="n">w</span><span class="o">.</span><span class="n">kill_task</span> <span class="c1"># kills the task associated with the window</span></pre>
534
- </div>
535
- <div class="chapter">
536
- <a name="chapter_13"><h1>7. Apps</h1></a>
537
-
538
- <p>Integrates prominent applications into Rum.</p>
539
- <pre class="highlight">require <span class="s1">&#39;rum/apps&#39;</span></pre>
540
- <h3>App objects</h3>
541
- <pre class="highlight"><span class="n">app</span> <span class="o">=</span> <span class="no">Emacs</span> <span class="c1">#=&gt; #&lt;Rum::App:...&gt;</span></pre>
542
- <p>Start app or bring it to the front when it's already running.<br />This works for all apps.<br />Returns true when the app could be activated instantly.</p>
543
- <pre class="highlight"><span class="n">app</span><span class="o">.</span><span class="n">activate</span> <span class="c1">#=&gt; true</span></pre>
544
- <h3>Emacs</h3>
545
- <pre class="highlight"><span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(message &quot;hi&quot;)&#39;</span> <span class="c1">#=&gt; &quot;\&quot;hi\&quot;&quot;</span>
546
- <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(* 3 3)&#39;</span> <span class="c1">#=&gt; &quot;9&quot;</span></pre>
547
- <p>Eval in the current buffer context.</p>
548
- <pre class="highlight"><span class="no">Emacs</span><span class="o">.</span><span class="n">eval_in_user_buffer</span> <span class="o">=</span> <span class="kp">true</span>
549
- <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;default-directory&#39;</span> <span class="c1">#=&gt; &quot;~/current_buffer_dir/&quot;</span>
550
- <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(idle-highlight-mode t)&#39;</span> <span class="c1"># Turns on a minor mode in the current buffer.</span></pre>
551
- <p>Set this on Windows to allow Emacs.activate to start Emacs when it's not running.</p>
552
- <pre class="highlight"><span class="no">Emacs</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;path/to/runemacs&#39;</span></pre>
553
- </div>
554
- </div>
555
- <div id='development'>
556
- <a name='development'>
557
- <h1>Development</h1>
558
- </a>
559
- <p>
560
- Patches and suggestions are most appreciated.
561
- </p>
562
- <p>
563
- There's a <a href="https://github.com/nonsequitur/rum-dev/blob/master/rum-development.org">low-ceremony
564
- to-do list</a> to coordinate the development
565
- of larger-scale features.<br />
566
- Feel free to have a look if you're interested in contributing.
567
- </p>
568
- <h2>Building</h2>
569
- <p>
570
- <span class='code'>rake build</span>
571
- builds the extension and the document.
572
- </p>
573
- <p>
574
- <span class='code'>rake ext</span>
575
- builds just the extension.
576
- </p>
577
- <p>
578
- <span class='code'>rake doc</span>
579
- builds this document. Requires Pygments.
580
- </p>
581
- <h3>Mac specifics:</h3>
582
- <p>
583
- XCode required.
584
- </p>
585
- <h3>Windows specifics:</h3>
586
- <p>
587
- Visual Studio required. (Out-of-the-box MinGW support coming soon.)
588
- </p>
589
- <p>
590
- You need to setup the Visual Studio build environment before running the rake commands.<br />Call <span class="code">"%programfiles%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86</span> from your Windows terminal.
591
- </p>
592
- <p>
593
- You might have to delete the following lines from <span class="code">ruby_dir/include/ruby-1.9.x/i386-mswin32/ruby/config.h</span> to work around a compiler error:
594
- <pre>#if _MSC_VER != 1200
595
- #error MSC version unmatch: _MSC_VER: 1200 is expected.
596
- #endif</pre>
597
- </p>
598
- <div id='footer'></div>
599
- </div>
600
- </div>
601
- </body>
602
- </html>
1
+ <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
2
+ <head>
3
+ <title>Rum</title>
4
+ <meta content='text/html;charset=utf-8' http-equiv='Content-Type' />
5
+ <link href='resources/screen.css' media='screen' rel='stylesheet' type='text/css' />
6
+ <link href='resources/highlight.css' media='screen' rel='stylesheet' type='text/css' />
7
+ </head>
8
+ <body>
9
+ <a href='#'>
10
+ <img id='logo' src='resources/logo.png' />
11
+ </a>
12
+ <a href='https://github.com/nonsequitur/rum'>
13
+ <img alt='Fork me on GitHub' src='https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png' style='position: absolute; top: 0; right: 0; border: 0;' />
14
+ </a>
15
+ <div id='nav'>
16
+ <ul>
17
+ <li>
18
+ <a href='#'>Intro</a>
19
+ </li>
20
+ <li>
21
+ <a href='#installation'>Installation</a>
22
+ </li>
23
+ <li>
24
+ <a href='#coding'>Coding</a>
25
+ </li>
26
+ <li>
27
+ <a href='#example'>Example</a>
28
+ </li>
29
+ <li>
30
+ <a href='#reference'>Reference</a>
31
+ </li>
32
+ <li>
33
+ <a href='#development'>Development</a>
34
+ </li>
35
+ </ul>
36
+ </div>
37
+ <div id='wrapper'>
38
+ <div id='intro'>Rum is a cross-platform Hotkey and Macro utility, built in Ruby.<br />It runs on Windows and Mac OS.</div>
39
+ <img src='resources/screenshot.png' />
40
+ <div id='screenshot-sub'></div>
41
+ <div id='intro-code'>
42
+ <div id='top'></div>
43
+ <div id='content'>
44
+ <img id='flash' src='resources/flash.png' />
45
+ <div id='sshot-sub'>This snippet powers the above screenshot.</div>
46
+ <div class="highlight"><pre>require <span class="s1">&#39;rum&#39;</span>
47
+
48
+ <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;caps&#39;</span>
49
+ <span class="s1">&#39;caps&#39;</span><span class="o">.</span><span class="n">do</span> <span class="s1">&#39;(cmd (tab))&#39;</span>
50
+ <span class="s1">&#39;caps shift&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">active_window</span><span class="o">.</span><span class="n">close</span> <span class="p">}</span>
51
+
52
+ require <span class="s1">&#39;rum/apps&#39;</span>
53
+ <span class="s1">&#39;caps h&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;Hello from Rum!&#39;</span> <span class="p">}</span>
54
+ <span class="s1">&#39;caps p&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Photoshop</span><span class="o">.</span><span class="n">activate</span> <span class="p">}</span>
55
+ <span class="s1">&#39;caps down&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="no">Photoshop</span><span class="p">)</span> <span class="p">{</span> <span class="no">Photoshop</span><span class="o">.</span><span class="n">next_blend_mode</span> <span class="p">}</span>
56
+ <span class="s1">&#39;caps b&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Chrome</span><span class="o">.</span><span class="n">activate_and_focus_address_bar</span> <span class="p">}</span>
57
+ <span class="s1">&#39;caps s&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(slime-repl)&#39;</span><span class="p">;</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">activate</span> <span class="p">}</span>
58
+ <span class="s1">&#39;caps c&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Clipboard</span><span class="o">.</span><span class="n">append</span> <span class="p">}</span>
59
+ <span class="s1">&#39;ctrl shift h&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">type</span> <span class="s1">&#39;hi&#39;</span> <span class="p">}</span>
60
+ <span class="c1"># Caveat: Some hotkey actions are not yet available on the Mac.</span>
61
+
62
+ <span class="no">Rum</span><span class="o">.</span><span class="n">start</span>
63
+ </pre></div>
64
+
65
+ </div>
66
+ <div id='bottom'></div>
67
+ <div id='intro-code-sub'>Rum configuration files are regular Ruby scripts, like the above.<br /> Running Rum is as easy as calling <span class="code">ruby my_rum_config_file.rb</span> from the command line.<br />(Or <span class="code">macruby -rubygems my_rum_config_file.rb</span> on the Mac.)</div>
68
+ </div>
69
+ <div id='guide'>
70
+ <div id='installation'>
71
+ <a name='installation'>
72
+ <h1>Installation</h1>
73
+ </a>
74
+ <div id='gem'>
75
+ <div id='regulargem'>
76
+ <span class='code'>gem install rum</span>
77
+ </div>
78
+ <div id='macgem'>
79
+ <span class='code'>macgem install rum</span>
80
+ <div>
81
+ </div>
82
+ </div>
83
+ <div class='clear'></div>
84
+ </div>
85
+ <p id='current_version'>
86
+ Current version:
87
+ 0.0.2
88
+ <span id='changelog'>(<a href="https://github.com/nonsequitur/rum/blob/master/CHANGELOG">Changelog</a>)</span>
89
+ </p>
90
+ <div id='platforms'>
91
+ <h3>Supported platforms</h3>
92
+ <ul>
93
+ <li>Mac OS X >= 10.7 – MacRuby >=0.10.<br /></li>
94
+ <li>
95
+ 32-bit Windows XP/Vista/7 – Ruby >=1.9.1p378.<br />
96
+ </li>
97
+ </ul>
98
+ </div>
99
+ <div id='growl'>
100
+ <h2>Recommended: Growl</h2>
101
+ <ul>
102
+ <li>Get Growl: <a href="http://growl.info/">Mac</a>, <a href="http://www.growlforwindows.com/gfw/">Windows</a></li>
103
+ <li>To use Growl in Rum: Add <span class="code">Gui.use Gui::Growl</span> to your Rum config.</li>
104
+ </ul>
105
+ <div id='growl-explanation'>
106
+ <h3>Why Growl?</h3>
107
+ Notification bubbles are a convenient alternative to focus-stealing message boxes.
108
+ Some higher level Rum methods only work smoothly with Growl-style notifications.
109
+ Currently, Growl is the only notification system supported by Rum.
110
+ </div>
111
+ </div>
112
+ </div>
113
+ <div id='coding'>
114
+ <a name='coding'>
115
+ <h1>Coding in Rum</h1>
116
+ </a>
117
+ Rum encourages an interactive approach to coding and a fast code-and-feedback cycle.
118
+ <h2>Core techniques</h2>
119
+ <ul id='core-techniques'>
120
+ <li>
121
+ <h3>rum-client REPL</h3>
122
+ <p>Add <span class="code">Rum::Server.start</span> to your Rum config.</p>
123
+ <p>Call <span class="code">rum-client -i</span> from the command line to start an IRB-session inside a running Rum instance. IRB Completion is fully supported.</p>
124
+ <p>Nearly all snippets in this guide can be evaluated interactively.</p>
125
+ <p>Set the environment variable <span class="code">RUM_PORT</span> to change the port on which client and server connect.</p>
126
+ <p>
127
+ <h3>rum-client in emacs:</h3>
128
+ <ul>
129
+ <li>Get the latest Inf-Ruby via <a href="http://marmalade-repo.org/packages/inf-ruby">ELPA</a></li>
130
+ <li>
131
+ Add the following to your Emacs config:
132
+ <pre id='inf_ruby_setup'>(add-to-list 'inf-ruby-implementations
133
+ '("rum-client" . "rum-client -i --inf-ruby-mode")
134
+ (defun rum-client ()
135
+ (interactive)
136
+ (inf-ruby "rum-client")))
137
+ </pre>
138
+ </li>
139
+ <li>
140
+ Run <span class="code">M-x rum-client</span>
141
+ </li>
142
+ </ul>
143
+ <div id='auto-completion'>
144
+ <h4>Auto-completion</h4>
145
+ <img id='auto-completion' src='resources/emacs-auto-completion.png' />
146
+ <p>
147
+ Company-Mode features auto-completion for IRB sessions.<br />
148
+ <a href="http://www.emacswiki.org/emacs/InfRubyCompany">See here for installation instructions</a>.
149
+ </p>
150
+ </div>
151
+ </p>
152
+ </li>
153
+ <li>
154
+ <h3>Rum.restart</h3>
155
+ Restarts Rum.
156
+ Bind it to a key, like <span class="code">'shift f1'.do { Rum.restart }</span>
157
+ </li>
158
+ </ul>
159
+ Run Rum with this basic, REPL-enabled setup to get started:
160
+ <div id='basic'><div class="highlight"><pre>require <span class="s1">&#39;rum&#39;</span>
161
+
162
+ <span class="s1">&#39;shift f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">restart</span> <span class="p">}</span>
163
+
164
+ <span class="c1"># If you use Emacs</span>
165
+ require <span class="s1">&#39;rum/apps&#39;</span>
166
+ <span class="s1">&#39;shift f2&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(rum-client)&#39;</span><span class="p">;</span> <span class="no">Emacs</span><span class="o">.</span><span class="n">activate</span> <span class="p">}</span>
167
+
168
+ <span class="no">Rum</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">start</span>
169
+ <span class="no">Rum</span><span class="o">.</span><span class="n">start</span>
170
+ </pre></div>
171
+ </div>
172
+ <div id='example'>
173
+ <a name='example'>
174
+ <h1>Extended Example</h1>
175
+ </a>
176
+ <div class="highlight"><pre><span class="c1">## A short survey of the main features</span>
177
+ <span class="c1">## This file can be found at rum_dir/doc/example.rb</span>
178
+
179
+ require <span class="s1">&#39;rum&#39;</span>
180
+
181
+ <span class="c1"># 1. Set up additional modifiers that can then</span>
182
+ <span class="c1"># be used in hotkey definitions.</span>
183
+ <span class="c1"># Any key can be a modifier</span>
184
+ <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;caps&#39;</span>
185
+ <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;escape&#39;</span>
186
+
187
+ <span class="c1"># 2. Hotkey definitions</span>
188
+ <span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;foo&#39;</span> <span class="p">}</span>
189
+ <span class="c1"># Hotkeys may consist solely of modifiers</span>
190
+ <span class="s1">&#39;caps&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span>
191
+ <span class="s1">&#39;caps ctrl&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span>
192
+ <span class="c1"># Hotkey conditions</span>
193
+ <span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="nb">rand</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">)</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;win!&#39;</span> <span class="p">}</span>
194
+ <span class="c1"># Fuzzy hotkeys, trigger regardless of other modifiers being pressed</span>
195
+ <span class="s1">&#39;* ctrl b&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;hi&#39;</span> <span class="p">}</span>
196
+ <span class="c1"># Translations</span>
197
+ <span class="s1">&#39;* caps j&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;down&#39;</span>
198
+
199
+ <span class="c1"># 3. Gui</span>
200
+ <span class="n">message</span> <span class="s1">&#39;message&#39;</span>
201
+ <span class="n">read</span> <span class="s1">&#39;hi, how are you?&#39;</span> <span class="c1"># Input box</span>
202
+
203
+ <span class="c1"># 4. Keyboard, send keypresses</span>
204
+ <span class="n">type</span> <span class="s1">&#39;hello&#39;</span>
205
+ <span class="n">type</span> <span class="s1">&#39;(ctrl (shift a))&#39;</span> <span class="c1"># Key combinations</span>
206
+
207
+ <span class="c1"># 5. Help and introspection</span>
208
+ <span class="c1"># Prompts you to enter a hotkey and then jumps to its</span>
209
+ <span class="c1"># definition in your text editor.</span>
210
+ <span class="s1">&#39;shift f2&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">visit_hotkey</span> <span class="p">}</span>
211
+
212
+ <span class="c1"># Asks you to enter an arbitrary hotkey and inserts a hotkey</span>
213
+ <span class="c1"># definition snippet.</span>
214
+ <span class="s1">&#39;shift f3&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">snippet</span> <span class="p">}</span>
215
+
216
+ <span class="c1"># Restarts Rum.</span>
217
+ <span class="s1">&#39;shift f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">restart</span> <span class="p">}</span>
218
+
219
+
220
+ <span class="c1"># 6. Integrate external features</span>
221
+ <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Gui</span><span class="o">::</span><span class="no">Growl</span>
222
+
223
+ <span class="c1"># Set up a text-editor for opening files</span>
224
+ require <span class="s1">&#39;rum/apps&#39;</span>
225
+ <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Textmate</span><span class="p">,</span> <span class="ss">:open_file</span>
226
+ <span class="c1"># Or</span>
227
+ <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Emacs</span><span class="p">,</span> <span class="ss">:open_file</span>
228
+
229
+ <span class="c1"># 7. Start the server. You can now connect to the</span>
230
+ <span class="c1"># Rum process via rum-client.</span>
231
+ <span class="no">Rum</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">start</span>
232
+
233
+ <span class="c1"># 8. Start rum</span>
234
+ <span class="no">Rum</span><span class="o">.</span><span class="n">start</span>
235
+ </pre></div>
236
+
237
+ </div>
238
+ <a name='reference'>
239
+ <h1>Reference</h1>
240
+ </a>
241
+ <p>
242
+ This section is also available as a Ruby source file and can be
243
+ conveniently viewed in a text editor.<br />
244
+ Call <span class="code">Rum.reference</span> or manually open
245
+ <span class="code">rum_dir/doc/reference.rb</span>.
246
+ </p>
247
+ </div>
248
+ </div>
249
+ <div id='reference_wrapper'><div id="table_of_contents"><h1>Chapters</h1><ul><li><a href="#chapter_1">1. Unicode</a></li><li><a href="#chapter_2">2. Layouts</a></li><li><a href="#chapter_3">3. Hotkeys</a></li><li><a href="#chapter_4">4. Keyboard</a></li><li><a href="#chapter_5">5. Gui</a></li><li><a href="#chapter_6">6. Get selected text</a></li><li><a href="#chapter_7">7. Clipboard</a></li><li><a href="#chapter_8">8. More methods</a></li><li><a href="#chapter_9">9. Rum's threading model</a></li><li><a href="#chapter_10">10. Help, introspection</a></li><li><a href="#chapter_11">11. Restarting, server</a></li><li><a href="#chapter_12">12. Windows</a></li><li><a href="#chapter_13">13. Apps</a></li></ul></div>
250
+ <div class="chapter">
251
+ <a name="chapter_1"><h1>1. Unicode</h1></a>
252
+
253
+ <p>Rum is unicode-compatible. The default encoding is UTF-8.</p>
254
+ </div>
255
+ <div class="chapter">
256
+ <a name="chapter_2"><h1>2. Layouts</h1></a>
257
+
258
+ <p>Keyboard layout changes must take place before any hotkey definitions.<br /><br />Rum starts with a default QWERTY layout</p>
259
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">layout</span> <span class="c1">#=&gt; #&lt;Rum::Layout:0xb99634 ... &gt;</span></pre>
260
+ <p>Changing the layout</p>
261
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">layout</span> <span class="o">=</span> <span class="no">Layouts</span><span class="o">.</span><span class="n">german</span></pre>
262
+ <p>Listing available layouts</p>
263
+ <pre class="highlight"><span class="no">Layouts</span><span class="o">.</span><span class="n">list</span></pre>
264
+ <h2>Editing a layout</h2>
265
+ <pre class="highlight"><span class="n">layout</span> <span class="o">=</span> <span class="no">Rum</span><span class="o">.</span><span class="n">layout</span></pre>
266
+ <h3>Adding a modifier.</h3>
267
+ <p>Any key can be a modifier.</p>
268
+ <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">modifier</span> <span class="s1">&#39;escape&#39;</span></pre>
269
+ <h3>Aliasing</h3>
270
+ <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">alias</span> <span class="s1">&#39;escape&#39;</span><span class="p">,</span> <span class="s1">&#39;esc&#39;</span></pre>
271
+ <p>The original key...</p>
272
+ <pre class="highlight"><span class="n">layout</span><span class="o">[</span><span class="s1">&#39;escape&#39;</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:escape&gt;</span></pre>
273
+ <p>...can now be referenced by the alias</p>
274
+ <pre class="highlight"><span class="n">layout</span><span class="o">[</span><span class="s1">&#39;esc&#39;</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:escape&gt;</span></pre>
275
+ <h3>Renaming</h3>
276
+ <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">rename</span> <span class="s1">&#39;escape&#39;</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span>
277
+ <span class="n">layout</span><span class="o">[</span><span class="s1">&#39;foo&#39;</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:foo&gt;</span></pre>
278
+ <h3>Finding out the name of a key</h3>
279
+ <p>All keyboard activity is reported at the terminal.<br />Switch to the Rum terminal window and press a key.</p>
280
+ <h2>Advanced</h2>
281
+ <h3>Adding a key</h3>
282
+ <p>add name, *aliases, id</p>
283
+ <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">add</span> <span class="s1">&#39;my-key&#39;</span><span class="p">,</span> <span class="mi">125</span>
284
+ <span class="n">layout</span><span class="o">.</span><span class="n">add</span> <span class="s1">&#39;my-other-key&#39;</span><span class="p">,</span> <span class="s1">&#39;my-alias&#39;</span><span class="p">,</span> <span class="mi">126</span></pre>
285
+ <h3>Remapping</h3>
286
+ <p>Maps multiple key ids to a single key.</p>
287
+ <pre class="highlight"><span class="n">layout</span><span class="o">[</span><span class="s1">&#39;lctrl&#39;</span><span class="o">].</span><span class="n">id</span> <span class="c1">#=&gt; 39</span>
288
+ <span class="n">layout</span><span class="o">[</span><span class="mi">39</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:lctrl&gt;</span></pre>
289
+ <p>remap from*, to</p>
290
+ <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">remap</span> <span class="s1">&#39;lctrl&#39;</span><span class="p">,</span> <span class="s1">&#39;ctrl&#39;</span>
291
+ <span class="n">layout</span><span class="o">[</span><span class="mi">39</span><span class="o">]</span> <span class="c1">#=&gt; #&lt;Key:ctrl&gt;</span></pre>
292
+ <h3>Core modifiers</h3>
293
+ <p>Core modifiers, unlike standard modifiers, are always passed on to the Operating System.<br />Shift, Ctrl, etc. are core modifiers.</p>
294
+ <pre class="highlight"><span class="n">layout</span><span class="o">.</span><span class="n">core_modifier</span> <span class="s1">&#39;escape&#39;</span> <span class="c1"># Sets a core modifier.</span></pre>
295
+ </div>
296
+ <div class="chapter">
297
+ <a name="chapter_3"><h1>3. Hotkeys</h1></a>
298
+
299
+ <h3>The basics</h3>
300
+ <pre class="highlight"><span class="s1">&#39;modifiers hotkey&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span>
301
+ <span class="s1">&#39;ctrl shift w&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">active_window</span><span class="o">.</span><span class="n">close</span> <span class="p">}</span>
302
+ <span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">type</span> <span class="s1">&#39;hello&#39;</span> <span class="p">}</span></pre>
303
+ <p>The last statement can be abbreviated:</p>
304
+ <pre class="highlight"><span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span> <span class="s1">&#39;hello&#39;</span></pre>
305
+ <h3>Hotkey conditions</h3>
306
+ <p>Restrict hotkeys to trigger only when certain conditions are met.</p>
307
+ <pre class="highlight"><span class="s1">&#39;hotkey&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">condition</span><span class="p">)</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span>
308
+ <span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="nb">rand</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">)</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s1">&#39;win!&#39;</span> <span class="p">}</span></pre>
309
+ <h3>Fuzzy hotkeys</h3>
310
+ <p>The wildcard '*' forces a hotkey to trigger regardless of other modifiers being pressed.</p>
311
+ <pre class="highlight"><span class="s1">&#39;* shift a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span> <span class="c1"># would be triggered by &#39;ctrl shift option a&#39;</span></pre>
312
+ <p>Normal, non-fuzzy hotkeys take precedence over fuzzy hotkeys.</p>
313
+ <h3>No-Repeat</h3>
314
+ <p>Don't trigger on repetitive key-down events that are spawned when a key is held down for a certain time:</p>
315
+ <pre class="highlight"><span class="s1">&#39;f1&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="ss">:no_repeat</span><span class="p">)</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span></pre>
316
+ <h3>Modifier hotkeys</h3>
317
+ <p>Hotkeys that consist solely of modifiers.</p>
318
+ <pre class="highlight"><span class="s1">&#39;ctrl&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span>
319
+ <span class="s1">&#39;ctrl shift&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span></pre>
320
+ <p>The modifiers used in modifier-only hotkeys can be part of another hotkey.<br />In this case, modifier hotkeys trigger on key-up and only when no other key has been pressed in the meantime.<br />Otherwise, they trigger instantly.<br /><br />Example, assuming 'caps' is a valid modifier:</p>
321
+ <pre class="highlight"><span class="s1">&#39;caps&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span> <span class="p">}</span> <span class="c1"># Hotkey 1) - Triggers on key-down.</span>
322
+ <span class="s1">&#39;caps a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">action</span><span class="p">}</span> <span class="c1"># Hotkey 2) - Conflicting hotkey.</span>
323
+ <span class="c1"># Forces hotkey 1) to now trigger on key-up.</span></pre>
324
+ <h3>Translations</h3>
325
+ <p>Translations allow keys or key combinations to act as another key.</p>
326
+ <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;up&#39;</span> <span class="c1"># &#39;up&#39; is pressed as soon as &#39;ctrl a&#39; is pressed.</span>
327
+ <span class="c1"># &#39;up&#39; is released when either &#39;ctrl&#39; or &#39;a&#39; are released.</span></pre>
328
+ <p>Translations are usually combined with fuzzy hotkeys</p>
329
+ <pre class="highlight"><span class="s1">&#39;* ctrl a&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;up&#39;</span> <span class="c1"># would be triggered by e.g. &#39;ctrl shift a&#39;</span></pre>
330
+ <p>Example: Move the 'up' and 'down' cursor keys to the home row</p>
331
+ <pre class="highlight"><span class="s1">&#39;* caps j&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;down&#39;</span>
332
+ <span class="s1">&#39;* caps k&#39;</span><span class="o">.</span><span class="n">translate</span> <span class="s1">&#39;up&#39;</span></pre>
333
+ <h3>Unregistering and re-registering hotkeys</h3>
334
+ <p>All methods concerned with registering or unregistering hotkeys return actions that can be, again, registered or unregistered.</p>
335
+ <pre class="highlight"><span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">do_stuff</span> <span class="p">}</span> <span class="c1">#=&gt; #&lt;Rum::Action...&gt;</span>
336
+ <span class="n">action</span><span class="o">.</span><span class="n">unregister</span> <span class="c1">#=&gt; #&lt;Rum::Action...&gt;</span>
337
+ <span class="n">action</span><span class="o">.</span><span class="n">register</span> <span class="c1">#=&gt; #&lt;Rum::Action...&gt;</span></pre>
338
+ <p>Unregistering the conditionless action of a hotkey</p>
339
+ <pre class="highlight"><span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">unregister</span></pre>
340
+ <p>Actions with conditions...</p>
341
+ <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">condition</span><span class="p">)</span> <span class="p">{</span> <span class="n">do_stuff</span> <span class="p">}</span></pre>
342
+ <p>... can't be unregistered this way</p>
343
+ </div>
344
+ <div class="chapter">
345
+ <a name="chapter_4"><h1>4. Keyboard</h1></a>
346
+
347
+ <h2>Caveat: Not yet available on the Mac.</h2>
348
+ <p>Generates keystrokes.</p>
349
+ <pre class="highlight"><span class="no">Keyboard</span><span class="o">.</span><span class="n">type</span> <span class="s1">&#39;hi&#39;</span></pre>
350
+ <p>The 'Keyboard.' prefix can be omitted.</p>
351
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;hello world&#39;</span></pre>
352
+ <p>Some keys have multi-character names or aliases.<br />Wrap them in parentheses.</p>
353
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;foo(tab)bar&#39;</span></pre>
354
+ <p>Pause for a short while between sending characters.</p>
355
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;hello&#39;</span><span class="p">,</span> <span class="ss">:slow</span></pre>
356
+ <h3>Sending key combinations</h3>
357
+ <p>To send key combinations, enclose multiple keys within parentheses and nest them. (S-expressions!)</p>
358
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;(ctrl (shift hi))&#39;</span> <span class="c1"># sends ctrl-down, shift-down, hi, shift-up, ctrl-up</span></pre>
359
+ <p>Backslash (\) acts as an escape character</p>
360
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;\(&#39;</span> <span class="c1"># sends a (</span></pre>
361
+ <h3>Send string literally, without syntax interpretation</h3>
362
+ <pre class="highlight"><span class="n">type!</span> <span class="s1">&#39;(in brackets)&#39;</span></pre>
363
+ <h3>Translations</h3>
364
+ <p>Some keys are translated into key combinations.</p>
365
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;A&#39;</span> <span class="c1"># sends &#39;(shift a)&#39;</span></pre>
366
+ <p>See Rum.layout.translations</p>
367
+ <h3>Sending single keyboard events</h3>
368
+ <pre class="highlight"><span class="no">System</span><span class="o">.</span><span class="n">keydown</span> <span class="s1">&#39;a&#39;</span>
369
+ <span class="no">System</span><span class="o">.</span><span class="n">keyup</span> <span class="s1">&#39;a&#39;</span></pre>
370
+ <p>In a future release, this might be integrated into the main keyboard syntax, like:</p>
371
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;(keydown a)&#39;</span></pre>
372
+ <h3>Auto-release</h3>
373
+ <p>Pressed core modifiers are released before keyboard input is generated.<br />You can safely do the following:</p>
374
+ <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">type</span> <span class="s1">&#39;w&#39;</span> <span class="p">}</span> <span class="c1"># &#39;ctrl&#39; gets released before &#39;w&#39; is sent.</span></pre>
375
+ <p>Provide the :blind flag to bypass auto-releasing</p>
376
+ <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="n">type</span> <span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="ss">:blind</span> <span class="p">}</span> <span class="c1"># &#39;ctrl&#39; might still be pressed when &#39;w&#39; is sent.</span></pre>
377
+ <h3>Windows-specific: Unicode input</h3>
378
+ <p>Sends unicode input. Supports the key combination syntax from 'type'.</p>
379
+ <pre class="highlight"><span class="n">type_unicode</span> <span class="s1">&#39;۩—↑ (ctrl ۞)&#39;</span></pre>
380
+ <h3>Windows-specific: Extended keys</h3>
381
+ <p>Sends 'alt' with the 'extended' flag set.</p>
382
+ <pre class="highlight"><span class="n">type</span> <span class="s1">&#39;(alt-extended)&#39;</span></pre>
383
+ </div>
384
+ <div class="chapter">
385
+ <a name="chapter_5"><h1>5. Gui</h1></a>
386
+
387
+ <h3>Messages</h3>
388
+ <p>Prints a non-disruptive notification when Growl is enabled, falls back to alert (see below) otherwise</p>
389
+ <pre class="highlight"><span class="n">message</span> <span class="s1">&#39;text&#39;</span>
390
+ <span class="n">message</span> <span class="s1">&#39;text&#39;</span><span class="p">,</span> <span class="s1">&#39;title&#39;</span></pre>
391
+ <p>Sticky: Keep the message from fading out after a few seconds</p>
392
+ <pre class="highlight"><span class="n">message</span> <span class="s1">&#39;hello&#39;</span><span class="p">,</span> <span class="ss">:sticky</span></pre>
393
+ <p>Callback: Do something when the user clicked on the message</p>
394
+ <pre class="highlight"><span class="n">message</span><span class="p">(</span><span class="s1">&#39;click me&#39;</span><span class="p">)</span> <span class="p">{</span> <span class="n">message</span> <span class="s1">&#39;clicked!&#39;</span> <span class="p">}</span></pre>
395
+ <h3>Alerts</h3>
396
+ <p>Shows a focus-stealing 'ok, cancel' message box, prompting for a response</p>
397
+ <pre class="highlight"><span class="n">alert</span> <span class="s1">&#39;message&#39;</span> <span class="c1"># returns true or false</span>
398
+ <span class="n">alert</span> <span class="s1">&#39;message&#39;</span><span class="p">,</span> <span class="s1">&#39;title&#39;</span></pre>
399
+ <h3>Input boxes</h3>
400
+ <pre class="highlight"><span class="n">read</span> <span class="c1"># returns the response or an empty string</span>
401
+ <span class="n">read</span> <span class="s1">&#39;hi, how are you?&#39;</span>
402
+ <span class="n">read</span> <span class="n">default</span><span class="p">:</span> <span class="s1">&#39;default input&#39;</span>
403
+ <span class="n">read</span> <span class="s1">&#39;hi, how are you?&#39;</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="s1">&#39;splendid&#39;</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="s1">&#39;greeting&#39;</span></pre>
404
+ <h3>Choose from candidates</h3>
405
+ <p>This one should launch a quicksilver-like fuzzy selection Gui.</p>
406
+ <pre class="highlight"><span class="n">choose</span> <span class="s1">&#39;choose one&#39;</span><span class="p">,</span> <span class="o">[</span><span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="s1">&#39;blue&#39;</span><span class="p">,</span> <span class="s1">&#39;yellow&#39;</span><span class="o">]</span></pre>
407
+ <p>TODO: Currently this is only supported via Emacs/Ido.<br />Falls back to an ugly combobox for non Emacs users.<br />Which selection GUIs are there already on the Mac and on Windows that could be harnessed?<br /><br />TODO: Emacs</p>
408
+ <pre class="highlight"><span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Gui</span><span class="o">::</span><span class="no">EmacsInteraction</span></pre>
409
+ <h3>Open (text) files</h3>
410
+ <pre class="highlight"><span class="n">open_file</span> <span class="n">path</span></pre>
411
+ <p>Using a text editor ...</p>
412
+ <pre class="highlight"><span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Textmate</span><span class="p">,</span> <span class="ss">:open_file</span>
413
+ <span class="no">Gui</span><span class="o">.</span><span class="n">use</span> <span class="no">Emacs</span><span class="p">,</span> <span class="ss">:open_file</span></pre>
414
+ <p>... enables jumping to a specific line</p>
415
+ <pre class="highlight"><span class="n">open_file</span> <span class="s1">&#39;foo.txt&#39;</span><span class="p">,</span> <span class="mi">24</span></pre>
416
+ <p>You may re-define open_file to fit your specific needs.</p>
417
+ <h3>Open URLs</h3>
418
+ <pre class="highlight"><span class="n">browse</span> <span class="s1">&#39;example.com&#39;</span> <span class="c1"># HTTP is implicit, unless another protocol is specified</span></pre>
419
+ <h3>Show directories or files in your file manager</h3>
420
+ <pre class="highlight"><span class="n">goto</span> <span class="s1">&#39;foo&#39;</span></pre>
421
+ <h3>Gui Module</h3>
422
+ <p>The above methods are part of the Gui module and may also be called explicitly:</p>
423
+ <pre class="highlight"><span class="no">Gui</span><span class="o">.</span><span class="n">message</span>
424
+ <span class="no">Gui</span><span class="o">.</span><span class="n">read</span>
425
+ <span class="o">.</span><span class="n">.</span><span class="o">.</span></pre>
426
+ </div>
427
+ <div class="chapter">
428
+ <a name="chapter_6"><h1>6. Get selected text</h1></a>
429
+
430
+ <h2>Caveat: Not yet available on the Mac.</h2>
431
+ <p>Grabs the currently selected text.</p>
432
+ <pre class="highlight"><span class="n">get_selection</span> <span class="c1"># returns the current selection or nil</span></pre>
433
+ </div>
434
+ <div class="chapter">
435
+ <a name="chapter_7"><h1>7. Clipboard</h1></a>
436
+
437
+ <h2>Caveat: Not yet available on the Mac.</h2>
438
+ <p>Retrieves the clipboard contents as text.</p>
439
+ <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1"># Always returns a string</span></pre>
440
+ <p>Sets the clipboard.</p>
441
+ <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">set</span> <span class="s1">&#39;hello&#39;</span></pre>
442
+ <p>Sends a 'copy to clipboard' keyboard shortcut and waits until the clipboard changes.</p>
443
+ <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">copy</span> <span class="c1"># returns true if successful</span></pre>
444
+ <p>Sends a 'paste' keyboard shortcut.</p>
445
+ <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">paste</span></pre>
446
+ <p>Append the result of get_selection as a new line to the current clipboard content.</p>
447
+ <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1">#=&gt; &quot;foo&quot;</span>
448
+ <span class="no">Clipboard</span><span class="o">.</span><span class="n">append</span>
449
+ <span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1">#=&gt; &quot;foo\nbar&quot;, assuming &#39;bar&#39; was selected.</span></pre>
450
+ <p>Run a block while preserving the clipboard contents.</p>
451
+ <pre class="highlight"><span class="no">Clipboard</span><span class="o">.</span><span class="n">set</span> <span class="s1">&#39;foo&#39;</span>
452
+ <span class="no">Clipboard</span><span class="o">.</span><span class="n">preserve</span> <span class="p">{</span> <span class="no">Clipboard</span><span class="o">.</span><span class="n">set</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span>
453
+ <span class="no">Clipboard</span><span class="o">.</span><span class="n">get</span> <span class="c1">#=&gt; &quot;foo&quot;</span></pre>
454
+ </div>
455
+ <div class="chapter">
456
+ <a name="chapter_8"><h1>8. More methods</h1></a>
457
+
458
+ <h3>Waiting</h3>
459
+ <p>Wait until condition is true. Times out after 5 seconds, updates every 0.01 seconds.</p>
460
+ <pre class="highlight"><span class="n">wait</span> <span class="p">{</span> <span class="n">condition</span> <span class="p">}</span> <span class="c1">#=&gt; False when timed-out. Otherwise: true</span></pre>
461
+ <p>Set a 10 second timeout and a 0.5 second update interval.</p>
462
+ <pre class="highlight"><span class="n">wait</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="o">.</span><span class="mi">5</span><span class="p">)</span> <span class="p">{</span> <span class="n">my_window</span><span class="o">.</span><span class="n">active?</span> <span class="p">}</span></pre>
463
+ <h3>Run a command in a separate terminal window.</h3>
464
+ <pre class="highlight"><span class="n">spawn_in_terminal</span> <span class="n">command</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span>
465
+ <span class="n">spawn_in_terminal</span> <span class="s1">&#39;ruby&#39;</span><span class="p">,</span> <span class="s1">&#39;-e&#39;</span><span class="p">,</span> <span class="s1">&#39;puts Time.now&#39;</span></pre>
466
+ <p>Close the window if the command exits without errors.</p>
467
+ <pre class="highlight"><span class="n">spawn_in_terminal</span> <span class="s1">&#39;ruby&#39;</span><span class="p">,</span> <span class="s1">&#39;-e&#39;</span><span class="p">,</span> <span class="s1">&#39;puts &quot;Hello!&quot;; sleep 2&#39;</span><span class="p">,</span> <span class="ss">:close_if_successful</span></pre>
468
+ <h3>Open documents, run programs</h3>
469
+ <p>Wraps the 'open' command on the Mac and ShellExecute on Windows.</p>
470
+ <pre class="highlight"><span class="n">start</span> <span class="n">file</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span></pre>
471
+ <h3>Applescript</h3>
472
+ <pre class="highlight"><span class="n">applescript</span> <span class="s1">&#39;tell application &quot;System Events&quot;</span>
473
+ <span class="s1"> activate</span>
474
+ <span class="s1"> display dialog &quot;Hello!&quot;</span>
475
+ <span class="s1"> end tell&#39;</span></pre>
476
+ <p>The last three methods are part of the System module and may be called explicitly:</p>
477
+ <pre class="highlight"><span class="no">System</span><span class="o">.</span><span class="n">spawn_in_terminal</span>
478
+ <span class="no">System</span><span class="o">.</span><span class="n">start</span>
479
+ <span class="no">System</span><span class="o">.</span><span class="n">applescript</span></pre>
480
+ </div>
481
+ <div class="chapter">
482
+ <a name="chapter_9"><h1>9. Rum's threading model</h1></a>
483
+
484
+ <p>Rum employs one worker thread that executes all hotkey actions sequentially.<br />Errors during execution are automatically reported via Gui.message.<br /><br />If you have a long running action that may run in parallel with other actions call 'Rum.switch_worker_thread'. Action execution is then resumed in another thread.</p>
485
+ <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Rum</span><span class="o">.</span><span class="n">switch_worker_thread</span><span class="p">;</span> <span class="n">long_running_stuff</span> <span class="p">}</span></pre>
486
+ <p>The following is also possible...</p>
487
+ <pre class="highlight"><span class="s1">&#39;ctrl a&#39;</span><span class="o">.</span><span class="n">do</span> <span class="p">{</span> <span class="no">Thread</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="n">long_running_stuff</span> <span class="p">}</span> <span class="p">}</span></pre>
488
+ <p>... but errors in 'long_running_stuff' won't be implicitly caught and reported by Rum.<br /><br />When you call Gui.read, Gui.alert or Gui.print then Rum.switch_worker_thread is automatically run.</p>
489
+ </div>
490
+ <div class="chapter">
491
+ <a name="chapter_10"><h1>10. Help, introspection</h1></a>
492
+
493
+ <p>Prompts you to enter a hotkey and then jumps to its definition via Gui.open_file.</p>
494
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">visit_hotkey</span></pre>
495
+ <p>(Requires you to register your text-editor, see Gui.open_file above.)<br /><br />Asks you to enter an arbitrary hotkey and inserts a hotkey definition snippet via Keyboard.type.<br />When 'shift a' is pressed, 'shift a'.do { } is inserted.</p>
496
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">snippet</span></pre>
497
+ <p>Reads a hotkey and passes it to the block.<br />(Internally used by Rum.snippet)</p>
498
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">read_key</span> <span class="p">{</span> <span class="o">|</span><span class="n">hotkey</span><span class="o">|</span> <span class="n">do_stuff_with</span> <span class="n">hotkey</span> <span class="p">}</span></pre>
499
+ <p>Shows information about windows as they become active.</p>
500
+ <pre class="highlight"><span class="no">WindowInfo</span><span class="o">.</span><span class="n">start</span></pre>
501
+ <p>Opens this reference in a text editor</p>
502
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">reference</span></pre>
503
+ </div>
504
+ <div class="chapter">
505
+ <a name="chapter_11"><h1>11. Restarting, server</h1></a>
506
+
507
+ <p>Restart the current Rum configuration.</p>
508
+ <pre class="highlight"><span class="no">Rum</span><span class="o">.</span><span class="n">restart</span></pre>
509
+ <p>Start the server. This allows for connections to the Rum process via rum-client.</p>
510
+ <pre class="highlight"><span class="no">Rum</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">start</span></pre>
511
+ </div>
512
+ <div class="chapter">
513
+ <a name="chapter_12"><h1>12. Windows</h1></a>
514
+
515
+ <h2>Caveat: Not yet available on the Mac.</h2>
516
+ <h3>Retrieving windows</h3>
517
+ <pre class="highlight"><span class="n">active_window</span> <span class="c1">#=&gt; #&lt;Rum::System::Window...&gt;</span></pre>
518
+ <p>Traversing all active windows:</p>
519
+ <pre class="highlight"><span class="n">active_windows</span> <span class="c1">#=&gt; #&lt;Enumerator:...&gt;</span>
520
+ <span class="n">active_windows</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">window</span><span class="o">|</span> <span class="n">window</span><span class="o">.</span><span class="n">close</span> <span class="k">if</span> <span class="n">window</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">empty?</span> <span class="p">}</span>
521
+ <span class="n">active_windows</span><span class="o">.</span><span class="n">map</span> <span class="o">&amp;</span><span class="ss">:title</span></pre>
522
+ <h3>Window Matchers</h3>
523
+ <p>WindowMatchers serve as a shorthand for using active_windows.find:</p>
524
+ <pre class="highlight"><span class="n">matcher</span> <span class="o">=</span> <span class="no">Window</span><span class="o">[</span><span class="n">title</span><span class="p">:</span> <span class="sr">/ruby/</span><span class="p">,</span> <span class="n">class_name</span><span class="p">:</span> <span class="s1">&#39;MozillaUIWindowClass&#39;</span><span class="o">]</span></pre>
525
+ <p>or shorter:</p>
526
+ <pre class="highlight"><span class="n">matcher</span> <span class="o">=</span> <span class="no">Window</span><span class="o">[</span><span class="sr">/ruby/</span><span class="p">,</span> <span class="s1">&#39;MozillaUIWindowClass&#39;</span><span class="o">]</span>
527
+ <span class="n">matcher</span> <span class="c1">#=&gt; #&lt;Rum::System::WindowMatcher...&gt;</span>
528
+ <span class="n">matcher</span><span class="o">.</span><span class="n">find</span> <span class="c1">#=&gt; #&lt;Rum::System::Window...&gt;</span>
529
+ <span class="no">Window</span><span class="o">[</span><span class="n">class_name</span><span class="p">:</span> <span class="s1">&#39;Emacs&#39;</span><span class="o">].</span><span class="n">find</span></pre>
530
+ <p>The first matching window is returned.<br />WindowMatcher attributes differ between platforms.<br />The Windows version shown here supports 'title' and 'class_name'.<br />String arguments are checked for equality with the corresponding window attributes, Regex arguments require a match.</p>
531
+ <h3>Window objects</h3>
532
+ <pre class="highlight"><span class="n">w</span> <span class="o">=</span> <span class="n">active_window</span> <span class="c1">#=&gt; #&lt;Rum::System::Window:...&gt;</span>
533
+ <span class="n">w</span> <span class="o">==</span> <span class="n">active_window</span> <span class="c1">#=&gt; true</span>
534
+ <span class="n">w</span><span class="o">.</span><span class="n">show</span> <span class="c1"># returns true if successful</span>
535
+ <span class="n">w</span><span class="o">.</span><span class="n">minimize</span>
536
+ <span class="n">w</span><span class="o">.</span><span class="n">maximize</span>
537
+ <span class="n">w</span><span class="o">.</span><span class="n">toggle_always_on_top</span>
538
+ <span class="n">w</span><span class="o">.</span><span class="n">title</span> <span class="c1">#=&gt; &quot;A window title&quot;</span>
539
+ <span class="n">w</span><span class="o">.</span><span class="n">class_name</span> <span class="c1">#=&gt; &quot;Chrome_WidgetWin_0&quot;</span>
540
+ <span class="n">w</span><span class="o">.</span><span class="n">close</span>
541
+ <span class="n">w</span><span class="o">.</span><span class="n">kill_task</span> <span class="c1"># kills the task associated with the window</span></pre>
542
+ <h3>Child windows</h3>
543
+ <p>Enumerate all child windows</p>
544
+ <pre class="highlight"><span class="n">w</span> <span class="o">=</span> <span class="n">active_window</span>
545
+ <span class="n">w</span><span class="o">.</span><span class="n">child_windows</span> <span class="p">{</span> <span class="o">|</span><span class="n">child</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">child</span><span class="o">.</span><span class="n">class_name</span> <span class="p">}</span>
546
+ <span class="n">w</span><span class="o">.</span><span class="n">child_windows</span> <span class="c1"># =&gt; #&lt;Enumerator: ...&gt;</span></pre>
547
+ <p>Get child window by class name. Pattern can be a regex or a string (for exact matches).</p>
548
+ <pre class="highlight"><span class="n">w</span><span class="o">.</span><span class="n">child_window</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span></pre>
549
+ <p>Example: Activate Evernote's search field</p>
550
+ <pre class="highlight"><span class="no">Evernote</span><span class="o">.</span><span class="n">window</span><span class="o">.</span><span class="n">child_window</span><span class="p">(</span><span class="s1">&#39;ENAutoCompleteEditCtrl&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">show</span></pre>
551
+ </div>
552
+ <div class="chapter">
553
+ <a name="chapter_13"><h1>13. Apps</h1></a>
554
+
555
+ <p>Integrates prominent applications into Rum.</p>
556
+ <pre class="highlight">require <span class="s1">&#39;rum/apps&#39;</span></pre>
557
+ <h3>App objects</h3>
558
+ <pre class="highlight"><span class="n">app</span> <span class="o">=</span> <span class="no">Emacs</span> <span class="c1">#=&gt; #&lt;Rum::App:...&gt;</span></pre>
559
+ <p>Start app or bring it to the front when it's already running.<br />This works for all apps.<br />Returns true when the app could be activated instantly.</p>
560
+ <pre class="highlight"><span class="n">app</span><span class="o">.</span><span class="n">activate</span> <span class="c1">#=&gt; true</span></pre>
561
+ <h3>Emacs</h3>
562
+ <pre class="highlight"><span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(message &quot;hi&quot;)&#39;</span> <span class="c1">#=&gt; &quot;\&quot;hi\&quot;&quot;</span>
563
+ <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(* 3 3)&#39;</span> <span class="c1">#=&gt; &quot;9&quot;</span></pre>
564
+ <p>Eval in the current buffer context.</p>
565
+ <pre class="highlight"><span class="no">Emacs</span><span class="o">.</span><span class="n">eval_in_user_buffer</span> <span class="o">=</span> <span class="kp">true</span>
566
+ <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;default-directory&#39;</span> <span class="c1">#=&gt; &quot;~/current_buffer_dir/&quot;</span>
567
+ <span class="no">Emacs</span><span class="o">.</span><span class="n">eval</span> <span class="s1">&#39;(idle-highlight-mode t)&#39;</span> <span class="c1"># Turns on a minor mode in the current buffer.</span></pre>
568
+ <p>Set this on Windows to allow Emacs.activate to start Emacs when it's not running.</p>
569
+ <pre class="highlight"><span class="no">Emacs</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;path/to/runemacs&#39;</span></pre>
570
+ </div>
571
+ </div>
572
+ <div id='development'>
573
+ <a name='development'>
574
+ <h1>Development</h1>
575
+ </a>
576
+ <p>
577
+ Patches and suggestions are most appreciated.
578
+ </p>
579
+ <p>
580
+ There's a <a href="https://github.com/nonsequitur/rum-dev/blob/master/rum-development.org">low-ceremony
581
+ to-do list</a> to coordinate the development
582
+ of larger-scale features.<br />
583
+ Feel free to have a look if you're interested in contributing.
584
+ </p>
585
+ <h2>Building</h2>
586
+ <p>
587
+ <span class='code'>rake build</span>
588
+ builds the extension and the document.
589
+ </p>
590
+ <p>
591
+ <span class='code'>rake ext</span>
592
+ builds just the extension.
593
+ </p>
594
+ <p>
595
+ <span class='code'>rake doc</span>
596
+ builds this document. Requires Pygments.
597
+ </p>
598
+ <h3>Mac specifics:</h3>
599
+ <p>
600
+ XCode required.
601
+ </p>
602
+ <h3>Windows specifics:</h3>
603
+ <p>
604
+ Visual Studio required. (Out-of-the-box MinGW support coming soon.)
605
+ </p>
606
+ <p>
607
+ You need to setup the Visual Studio build environment before running the rake commands.<br />Call <span class="code">"%programfiles%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86</span> from your Windows terminal.
608
+ </p>
609
+ <p>
610
+ You might have to delete the following lines from <span class="code">ruby_dir/include/ruby-1.9.x/i386-mswin32/ruby/config.h</span> to work around a compiler error:
611
+ <pre>#if _MSC_VER != 1200
612
+ #error MSC version unmatch: _MSC_VER: 1200 is expected.
613
+ #endif</pre>
614
+ </p>
615
+ <div id='footer'></div>
616
+ </div>
617
+ </div>
618
+ </body>
619
+ </html>