vimilicious 0.1.5

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.
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
+