utils 0.0.67 → 0.0.68

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/VERSION +1 -1
  2. data/bin/edit +3 -1
  3. data/lib/utils/editor.rb +14 -0
  4. data/lib/utils/version.rb +1 -1
  5. data/utils.gemspec +3 -3
  6. metadata +3 -74
  7. data/lib/utils/config/vim/after/syntax/haml.vim +0 -9
  8. data/lib/utils/config/vim/after/syntax/html.vim +0 -11
  9. data/lib/utils/config/vim/autoload/Align.vim +0 -1029
  10. data/lib/utils/config/vim/autoload/AlignMaps.vim +0 -330
  11. data/lib/utils/config/vim/autoload/ctrlp/bookmarkdir.vim +0 -139
  12. data/lib/utils/config/vim/autoload/ctrlp/buffertag.vim +0 -238
  13. data/lib/utils/config/vim/autoload/ctrlp/changes.vim +0 -96
  14. data/lib/utils/config/vim/autoload/ctrlp/dir.vim +0 -90
  15. data/lib/utils/config/vim/autoload/ctrlp/line.vim +0 -63
  16. data/lib/utils/config/vim/autoload/ctrlp/mixed.vim +0 -83
  17. data/lib/utils/config/vim/autoload/ctrlp/mrufiles.vim +0 -119
  18. data/lib/utils/config/vim/autoload/ctrlp/quickfix.vim +0 -62
  19. data/lib/utils/config/vim/autoload/ctrlp/rtscript.vim +0 -49
  20. data/lib/utils/config/vim/autoload/ctrlp/tag.vim +0 -112
  21. data/lib/utils/config/vim/autoload/ctrlp/undo.vim +0 -154
  22. data/lib/utils/config/vim/autoload/ctrlp/utils.vim +0 -72
  23. data/lib/utils/config/vim/autoload/ctrlp.vim +0 -1772
  24. data/lib/utils/config/vim/autoload/rails.vim +0 -4570
  25. data/lib/utils/config/vim/autoload/rubycomplete.vim +0 -801
  26. data/lib/utils/config/vim/autoload/sqlcomplete.vim +0 -741
  27. data/lib/utils/config/vim/autoload/vimball.vim +0 -750
  28. data/lib/utils/config/vim/colors/flori.vim +0 -116
  29. data/lib/utils/config/vim/compiler/coffee.vim +0 -68
  30. data/lib/utils/config/vim/compiler/eruby.vim +0 -40
  31. data/lib/utils/config/vim/compiler/ruby.vim +0 -67
  32. data/lib/utils/config/vim/compiler/rubyunit.vim +0 -34
  33. data/lib/utils/config/vim/doc/Decho.txt +0 -372
  34. data/lib/utils/config/vim/doc/coffee-script.txt +0 -116
  35. data/lib/utils/config/vim/doc/ctrlp.txt +0 -1113
  36. data/lib/utils/config/vim/doc/fugitive.txt +0 -257
  37. data/lib/utils/config/vim/doc/rails.txt +0 -1022
  38. data/lib/utils/config/vim/doc/xml-plugin.txt +0 -226
  39. data/lib/utils/config/vim/ftdetect/coffee.vim +0 -8
  40. data/lib/utils/config/vim/ftdetect/eco.vim +0 -1
  41. data/lib/utils/config/vim/ftdetect/ragel.vim +0 -2
  42. data/lib/utils/config/vim/ftdetect/ruby.vim +0 -17
  43. data/lib/utils/config/vim/ftdetect/slim.vim +0 -2
  44. data/lib/utils/config/vim/ftplugin/coffee.vim +0 -221
  45. data/lib/utils/config/vim/ftplugin/eruby.vim +0 -100
  46. data/lib/utils/config/vim/ftplugin/ruby.vim +0 -260
  47. data/lib/utils/config/vim/ftplugin/xml.vim +0 -941
  48. data/lib/utils/config/vim/indent/IndentAnything_html.vim +0 -35
  49. data/lib/utils/config/vim/indent/coffee.vim +0 -338
  50. data/lib/utils/config/vim/indent/eruby.vim +0 -77
  51. data/lib/utils/config/vim/indent/javascript.vim +0 -116
  52. data/lib/utils/config/vim/indent/ruby.vim +0 -377
  53. data/lib/utils/config/vim/indent/slim.vim +0 -75
  54. data/lib/utils/config/vim/plugin/AlignMapsPlugin.vim +0 -242
  55. data/lib/utils/config/vim/plugin/AlignPlugin.vim +0 -41
  56. data/lib/utils/config/vim/plugin/Decho.vim +0 -592
  57. data/lib/utils/config/vim/plugin/IndentAnything.vim +0 -675
  58. data/lib/utils/config/vim/plugin/bufexplorer.vim +0 -1144
  59. data/lib/utils/config/vim/plugin/cecutil.vim +0 -508
  60. data/lib/utils/config/vim/plugin/ctrlp.vim +0 -61
  61. data/lib/utils/config/vim/plugin/fugitive.vim +0 -2041
  62. data/lib/utils/config/vim/plugin/lusty-explorer.vim +0 -1509
  63. data/lib/utils/config/vim/plugin/rails.vim +0 -339
  64. data/lib/utils/config/vim/plugin/rubyextra.vim +0 -193
  65. data/lib/utils/config/vim/plugin/surround.vim +0 -628
  66. data/lib/utils/config/vim/plugin/taglist.vim +0 -4546
  67. data/lib/utils/config/vim/plugin/test/IndentAnything/test.js +0 -131
  68. data/lib/utils/config/vim/plugin/vimballPlugin.vim +0 -40
  69. data/lib/utils/config/vim/syntax/Decho.vim +0 -101
  70. data/lib/utils/config/vim/syntax/coffee.vim +0 -217
  71. data/lib/utils/config/vim/syntax/eco.vim +0 -62
  72. data/lib/utils/config/vim/syntax/eruby.vim +0 -73
  73. data/lib/utils/config/vim/syntax/javascript.vim +0 -246
  74. data/lib/utils/config/vim/syntax/ragel.vim +0 -165
  75. data/lib/utils/config/vim/syntax/ruby.vim +0 -367
  76. data/lib/utils/config/vim/syntax/slim.vim +0 -117
  77. data/lib/utils/config/vimrc +0 -540
