rum 0.0.1-universal-darwin-10 → 0.0.3-universal-darwin-10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) 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/keyboard_hook/KeyboardHook.framework/KeyboardHook +0 -0
  34. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/KeyboardHook +0 -0
  35. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/English.lproj/InfoPlist.strings +0 -0
  36. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/Info.plist +16 -0
  37. data/lib/rum/mac/layouts.rb +4 -4
  38. data/lib/rum/mac/system.rb +2 -2
  39. data/lib/rum/remote.rb +3 -3
  40. data/lib/rum/server.rb +2 -3
  41. data/lib/rum/windows.rb +2 -1
  42. data/lib/rum/windows/app.rb +12 -7
  43. data/lib/rum/windows/apps.rb +3 -8
  44. data/lib/rum/windows/gui.rb +8 -8
  45. data/lib/rum/windows/keyboard.rb +34 -9
  46. data/lib/rum/windows/layouts.rb +6 -6
  47. data/lib/rum/windows/system.rb +71 -28
  48. data/lib/rum/windows/system_foreign_functions.rb +44 -20
  49. data/rum.gemspec +2 -2
  50. metadata +32 -53
  51. data/README +0 -30
@@ -6,7 +6,7 @@ require 'rum/mac/app'
6
6
 
7
7
  module Rum
8
8
  Platform = :mac
9
-
9
+
10
10
  def self.restart_platform_specific
11
11
  Rum::Server.close_connections
12
12
  exec(RUBY_ENGINE, $PROGRAM_NAME)
@@ -17,7 +17,7 @@ module Rum
17
17
  url = NSURL.URLWithString(url)
18
18
  NSWorkspace.sharedWorkspace.openURL(url)
19
19
  end
20
-
20
+
21
21
  binary = File.join(File.dirname(__FILE__),
22
22
  'gui/CocoaDialog.app/Contents/MacOS/CocoaDialog')
23
23
  CocoaDialog.setup binary
@@ -8,7 +8,7 @@ module Rum
8
8
  @callbacks = {}
9
9
  GrowlApplicationBridge.setGrowlDelegate(self)
10
10
  end
11
-
11
+
12
12
  def registrationDictionaryForGrowl
13
13
  notifications = [@notification_name]
