rum 0.0.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/CHANGELOG +3 -0
  2. data/README +30 -0
  3. data/Rakefile +134 -0
  4. data/bin/rum-client +124 -0
  5. data/doc/basic.rb +10 -0
  6. data/doc/doc.html +602 -0
  7. data/doc/example.rb +59 -0
  8. data/doc/reference.rb +415 -0
  9. data/doc/resources/bg.png +0 -0
  10. data/doc/resources/bottom.png +0 -0
  11. data/doc/resources/build.rb +235 -0
  12. data/doc/resources/doc.haml +167 -0
  13. data/doc/resources/emacs-auto-completion.png +0 -0
  14. data/doc/resources/flash.png +0 -0
  15. data/doc/resources/highlight.css +94 -0
  16. data/doc/resources/intro.rb +17 -0
  17. data/doc/resources/left.png +0 -0
  18. data/doc/resources/logo.png +0 -0
  19. data/doc/resources/screen.css +420 -0
  20. data/doc/resources/screenshot.png +0 -0
  21. data/doc/resources/top.png +0 -0
  22. data/ext/mac/keyboard_hook/English.lproj/InfoPlist.strings +0 -0
  23. data/ext/mac/keyboard_hook/Event.h +17 -0
  24. data/ext/mac/keyboard_hook/Event.m +18 -0
  25. data/ext/mac/keyboard_hook/EventTap.h +11 -0
  26. data/ext/mac/keyboard_hook/EventTap.m +77 -0
  27. data/ext/mac/keyboard_hook/Info.plist +26 -0
  28. data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/TemplateIcon.icns +0 -0
  29. data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/project.pbxproj +323 -0
  30. data/ext/mac/keyboard_hook/KeyboardHook_Prefix.pch +7 -0
  31. data/ext/mac/keyboard_hook/version.plist +16 -0
  32. data/ext/windows/keyboard_hook/extconf.rb +2 -0
  33. data/ext/windows/keyboard_hook/keyboard_hook.c +126 -0
  34. data/ext/windows/system/autohotkey_stuff.c +255 -0
  35. data/ext/windows/system/autohotkey_stuff.h +2 -0
  36. data/ext/windows/system/clipboard_watcher.c +58 -0
  37. data/ext/windows/system/clipboard_watcher.h +2 -0
  38. data/ext/windows/system/extconf.rb +3 -0
  39. data/ext/windows/system/input_box.c +239 -0
  40. data/ext/windows/system/input_box.h +4 -0
  41. data/ext/windows/system/system.c +273 -0
  42. data/lib/rum.rb +4 -0
  43. data/lib/rum/apps.rb +4 -0
  44. data/lib/rum/barrel.rb +157 -0
  45. data/lib/rum/barrel/emacs.rb +44 -0
  46. data/lib/rum/barrel/emacs_client.rb +74 -0
  47. data/lib/rum/core.rb +125 -0
  48. data/lib/rum/dsl.rb +109 -0
  49. data/lib/rum/gui.rb +93 -0
  50. data/lib/rum/help.rb +128 -0
  51. data/lib/rum/hotkey_core.rb +479 -0
  52. data/lib/rum/mac.rb +18 -0
  53. data/lib/rum/mac/app.rb +4 -0
  54. data/lib/rum/mac/apps.rb +19 -0
  55. data/lib/rum/mac/gui.rb +26 -0
  56. data/lib/rum/mac/gui/growl.rb +54 -0
  57. data/lib/rum/mac/irb/completion.rb +207 -0
  58. data/lib/rum/mac/keyboard_hook.rb +73 -0
  59. data/lib/rum/mac/layouts.rb +146 -0
  60. data/lib/rum/mac/system.rb +45 -0
  61. data/lib/rum/remote.rb +48 -0
  62. data/lib/rum/server.rb +92 -0
  63. data/lib/rum/windows.rb +23 -0
  64. data/lib/rum/windows/app.rb +72 -0
  65. data/lib/rum/windows/apps.rb +25 -0
  66. data/lib/rum/windows/gui.rb +116 -0
  67. data/lib/rum/windows/keyboard.rb +80 -0
  68. data/lib/rum/windows/keyboard_hook.rb +20 -0
  69. data/lib/rum/windows/keyboard_hook.so +0 -0
  70. data/lib/rum/windows/layouts.rb +232 -0
  71. data/lib/rum/windows/system.rb +310 -0
  72. data/lib/rum/windows/system.so +0 -0
  73. data/lib/rum/windows/system_foreign_functions.rb +129 -0
  74. data/rum.gemspec +14 -0
  75. metadata +156 -0
