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.
- data/lib/vimilicious.rb +340 -0
- metadata +62 -0
data/lib/vimilicious.rb
ADDED
|
@@ -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
|
+
|