14
14
  { TicketVersion: 1, AllNotifications: notifications,
@@ -42,9 +42,9 @@ module Rum
42
42
  framework File.join(File.dirname(__FILE__), 'Growl.framework')
43
43
  @@notifier = Notifier.new('Rum', 'Notification')
44
44
  end
45
-
45
+
46
46
  private
47
-
47
+
48
48
  def message_backend(text, title, sticky, callback)
49
49
  title ||= 'Rum' # Mac Growl needs a title
50
50
  @@notifier.notify(title, text, sticky, callback)
@@ -1,5 +1,5 @@
1
1
  #
2
- # irb/completor.rb -
2
+ # irb/completor.rb -
3
3
  # $Release Version: 0.9$
4
4
  # $Revision: 23233 $
5
5
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
@@ -15,16 +15,16 @@ module IRB
15
15
 
16
16
  ReservedWords = [
17
17
  "BEGIN", "END",
18
- "alias", "and",
19
- "begin", "break",
18
+ "alias", "and",
19
+ "begin", "break",
20
20
  "case", "class",
21
21
  "def", "defined", "do",
22
22
  "else", "elsif", "end", "ensure",
23
- "false", "for",
24
- "if", "in",
25
- "module",
23
+ "false", "for",
24
+ "if", "in",
25
+ "module",
26
26
  "next", "nil", "not",
27
- "or",
27
+ "or",
28
28
  "redo", "rescue", "retry", "return",
29
29
  "self", "super",
30
30
  "then", "true",
@@ -32,10 +32,10 @@ module IRB
32
32
  "when", "while",
33
33
  "yield",
34
34
  ]
35
-
35
+
36
36
  CompletionProc = proc { |input|
37
37
  bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
38
-
38
+
39
39
  # puts "input: #{input}"
40
40
 
41
41
  case input
@@ -63,7 +63,7 @@ module IRB
63
63
  candidates = Proc.instance_methods.collect{|m| m.to_s}
64
64
  candidates |= Hash.instance_methods.collect{|m| m.to_s}
65
65
  select_message(receiver, message, candidates)
66
-
66
+
67
67
  when /^(:[^:.]*)$/
68
68
  # Symbol
69
69
  if Symbol.respond_to?(:all_symbols)
@@ -137,7 +137,7 @@ module IRB
137
137
  gv = eval("global_variables", bind).collect{|m| m.to_s}
138
138
  lv = eval("local_variables", bind).collect{|m| m.to_s}
139
139
  cv = eval("self.class.constants", bind).collect{|m| m.to_s}
140
-
140
+
141
141
  if (gv | lv | cv).include?(receiver)
142
142
  # foo.func and foo is local var.
143
143
  candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
@@ -157,7 +157,7 @@ module IRB
157
157
  rescue Exception
158
158
  name = ""
159
159
  end
160
- next if name != "IRB::Context" and
160
+ next if name != "IRB::Context" and
161
161
  /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
162
162
  candidates.concat m.instance_methods(false).collect{|x| x.to_s}
163
163
  }
@@ -177,7 +177,7 @@ module IRB
177
177
 
178
178
  else
179
179
  candidates = eval("methods | private_methods | local_variables | self.class.constants", bind).collect{|m| m.to_s}
180
-
180
+
181
181
  (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
182
182
  end
183
183
  }
@@ -1,4 +1,8 @@
1
- framework "ApplicationServices"
1
+ framework 'CoreGraphics' # OS X 10.8 location for kCGKeyboardEventKeycode and related symbols
2
+ unless defined? KCGKeyboardEventKeycode
3
+ framework 'ApplicationServices' # 10.7 location
4
+ end
5
+
2
6
  framework "#{File.dirname(__FILE__)}/keyboard_hook/KeyboardHook.framework"
3
7
  framework 'Cocoa'
4
8
 
@@ -16,7 +20,7 @@ module KeyboardHook
16
20
  end
17
21
 
18
22
  class EventTap
19
- def handleEvent(event)
23
+ def handleKeyEvent(event)
20
24
  event if @proc.call(event)
21
25
  end
22
26
 
@@ -41,7 +45,7 @@ class Event
41
45
  def keycode
42
46
  get_integer_value_field(KCGKeyboardEventKeycode)
43
47
  end
44
-
48
+
45
49
  def id
46
50
  get_integer_value_field(KCGKeyboardEventKeycode)
47
51
  end
@@ -63,11 +67,10 @@ class Event
63
67
  end
64
68
 
65
69
  def get_flags
66
- CGEventGetFlags(eventRef)
70
+ CGEventGetFlags(eventRef)
67
71
  end
68
72
 
69
73
  def set_flags(flags)
70
74
  CGEventSetFlags(eventRef, flags)
71
75
  end
72
76
  end
73
-
@@ -2,6 +2,8 @@
2
2
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
3
  <plist version="1.0">
4
4
  <dict>
5
+ <key>BuildMachineOSBuild</key>
6
+ <string>12C54</string>
5
7
  <key>CFBundleDevelopmentRegion</key>
6
8
  <string>English</string>
7
9
  <key>CFBundleExecutable</key>
@@ -18,5 +20,19 @@
18
20
  <string>????</string>
19
21
  <key>CFBundleVersion</key>
20
22
  <string>1.0</string>
23
+ <key>DTCompiler</key>
24
+ <string></string>
25
+ <key>DTPlatformBuild</key>
26
+ <string>4G2008a</string>
27
+ <key>DTPlatformVersion</key>
28
+ <string>GM</string>
29
+ <key>DTSDKBuild</key>
30
+ <string>11E52</string>
31
+ <key>DTSDKName</key>
32
+ <string>macosx10.7</string>
33
+ <key>DTXcode</key>
34
+ <string>0452</string>
35
+ <key>DTXcodeBuild</key>
36
+ <string>4G2008a</string>
21
37
  </dict>
22
38
  </plist>
@@ -3,7 +3,7 @@
3
3
  module Rum
4
4
  module Layouts
5
5
  module_function
6
-
6
+
7
7
  def default_layout
8
8
  us
9
9
  end
@@ -11,7 +11,7 @@ module Rum
11
11
  # /System/Library/Frameworks/Carbon.framework/.../Events.h
12
12
  def core
13
13
  core = Layout.new
14
-
14
+
15
15
  [['return', "\n", 36],
16
16
  ['tab', 48],
17
17
  ['space', ' ', 49],
@@ -60,7 +60,7 @@ module Rum
60
60
  ['rightarrow', 124],
61
61
  ['downarrow', 125],
62
62
  ['uparrow', 126]].each { |key| core.add *key }
63
-
63
+
64
64
  core
65
65
  end
66
66
 
@@ -123,7 +123,7 @@ module Rum
123
123
  5 = 9 7 - 8 0 ] o u [ i p _ l j _ k ; _ , / n m .}.each_with_index do |key, id|
124
124
  us.add key, id unless key == '_'
125
125
  end
126
-
126
+
127
127
  us.add "'", 39
128
128
  us.add '\\', 42
129
129
  us.add '`', 50
@@ -5,9 +5,9 @@ module Rum
5
5
  def applescript src
6
6
  pointer = Pointer.new_with_type("@")
