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.
- data/CHANGELOG +9 -0
- data/README.md +35 -0
- data/Rakefile +22 -19
- data/bin/rum-client +4 -4
- data/doc/basic.rb +1 -1
- data/doc/doc.html +619 -602
- data/doc/example.rb +1 -1
- data/doc/reference.rb +29 -16
- data/doc/resources/build.rb +14 -12
- data/doc/resources/doc.haml +8 -3
- data/ext/mac/keyboard_hook/EventTap.h +1 -1
- data/ext/mac/keyboard_hook/EventTap.m +9 -9
- data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/project.pbxproj +12 -9
- data/ext/windows/keyboard_hook/keyboard_hook.c +3 -3
- data/ext/windows/system/autohotkey_stuff.c +12 -10
- data/ext/windows/system/clipboard_watcher.c +2 -2
- data/ext/windows/system/extconf.rb +1 -0
- data/ext/windows/system/input_box.c +9 -9
- data/ext/windows/system/system.c +51 -46
- data/lib/rum/barrel.rb +46 -16
- data/lib/rum/barrel/emacs.rb +1 -1
- data/lib/rum/barrel/emacs_client.rb +32 -5
- data/lib/rum/core.rb +24 -22
- data/lib/rum/dsl.rb +15 -16
- data/lib/rum/gui.rb +3 -3
- data/lib/rum/help.rb +10 -8
- data/lib/rum/hotkey_core.rb +35 -25
- data/lib/rum/mac.rb +1 -1
- data/lib/rum/mac/gui.rb +1 -1
- data/lib/rum/mac/gui/growl.rb +3 -3
- data/lib/rum/mac/irb/completion.rb +13 -13
- data/lib/rum/mac/keyboard_hook.rb +8 -5
- data/lib/rum/mac/layouts.rb +4 -4
- data/lib/rum/mac/system.rb +2 -2
- data/lib/rum/remote.rb +3 -3
- data/lib/rum/server.rb +2 -3
- data/lib/rum/windows.rb +2 -1
- data/lib/rum/windows/app.rb +12 -7
- data/lib/rum/windows/apps.rb +3 -8
- data/lib/rum/windows/gui.rb +8 -8
- data/lib/rum/windows/keyboard.rb +34 -9
- data/lib/rum/windows/keyboard_hook.so +0 -0
- data/lib/rum/windows/layouts.rb +6 -6
- data/lib/rum/windows/system.rb +71 -28
- data/lib/rum/windows/system.so +0 -0
- data/lib/rum/windows/system_foreign_functions.rb +44 -20
- data/rum.gemspec +2 -2
- metadata +19 -21
- data/README +0 -30
data/lib/rum/core.rb
CHANGED
@@ -14,7 +14,7 @@ Encoding.default_external = Encoding::UTF_8
|
|
14
14
|
|
15
15
|
module Rum
|
16
16
|
autoload :Server, 'rum/server'
|
17
|
-
|
17
|
+
|
18
18
|
class << self
|
19
19
|
attr_writer :layout
|
20
20
|
attr_reader :hotkey_set, :hotkey_processor, \
|
@@ -23,7 +23,7 @@ module Rum
|
|
23
23
|
def layout
|
24
24
|
@layout ||= Layouts.default_layout
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def setup
|
28
28
|
return if setup_completed?
|
29
29
|
@hotkey_set = HotkeySet.new(layout)
|
@@ -60,8 +60,8 @@ module Rum
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def display_exception(exception)
|
63
|
-
error_message = ["#{exception.class}
|
64
|
-
|
63
|
+
error_message = ["#{exception.class}:\n#{exception}",
|
64
|
+
*exception.backtrace].join("\n\n")
|
65
65
|
|
66
66
|
file, line = parse_stack_frame(exception.backtrace.first)
|
67
67
|
if file
|
@@ -73,21 +73,8 @@ module Rum
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
77
|
-
Gui.message error_message, :sticky, &callback
|
78
|
-
end
|
79
76
|
|
80
|
-
|
81
|
-
if match = frame.match(/^(.+?):(\d+)/)
|
82
|
-
file, line = match.captures
|
83
|
-
# Different file names in IRB stackframes:
|
84
|
-
# Ruby 1.9.1: (eval)
|
85
|
-
# Ruby 1.9.2: <main>
|
86
|
-
# MacRuby 0.10: /working_directory/(eval)
|
87
|
-
if file !~ /\(eval\)$/ and file != '<main>'
|
88
|
-
[file, line.to_i]
|
89
|
-
end
|
90
|
-
end
|
77
|
+
Gui.message error_message, :sticky, &callback
|
91
78
|
end
|
92
79
|
|
93
80
|
def switch_worker_thread
|
@@ -98,12 +85,27 @@ module Rum
|
|
98
85
|
@worker_thread = start_worker_thread(new)
|
99
86
|
old.enq nil # Signal the worker thread to stop
|
100
87
|
end
|
88
|
+
|
89
|
+
def parse_stack_frame(frame)
|
90
|
+
if match = frame.match(/^(.+?):(\d+)/)
|
91
|
+
file, line = match.captures
|
92
|
+
[file, line.to_i] if physical_file? file
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def physical_file? file
|
97
|
+
# Different file names in IRB stackframes:
|
98
|
+
# Ruby 1.9.1: (eval)
|
99
|
+
# Ruby 1.9.2: <main>
|
100
|
+
# MacRuby 0.10: /working_directory/(eval)
|
101
|
+
file !~ /\(eval\)$/ and file != '<main>'
|
102
|
+
end
|
101
103
|
end
|
102
104
|
|
103
|
-
|
104
|
-
|
105
|
+
InitialWorkingDir = Dir.pwd
|
106
|
+
|
105
107
|
def restart
|
106
|
-
Dir.chdir
|
108
|
+
Dir.chdir InitialWorkingDir
|
107
109
|
if Thread.current == Rum::Server.thread
|
108
110
|
Thread.new do
|
109
111
|
sleep 0.01 # Allow server to respond. Slightly hacky.
|
@@ -114,7 +116,7 @@ module Rum
|
|
114
116
|
restart_platform_specific
|
115
117
|
end
|
116
118
|
end
|
117
|
-
|
119
|
+
|
118
120
|
def show
|
119
121
|
System.terminal_window.show
|
120
122
|
end
|
data/lib/rum/dsl.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
include Rum
|
2
|
-
include System
|
3
|
-
include Keyboard
|
2
|
+
include Rum::System
|
3
|
+
include Rum::Keyboard
|
4
4
|
|
5
5
|
module Rum
|
6
6
|
class Action
|
7
7
|
def register
|
8
8
|
Rum.hotkey_set.register(self)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def unregister
|
12
12
|
Rum.hotkey_set.unregister(self)
|
13
13
|
end
|
@@ -27,25 +27,26 @@ module Rum
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def visit
|
31
31
|
Gui.open_file(@file, @line)
|
32
32
|
true
|
33
33
|
end
|
34
34
|
end
|
35
|
-
end
|
36
35
|
|
37
|
-
module GuiMixin
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
module GuiMixin
|
37
|
+
# Delegating to Gui instead of directly including Gui avoids dealing
|
38
|
+
# with module hierarchy corner cases that appear when other modules
|
39
|
+
# are later dynamically included into Gui via Gui.use.
|
40
|
+
[:message, :alert, :read, :choose, :open_file, :browse, :goto].each do |method_name|
|
41
|
+
define_method(method_name) do |*args, &block|
|
42
|
+
Gui.send(method_name, *args, &block)
|
43
|
+
end
|
44
|
+
private method_name
|
44
45
|
end
|
45
|
-
private method_name
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
|
+
include Rum::GuiMixin
|
49
50
|
|
50
51
|
def wait(timeout=5, interval=0.01)
|
51
52
|
start = Time.new
|
@@ -87,9 +88,7 @@ class String
|
|
87
88
|
Rum.hotkey_set.add_translation(self, to, condition,
|
88
89
|
FileLocation.from_stack_frame(caller.first))
|
89
90
|
end
|
90
|
-
end
|
91
91
|
|
92
|
-
class String
|
93
92
|
# Prepare a special version of #do that is only active when the user
|
94
93
|
# calls #do for the first time.
|
95
94
|
# After running Rum.setup it calls and restores the default version of #do.
|
data/lib/rum/gui.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Rum
|
2
2
|
module Gui
|
3
3
|
extend self
|
4
|
-
|
4
|
+
|
5
5
|
def self.use gui_module, *methods
|
6
6
|
if methods.empty?
|
7
7
|
include gui_module
|
@@ -56,7 +56,7 @@ module Rum
|
|
56
56
|
private
|
57
57
|
|
58
58
|
def alert_backend prompt, title
|
59
|
-
result = dialog('ok-msgbox', '--text', prompt.to_s, '--title', title.to_s)
|
59
|
+
result = dialog('ok-msgbox', '--text', prompt.to_s, '--title', title.to_s)
|
60
60
|
result.first == '1'
|
61
61
|
end
|
62
62
|
|
@@ -77,7 +77,7 @@ module Rum
|
|
77
77
|
result = dialog('standard-dropdown', '--items', *choices.map(&:to_s), *prompt)
|
78
78
|
choices[result[1].to_i] if result.first == '1'
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def dialog *args
|
82
82
|
IO.popen([@@binary, *args]) { |p| p.read }.split
|
83
83
|
end
|
data/lib/rum/help.rb
CHANGED
@@ -4,16 +4,17 @@ module Rum
|
|
4
4
|
'doc', 'reference.rb')
|
5
5
|
Gui.open_file reference
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def self.read_key &proc
|
9
9
|
KeyReader.start(hotkey_processor, proc)
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.
|
12
|
+
def self.visit_hotkey
|
13
13
|
read_key { |hotkey| Gui.message "'#{hotkey}' not active" }
|
14
14
|
Action.hook = lambda do |action|
|
15
15
|
KeyReader.remove_hooks
|
16
|
-
action.
|
16
|
+
action.visit_definition or Gui.message "Can't visit definition.\n"\
|
17
|
+
"Hotkey was not defined in a file."
|
17
18
|
# Must return true for the key that triggered the action to be
|
18
19
|
# retained by the processor.
|
19
20
|
true
|
@@ -36,7 +37,7 @@ module Rum
|
|
36
37
|
module KeyReader
|
37
38
|
extend self
|
38
39
|
attr_accessor :pressed_modifiers
|
39
|
-
|
40
|
+
|
40
41
|
Hook = proc do
|
41
42
|
@pass_key = false
|
42
43
|
if @key.modifier?
|
@@ -44,7 +45,7 @@ module Rum
|
|
44
45
|
KeyReader.pressed_modifiers << @key
|
45
46
|
elsif seen_key = KeyReader.pressed_modifiers.delete(@key)
|
46
47
|
if @key == @last_key
|
47
|
-
KeyReader.stop(@key, @pressed_modifiers)
|
48
|
+
KeyReader.stop(@key, @pressed_modifiers)
|
48
49
|
elsif @pressed_modifiers.values.compact.empty?
|
49
50
|
KeyReader.stop
|
50
51
|
end
|
@@ -55,7 +56,7 @@ module Rum
|
|
55
56
|
KeyReader.stop(@key, @pressed_modifiers)
|
56
57
|
end
|
57
58
|
end
|
58
|
-
|
59
|
+
|
59
60
|
def start(hotkey_processor, proc)
|
60
61
|
@hotkey_processor = hotkey_processor
|
61
62
|
@proc = proc
|
@@ -85,7 +86,7 @@ module Rum
|
|
85
86
|
|
86
87
|
module WindowInfo
|
87
88
|
module_function
|
88
|
-
|
89
|
+
|
89
90
|
def start
|
90
91
|
return if @thread
|
91
92
|
register_stop_key
|
@@ -96,7 +97,8 @@ module Rum
|
|
96
97
|
break if @stop
|
97
98
|
new = active_window
|
98
99
|
if new != old
|
99
|
-
|
100
|
+
window_report = new.report
|
101
|
+
Gui.message(window_report) { System::Clipboard.set window_report }
|
100
102
|
old = new
|
101
103
|
end
|
102
104
|
sleep 0.1
|
data/lib/rum/hotkey_core.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Rum
|
2
2
|
class Key
|
3
3
|
attr_accessor :name, :id, :aliases, :modifier
|
4
|
-
|
4
|
+
|
5
5
|
def initialize name, aliases, id
|
6
6
|
@name = name
|
7
7
|
@id = id
|
8
8
|
@aliases = aliases
|
9
9
|
@modifier = false
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def modifier?
|
13
13
|
@modifier
|
14
14
|
end
|
@@ -21,7 +21,7 @@ module Rum
|
|
21
21
|
class Layout
|
22
22
|
attr_accessor :ids, :names, :aliases, :modifiers, :core_modifiers, \
|
23
23
|
:action_modifiers, :translations
|
24
|
-
|
24
|
+
|
25
25
|
def initialize
|
26
26
|
@ids = {}
|
27
27
|
@names = {}
|
@@ -37,7 +37,7 @@ module Rum
|
|
37
37
|
@ids.values.uniq
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def lookup_key id
|
41
41
|
@ids[id]
|
42
42
|
end
|
43
43
|
|
@@ -60,10 +60,11 @@ module Rum
|
|
60
60
|
name = args.shift
|
61
61
|
aliases = args
|
62
62
|
key = Key.new(name, aliases, id)
|
63
|
-
|
63
|
+
|
64
64
|
@ids[id] = key
|
65
65
|
@names[name] = key
|
66
66
|
aliases.each { |key_alias| @aliases[key_alias] = key }
|
67
|
+
key
|
67
68
|
end
|
68
69
|
|
69
70
|
def alias key, key_alias
|
@@ -109,7 +110,7 @@ module Rum
|
|
109
110
|
|
110
111
|
class Hotkey
|
111
112
|
attr_accessor :key, :modifiers, :actions, :direction # todo: unveränderlich machen
|
112
|
-
|
113
|
+
|
113
114
|
def initialize key, modifiers=[], fuzzy=false, actions=[]
|
114
115
|
@key = key
|
115
116
|
@modifiers = modifiers
|
@@ -136,7 +137,7 @@ module Rum
|
|
136
137
|
attr_accessor :action, :condition, :hotkey, :location
|
137
138
|
|
138
139
|
@@hook = nil
|
139
|
-
|
140
|
+
|
140
141
|
def self.work_queue= queue
|
141
142
|
@@work_queue = queue
|
142
143
|
end
|
@@ -148,7 +149,7 @@ module Rum
|
|
148
149
|
def self.hook
|
149
150
|
@@hook
|
150
151
|
end
|
151
|
-
|
152
|
+
|
152
153
|
def initialize(action, condition, repeated, location)
|
153
154
|
@action = action
|
154
155
|
@condition = condition
|
@@ -168,8 +169,8 @@ module Rum
|
|
168
169
|
end
|
169
170
|
end
|
170
171
|
|
171
|
-
def
|
172
|
-
@location.
|
172
|
+
def visit_definition
|
173
|
+
@location.visit if @location
|
173
174
|
end
|
174
175
|
end
|
175
176
|
|
@@ -211,7 +212,7 @@ module Rum
|
|
211
212
|
down_hotkey.direction = :down
|
212
213
|
up_hotkey.direction = :up
|
213
214
|
to_key = @layout[to]
|
214
|
-
|
215
|
+
|
215
216
|
catch_modifier_up = proc do
|
216
217
|
if down_hotkey.modifiers.include? @key
|
217
218
|
send_key_event(to_key, false)
|
@@ -248,11 +249,11 @@ module Rum
|
|
248
249
|
end
|
249
250
|
end
|
250
251
|
modifiers = modifiers.sort_by &:id
|
251
|
-
|
252
|
+
|
252
253
|
# Lookup key
|
253
254
|
key = @layout[key_alias]
|
254
255
|
raise "#{key_alias} is no valid key." unless key
|
255
|
-
|
256
|
+
|
256
257
|
Hotkey.new(key, modifiers, fuzzy)
|
257
258
|
end
|
258
259
|
|
@@ -269,7 +270,7 @@ module Rum
|
|
269
270
|
end
|
270
271
|
action
|
271
272
|
end
|
272
|
-
|
273
|
+
|
273
274
|
def unregister action
|
274
275
|
if hotkey = action.hotkey
|
275
276
|
hotkey.actions.delete(action)
|
@@ -304,7 +305,7 @@ module Rum
|
|
304
305
|
end
|
305
306
|
[dict, dict_key]
|
306
307
|
end
|
307
|
-
|
308
|
+
|
308
309
|
def key_signature hotkey
|
309
310
|
hotkey.modifiers.dup << hotkey.key
|
310
311
|
end
|
@@ -317,7 +318,7 @@ module Rum
|
|
317
318
|
def register_hotkey hotkey
|
318
319
|
dict, dict_key = get_dict(hotkey)
|
319
320
|
existing_hotkey = dict[dict_key] and return existing_hotkey
|
320
|
-
|
321
|
+
|
321
322
|
dict[dict_key] = hotkey
|
322
323
|
if hotkey.key.modifier? # Modifier hotkeys aren't allowed to be fuzzy.
|
323
324
|
@modifier_hotkeys[dict_key] = hotkey
|
@@ -393,11 +394,12 @@ module Rum
|
|
393
394
|
@modifiers = @hotkey_set.modifiers
|
394
395
|
@layout = @hotkey_set.layout
|
395
396
|
@pressed_modifiers = {}
|
397
|
+
@pressed_core_modifier_ids = {}
|
396
398
|
@was_executed = {}
|
397
399
|
@key_signature = nil
|
398
400
|
@hooks = []
|
399
401
|
@pass_key = true
|
400
|
-
|
402
|
+
|
401
403
|
@key = nil
|
402
404
|
@last_key = nil
|
403
405
|
@down = nil
|
@@ -409,12 +411,12 @@ module Rum
|
|
409
411
|
@hooks.unshift hook
|
410
412
|
hook
|
411
413
|
end
|
412
|
-
|
414
|
+
|
413
415
|
# Return removed hook.
|
414
416
|
def remove_hook(hook)
|
415
417
|
@hooks.delete hook
|
416
418
|
end
|
417
|
-
|
419
|
+
|
418
420
|
def key_signature key
|
419
421
|
@modifiers.select { |modifier| @pressed_modifiers[modifier] } << key
|
420
422
|
end
|
@@ -428,7 +430,7 @@ module Rum
|
|
428
430
|
|
429
431
|
def process_event event
|
430
432
|
puts event
|
431
|
-
@key = @layout.
|
433
|
+
@key = @layout.lookup_key(event.id)
|
432
434
|
@down = event.down?
|
433
435
|
unless @key
|
434
436
|
puts "Unknown Key\n"
|
@@ -441,10 +443,10 @@ module Rum
|
|
441
443
|
@key_signature = key_signature(@key)
|
442
444
|
end
|
443
445
|
@last_event_up = !@down
|
444
|
-
|
446
|
+
|
445
447
|
print "[#{@key_signature.map { |key| key.name.capitalize }.join(', ')}]"
|
446
448
|
print ' (again)' if @key == @last_key; puts
|
447
|
-
|
449
|
+
|
448
450
|
if @down
|
449
451
|
repeated = @was_executed[@key]
|
450
452
|
eat = @was_executed[@key] = true if execute(true, repeated)
|
@@ -452,11 +454,13 @@ module Rum
|
|
452
454
|
eat = true
|
453
455
|
elsif modifier # if repeated, the modifier has already been added to pressed_modifiers
|
454
456
|
@pressed_modifiers[@key] = true
|
457
|
+
@pressed_core_modifier_ids[event.id] = true if @layout.core_modifiers[@key]
|
455
458
|
end
|
456
459
|
else #up
|
457
460
|
@was_executed[@key] = true if execute(false, false)
|
458
461
|
if modifier
|
459
|
-
@pressed_modifiers[@key] = nil
|
462
|
+
@pressed_modifiers[@key] = nil
|
463
|
+
@pressed_core_modifier_ids[event.id] = nil if @layout.core_modifiers[@key]
|
460
464
|
if @layout.action_modifiers[@key] and \
|
461
465
|
(!@pass_key or @was_executed[@key])
|
462
466
|
inhibit_modifier_action
|
@@ -464,7 +468,7 @@ module Rum
|
|
464
468
|
end
|
465
469
|
eat = @was_executed.delete(@key)
|
466
470
|
end
|
467
|
-
|
471
|
+
|
468
472
|
@pass_key = if modifier
|
469
473
|
@layout.core_modifiers[@key]
|
470
474
|
else
|
@@ -473,7 +477,13 @@ module Rum
|
|
473
477
|
@hooks.dup.each { |hook| instance_eval &hook }
|
474
478
|
@last_key = @key
|
475
479
|
puts
|
476
|
-
@pass_key
|
480
|
+
@pass_key
|
481
|
+
end
|
482
|
+
|
483
|
+
def release_core_modifiers
|
484
|
+
@pressed_core_modifier_ids.each do |id, pressed|
|
485
|
+
send_key_event_for_id id, false if pressed
|
486
|
+
end
|
477
487
|
end
|
478
488
|
end
|
479
489
|
end
|