ver 2009.10.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. data/CHANGELOG +1404 -0
  2. data/MANIFEST +187 -0
  3. data/Rakefile +30 -0
  4. data/TODO +169 -0
  5. data/bin/ver +19 -0
  6. data/config/detect.rb +109 -0
  7. data/config/keymap/vim.rb +239 -0
  8. data/config/rc.rb +0 -0
  9. data/config/scratch +3 -0
  10. data/config/syntax/ANTLR.json +275 -0
  11. data/config/syntax/ASP VB.net.json +228 -0
  12. data/config/syntax/ASP.json +135 -0
  13. data/config/syntax/ActionScript.json +168 -0
  14. data/config/syntax/Ada.json +108 -0
  15. data/config/syntax/Apache.json +342 -0
  16. data/config/syntax/AppleScript.json +721 -0
  17. data/config/syntax/Bibtex.json +253 -0
  18. data/config/syntax/Blog (HTML).json +47 -0
  19. data/config/syntax/Blog (Markdown).json +50 -0
  20. data/config/syntax/Blog (Text).json +45 -0
  21. data/config/syntax/Blog (Textile).json +45 -0
  22. data/config/syntax/Bulletin Board.json +428 -0
  23. data/config/syntax/C++.json +323 -0
  24. data/config/syntax/C.json +694 -0
  25. data/config/syntax/CSS.json +346 -0
  26. data/config/syntax/DOT.json +79 -0
  27. data/config/syntax/Diff.json +136 -0
  28. data/config/syntax/Dylan.json +104 -0
  29. data/config/syntax/Eiffel.json +128 -0
  30. data/config/syntax/Erlang.json +1636 -0
  31. data/config/syntax/F-Script.json +137 -0
  32. data/config/syntax/FXScript.json +260 -0
  33. data/config/syntax/Gri.json +141 -0
  34. data/config/syntax/HTML (Mason).json +207 -0
  35. data/config/syntax/HTML (Rails).json +52 -0
  36. data/config/syntax/HTML (Tcl).json +42 -0
  37. data/config/syntax/HTML for ASP.net.json +736 -0
  38. data/config/syntax/HTML-ASP.json +45 -0
  39. data/config/syntax/HTML.json +614 -0
  40. data/config/syntax/Haskell.json +407 -0
  41. data/config/syntax/Inform.json +80 -0
  42. data/config/syntax/Ini.json +91 -0
  43. data/config/syntax/Io.json +142 -0
  44. data/config/syntax/Java.json +745 -0
  45. data/config/syntax/JavaProperties.json +42 -0
  46. data/config/syntax/JavaScript.json +446 -0
  47. data/config/syntax/LaTeX Beamer.json +65 -0
  48. data/config/syntax/LaTeX Log.json +88 -0
  49. data/config/syntax/LaTeX.json +962 -0
  50. data/config/syntax/Lighttpd.json +93 -0
  51. data/config/syntax/Lisp.json +101 -0
  52. data/config/syntax/Literate Haskell.json +55 -0
  53. data/config/syntax/Logtalk.json +289 -0
  54. data/config/syntax/Lua.json +146 -0
  55. data/config/syntax/M.json +744 -0
  56. data/config/syntax/MEL.json +161 -0
  57. data/config/syntax/MIPS.json +114 -0
  58. data/config/syntax/Mail.json +224 -0
  59. data/config/syntax/Makefile.json +66 -0
  60. data/config/syntax/Markdown.json +644 -0
  61. data/config/syntax/Modula-3.json +80 -0
  62. data/config/syntax/Movable Type.json +348 -0
  63. data/config/syntax/OCaml.json +1391 -0
  64. data/config/syntax/Objective-C++.json +21 -0
  65. data/config/syntax/OpenGL.json +24 -0
  66. data/config/syntax/PHP.json +2184 -0
  67. data/config/syntax/Pascal.json +128 -0
  68. data/config/syntax/Perl.json +2091 -0
  69. data/config/syntax/Plain text.json +49 -0
  70. data/config/syntax/Processing.json +188 -0
  71. data/config/syntax/Quake3 Config.json +54 -0
  72. data/config/syntax/R.json +157 -0
  73. data/config/syntax/Rez.json +137 -0
  74. data/config/syntax/Ruby on Rails.json +170 -0
  75. data/config/syntax/Ruby.json +1753 -0
  76. data/config/syntax/SQL (Rails).json +31 -0
  77. data/config/syntax/SQL.json +435 -0
  78. data/config/syntax/SWIG.json +96 -0
  79. data/config/syntax/Scheme.json +359 -0
  80. data/config/syntax/Shell-Unix-Generic.json +1198 -0
  81. data/config/syntax/Slate.json +265 -0
  82. data/config/syntax/Smarty.json +110 -0
  83. data/config/syntax/Standard ML.json +322 -0
  84. data/config/syntax/Subversion commit message.json +62 -0
  85. data/config/syntax/Tcl.json +278 -0
  86. data/config/syntax/TeX Math.json +83 -0
  87. data/config/syntax/TeX.json +157 -0
  88. data/config/syntax/Textile.json +273 -0
  89. data/config/syntax/Twiki.json +436 -0
  90. data/config/syntax/Vectorscript.json +97 -0
  91. data/config/syntax/XML strict.json +148 -0
  92. data/config/syntax/XML.json +301 -0
  93. data/config/syntax/XSL.json +96 -0
  94. data/config/syntax/YAML.json +293 -0
  95. data/config/syntax/iCalendar.json +51 -0
  96. data/config/syntax/reStructuredText.json +403 -0
  97. data/config/theme/Active4D.json +260 -0
  98. data/config/theme/All Hallow's Eve.json +171 -0
  99. data/config/theme/Amy.json +359 -0
  100. data/config/theme/BBEdit.json +269 -0
  101. data/config/theme/Bespin.json +322 -0
  102. data/config/theme/Blackboard.json +215 -0
  103. data/config/theme/BoysAndGirls01.json +156 -0
  104. data/config/theme/Brilliance Black.json +1695 -0
  105. data/config/theme/Brilliance Dull.json +1451 -0
  106. data/config/theme/Classic Modified.json +288 -0
  107. data/config/theme/Cobalt.json +345 -0
  108. data/config/theme/Cool Glow.json +215 -0
  109. data/config/theme/Dawn.json +258 -0
  110. data/config/theme/Eiffel.json +270 -0
  111. data/config/theme/Espresso Libre.json +247 -0
  112. data/config/theme/Fluidvision.json +272 -0
  113. data/config/theme/IDLE.json +159 -0
  114. data/config/theme/LAZY.json +178 -0
  115. data/config/theme/Mac Classic.json +277 -0
  116. data/config/theme/MagicWB (Amiga).json +231 -0
  117. data/config/theme/Merbivore Soft.json +181 -0
  118. data/config/theme/Merbivore.json +181 -0
  119. data/config/theme/Monokai.json +177 -0
  120. data/config/theme/Notepad2.json +166 -0
  121. data/config/theme/Pastels on Dark.json +437 -0
  122. data/config/theme/RubyBlue.json +226 -0
  123. data/config/theme/Sin City 2.json +361 -0
  124. data/config/theme/Slate.json +270 -0
  125. data/config/theme/Slush & Poppies.json +232 -0
  126. data/config/theme/SpaceCadet.json +143 -0
  127. data/config/theme/Sunburst.json +415 -0
  128. data/config/theme/Twilight BG FG.json +633 -0
  129. data/config/theme/Twilight.json +321 -0
  130. data/config/theme/Whys Poignant.json +119 -0
  131. data/config/theme/Zenburnesque.json +237 -0
  132. data/config/theme/barf.json +155 -0
  133. data/config/theme/fake.json +418 -0
  134. data/config/theme/happydeluxe.json +114 -0
  135. data/config/theme/iLife 05.json +393 -0
  136. data/config/theme/iPlastic.json +177 -0
  137. data/config/theme/mintBlue Dark.json +414 -0
  138. data/config/theme/mintBlue.json +415 -0
  139. data/config/theme/monoindustrial.json +276 -0
  140. data/config/theme/starlight.json +67 -0
  141. data/config/tutorial +74 -0
  142. data/config/welcome +115 -0
  143. data/help/index.verh +14 -0
  144. data/lib/ver.rb +156 -0
  145. data/lib/ver/entry.rb +97 -0
  146. data/lib/ver/keymap.rb +96 -0
  147. data/lib/ver/layout.rb +107 -0
  148. data/lib/ver/methods.rb +19 -0
  149. data/lib/ver/methods/completion.rb +116 -0
  150. data/lib/ver/methods/control.rb +340 -0
  151. data/lib/ver/methods/insert.rb +6 -0
  152. data/lib/ver/methods/move.rb +65 -0
  153. data/lib/ver/methods/search.rb +33 -0
  154. data/lib/ver/methods/select.rb +145 -0
  155. data/lib/ver/methods/views.rb +21 -0
  156. data/lib/ver/mode.rb +160 -0
  157. data/lib/ver/options.rb +207 -0
  158. data/lib/ver/plist.rb +106 -0
  159. data/lib/ver/status.rb +67 -0
  160. data/lib/ver/syntax.rb +68 -0
  161. data/lib/ver/syntax/detector.rb +53 -0
  162. data/lib/ver/syntax/processor.rb +48 -0
  163. data/lib/ver/text.rb +374 -0
  164. data/lib/ver/textpow.rb +357 -0
  165. data/lib/ver/theme.rb +162 -0
  166. data/lib/ver/vendor/fuzzy_file_finder.rb +340 -0
  167. data/lib/ver/view.rb +163 -0
  168. data/lib/ver/view/entry.rb +28 -0
  169. data/lib/ver/view/list.rb +137 -0
  170. data/lib/ver/view/list/buffer.rb +27 -0
  171. data/lib/ver/view/list/fuzzy_file_finder.rb +44 -0
  172. data/lib/ver/view/list/syntax.rb +13 -0
  173. data/lib/ver/view/list/theme.rb +13 -0
  174. data/spec/keymap.rb +224 -0
  175. data/tasks/bacon.rake +49 -0
  176. data/tasks/changelog.rake +18 -0
  177. data/tasks/gem.rake +22 -0
  178. data/tasks/gem_installer.rake +76 -0
  179. data/tasks/grancher.rake +12 -0
  180. data/tasks/install_dependencies.rake +6 -0
  181. data/tasks/manifest.rake +4 -0
  182. data/tasks/plist2json.rake +35 -0
  183. data/tasks/rcov.rake +18 -0
  184. data/tasks/release.rake +12 -0
  185. data/tasks/reversion.rake +8 -0
  186. data/tasks/syntax_list.rake +31 -0
  187. data/ver.gemspec +29 -0
  188. metadata +241 -0
