]> git.r.bdr.sh - rbdr/dotfiles/blob - vim/tmp/command-t-1.2.1.vba
Relative line numbers for vim
[rbdr/dotfiles] / vim / tmp / command-t-1.2.1.vba
1 " Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
2 UseVimball
3 finish
4 ruby/command-t/controller.rb [[[1
5 317
6 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # 1. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 require 'command-t/finder/buffer_finder'
30 require 'command-t/finder/file_finder'
31 require 'command-t/match_window'
32 require 'command-t/prompt'
33 require 'command-t/vim/path_utilities'
34
35 module CommandT
36 class Controller
37 include VIM::PathUtilities
38
39 def initialize
40 @prompt = Prompt.new
41 @buffer_finder = CommandT::BufferFinder.new
42 set_up_file_finder
43 set_up_max_height
44 end
45
46 def show_buffer_finder
47 @path = VIM::pwd
48 @active_finder = @buffer_finder
49 show
50 end
51
52 def show_file_finder
53 # optional parameter will be desired starting directory, or ""
54 @path = File.expand_path(::VIM::evaluate('a:arg'), VIM::pwd)
55 @file_finder.path = @path
56 @active_finder = @file_finder
57 show
58 rescue Errno::ENOENT
59 # probably a problem with the optional parameter
60 @match_window.print_no_such_file_or_directory
61 end
62
63 def hide
64 @match_window.close
65 if VIM::Window.select @initial_window
66 if @initial_buffer.number == 0
67 # upstream bug: buffer number misreported as 0
68 # see: https://wincent.com/issues/1617
69 ::VIM::command "silent b #{@initial_buffer.name}"
70 else
71 ::VIM::command "silent b #{@initial_buffer.number}"
72 end
73 end
74 end
75
76 def flush
77 set_up_max_height
78 set_up_file_finder
79 end
80
81 def handle_key
82 key = ::VIM::evaluate('a:arg').to_i.chr
83 if @focus == @prompt
84 @prompt.add! key
85 list_matches
86 else
87 @match_window.find key
88 end
89 end
90
91 def backspace
92 if @focus == @prompt
93 @prompt.backspace!
94 list_matches
95 end
96 end
97
98 def delete
99 if @focus == @prompt
100 @prompt.delete!
101 list_matches
102 end
103 end
104
105 def accept_selection options = {}
106 selection = @match_window.selection
107 hide
108 open_selection(selection, options) unless selection.nil?
109 end
110
111 def toggle_focus
112 @focus.unfocus # old focus
113 @focus = @focus == @prompt ? @match_window : @prompt
114 @focus.focus # new focus
115 end
116
117 def cancel
118 hide
119 end
120
121 def select_next
122 @match_window.select_next
123 end
124
125 def select_prev
126 @match_window.select_prev
127 end
128
129 def clear
130 @prompt.clear!
131 list_matches
132 end
133
134 def cursor_left
135 @prompt.cursor_left if @focus == @prompt
136 end
137
138 def cursor_right
139 @prompt.cursor_right if @focus == @prompt
140 end
141
142 def cursor_end
143 @prompt.cursor_end if @focus == @prompt
144 end
145
146 def cursor_start
147 @prompt.cursor_start if @focus == @prompt
148 end
149
150 def leave
151 @match_window.leave
152 end
153
154 def unload
155 @match_window.unload
156 end
157
158 private
159
160 def show
161 @initial_window = $curwin
162 @initial_buffer = $curbuf
163 @match_window = MatchWindow.new \
164 :prompt => @prompt,
165 :match_window_at_top => get_bool('g:CommandTMatchWindowAtTop'),
166 :match_window_reverse => get_bool('g:CommandTMatchWindowReverse')
167 @focus = @prompt
168 @prompt.focus
169 register_for_key_presses
170 clear # clears prompt and lists matches
171 end
172
173 def set_up_max_height
174 @max_height = get_number('g:CommandTMaxHeight') || 0
175 end
176
177 def set_up_file_finder
178 @file_finder = CommandT::FileFinder.new nil,
179 :max_files => get_number('g:CommandTMaxFiles'),
180 :max_depth => get_number('g:CommandTMaxDepth'),
181 :always_show_dot_files => get_bool('g:CommandTAlwaysShowDotFiles'),
182 :never_show_dot_files => get_bool('g:CommandTNeverShowDotFiles'),
183 :scan_dot_directories => get_bool('g:CommandTScanDotDirectories')
184 end
185
186 def exists? name
187 ::VIM::evaluate("exists(\"#{name}\")").to_i != 0
188 end
189
190 def get_number name
191 exists?(name) ? ::VIM::evaluate("#{name}").to_i : nil
192 end
193
194 def get_bool name
195 exists?(name) ? ::VIM::evaluate("#{name}").to_i != 0 : nil
196 end
197
198 def get_string name
199 exists?(name) ? ::VIM::evaluate("#{name}").to_s : nil
200 end
201
202 # expect a string or a list of strings
203 def get_list_or_string name
204 return nil unless exists?(name)
205 list_or_string = ::VIM::evaluate("#{name}")
206 if list_or_string.kind_of?(Array)
207 list_or_string.map { |item| item.to_s }
208 else
209 list_or_string.to_s
210 end
211 end
212
213 # Backslash-escape space, \, |, %, #, "
214 def sanitize_path_string str
215 # for details on escaping command-line mode arguments see: :h :
216 # (that is, help on ":") in the Vim documentation.
217 str.gsub(/[ \\|%#"]/, '\\\\\0')
218 end
219
220 def default_open_command
221 if !get_bool('&hidden') && get_bool('&modified')
222 'sp'
223 else
224 'e'
225 end
226 end
227
228 def ensure_appropriate_window_selection
229 # normally we try to open the selection in the current window, but there
230 # is one exception:
231 #
232 # - we don't touch any "unlisted" buffer with buftype "nofile" (such as
233 # NERDTree or MiniBufExplorer); this is to avoid things like the "Not
234 # enough room" error which occurs when trying to open in a split in a
235 # shallow (potentially 1-line) buffer like MiniBufExplorer is current
236 #
237 # Other "unlisted" buffers, such as those with buftype "help" are treated
238 # normally.
239 initial = $curwin
240 while true do
241 break unless ::VIM::evaluate('&buflisted').to_i == 0 &&
242 ::VIM::evaluate('&buftype').to_s == 'nofile'
243 ::VIM::command 'wincmd w' # try next window
244 break if $curwin == initial # have already tried all
245 end
246 end
247
248 def open_selection selection, options = {}
249 command = options[:command] || default_open_command
250 selection = File.expand_path selection, @path
251 selection = relative_path_under_working_directory selection
252 selection = sanitize_path_string selection
253 ensure_appropriate_window_selection
254 ::VIM::command "silent #{command} #{selection}"
255 end
256
257 def map key, function, param = nil
258 ::VIM::command "noremap <silent> <buffer> #{key} " \
259 ":call CommandT#{function}(#{param})<CR>"
260 end
261
262 def xterm?
263 !!(::VIM::evaluate('&term') =~ /\Axterm/)
264 end
265
266 def vt100?
267 !!(::VIM::evaluate('&term') =~ /\Avt100/)
268 end
269
270 def register_for_key_presses
271 # "normal" keys (interpreted literally)
272 numbers = ('0'..'9').to_a.join
273 lowercase = ('a'..'z').to_a.join
274 uppercase = lowercase.upcase
275 punctuation = '<>`@#~!"$%&/()=+*-_.,;:?\\\'{}[] ' # and space
276 (numbers + lowercase + uppercase + punctuation).each_byte do |b|
277 map "<Char-#{b}>", 'HandleKey', b
278 end
279
280 # "special" keys (overridable by settings)
281 { 'Backspace' => '<BS>',
282 'Delete' => '<Del>',
283 'AcceptSelection' => '<CR>',
284 'AcceptSelectionSplit' => ['<C-CR>', '<C-s>'],
285 'AcceptSelectionTab' => '<C-t>',
286 'AcceptSelectionVSplit' => '<C-v>',
287 'ToggleFocus' => '<Tab>',
288 'Cancel' => ['<C-c>', '<Esc>'],
289 'SelectNext' => ['<C-n>', '<C-j>', '<Down>'],
290 'SelectPrev' => ['<C-p>', '<C-k>', '<Up>'],
291 'Clear' => '<C-u>',
292 'CursorLeft' => ['<Left>', '<C-h>'],
293 'CursorRight' => ['<Right>', '<C-l>'],
294 'CursorEnd' => '<C-e>',
295 'CursorStart' => '<C-a>' }.each do |key, value|
296 if override = get_list_or_string("g:CommandT#{key}Map")
297 [override].flatten.each do |mapping|
298 map mapping, key
299 end
300 else
301 [value].flatten.each do |mapping|
302 map mapping, key unless mapping == '<Esc>' && (xterm? || vt100?)
303 end
304 end
305 end
306 end
307
308 # Returns the desired maximum number of matches, based on available
309 # vertical space and the g:CommandTMaxHeight option.
310 def match_limit
311 limit = VIM::Screen.lines - 5
312 limit = 1 if limit < 0
313 limit = [limit, @max_height].min if @max_height > 0
314 limit
315 end
316
317 def list_matches
318 matches = @active_finder.sorted_matches_for @prompt.abbrev, :limit => match_limit
319 @match_window.matches = matches
320 end
321 end # class Controller
322 end # module commandT
323 ruby/command-t/extconf.rb [[[1
324 32
325 # Copyright 2010 Wincent Colaiuta. All rights reserved.
326 #
327 # Redistribution and use in source and binary forms, with or without
328 # modification, are permitted provided that the following conditions are met:
329 #
330 # 1. Redistributions of source code must retain the above copyright notice,
331 # this list of conditions and the following disclaimer.
332 # 2. Redistributions in binary form must reproduce the above copyright notice,
333 # this list of conditions and the following disclaimer in the documentation
334 # and/or other materials provided with the distribution.
335 #
336 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
337 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
338 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
339 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
340 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
341 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
342 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
343 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
344 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
345 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
346 # POSSIBILITY OF SUCH DAMAGE.
347
348 require 'mkmf'
349
350 def missing item
351 puts "couldn't find #{item} (required)"
352 exit 1
353 end
354
355 have_header('ruby.h') or missing('ruby.h')
356 create_makefile('ext')
357 ruby/command-t/finder/buffer_finder.rb [[[1
358 35
359 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
360 #
361 # Redistribution and use in source and binary forms, with or without
362 # modification, are permitted provided that the following conditions are met:
363 #
364 # 1. Redistributions of source code must retain the above copyright notice,
365 # this list of conditions and the following disclaimer.
366 # 2. Redistributions in binary form must reproduce the above copyright notice,
367 # this list of conditions and the following disclaimer in the documentation
368 # and/or other materials provided with the distribution.
369 #
370 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
371 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
372 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
373 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
374 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
375 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
376 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
377 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
378 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
379 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
380 # POSSIBILITY OF SUCH DAMAGE.
381
382 require 'command-t/ext' # CommandT::Matcher
383 require 'command-t/scanner/buffer_scanner'
384 require 'command-t/finder'
385
386 module CommandT
387 class BufferFinder < Finder
388 def initialize
389 @scanner = BufferScanner.new
390 @matcher = Matcher.new @scanner, :always_show_dot_files => true
391 end
392 end # class BufferFinder
393 end # CommandT
394 ruby/command-t/finder/file_finder.rb [[[1
395 35
396 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
397 #
398 # Redistribution and use in source and binary forms, with or without
399 # modification, are permitted provided that the following conditions are met:
400 #
401 # 1. Redistributions of source code must retain the above copyright notice,
402 # this list of conditions and the following disclaimer.
403 # 2. Redistributions in binary form must reproduce the above copyright notice,
404 # this list of conditions and the following disclaimer in the documentation
405 # and/or other materials provided with the distribution.
406 #
407 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
408 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
409 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
410 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
411 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
412 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
413 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
414 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
415 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
416 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
417 # POSSIBILITY OF SUCH DAMAGE.
418
419 require 'command-t/ext' # CommandT::Matcher
420 require 'command-t/finder'
421 require 'command-t/scanner/file_scanner'
422
423 module CommandT
424 class FileFinder < Finder
425 def initialize path = Dir.pwd, options = {}
426 @scanner = FileScanner.new path, options
427 @matcher = Matcher.new @scanner, options
428 end
429 end # class FileFinder
430 end # CommandT
431 ruby/command-t/finder.rb [[[1
432 52
433 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
434 #
435 # Redistribution and use in source and binary forms, with or without
436 # modification, are permitted provided that the following conditions are met:
437 #
438 # 1. Redistributions of source code must retain the above copyright notice,
439 # this list of conditions and the following disclaimer.
440 # 2. Redistributions in binary form must reproduce the above copyright notice,
441 # this list of conditions and the following disclaimer in the documentation
442 # and/or other materials provided with the distribution.
443 #
444 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
445 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
446 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
447 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
448 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
449 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
450 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
451 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
452 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
453 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
454 # POSSIBILITY OF SUCH DAMAGE.
455
456 require 'command-t/ext' # CommandT::Matcher
457
458 module CommandT
459 # Encapsulates a Scanner instance (which builds up a list of available files
460 # in a directory) and a Matcher instance (which selects from that list based
461 # on a search string).
462 #
463 # Specialized subclasses use different kinds of scanners adapted for
464 # different kinds of search (files, buffers).
465 class Finder
466 def initialize path = Dir.pwd, options = {}
467 raise RuntimeError, 'Subclass responsibility'
468 end
469
470 # Options:
471 # :limit (integer): limit the number of returned matches
472 def sorted_matches_for str, options = {}
473 @matcher.sorted_matches_for str, options
474 end
475
476 def flush
477 @scanner.flush
478 end
479
480 def path= path
481 @scanner.path = path
482 end
483 end # class Finder
484 end # CommandT
485 ruby/command-t/match_window.rb [[[1
486 387
487 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
488 #
489 # Redistribution and use in source and binary forms, with or without
490 # modification, are permitted provided that the following conditions are met:
491 #
492 # 1. Redistributions of source code must retain the above copyright notice,
493 # this list of conditions and the following disclaimer.
494 # 2. Redistributions in binary form must reproduce the above copyright notice,
495 # this list of conditions and the following disclaimer in the documentation
496 # and/or other materials provided with the distribution.
497 #
498 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
499 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
500 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
501 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
502 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
503 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
504 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
505 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
506 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
507 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
508 # POSSIBILITY OF SUCH DAMAGE.
509
510 require 'ostruct'
511 require 'command-t/settings'
512
513 module CommandT
514 class MatchWindow
515 @@selection_marker = '> '
516 @@marker_length = @@selection_marker.length
517 @@unselected_marker = ' ' * @@marker_length
518 @@buffer = nil
519
520 def initialize options = {}
521 @prompt = options[:prompt]
522 @reverse_list = options[:match_window_reverse]
523
524 # save existing window dimensions so we can restore them later
525 @windows = []
526 (0..(::VIM::Window.count - 1)).each do |i|
527 window = OpenStruct.new :index => i, :height => ::VIM::Window[i].height
528 @windows << window
529 end
530
531 # global settings (must manually save and restore)
532 @settings = Settings.new
533 ::VIM::set_option 'timeout' # ensure mappings timeout
534 ::VIM::set_option 'timeoutlen=0' # respond immediately to mappings
535 ::VIM::set_option 'nohlsearch' # don't highlight search strings
536 ::VIM::set_option 'noinsertmode' # don't make Insert mode the default
537 ::VIM::set_option 'noshowcmd' # don't show command info on last line
538 ::VIM::set_option 'report=9999' # don't show "X lines changed" reports
539 ::VIM::set_option 'sidescroll=0' # don't sidescroll in jumps
540 ::VIM::set_option 'sidescrolloff=0' # don't sidescroll automatically
541 ::VIM::set_option 'noequalalways' # don't auto-balance window sizes
542
543 # show match window
544 split_location = options[:match_window_at_top] ? 'topleft' : 'botright'
545 if @@buffer # still have buffer from last time
546 ::VIM::command "silent! #{split_location} #{@@buffer.number}sbuffer"
547 raise "Can't re-open GoToFile buffer" unless $curbuf.number == @@buffer.number
548 $curwin.height = 1
549 else # creating match window for first time and set it up
550 split_command = "silent! #{split_location} 1split GoToFile"
551 [
552 split_command,
553 'setlocal bufhidden=unload', # unload buf when no longer displayed
554 'setlocal buftype=nofile', # buffer is not related to any file
555 'setlocal nomodifiable', # prevent manual edits
556 'setlocal noswapfile', # don't create a swapfile
557 'setlocal nowrap', # don't soft-wrap
558 'setlocal nonumber', # don't show line numbers
559 'setlocal nolist', # don't use List mode (visible tabs etc)
560 'setlocal foldcolumn=0', # don't show a fold column at side
561 'setlocal foldlevel=99', # don't fold anything
562 'setlocal nocursorline', # don't highlight line cursor is on
563 'setlocal nospell', # spell-checking off
564 'setlocal nobuflisted', # don't show up in the buffer list
565 'setlocal textwidth=0' # don't hard-wrap (break long lines)
566 ].each { |command| ::VIM::command command }
567
568 # sanity check: make sure the buffer really was created
569 raise "Can't find GoToFile buffer" unless $curbuf.name.match /GoToFile\z/
570 @@buffer = $curbuf
571 end
572
573 # syntax coloring
574 if VIM::has_syntax?
575 ::VIM::command "syntax match CommandTSelection \"^#{@@selection_marker}.\\+$\""
576 ::VIM::command 'syntax match CommandTNoEntries "^-- NO MATCHES --$"'
577 ::VIM::command 'syntax match CommandTNoEntries "^-- NO SUCH FILE OR DIRECTORY --$"'
578 ::VIM::command 'highlight link CommandTSelection Visual'
579 ::VIM::command 'highlight link CommandTNoEntries Error'
580 ::VIM::evaluate 'clearmatches()'
581
582 # hide cursor
583 @cursor_highlight = get_cursor_highlight
584 hide_cursor
585 end
586
587 # perform cleanup using an autocmd to ensure we don't get caught out
588 # by some unexpected means of dismissing or leaving the Command-T window
589 # (eg. <C-W q>, <C-W k> etc)
590 ::VIM::command 'autocmd! * <buffer>'
591 ::VIM::command 'autocmd BufLeave <buffer> ruby $command_t.leave'
592 ::VIM::command 'autocmd BufUnload <buffer> ruby $command_t.unload'
593
594 @has_focus = false
595 @selection = nil
596 @abbrev = ''
597 @window = $curwin
598 end
599
600 def close
601 # Workaround for upstream bug in Vim 7.3 on some platforms
602 #
603 # On some platforms, $curbuf.number always returns 0. One workaround is
604 # to build Vim with --disable-largefile, but as this is producing lots of
605 # support requests, implement the following fallback to the buffer name
606 # instead, at least until upstream gets fixed.
607 #
608 # For more details, see: https://wincent.com/issues/1617
609 if $curbuf.number == 0
610 # use bwipeout as bunload fails if passed the name of a hidden buffer
611 ::VIM::command 'bwipeout! GoToFile'
612 @@buffer = nil
613 else
614 ::VIM::command "bunload! #{@@buffer.number}"
615 end
616 end
617
618 def leave
619 close
620 unload
621 end
622
623 def unload
624 restore_window_dimensions
625 @settings.restore
626 @prompt.dispose
627 show_cursor
628 end
629
630 def add! char
631 @abbrev += char
632 end
633
634 def backspace!
635 @abbrev.chop!
636 end
637
638 def select_next
639 if @selection < @matches.length - 1
640 @selection += 1
641 print_match(@selection - 1) # redraw old selection (removes marker)
642 print_match(@selection) # redraw new selection (adds marker)
643 move_cursor_to_selected_line
644 else
645 # (possibly) loop or scroll
646 end
647 end
648
649 def select_prev
650 if @selection > 0
651 @selection -= 1
652 print_match(@selection + 1) # redraw old selection (removes marker)
653 print_match(@selection) # redraw new selection (adds marker)
654 move_cursor_to_selected_line
655 else
656 # (possibly) loop or scroll
657 end
658 end
659
660 def matches= matches
661 matches = matches.reverse if @reverse_list
662 if matches != @matches
663 @matches = matches
664 @selection = @reverse_list ? @matches.length - 1 : 0
665 print_matches
666 move_cursor_to_selected_line
667 end
668 end
669
670 def focus
671 unless @has_focus
672 @has_focus = true
673 if VIM::has_syntax?
674 ::VIM::command 'highlight link CommandTSelection Search'
675 end
676 end
677 end
678
679 def unfocus
680 if @has_focus
681 @has_focus = false
682 if VIM::has_syntax?
683 ::VIM::command 'highlight link CommandTSelection Visual'
684 end
685 end
686 end
687
688 def find char
689 # is this a new search or the continuation of a previous one?
690 now = Time.now
691 if @last_key_time.nil? or @last_key_time < (now - 0.5)
692 @find_string = char
693 else
694 @find_string += char
695 end
696 @last_key_time = now
697
698 # see if there's anything up ahead that matches
699 @matches.each_with_index do |match, idx|
700 if match[0, @find_string.length].casecmp(@find_string) == 0
701 old_selection = @selection
702 @selection = idx
703 print_match(old_selection) # redraw old selection (removes marker)
704 print_match(@selection) # redraw new selection (adds marker)
705 break
706 end
707 end
708 end
709
710 # Returns the currently selected item as a String.
711 def selection
712 @matches[@selection]
713 end
714
715 def print_no_such_file_or_directory
716 print_error 'NO SUCH FILE OR DIRECTORY'
717 end
718
719 private
720
721 def move_cursor_to_selected_line
722 # on some non-GUI terminals, the cursor doesn't hide properly
723 # so we move the cursor to prevent it from blinking away in the
724 # upper-left corner in a distracting fashion
725 @window.cursor = [@selection + 1, 0]
726 end
727
728 def print_error msg
729 return unless VIM::Window.select(@window)
730 unlock
731 clear
732 @window.height = 1
733 @@buffer[1] = "-- #{msg} --"
734 lock
735 end
736
737 def restore_window_dimensions
738 # sort from tallest to shortest
739 @windows.sort! { |a, b| b.height <=> a.height }
740
741 # starting with the tallest ensures that there are no constraints
742 # preventing windows on the side of vertical splits from regaining
743 # their original full size
744 @windows.each do |w|
745 # beware: window may be nil
746 window = ::VIM::Window[w.index]
747 window.height = w.height if window
748 end
749 end
750
751 def match_text_for_idx idx
752 match = truncated_match @matches[idx]
753 if idx == @selection
754 prefix = @@selection_marker
755 suffix = padding_for_selected_match match
756 else
757 prefix = @@unselected_marker
758 suffix = ''
759 end
760 prefix + match + suffix
761 end
762
763 # Print just the specified match.
764 def print_match idx
765 return unless VIM::Window.select(@window)
766 unlock
767 @@buffer[idx + 1] = match_text_for_idx idx
768 lock
769 end
770
771 # Print all matches.
772 def print_matches
773 match_count = @matches.length
774 if match_count == 0
775 print_error 'NO MATCHES'
776 else
777 return unless VIM::Window.select(@window)
778 unlock
779 clear
780 actual_lines = 1
781 @window_width = @window.width # update cached value
782 max_lines = VIM::Screen.lines - 5
783 max_lines = 1 if max_lines < 0
784 actual_lines = match_count > max_lines ? max_lines : match_count
785 @window.height = actual_lines
786 (1..actual_lines).each do |line|
787 idx = line - 1
788 if @@buffer.count >= line
789 @@buffer[line] = match_text_for_idx idx
790 else
791 @@buffer.append line - 1, match_text_for_idx(idx)
792 end
793 end
794 lock
795 end
796 end
797
798 # Prepare padding for match text (trailing spaces) so that selection
799 # highlighting extends all the way to the right edge of the window.
800 def padding_for_selected_match str
801 len = str.length
802 if len >= @window_width - @@marker_length
803 ''
804 else
805 ' ' * (@window_width - @@marker_length - len)
806 end
807 end
808
809 # Convert "really/long/path" into "really...path" based on available
810 # window width.
811 def truncated_match str
812 len = str.length
813 available_width = @window_width - @@marker_length
814 return str if len <= available_width
815 left = (available_width / 2) - 1
816 right = (available_width / 2) - 2 + (available_width % 2)
817 str[0, left] + '...' + str[-right, right]
818 end
819
820 def clear
821 # range = % (whole buffer)
822 # action = d (delete)
823 # register = _ (black hole register, don't record deleted text)
824 ::VIM::command 'silent %d _'
825 end
826
827 def get_cursor_highlight
828 # as :highlight returns nothing and only prints,
829 # must redirect its output to a variable
830 ::VIM::command 'silent redir => g:command_t_cursor_highlight'
831
832 # force 0 verbosity to ensure origin information isn't printed as well
833 ::VIM::command 'silent! 0verbose highlight Cursor'
834 ::VIM::command 'silent redir END'
835
836 # there are 3 possible formats to check for, each needing to be
837 # transformed in a certain way in order to reapply the highlight:
838 # Cursor xxx guifg=bg guibg=fg -> :hi! Cursor guifg=bg guibg=fg
839 # Cursor xxx links to SomethingElse -> :hi! link Cursor SomethingElse
840 # Cursor xxx cleared -> :hi! clear Cursor
841 highlight = ::VIM::evaluate 'g:command_t_cursor_highlight'
842 if highlight =~ /^Cursor\s+xxx\s+links to (\w+)/
843 "link Cursor #{$~[1]}"
844 elsif highlight =~ /^Cursor\s+xxx\s+cleared/
845 'clear Cursor'
846 elsif highlight =~ /Cursor\s+xxx\s+(.+)/
847 "Cursor #{$~[1]}"
848 else # likely cause E411 Cursor highlight group not found
849 nil
850 end
851 end
852
853 def hide_cursor
854 if @cursor_highlight
855 ::VIM::command 'highlight Cursor NONE'
856 end
857 end
858
859 def show_cursor
860 if @cursor_highlight
861 ::VIM::command "highlight #{@cursor_highlight}"
862 end
863 end
864
865 def lock
866 ::VIM::command 'setlocal nomodifiable'
867 end
868
869 def unlock
870 ::VIM::command 'setlocal modifiable'
871 end
872 end
873 end
874 ruby/command-t/prompt.rb [[[1
875 165
876 # Copyright 2010 Wincent Colaiuta. All rights reserved.
877 #
878 # Redistribution and use in source and binary forms, with or without
879 # modification, are permitted provided that the following conditions are met:
880 #
881 # 1. Redistributions of source code must retain the above copyright notice,
882 # this list of conditions and the following disclaimer.
883 # 2. Redistributions in binary form must reproduce the above copyright notice,
884 # this list of conditions and the following disclaimer in the documentation
885 # and/or other materials provided with the distribution.
886 #
887 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
888 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
889 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
890 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
891 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
892 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
893 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
894 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
895 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
896 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
897 # POSSIBILITY OF SUCH DAMAGE.
898
899 module CommandT
900 # Abuse the status line as a prompt.
901 class Prompt
902 attr_accessor :abbrev
903
904 def initialize
905 @abbrev = '' # abbreviation entered so far
906 @col = 0 # cursor position
907 @has_focus = false
908 end
909
910 # Erase whatever is displayed in the prompt line,
911 # effectively disposing of the prompt
912 def dispose
913 ::VIM::command 'echo'
914 ::VIM::command 'redraw'
915 end
916
917 # Clear any entered text.
918 def clear!
919 @abbrev = ''
920 @col = 0
921 redraw
922 end
923
924 # Insert a character at (before) the current cursor position.
925 def add! char
926 left, cursor, right = abbrev_segments
927 @abbrev = left + char + cursor + right
928 @col += 1
929 redraw
930 end
931
932 # Delete a character to the left of the current cursor position.
933 def backspace!
934 if @col > 0
935 left, cursor, right = abbrev_segments
936 @abbrev = left.chop! + cursor + right
937 @col -= 1
938 redraw
939 end
940 end
941
942 # Delete a character at the current cursor position.
943 def delete!
944 if @col < @abbrev.length
945 left, cursor, right = abbrev_segments
946 @abbrev = left + right
947 redraw
948 end
949 end
950
951 def cursor_left
952 if @col > 0
953 @col -= 1
954 redraw
955 end
956 end
957
958 def cursor_right
959 if @col < @abbrev.length
960 @col += 1
961 redraw
962 end
963 end
964
965 def cursor_end
966 if @col < @abbrev.length
967 @col = @abbrev.length
968 redraw
969 end
970 end
971
972 def cursor_start
973 if @col != 0
974 @col = 0
975 redraw
976 end
977 end
978
979 def redraw
980 if @has_focus
981 prompt_highlight = 'Comment'
982 normal_highlight = 'None'
983 cursor_highlight = 'Underlined'
984 else
985 prompt_highlight = 'NonText'
986 normal_highlight = 'NonText'
987 cursor_highlight = 'NonText'
988 end
989 left, cursor, right = abbrev_segments
990 components = [prompt_highlight, '>>', 'None', ' ']
991 components += [normal_highlight, left] unless left.empty?
992 components += [cursor_highlight, cursor] unless cursor.empty?
993 components += [normal_highlight, right] unless right.empty?
994 components += [cursor_highlight, ' '] if cursor.empty?
995 set_status *components
996 end
997
998 def focus
999 unless @has_focus
1000 @has_focus = true
1001 redraw
1002 end
1003 end
1004
1005 def unfocus
1006 if @has_focus
1007 @has_focus = false
1008 redraw
1009 end
1010 end
1011
1012 private
1013
1014 # Returns the @abbrev string divided up into three sections, any of
1015 # which may actually be zero width, depending on the location of the
1016 # cursor:
1017 # - left segment (to left of cursor)
1018 # - cursor segment (character at cursor)
1019 # - right segment (to right of cursor)
1020 def abbrev_segments
1021 left = @abbrev[0, @col]
1022 cursor = @abbrev[@col, 1]
1023 right = @abbrev[(@col + 1)..-1] || ''
1024 [left, cursor, right]
1025 end
1026
1027 def set_status *args
1028 # see ':help :echo' for why forcing a redraw here helps
1029 # prevent the status line from getting inadvertantly cleared
1030 # after our echo commands
1031 ::VIM::command 'redraw'
1032 while (highlight = args.shift) and (text = args.shift) do
1033 text = VIM::escape_for_single_quotes text
1034 ::VIM::command "echohl #{highlight}"
1035 ::VIM::command "echon '#{text}'"
1036 end
1037 ::VIM::command 'echohl None'
1038 end
1039 end # class Prompt
1040 end # module CommandT
1041 ruby/command-t/scanner/buffer_scanner.rb [[[1
1042 42
1043 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
1044 #
1045 # Redistribution and use in source and binary forms, with or without
1046 # modification, are permitted provided that the following conditions are met:
1047 #
1048 # 1. Redistributions of source code must retain the above copyright notice,
1049 # this list of conditions and the following disclaimer.
1050 # 2. Redistributions in binary form must reproduce the above copyright notice,
1051 # this list of conditions and the following disclaimer in the documentation
1052 # and/or other materials provided with the distribution.
1053 #
1054 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1055 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1056 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1057 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1058 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1059 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1060 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1061 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1062 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1063 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1064 # POSSIBILITY OF SUCH DAMAGE.
1065
1066 require 'command-t/vim'
1067 require 'command-t/vim/path_utilities'
1068 require 'command-t/scanner'
1069
1070 module CommandT
1071 # Returns a list of all open buffers.
1072 class BufferScanner < Scanner
1073 include VIM::PathUtilities
1074
1075 def paths
1076 (0..(::VIM::Buffer.count - 1)).map do |n|
1077 buffer = ::VIM::Buffer[n]
1078 if buffer.name # beware, may be nil
1079 relative_path_under_working_directory buffer.name
1080 end
1081 end.compact
1082 end
1083 end # class BufferScanner
1084 end # module CommandT
1085 ruby/command-t/scanner/file_scanner.rb [[[1
1086 94
1087 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
1088 #
1089 # Redistribution and use in source and binary forms, with or without
1090 # modification, are permitted provided that the following conditions are met:
1091 #
1092 # 1. Redistributions of source code must retain the above copyright notice,
1093 # this list of conditions and the following disclaimer.
1094 # 2. Redistributions in binary form must reproduce the above copyright notice,
1095 # this list of conditions and the following disclaimer in the documentation
1096 # and/or other materials provided with the distribution.
1097 #
1098 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1099 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1100 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1101 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1102 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1103 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1104 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1105 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1106 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1107 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1108 # POSSIBILITY OF SUCH DAMAGE.
1109
1110 require 'command-t/vim'
1111 require 'command-t/scanner'
1112
1113 module CommandT
1114 # Reads the current directory recursively for the paths to all regular files.
1115 class FileScanner < Scanner
1116 class FileLimitExceeded < ::RuntimeError; end
1117
1118 def initialize path = Dir.pwd, options = {}
1119 @path = path
1120 @max_depth = options[:max_depth] || 15
1121 @max_files = options[:max_files] || 10_000
1122 @scan_dot_directories = options[:scan_dot_directories] || false
1123 end
1124
1125 def paths
1126 return @paths unless @paths.nil?
1127 begin
1128 @paths = []
1129 @depth = 0
1130 @files = 0
1131 @prefix_len = @path.chomp('/').length
1132 add_paths_for_directory @path, @paths
1133 rescue FileLimitExceeded
1134 end
1135 @paths
1136 end
1137
1138 def flush
1139 @paths = nil
1140 end
1141
1142 def path= str
1143 if @path != str
1144 @path = str
1145 flush
1146 end
1147 end
1148
1149 private
1150
1151 def path_excluded? path
1152 # first strip common prefix (@path) from path to match VIM's behavior
1153 path = path[(@prefix_len + 1)..-1]
1154 path = VIM::escape_for_single_quotes path
1155 ::VIM::evaluate("empty(expand(fnameescape('#{path}')))").to_i == 1
1156 end
1157
1158 def add_paths_for_directory dir, accumulator
1159 Dir.foreach(dir) do |entry|
1160 next if ['.', '..'].include?(entry)
1161 path = File.join(dir, entry)
1162 unless path_excluded?(path)
1163 if File.file?(path)
1164 @files += 1
1165 raise FileLimitExceeded if @files > @max_files
1166 accumulator << path[@prefix_len + 1..-1]
1167 elsif File.directory?(path)
1168 next if @depth >= @max_depth
1169 next if (entry.match(/\A\./) && !@scan_dot_directories)
1170 @depth += 1
1171 add_paths_for_directory path, accumulator
1172 @depth -= 1
1173 end
1174 end
1175 end
1176 rescue Errno::EACCES
1177 # skip over directories for which we don't have access
1178 end
1179 end # class FileScanner
1180 end # module CommandT
1181 ruby/command-t/scanner.rb [[[1
1182 28
1183 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
1184 #
1185 # Redistribution and use in source and binary forms, with or without
1186 # modification, are permitted provided that the following conditions are met:
1187 #
1188 # 1. Redistributions of source code must retain the above copyright notice,
1189 # this list of conditions and the following disclaimer.
1190 # 2. Redistributions in binary form must reproduce the above copyright notice,
1191 # this list of conditions and the following disclaimer in the documentation
1192 # and/or other materials provided with the distribution.
1193 #
1194 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1195 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1196 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1197 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1198 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1199 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1200 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1201 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1202 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1203 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1204 # POSSIBILITY OF SUCH DAMAGE.
1205
1206 require 'command-t/vim'
1207
1208 module CommandT
1209 class Scanner; end
1210 end # module CommandT
1211 ruby/command-t/settings.rb [[[1
1212 77
1213 # Copyright 2010 Wincent Colaiuta. All rights reserved.
1214 #
1215 # Redistribution and use in source and binary forms, with or without
1216 # modification, are permitted provided that the following conditions are met:
1217 #
1218 # 1. Redistributions of source code must retain the above copyright notice,
1219 # this list of conditions and the following disclaimer.
1220 # 2. Redistributions in binary form must reproduce the above copyright notice,
1221 # this list of conditions and the following disclaimer in the documentation
1222 # and/or other materials provided with the distribution.
1223 #
1224 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1225 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1226 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1227 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1228 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1229 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1230 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1231 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1232 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1233 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1234 # POSSIBILITY OF SUCH DAMAGE.
1235
1236 module CommandT
1237 # Convenience class for saving and restoring global settings.
1238 class Settings
1239 def initialize
1240 save
1241 end
1242
1243 def save
1244 @timeoutlen = get_number 'timeoutlen'
1245 @report = get_number 'report'
1246 @sidescroll = get_number 'sidescroll'
1247 @sidescrolloff = get_number 'sidescrolloff'
1248 @timeout = get_bool 'timeout'
1249 @equalalways = get_bool 'equalalways'
1250 @hlsearch = get_bool 'hlsearch'
1251 @insertmode = get_bool 'insertmode'
1252 @showcmd = get_bool 'showcmd'
1253 end
1254
1255 def restore
1256 set_number 'timeoutlen', @timeoutlen
1257 set_number 'report', @report
1258 set_number 'sidescroll', @sidescroll
1259 set_number 'sidescrolloff', @sidescrolloff
1260 set_bool 'timeout', @timeout
1261 set_bool 'equalalways', @equalalways
1262 set_bool 'hlsearch', @hlsearch
1263 set_bool 'insertmode', @insertmode
1264 set_bool 'showcmd', @showcmd
1265 end
1266
1267 private
1268
1269 def get_number setting
1270 ::VIM::evaluate("&#{setting}").to_i
1271 end
1272
1273 def get_bool setting
1274 ::VIM::evaluate("&#{setting}").to_i == 1
1275 end
1276
1277 def set_number setting, value
1278 ::VIM::set_option "#{setting}=#{value}"
1279 end
1280
1281 def set_bool setting, value
1282 if value
1283 ::VIM::set_option setting
1284 else
1285 ::VIM::set_option "no#{setting}"
1286 end
1287 end
1288 end # class Settings
1289 end # module CommandT
1290 ruby/command-t/stub.rb [[[1
1291 46
1292 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
1293 #
1294 # Redistribution and use in source and binary forms, with or without
1295 # modification, are permitted provided that the following conditions are met:
1296 #
1297 # 1. Redistributions of source code must retain the above copyright notice,
1298 # this list of conditions and the following disclaimer.
1299 # 2. Redistributions in binary form must reproduce the above copyright notice,
1300 # this list of conditions and the following disclaimer in the documentation
1301 # and/or other materials provided with the distribution.
1302 #
1303 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1304 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1305 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1306 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1307 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1308 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1309 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1310 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1311 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1312 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1313 # POSSIBILITY OF SUCH DAMAGE.
1314
1315 module CommandT
1316 class Stub
1317 @@load_error = ['command-t.vim could not load the C extension',
1318 'Please see INSTALLATION and TROUBLE-SHOOTING in the help',
1319 'For more information type: :help command-t']
1320
1321 def show_file_finder
1322 warn *@@load_error
1323 end
1324
1325 def flush
1326 warn *@@load_error
1327 end
1328
1329 private
1330
1331 def warn *msg
1332 ::VIM::command 'echohl WarningMsg'
1333 msg.each { |m| ::VIM::command "echo '#{m}'" }
1334 ::VIM::command 'echohl none'
1335 end
1336 end # class Stub
1337 end # module CommandT
1338 ruby/command-t/vim/path_utilities.rb [[[1
1339 40
1340 # Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
1341 #
1342 # Redistribution and use in source and binary forms, with or without
1343 # modification, are permitted provided that the following conditions are met:
1344 #
1345 # 1. Redistributions of source code must retain the above copyright notice,
1346 # this list of conditions and the following disclaimer.
1347 # 2. Redistributions in binary form must reproduce the above copyright notice,
1348 # this list of conditions and the following disclaimer in the documentation
1349 # and/or other materials provided with the distribution.
1350 #
1351 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1352 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1353 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1354 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1355 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1356 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1357 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1358 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1359 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1360 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1361 # POSSIBILITY OF SUCH DAMAGE.
1362
1363 require 'command-t/vim'
1364
1365 module CommandT
1366 module VIM
1367 module PathUtilities
1368
1369 private
1370
1371 def relative_path_under_working_directory path
1372 # any path under the working directory will be specified as a relative
1373 # path to improve the readability of the buffer list etc
1374 pwd = File.expand_path(VIM::pwd) + '/'
1375 path.index(pwd) == 0 ? path[pwd.length..-1] : path
1376 end
1377 end # module PathUtilities
1378 end # module VIM
1379 end # module CommandT
1380 ruby/command-t/vim/screen.rb [[[1
1381 32
1382 # Copyright 2010 Wincent Colaiuta. All rights reserved.
1383 #
1384 # Redistribution and use in source and binary forms, with or without
1385 # modification, are permitted provided that the following conditions are met:
1386 #
1387 # 1. Redistributions of source code must retain the above copyright notice,
1388 # this list of conditions and the following disclaimer.
1389 # 2. Redistributions in binary form must reproduce the above copyright notice,
1390 # this list of conditions and the following disclaimer in the documentation
1391 # and/or other materials provided with the distribution.
1392 #
1393 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1394 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1395 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1396 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1397 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1398 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1399 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1400 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1401 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1402 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1403 # POSSIBILITY OF SUCH DAMAGE.
1404
1405 module CommandT
1406 module VIM
1407 module Screen
1408 def self.lines
1409 ::VIM::evaluate('&lines').to_i
1410 end
1411 end # module Screen
1412 end # module VIM
1413 end # module CommandT
1414 ruby/command-t/vim/window.rb [[[1
1415 38
1416 # Copyright 2010 Wincent Colaiuta. All rights reserved.
1417 #
1418 # Redistribution and use in source and binary forms, with or without
1419 # modification, are permitted provided that the following conditions are met:
1420 #
1421 # 1. Redistributions of source code must retain the above copyright notice,
1422 # this list of conditions and the following disclaimer.
1423 # 2. Redistributions in binary form must reproduce the above copyright notice,
1424 # this list of conditions and the following disclaimer in the documentation
1425 # and/or other materials provided with the distribution.
1426 #
1427 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1428 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1429 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1430 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1431 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1432 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1433 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1434 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1435 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1436 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1437 # POSSIBILITY OF SUCH DAMAGE.
1438
1439 module CommandT
1440 module VIM
1441 class Window
1442 def self.select window
1443 return true if $curwin == window
1444 initial = $curwin
1445 while true do
1446 ::VIM::command 'wincmd w' # cycle through windows
1447 return true if $curwin == window # have selected desired window
1448 return false if $curwin == initial # have already looped through all
1449 end
1450 end
1451 end # class Window
1452 end # module VIM
1453 end # module CommandT
1454 ruby/command-t/vim.rb [[[1
1455 43
1456 # Copyright 2010 Wincent Colaiuta. All rights reserved.
1457 #
1458 # Redistribution and use in source and binary forms, with or without
1459 # modification, are permitted provided that the following conditions are met:
1460 #
1461 # 1. Redistributions of source code must retain the above copyright notice,
1462 # this list of conditions and the following disclaimer.
1463 # 2. Redistributions in binary form must reproduce the above copyright notice,
1464 # this list of conditions and the following disclaimer in the documentation
1465 # and/or other materials provided with the distribution.
1466 #
1467 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1468 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1469 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1470 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1471 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1472 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1473 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1474 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1475 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1476 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1477 # POSSIBILITY OF SUCH DAMAGE.
1478
1479 require 'command-t/vim/screen'
1480 require 'command-t/vim/window'
1481
1482 module CommandT
1483 module VIM
1484 def self.has_syntax?
1485 ::VIM::evaluate('has("syntax")').to_i != 0
1486 end
1487
1488 def self.pwd
1489 ::VIM::evaluate 'getcwd()'
1490 end
1491
1492 # Escape a string for safe inclusion in a Vim single-quoted string
1493 # (single quotes escaped by doubling, everything else is literal)
1494 def self.escape_for_single_quotes str
1495 str.gsub "'", "''"
1496 end
1497 end # module VIM
1498 end # module CommandT
1499 ruby/command-t/ext.c [[[1
1500 65
1501 // Copyright 2010 Wincent Colaiuta. All rights reserved.
1502 //
1503 // Redistribution and use in source and binary forms, with or without
1504 // modification, are permitted provided that the following conditions are met:
1505 //
1506 // 1. Redistributions of source code must retain the above copyright notice,
1507 // this list of conditions and the following disclaimer.
1508 // 2. Redistributions in binary form must reproduce the above copyright notice,
1509 // this list of conditions and the following disclaimer in the documentation
1510 // and/or other materials provided with the distribution.
1511 //
1512 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1513 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1514 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1515 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1516 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1517 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1518 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1519 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1520 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1521 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1522 // POSSIBILITY OF SUCH DAMAGE.
1523
1524 #include "match.h"
1525 #include "matcher.h"
1526
1527 VALUE mCommandT = 0; // module CommandT
1528 VALUE cCommandTMatch = 0; // class CommandT::Match
1529 VALUE cCommandTMatcher = 0; // class CommandT::Matcher
1530
1531 VALUE CommandT_option_from_hash(const char *option, VALUE hash)
1532 {
1533 if (NIL_P(hash))
1534 return Qnil;
1535 VALUE key = ID2SYM(rb_intern(option));
1536 if (rb_funcall(hash, rb_intern("has_key?"), 1, key) == Qtrue)
1537 return rb_hash_aref(hash, key);
1538 else
1539 return Qnil;
1540 }
1541
1542 void Init_ext()
1543 {
1544 // module CommandT
1545 mCommandT = rb_define_module("CommandT");
1546
1547 // class CommandT::Match
1548 cCommandTMatch = rb_define_class_under(mCommandT, "Match", rb_cObject);
1549
1550 // methods
1551 rb_define_method(cCommandTMatch, "initialize", CommandTMatch_initialize, -1);
1552 rb_define_method(cCommandTMatch, "matches?", CommandTMatch_matches, 0);
1553 rb_define_method(cCommandTMatch, "to_s", CommandTMatch_to_s, 0);
1554
1555 // attributes
1556 rb_define_attr(cCommandTMatch, "score", Qtrue, Qfalse); // reader: true, writer: false
1557
1558 // class CommandT::Matcher
1559 cCommandTMatcher = rb_define_class_under(mCommandT, "Matcher", rb_cObject);
1560
1561 // methods
1562 rb_define_method(cCommandTMatcher, "initialize", CommandTMatcher_initialize, -1);
1563 rb_define_method(cCommandTMatcher, "sorted_matches_for", CommandTMatcher_sorted_matches_for, 2);
1564 rb_define_method(cCommandTMatcher, "matches_for", CommandTMatcher_matches_for, 1);
1565 }
1566 ruby/command-t/match.c [[[1
1567 189
1568 // Copyright 2010 Wincent Colaiuta. All rights reserved.
1569 //
1570 // Redistribution and use in source and binary forms, with or without
1571 // modification, are permitted provided that the following conditions are met:
1572 //
1573 // 1. Redistributions of source code must retain the above copyright notice,
1574 // this list of conditions and the following disclaimer.
1575 // 2. Redistributions in binary form must reproduce the above copyright notice,
1576 // this list of conditions and the following disclaimer in the documentation
1577 // and/or other materials provided with the distribution.
1578 //
1579 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1580 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1581 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1582 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1583 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1584 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1585 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1586 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1587 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1588 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1589 // POSSIBILITY OF SUCH DAMAGE.
1590
1591 #include "match.h"
1592 #include "ext.h"
1593 #include "ruby_compat.h"
1594
1595 // use a struct to make passing params during recursion easier
1596 typedef struct
1597 {
1598 char *str_p; // pointer to string to be searched
1599 long str_len; // length of same
1600 char *abbrev_p; // pointer to search string (abbreviation)
1601 long abbrev_len; // length of same
1602 double max_score_per_char;
1603 int dot_file; // boolean: true if str is a dot-file
1604 int always_show_dot_files; // boolean
1605 int never_show_dot_files; // boolean
1606 } matchinfo_t;
1607
1608 double recursive_match(matchinfo_t *m, // sharable meta-data
1609 long str_idx, // where in the path string to start
1610 long abbrev_idx, // where in the search string to start
1611 long last_idx, // location of last matched character
1612 double score) // cumulative score so far
1613 {
1614 double seen_score = 0; // remember best score seen via recursion
1615 int dot_file_match = 0; // true if abbrev matches a dot-file
1616 int dot_search = 0; // true if searching for a dot
1617
1618 for (long i = abbrev_idx; i < m->abbrev_len; i++)
1619 {
1620 char c = m->abbrev_p[i];
1621 if (c == '.')
1622 dot_search = 1;
1623 int found = 0;
1624 for (long j = str_idx; j < m->str_len; j++, str_idx++)
1625 {
1626 char d = m->str_p[j];
1627 if (d == '.')
1628 {
1629 if (j == 0 || m->str_p[j - 1] == '/')
1630 {
1631 m->dot_file = 1; // this is a dot-file
1632 if (dot_search) // and we are searching for a dot
1633 dot_file_match = 1; // so this must be a match
1634 }
1635 }
1636 else if (d >= 'A' && d <= 'Z')
1637 d += 'a' - 'A'; // add 32 to downcase
1638 if (c == d)
1639 {
1640 found = 1;
1641 dot_search = 0;
1642
1643 // calculate score
1644 double score_for_char = m->max_score_per_char;
1645 long distance = j - last_idx;
1646 if (distance > 1)
1647 {
1648 double factor = 1.0;
1649 char last = m->str_p[j - 1];
1650 char curr = m->str_p[j]; // case matters, so get again
1651 if (last == '/')
1652 factor = 0.9;
1653 else if (last == '-' ||
1654 last == '_' ||
1655 last == ' ' ||
1656 (last >= '0' && last <= '9'))
1657 factor = 0.8;
1658 else if (last >= 'a' && last <= 'z' &&
1659 curr >= 'A' && curr <= 'Z')
1660 factor = 0.8;
1661 else if (last == '.')
1662 factor = 0.7;
1663 else
1664 // if no "special" chars behind char, factor diminishes
1665 // as distance from last matched char increases
1666 factor = (1.0 / distance) * 0.75;
1667 score_for_char *= factor;
1668 }
1669
1670 if (++j < m->str_len)
1671 {
1672 // bump cursor one char to the right and
1673 // use recursion to try and find a better match
1674 double sub_score = recursive_match(m, j, i, last_idx, score);
1675 if (sub_score > seen_score)
1676 seen_score = sub_score;
1677 }
1678
1679 score += score_for_char;
1680 last_idx = str_idx++;
1681 break;
1682 }
1683 }
1684 if (!found)
1685 return 0.0;
1686 }
1687 if (m->dot_file)
1688 {
1689 if (m->never_show_dot_files ||
1690 (!dot_file_match && !m->always_show_dot_files))
1691 return 0.0;
1692 }
1693 return (score > seen_score) ? score : seen_score;
1694 }
1695
1696 // Match.new abbrev, string, options = {}
1697 VALUE CommandTMatch_initialize(int argc, VALUE *argv, VALUE self)
1698 {
1699 // process arguments: 2 mandatory, 1 optional
1700 VALUE str, abbrev, options;
1701 if (rb_scan_args(argc, argv, "21", &str, &abbrev, &options) == 2)
1702 options = Qnil;
1703 str = StringValue(str);
1704 abbrev = StringValue(abbrev); // already downcased by caller
1705
1706 // check optional options hash for overrides
1707 VALUE always_show_dot_files = CommandT_option_from_hash("always_show_dot_files", options);
1708 VALUE never_show_dot_files = CommandT_option_from_hash("never_show_dot_files", options);
1709
1710 matchinfo_t m;
1711 m.str_p = RSTRING_PTR(str);
1712 m.str_len = RSTRING_LEN(str);
1713 m.abbrev_p = RSTRING_PTR(abbrev);
1714 m.abbrev_len = RSTRING_LEN(abbrev);
1715 m.max_score_per_char = (1.0 / m.str_len + 1.0 / m.abbrev_len) / 2;
1716 m.dot_file = 0;
1717 m.always_show_dot_files = always_show_dot_files == Qtrue;
1718 m.never_show_dot_files = never_show_dot_files == Qtrue;
1719
1720 // calculate score
1721 double score = 1.0;
1722 if (m.abbrev_len == 0) // special case for zero-length search string
1723 {
1724 // filter out dot files
1725 if (!m.always_show_dot_files)
1726 {
1727 for (long i = 0; i < m.str_len; i++)
1728 {
1729 char c = m.str_p[i];
1730 if (c == '.' && (i == 0 || m.str_p[i - 1] == '/'))
1731 {
1732 score = 0.0;
1733 break;
1734 }
1735 }
1736 }
1737 }
1738 else // normal case
1739 score = recursive_match(&m, 0, 0, 0, 0.0);
1740
1741 // clean-up and final book-keeping
1742 rb_iv_set(self, "@score", rb_float_new(score));
1743 rb_iv_set(self, "@str", str);
1744 return Qnil;
1745 }
1746
1747 VALUE CommandTMatch_matches(VALUE self)
1748 {
1749 double score = NUM2DBL(rb_iv_get(self, "@score"));
1750 return score > 0 ? Qtrue : Qfalse;
1751 }
1752
1753 VALUE CommandTMatch_to_s(VALUE self)
1754 {
1755 return rb_iv_get(self, "@str");
1756 }
1757 ruby/command-t/matcher.c [[[1
1758 164
1759 // Copyright 2010 Wincent Colaiuta. All rights reserved.
1760 //
1761 // Redistribution and use in source and binary forms, with or without
1762 // modification, are permitted provided that the following conditions are met:
1763 //
1764 // 1. Redistributions of source code must retain the above copyright notice,
1765 // this list of conditions and the following disclaimer.
1766 // 2. Redistributions in binary form must reproduce the above copyright notice,
1767 // this list of conditions and the following disclaimer in the documentation
1768 // and/or other materials provided with the distribution.
1769 //
1770 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1771 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1772 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1773 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1774 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1775 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1776 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1777 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1778 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1779 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1780 // POSSIBILITY OF SUCH DAMAGE.
1781
1782 #include <stdlib.h> /* for qsort() */
1783 #include <string.h> /* for strcmp() */
1784 #include "matcher.h"
1785 #include "ext.h"
1786 #include "ruby_compat.h"
1787
1788 // comparison function for use with qsort
1789 int comp_alpha(const void *a, const void *b)
1790 {
1791 VALUE a_val = *(VALUE *)a;
1792 VALUE b_val = *(VALUE *)b;
1793 ID to_s = rb_intern("to_s");
1794
1795 VALUE a_str = rb_funcall(a_val, to_s, 0);
1796 VALUE b_str = rb_funcall(b_val, to_s, 0);
1797 char *a_p = RSTRING_PTR(a_str);
1798 long a_len = RSTRING_LEN(a_str);
1799 char *b_p = RSTRING_PTR(b_str);
1800 long b_len = RSTRING_LEN(b_str);
1801 int order = 0;
1802 if (a_len > b_len)
1803 {
1804 order = strncmp(a_p, b_p, b_len);
1805 if (order == 0)
1806 order = 1; // shorter string (b) wins
1807 }
1808 else if (a_len < b_len)
1809 {
1810 order = strncmp(a_p, b_p, a_len);
1811 if (order == 0)
1812 order = -1; // shorter string (a) wins
1813 }
1814 else
1815 order = strncmp(a_p, b_p, a_len);
1816 return order;
1817 }
1818
1819 // comparison function for use with qsort
1820 int comp_score(const void *a, const void *b)
1821 {
1822 VALUE a_val = *(VALUE *)a;
1823 VALUE b_val = *(VALUE *)b;
1824 ID score = rb_intern("score");
1825 double a_score = RFLOAT_VALUE(rb_funcall(a_val, score, 0));
1826 double b_score = RFLOAT_VALUE(rb_funcall(b_val, score, 0));
1827 if (a_score > b_score)
1828 return -1; // a scores higher, a should appear sooner
1829 else if (a_score < b_score)
1830 return 1; // b scores higher, a should appear later
1831 else
1832 return comp_alpha(a, b);
1833 }
1834
1835 VALUE CommandTMatcher_initialize(int argc, VALUE *argv, VALUE self)
1836 {
1837 // process arguments: 1 mandatory, 1 optional
1838 VALUE scanner, options;
1839 if (rb_scan_args(argc, argv, "11", &scanner, &options) == 1)
1840 options = Qnil;
1841 if (NIL_P(scanner))
1842 rb_raise(rb_eArgError, "nil scanner");
1843 rb_iv_set(self, "@scanner", scanner);
1844
1845 // check optional options hash for overrides
1846 VALUE always_show_dot_files = CommandT_option_from_hash("always_show_dot_files", options);
1847 if (always_show_dot_files != Qtrue)
1848 always_show_dot_files = Qfalse;
1849 VALUE never_show_dot_files = CommandT_option_from_hash("never_show_dot_files", options);
1850 if (never_show_dot_files != Qtrue)
1851 never_show_dot_files = Qfalse;
1852 rb_iv_set(self, "@always_show_dot_files", always_show_dot_files);
1853 rb_iv_set(self, "@never_show_dot_files", never_show_dot_files);
1854 return Qnil;
1855 }
1856
1857 VALUE CommandTMatcher_sorted_matches_for(VALUE self, VALUE abbrev, VALUE options)
1858 {
1859 // process optional options hash
1860 VALUE limit_option = CommandT_option_from_hash("limit", options);
1861
1862 // get unsorted matches
1863 VALUE matches = CommandTMatcher_matches_for(self, abbrev);
1864
1865 abbrev = StringValue(abbrev);
1866 if (RSTRING_LEN(abbrev) == 0 ||
1867 (RSTRING_LEN(abbrev) == 1 && RSTRING_PTR(abbrev)[0] == '.'))
1868 // alphabetic order if search string is only "" or "."
1869 qsort(RARRAY_PTR(matches), RARRAY_LEN(matches), sizeof(VALUE), comp_alpha);
1870 else
1871 // for all other non-empty search strings, sort by score
1872 qsort(RARRAY_PTR(matches), RARRAY_LEN(matches), sizeof(VALUE), comp_score);
1873
1874 // apply optional limit option
1875 long limit = NIL_P(limit_option) ? 0 : NUM2LONG(limit_option);
1876 if (limit == 0 || RARRAY_LEN(matches) < limit)
1877 limit = RARRAY_LEN(matches);
1878
1879 // will return an array of strings, not an array of Match objects
1880 for (long i = 0; i < limit; i++)
1881 {
1882 VALUE str = rb_funcall(RARRAY_PTR(matches)[i], rb_intern("to_s"), 0);
1883 RARRAY_PTR(matches)[i] = str;
1884 }
1885
1886 // trim off any items beyond the limit
1887 if (limit < RARRAY_LEN(matches))
1888 (void)rb_funcall(matches, rb_intern("slice!"), 2, LONG2NUM(limit),
1889 LONG2NUM(RARRAY_LEN(matches) - limit));
1890 return matches;
1891 }
1892
1893 VALUE CommandTMatcher_matches_for(VALUE self, VALUE abbrev)
1894 {
1895 if (NIL_P(abbrev))
1896 rb_raise(rb_eArgError, "nil abbrev");
1897 VALUE matches = rb_ary_new();
1898 VALUE scanner = rb_iv_get(self, "@scanner");
1899 VALUE always_show_dot_files = rb_iv_get(self, "@always_show_dot_files");
1900 VALUE never_show_dot_files = rb_iv_get(self, "@never_show_dot_files");
1901 VALUE options = Qnil;
1902 if (always_show_dot_files == Qtrue)
1903 {
1904 options = rb_hash_new();
1905 rb_hash_aset(options, ID2SYM(rb_intern("always_show_dot_files")), always_show_dot_files);
1906 }
1907 else if (never_show_dot_files == Qtrue)
1908 {
1909 options = rb_hash_new();
1910 rb_hash_aset(options, ID2SYM(rb_intern("never_show_dot_files")), never_show_dot_files);
1911 }
1912 abbrev = rb_funcall(abbrev, rb_intern("downcase"), 0);
1913 VALUE paths = rb_funcall(scanner, rb_intern("paths"), 0);
1914 for (long i = 0, max = RARRAY_LEN(paths); i < max; i++)
1915 {
1916 VALUE path = RARRAY_PTR(paths)[i];
1917 VALUE match = rb_funcall(cCommandTMatch, rb_intern("new"), 3, path, abbrev, options);
1918 if (rb_funcall(match, rb_intern("matches?"), 0) == Qtrue)
1919 rb_funcall(matches, rb_intern("push"), 1, match);
1920 }
1921 return matches;
1922 }
1923 ruby/command-t/ext.h [[[1
1924 36
1925 // Copyright 2010 Wincent Colaiuta. All rights reserved.
1926 //
1927 // Redistribution and use in source and binary forms, with or without
1928 // modification, are permitted provided that the following conditions are met:
1929 //
1930 // 1. Redistributions of source code must retain the above copyright notice,
1931 // this list of conditions and the following disclaimer.
1932 // 2. Redistributions in binary form must reproduce the above copyright notice,
1933 // this list of conditions and the following disclaimer in the documentation
1934 // and/or other materials provided with the distribution.
1935 //
1936 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1937 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1938 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1939 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1940 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1941 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1942 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1943 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1944 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1945 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1946 // POSSIBILITY OF SUCH DAMAGE.
1947
1948 #include <ruby.h>
1949
1950 extern VALUE mCommandT; // module CommandT
1951 extern VALUE cCommandTMatch; // class CommandT::Match
1952 extern VALUE cCommandTMatcher; // class CommandT::Matcher
1953
1954 // Encapsulates common pattern of checking for an option in an optional
1955 // options hash. The hash itself may be nil, but an exception will be
1956 // raised if it is not nil and not a hash.
1957 VALUE CommandT_option_from_hash(const char *option, VALUE hash);
1958
1959 // Debugging macro.
1960 #define ruby_inspect(obj) rb_funcall(rb_mKernel, rb_intern("p"), 1, obj)
1961 ruby/command-t/match.h [[[1
1962 29
1963 // Copyright 2010 Wincent Colaiuta. All rights reserved.
1964 //
1965 // Redistribution and use in source and binary forms, with or without
1966 // modification, are permitted provided that the following conditions are met:
1967 //
1968 // 1. Redistributions of source code must retain the above copyright notice,
1969 // this list of conditions and the following disclaimer.
1970 // 2. Redistributions in binary form must reproduce the above copyright notice,
1971 // this list of conditions and the following disclaimer in the documentation
1972 // and/or other materials provided with the distribution.
1973 //
1974 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1975 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1976 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1977 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1978 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1979 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1980 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1981 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1982 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1983 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1984 // POSSIBILITY OF SUCH DAMAGE.
1985
1986 #include <ruby.h>
1987
1988 extern VALUE CommandTMatch_initialize(int argc, VALUE *argv, VALUE self);
1989 extern VALUE CommandTMatch_matches(VALUE self);
1990 extern VALUE CommandTMatch_score(VALUE self);
1991 extern VALUE CommandTMatch_to_s(VALUE self);
1992 ruby/command-t/matcher.h [[[1
1993 30
1994 // Copyright 2010 Wincent Colaiuta. All rights reserved.
1995 //
1996 // Redistribution and use in source and binary forms, with or without
1997 // modification, are permitted provided that the following conditions are met:
1998 //
1999 // 1. Redistributions of source code must retain the above copyright notice,
2000 // this list of conditions and the following disclaimer.
2001 // 2. Redistributions in binary form must reproduce the above copyright notice,
2002 // this list of conditions and the following disclaimer in the documentation
2003 // and/or other materials provided with the distribution.
2004 //
2005 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2006 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2007 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2008 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
2009 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2010 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2011 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2012 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2013 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2014 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2015 // POSSIBILITY OF SUCH DAMAGE.
2016
2017 #include <ruby.h>
2018
2019 extern VALUE CommandTMatcher_initialize(int argc, VALUE *argv, VALUE self);
2020 extern VALUE CommandTMatcher_sorted_matches_for(VALUE self, VALUE abbrev, VALUE options);
2021
2022 // most likely the function will be subsumed by the sorted_matcher_for function
2023 extern VALUE CommandTMatcher_matches_for(VALUE self, VALUE abbrev);
2024 ruby/command-t/ruby_compat.h [[[1
2025 49
2026 // Copyright 2010 Wincent Colaiuta. All rights reserved.
2027 //
2028 // Redistribution and use in source and binary forms, with or without
2029 // modification, are permitted provided that the following conditions are met:
2030 //
2031 // 1. Redistributions of source code must retain the above copyright notice,
2032 // this list of conditions and the following disclaimer.
2033 // 2. Redistributions in binary form must reproduce the above copyright notice,
2034 // this list of conditions and the following disclaimer in the documentation
2035 // and/or other materials provided with the distribution.
2036 //
2037 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2038 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2039 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2040 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
2041 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2042 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2043 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2044 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2045 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2046 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2047 // POSSIBILITY OF SUCH DAMAGE.
2048
2049 #include <ruby.h>
2050
2051 // for compatibility with older versions of Ruby which don't declare RSTRING_PTR
2052 #ifndef RSTRING_PTR
2053 #define RSTRING_PTR(s) (RSTRING(s)->ptr)
2054 #endif
2055
2056 // for compatibility with older versions of Ruby which don't declare RSTRING_LEN
2057 #ifndef RSTRING_LEN
2058 #define RSTRING_LEN(s) (RSTRING(s)->len)
2059 #endif
2060
2061 // for compatibility with older versions of Ruby which don't declare RARRAY_PTR
2062 #ifndef RARRAY_PTR
2063 #define RARRAY_PTR(a) (RARRAY(a)->ptr)
2064 #endif
2065
2066 // for compatibility with older versions of Ruby which don't declare RARRAY_LEN
2067 #ifndef RARRAY_LEN
2068 #define RARRAY_LEN(a) (RARRAY(a)->len)
2069 #endif
2070
2071 // for compatibility with older versions of Ruby which don't declare RFLOAT_VALUE
2072 #ifndef RFLOAT_VALUE
2073 #define RFLOAT_VALUE(f) (RFLOAT(f)->value)
2074 #endif
2075 ruby/command-t/depend [[[1
2076 24
2077 # Copyright 2010 Wincent Colaiuta. All rights reserved.
2078 #
2079 # Redistribution and use in source and binary forms, with or without
2080 # modification, are permitted provided that the following conditions are met:
2081 #
2082 # 1. Redistributions of source code must retain the above copyright notice,
2083 # this list of conditions and the following disclaimer.
2084 # 2. Redistributions in binary form must reproduce the above copyright notice,
2085 # this list of conditions and the following disclaimer in the documentation
2086 # and/or other materials provided with the distribution.
2087 #
2088 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2089 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2090 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2091 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
2092 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2093 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2094 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2095 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2096 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2097 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2098 # POSSIBILITY OF SUCH DAMAGE.
2099
2100 CFLAGS += -std=c99 -Wall -Wextra -Wno-unused-parameter
2101 doc/command-t.txt [[[1
2102 786
2103 *command-t.txt* Command-T plug-in for Vim *command-t*
2104
2105 CONTENTS *command-t-contents*
2106
2107 1. Introduction |command-t-intro|
2108 2. Requirements |command-t-requirements|
2109 3. Installation |command-t-installation|
2110 3. Managing using Pathogen |command-t-pathogen|
2111 4. Trouble-shooting |command-t-trouble-shooting|
2112 5. Usage |command-t-usage|
2113 6. Commands |command-t-commands|
2114 7. Mappings |command-t-mappings|
2115 8. Options |command-t-options|
2116 9. Authors |command-t-authors|
2117 10. Website |command-t-website|
2118 11. Donations |command-t-donations|
2119 12. License |command-t-license|
2120 13. History |command-t-history|
2121
2122
2123 INTRODUCTION *command-t-intro*
2124
2125 The Command-T plug-in provides an extremely fast, intuitive mechanism for
2126 opening files and buffers with a minimal number of keystrokes. It's named
2127 "Command-T" because it is inspired by the "Go to File" window bound to
2128 Command-T in TextMate.
2129
2130 Files are selected by typing characters that appear in their paths, and are
2131 ordered by an algorithm which knows that characters that appear in certain
2132 locations (for example, immediately after a path separator) should be given
2133 more weight.
2134
2135 To search efficiently, especially in large projects, you should adopt a
2136 "path-centric" rather than a "filename-centric" mentality. That is you should
2137 think more about where the desired file is found rather than what it is
2138 called. This means narrowing your search down by including some characters
2139 from the upper path components rather than just entering characters from the
2140 filename itself.
2141
2142 Screencasts demonstrating the plug-in can be viewed at:
2143
2144 https://wincent.com/products/command-t
2145
2146
2147 REQUIREMENTS *command-t-requirements*
2148
2149 The plug-in requires Vim compiled with Ruby support, a compatible Ruby
2150 installation at the operating system level, and a C compiler to build
2151 the Ruby extension.
2152
2153
2154 1. Vim compiled with Ruby support
2155
2156 You can check for Ruby support by launching Vim with the --version switch:
2157
2158 vim --version
2159
2160 If "+ruby" appears in the version information then your version of Vim has
2161 Ruby support.
2162
2163 Another way to check is to simply try using the :ruby command from within Vim
2164 itself:
2165
2166 :ruby 1
2167
2168 If your Vim lacks support you'll see an error message like this:
2169
2170 E319: Sorry, the command is not available in this version
2171
2172 The version of Vim distributed with Mac OS X does not include Ruby support,
2173 while MacVim does; it is available from:
2174
2175 http://github.com/b4winckler/macvim/downloads
2176
2177 For Windows users, the Vim 7.2 executable available from www.vim.org does
2178 include Ruby support, and is recommended over version 7.3 (which links against
2179 Ruby 1.9, but apparently has some bugs that need to be resolved).
2180
2181
2182 2. Ruby
2183
2184 In addition to having Ruby support in Vim, your system itself must have a
2185 compatible Ruby install. "Compatible" means the same version as Vim itself
2186 links against. If you use a different version then Command-T is unlikely
2187 to work (see TROUBLE-SHOOTING below).
2188
2189 On Mac OS X Snow Leopard, the system comes with Ruby 1.8.7 and all recent
2190 versions of MacVim (the 7.2 snapshots and 7.3) are linked against it.
2191
2192 On Linux and similar platforms, the linked version of Ruby will depend on
2193 your distribution. You can usually find this out by examining the
2194 compilation and linking flags displayed by the |:version| command in Vim, and
2195 by looking at the output of:
2196
2197 :ruby puts RUBY_VERSION
2198
2199 A suitable Ruby environment for Windows can be installed using the Ruby
2200 1.8.7-p299 RubyInstaller available at:
2201
2202 http://rubyinstaller.org/downloads/archives
2203
2204 If using RubyInstaller be sure to download the installer executable, not the
2205 7-zip archive. When installing mark the checkbox "Add Ruby executables to your
2206 PATH" so that Vim can find them.
2207
2208
2209 3. C compiler
2210
2211 Part of Command-T is implemented in C as a Ruby extension for speed, allowing
2212 it to work responsively even on directory hierarchies containing enormous
2213 numbers of files. As such, a C compiler is required in order to build the
2214 extension and complete the installation.
2215
2216 On Mac OS X, this can be obtained by installing the Xcode Tools that come on
2217 the Mac OS X install disc.
2218
2219 On Windows, the RubyInstaller Development Kit can be used to conveniently
2220 install the necessary tool chain:
2221
2222 http://rubyinstaller.org/downloads/archives
2223
2224 At the time of writing, the appropriate development kit for use with Ruby
2225 1.8.7 is DevKit-3.4.5r3-20091110.
2226
2227 To use the Development Kit extract the archive contents to your C:\Ruby
2228 folder.
2229
2230
2231 INSTALLATION *command-t-installation*
2232
2233 Command-T is distributed as a "vimball" which means that it can be installed
2234 by opening it in Vim and then sourcing it:
2235
2236 :e command-t.vba
2237 :so %
2238
2239 The files will be installed in your |'runtimepath'|. To check where this is
2240 you can issue:
2241
2242 :echo &rtp
2243
2244 The C extension must then be built, which can be done from the shell. If you
2245 use a typical |'runtimepath'| then the files were installed inside ~/.vim and
2246 you can build the extension with:
2247
2248 cd ~/.vim/ruby/command-t
2249 ruby extconf.rb
2250 make
2251
2252 Note: If you are an RVM user, you must perform the build using the same
2253 version of Ruby that Vim itself is linked against. This will often be the
2254 system Ruby, which can be selected before issuing the "make" command with:
2255
2256 rvm use system
2257
2258
2259 MANAGING USING PATHOGEN *command-t-pathogen*
2260
2261 Pathogen is a plugin that allows you to maintain plugin installations in
2262 separate, isolated subdirectories under the "bundle" directory in your
2263 |'runtimepath'|. The following examples assume that you already have
2264 Pathogen installed and configured, and that you are installing into
2265 ~/.vim/bundle. For more information about Pathogen, see:
2266
2267 http://www.vim.org/scripts/script.php?script_id=2332
2268
2269 If you manage your entire ~/.vim folder using Git then you can add the
2270 Command-T repository as a submodule:
2271
2272 cd ~/.vim
2273 git submodule add git://git.wincent.com/command-t.git bundle/command-t
2274 git submodule init
2275
2276 Or if you just wish to do a simple clone instead of using submodules:
2277
2278 cd ~/.vim
2279 git clone git://git.wincent.com/command-t.git bundle/command-t
2280
2281 Once you have a local copy of the repository you can update it at any time
2282 with:
2283
2284 cd ~/.vim/bundle/command-t
2285 git pull
2286
2287 Or you can switch to a specific release with:
2288
2289 cd ~/.vim/bundle/command-t
2290 git checkout 0.8b
2291
2292 After installing or updating you must build the extension:
2293
2294 cd ~/.vim/bundle/command-t
2295 rake make
2296
2297 While the Vimball installation automatically generates the help tags, under
2298 Pathogen it is necessary to do so explicitly from inside Vim:
2299
2300 :call pathogen#helptags()
2301
2302
2303 TROUBLE-SHOOTING *command-t-trouble-shooting*
2304
2305 Most installation problems are caused by a mismatch between the version of
2306 Ruby on the host operating system, and the version of Ruby that Vim itself
2307 linked against at compile time. For example, if one is 32-bit and the other is
2308 64-bit, or one is from the Ruby 1.9 series and the other is from the 1.8
2309 series, then the plug-in is not likely to work.
2310
2311 As such, on Mac OS X, I recommend using the standard Ruby that comes with the
2312 system (currently 1.8.7) along with the latest version of MacVim (currently
2313 version 7.3). If you wish to use custom builds of Ruby or of MacVim (not
2314 recommmended) then you will have to take extra care to ensure that the exact
2315 same Ruby environment is in effect when building Ruby, Vim and the Command-T
2316 extension.
2317
2318 For Windows, the following combination is known to work:
2319
2320 - Vim 7.2 from http://www.vim.org/download.php:
2321 ftp://ftp.vim.org/pub/vim/pc/gvim72.exe
2322 - Ruby 1.8.7-p299 from http://rubyinstaller.org/downloads/archives:
2323 http://rubyforge.org/frs/download.php/71492/rubyinstaller-1.8.7-p299.exe
2324 - DevKit 3.4.5r3-20091110 from http://rubyinstaller.org/downloads/archives:
2325 http://rubyforge.org/frs/download.php/66888/devkit-3.4.5r3-20091110.7z
2326
2327 If a problem occurs the first thing you should do is inspect the output of:
2328
2329 ruby extconf.rb
2330 make
2331
2332 During the installation, and:
2333
2334 vim --version
2335
2336 And compare the compilation and linker flags that were passed to the
2337 extension and to Vim itself when they were built. If the Ruby-related
2338 flags or architecture flags are different then it is likely that something
2339 has changed in your Ruby environment and the extension may not work until
2340 you eliminate the discrepancy.
2341
2342
2343 USAGE *command-t-usage*
2344
2345 Bring up the Command-T file window by typing:
2346
2347 <Leader>t
2348
2349 This mapping is set up automatically for you, provided you do not already have
2350 a mapping for <Leader>t or |:CommandT|. You can also bring up the file window
2351 by issuing the command:
2352
2353 :CommandT
2354
2355 A prompt will appear at the bottom of the screen along with a file window
2356 showing all of the files in the current directory (as returned by the
2357 |:pwd| command).
2358
2359 For the most efficient file navigation within a project it's recommended that
2360 you |:cd| into the root directory of your project when starting to work on it.
2361 If you wish to open a file from outside of the project folder you can pass in
2362 an optional path argument (relative or absolute) to |:CommandT|:
2363
2364 :CommandT ../path/to/other/files
2365
2366 Type letters in the prompt to narrow down the selection, showing only the
2367 files whose paths contain those letters in the specified order. Letters do not
2368 need to appear consecutively in a path in order for it to be classified as a
2369 match.
2370
2371 Once the desired file has been selected it can be opened by pressing <CR>.
2372 (By default files are opened in the current window, but there are other
2373 mappings that you can use to open in a vertical or horizontal split, or in
2374 a new tab.) Note that if you have |'nohidden'| set and there are unsaved
2375 changes in the current window when you press <CR> then opening in the current
2376 window would fail; in this case Command-T will open the file in a new split.
2377
2378 The following mappings are active when the prompt has focus:
2379
2380 <BS> delete the character to the left of the cursor
2381 <Del> delete the character at the cursor
2382 <Left> move the cursor one character to the left
2383 <C-h> move the cursor one character to the left
2384 <Right> move the cursor one character to the right
2385 <C-l> move the cursor one character to the right
2386 <C-a> move the cursor to the start (left)
2387 <C-e> move the cursor to the end (right)
2388 <C-u> clear the contents of the prompt
2389 <Tab> change focus to the file listing
2390
2391 The following mappings are active when the file listing has focus:
2392
2393 <Tab> change focus to the prompt
2394
2395 The following mappings are active when either the prompt or the file listing
2396 has focus:
2397
2398 <CR> open the selected file
2399 <C-CR> open the selected file in a new split window
2400 <C-s> open the selected file in a new split window
2401 <C-v> open the selected file in a new vertical split window
2402 <C-t> open the selected file in a new tab
2403 <C-j> select next file in the file listing
2404 <C-n> select next file in the file listing
2405 <Down> select next file in the file listing
2406 <C-k> select previous file in the file listing
2407 <C-p> select previous file in the file listing
2408 <Up> select previous file in the file listing
2409 <C-c> cancel (dismisses file listing)
2410
2411 The following is also available on terminals which support it:
2412
2413 <Esc> cancel (dismisses file listing)
2414
2415 Note that the default mappings can be overriden by setting options in your
2416 ~/.vimrc file (see the OPTIONS section for a full list of available options).
2417
2418 In addition, when the file listing has focus, typing a character will cause
2419 the selection to jump to the first path which begins with that character.
2420 Typing multiple characters consecutively can be used to distinguish between
2421 paths which begin with the same prefix.
2422
2423
2424 COMMANDS *command-t-commands*
2425
2426 *:CommandT*
2427 |:CommandT| Brings up the Command-T file window, starting in the
2428 current working directory as returned by the|:pwd|
2429 command.
2430
2431 *:CommandTBuffer*
2432 |:CommandTBuffer|Brings up the Command-T buffer window.
2433 This works exactly like the standard file window,
2434 except that the selection is limited to files that
2435 you already have open in buffers.
2436
2437 *:CommandTFlush*
2438 |:CommandTFlush|Instructs the plug-in to flush its path cache, causing
2439 the directory to be rescanned for new or deleted paths
2440 the next time the file window is shown. In addition, all
2441 configuration settings are re-evaluated, causing any
2442 changes made to settings via the |:let| command to be picked
2443 up.
2444
2445
2446 MAPPINGS *command-t-mappings*
2447
2448 By default Command-T comes with only two mappings:
2449
2450 <Leader>t bring up the Command-T file window
2451 <Leader>b bring up the Command-T buffer window
2452
2453 However, Command-T won't overwrite a pre-existing mapping so if you prefer
2454 to define different mappings use lines like these in your ~/.vimrc:
2455
2456 nmap <silent> <Leader>t :CommandT<CR>
2457 nmap <silent> <Leader>b :CommandTBuffer<CR>
2458
2459 Replacing "<Leader>t" or "<Leader>b" with your mapping of choice.
2460
2461 Note that in the case of MacVim you actually can map to Command-T (written
2462 as <D-t> in Vim) in your ~/.gvimrc file if you first unmap the existing menu
2463 binding of Command-T to "New Tab":
2464
2465 if has("gui_macvim")
2466 macmenu &File.New\ Tab key=<nop>
2467 map <D-t> :CommandT<CR>
2468 endif
2469
2470 When the Command-T window is active a number of other additional mappings
2471 become available for doing things like moving between and selecting matches.
2472 These are fully described above in the USAGE section, and settings for
2473 overriding the mappings are listed below under OPTIONS.
2474
2475
2476 OPTIONS *command-t-options*
2477
2478 A number of options may be set in your ~/.vimrc to influence the behaviour of
2479 the plug-in. To set an option, you include a line like this in your ~/.vimrc:
2480
2481 let g:CommandTMaxFiles=20000
2482
2483 To have Command-T pick up new settings immediately (that is, without having
2484 to restart Vim) you can issue the |:CommandTFlush| command after making
2485 changes via |:let|.
2486
2487 Following is a list of all available options:
2488
2489 *g:CommandTMaxFiles*
2490 |g:CommandTMaxFiles| number (default 10000)
2491
2492 The maximum number of files that will be considered when scanning the
2493 current directory. Upon reaching this number scanning stops. This
2494 limit applies only to file listings and is ignored for buffer
2495 listings.
2496
2497 *g:CommandTMaxDepth*
2498 |g:CommandTMaxDepth| number (default 15)
2499
2500 The maximum depth (levels of recursion) to be explored when scanning the
2501 current directory. Any directories at levels beyond this depth will be
2502 skipped.
2503
2504 *g:CommandTMaxHeight*
2505 |g:CommandTMaxHeight| number (default: 0)
2506
2507 The maximum height in lines the match window is allowed to expand to.
2508 If set to 0, the window will occupy as much of the available space as
2509 needed to show matching entries.
2510
2511 *g:CommandTAlwaysShowDotFiles*
2512 |g:CommandTAlwaysShowDotFiles| boolean (default: 0)
2513
2514 When showing the file listing Command-T will by default show dot-files
2515 only if the entered search string contains a dot that could cause a
2516 dot-file to match. When set to a non-zero value, this setting instructs
2517 Command-T to always include matching dot-files in the match list
2518 regardless of whether the search string contains a dot. See also
2519 |g:CommandTNeverShowDotFiles|. Note that this setting only influences
2520 the file listing; the buffer listing treats dot-files like any other
2521 file.
2522
2523 *g:CommandTNeverShowDotFiles*
2524 |g:CommandTNeverShowDotFiles| boolean (default: 0)
2525
2526 In the file listing, Command-T will by default show dot-files if the
2527 entered search string contains a dot that could cause a dot-file to
2528 match. When set to a non-zero value, this setting instructs Command-T to
2529 never show dot-files under any circumstances. Note that it is
2530 contradictory to set both this setting and
2531 |g:CommandTAlwaysShowDotFiles| to true, and if you do so Vim will suffer
2532 from headaches, nervous twitches, and sudden mood swings. This setting
2533 has no effect in buffer listings, where dot files are treated like any
2534 other file.
2535
2536 *g:CommandTScanDotDirectories*
2537 |g:CommandTScanDotDirectories| boolean (default: 0)
2538
2539 Normally Command-T will not recurse into "dot-directories" (directories
2540 whose names begin with a dot) while performing its initial scan. Set
2541 this setting to a non-zero value to override this behavior and recurse.
2542 Note that this setting is completely independent of the
2543 |g:CommandTAlwaysShowDotFiles| and |g:CommandTNeverShowDotFiles|
2544 settings; those apply only to the selection and display of matches
2545 (after scanning has been performed), whereas
2546 |g:CommandTScanDotDirectories| affects the behaviour at scan-time.
2547
2548 Note also that even with this setting off you can still use Command-T to
2549 open files inside a "dot-directory" such as ~/.vim, but you have to use
2550 the |:cd| command to change into that directory first. For example:
2551
2552 :cd ~/.vim
2553 :CommandT
2554
2555 *g:CommandTMatchWindowAtTop*
2556 |g:CommandTMatchWindowAtTop| boolean (default: 0)
2557
2558 When this setting is off (the default) the match window will appear at
2559 the bottom so as to keep it near to the prompt. Turning it on causes the
2560 match window to appear at the top instead. This may be preferable if you
2561 want the best match (usually the first one) to appear in a fixed location
2562 on the screen rather than moving as the number of matches changes during
2563 typing.
2564
2565 *g:CommandTMatchWindowReverse*
2566 |g:CommandTMatchWindowReverse| boolean (default: 0)
2567
2568 When this setting is off (the default) the matches will appear from
2569 top to bottom with the topmost being selected. Turning it on causes the
2570 matches to be reversed so the best match is at the bottom and the
2571 initially selected match is the bottom most. This may be preferable if
2572 you want the best match to appear in a fixed location on the screen
2573 but still be near the prompt at the bottom.
2574
2575 As well as the basic options listed above, there are a number of settings that
2576 can be used to override the default key mappings used by Command-T. For
2577 example, to set <C-x> as the mapping for cancelling (dismissing) the Command-T
2578 window, you would add the following to your ~/.vimrc:
2579
2580 let g:CommandTCancelMap='<C-x>'
2581
2582 Multiple, alternative mappings may be specified using list syntax:
2583
2584 let g:CommandTCancelMap=['<C-x>', '<C-c>']
2585
2586 Following is a list of all map settings and their defaults:
2587
2588 Setting Default mapping(s)
2589
2590 *g:CommandTBackspaceMap*
2591 |g:CommandTBackspaceMap| <BS>
2592
2593 *g:CommandTDeleteMap*
2594 |g:CommandTDeleteMap| <Del>
2595
2596 *g:CommandTAcceptSelectionMap*
2597 |g:CommandTAcceptSelectionMap| <CR>
2598
2599 *g:CommandTAcceptSelectionSplitMap*
2600 |g:CommandTAcceptSelectionSplitMap| <C-CR>
2601 <C-s>
2602
2603 *g:CommandTAcceptSelectionTabMap*
2604 |g:CommandTAcceptSelectionTabMap| <C-t>
2605
2606 *g:CommandTAcceptSelectionVSplitMap*
2607 |g:CommandTAcceptSelectionVSplitMap| <C-v>
2608
2609 *g:CommandTToggleFocusMap*
2610 |g:CommandTToggleFocusMap| <Tab>
2611
2612 *g:CommandTCancelMap*
2613 |g:CommandTCancelMap| <C-c>
2614 <Esc> (not on all terminals)
2615
2616 *g:CommandTSelectNextMap*
2617 |g:CommandTSelectNextMap| <C-n>
2618 <C-j>
2619 <Down>
2620
2621 *g:CommandTSelectPrevMap*
2622 |g:CommandTSelectPrevMap| <C-p>
2623 <C-k>
2624 <Up>
2625
2626 *g:CommandTClearMap*
2627 |g:CommandTClearMap| <C-u>
2628
2629 *g:CommandTCursorLeftMap*
2630 |g:CommandTCursorLeftMap| <Left>
2631 <C-h>
2632
2633 *g:CommandTCursorRightMap*
2634 |g:CommandTCursorRightMap| <Right>
2635 <C-l>
2636
2637 *g:CommandTCursorEndMap*
2638 |g:CommandTCursorEndMap| <C-e>
2639
2640 *g:CommandTCursorStartMap*
2641 |g:CommandTCursorStartMap| <C-a>
2642
2643 In addition to the options provided by Command-T itself, some of Vim's own
2644 settings can be used to control behavior:
2645
2646 *command-t-wildignore*
2647 |'wildignore'| string (default: '')
2648
2649 Vim's |'wildignore'| setting is used to determine which files should be
2650 excluded from listings. This is a comma-separated list of glob patterns.
2651 It defaults to the empty string, but common settings include "*.o,*.obj"
2652 (to exclude object files) or ".git,.svn" (to exclude SCM metadata
2653 directories). For example:
2654
2655 :set wildignore+=*.o,*.obj,.git
2656
2657 A pattern such as "vendor/rails/**" would exclude all files and
2658 subdirectories inside the "vendor/rails" directory (relative to
2659 directory Command-T starts in).
2660
2661 See the |'wildignore'| documentation for more information.
2662
2663
2664 AUTHORS *command-t-authors*
2665
2666 Command-T is written and maintained by Wincent Colaiuta <win@wincent.com>.
2667 Other contributors that have submitted patches include (in alphabetical
2668 order):
2669
2670 Daniel Hahler
2671 Lucas de Vries
2672 Matthew Todd
2673 Mike Lundy
2674 Scott Bronson
2675 Steven Moazami
2676 Sung Pae
2677 Victor Hugo Borja
2678 Zak Johnson
2679
2680 As this was the first Vim plug-in I had ever written I was heavily influenced
2681 by the design of the LustyExplorer plug-in by Stephen Bach, which I understand
2682 is one of the largest Ruby-based Vim plug-ins to date.
2683
2684 While the Command-T codebase doesn't contain any code directly copied from
2685 LustyExplorer, I did use it as a reference for answers to basic questions (like
2686 "How do you do 'X' in a Ruby-based Vim plug-in?"), and also copied some basic
2687 architectural decisions (like the division of the code into Prompt, Settings
2688 and MatchWindow classes).
2689
2690 LustyExplorer is available from:
2691
2692 http://www.vim.org/scripts/script.php?script_id=1890
2693
2694
2695 WEBSITE *command-t-website*
2696
2697 The official website for Command-T is:
2698
2699 https://wincent.com/products/command-t
2700
2701 The latest release will always be available from there.
2702
2703 Development in progress can be inspected via the project's Git repository
2704 browser at:
2705
2706 https://wincent.com/repos/command-t
2707
2708 A copy of each release is also available from the official Vim scripts site
2709 at:
2710
2711 http://www.vim.org/scripts/script.php?script_id=3025
2712
2713 Bug reports should be submitted to the issue tracker at:
2714
2715 https://wincent.com/issues
2716
2717
2718 DONATIONS *command-t-donations*
2719
2720 Command-T itself is free software released under the terms of the BSD license.
2721 If you would like to support further development you can make a donation via
2722 PayPal to win@wincent.com:
2723
2724 https://wincent.com/products/command-t/donations
2725
2726
2727 LICENSE *command-t-license*
2728
2729 Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
2730
2731 Redistribution and use in source and binary forms, with or without
2732 modification, are permitted provided that the following conditions are met:
2733
2734 1. Redistributions of source code must retain the above copyright notice,
2735 this list of conditions and the following disclaimer.
2736 2. Redistributions in binary form must reproduce the above copyright notice,
2737 this list of conditions and the following disclaimer in the documentation
2738 and/or other materials provided with the distribution.
2739
2740 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2741 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2742 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2743 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
2744 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2745 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2746 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2747 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2748 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2749 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2750 POSSIBILITY OF SUCH DAMAGE.
2751
2752
2753 HISTORY *command-t-history*
2754
2755 1.2.1 (30 April 2011)
2756
2757 - Remove duplicate copy of the documentation that was causing "Duplicate tag"
2758 errors
2759 - Mitigate issue with distracting blinking cursor in non-GUI versions of Vim
2760 (patch from Steven Moazami)
2761
2762 1.2 (30 April 2011)
2763
2764 - added |g:CommandTMatchWindowReverse| option, to reverse the order of items
2765 in the match listing (patch from Steven Moazami)
2766
2767 1.1b2 (26 March 2011)
2768
2769 - fix a glitch in the release process; the plugin itself is unchanged since
2770 1.1b
2771
2772 1.1b (26 March 2011)
2773
2774 - add |:CommandTBuffer| command for quickly selecting among open buffers
2775
2776 1.0.1 (5 January 2011)
2777
2778 - work around bug when mapping |:CommandTFlush|, wherein the default mapping
2779 for |:CommandT| would not be set up
2780 - clean up when leaving the Command-T buffer via unexpected means (such as
2781 with <C-W k> or similar)
2782
2783 1.0 (26 November 2010)
2784
2785 - make relative path simplification work on Windows
2786
2787 1.0b (5 November 2010)
2788
2789 - work around platform-specific Vim 7.3 bug seen by some users (wherein
2790 Vim always falsely reports to Ruby that the buffer numbers is 0)
2791 - re-use the buffer that is used to show the match listing, rather than
2792 throwing it away and recreating it each time Command-T is shown; this
2793 stops the buffer numbers from creeping up needlessly
2794
2795 0.9 (8 October 2010)
2796
2797 - use relative paths when opening files inside the current working directory
2798 in order to keep buffer listings as brief as possible (patch from Matthew
2799 Todd)
2800
2801 0.8.1 (14 September 2010)
2802
2803 - fix mapping issues for users who have set |'notimeout'| (patch from Sung
2804 Pae)
2805
2806 0.8 (19 August 2010)
2807
2808 - overrides for the default mappings can now be lists of strings, allowing
2809 multiple mappings to be defined for any given action
2810 - <Leader>t mapping only set up if no other map for |:CommandT| exists
2811 (patch from Scott Bronson)
2812 - prevent folds from appearing in the match listing
2813 - tweaks to avoid the likelihood of "Not enough room" errors when trying to
2814 open files
2815 - watch out for "nil" windows when restoring window dimensions
2816 - optimizations (avoid some repeated downcasing)
2817 - move all Ruby files under the "command-t" subdirectory and avoid polluting
2818 the "Vim" module namespace
2819
2820 0.8b (11 July 2010)
2821
2822 - large overhaul of the scoring algorithm to make the ordering of returned
2823 results more intuitive; given the scope of the changes and room for
2824 optimization of the new algorithm, this release is labelled as "beta"
2825
2826 0.7 (10 June 2010)
2827
2828 - handle more |'wildignore'| patterns by delegating to Vim's own |expand()|
2829 function; with this change it is now viable to exclude patterns such as
2830 'vendor/rails/**' in addition to filename-only patterns like '*.o' and
2831 '.git' (patch from Mike Lundy)
2832 - always sort results alphabetically for empty search strings; this eliminates
2833 filesystem-specific variations (patch from Mike Lundy)
2834
2835 0.6 (28 April 2010)
2836
2837 - |:CommandT| now accepts an optional parameter to specify the starting
2838 directory, temporarily overriding the usual default of Vim's |:pwd|
2839 - fix truncated paths when operating from root directory
2840
2841 0.5.1 (11 April 2010)
2842
2843 - fix for Ruby 1.9 compatibility regression introduced in 0.5
2844 - documentation enhancements, specifically targetted at Windows users
2845
2846 0.5 (3 April 2010)
2847
2848 - |:CommandTFlush| now re-evaluates settings, allowing changes made via |let|
2849 to be picked up without having to restart Vim
2850 - fix premature abort when scanning very deep directory hierarchies
2851 - remove broken |<Esc>| key mapping on vt100 and xterm terminals
2852 - provide settings for overriding default mappings
2853 - minor performance optimization
2854
2855 0.4 (27 March 2010)
2856
2857 - add |g:CommandTMatchWindowAtTop| setting (patch from Zak Johnson)
2858 - documentation fixes and enhancements
2859 - internal refactoring and simplification
2860
2861 0.3 (24 March 2010)
2862
2863 - add |g:CommandTMaxHeight| setting for controlling the maximum height of the
2864 match window (patch from Lucas de Vries)
2865 - fix bug where |'list'| setting might be inappropriately set after dismissing
2866 Command-T
2867 - compatibility fix for different behaviour of "autoload" under Ruby 1.9.1
2868 - avoid "highlight group not found" warning when run under a version of Vim
2869 that does not have syntax highlighting support
2870 - open in split when opening normally would fail due to |'hidden'| and
2871 |'modified'| values
2872
2873 0.2 (23 March 2010)
2874
2875 - compatibility fixes for compilation under Ruby 1.9 series
2876 - compatibility fixes for compilation under Ruby 1.8.5
2877 - compatibility fixes for Windows and other non-UNIX platforms
2878 - suppress "mapping already exists" message if <Leader>t mapping is already
2879 defined when plug-in is loaded
2880 - exclude paths based on |'wildignore'| setting rather than a hardcoded
2881 regular expression
2882
2883 0.1 (22 March 2010)
2884
2885 - initial public release
2886
2887 ------------------------------------------------------------------------------
2888 vim:tw=78:ft=help:
2889 plugin/command-t.vim [[[1
2890 164
2891 " command-t.vim
2892 " Copyright 2010-2011 Wincent Colaiuta. All rights reserved.
2893 "
2894 " Redistribution and use in source and binary forms, with or without
2895 " modification, are permitted provided that the following conditions are met:
2896 "
2897 " 1. Redistributions of source code must retain the above copyright notice,
2898 " this list of conditions and the following disclaimer.
2899 " 2. Redistributions in binary form must reproduce the above copyright notice,
2900 " this list of conditions and the following disclaimer in the documentation
2901 " and/or other materials provided with the distribution.
2902 "
2903 " THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2904 " AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2905 " IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2906 " ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
2907 " LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2908 " CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2909 " SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2910 " INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911 " CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2912 " ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2913 " POSSIBILITY OF SUCH DAMAGE.
2914
2915 if exists("g:command_t_loaded")
2916 finish
2917 endif
2918 let g:command_t_loaded = 1
2919
2920 command CommandTBuffer call <SID>CommandTShowBufferFinder()
2921 command -nargs=? -complete=dir CommandT call <SID>CommandTShowFileFinder(<q-args>)
2922 command CommandTFlush call <SID>CommandTFlush()
2923
2924 if !hasmapto(':CommandT<CR>')
2925 silent! nmap <unique> <silent> <Leader>t :CommandT<CR>
2926 endif
2927
2928 if !hasmapto(':CommandTBuffer<CR>')
2929 silent! nmap <unique> <silent> <Leader>b :CommandTBuffer<CR>
2930 endif
2931
2932 function s:CommandTRubyWarning()
2933 echohl WarningMsg
2934 echo "command-t.vim requires Vim to be compiled with Ruby support"
2935 echo "For more information type: :help command-t"
2936 echohl none
2937 endfunction
2938
2939 function s:CommandTShowBufferFinder()
2940 if has('ruby')
2941 ruby $command_t.show_buffer_finder
2942 else
2943 call s:CommandTRubyWarning()
2944 endif
2945 endfunction
2946
2947 function s:CommandTShowFileFinder(arg)
2948 if has('ruby')
2949 ruby $command_t.show_file_finder
2950 else
2951 call s:CommandTRubyWarning()
2952 endif
2953 endfunction
2954
2955 function s:CommandTFlush()
2956 if has('ruby')
2957 ruby $command_t.flush
2958 else
2959 call s:CommandTRubyWarning()
2960 endif
2961 endfunction
2962
2963 if !has('ruby')
2964 finish
2965 endif
2966
2967 function CommandTHandleKey(arg)
2968 ruby $command_t.handle_key
2969 endfunction
2970
2971 function CommandTBackspace()
2972 ruby $command_t.backspace
2973 endfunction
2974
2975 function CommandTDelete()
2976 ruby $command_t.delete
2977 endfunction
2978
2979 function CommandTAcceptSelection()
2980 ruby $command_t.accept_selection
2981 endfunction
2982
2983 function CommandTAcceptSelectionTab()
2984 ruby $command_t.accept_selection :command => 'tabe'
2985 endfunction
2986
2987 function CommandTAcceptSelectionSplit()
2988 ruby $command_t.accept_selection :command => 'sp'
2989 endfunction
2990
2991 function CommandTAcceptSelectionVSplit()
2992 ruby $command_t.accept_selection :command => 'vs'
2993 endfunction
2994
2995 function CommandTToggleFocus()
2996 ruby $command_t.toggle_focus
2997 endfunction
2998
2999 function CommandTCancel()
3000 ruby $command_t.cancel
3001 endfunction
3002
3003 function CommandTSelectNext()
3004 ruby $command_t.select_next
3005 endfunction
3006
3007 function CommandTSelectPrev()
3008 ruby $command_t.select_prev
3009 endfunction
3010
3011 function CommandTClear()
3012 ruby $command_t.clear
3013 endfunction
3014
3015 function CommandTCursorLeft()
3016 ruby $command_t.cursor_left
3017 endfunction
3018
3019 function CommandTCursorRight()
3020 ruby $command_t.cursor_right
3021 endfunction
3022
3023 function CommandTCursorEnd()
3024 ruby $command_t.cursor_end
3025 endfunction
3026
3027 function CommandTCursorStart()
3028 ruby $command_t.cursor_start
3029 endfunction
3030
3031 ruby << EOF
3032 # require Ruby files
3033 begin
3034 # prepare controller
3035 require 'command-t/vim'
3036 require 'command-t/controller'
3037 $command_t = CommandT::Controller.new
3038 rescue LoadError
3039 load_path_modified = false
3040 ::VIM::evaluate('&runtimepath').to_s.split(',').each do |path|
3041 lib = "#{path}/ruby"
3042 if !$LOAD_PATH.include?(lib) and File.exist?(lib)
3043 $LOAD_PATH << lib
3044 load_path_modified = true
3045 end
3046 end
3047 retry if load_path_modified
3048
3049 # could get here if C extension was not compiled, or was compiled
3050 # for the wrong architecture or Ruby version
3051 require 'command-t/stub'
3052 $command_t = CommandT::Stub.new
3053 end
3054 EOF