7
7
  as = NSAppleScript.alloc.initWithSource(src)
8
- as.executeAndReturnError(pointer)
8
+ as.executeAndReturnError(pointer)
9
9
  end
10
-
10
+
11
11
  def start *args
12
12
  system 'open', *args
13
13
  end
@@ -31,15 +31,15 @@ module Rum
31
31
  msg.force_encoding Encoding::BINARY
32
32
  write([msg.length].pack('N') + msg)
33
33
  end
34
-
34
+
35
35
  def receive
36
36
  if message_size = read(4) # sizeof (N)
37
- message_size = message_size.unpack('N')[0]
37
+ message_size = message_size.unpack('N')[0]
38
38
  read(message_size).force_encoding(Encoding::UTF_8)
39
39
  end
40
40
  end
41
41
  end
42
-
42
+
43
43
  def Connection.new(stream)
44
44
  stream.extend Messaging
45
45
  end
@@ -3,7 +3,7 @@ require 'rum/remote'
3
3
  module Rum
4
4
  module Server
5
5
  module_function
6
-
6
+
7
7
  # This makes it easier for code to check if it runs inside the server thread.
8
8
  def thread
9
9
  @thread
@@ -15,7 +15,6 @@ module Rum
15
15
  @server = TCPServer.new('127.0.0.1', Remote.default_port)
16
16
  puts "Server started."
17
17
  begin
18
- @connection = nil
19
18
  loop do
20
19
  @connection = Remote::Connection.new(@server.accept)
21
20
  handle(@connection)
@@ -71,7 +70,7 @@ module Rum
71
70
  workspace = Struct.new(:binding).new(binding)
72
71
  context = Struct.new(:workspace).new(workspace)
73
72
  @CONF = { MAIN_CONTEXT: context }
74
-
73
+
75
74
  def IRB.conf
76
75
  @CONF
77
76
  end'
@@ -7,7 +7,7 @@ require 'rum/windows/layouts'
7
7
 
8
8
  module Rum
9
9
  Platform = :windows
10
-
10
+
11
11
  def self.restart_platform_specific
12
12
  Rum::Server.stop
13
13
  System.spawn_in_terminal('ruby', $PROGRAM_NAME)
@@ -21,3 +21,4 @@ module Rum
21
21
  end
22
22
  end
23
23
  end
24
+
@@ -3,11 +3,11 @@ module Rum
3
3
  include System
4
4
 
5
5
  @@apps = {}
6
-
6
+
7
7
  def self.add(app)
8
8
  @@apps[app.binary] = app
9
9
  end
10
-
10
+
11
11
  def self.remove(app)
12
12
  @@apps.delete(app.binary)
13
13
  end
@@ -22,16 +22,21 @@ module Rum
22
22
 
23
23
  attr_accessor :path, :binary, :matcher
24
24
 
25
- def initialize(path, *matcher)
26
- @path = append_path_to_programfiles_if_relative(path)
25
+ def initialize(path, *args)
26
+ x64 = args.delete :x64
27
+ @path = append_path_to_programfiles_if_relative(path, x64)
27
28
  @binary = File.basename(@path).sub(/\.exe$/, '').downcase
28
- @matcher = WindowMatcher.new(*matcher)
29
+ @matcher = WindowMatcher.new(*args)
29
30
  App.add(self)
30
31
  end
31
32
 
32
- def append_path_to_programfiles_if_relative(path)
33
+ PROGRAM_FILES = ENV['PROGRAMFILES'].gsub('\\', '/')
34
+ PROGRAM_FILES_X64 = ENV['ProgramW6432'].gsub('\\', '/')
35
+
36
+ def append_path_to_programfiles_if_relative(path, x64)
33
37
  if path !~ /^\w:|^%/
34
- path = File.join(ENV['PROGRAMFILES'].gsub("\\", '/'), path)
38
+ program_files = x64 ? PROGRAM_FILES_X64 : PROGRAM_FILES
39
+ path = File.join(program_files, path)
35
40
  end
36
41
  path
37
42
  end
@@ -8,18 +8,13 @@ def Firefox.activate_and_focus_address_bar
8
8
  Keyboard.type '(ctrl l)' if activate
9
9
  end
10
10
 
11
- Photoshop = App.new('Adobe/Adobe Photoshop CS5/Photoshop', nil, 'Photoshop')
11
+ Photoshop = App.new('Adobe/Adobe Photoshop CS6 (64 Bit)/Photoshop', nil, 'Photoshop', :x64)
12
12
  class << Photoshop
13
13
  def next_blend_mode
14
- if Rum.layout['ö'] # german layout
15
- type '(shift 0)'
16
- else
17
- type '(shift +)'
18
- end
14
+ type '(shift (add))'
19
15
  end
20
16
 
21
17
  def previous_blend_mode
