vimilicious 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/vimilicious.rb +340 -0
  2. metadata +62 -0
@@ -0,0 +1,340 @@
1
+ # common methods for vim-ruby scripts
2
+ module Vimilicious
3
+
4
+ # run vim command
5
+ #
6
+ # :ruby puts cmd("echo 'hello!'")
7
+ def cmd vim_ex_command
8
+ VIM::command vim_ex_command
9
+ end
10
+
11
+ # runs a system command in vim, by calling :! command
12
+ #
13
+ # :ruby run 'ls'
14
+ def run system_command
15
+ cmd "! #{ system_command }"
16
+ end
17
+
18
+ # evaluate vim expression
19
+ #
20
+ # :ruby puts 'x = ' + vim_eval('x')
21
+ def vim_eval vim_expression
22
+ VIM::evaluate vim_expression
23
+ end
24
+
25
+ # execute 'normal' command
26
+ #
27
+ # :ruby exec '<ESC>ihello there!<ESC>'
28
+ def exec normal_vim_command
29
+ cmd %[exec "normal #{normal_vim_command}"].gsub('<','\<')
30
+ end
31
+
32
+ # alias 'puts' to vim 'print' method
33
+ #
34
+ # :ruby puts 'hello!'
35
+ def puts message
36
+ print message
37
+ end
38
+
39
+ # check to see if a vim variable is defined
40
+ #
41
+ # :ruby puts 'x is defined? ' + vim_defined?'x'
42
+ def vim_defined? var
43
+ vim_eval("exists('#{var}')") == '1'
44
+ end
45
+
46
+ # get the value of a vim variable (else nil)
47
+ #
48
+ # :ruby x = vim_var('x'); puts "x = #{x}"
49
+ def vim_var var
50
+ vim_eval(var) if vim_defined?var
51
+ end
52
+
53
+ # get the current buffer
54
+ #
55
+ # :ruby puts "the current line says: #{current_buffer.line}"
56
+ def current_buffer
57
+ VIM::Buffer.current # $curbuf
58
+ end
59
+
60
+ # get the current window
61
+ #
62
+ # :ruby puts "the cursor is at: #{current_window.cursor.inspect}"
63
+ def current_window
64
+ VIM::Window.current # $curwin
65
+ end
66
+
67
+ # get the name of the current file
68
+ #
69
+ # :ruby puts "currently editing: #{current_file}"
70
+ def current_file
71
+ current_buffer.name
72
+ end
73
+
74
+ # get the current cursor location (as array [line_number,position])
75
+ #
76
+ # :ruby puts "the cursor is at: #{cursor.inspect}"
77
+ def cursor
78
+ current_window.cursor
79
+ end
80
+
81
+ # get the current line number (of the #current_buffer)
82
+ def line_number
83
+ cursor.first
84
+ end
85
+
86
+ # get the text of the given #line_number (of the #current_buffer)
87
+ def line_text the_line_number = line_number
88
+ current_buffer[the_line_number]
89
+ end
90
+
91
+ # get the text of the currently selected line
92
+ #
93
+ # :ruby puts "the current line says: #{current_line}"
94
+ def current_line
95
+ current_buffer.line
96
+ end
97
+
98
+ # set the text of the currently selected line
99
+ #
100
+ # we're not using the more conventional current_line= because
101
+ # that simply creates a local variable named current_line
102
+ #
103
+ # :ruby set_current_line 'hi there'
104
+ def set_current_line text
105
+ current_buffer[ current_buffer.line_number ] = text.to_s
106
+ end
107
+
108
+ # deletes the current buffer (closes the file) but keeps the current layout
109
+ #
110
+ # :ruby clear
111
+ def clear
112
+ cmd 'let kwbd_bn= bufnr("%")|enew|exe "bdel ".kwbd_bn|unlet kwbd_bn'
113
+ clear_buffer
114
+ end
115
+
116
+ # forcefully deletes the current buffer and clears the wholelayout
117
+ #
118
+ # :ruby clear!
119
+ def clear!
120
+ cmd 'bd!'
121
+ clear_buffer
122
+ end
123
+
124
+ # deletes all lines in the current_buffer
125
+ def clear_buffer
126
+ exec 'gg'
127
+ current_buffer.length.times { current_buffer.delete(1) }
128
+ end
129
+
130
+ # append text to the end of the current_buffer
131
+ #
132
+ # :ruby append 'hello there'
133
+ def append text
134
+ current_buffer.append current_buffer.length, text
135
+ end
136
+
137
+ # prompts user for input
138
+ #
139
+ # :ruby prompt('username')
140
+ def prompt name = 'input', format = lambda { |name| "#{name}: " }
141
+ input = vim_eval("inputdialog('#{ format.call(name) }')")
142
+ puts '' # clear statusline thinger
143
+ input
144
+ end
145
+
146
+ # ruby method for mapping keyboard shortcuts to something
147
+ #
148
+ # this is a ruby wrapper around vim's map functions
149
+ #
150
+ # ==== VIM Modes
151
+ #
152
+ # map:: Normal, Visual, Operator-pending
153
+ # map!:: Insert, Command-line
154
+ # nmap:: Normal
155
+ # vmap:: Visual
156
+ # omap:: Operator-pending
157
+ # cmap:: Command-line
158
+ # imap:: Insert
159
+ # lmap:: Insert, Command-line, Lang-Arg
160
+ #
161
+ # references:
162
+ # - http://www.vim.org/htmldoc/map.html
163
+ # - http://howto.wikia.com/wiki/Howto_map_keys_in_vim
164
+ #
165
+ # === Usage
166
+ #
167
+ # map :normal, '<C-v>', do
168
+ # # some code that will run whenever
169
+ # # Control-V is pressed in Normal mode
170
+ # end
171
+ #
172
+ # map '<F5>', ":echo 'hello from F5'<Enter>"
173
+ #
174
+ # ==== Parameters
175
+ # modes::
176
+ # optional. either a single mode, eg. :normal or an Array of
177
+ # multiple modes, eg. %w( visual command ). default: 'normal'
178
+ #
179
+ # valid mode names: normal, visual, insert, command, operator, lang
180
+ #
181
+ # shortcut::
182
+ # a shortcut just like VIM normally understands, eg. <C-v>
183
+ #
184
+ # vim_command::
185
+ # optional. this is a string command that we'll map
186
+ # this shortcut to. if this is passed, the &block
187
+ # parameter is ignored and vim_command is run instead!
188
+ # you can still run ruby with this parameter by
189
+ # passing something like '<Esc>:ruby puts 'hi'<Enter>'
190
+ #
191
+ # &block::
192
+ # a block of code to run whenever the code is pressed
193
+ #
194
+ # TODO allow #map('<C-r>'){ ... } and use default mode
195
+ # TODO allow #map('<C-r>', 'vim command')
196
+ #
197
+ def map modes, shortcut = nil, vim_command = nil, &block
198
+
199
+ # first argument isn't a mode, it's a shortcut!
200
+ unless modes.is_a?(Symbol) or modes.is_a?(Array)
201
+ vim_command = shortcut
202
+ shortcut = modes
203
+ modes = :normal # default
204
+ end
205
+
206
+ modes_to_use = map_commands_for *modes
207
+ raise "Don't know how to map #{ modes.inspect }" if modes_to_use.empty?
208
+
209
+ if vim_command
210
+ modes_to_use.each do |mode|
211
+ cmd "#{ mode } #{ shortcut } #{ vim_command }"
212
+ end
213
+
214
+ elsif block
215
+ unique_key = "#{ shortcut.inspect }_#{ modes.inspect }_#{ Time.now.to_i }"
216
+ @mapped_blocks ||= { }
217
+ @mapped_blocks[unique_key] = block
218
+ modes_to_use.each do |mode|
219
+ cmd "#{ mode } #{ shortcut } <Esc>:ruby @mapped_blocks[#{ unique_key.inspect }].call<Enter>"
220
+ end
221
+
222
+ else
223
+ raise "Not sure what you want to map to ... no vim_command or block passed."
224
+ end
225
+ end
226
+
227
+ # returns the map command(s) you should use if you want
228
+ # to map with the mode(s) given
229
+ #
230
+ # see spec/mapping_spec.rb
231
+ #
232
+ # >> map_commands_for(:normal)
233
+ # => :nmap
234
+ #
235
+ def map_commands_for *modes
236
+ @mapmodes ||= {
237
+ :map => [ :normal, :visual, :operator ],
238
+ :map! => [ :insert, :command ],
239
+ :nmap => [ :normal ],
240
+ :vmap => [ :visual ],
241
+ :omap => [ :operator ],
242
+ :cmap => [ :command ],
243
+ :imap => [ :insert ],
244
+ :lmap => [ :insert, :command, :lang ]
245
+ }
246
+
247
+ # symbolize
248
+ modes = modes.map {|mode| mode.to_s.downcase.to_sym }
249
+
250
+ # first, see if there's a mode that has the modes we want and nothing more
251
+ mode_that_has_everything_we_want_and_nothing_else = @mapmodes.find do |mode_command, available_modes|
252
+ match = true
253
+ match = false unless available_modes.length == modes.length
254
+ modes.each {|mode| match = false unless available_modes.include?(mode) }
255
+ match
256
+ end
257
+
258
+ return [ mode_that_has_everything_we_want_and_nothing_else[0] ] if mode_that_has_everything_we_want_and_nothing_else
259
+
260
+ # see if the modes we're looking for have a 1 <=> 1 mapping with available modes
261
+ one_to_one_mapping_modes = modes.map do |mode|
262
+ @mapmodes.find do |mode_command, available_modes|
263
+ available_modes == [mode]
264
+ end
265
+ end
266
+
267
+ return one_to_one_mapping_modes.map {|mode_command, available_modes|
268
+ mode_command
269
+ } unless one_to_one_mapping_modes.include? nil
270
+
271
+ # hmm, regardless of whether it'll have more than we want, see if we can find a mode
272
+ # that has all of the modes we're looking for
273
+ modes_that_have_everything_we_want_and_some_more = @mapmodes.select do |mode_command, available_modes|
274
+ match = true
275
+ modes.each {|mode| match = false unless available_modes.include?(mode) }
276
+ match
277
+ end
278
+
279
+ if modes_that_have_everything_we_want_and_some_more.length == 1
280
+ return [ modes_that_have_everything_we_want_and_some_more[0][0] ]
281
+ else
282
+ [] # couldn't find anything :/
283
+ end
284
+
285
+ end
286
+
287
+ # create a vim user command that calls a ruby method or block
288
+ #
289
+ # :ruby create_command :test # creates a :Test command that calls a 'test' method
290
+ # :ruby create_command 'test', :hi # creates a :Test command that calls a 'hi' method
291
+ # :ruby create_command(:test){ puts 'hi' } # creates a :Test command that calls the block passed in
292
+ #
293
+ # :ruby create_command(:foo){|*args| puts "called foo with args: #{ args.inspect }" }
294
+ #
295
+ # :Foo 'hello', 'there', 1, 2, 3
296
+ # called foo with args: ["hi", "there", 1, 2, 3]
297
+ #
298
+ # ==== Notes
299
+ #
300
+ # the name of the command will be capitalized, so :test is callable as :Test
301
+ #
302
+ def create_command name, method = nil, &block
303
+ name = name.to_s
304
+ command_name = name[0..0] + name[1..name.length]
305
+ method_name = (method.nil?) ? name.to_s : method.to_s
306
+ function_name = command_name + 'AutoGeneratedFunction'
307
+
308
+ # create a function that calls method (or block)
309
+ if block.nil?
310
+ cmd %[fu! #{ function_name }(...)\n ruby #{ method_name } *eval("\#{ vim_eval('string(a:000)') }")\nendfu]
311
+ else
312
+ generated_method = command_name + '_auto_generated_method'
313
+ Kernel.module_eval { define_method generated_method, block }
314
+ cmd %[fu! #{ function_name }(...)\n ruby #{ generated_method } *eval("\#{ vim_eval('string(a:000)') }")\nendfu]
315
+ end
316
+
317
+ # create a vim command that calls the vim function
318
+ cmd %{command! -nargs=* #{ command_name } call #{ function_name }(<args>)}
319
+ end
320
+
321
+ # get the word under the cursor
322
+ #
323
+ # :ruby puts "the cursor is on top of the word: #{current_word}"
324
+ def current_word filter=/[,'`\.:\(\)\[\]\}\{]/, replace_with=''
325
+ line, index = current_line, cursor[1]
326
+ word_start, word_end = line.rindex(' ',index) || 0, line.index(' ',index)
327
+ word_start += 1 if word_start > 0
328
+ word_end = line.length if word_end.nil?
329
+ word = line[word_start, word_end-word_start] || ''
330
+ word.gsub!(filter,replace_with) unless word.empty?
331
+ word
332
+ end
333
+
334
+ end
335
+
336
+ include Vimilicious
337
+
338
+ ### COMMANDS ###
339
+
340
+ create_command('InspectArgs'){ |*args| puts "passed: #{args.inspect}" }
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vimilicious
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 5
9
+ version: 0.1.5
10
+ platform: ruby
11
+ authors:
12
+ - remi
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-22 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: vim-ruby library making it easier to work with vim via ruby
22
+ email: remi@remitaylor.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/vimilicious.rb
31
+ has_rdoc: true
32
+ homepage: http://github.com/remi/vimilicious
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.3.6
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: vim-ruby library for making vim easy
61
+ test_files: []
62
+