@@ -0,0 +1,28 @@
1
+ module VER
2
+ class View
3
+ # This sucks, should we go method_missing?
4
+ class Entry < VER::Entry
5
+ attr_accessor :list_view
6
+
7
+ def pick_first
8
+ list_view.pick_first
9
+ end
10
+
11
+ def pick_selection
12
+ list_view.pick_selection
13
+ end
14
+
15
+ def cancel
16
+ list_view.cancel
17
+ end
18
+
19
+ def go_line_up
20
+ list_view.go_line_up
21
+ end
22
+
23
+ def go_line_down
24
+ list_view.go_line_down
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,137 @@
1
+ module VER
2
+ class View::List < Struct.new(:parent, :frame, :list, :entry, :tag, :callback)
3
+ autoload :Buffer, 'ver/view/list/buffer'
4
+ autoload :Window, 'ver/view/list/buffer'
5
+ autoload :FuzzyFileFinder, 'ver/view/list/fuzzy_file_finder'
6
+ autoload :Syntax, 'ver/view/list/syntax'
7
+ autoload :Theme, 'ver/view/list/theme'
8
+
9
+ def initialize(parent, &block)
10
+ self.parent, self.callback = parent, block
11
+
12
+ setup_widgets
13
+ setup_keymap
14
+ setup_events
15
+ on_update
16
+ end
17
+
18
+ def setup_widgets
19
+ self.frame = TkFrame.new{
20
+ pack fill: :both, expand: true
21
+ }
22
+
23
+ self.list = Tk::Listbox.new(frame){
24
+ setgrid 'yes'
25
+ width 0
26
+ background '#000'
27
+ foreground '#fff'
28
+ selectforeground '#000'
29
+ selectbackground '#fff'
30
+ font VER.options[:font]
31
+ pack fill: :both, expand: true
32
+ }
33
+
34
+ self.entry = View::Entry.new(frame){
35
+ pack fill: :x, expand: false
36
+ font VER.options[:font]
37
+ focus
38
+ }
39
+ entry.list_view = self
40
+ end
41
+
42
+ def setup_keymap
43
+ keymap_name = VER.options.fetch(:keymap)
44
+
45
+ @list_keymap = Keymap.get(
46
+ name: keymap_name, receiver: self, widget: list, mode: :list_view_list)
47
+
48
+ @entry_keymap = Keymap.get(
49
+ name: keymap_name, receiver: entry, widget: entry, mode: :list_view_entry)
50
+ end
51
+
52
+ # Setup this event, because Keymap gets very confused when you bind 'Key' and
53
+ # we don't want to break the event-chain anyway
54
+ def setup_events
55
+ entry.bind('<Modified>'){ on_update }
56
+ end
57
+
58
+ def on_update
59
+ update
60
+ list.selection_set(0)
61
+ list.activate(0)
62
+ end
63
+
64
+ def quit
65
+ Tk.exit
66
+ end
67
+
68
+ def go_line_up
69
+ index = list.curselection.first - 1
70
+
71
+ if index >= 0
72
+ list.selection_clear(0, 'end')
73
+ select_index(index)
74
+ end
75
+ end
76
+
77
+ def go_line_down
78
+ index = list.curselection.first + 1
79
+ max = list.size
80
+
81
+ if index < max
82
+ list.selection_clear(0, 'end')
83
+ select_index(index)
84
+ end
85
+ end
86
+
87
+ def select_index(index)
88
+ list.selection_set(index)
89
+ list.activate(index)
90
+ list.see(index)
91
+ end
92
+
93
+ def cancel
94
+ destroy
95
+ end
96
+
97
+ def destroy
98
+ entry.destroy
99
+ list.destroy
100
+ frame.destroy
101
+ parent.focus
102
+ end
103
+
104
+ def sublist(list, input = entry.value)
105
+ if input == input.downcase
106
+ list.select{|item| item.to_s.downcase.include?(input) }
107
+ else
108
+ list.select{|item| item.to_s.include?(input) }
109
+ end
110
+ end
111
+
112
+ def pick(item)
113
+ if list.size > 0
114
+ pick_action(item)
115
+ destroy
116
+ else
117
+ message "VER is confused, what did you actually want to do?"
118
+ end
119
+ end
120
+
121
+ def pick_first
122
+ pick list.get(0)
123
+ end
124
+
125
+ def pick_selection
126
+ pick TkSelection.get
127
+ end
128
+
129
+ def pick_action(item)
130
+ callback.call(item) if callback
131
+ end
132
+
133
+ def message(string)
134
+ parent.status.message(string)
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,27 @@
1
+ module VER
2
+ class View::List::Window < View::List
3
+ def update
4
+ list.value = sublist(windows.keys)
5
+ end
6
+
7
+ def windows
8
+ path_view = parent.layout.views.map{|view| [view.filename.to_s, view] }
9
+ Hash[path_view]
10
+ end
11
+
12
+ def pick_action(filename)
13
+ view = windows[filename]
14
+ callback.call(view) if callback && view
15
+ end
16
+ end
17
+
18
+ class View::List::Buffer < View::List
19
+ def update
20
+ list.value = sublist(buffers)
21
+ end
22
+
23
+ def buffers
24
+ VER.paths.map(&:to_s).select {|b| ! b.empty? }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ require 'ver/vendor/fuzzy_file_finder'
2
+
3
+ module VER
4
+ class View::List::FuzzyFileFinder < View::List
5
+ FFF = ::FuzzyFileFinder
6
+
7
+ def fffinder
8
+ @fffinder ||= FFF.new(Dir.pwd)
9
+ rescue FFF::TooManyEntries
10
+ message "The FuzzyFileFinder is overwhelmed by the amount of files"
11
+ destroy
12
+ end
13
+
14
+ def update
15
+ choices = fffinder.find(entry.value.chomp('/'))
16
+ choices = choices.sort_by{|m| [-m[:score], m[:path]] }
17
+
18
+ list.clear
19
+
20
+ pwd = Dir.pwd + '/'
21
+ choices.each do |choice|
22
+ choice[:path].sub!(pwd, '')
23
+ insert_choice(choice)
24
+ end
25
+ end
26
+
27
+ def insert_choice(choice)
28
+ path, score = choice.values_at(:path, :score)
29
+ list.insert(:end, path)
30
+
31
+ foreground, background =
32
+ case score
33
+ when 0 ; ['white', 'black']
34
+ when 0 ..0.25 ; ['red', 'black']
35
+ when 0.25..0.75 ; ['yellow', 'black']
36
+ when 0.75..1 ; ['green', 'black']
37
+ end
38
+
39
+ list.itemconfigure(:end,
40
+ foreground: foreground, background: background,
41
+ selectforeground: background, selectbackground: foreground)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,13 @@
1
+ module VER
2
+ class View::List::Syntax < View::List
3
+ def update
4
+ list.value = sublist(syntaxes)
5
+ end
6
+
7
+ def syntaxes
8
+ VER::Syntax.list.map do |fullpath|
9
+ File.basename(fullpath, File.extname(fullpath))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module VER
2
+ class View::List::Theme < View::List
3
+ def update
4
+ list.value = sublist(themes)
5
+ end
6
+
7
+ def themes
8
+ VER::Theme.list.map do |fullpath|
9
+ File.basename(fullpath, File.extname(fullpath))
10
+ end
11
+ end
12
+ end
13
+ end
data/spec/keymap.rb ADDED
@@ -0,0 +1,224 @@
1
+ require 'bacon'
2
+ Bacon.summary_on_exit
3
+
4
+ module VER
5
+ class Keyboard
6
+ end
7
+
8
+ class Keymap
9
+ attr_accessor :modes, :current_mode
10
+
11
+ def initialize
12
+ @modes = {}
13
+ end
14
+
15
+ def send(*args)
16
+ @callback.__send__(*args)
17
+ end
18
+
19
+ def enter_key(key)
20
+ modes[current_mode].enter_key key
21
+ end
22
+
23
+ # TODO: callbacks
24
+ def current_mode=(cm)
25
+ @current_mode = cm.to_sym
26
+ end
27
+
28
+ def add_mode(name)
29
+ @modes[name.to_sym] = mode = Mode.new(self)
30
+ yield mode if block_given?
31
+ mode
32
+ end
33
+ end
34
+
35
+ class Mode
36
+ def initialize(callback = nil)
37
+ @callback = callback
38
+ @stack = []
39
+ @map = {}
40
+ @ancestors = []
41
+ end
42
+
43
+ def inherit(other)
44
+ @ancestors.delete other
45
+ @ancestors.unshift other
46
+ end
47
+
48
+ def ancestors(&block)
49
+ ([self] + @ancestors).find(&block)
50
+ end
51
+
52
+ def map(sym, *keychain)
53
+ bind(*keychain.flatten){|*arg| @callback.send(sym, *arg) }
54
+ end
55
+
56
+ def bind(*keychain, &block)
57
+ keychain = keychain.dup
58
+ total = hash = {}
59
+
60
+ while key = keychain.shift
61
+ if keychain.empty?
62
+ hash[key] = block
63
+ else
64
+ hash = hash[key] = {}
65
+ end
66
+ end
67
+
68
+ @map.replace @map.merge(total, &MERGER)
69
+ end
70
+
71
+ def enter_keys(*keys)
72
+ keys.flatten.each{|key| enter_key(key) }
73
+ end
74
+
75
+ def enter_key(key)
76
+ @stack << key
77
+ ancestors{|ancestor| ancestor.attempt_execute(@stack) }
78
+ end
79
+
80
+ def attempt_execute(original_stack)
81
+ stack, arg = Mode.split_stack(original_stack)
82
+ return false if stack.empty?
83
+
84
+ executable = stack.inject(@map){|keys, key| keys.fetch(key) }
85
+
86
+ if execute(executable, *arg)
87
+ original_stack.clear
88
+ return true
89
+ end
90
+
91
+ false
92
+ rescue KeyError
93
+ false
94
+ end
95
+
96
+ def execute(executable, *arg)
97
+ case executable
98
+ when Proc
99
+ executable.call(*arg)
100
+ true
101
+ when Symbol
102
+ @callback.send(executable, *arg)
103
+ else
104
+ false
105
+ end
106
+ end
107
+
108
+ def self.split_stack(stack)
109
+ return stack, nil if stack[0] == '0'
110
+
111
+ pivot = stack.index{|c| c !~ /\d/ }
112
+
113
+ if pivot == 0
114
+ return stack, nil
115
+ elsif pivot
116
+ return stack[pivot..-1], stack[0..pivot].join.to_i
117
+ else
118
+ return [], nil
119
+ end
120
+ end
121
+
122
+ MERGER = proc{|key,v1,v2|
123
+ Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
124
+ }
125
+ end
126
+ end
127
+
128
+ describe Mode = VER::Mode do
129
+ it 'splits stack into argument and keychain' do
130
+ Mode.split_stack(['4', 'a']).should == [['a'], 4]
131
+ Mode.split_stack(['4', '2', 'a']).should == [['a'], 42]
132
+ Mode.split_stack(['4', '2', 'a', 'b']).should == [['a', 'b'], 42]
133
+ Mode.split_stack(['a', 'b']).should == [['a', 'b'], nil]
134
+ end
135
+
136
+ it 'executes action assigned to key' do
137
+ done = false
138
+ mode = Mode.new
139
+ mode.bind('a'){ done = true }
140
+ mode.enter_keys 'a'
141
+ done.should == true
142
+ end
143
+
144
+ it 'executes action assigned to key chain (immediately)' do
145
+ done = false
146
+ mode = Mode.new
147
+ mode.bind('a', 'b', 'c'){ done = true }
148
+ mode.enter_keys 'a', 'b', 'c'
149
+ done.should == true
150
+ end
151
+
152
+ it 'executes action assigned to key chain (delayed)' do
153
+ done = false
154
+ mode = Mode.new
155
+ mode.bind('a', 'b', 'c'){ done = true }
156
+ mode.enter_key 'a'
157
+ mode.enter_key 'b'
158
+ mode.enter_key 'c'
159
+ done.should == true
160
+ end
161
+
162
+ it 'executes action with numeric argument' do
163
+ done = false
164
+ mode = Mode.new
165
+ mode.bind('a', 'b', 'c'){|arg| done = arg }
166
+ mode.enter_keys '4', '2', 'a', 'b', 'c'
167
+ done.should == 42
168
+ end
169
+
170
+ it 'executes action on callback' do
171
+ done = false
172
+ callback = Class.new{
173
+ attr_accessor :done
174
+
175
+ def foo
176
+ @done = true
177
+ end
178
+ }.new
179
+
180
+ mode = Mode.new(callback)
181
+ mode.map :foo, %w[a b c]
182
+ mode.enter_keys %w[a b c]
183
+ callback.done.should == true
184
+ end
185
+
186
+ it 'inherits another mode but executes actions itself' do
187
+ first_done = second_done = false
188
+ first, second = Mode.new, Mode.new
189
+ second.inherit(first)
190
+ second.bind('a', 'b', 'c'){|arg| second_done = arg }
191
+ second.enter_keys %w[4 2 a b c]
192
+ second_done.should == 42
193
+ end
194
+
195
+ it 'inherits another mode that also executes actions' do
196
+ first_done = second_done = false
197
+ first, second = Mode.new, Mode.new
198
+ second.inherit(first)
199
+
200
+ first.bind('first-key'){|arg| first_done = arg }
201
+ second.bind('second-key'){|arg| second_done = arg }
202
+
203
+ second.enter_keys %w[4 2 first-key]
204
+ first_done.should == 42
205
+
206
+ second.enter_keys %w[2 4 second-key]
207
+ second_done.should == 24
208
+ end
209
+ end
210
+
211
+ describe Keymap = VER::Keymap do
212
+ it 'adds a mode into the keymap' do
213
+ done = false
214
+
215
+ keymap = Keymap.new
216
+ keymap.add_mode :test do |mode|
217
+ mode.bind('a'){ done = true }
218
+ end
219
+ keymap.current_mode = :test
220
+
221
+ keymap.enter_key 'a'
222
+ done.should == true
223
+ end
224
+ end