@@ -0,0 +1,59 @@
1
+ ## A short survey of the main features
2
+ ## This file can be found at rum_dir/doc/example.rb
3
+
4
+ require 'rum'
5
+
6
+ # 1. Set up additional modifiers that can then
7
+ # be used in hotkey definitions.
8
+ # Any key can be a modifier
9
+ Rum.layout.modifier 'caps'
10
+ Rum.layout.modifier 'escape'
11
+
12
+ # 2. Hotkey definitions
13
+ 'ctrl a'.do { puts 'foo' }
14
+ # Hotkeys may consist solely of modifiers
15
+ 'caps'.do { puts 'bar' }
16
+ 'caps ctrl'.do { puts 'bar' }
17
+ # Hotkey conditions
18
+ 'f1'.do( lambda { rand(2) == 1 } ) { puts 'win!' }
19
+ # Fuzzy hotkeys, trigger regardless of other modifiers being pressed
20
+ '* ctrl b'.do { puts 'hi' }
21
+ # Translations
22
+ '* caps j'.translate 'down'
23
+
24
+ # 3. Gui
25
+ message 'message'
26
+ read 'hi, how are you?' # Input box
27
+
28
+ # 4. Keyboard, send keypresses
29
+ type 'hello'
30
+ type '(ctrl (shift a))' # Key combinations
31
+
32
+ # 5. Help and introspection
33
+ # Prompts you to enter a hotkey and then jumps to its
34
+ # definition in your text editor.
35
+ 'shift f2'.do { Rum.show_hotkey }
36
+
37
+ # Asks you to enter an arbitrary hotkey and inserts a hotkey
38
+ # definition snippet.
39
+ 'shift f3'.do { Rum.snippet }
40
+
41
+ # Restarts Rum.
42
+ 'shift f1'.do { Rum.restart }
43
+
44
+
45
+ # 6. Integrate external features
46
+ Gui.use Gui::Growl
47
+
48
+ # Set up a text-editor for opening files
49
+ require 'rum/apps'
50
+ Gui.use Textmate, :open_file
51
+ # Or
52
+ Gui.use Emacs, :open_file
53
+
54
+ # 7. Start the server. You can now connect to the
55
+ # Rum process via rum-client.
56
+ Rum::Server.start
57
+
58
+ # 8. Start rum
59
+ Rum.start
@@ -0,0 +1,415 @@
1
+ #### 1. Unicode
2
+ # Rum is unicode-compatible. The default encoding is UTF-8.
3
+
4
+ #### 2. Layouts
5
+ # Keyboard layout changes must take place before any hotkey definitions.
6
+
7
+ # Rum starts with a default QWERTY layout
8
+ Rum.layout #=> #<Rum::Layout:0xb99634 ... >
9
+
10
+ # Changing the layout
11
+ Rum.layout = Layouts.german
12
+
13
+ # Listing available layouts
14
+ Layouts.list
15
+
16
+ ### Editing a layout
17
+ layout = Rum.layout
18
+
19
+ ## Adding a modifier.
20
+ # Any key can be a modifier.
21
+ layout.modifier 'escape'
22
+
23
+ ## Aliasing
24
+ layout.alias 'escape', 'esc'
25
+ # The original key...
26
+ layout['escape'] #=> #<Key:escape>
27
+ # ...can now be referenced by the alias
28
+ layout['esc'] #=> #<Key:escape>
29
+
30
+ ## Renaming
31
+ layout.rename 'escape', 'foo'
32
+ layout['foo'] #=> #<Key:foo>
33
+
34
+ ## Finding out the name of a key
35
+ # All keyboard activity is reported at the terminal.
36
+ # Switch to the Rum terminal window and press a key.
37
+
38
+
39
+ ### Advanced
40
+ ## Adding a key
41
+ # add name, *aliases, id
42
+ layout.add 'my-key', 125
43
+ layout.add 'my-other-key', 'my-alias', 126
44
+
45
+ ## Remapping
46
+ # Maps multiple key ids to a single key.
47
+ layout['lctrl'].id #=> 39
48
+ layout[39] #=> #<Key:lctrl>
49
+ # remap from*, to
50
+ layout.remap 'lctrl', 'ctrl'
51
+ layout[39] #=> #<Key:ctrl>
52
+
53
+ ## Core modifiers
54
+ # Core modifiers, unlike standard modifiers, are always passed on to
55
+ # the Operating System.
56
+ # Shift, Ctrl, etc. are core modifiers.
57
+ layout.core_modifier 'escape' # Sets a core modifier.
58
+
59
+
60
+
61
+ #### 2. Hotkeys
62
+ ## The basics
63
+ 'modifiers hotkey'.do { action }
64
+ 'ctrl shift w'.do { active_window.close }
65
+ 'f1'.do { type 'hello' }
66
+ # The last statement can be abbreviated:
67
+ 'f1'.do 'hello'
68
+
69
+ ## Hotkey conditions
70
+ # Restrict hotkeys to trigger only when certain
71
+ # conditions are met.
72
+ 'hotkey'.do(condition) { action }
73
+ 'f1'.do( lambda { rand(3) == 1 } ) { puts 'win!' }
74
+
75
+ ## Fuzzy hotkeys
76
+ # The wildcard '*' forces a hotkey to trigger regardless of
77
+ # other modifiers being pressed.
78
+ '* shift a'.do { action } # would be triggered by 'ctrl shift option a'
79
+
80
+ # Normal, non-fuzzy hotkeys take precedence over fuzzy hotkeys.
81
+
82
+ ## No-Repeat
83
+ # Don't trigger on repetitive key-down events that are spawned when a key is
84
+ # held down for a certain time:
85
+ 'f1'.do(:no_repeat) { action }
86
+
87
+ ## Modifier hotkeys
88
+ # Hotkeys that consist solely of modifiers.
89
+ 'ctrl'.do { action }
90
+ 'ctrl shift'.do { action }
91
+ # The modifiers used in modifier-only hotkeys can be part of another
92
+ # hotkey.
93
+ # In this case, modifier hotkeys trigger on key-up and only when
94
+ # no other key has been pressed in the meantime.
95
+ # Otherwise, they trigger instantly.
96
+
97
+ # Example, assuming 'caps' is a valid modifier:
98
+ 'caps'.do { action } # Hotkey 1) - Triggers on key-down.
99
+ 'caps a'.do { action} # Hotkey 2) - Conflicting hotkey.
100
+ # Forces hotkey 1) to now trigger on key-up.
101
+
102
+ ## Translations
103
+ # Translations allow keys or key combinations to act as another key.
104
+
105
+ 'ctrl a'.translate 'up' # 'up' is pressed as soon as 'ctrl a' is pressed.
106
+ # 'up' is released when either 'ctrl' or 'a' are released.
107
+
108
+ # Translations are usually combined with fuzzy hotkeys
109
+ '* ctrl a'.translate 'up' # would be triggered by e.g. 'ctrl shift a'
110
+
111
+ # Example: Move the 'up' and 'down' cursor keys to the home row
112
+ '* caps j'.translate 'down'
113
+ '* caps k'.translate 'up'
114
+
115
+
116
+ ## Unregistering and re-registering hotkeys
117
+
118
+ # All methods concerned with registering or unregistering hotkeys
119
+ # return actions that can be, again, registered or unregistered.
120
+ action = 'ctrl a'.do { do_stuff } #=> #<Rum::Action...>
121
+ action.unregister #=> #<Rum::Action...>
122
+ action.register #=> #<Rum::Action...>
123
+
124
+ # Unregistering the conditionless action of a hotkey
125
+ action = 'ctrl a'.unregister
126
+ # Actions with conditions...
127
+ 'ctrl a'.do(condition) { do_stuff }
128
+ # ... can't be unregistered this way
129
+
130
+
131
+
132
+ #### 3. Keyboard
133
+
134
+ ### Caveat: Not yet available on the Mac.
135
+
136
+ # Generates keystrokes.
137
+ Keyboard.type 'hi'
138
+ # The 'Keyboard.' prefix can be omitted.
139
+ type 'hello world'
140
+
141
+ # Some keys have multi-character names or aliases.
142
+ # Wrap them in parentheses.
143
+ type 'foo(tab)bar'
144
+
145
+ # Pause for a short while between sending characters.
146
+ type 'hello', :slow
147
+
148
+ ## Sending key combinations
149
+ # To send key combinations, enclose multiple keys within
150
+ # parentheses and nest them. (S-expressions!)
151
+ type '(ctrl (shift hi))' # sends ctrl-down, shift-down, hi, shift-up, ctrl-up
152
+
153
+ # Backslash (\) acts as an escape character
154
+ type '\(' # sends a (
155
+
156
+ ## Send string literally, without syntax interpretation
157
+ type! '(in brackets)'
158
+
159
+ ## Translations
160
+ # Some keys are translated into key combinations.
161
+ type 'A' # sends '(shift a)'
162
+ # See Rum.layout.translations
163
+
164
+ ## Sending single keyboard events
165
+ System.keydown 'a'
166
+ System.keyup 'a'
167
+ # In a future release, this might be integrated
168
+ # into the main keyboard syntax, like:
169
+ type '(keydown a)'
170
+
171
+ ## Auto-release
172
+ # Pressed core modifiers are released before
173
+ # keyboard input is generated.
174
+ # You can safely do the following:
175
+ 'ctrl a'.do { type 'w' } # 'ctrl' gets released before 'w' is sent.
176
+
177
+ # Provide the :blind flag to bypass auto-releasing
178
+ 'ctrl a'.do { type 'w', :blind } # 'ctrl' might still be pressed when 'w' is sent.
179
+
180
+
181
+ ## Windows-specific: Extended keys
182
+ # Sends 'alt' with the 'extended' flag set.
183
+ type '(alt-extended)'
184
+
185
+
186
+
187
+ #### 3. Gui
188
+ ## Messages
189
+ # Prints a non-disruptive notification when Growl is enabled,
190
+ # falls back to alert (see below) otherwise
191
+ message 'text'
192
+ message 'text', 'title'
193
+ # Sticky: Keep the message from fading out after a few seconds
194
+ message 'hello', :sticky
195
+ # Callback: Do something when the user clicked on the message
196
+ message('click me') { message 'clicked!' }
197
+
198
+ ## Alerts
199
+ # Shows a focus-stealing 'ok, cancel' message box, prompting for a response
200
+ alert 'message' # returns true or false
201
+ alert 'message', 'title'
202
+
203
+ ## Input boxes
204
+ read # returns the response or an empty string
205
+ read 'hi, how are you?'
206
+ read default: 'default input'
207
+ read 'hi, how are you?', default: 'splendid', title: 'greeting'
208
+
209
+ ## Choose from candidates
210
+ # This one should launch a quicksilver-like fuzzy selection Gui.
211
+ choose 'choose one', ['red', 'blue', 'yellow']
212
+ # TODO: Currently this is only supported via Emacs/Ido.
213
+ # Falls back to an ugly combobox for non Emacs users.
214
+ # Which selection GUIs are there already on the Mac and on
215
+ # Windows that could be harnessed?
216
+
217
+ # TODO: Emacs
218
+ Gui.use Gui::EmacsInteraction
219
+
220
+ ## Open (text) files
221
+ open_file path
222
+ # Using a text editor ...
223
+ Gui.use Textmate, :open_file
224
+ Gui.use Emacs, :open_file
225
+ # ... enables jumping to a specific line
226
+ open_file 'foo.txt', 24
227
+ # You may re-define open_file to fit your specific needs.
228
+
229
+ ## Open URLs
230
+ browse 'example.com' # HTTP is implicit, unless another protocol is specified
231
+
232
+ ## Show directories or files in your file manager
233
+ goto 'foo'
234
+
235
+ ## Gui Module
236
+ # The above methods are part of the Gui module and may also be called explicitly:
237
+ Gui.message
238
+ Gui.read
239
+ ...
240
+
241
+
242
+ #### 4. Get selected text
243
+ ### Caveat: Not yet available on the Mac.
244
+ # Grabs the currently selected text.
245
+ get_selection # returns the current selection or nil
246
+
247
+
248
+ #### 5. Clipboard
249
+ ### Caveat: Not yet available on the Mac.
250
+ # Retrieves the clipboard contents as text.
251
+ Clipboard.get # Always returns a string
252
+
253
+ # Sets the clipboard.
254
+ Clipboard.set 'hello'
255
+
256
+ # Sends a 'copy to clipboard' keyboard shortcut
257
+ # and waits until the clipboard changes.
258
+ Clipboard.copy # returns true if successful
259
+
260
+ # Sends a 'paste' keyboard shortcut.
261
+ Clipboard.paste
262
+
263
+ # Append the result of get_selection as a new line
264
+ # to the current clipboard content.
265
+ Clipboard.get #=> "foo"
266
+ Clipboard.append
267
+ Clipboard.get #=> "foo\nbar", assuming 'bar' was selected.
268
+
269
+ # Run a block while preserving the clipboard contents.
270
+ Clipboard.set 'foo'
271
+ Clipboard.preserve { Clipboard.set 'bar' }
272
+ Clipboard.get #=> "foo"
273
+
274
+
275
+ #### 6. More methods
276
+ ## Waiting
277
+ # Wait until condition is true. Times out after 5 seconds, updates every 0.01 seconds.
278
+ wait { condition } #=> False when timed-out. Otherwise: true
279
+
280
+ # Set a 10 second timeout and a 0.5 second update interval.
281
+ wait(10, 0.5) { my_window.active? }
282
+
283
+ ## Run a command in a separate terminal window.
284
+ spawn_in_terminal command, *args
285
+ spawn_in_terminal 'ruby', '-e', 'puts Time.now'
286
+ # Close the window if the command exits without errors.
287
+ spawn_in_terminal 'ruby', '-e', 'puts "Hello!"; sleep 2', :close_if_successful
288
+
289
+ ## Open documents, run programs
290
+ # Wraps the 'open' command on the Mac and ShellExecute on Windows.
291
+ start file, *args
292
+
293
+ ## Applescript
294
+ applescript 'tell application "System Events"
295
+ activate
296
+ display dialog "Hello!"
297
+ end tell'
298
+
299
+ # The last three methods are part of the System module and may be
300
+ # called explicitly:
301
+ System.spawn_in_terminal
302
+ System.start
303
+ System.applescript
304
+
305
+ #### 6. Rum's threading model
306
+ # Rum employs one worker thread that executes all hotkey actions
307
+ # sequentially.
308
+ # Errors during execution are automatically reported via Gui.message.
309
+
310
+ # If you have a long running action that may run in parallel with
311
+ # other actions call 'Rum.switch_worker_thread'. Action execution is
312
+ # then resumed on another thread.
313
+ 'ctrl a'.do { Rum.switch_worker_thread; long_running_stuff }
314
+
315
+ # The following is also possible...
316
+ 'ctrl a'.do { Thread.new { long_running_stuff } }
317
+ # ... but errors in 'long_running_stuff' won't be implicitly
318
+ # caught and reported by Rum.
319
+
320
+ # When you call Gui.read, Gui.alert or Gui.print
321
+ # then Rum.switch_worker_thread is automatically run.
322
+
323
+ #### 5. Help, introspection
324
+ # Prompts you to enter a hotkey and then jumps to its
325
+ # definition via Gui.open_file.
326
+ Rum.show_hotkey
327
+ # (Requires you to register your text-editor, see Gui.open_file above.)
328
+
329
+ # Asks you to enter an arbitrary hotkey and inserts a hotkey
330
+ # definition snippet via Keyboard.type.
331
+ # When 'shift a' is pressed, 'shift a'.do { } is inserted.
332
+ Rum.snippet
333
+
334
+ # Reads a hotkey and passes it to the block.
335
+ # (Internally used by Rum.snippet)
336
+ Rum.read_key { |hotkey| do_stuff_with hotkey }
337
+
338
+ # Shows information about windows as they become active.
339
+ WindowInfo.start
340
+
341
+ # Opens this reference in a text editor
342
+ Rum.reference
343
+
344
+
345
+ #### 5. Restarting, server
346
+ # Restart the current Rum configuration.
347
+ Rum.restart
348
+
349
+ # Start the server. This allows for connections to the
350
+ # Rum process via rum-client.
351
+ Rum::Server.start
352
+
353
+
354
+ #### 6. Windows
355
+
356
+ ### Caveat: Not yet available on the Mac.
357
+
358
+ ## Retrieving windows
359
+ active_window #=> #<Rum::System::Window...>
360
+ # Traversing all active windows:
361
+ active_windows #=> #<Enumerator:...>
362
+ active_windows.each { |window| window.close if window.title.empty? }
363
+ active_windows.map &:title
364
+
365
+ ## Window Matchers
366
+ # WindowMatchers serve as a shorthand for using active_windows.find:
367
+ matcher = Window[title: /ruby/, class_name: 'MozillaUIWindowClass']
368
+ # or shorter:
369
+ matcher = Window[/ruby/, 'MozillaUIWindowClass']
370
+ matcher #=> #<Rum::System::WindowMatcher...>
371
+ matcher.find #=> #<Rum::System::Window...>
372
+ Window[class_name: 'Emacs'].find
373
+ # The first matching window is returned.
374
+ # WindowMatcher attributes differ between platforms.
375
+ # The Windows version shown here supports 'title' and 'class_name'.
376
+ # String arguments are checked for equality with the corresponding
377
+ # window attributes, Regex arguments require a match.
378
+
379
+ ## Window objects
380
+ w = active_window #=> #<Rum::System::Window:...>
381
+ w == active_window #=> true
382
+ w.show # returns true if successful
383
+ w.minimize
384
+ w.maximize
385
+ w.toggle_always_on_top
386
+ w.title #=> "A window title"
387
+ w.class_name #=> "Chrome_WidgetWin_0"
388
+ w.close
389
+ w.kill_task # kills the task associated with the window
390
+
391
+
392
+ #### 7. Apps
393
+ # Integrates prominent applications into Rum.
394
+ require 'rum/apps'
395
+
396
+ ## App objects
397
+ app = Emacs #=> #<Rum::App:...>
398
+ # Start app or bring it to the front when it's already running.
399
+ # This works for all apps.
400
+ # Returns true when the app could be activated instantly.
401
+ app.activate #=> true
402
+
403
+ ## Emacs
404
+ Emacs.eval '(message "hi")' #=> "\"hi\""
405
+ Emacs.eval '(* 3 3)' #=> "9"
406
+
407
+ # Eval in the current buffer context.
408
+ Emacs.eval_in_user_buffer = true
409
+ Emacs.eval 'default-directory' #=> "~/current_buffer_dir/"
410
+ Emacs.eval '(idle-highlight-mode t)' # Turns on a minor mode in the current buffer.
411
+
412
+ # Set this on Windows to allow Emacs.activate
413
+ # to start Emacs when it's not running.
414
+ Emacs.path = 'path/to/runemacs'
415
+