22
- type '(shift -)'
18
+ type '(shift (subtract))'
23
19
  end
24
20
  end
25
-
@@ -7,7 +7,7 @@ module Rum
7
7
  Gui.message "Can't visit a file in Windows Explorer."
8
8
  end
9
9
  end
10
-
10
+
11
11
  def open_file file, line=nil
12
12
  System.start file
13
13
  end
@@ -23,7 +23,7 @@ module Rum
23
23
  def alert_backend text, title
24
24
  System.message_box text, title
25
25
  end
26
-
26
+
27
27
  def message_backend text, title, sticky, callback
28
28
  alert text, title
29
29
  end
@@ -39,7 +39,7 @@ module Rum
39
39
  Message = 'message'
40
40
 
41
41
  private
42
-
42
+
43
43
  def message_backend(text, title, sticky, callback)
44
44
  unless title
45
45
  title = text
@@ -50,13 +50,13 @@ module Rum
50
50
  if callback
51
51
  on_click = lambda { |event| callback.call if event[:callback_result] == "CLICK" }
52
52
  end
53
-
53
+
54
54
  Growl.client.notify(name: Message, title: title,
55
55
  text: text, sticky: sticky, &on_click)
56
56
  end
57
-
57
+
58
58
  module_function
59
-
59
+
60
60
  def auto_setup
61
61
  require 'ruby_gntp'
62
62
  @growl = GNTP.new("Rum")
@@ -73,10 +73,10 @@ module Rum
73
73
 
74
74
  module EmacsInteraction
75
75
  private
76
-
76
+
77
77
  def interaction(*args)
78
78
  emacs = Emacs.window
79
- return '' unless emacs
79
+ return unless emacs
80
80
  unless (emacs_already_active = emacs.active?)
81
81
  old = System.active_window
82
82
  emacs.move(400, 400, 800, 300)
@@ -3,21 +3,24 @@ require 'strscan'
3
3
  module Rum
4
4
  module Keyboard
5
5
  extend self
6
-
6
+
7
7
  def type(key_sequence, *args)
8
8
  release_core_modifiers unless args.include? :blind
9
9
  type_sequence(key_sequence, args.include?(:slow))
10
10
  end
11
-
11
+
12
12
  def type!(key_sequence, *args)
13
13
  release_core_modifiers unless args.include? :blind
14
14
  type_sequence_literally(key_sequence, args.include?(:slow))
15
15
  end
16
16
 
17
+ def type_unicode(key_sequence, *args)
18
+ release_core_modifiers unless args.include? :blind
19
+ type_sequence_unicode(key_sequence, args.include?(:slow))
20
+ end
21
+
17
22
  def release_core_modifiers
18
- pressed = Rum.hotkey_processor.pressed_modifiers
19
- to_release = Rum.layout.core_modifiers.keys.select { |mod| pressed[mod] }
20
- to_release.each { |key| System.send_key_event key, false }
23
+ Rum.hotkey_processor.release_core_modifiers
21
24
  end
22
25
 
23
26
  private
@@ -39,7 +42,7 @@ module Rum
39
42
  while (char = s.getch)
40
43
  case char
41
44
  when '\\'
42
- down_and_up(s.getch, slow)
45
+ (char = s.getch) and down_and_up(char, slow)
43
46
  when '('
44
47
  key = s.scan(/[^() ]+/)
45
48
  s.skip /\ /
@@ -55,10 +58,26 @@ module Rum
55
58
  pressed_keys.reverse_each { |key| up key }
56
59
  end
57
60
 
58
- def send_key(key, down)
59
- if id = Rum.layout[key]
60
- System.send_key_event id, down
61
+ def type_sequence_unicode(key_sequence, slow)
62
+ s = StringScanner.new(key_sequence)
63
+ pressed_keys = []
64
+ while (char = s.getch)
65
+ case char
66
+ when '\\'
67
+ (char = s.getch) and System.send_unicode_char(char)
68
+ when '('
69
+ key = s.scan(/[^() ]+/)
70
+ s.skip /\ /
71
+ down key
72
+ pressed_keys << key
73
+ when ')'
74
+ up pressed_keys.pop
75
+ else
76
+ System.send_unicode_char(char)
77
+ end
78
+ sleep 0.01 if slow
61
79
  end
80
+ pressed_keys.reverse_each { |key| up key }
62
81
  end
63
82
 
64
83
  def down(key)
@@ -76,5 +95,11 @@ module Rum
76
95
  type_sequence(key_sequence, slow)
77
96
  end
78
97
  end
98
+
99
+ def send_key(key_alias, down)
100
+ if key = Rum.layout[key_alias]
101
+ System.send_key_event key, down
102
+ end
103
+ end
79
104
  end
80
105
  end