garybernhardt / dotfiles
My vim, bash, emacs, etc. configurations. These have grown over many years, so they may not make sense in places. ;)
Clone this repository (size: 1.5 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/garybernhardt/dotfiles/
| commit 150: | cae8e2328b60 |
| parent 149: | 11c651841192 |
| branch: | default |
Added missing bike plugin to vim
4 months ago
Changed (Δ12.7 KB):
raw changeset »
.vim/plugin/bike.vim (430 lines added, 0 lines removed)
Up to file-list .vim/plugin/bike.vim:
1 |
" Bicycle Repair Man integration for Vim |
|
2 |
" Version 0.3 |
|
3 |
" Copyright (c) 2003 Marius Gedminas <mgedmin@delfi.lt> |
|
4 |
" |
|
5 |
" Needs Vim 6.x with python interpreter (Python 2.2 or newer) |
|
6 |
" Installation instructions: just drop it into $HOME/.vim/plugin and you |
|
7 |
" should see the Bicycle Repair Menu appear in GVim (or you can check if |
|
8 |
" any of the BikeXxx commands are defined in console mode Vim). If bike.vim |
|
9 |
" fails to load and you want to see the reason, try |
|
10 |
" let g:bike_exceptions = 1 |
|
11 |
" source ~/.vim/plugin/bike.vim |
|
12 |
" |
|
13 |
" Configuration options you can add to your .vimrc: |
|
14 |
" let g:bike_exceptions = 1 " show tracebacks on exceptions |
|
15 |
" let g:bike_progress = 1 " show import progress |
|
16 |
" |
|
17 |
" Commands defined: |
|
18 |
" |
|
19 |
" BikeShowScope |
|
20 |
" Show current scope. Sample of usage: |
|
21 |
" autocmd CursorHold *.py BikeShowScope |
|
22 |
" |
|
23 |
" <range> BikeShowType |
|
24 |
" Show selected expression type. The range is ignored, '<,'> is always |
|
25 |
" used. Use this in visual block mode. |
|
26 |
" |
|
27 |
" BikeFindRefs |
|
28 |
" Finds all references of the function/method/class defined in current |
|
29 |
" line. |
|
30 |
" |
|
31 |
" BikeFindDef |
|
32 |
" Finds the definition of the function/method/class under cursor. |
|
33 |
" |
|
34 |
" BikeRename |
|
35 |
" Renames the function/method/class defined in current line. Updates |
|
36 |
" all references in all files known (i.e. imported) to Bicycle Repair |
|
37 |
" Man. |
|
38 |
" |
|
39 |
" <range> BikeExtract |
|
40 |
" Extracts a part of the function/method into a new function/method. |
|
41 |
" The range is ignored, '<,'> is always used. Use this in visual mode. |
|
42 |
" |
|
43 |
" BikeUndo |
|
44 |
" Globally undoes the previous refactoring. |
|
45 |
" |
|
46 |
" Issues: |
|
47 |
" - Saves all modified buffers to disk without asking the user -- not nice |
|
48 |
" - Does not reimport files that were modified outside of Vim |
|
49 |
" - Uses mktemp() -- I think that produces deprecation warnings in Python 2.3 |
|
50 |
" - BikeShowType, BikeExtract ignores the specified range, that's confusing. |
|
51 |
" At least BikeExtract ought to work... |
|
52 |
" - BikeShowType/BikeExtract or their GUI counterparts work when not in |
|
53 |
" visual mode by using the previous values of '<,'>. Might be confusing. |
|
54 |
" - Would be nice if :BikeImport<CR> asked to enter package |
|
55 |
" - Would be nice if :BikeRename myNewName<CR> worked |
|
56 |
" - The code is not very robust (grep for XXX) |
|
57 |
||
58 |
" |
|
59 |
" Default settings for global configuration variables {{{1 |
|
60 |
" |
|
61 |
||
62 |
" Set to 1 to see full tracebacks |
|
63 |
if !exists("g:bike_exceptions") |
|
64 |
let g:bike_exceptions = 0 |
|
65 |
endif |
|
66 |
||
67 |
" Set to 1 to see import progress |
|
68 |
if !exists("g:bike_progress") |
|
69 |
let g:bike_progress = 0 |
|
70 |
endif |
|
71 |
||
72 |
" |
|
73 |
" Initialization {{{1 |
|
74 |
" |
|
75 |
||
76 |
" First check that Vim is sufficiently recent, that we have python interpreted |
|
77 |
" support, and that Bicycle Repair Man is available. |
|
78 |
" |
|
79 |
" If something is wrong, fail silently, as error messages every time vim |
|
80 |
" starts are very annoying. But if the user wants to see why bike.vim failed |
|
81 |
" to load, she can let g:bike_exceptions = 1 |
|
82 |
if version < 600 |
|
83 |
if g:bike_exceptions |
|
84 |
echo 'Bicycle Repair Man needs Vim 6.0' |
|
85 |
endif |
|
86 |
finish |
|
87 |
endif |
|
88 |
||
89 |
if !has("python") |
|
90 |
if g:bike_exceptions |
|
91 |
echo 'Bicycle Repair Man needs Vim with Python interpreter support (2.2 or newer)' |
|
92 |
endif |
|
93 |
finish |
|
94 |
endif |
|
95 |
||
96 |
let s:has_bike=1 |
|
97 |
python << END |
|
98 |
import vim |
|
99 |
import sys |
|
100 |
try: |
|
101 |
if sys.version_info < (2, 2): |
|
102 |
raise ImportError, 'Bicycle Repair Man needs Python 2.2 or newer' |
|
103 |
import bike |
|
104 |
bikectx = bike.init() |
|
105 |
bikectx.isLoaded # make sure bike package is recent enough |
|
106 |
except ImportError: |
|
107 |
vim.command("let s:has_bike=0") |
|
108 |
if vim.eval('g:bike_exceptions') not in (None, '', '0'): |
|
109 |
raise |
|
110 |
END |
|
111 |
if !s:has_bike |
|
112 |
finish |
|
113 |
endif |
|
114 |
||
115 |
" Use sane cpoptions |
|
116 |
let s:cpo_save = &cpo |
|
117 |
set cpo&vim |
|
118 |
||
119 |
" |
|
120 |
" Menu {{{1 |
|
121 |
" |
|
122 |
silent! aunmenu Bicycle\ Repair\ Man |
|
123 |
||
124 |
" Shortcuts available: ab-----h-jk--nopq----vw--z |
|
125 |
amenu <silent> Bicycle\ &Repair\ Man.-SEP1- |
|
126 |
\ : |
|
127 |
amenu <silent> Bicycle\ &Repair\ Man.&Find\ References |
|
128 |
\ :call <SID>BikeFindRefs()<CR> |
|
129 |
amenu <silent> Bicycle\ &Repair\ Man.Find\ &Definition |
|
130 |
\ :call <SID>BikeFindDef()<CR> |
|
131 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&List<tab>:cl |
|
132 |
\ :cl<CR> |
|
133 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Current<tab>:cc |
|
134 |
\ :cc<CR> |
|
135 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Next<tab>:cn |
|
136 |
\ :cn<CR> |
|
137 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Previous<tab>:cp |
|
138 |
\ :cp<CR> |
|
139 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&First<tab>:cfirst |
|
140 |
\ :cfirst<CR> |
|
141 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.Las&t<tab>:clast |
|
142 |
\ :clast<CR> |
|
143 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Older\ List<tab>:colder |
|
144 |
\ :colder<CR> |
|
145 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.N&ewer\ List<tab>:cnewer |
|
146 |
\ :cnewer<CR> |
|
147 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Window.&Update<tab>:cw |
|
148 |
\ :cw<CR> |
|
149 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Window.&Open<tab>:copen |
|
150 |
\ :copen<CR> |
|
151 |
amenu <silent> Bicycle\ &Repair\ Man.Resu<s.&Window.&Close<tab>:cclose |
|
152 |
\ :cclose<CR> |
|
153 |
amenu <silent> Bicycle\ &Repair\ Man.-SEP2- |
|
154 |
\ : |
|
155 |
amenu <silent> Bicycle\ &Repair\ Man.&Rename |
|
156 |
\ :call <SID>BikeRename()<CR> |
|
157 |
amenu <silent> Bicycle\ &Repair\ Man.E&xtract\ Method |
|
158 |
\ :call <SID>BikeExtract('method')<CR> |
|
159 |
amenu <silent> Bicycle\ &Repair\ Man.&Extract\ Function |
|
160 |
\ :call <SID>BikeExtract('function')<CR> |
|
161 |
amenu <silent> Bicycle\ &Repair\ Man.&Undo |
|
162 |
\ :call <SID>BikeUndo()<CR> |
|
163 |
amenu <silent> Bicycle\ &Repair\ Man.-SEP3- |
|
164 |
\ : |
|
165 |
amenu <silent> Bicycle\ &Repair\ Man.Settin&gs.Import\ &Progress.&Enable |
|
166 |
\ :let g:bike_progress = 1<CR> |
|
167 |
amenu <silent> Bicycle\ &Repair\ Man.Settin&gs.Import\ &Progress.&Disable |
|
168 |
\ :let g:bike_progress = 0<CR> |
|
169 |
amenu <silent> Bicycle\ &Repair\ Man.Settin&gs.Full\ &Exceptions.&Enable |
|
170 |
\ :let g:bike_exceptions = 1<CR> |
|
171 |
amenu <silent> Bicycle\ &Repair\ Man.Settin&gs.Full\ &Exceptions.&Disable |
|
172 |
\ :let g:bike_exceptions = 0<CR> |
|
173 |
||
174 |
" Note: The three rename commands are basically identical. The two extract |
|
175 |
" commands are also identical behind the scenes. |
|
176 |
||
177 |
" |
|
178 |
" Commands {{{1 |
|
179 |
" |
|
180 |
||
181 |
command! BikeShowScope call <SID>BikeShowScope() |
|
182 |
command! -range BikeShowType call <SID>BikeShowType() |
|
183 |
command! BikeFindRefs call <SID>BikeFindRefs() |
|
184 |
command! BikeFindDef call <SID>BikeFindDef() |
|
185 |
||
186 |
command! BikeRename call <SID>BikeRename() |
|
187 |
command! -range BikeExtract call <SID>BikeExtract('function') |
|
188 |
command! BikeUndo call <SID>BikeUndo() |
|
189 |
||
190 |
" |
|
191 |
" Implementation {{{1 |
|
192 |
" |
|
193 |
||
194 |
" Query functions {{{2 |
|
195 |
||
196 |
function! s:BikeShowScope() |
|
197 |
" Shows the scope under cursor |
|
198 |
python << END |
|
199 |
fn = vim.current.buffer.name |
|
200 |
row, col = vim.current.window.cursor |
|
201 |
try: |
|
202 |
print bikectx.getFullyQualifiedNameOfScope(fn, row) |
|
203 |
except: |
|
204 |
show_exc() |
|
205 |
END |
|
206 |
endf |
|
207 |
||
208 |
function! s:BikeShowType() |
|
209 |
" Shows the inferred type of the selected expression |
|
210 |
if col("'<") == 0 " mark not set |
|
211 |
echo "Select a region first!" |
|
212 |
return |
|
213 |
endif |
|
214 |
if line("'<") != line("'>") " multiline selection |
|
215 |
echo "Multi-line regions not supported" |
|
216 |
" XXX deficiency of bikefacade interface, expressions can easily span |
|
217 |
" several lines in Python |
|
218 |
return |
|
219 |
endif |
|
220 |
python << END |
|
221 |
fn = vim.current.buffer.name |
|
222 |
row1, col1 = vim.current.buffer.mark('<') |
|
223 |
row2, col2 = vim.current.buffer.mark('>') |
|
224 |
try: |
|
225 |
print bikectx.getTypeOfExpression(fn, row1, col1, col2) |
|
226 |
except: |
|
227 |
show_exc() |
|
228 |
END |
|
229 |
endf |
|
230 |
||
231 |
function! s:BikeFindRefs() |
|
232 |
" Find all references to the item defined on current line |
|
233 |
wall |
|
234 |
python << END |
|
235 |
fn = vim.current.buffer.name |
|
236 |
row, col = vim.current.window.cursor |
|
237 |
try: |
|
238 |
refs = bikectx.findReferencesByCoordinates(fn, row, col) |
|
239 |
quickfixdefs(refs) |
|
240 |
except: |
|
241 |
show_exc() |
|
242 |
END |
|
243 |
endf |
|
244 |
||
245 |
function! s:BikeFindDef() |
|
246 |
" Find all definitions of the item under cursor. Ideally there should be only |
|
247 |
" one. |
|
248 |
wall |
|
249 |
python << END |
|
250 |
fn = vim.current.buffer.name |
|
251 |
row, col = vim.current.window.cursor |
|
252 |
try: |
|
253 |
defs = bikectx.findDefinitionByCoordinates(fn, row, col) |
|
254 |
quickfixdefs(defs) |
|
255 |
except: |
|
256 |
show_exc() |
|
257 |
END |
|
258 |
endf |
|
259 |
||
260 |
" Refactoring commands {{{2 |
|
261 |
||
262 |
function! s:BikeRename() |
|
263 |
" Rename a function/method/class. |
|
264 |
||
265 |
let newname = inputdialog('Rename to: ') |
|
266 |
wall |
|
267 |
python << END |
|
268 |
fn = vim.current.buffer.name |
|
269 |
row, col = vim.current.window.cursor |
|
270 |
newname = vim.eval("newname") |
|
271 |
if newname: |
|
272 |
try: |
|
273 |
bikectx.setRenameMethodPromptCallback(renameMethodPromptCallback) |
|
274 |
bikectx.renameByCoordinates(fn, row, col, newname) |
|
275 |
except: |
|
276 |
show_exc() |
|
277 |
saveChanges() |
|
278 |
else: |
|
279 |
print "Aborted" |
|
280 |
END |
|
281 |
endf |
|
282 |
||
283 |
function! s:BikeExtract(what) |
|
284 |
" Extract a piece of code into a separate function/method. The argument |
|
285 |
" a:what can be 'method' or 'function'. |
|
286 |
if col("'<") == 0 " mark not set |
|
287 |
echo "Select a region first!" |
|
288 |
return |
|
289 |
endif |
|
290 |
let newname = inputdialog('New function name: ') |
|
291 |
wall |
|
292 |
python << END |
|
293 |
fn = vim.current.buffer.name |
|
294 |
row1, col1 = vim.current.buffer.mark('<') |
|
295 |
row2, col2 = vim.current.buffer.mark('>') |
|
296 |
newname = vim.eval("newname") |
|
297 |
if newname: |
|
298 |
try: |
|
299 |
bikectx.extractMethod(fn, row1, col1, row2, col2, newname) |
|
300 |
except: |
|
301 |
show_exc() |
|
302 |
saveChanges() |
|
303 |
else: |
|
304 |
print "Aborted" |
|
305 |
END |
|
306 |
endf |
|
307 |
||
308 |
function! s:BikeUndo() |
|
309 |
" Undoes the last refactoring |
|
310 |
wall |
|
311 |
python << END |
|
312 |
try: |
|
313 |
bikectx.undo() |
|
314 |
saveChanges() |
|
315 |
except bike.UndoStackEmptyException, e: |
|
316 |
print "Nothing to undo" |
|
317 |
END |
|
318 |
endf |
|
319 |
||
320 |
" |
|
321 |
" Helper functions {{{1 |
|
322 |
" |
|
323 |
||
324 |
" Python helpers |
|
325 |
||
326 |
python << END |
|
327 |
||
328 |
import tempfile |
|
329 |
import os |
|
330 |
import linecache |
|
331 |
||
332 |
modified = {} # a dictionary whose keys are the names of files modifed |
|
333 |
# in Vim since the last import |
|
334 |
||
335 |
def show_exc(): |
|
336 |
"""Print exception according to bike settings.""" |
|
337 |
if vim.eval('g:bike_exceptions') not in (None, '', '0'): |
|
338 |
import traceback |
|
339 |
traceback.print_exc() |
|
340 |
else: |
|
341 |
type, value = sys.exc_info()[:2] |
|
342 |
if value is not None: |
|
343 |
print "%s: %s" % (type, value) |
|
344 |
else: |
|
345 |
print type |
|
346 |
||
347 |
def writedefs(defs, filename): |
|
348 |
"""Write a list of file locations to a file.""" |
|
349 |
ef = None |
|
350 |
curdir = os.getcwd() |
|
351 |
if not curdir.endswith(os.sep): |
|
352 |
curdir = curdir + os.sep |
|
353 |
for d in defs: |
|
354 |
if not ef: |
|
355 |
ef = open(filename, "w") |
|
356 |
fn = d.filename |
|
357 |
if fn.startswith(curdir): |
|
358 |
fn = fn[len(curdir):] |
|
359 |
line = linecache.getline(fn, d.lineno).strip() |
|
360 |
res ="%s:%d: %3d%%: %s" % (fn, d.lineno, d.confidence, line) |
|
361 |
print res |
|
362 |
print >> ef, res |
|
363 |
if ef: |
|
364 |
ef.close() |
|
365 |
return ef is not None |
|
366 |
||
367 |
def quickfixdefs(defs): |
|
368 |
"""Import a list of file locations into vim error list.""" |
|
369 |
fn = tempfile.mktemp() # XXX unsafe |
|
370 |
if writedefs(defs, fn): |
|
371 |
vim.command('let old_errorfile = &errorfile') |
|
372 |
vim.command('let old_errorformat = &errorformat') |
|
373 |
vim.command(r'set errorformat=\%f:\%l:\ \%m') |
|
374 |
vim.command("cfile %s" % fn) |
|
375 |
vim.command('let &errorformat = old_errorformat') |
|
376 |
vim.command('let &errorfile = old_errorfile') |
|
377 |
os.unlink(fn) |
|
378 |
else: |
|
379 |
print "Not found" |
|
380 |
||
381 |
def renameMethodPromptCallback(filename, line, col1, col2): |
|
382 |
"""Verify that the call in a given file position should be renamed.""" |
|
383 |
vim.command('e +%d %s' % (line, filename)) |
|
384 |
vim.command('normal %d|' % col1) |
|
385 |
vim.command('match Search /\%%%dl\%%>%dc\%%<%dc' % (line, col1, col2+1)) |
|
386 |
vim.command('redraw') |
|
387 |
ans = vim.eval('confirm("Cannot deduce instance type. Rename this call?",' |
|
388 |
' "&Yes\n&No", 1, "Question")') |
|
389 |
vim.command('match none') |
|
390 |
if ans == '1': |
|
391 |
return 1 |
|
392 |
else: |
|
393 |
return 0 |
|
394 |
||
395 |
||
396 |
def saveChanges(): |
|
397 |
"""Save refactoring changes to the file system and reload the modified |
|
398 |
files in Vim.""" |
|
399 |
# bikectx.save() returns a list of modified file names. We should make |
|
400 |
# sure that all those files are reloaded iff they were open in vim. |
|
401 |
files = map(os.path.abspath, bikectx.save()) |
|
402 |
||
403 |
opened_files = {} |
|
404 |
for b in vim.buffers: |
|
405 |
if b.name is not None: |
|
406 |
opened_files[os.path.abspath(b.name)] = b.name |
|
407 |
||
408 |
for f in files: |
|
409 |
try: |
|
410 |
# XXX might fail when file name contains funny characters |
|
411 |
vim.command("sp %s | q" % opened_files[f]) |
|
412 |
except KeyError: |
|
413 |
pass |
|
414 |
||
415 |
# Just in case: |
|
416 |
vim.command("checktime") |
|
417 |
vim.command("e") |
|
418 |
||
419 |
END |
|
420 |
||
421 |
" Make sure modified files are reimported into BRM |
|
422 |
autocmd BufWrite * python modified[os.path.abspath(vim.current.buffer.name)] = 1 |
|
423 |
||
424 |
" |
|
425 |
" Cleanup {{{1 |
|
426 |
" |
|
427 |
||
428 |
" Restore cpoptions |
|
429 |
let &cpo = s:cpo_save |
|
430 |
unlet s:cpo_save |
