More files, other stuff.
This commit is contained in:
parent
4fcb8721da
commit
a6a986cb76
37 changed files with 2826 additions and 8 deletions
357
vimfiles/ruby/command-t/controller.rb
Normal file
357
vimfiles/ruby/command-t/controller.rb
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
# Copyright 2010-2012 Wincent Colaiuta. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'command-t/finder/buffer_finder'
|
||||
require 'command-t/finder/jump_finder'
|
||||
require 'command-t/finder/file_finder'
|
||||
require 'command-t/finder/tag_finder'
|
||||
require 'command-t/match_window'
|
||||
require 'command-t/prompt'
|
||||
require 'command-t/vim/path_utilities'
|
||||
|
||||
module CommandT
|
||||
class Controller
|
||||
include VIM::PathUtilities
|
||||
|
||||
def initialize
|
||||
@prompt = Prompt.new
|
||||
end
|
||||
|
||||
def show_buffer_finder
|
||||
@path = VIM::pwd
|
||||
@active_finder = buffer_finder
|
||||
show
|
||||
end
|
||||
|
||||
def show_jump_finder
|
||||
@path = VIM::pwd
|
||||
@active_finder = jump_finder
|
||||
show
|
||||
end
|
||||
|
||||
def show_tag_finder
|
||||
@path = VIM::pwd
|
||||
@active_finder = tag_finder
|
||||
show
|
||||
end
|
||||
|
||||
def show_file_finder
|
||||
# optional parameter will be desired starting directory, or ""
|
||||
@path = File.expand_path(::VIM::evaluate('a:arg'), VIM::pwd)
|
||||
@active_finder = file_finder
|
||||
file_finder.path = @path
|
||||
show
|
||||
rescue Errno::ENOENT
|
||||
# probably a problem with the optional parameter
|
||||
@match_window.print_no_such_file_or_directory
|
||||
end
|
||||
|
||||
def hide
|
||||
@match_window.close
|
||||
if VIM::Window.select @initial_window
|
||||
if @initial_buffer.number == 0
|
||||
# upstream bug: buffer number misreported as 0
|
||||
# see: https://wincent.com/issues/1617
|
||||
::VIM::command "silent b #{@initial_buffer.name}"
|
||||
else
|
||||
::VIM::command "silent b #{@initial_buffer.number}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
return unless @active_finder && @active_finder.respond_to?(:flush)
|
||||
@active_finder.flush
|
||||
list_matches
|
||||
end
|
||||
|
||||
def flush
|
||||
@max_height = nil
|
||||
@min_height = nil
|
||||
@file_finder = nil
|
||||
@tag_finder = nil
|
||||
end
|
||||
|
||||
def handle_key
|
||||
key = ::VIM::evaluate('a:arg').to_i.chr
|
||||
if @focus == @prompt
|
||||
@prompt.add! key
|
||||
list_matches
|
||||
else
|
||||
@match_window.find key
|
||||
end
|
||||
end
|
||||
|
||||
def backspace
|
||||
if @focus == @prompt
|
||||
@prompt.backspace!
|
||||
list_matches
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
if @focus == @prompt
|
||||
@prompt.delete!
|
||||
list_matches
|
||||
end
|
||||
end
|
||||
|
||||
def accept_selection options = {}
|
||||
selection = @match_window.selection
|
||||
hide
|
||||
open_selection(selection, options) unless selection.nil?
|
||||
end
|
||||
|
||||
def toggle_focus
|
||||
@focus.unfocus # old focus
|
||||
@focus = @focus == @prompt ? @match_window : @prompt
|
||||
@focus.focus # new focus
|
||||
end
|
||||
|
||||
def cancel
|
||||
hide
|
||||
end
|
||||
|
||||
def select_next
|
||||
@match_window.select_next
|
||||
end
|
||||
|
||||
def select_prev
|
||||
@match_window.select_prev
|
||||
end
|
||||
|
||||
def clear
|
||||
@prompt.clear!
|
||||
list_matches
|
||||
end
|
||||
|
||||
def cursor_left
|
||||
@prompt.cursor_left if @focus == @prompt
|
||||
end
|
||||
|
||||
def cursor_right
|
||||
@prompt.cursor_right if @focus == @prompt
|
||||
end
|
||||
|
||||
def cursor_end
|
||||
@prompt.cursor_end if @focus == @prompt
|
||||
end
|
||||
|
||||
def cursor_start
|
||||
@prompt.cursor_start if @focus == @prompt
|
||||
end
|
||||
|
||||
def leave
|
||||
@match_window.leave
|
||||
end
|
||||
|
||||
def unload
|
||||
@match_window.unload
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def show
|
||||
@initial_window = $curwin
|
||||
@initial_buffer = $curbuf
|
||||
@match_window = MatchWindow.new \
|
||||
:prompt => @prompt,
|
||||
:match_window_at_top => get_bool('g:CommandTMatchWindowAtTop'),
|
||||
:match_window_reverse => get_bool('g:CommandTMatchWindowReverse'),
|
||||
:min_height => min_height
|
||||
@focus = @prompt
|
||||
@prompt.focus
|
||||
register_for_key_presses
|
||||
clear # clears prompt and lists matches
|
||||
end
|
||||
|
||||
def max_height
|
||||
@max_height ||= get_number('g:CommandTMaxHeight') || 0
|
||||
end
|
||||
|
||||
def min_height
|
||||
@min_height ||= begin
|
||||
min_height = get_number('g:CommandTMinHeight') || 0
|
||||
min_height = max_height if max_height != 0 && min_height > max_height
|
||||
min_height
|
||||
end
|
||||
end
|
||||
|
||||
def get_number name
|
||||
VIM::exists?(name) ? ::VIM::evaluate("#{name}").to_i : nil
|
||||
end
|
||||
|
||||
def get_bool name
|
||||
VIM::exists?(name) ? ::VIM::evaluate("#{name}").to_i != 0 : nil
|
||||
end
|
||||
|
||||
def get_string name
|
||||
VIM::exists?(name) ? ::VIM::evaluate("#{name}").to_s : nil
|
||||
end
|
||||
|
||||
# expect a string or a list of strings
|
||||
def get_list_or_string name
|
||||
return nil unless VIM::exists?(name)
|
||||
list_or_string = ::VIM::evaluate("#{name}")
|
||||
if list_or_string.kind_of?(Array)
|
||||
list_or_string.map { |item| item.to_s }
|
||||
else
|
||||
list_or_string.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Backslash-escape space, \, |, %, #, "
|
||||
def sanitize_path_string str
|
||||
# for details on escaping command-line mode arguments see: :h :
|
||||
# (that is, help on ":") in the Vim documentation.
|
||||
str.gsub(/[ \\|%#"]/, '\\\\\0')
|
||||
end
|
||||
|
||||
def default_open_command
|
||||
if !get_bool('&hidden') && get_bool('&modified')
|
||||
'sp'
|
||||
else
|
||||
'e'
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_appropriate_window_selection
|
||||
# normally we try to open the selection in the current window, but there
|
||||
# is one exception:
|
||||
#
|
||||
# - we don't touch any "unlisted" buffer with buftype "nofile" (such as
|
||||
# NERDTree or MiniBufExplorer); this is to avoid things like the "Not
|
||||
# enough room" error which occurs when trying to open in a split in a
|
||||
# shallow (potentially 1-line) buffer like MiniBufExplorer is current
|
||||
#
|
||||
# Other "unlisted" buffers, such as those with buftype "help" are treated
|
||||
# normally.
|
||||
initial = $curwin
|
||||
while true do
|
||||
break unless ::VIM::evaluate('&buflisted').to_i == 0 &&
|
||||
::VIM::evaluate('&buftype').to_s == 'nofile'
|
||||
::VIM::command 'wincmd w' # try next window
|
||||
break if $curwin == initial # have already tried all
|
||||
end
|
||||
end
|
||||
|
||||
def open_selection selection, options = {}
|
||||
command = options[:command] || default_open_command
|
||||
selection = File.expand_path selection, @path
|
||||
selection = relative_path_under_working_directory selection
|
||||
selection = sanitize_path_string selection
|
||||
ensure_appropriate_window_selection
|
||||
|
||||
@active_finder.open_selection command, selection, options
|
||||
end
|
||||
|
||||
def map key, function, param = nil
|
||||
::VIM::command "noremap <silent> <buffer> #{key} " \
|
||||
":call CommandT#{function}(#{param})<CR>"
|
||||
end
|
||||
|
||||
def term
|
||||
@term ||= ::VIM::evaluate('&term')
|
||||
end
|
||||
|
||||
def register_for_key_presses
|
||||
# "normal" keys (interpreted literally)
|
||||
numbers = ('0'..'9').to_a.join
|
||||
lowercase = ('a'..'z').to_a.join
|
||||
uppercase = lowercase.upcase
|
||||
punctuation = '<>`@#~!"$%&/()=+*-_.,;:?\\\'{}[] ' # and space
|
||||
(numbers + lowercase + uppercase + punctuation).each_byte do |b|
|
||||
map "<Char-#{b}>", 'HandleKey', b
|
||||
end
|
||||
|
||||
# "special" keys (overridable by settings)
|
||||
{
|
||||
'AcceptSelection' => '<CR>',
|
||||
'AcceptSelectionSplit' => ['<C-CR>', '<C-s>'],
|
||||
'AcceptSelectionTab' => '<C-t>',
|
||||
'AcceptSelectionVSplit' => '<C-v>',
|
||||
'Backspace' => '<BS>',
|
||||
'Cancel' => ['<C-c>', '<Esc>'],
|
||||
'Clear' => '<C-u>',
|
||||
'CursorEnd' => '<C-e>',
|
||||
'CursorLeft' => ['<Left>', '<C-h>'],
|
||||
'CursorRight' => ['<Right>', '<C-l>'],
|
||||
'CursorStart' => '<C-a>',
|
||||
'Delete' => '<Del>',
|
||||
'Refresh' => '<C-f>',
|
||||
'SelectNext' => ['<C-n>', '<C-j>', '<Down>'],
|
||||
'SelectPrev' => ['<C-p>', '<C-k>', '<Up>'],
|
||||
'ToggleFocus' => '<Tab>',
|
||||
}.each do |key, value|
|
||||
if override = get_list_or_string("g:CommandT#{key}Map")
|
||||
Array(override).each do |mapping|
|
||||
map mapping, key
|
||||
end
|
||||
else
|
||||
Array(value).each do |mapping|
|
||||
unless mapping == '<Esc>' && term =~ /\A(screen|xterm|vt100)/
|
||||
map mapping, key
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the desired maximum number of matches, based on available
|
||||
# vertical space and the g:CommandTMaxHeight option.
|
||||
def match_limit
|
||||
limit = VIM::Screen.lines - 5
|
||||
limit = 1 if limit < 0
|
||||
limit = [limit, max_height].min if max_height > 0
|
||||
limit
|
||||
end
|
||||
|
||||
def list_matches
|
||||
matches = @active_finder.sorted_matches_for @prompt.abbrev, :limit => match_limit
|
||||
@match_window.matches = matches
|
||||
end
|
||||
|
||||
def buffer_finder
|
||||
@buffer_finder ||= CommandT::BufferFinder.new
|
||||
end
|
||||
|
||||
def file_finder
|
||||
@file_finder ||= CommandT::FileFinder.new nil,
|
||||
:max_depth => get_number('g:CommandTMaxDepth'),
|
||||
:max_files => get_number('g:CommandTMaxFiles'),
|
||||
:max_caches => get_number('g:CommandTMaxCachedDirectories'),
|
||||
:always_show_dot_files => get_bool('g:CommandTAlwaysShowDotFiles'),
|
||||
:never_show_dot_files => get_bool('g:CommandTNeverShowDotFiles'),
|
||||
:scan_dot_directories => get_bool('g:CommandTScanDotDirectories')
|
||||
end
|
||||
|
||||
def jump_finder
|
||||
@jump_finder ||= CommandT::JumpFinder.new
|
||||
end
|
||||
|
||||
def tag_finder
|
||||
@tag_finder ||= CommandT::TagFinder.new \
|
||||
:include_filenames => get_bool('g:CommandTTagIncludeFilenames')
|
||||
end
|
||||
end # class Controller
|
||||
end # module commandT
|
||||
Loading…
Add table
Add a link
Reference in a new issue