@@ -1,1509 +0,0 @@
1
- " Copyright: Copyright (C) 2007-2010 Stephen Bach
2
- " Permission is hereby granted to use and distribute this code,
3
- " with or without modifications, provided that this copyright
4
- " notice is copied with it. Like anything else that's free,
5
- " lusty-explorer.vim is provided *as is* and comes with no
6
- " warranty of any kind, either expressed or implied. In no
7
- " event will the copyright holder be liable for any damages
8
- " resulting from the use of this software.
9
- "
10
- " Name Of File: lusty-explorer.vim
11
- " Description: Dynamic Filesystem and Buffer Explorer Vim Plugin
12
- " Maintainers: Stephen Bach <this-file@sjbach.com>
13
- " Matt Tolton <matt-lusty-explorer@tolton.com>
14
- " Contributors: Raimon Grau, Sergey Popov, Yuichi Tateno, Bernhard Walle,
15
- " Rajendra Badapanda, cho45, Simo Salminen, Sami Samhuri,
16
- " Matt Tolton, Björn Winckler, sowill
17
- "
18
- " Release Date: March 3, 2010
19
- " Version: 2.1.3
20
- " Inspired by Viewglob, Emacs, and by Jeff Lanzarotta's Buffer
21
- " Explorer plugin.
22
- "
23
- " Usage: To launch the explorers:
24
- "
25
- " <Leader>lf - Opens the filesystem explorer.
26
- " <Leader>lr - Opens the filesystem explorer from the parent
27
- " directory of the current file.
28
- " <Leader>lb - Opens the buffer explorer.
29
- "
30
- " You can also use the commands:
31
- "
32
- " ":FilesystemExplorer"
33
- " ":FilesystemExplorerFromHere"
34
- " ":BufferExplorer"
35
- "
36
- " (Personally, I map these to ,f and ,r and ,b)
37
- "
38
- " The interface is intuitive. When one of the explorers is
39
- " launched, a new window appears at bottom presenting a list of
40
- " files/dirs or buffers, and in the status bar is a prompt:
41
- "
42
- " >>
43
- "
44
- " As you type, the list updates for possible matches using a
45
- " fuzzy matching algorithm. Special keys include:
46
- "
47
- " <Enter> open the selected match
48
- " <Tab> open the selected match
49
- " <Esc> cancel
50
- " <C-c> cancel
51
- " <C-g> cancel
52
- "
53
- " <C-t> open the selected match in a new tab
54
- " <C-n> select the next match
55
- " <C-p> select the previous match
56
- " <C-w> ascend one directory at prompt
57
- " <C-u> clear the prompt
58
- "
59
- " Additional shortcuts for the filesystem explorer:
60
- "
61
- " <C-r> refresh directory contents
62
- " <C-a> open all files in the current list
63
- " <C-e> create a new file with the given name
64
- "
65
- " Buffer Explorer:
66
- " - The currently active buffer is highlighted.
67
- " - Buffers are listed without path unless needed to differentiate buffers of
68
- " the same name.
69
- "
70
- " Filesystem Explorer:
71
- " - Directory contents are memoized.
72
- " - You can recurse into and out of directories by typing the directory name
73
- " and a slash, e.g. "stuff/" or "../".
74
- " - Variable expansion, e.g. "$D" -> "/long/dir/path/".
75
- " - Tilde (~) expansion, e.g. "~/" -> "/home/steve/".
76
- " - Dotfiles are hidden by default, but are shown if the current search term
77
- " begins with a '.'. To show these file at all times, set this option:
78
- "
79
- " let g:LustyExplorerAlwaysShowDotFiles = 1
80
- "
81
- " You can prevent certain files from appearing in the directory listings with
82
- " the following variable:
83
- "
84
- " set wildignore=*.o,*.fasl,CVS
85
- "
86
- " The above example will mask all object files, compiled lisp files, and
87
- " files/directories named CVS from appearing in the filesystem explorer.
88
- " Note that they can still be opened by being named explicitly.
89
- "
90
- " See :help 'wildignore' for more information.
91
- "
92
- "
93
- " Install Details:
94
- "
95
- " Copy this file into your $HOME/.vim/plugin directory so that it will be
96
- " sourced on startup automatically.
97
- "
98
- " Note! This plugin requires Vim be compiled with Ruby interpretation. If you
99
- " don't know if your build of Vim has this functionality, you can check by
100
- " running "vim --version" from the command line and looking for "+ruby".
101
- " Alternatively, just try sourcing this script.
102
- "
103
- " If your version of Vim does not have "+ruby" but you would still like to
104
- " use this plugin, you can fix it. See the "Check for Ruby functionality"
105
- " comment below for instructions.
106
- "
107
- " If you are using the same Vim configuration and plugins for multiple
108
- " machines, some of which have Ruby and some of which don't, you may want to
109
- " turn off the "Sorry, LustyExplorer requires ruby" warning. You can do so
110
- " like this (in .vimrc):
111
- "
112
- " let g:LustyExplorerSuppressRubyWarning = 1
113
- "
114
- " GetLatestVimScripts: 1890 1 :AutoInstall: lusty-explorer.vim
115
- "
116
- " TODO:
117
- " - when an edited file is in nowrap mode and the explorer is called while the
118
- " current window is scrolled to the right, name truncation occurs.
119
- " - bug: NO ENTRIES is not red when input is a space
120
- " - happens because LustyExpMatch declares after LustyExpNoEntries.
121
- " - if new_hash == previous_hash, don't bother 'repainting'.
122
-
123
- " Exit quickly when already loaded.
124
- if exists("g:loaded_lustyexplorer")
125
- finish
126
- endif
127
-
128
- if exists("g:FuzzyFinderMode.TextMate")
129
- echohl WarningMsg
130
- echo "Warning: LustyExplorer detects the presence of fuzzyfinder_textmate;"
131
- echo "that plugin sometimes interacts poorly with other Ruby plugins."
132
- echohl none
133
- endif
134
-
135
- " Check for Ruby functionality.
136
- if !has("ruby") || version < 700
137
- if !exists("g:LustyExplorerSuppressRubyWarning") ||
138
- \ g:LustyExplorerSuppressRubyWarning == "0"
139
- if !exists("g:LustyJugglerSuppressRubyWarning") ||
140
- \ g:LustyJugglerSuppressRubyWarning == "0"
141
- echohl ErrorMsg
142
- echon "Sorry, LustyExplorer requires ruby. "
143
- echon "Here are some tips for adding it:\n"
144
-
145
- echo "Debian / Ubuntu:"
146
- echo " # apt-get install vim-ruby\n"
147
-
148
- echo "Fedora:"
149
- echo " # yum install vim-enhanced\n"
150
-
151
- echo "Gentoo:"
152
- echo " # USE=\"ruby\" emerge vim\n"
153
-
154
- echo "FreeBSD:"
155
- echo " # pkg_add -r vim+ruby\n"
156
-
157
- echo "Windows:"
158
- echo " 1. Download and install Ruby from here:"
159
- echo " http://www.ruby-lang.org/"
160
- echo " 2. Install a Vim binary with Ruby support:"
161
- echo " http://segfault.hasno.info/vim/gvim72.zip\n"
162
-
163
- echo "Manually (including Cygwin):"
164
- echo " 1. Install Ruby."
165
- echo " 2. Download the Vim source package (say, vim-7.0.tar.bz2)"
166
- echo " 3. Build and install:"
167
- echo " # tar -xvjf vim-7.0.tar.bz2"
168
- echo " # ./configure --enable-rubyinterp"
169
- echo " # make && make install"
170
-
171
- echo "(If you just wish to stifle this message, set the following option:"
172
- echo " let g:LustyJugglerSuppressRubyWarning = 1)"
173
- echohl none
174
- endif
175
- endif
176
- finish
177
- endif
178
-
179
- let g:loaded_lustyexplorer = "yep"
180
-
181
- " Commands.
182
- command BufferExplorer :call <SID>BufferExplorerStart()
183
- command FilesystemExplorer :call <SID>FilesystemExplorerStart()
184
- command FilesystemExplorerFromHere :call <SID>FilesystemExplorerStartFromHere()
185
-
186
- " Default mappings.
187
- nmap <silent> <Leader>lf :FilesystemExplorer<CR>
188
- nmap <silent> <Leader>lr :FilesystemExplorerFromHere<CR>
189
- nmap <silent> <Leader>lb :BufferExplorer<CR>
190
-
191
- " Old mappings (from DynamicExplorer).
192
- nmap <silent> <Leader>df :FilesystemExplorer<CR>
193
- nmap <silent> <Leader>db :BufferExplorer<CR>
194
-
195
- " Vim-to-ruby function calls.
196
- function! s:FilesystemExplorerStart()
197
- ruby $filesystem_explorer.run_from_wd
198
- endfunction
199
-
200
- function! s:FilesystemExplorerStartFromHere()
201
- ruby $filesystem_explorer.run_from_here
202
- endfunction
203
-
204
- function! s:BufferExplorerStart()
205
- ruby $buffer_explorer.run
206
- endfunction
207
-
208
- function! FilesystemExplorerCancel()
209
- ruby $filesystem_explorer.cancel
210
- endfunction
211
-
212
- function! BufferExplorerCancel()
213
- ruby $buffer_explorer.cancel
214
- endfunction
215
-
216
- function! FilesystemExplorerKeyPressed(code_arg)
217
- ruby $filesystem_explorer.key_pressed
218
- endfunction
219
-
220
- function! BufferExplorerKeyPressed(code_arg)
221
- ruby $buffer_explorer.key_pressed
222
- endfunction
223
-
224
- " Setup the autocommands that handle buffer MRU ordering.
225
- "augroup LustyExplorer
226
- " autocmd!
227
- " autocmd BufEnter * ruby Window.buffer_stack.push
228
- " autocmd BufDelete * ruby Window.buffer_stack.pop
229
- " autocmd BufWipeout * ruby Window.buffer_stack.pop
230
- "augroup End
231
-
232
- ruby << EOF
233
- require 'pathname'
234
- # Needed for String#each_char in Ruby 1.8 on some platforms
235
- require 'jcode' unless "".respond_to? :each_char
236
-
237
- $PROFILING = false
238
-
239
- if $PROFILING
240
- require 'rubygems'
241
- require 'ruby-prof'
242
- end
243
-
244
- class String
245
- def ends_with?(s)
246
- tail = self[-s.length, s.length]
247
- tail == s
248
- end
249
-
250
- def starts_with?(s)
251
- head = self[0, s.length]
252
- head == s
253
- end
254
- end
255
-
256
- class IO
257
- def ready_for_read?
258
- result = IO.select([self], nil, nil, 0)
259
- result && (result.first.first == self)
260
- end
261
- end
262
-
263
- class File
264
- def self.simplify_path(s)
265
- begin
266
- if s[0] == '~'[0]
267
- s = File.expand_path(s.sub(/\/.*/,'')) + \
268
- s.sub(/^[^\/]+/,'')
269
- end
270
-
271
- if s.ends_with?(File::SEPARATOR)
272
- File.expand_path(s) + File::SEPARATOR
273
- else
274
- File.expand_path(File.dirname(s)) + File::SEPARATOR + File.basename(s)
275
- end
276
- rescue ArgumentError
277
- s
278
- end
279
- end
280
- end
281
-
282
- module VIM
283
- def self.zero?(var)
284
- # In Vim 7.2 and older, VIM::evaluate returns Strings for boolean
285
- # expressions; in later versions, Fixnums.
286
- case var
287
- when String
288
- var == "0"
289
- when Fixnum
290
- var == 0
291
- else
292
- assert(false, "unexpected type: #{var.class}")
293
- end
294
- end
295
-
296
- def self.nonzero?(var)
297
- not(self.zero? var)
298
- end
299
-
300
- def self.has_syntax?
301
- VIM::nonzero? eva('has("syntax")')
302
- end
303
-
304
- def self.columns
305
- eva("&columns").to_i
306
- end
307
-
308
- def self.lines
309
- eva("&lines").to_i
310
- end
311
-
312
- def self.getcwd
313
- eva("getcwd()")
314
- end
315
-
316
- def self.single_quote_escape(s)
317
- # Everything in a Vim single quoted string is literal, except single quotes.
318
- # Single quotes are escaped by doubling them.
319
- s.gsub("'", "''")
320
- end
321
-
322
- def self.filename_escape(s)
323
- # Escape slashes, open square braces, spaces, sharps, and double quotes.
324
- s.gsub(/\\/, '\\\\\\').gsub(/[\[ #"]/, '\\\\\0')
325
- end
326
-
327
- def self.regex_escape(s)
328
- s.gsub(/[\]\[.~"^$\\*]/,'\\\\\0')
329
- end
330
-
331
- class Buffer
332
- def modified?
333
- VIM::nonzero? eva("getbufvar(#{number()}, '&modified')")
334
- end
335
- end
336
- end
337
-
338
- def lusty_option_set?(opt_name)
339
- opt_name = "g:LustyExplorer" + opt_name
340
- VIM::nonzero? eva("exists('#{opt_name}') && #{opt_name} != '0'")
341
- end
342
-
343
- # Port of Ryan McGeary's LiquidMetal fuzzy matching algorithm found at:
344
- # http://github.com/rmm5t/liquidmetal/tree/master.
345
- class LiquidMetal
346
- @@SCORE_NO_MATCH = 0.0
347
- @@SCORE_MATCH = 1.0
348
- @@SCORE_TRAILING = 0.8
349
- @@SCORE_TRAILING_BUT_STARTED = 0.90
350
- @@SCORE_BUFFER = 0.85
351
-
352
- def self.score(string, abbrev)
353
-
354
- return @@SCORE_TRAILING if abbrev.empty?
355
- return @@SCORE_NO_MATCH if abbrev.length > string.length
356
-
357
- scores = buildScoreArray(string, abbrev)
358
-
359
- sum = scores.inject { |a, b| a + b }
360
-
361
- return sum / scores.length;
362
- end
363
-
364
- def self.buildScoreArray(string, abbrev)
365
- scores = Array.new(string.length)
366
- lower = string.downcase()
367
-
368
- lastIndex = -1
369
- started = false
370
-
371
- abbrev.downcase().each_char do |c|
372
- index = lower.index(c, lastIndex + 1)
373
- return scores.fill(@@SCORE_NO_MATCH, 0..-1) if index.nil?
374
- started = true if index == 0
375
-
376
- if index > 0 and " \t/._-".include?(string[index - 1])
377
- scores[index - 1] = @@SCORE_MATCH
378
- scores.fill(@@SCORE_BUFFER, (lastIndex + 1)...(index - 1))
379
- elsif string[index] >= "A"[0] and string[index] <= "Z"[0]
380
- scores.fill(@@SCORE_BUFFER, (lastIndex + 1)...index)
381
- else
382
- scores.fill(@@SCORE_NO_MATCH, (lastIndex + 1)...index)
383
- end
384
-
385
- scores[index] = @@SCORE_MATCH
386
- lastIndex = index
387
- end
388
-
389
- trailing_score = started ? @@SCORE_TRAILING_BUT_STARTED : @@SCORE_TRAILING
390
- scores.fill(trailing_score, lastIndex + 1)
391
- return scores
392
- end
393
- end
394
-
395
- # Used in FilesystemExplorer
396
- class Entry
397
- attr_accessor :name, :current_score
398
- def initialize(name)
399
- @name = name
400
- @current_score = 0.0
401
- end
402
- end
403
-
404
- # Used in BufferExplorer
405
- class BufferEntry < Entry
406
- attr_accessor :full_name, :vim_buffer
407
- def initialize(vim_buffer)
408
- @full_name = vim_buffer.name
409
- @vim_buffer = vim_buffer
410
- @name = "::UNSET::"
411
- @current_score = 0.0
412
- end
413
- end
414
-
415
- class LustyExplorer
416
- public
417
- def initialize
418
- @settings = SavedSettings.new
419
- @displayer = Displayer.new title()
420
- @prompt = nil
421
- @ordered_matching_entries = []
422
- @running = false
423
- end
424
-
425
- def run
426
- return if @running
427
-
428
- if $PROFILING
429
- RubyProf.measure_mode = RubyProf::WALL_TIME
430
- end
431
-
432
- @settings.save
433
- @running = true
434
- @calling_window = $curwin
435
- @saved_alternate_bufnum = if VIM::nonzero? eva("expand('#') == ''")
436
- nil
437
- else
438
- eva("bufnr(expand('#'))")
439
- end
440
- @selected_index = 0
441
- create_explorer_window()
442
- refresh(:full)
443
- end
444
-
445
- def key_pressed()
446
- # Grab argument from the Vim function.
447
- i = eva("a:code_arg").to_i
448
- refresh_mode = :full
449
-
450
- case i
451
- when 32..126 # Printable characters
452
- c = i.chr
453
- @prompt.add! c
454
- @selected_index = 0
455
- when 8 # Backspace/Del/C-h
456
- @prompt.backspace!
457
- @selected_index = 0
458
- when 9, 13 # Tab and Enter
459
- choose(:current_tab)
460
- @selected_index = 0
461
- when 23 # C-w (delete 1 dir backward)
462
- @prompt.up_one_dir!
463
- @selected_index = 0
464
- when 14 # C-n (select next)
465
- @selected_index = \
466
- (@selected_index + 1) % @ordered_matching_entries.size
467
- refresh_mode = :no_recompute
468
- when 16 # C-p (select previous)
469
- @selected_index = \
470
- (@selected_index - 1) % @ordered_matching_entries.size
471
- refresh_mode = :no_recompute
472
- when 20 # C-t choose in new tab
473
- choose(:new_tab)
474
- @selected_index = 0
475
- when 21 # C-u clear prompt
476
- @prompt.clear!
477
- @selected_index = 0
478
- end
479
-
480
- refresh(refresh_mode)
481
- end
482
-
483
- def cancel
484
- if @running
485
- cleanup()
486
- # fix alternate file
487
- if @saved_alternate_bufnum
488
- cur = $curbuf
489
- exe "silent b #{@saved_alternate_bufnum}"
490
- exe "silent b #{cur.number}"
491
- end
492
-
493
- if $PROFILING
494
- #outfile = File.new('rbprof.txt', 'a')
495
- #RubyProf::CallTreePrinter.new(RubyProf.stop).print(outfile)
496
- outfile = File.new('rbprof.html', 'a')
497
- RubyProf::GraphHtmlPrinter.new(RubyProf.stop).print(outfile)
498
- end
499
- end
500
- end
501
-
502
- private
503
- def refresh(mode)
504
- return if not @running
505
-
506
- if mode == :full
507
- @ordered_matching_entries = compute_ordered_matching_entries()
508
- end
509
-
510
- on_refresh()
511
- highlight_selected_index()
512
- @displayer.print @ordered_matching_entries.map { |x| x.name }
513
- @prompt.print
514
- end
515
-
516
- def create_explorer_window
517
-
518
- @displayer.create
519
-
520
- # Setup key mappings to reroute user input.
521
-
522
- # Non-special printable characters.
523
- printables = '/!"#$%&\'()*+,-.0123456789:<=>?#@"' \
524
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
525
- '[]^_`abcdefghijklmnopqrstuvwxyz{}~'
526
-
527
- map_command = "noremap <silent> <buffer> "
528
-
529
- printables.each_byte do |b|
530
- exe "#{map_command} <Char-#{b}> :call #{self.class}KeyPressed(#{b})<CR>"
531
- end
532
-
533
- # Special characters
534
- exe "#{map_command} <Tab> :call #{self.class}KeyPressed(9)<CR>"
535
- exe "#{map_command} <Bslash> :call #{self.class}KeyPressed(92)<CR>"
536
- exe "#{map_command} <Space> :call #{self.class}KeyPressed(32)<CR>"
537
- exe "#{map_command} \026| :call #{self.class}KeyPressed(124)<CR>"
538
-
539
- exe "#{map_command} <BS> :call #{self.class}KeyPressed(8)<CR>"
540
- exe "#{map_command} <Del> :call #{self.class}KeyPressed(8)<CR>"
541
- exe "#{map_command} <C-h> :call #{self.class}KeyPressed(8)<CR>"
542
-
543
- exe "#{map_command} <CR> :call #{self.class}KeyPressed(13)<CR>"
544
- exe "#{map_command} <S-CR> :call #{self.class}KeyPressed(10)<CR>"
545
- exe "#{map_command} <C-a> :call #{self.class}KeyPressed(1)<CR>"
546
-
547
- exe "#{map_command} <Esc> :call #{self.class}Cancel()<CR>"
548
- exe "#{map_command} <C-c> :call #{self.class}Cancel()<CR>"
549
- exe "#{map_command} <C-g> :call #{self.class}Cancel()<CR>"
550
-
551
- exe "#{map_command} <C-w> :call #{self.class}KeyPressed(23)<CR>"
552
- exe "#{map_command} <C-n> :call #{self.class}KeyPressed(14)<CR>"
553
- exe "#{map_command} <C-p> :call #{self.class}KeyPressed(16)<CR>"
554
- exe "#{map_command} <C-t> :call #{self.class}KeyPressed(20)<CR>"
555
- exe "#{map_command} <C-e> :call #{self.class}KeyPressed(5)<CR>"
556
- exe "#{map_command} <C-r> :call #{self.class}KeyPressed(18)<CR>"
557
- exe "#{map_command} <C-u> :call #{self.class}KeyPressed(21)<CR>"
558
- end
559
-
560
- def highlight_selected_index
561
- return unless VIM::has_syntax?
562
-
563
- entry = @ordered_matching_entries[@selected_index]
564
- return if entry.nil?
565
-
566
- exe "syn clear LustyExpSelected"
567
- exe "syn match LustyExpSelected " \
568
- "\"#{Displayer.vim_match_string(entry.name, false)}\" "
569
- end
570
-
571
- def compute_ordered_matching_entries
572
- abbrev = current_abbreviation()
573
- unordered = matching_entries()
574
-
575
- # Sort alphabetically if there's just a dot or we have no abbreviation,
576
- # otherwise it just looks weird.
577
- if abbrev.length == 0 or abbrev == '.'
578
- unordered.sort! { |x, y| x.name <=> y.name }
579
- else
580
- # Sort by score.
581
- unordered.sort! { |x, y| y.current_score <=> x.current_score }
582
- end
583
- end
584
-
585
- def matching_entries
586
- all_entries().select { |x|
587
- x.current_score = LiquidMetal.score(x.name, current_abbreviation())
588
- x.current_score != 0.0
589
- }
590
- end
591
-
592
- def choose(open_mode)
593
- entry = @ordered_matching_entries[@selected_index]
594
- return if entry.nil?
595
- @selected_index = 0
596
- open_entry(entry, open_mode)
597
- end
598
-
599
- def cleanup
600
- @displayer.close
601
- Window.select @calling_window
602
- @settings.restore
603
- @running = false
604
- msg ""
605
- assert(@calling_window == $curwin)
606
- end
607
- end
608
-
609
-
610
- class BufferExplorer < LustyExplorer
611
- public
612
- def initialize
613
- super
614
- @prompt = Prompt.new
615
- @buffer_entries = []
616
- end
617
-
618
- def run
619
- unless @running
620
- @prompt.clear!
621
- @curbuf_at_start = VIM::Buffer.current
622
- fill_buffer_entries()
623
- super
624
- end
625
- end
626
-
627
- private
628
- def title
629
- '[LustyExplorer-Buffers]'
630
- end
631
-
632
- def curbuf_match_string
633
- curbuf = @buffer_entries.find { |x| x.vim_buffer == @curbuf_at_start }
634
- if curbuf
635
- Displayer.vim_match_string(curbuf.name, @prompt.insensitive?)
636
- else
637
- ""
638
- end
639
- end
640
-
641
- def on_refresh
642
- # Highlighting for the current buffer name.
643
- if VIM::has_syntax?
644
- exe 'syn clear LustyExpCurrentBuffer'
645
- exe "syn match LustyExpCurrentBuffer \"#{curbuf_match_string()}\" " \
646
- 'contains=LustyExpModified'
647
- end
648
- end
649
-
650
- def common_prefix(entries)
651
- prefix = entries[0].full_name
652
- entries.each do |entry|
653
- full_name = entry.full_name
654
- for i in 0...prefix.length
655
- if full_name.length <= i or prefix[i] != full_name[i]
656
- prefix = prefix[0...i]
657
- prefix = prefix[0..(prefix.rindex('/') or -1)]
658
- break
659
- end
660
- end
661
- end
662
- return prefix
663
- end
664
-
665
- def fill_buffer_entries
666
- @buffer_entries.clear
667
- (0..VIM::Buffer.count-1).each do |i|
668
- @buffer_entries << BufferEntry.new(VIM::Buffer[i])
669
- end
670
-
671
- # Shorten each buffer name by removing all path elements which are not
672
- # needed to differentiate a given name from other names. This usually
673
- # results in only the basename shown, but if several buffers of the
674
- # same basename are opened, there will be more.
675
-
676
- # Group the buffers by common basename
677
- common_base = Hash.new { |hash, k| hash[k] = [] }
678
- @buffer_entries.each do |entry|
679
- if entry.full_name
680
- basename = Pathname.new(entry.full_name).basename.to_s
681
- common_base[basename] << entry
682
- end
683
- end
684
-
685
- # Determine the longest common prefix for each basename group.
686
- basename_to_prefix = {}
687
- common_base.each do |base, entries|
688
- if entries.length > 1
689
- basename_to_prefix[base] = common_prefix(entries)
690
- end
691
- end
692
-
693
- # Compute shortened buffer names by removing prefix, if possible.
694
- @buffer_entries.each do |entry|
695
- full_name = entry.full_name
696
-
697
- short_name = if full_name.nil?
698
- '[No Name]'
699
- elsif full_name.starts_with?("scp://")
700
- full_name
701
- else
702
- base = Pathname.new(full_name).basename.to_s
703
- prefix = basename_to_prefix[base]
704
-
705
- prefix ? full_name[prefix.length..-1] \
706
- : base
707
- end
708
-
709
- # Disabled: show buffer number next to name
710
- #short_name += ' ' + buffer.number.to_s
711
-
712
- # Show modification indicator
713
- short_name += entry.vim_buffer.modified? ? " [+]" : ""
714
-
715
- entry.name = short_name
716
- end
717
- end
718
-
719
- def current_abbreviation
720
- @prompt.input
721
- end
722
-
723
- def all_entries
724
- @buffer_entries
725
- end
726
-
727
- def open_entry(entry, open_mode)
728
- cleanup()
729
- assert($curwin == @calling_window)
730
-
731
- number = entry.vim_buffer.number
732
- assert(number)
733
-
734
- cmd = case open_mode
735
- when :current_tab
736
- "b"
737
- when :new_tab
738
- # For some reason just using tabe or e gives an error when
739
- # the alternate-file isn't set.
740
- "tab split | b"
741
- else
742
- assert(false, "bad open mode")
743
- end
744
-
745
- exe "silent #{cmd} #{number}"
746
- end
747
- end
748
-
749
- def time
750
- if $PROFILING
751
- RubyProf.resume
752
- end
753
- begin
754
- yield
755
- rescue Exception => e
756
- puts e
757
- puts e.backtrace
758
- end
759
- if $PROFILING
760
- RubyProf.pause
761
- end
762
- end
763
-
764
- class FilesystemExplorer < LustyExplorer
765
- public
766
- def initialize
767
- super
768
- @prompt = FilesystemPrompt.new
769
- @memoized_entries = {}
770
- end
771
-
772
- def run
773
- FileMasks.create_glob_masks()
774
- @vim_swaps = VimSwaps.new
775
- super
776
- end
777
-
778
- def run_from_here
779
- start_path = if $curbuf.name.nil?
780
- VIM::getcwd()
781
- else
782
- eva("expand('%:p:h')")
783
- end
784
-
785
- @prompt.set!(start_path + File::SEPARATOR)
786
- run()
787
- end
788
-
789
- def run_from_wd
790
- @prompt.set!(VIM::getcwd() + File::SEPARATOR)
791
- run()
792
- end
793
-
794
- def key_pressed()
795
- time do
796
- i = eva("a:code_arg").to_i
797
-
798
- case i
799
- when 1, 10 # <C-a>, <Shift-Enter>
800
- cleanup()
801
- # Open all non-directories currently in view.
802
- @ordered_matching_entries.each do |e|
803
- path_str = \
804
- if @prompt.at_dir?
805
- @prompt.input + e.name
806
- else
807
- @prompt.dirname + File::SEPARATOR + e.name
808
- end
809
-
810
- load_file(path_str, :current_tab) unless File.directory?(path_str)
811
- end
812
- when 5 # <C-e> edit file, create it if necessary
813
- if not @prompt.at_dir?
814
- cleanup()
815
- # Force a reread of this directory so that the new file will
816
- # show up (as long as it is saved before the next run).
817
- @memoized_entries.delete(view_path())
818
- load_file(@prompt.input, :current_tab)
819
- end
820
- when 18 # <C-r> refresh
821
- @memoized_entries.delete(view_path())
822
- refresh(:full)
823
- else
824
- super
825
- end
826
- end
827
- end
828
-
829
- private
830
- def title
831
- '[LustyExplorer-Files]'
832
- end
833
-
834
- def on_refresh
835
- if VIM::has_syntax?
836
- exe 'syn clear LustyExpFileWithSwap'
837
-
838
- view = view_path()
839
- @vim_swaps.file_names.each do |file_with_swap|
840
- if file_with_swap.dirname == view
841
- base = file_with_swap.basename
842
- match_str = Displayer.vim_match_string(base.to_s, false)
843
- exe "syn match LustyExpFileWithSwap \"#{match_str}\""
844
- end
845
- end
846
- end
847
-
848
- # TODO: restore highlighting for open buffers?
849
- end
850
-
851
- def current_abbreviation
852
- if @prompt.at_dir?
853
- ""
854
- else
855
- File.basename(@prompt.input)
856
- end
857
- end
858
-
859
- def view_path
860
- input = @prompt.input
861
-
862
- path = \
863
- if @prompt.at_dir? and \
864
- input.length > 1 # Not root
865
- # The last element in the path is a directory + '/' and we want to
866
- # see what's in it instead of what's in its parent directory.
867
-
868
- Pathname.new(input[0..-2]) # Canonicalize by removing trailing '/'
869
- else
870
- Pathname.new(input).dirname
871
- end
872
-
873
- return path
874
- end
875
-
876
- def all_entries
877
- view = view_path()
878
-
879
- if not view.exist?
880
- return []
881
- elsif not view.readable?
882
- # TODO: show "-- PERMISSION DENIED --"
883
- return []
884
- end
885
-
886
- unless @memoized_entries.has_key?(view)
887
- # Generate an array of the files
888
- entries = []
889
- view.each_entry do |file|
890
- name = file.basename.to_s
891
- next if name == "." # Skip pwd
892
- next if name == ".." and lusty_option_set?("AlwaysShowDotFiles")
893
-
894
- # Hide masked files.
895
- next if FileMasks.masked?(name)
896
-
897
- if (view + file).directory?
898
- # ^^ bug in Pathname.each_entry -- block variable has no dir.
899
- name += File::SEPARATOR
900
- end
901
- entries << Entry.new(name)
902
- end
903
- @memoized_entries[view] = entries
904
- end
905
-
906
- all = @memoized_entries[view]
907
-
908
- if lusty_option_set?("AlwaysShowDotFiles") or \
909
- current_abbreviation()[0] == '.'[0]
910
- all
911
- else
912
- # Filter out dotfiles if the current abbreviation doesn't start with
913
- # '.'.
914
- all.select { |x| x.name[0] != '.'[0] }
915
- end
916
- end
917
-
918
- def open_entry(entry, open_mode)
919
- path = view_path() + entry.name
920
-
921
- if File.directory?(path)
922
- # Recurse into the directory instead of opening it.
923
- @prompt.set!(path.to_s)
924
- elsif entry.name.include?(File::SEPARATOR)
925
- # Don't open a fake file/buffer with "/" in its name.
926
- return
927
- else
928
- cleanup()
929
- load_file(path.to_s, open_mode)
930
- end
931
- end
932
-
933
- def load_file(path_str, open_mode)
934
- assert($curwin == @calling_window)
935
- # Escape for Vim and remove leading ./ for files in pwd.
936
- escaped = VIM::filename_escape(path_str).sub(/^\.\//,"")
937
- sanitized = eva "fnamemodify('#{escaped}', ':.')"
938
- cmd = case open_mode
939
- when :current_tab
940
- "e"
941
- when :new_tab
942
- "tabe"
943
- else
944
- assert(false, "bad open mode")
945
- end
946
-
947
- exe "silent #{cmd} #{sanitized}"
948
- end
949
- end
950
-
951
-
952
- class Prompt
953
- private
954
- @@PROMPT = ">> "
955
-
956
- public
957
- def initialize
958
- clear!
959
- end
960
-
961
- def clear!
962
- @input = ""
963
- end
964
-
965
- def print
966
- pretty_msg("Comment", @@PROMPT, "None", @input, "Underlined", " ")
967
- end
968
-
969
- def set!(s)
970
- @input = s
971
- end
972
-
973
- def input
974
- @input
975
- end
976
-
977
- def insensitive?
978
- @input == @input.downcase
979
- end
980
-
981
- def ends_with?(c)
982
- @input.ends_with? c
983
- end
984
-
985
- def add!(s)
986
- @input += s
987
- end
988
-
989
- def backspace!
990
- @input.chop!
991
- end
992
-
993
- def up_one_dir!
994
- @input.chop!
995
- while !@input.empty? and @input[-1] != '/'[0]
996
- @input.chop!
997
- end
998
- end
999
- end
1000
-
1001
- class FilesystemPrompt < Prompt
1002
-
1003
- def initialize
1004
- super
1005
- @memoized = nil
1006
- @dirty = true
1007
- end
1008
-
1009
- def clear!
1010
- @dirty = true
1011
- super
1012
- end
1013
-
1014
- def set!(s)
1015
- @dirty = true
1016
- # On Windows, Vim will return paths with a '\' separator, but
1017
- # we want to use '/'.
1018
- super(s.gsub('\\', '/'))
1019
- end
1020
-
1021
- def backspace!
1022
- @dirty = true
1023
- super
1024
- end
1025
-
1026
- def up_one_dir!
1027
- @dirty = true
1028
- super
1029
- end
1030
-
1031
- def at_dir?
1032
- # We have not typed anything yet or have just typed the final '/' on a
1033
- # directory name in pwd. This check is interspersed throughout
1034
- # FilesystemExplorer because of the conventions of basename and dirname.
1035
- input().empty? or input().ends_with?(File::SEPARATOR)
1036
- # Don't think the File.directory? call is necessary, but leaving this
1037
- # here as a reminder.
1038
- #(File.directory?(input()) and input().ends_with?(File::SEPARATOR))
1039
- end
1040
-
1041
- def insensitive?
1042
- at_dir? or (basename() == basename().downcase)
1043
- end
1044
-
1045
- def add!(s)
1046
- # Assumption: add!() will only receive enough chars at a time to complete
1047
- # a single directory level, e.g. foo/, not foo/bar/
1048
-
1049
- @input += s
1050
- @dirty = true
1051
- end
1052
-
1053
- def input
1054
- if @dirty
1055
- @memoized = variable_expansion(File.simplify_path(@input))
1056
- @dirty = false
1057
- end
1058
-
1059
- @memoized
1060
- end
1061
-
1062
- def basename
1063
- File.basename input()
1064
- end
1065
-
1066
- def dirname
1067
- File.dirname input()
1068
- end
1069
-
1070
- private
1071
- def variable_expansion (input_str)
1072
- # FIXME does this still work?
1073
- strings = input_str.split('$', -1)
1074
- return "" if strings.nil? or strings.length == 0
1075
-
1076
- first = strings.shift
1077
-
1078
- # Try to expand each instance of $<word>.
1079
- strings.inject(first) { |str, s|
1080
- if s =~ /^(\w+)/ and ENV[$1]
1081
- str + s.sub($1, ENV[$1])
1082
- else
1083
- str + "$" + s
1084
- end
1085
- }
1086
- end
1087
- end
1088
-
1089
- # Simplify switching between windows.
1090
- class Window
1091
- def Window.select(window)
1092
- return true if window == $curwin
1093
-
1094
- start = $curwin
1095
-
1096
- # Try to select the given window.
1097
- begin
1098
- exe "wincmd w"
1099
- end while ($curwin != window) and ($curwin != start)
1100
-
1101
- if $curwin == window
1102
- return true
1103
- else
1104
- # Failed -- re-select the starting window.
1105
- exe("wincmd w") while $curwin != start
1106
- pretty_msg("ErrorMsg", "Cannot find the correct window!")
1107
- return false
1108
- end
1109
- end
1110
- end
1111
-
1112
- # Save and restore settings when creating the explorer buffer.
1113
- class SavedSettings
1114
- def initialize
1115
- save()
1116
- end
1117
-
1118
- def save
1119
- @timeoutlen = eva "&timeoutlen"
1120
-
1121
- @splitbelow = VIM::nonzero? eva("&splitbelow")
1122
- @insertmode = VIM::nonzero? eva("&insertmode")
1123
- @showcmd = VIM::nonzero? eva("&showcmd")
1124
- @list = VIM::nonzero? eva("&list")
1125
-
1126
- @report = eva "&report"
1127
- @sidescroll = eva "&sidescroll"
1128
- @sidescrolloff = eva "&sidescrolloff"
1129
- end
1130
-
1131
- def restore
1132
- set "timeoutlen=#{@timeoutlen}"
1133
-
1134
- if @splitbelow
1135
- set "splitbelow"
1136
- else
1137
- set "nosplitbelow"
1138
- end
1139
-
1140
- if @insertmode
1141
- set "insertmode"
1142
- else
1143
- set "noinsertmode"
1144
- end
1145
-
1146
- if @showcmd
1147
- set "showcmd"
1148
- else
1149
- set "noshowcmd"
1150
- end
1151
-
1152
- if @list
1153
- set "list"
1154
- else
1155
- set "nolist"
1156
- end
1157
-
1158
- exe "set report=#{@report}"
1159
- exe "set sidescroll=#{@sidescroll}"
1160
- exe "set sidescrolloff=#{@sidescrolloff}"
1161
- end
1162
- end
1163
-
1164
- # Manage the explorer buffer.
1165
- class Displayer
1166
- private
1167
- @@COLUMN_SEPARATOR = " "
1168
- @@NO_ENTRIES_STRING = "-- NO ENTRIES --"
1169
- @@TRUNCATED_STRING = "-- TRUNCATED --"
1170
-
1171
- public
1172
- def Displayer.vim_match_string(s, case_insensitive)
1173
- # Create a match regex string for the given s. This is for a Vim regex,
1174
- # not for a Ruby regex.
1175
-
1176
- str = '\%(^\|' + @@COLUMN_SEPARATOR + '\)' \
1177
- '\zs' + VIM::regex_escape(s) + '\%( \[+\]\)\?' + '\ze' \
1178
- '\%(\s*$\|' + @@COLUMN_SEPARATOR + '\)'
1179
-
1180
- str += '\c' if case_insensitive
1181
-
1182
- return str
1183
- end
1184
-
1185
- def initialize(title)
1186
- @title = title
1187
- @window = nil
1188
- @buffer = nil
1189
- end
1190
-
1191
- def create
1192
- # Make a window for the displayer and move there.
1193
- exe "silent! botright split #{@title}"
1194
-
1195
- @window = $curwin
1196
- @buffer = $curbuf
1197
-
1198
- # Displayer buffer is special.
1199
- exe "setlocal bufhidden=delete"
1200
- exe "setlocal buftype=nofile"
1201
- exe "setlocal nomodifiable"
1202
- exe "setlocal noswapfile"
1203
- exe "setlocal nowrap"
1204
- exe "setlocal nonumber"
1205
- exe "setlocal foldcolumn=0"
1206
- exe "setlocal nocursorline"
1207
- exe "setlocal nospell"
1208
- exe "setlocal nobuflisted"
1209
- exe "setlocal textwidth=0"
1210
-
1211
- # (Update SavedSettings if adding to below.)
1212
- set "timeoutlen=0"
1213
- set "noinsertmode"
1214
- set "noshowcmd"
1215
- set "nolist"
1216
- set "report=9999"
1217
- set "sidescroll=0"
1218
- set "sidescrolloff=0"
1219
-
1220
- # TODO -- cpoptions?
1221
-
1222
- if VIM::has_syntax?
1223
- exe 'syn match LustyExpSlash "/" contained'
1224
- exe 'syn match LustyExpDir "\zs\%(\S\+ \)*\S\+/\ze" ' \
1225
- 'contains=LustyExpSlash'
1226
-
1227
- exe 'syn match LustyExpModified " \[+\]"'
1228
-
1229
- exe 'syn match LustyExpNoEntries "\%^\s*' \
1230
- "#{@@NO_ENTRIES_STRING}" \
1231
- '\s*\%$"'
1232
-
1233
- exe 'syn match LustyExpTruncated "^\s*' \
1234
- "#{@@TRUNCATED_STRING}" \
1235
- '\s*$"'
1236
-
1237
- exe 'highlight link LustyExpDir Directory'
1238
- exe 'highlight link LustyExpSlash Function'
1239
- exe 'highlight link LustyExpSelected Type'
1240
- exe 'highlight link LustyExpModified Special'
1241
- exe 'highlight link LustyExpCurrentBuffer Constant'
1242
- exe 'highlight link LustyExpOpenedFile PreProc'
1243
- exe 'highlight link LustyExpFileWithSwap WarningMsg'
1244
- exe 'highlight link LustyExpNoEntries ErrorMsg'
1245
- exe 'highlight link LustyExpTruncated Visual'
1246
- end
1247
- end
1248
-
1249
- def print(strings)
1250
- Window.select(@window) || return
1251
-
1252
- if strings.empty?
1253
- print_no_entries()
1254
- return
1255
- end
1256
-
1257
- # Perhaps truncate the results to just over the upper bound of
1258
- # displayable strings. This isn't exact, but it's close enough.
1259
- max = VIM::lines * (VIM::columns / (1 + @@COLUMN_SEPARATOR.length))
1260
- if strings.length > max
1261
- strings.slice!(max, strings.length - max)
1262
- end
1263
-
1264
- # Get a high upper bound on the number of columns to display to optimize
1265
- # the following algorithm a little.
1266
- col_count = column_count_upper_bound(strings)
1267
-
1268
- # Figure out the actual number of columns to use (yuck)
1269
- cols = nil
1270
- widths = nil
1271
- while col_count > 1 do
1272
-
1273
- cols = columnize(strings, col_count);
1274
-
1275
- widths = cols.map { |col|
1276
- col.max { |a, b| a.length <=> b.length }.length
1277
- }
1278
-
1279
- full_width = widths.inject { |sum, n| sum + n }
1280
- full_width += @@COLUMN_SEPARATOR.length * (col_count - 1)
1281
-
1282
- if full_width <= $curwin.width
1283
- break
1284
- end
1285
-
1286
- col_count -= 1
1287
- end
1288
-
1289
- if col_count <= 1
1290
- cols = [strings]
1291
- widths = [0]
1292
- end
1293
-
1294
- print_columns(cols, widths)
1295
- end
1296
-
1297
- def close
1298
- # Only wipe the buffer if we're *sure* it's the explorer.
1299
- if Window.select @window and \
1300
- $curbuf == @buffer and \
1301
- $curbuf.name =~ /#{Regexp.escape(@title)}$/
1302
- exe "bwipeout!"
1303
- @window = nil
1304
- @buffer = nil
1305
- end
1306
- end
1307
-
1308
- private
1309
- def print_columns(cols, widths)
1310
- unlock_and_clear()
1311
-
1312
- # Set the height to the height of the longest column.
1313
- $curwin.height = cols.max { |a, b| a.length <=> b.length }.length
1314
-
1315
- (0..$curwin.height-1).each do |i|
1316
-
1317
- string = ""
1318
- (0..cols.length-1).each do |j|
1319
- break if cols[j][i].nil?
1320
- string += cols[j][i]
1321
- string += " " * [(widths[j] - cols[j][i].length), 0].max
1322
- string += @@COLUMN_SEPARATOR
1323
- end
1324
-
1325
- # Stretch the line to the length of the window with whitespace so that
1326
- # we can "hide" the cursor in the corner.
1327
- string += " " * [($curwin.width - string.length), 0].max
1328
-
1329
- $curwin.cursor = [i+1, 1]
1330
- $curbuf.append(i, string)
1331
- end
1332
-
1333
- # Check for result truncation.
1334
- if cols[0][$curwin.height]
1335
- # Show a truncation indicator.
1336
- $curbuf.delete($curbuf.count - 1)
1337
- $curwin.cursor = [$curbuf.count, 1]
1338
- $curbuf.append($curbuf.count - 1, \
1339
- @@TRUNCATED_STRING.center($curwin.width, " "))
1340
- end
1341
-
1342
- # There's a blank line at the end of the buffer because of how
1343
- # VIM::Buffer.append works.
1344
- $curbuf.delete $curbuf.count
1345
- lock()
1346
- end
1347
-
1348
- def print_no_entries
1349
- unlock_and_clear()
1350
- $curwin.height = 1
1351
-
1352
- $curbuf[1] = @@NO_ENTRIES_STRING.center($curwin.width, " ")
1353
- lock()
1354
- end
1355
-
1356
- def unlock_and_clear
1357
- exe "setlocal modifiable"
1358
-
1359
- # Clear the explorer (black hole register)
1360
- exe "silent %d _"
1361
- end
1362
-
1363
- def lock
1364
- exe "setlocal nomodifiable"
1365
-
1366
- # Hide the cursor
1367
- exe "normal! Gg$"
1368
- end
1369
-
1370
- # Get a starting upper bound on the number of columns
1371
- def column_count_upper_bound(strings)
1372
- column_count = 0
1373
- length = 0
1374
-
1375
- sorted_by_length = strings.sort {|x, y| x.length <=> y.length }
1376
-
1377
- sorted_by_length.each do |e|
1378
- length += e.length
1379
- break unless length < $curwin.width
1380
-
1381
- column_count += 1
1382
- length += @@COLUMN_SEPARATOR.length
1383
- end
1384
-
1385
- return column_count
1386
- end
1387
-
1388
- def columnize(strings, n_cols)
1389
- n_rows = (strings.length.to_f / n_cols).ceil
1390
-
1391
- # Break the array into sub arrays representing columns
1392
- cols = []
1393
- 0.step(strings.size-1, n_rows) do |i|
1394
- cols << strings[i..(i + n_rows - 1)]
1395
- end
1396
- return cols
1397
- end
1398
- end
1399
-
1400
-
1401
- class FileMasks
1402
- private
1403
- @@glob_masks = []
1404
-
1405
- public
1406
- def FileMasks.create_glob_masks
1407
- @@glob_masks = \
1408
- if VIM::nonzero? eva('exists("g:LustyExplorerFileMasks")')
1409
- # Note: this variable deprecated.
1410
- eva("g:LustyExplorerFileMasks").split(',')
1411
- elsif VIM::nonzero? eva('exists("&wildignore")')
1412
- eva("&wildignore").split(',')
1413
- else
1414
- []
1415
- end
1416
- end
1417
-
1418
- def FileMasks.masked?(str)
1419
- @@glob_masks.each do |mask|
1420
- return true if File.fnmatch(mask, str)
1421
- end
1422
-
1423
- return false
1424
- end
1425
- end
1426
-
1427
- class VimSwaps
1428
- def initialize
1429
- if VIM::has_syntax?
1430
- # FIXME: vvv disabled
1431
- # @vim_r = IO.popen("vim -r 2>&1")
1432
- # @files_with_swaps = nil
1433
- @files_with_swaps = []
1434
- else
1435
- @files_with_swaps = []
1436
- end
1437
- end
1438
-
1439
- def file_names
1440
- if @files_with_swaps.nil?
1441
- if @vim_r.ready_for_read?
1442
- @files_with_swaps = []
1443
- @vim_r.each_line do |line|
1444
- if line =~ /^ +file name: (.*)$/
1445
- file = $1.chomp
1446
- @files_with_swaps << Pathname.new(File.simplify_path(file))
1447
- end
1448
- end
1449
- else
1450
- return []
1451
- end
1452
- end
1453
-
1454
- @files_with_swaps
1455
- end
1456
- end
1457
-
1458
-
1459
- def d(s)
1460
- # (Debug print)
1461
- $stderr.puts s
1462
- end
1463
-
1464
- # Simple mappings to decrease typing.
1465
- def exe(s)
1466
- VIM.command s
1467
- end
1468
-
1469
- def eva(s)
1470
- VIM.evaluate s
1471
- end
1472
-
1473
- def set(s)
1474
- VIM.set_option s
1475
- end
1476
-
1477
- def msg(s)
1478
- VIM.message s
1479
- end
1480
-
1481
- def pretty_msg(*rest)
1482
- return if rest.length == 0
1483
- return if rest.length % 2 != 0
1484
-
1485
- exe "redraw" # see :help echo-redraw
1486
- i = 0
1487
- while i < rest.length do
1488
- exe "echohl #{rest[i]}"
1489
- exe "echon '#{rest[i+1]}'"
1490
- i += 2
1491
- end
1492
-
1493
- exe 'echohl None'
1494
- end
1495
-
1496
- class AssertionError < StandardError
1497
- end
1498
-
1499
- def assert(condition, message = 'assertion failure')
1500
- raise AssertionError.new(message) unless condition
1501
- end
1502
-
1503
-
1504
- $buffer_explorer = BufferExplorer.new
1505
- $filesystem_explorer = FilesystemExplorer.new
1506
-
1507
- EOF
1508
-
1509
- " vim: set sts=2 sw=2: