Permalink
Browse files

implemented #map ... :ruby map('<F5>'){ puts 'pressed F5!' }

  • Loading branch information...
1 parent c6691da commit 468860987075dfa3482877e8e0de01dfc7fac4c4 @remi committed Apr 27, 2009
Showing with 41 additions and 5 deletions.
  1. +37 −5 lib/vimilicious.rb
  2. +4 −0 spec/mapping_spec.rb
View
@@ -152,10 +152,12 @@ def prompt name = 'input', format = lambda { |name| "#{name}: " }
# # Control-V is pressed in Normal mode
# end
#
+ # map '<F5>', ":echo 'hello from F5'<Enter>"
+ #
# ==== Parameters
# modes::
- # either a single mode, eg. :normal or an Array of
- # multiple modes, eg. %w( visual command ).
+ # optional. either a single mode, eg. :normal or an Array of
+ # multiple modes, eg. %w( visual command ). default: 'normal'
#
# valid mode names: normal, visual, insert, command, operator, lang
#
@@ -173,8 +175,36 @@ def prompt name = 'input', format = lambda { |name| "#{name}: " }
# a block of code to run whenever the code is pressed
#
# TODO allow #map('<C-r>'){ ... } and use default mode
+ # TODO allow #map('<C-r>', 'vim command')
#
- def map mode, shortcut, vim_command = nil, &block
+ def map modes, shortcut = nil, vim_command = nil, &block
+
+ # first argument isn't a mode, it's a shortcut!
+ unless modes.is_a?(Symbol) or modes.is_a?(Array)
+ vim_command = shortcut
+ shortcut = modes
+ modes = :normal # default
+ end
+
+ modes_to_use = map_commands_for *modes
+ raise "Don't know how to map #{ modes.inspect }" if modes_to_use.empty?
+
+ if vim_command
+ modes_to_use.each do |mode|
+ cmd "#{ mode } #{ shortcut } #{ vim_command }"
+ end
+
+ elsif block
+ unique_key = "#{ shortcut.inspect } #{ modes.inspect } #{ Time.now }"
+ @mapped_blocks ||= { }
+ @mapped_blocks[unique_key] = block
+ modes_to_use.each do |mode|
+ cmd "#{ mode } #{ shortcut } :ruby @mapped_blocks[%{#{ unique_key }}].call<Enter>"
+ end
+
+ else
+ raise "Not sure what you want to map to ... no vim_command or block passed."
+ end
end
# returns the map command(s) you should use if you want
@@ -196,6 +226,9 @@ def map_commands_for *modes
:imap => [ :insert ],
:lmap => [ :insert, :command, :lang ]
}
+
+ # symbolize
+ modes = modes.map {|mode| mode.to_s.downcase.to_sym }
# first, see if there's a mode that has the modes we want and nothing more
mode_that_has_everything_we_want_and_nothing_else = @mapmodes.find do |mode_command, available_modes|
@@ -229,8 +262,7 @@ def map_commands_for *modes
if modes_that_have_everything_we_want_and_some_more.length == 1
return [ modes_that_have_everything_we_want_and_some_more[0][0] ]
else
- puts "modes: #{ modes.inspect } ... we found: #{ modes_that_have_everything_we_want_and_some_more.inspect }"
- []
+ [] # couldn't find anything :/
end
end
View
@@ -22,8 +22,12 @@
# cmap:: Command-line
# imap:: Insert
# lmap:: Insert, Command-line, Lang-Arg
+ #
it 'should be able to figure out which vim mapping command to use' do
+ map_commands_for('visual').should == [:vmap]
+ map_commands_for('ViSuaL').should == [:vmap]
map_commands_for(:visual).should == [:vmap]
+
map_commands_for(:command).should == [:cmap]
map_commands_for(:lang).should == [:lmap] # it has to, because it's the only option with lmap
map_commands_for(:insert).should == [:imap]

0 comments on commit 4688609

Please sign in to comment.