diff --git a/.emacs.d/init.el b/.emacs.d/init.el index 878c5c4..d513b44 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -10,10 +10,10 @@ ;; There are many like it, but this one is mine. (custom-set-variables - ;; custom-set-variables was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. '(blink-matching-paren-dont-ignore-comments t) '(c-echo-syntactic-information-p t) '(c-indent-level 4) @@ -28,6 +28,7 @@ '(font-lock-support-mode (quote jit-lock-mode)) '(global-auto-revert-mode t) '(global-font-lock-mode t nil (font-lock)) + '(ido-enable-flex-matching t) '(ido-mode (quote both) nil (ido)) '(indent-tabs-mode nil) '(inhibit-startup-screen t) @@ -519,8 +520,8 @@ ;; have been thinking of something. ;; ================================================================= (custom-set-faces - ;; custom-set-faces was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. ) diff --git a/.gitignore b/.gitignore index 32766ea..b495a96 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,23 @@ .bash_history .bash_logout .bitcoin/ +Bitlocker/ +Calibre Library/ +CardMinder/ .cache/ .config/fish/fish_history .config/fish/fishd* .config/fish/generated_completions +Diablo III/ +DnD - 3.5/ +DnD - 4.0/ +DnD - Mesh/ +DnD/ +Doty Family/ +Downloads/ +.DS_Store +.gem/ +.gimp-2.6/ .histfile .ido.last .landscape/ @@ -16,13 +29,80 @@ .sickbeard/ .ssh/ .subversion/ +.thumbnails/ +.VirtualBox/ .w3m/ .zcompdump +Backup/ bifrost bin/ +go-ext/ newznab/ sabnzbd/ src/ test/ *~ +*.acdb +*.elc +*.docx +*.htm +*.exe +*.txt +*.rdp +*.xbel +*.xls +*.xlsm +*.xlsx +*.zip + +_viminfo + +Database1.accdb +Dungeon Tiles.vss +Endless Space/ +Expression/ +Fax/ +Fiddler2/ +IISExpress/ +Inform/ +John's Quicken Data.QDF-backup +KentuckyRouteZero/ +LINQPad Queries/ +Memoir Class Manual.pdf +My Games/ +My Kindle Content/ +My Received Files/ +My Shapes/ +My Sharing Folders.lnk +New folder/ +OneNote Notebooks/ +Playing.vsd +Protege-1996-1.pdf +Purchased/ +Quicken/ +SampleExplorer.Settings.xml +Saved Games/ +ScanSnap/ +Seesmic/ +Shared/ +Shiner/ +SimCity 4/ +Tales of the City/ +Taxes/ +Telltale Games/ +Thumbs.db +Tokens.vsd +VirtualBox VMs/ +Visual Studio 11/ +Visual Studio 2005/ +Visual Studio 2008/ +Visual Studio 2010/ +Visual Studio 2012/ +WorldWorks/ +backupcert.pfx +ddi/ +desktop.ini +lshort.pdf +notes +rallymaker/ diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..f0d4d99 --- /dev/null +++ b/.vimrc @@ -0,0 +1,93 @@ +" This is my .vimrc. Good times! +" It was shamelessly stolen from the sample .vimrc, because I have yet to have +" any good taste. + +" When started as "evim", evim.vim will already have done these settings. +if v:progname =~? "evim" + finish +endif + +" Use Vim settings, rather than Vi settings (much better!). +" This must be first, because it changes other options as a side effect. +set nocompatible + +" allow backspacing over everything in insert mode +set backspace=indent,eol,start + +if has("vms") + set nobackup " do not keep a backup file, use versions instead +else + set backup " keep a backup file +endif +set history=50 " keep 50 lines of command line history +set ruler " show the cursor position all the time +set showcmd " display incomplete commands +set incsearch " do incremental searching + +" For Win32 GUI: remove 't' flag from 'guioptions': no tearoff menu entries +" let &guioptions = substitute(&guioptions, "t", "", "g") + +" Don't use Ex mode, use Q for formatting +map Q gq + +" CTRL-U in insert mode deletes a lot. Use CTRL-G u to first break undo, +" so that you can undo CTRL-U after inserting a line break. +inoremap u + +" In many terminal emulators the mouse works just fine, thus enable it. +if has('mouse') + set mouse=a +endif + +" Switch syntax highlighting on, when the terminal has colors +" Also switch on highlighting the last used search pattern. +if &t_Co > 2 || has("gui_running") + syntax on + set hlsearch +endif + +" Only do this part when compiled with support for autocommands. +if has("autocmd") + + " Support for go + set rtp+=$GOROOT/misc/vim + + " Enable file type detection. + " Use the default filetype settings, so that mail gets 'tw' set to 72, + " 'cindent' is on in C files, etc. + " Also load indent files, to automatically do language-dependent indenting. + filetype plugin indent on + + " Put these in an autocmd group, so that we can delete them easily. + augroup vimrcEx + au! + + " For all text files set 'textwidth' to 78 characters. + autocmd FileType text setlocal textwidth=78 + + " When editing a file, always jump to the last known cursor position. + " Don't do it when the position is invalid or when inside an event handler + " (happens when dropping a file on gvim). + " Also don't do it when the mark is in the first line, that is the default + " position when opening a file. + autocmd BufReadPost * + \ if line("'\"") > 1 && line("'\"") <= line("$") | + \ exe "normal! g`\"" | + \ endif + + augroup END + +else + + set autoindent " always set autoindenting on + +endif " has("autocmd") + +" Convenient command to see the difference between the current buffer and the +" file it was loaded from, thus the changes you made. +" Only define it when not defined already. +if !exists(":DiffOrig") + command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis + \ | wincmd p | diffthis +endif + diff --git a/WindowsPowershell/Profile.ps1 b/WindowsPowershell/Profile.ps1 index f8291fe..fbc8e5a 100644 --- a/WindowsPowershell/Profile.ps1 +++ b/WindowsPowershell/Profile.ps1 @@ -184,3 +184,7 @@ function ConvertFrom-EKB($text) return $ekb } + +function ConvertFrom-Base64UTF8($base64) { + return [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($base64)) +} \ No newline at end of file diff --git a/_profile.ps1 b/_profile.ps1 new file mode 100644 index 0000000..9630b52 --- /dev/null +++ b/_profile.ps1 @@ -0,0 +1,43 @@ +# These bits of profile courtesy of http://winterdom.com/ +# +# http://winterdom.com/2008/01/modifyingthehomeinpowershell +# Set the $HOME variable for our use +# and make powershell recognize ~\ as $HOME +# in paths +# +set-variable -name HOME -value (resolve-path $env:Home) -force +(get-psprovider FileSystem).Home = $HOME + +# http://winterdom.com/2008/08/mypowershellprompt +function shorten-path([string] $path) +{ + $loc = $path.Replace($HOME, '~') + # remove prefix for UNC paths + $loc = $loc -replace '^[^:]+::', '' + # make path shorter like tabs in Vim, + # handle paths starting with \\ and . correctly + return ($loc -replace '\\(\.?)([^\\]{3})[^\\]*(?=\\)','\$1$2') +} + +function prompt +{ + # our theme + $cdelim = [ConsoleColor]::DarkCyan + $chost = [ConsoleColor]::Green + $cloc = [ConsoleColor]::Cyan + + write-host "$([char]0x0A7) " -n -f $cloc + write-host ([net.dns]::GetHostName()) -n -f $chost + write-host ' {' -n -f $cdelim + write-host (shorten-path (pwd).Path) -n -f $cloc + write-host '}' -n -f $cdelim + return ' ' +} + +function Get-JDHelp( + [switch] $Full, +[switch] $Detailed + +) +{ +} \ No newline at end of file diff --git a/vimfiles/.VimballRecord b/vimfiles/.VimballRecord new file mode 100644 index 0000000..d4e6c8a --- /dev/null +++ b/vimfiles/.VimballRecord @@ -0,0 +1 @@ +command-t-1.4.vba: call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/controller.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/extconf.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/finder/buffer_finder.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/finder/file_finder.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/finder/jump_finder.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/finder/tag_finder.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/finder.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/match_window.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/prompt.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/scanner/buffer_scanner.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/scanner/file_scanner.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/scanner/jump_scanner.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/scanner/tag_scanner.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/scanner.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/settings.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/stub.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/vim/path_utilities.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/vim/screen.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/vim/window.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/vim.rb')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/ext.c')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/match.c')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/matcher.c')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/ext.h')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/match.h')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/matcher.h')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/ruby_compat.h')|call delete('C:\Users\John\Documents\vimfiles/ruby/command-t/depend')|call delete('C:\Users\John\Documents\vimfiles/doc/command-t.txt')|call delete('C:\Users\John\Documents\vimfiles/plugin/command-t.vim') diff --git a/vimfiles/.netrwhist b/vimfiles/.netrwhist new file mode 100644 index 0000000..6d12145 --- /dev/null +++ b/vimfiles/.netrwhist @@ -0,0 +1,3 @@ +let g:netrw_dirhistmax =10 +let g:netrw_dirhist_cnt =1 +let g:netrw_dirhist_1='C:\src\Rama\RamaGo' diff --git a/vimfiles/doc/tags b/vimfiles/doc/tags new file mode 100644 index 0000000..5c398b9 --- /dev/null +++ b/vimfiles/doc/tags @@ -0,0 +1,51 @@ +:CommandT command-t.txt /*:CommandT* +:CommandTBuffer command-t.txt /*:CommandTBuffer* +:CommandTFlush command-t.txt /*:CommandTFlush* +:CommandTJumps command-t.txt /*:CommandTJumps* +:CommandTTag command-t.txt /*:CommandTTag* +command-t command-t.txt /*command-t* +command-t-authors command-t.txt /*command-t-authors* +command-t-commands command-t.txt /*command-t-commands* +command-t-contents command-t.txt /*command-t-contents* +command-t-development command-t.txt /*command-t-development* +command-t-donations command-t.txt /*command-t-donations* +command-t-history command-t.txt /*command-t-history* +command-t-installation command-t.txt /*command-t-installation* +command-t-intro command-t.txt /*command-t-intro* +command-t-license command-t.txt /*command-t-license* +command-t-mappings command-t.txt /*command-t-mappings* +command-t-options command-t.txt /*command-t-options* +command-t-pathogen command-t.txt /*command-t-pathogen* +command-t-requirements command-t.txt /*command-t-requirements* +command-t-trouble-shooting command-t.txt /*command-t-trouble-shooting* +command-t-usage command-t.txt /*command-t-usage* +command-t-website command-t.txt /*command-t-website* +command-t-wildignore command-t.txt /*command-t-wildignore* +command-t.txt command-t.txt /*command-t.txt* +g:CommandTAcceptSelectionMap command-t.txt /*g:CommandTAcceptSelectionMap* +g:CommandTAcceptSelectionSplitMap command-t.txt /*g:CommandTAcceptSelectionSplitMap* +g:CommandTAcceptSelectionTabMap command-t.txt /*g:CommandTAcceptSelectionTabMap* +g:CommandTAcceptSelectionVSplitMap command-t.txt /*g:CommandTAcceptSelectionVSplitMap* +g:CommandTAlwaysShowDotFiles command-t.txt /*g:CommandTAlwaysShowDotFiles* +g:CommandTBackspaceMap command-t.txt /*g:CommandTBackspaceMap* +g:CommandTCancelMap command-t.txt /*g:CommandTCancelMap* +g:CommandTClearMap command-t.txt /*g:CommandTClearMap* +g:CommandTCursorEndMap command-t.txt /*g:CommandTCursorEndMap* +g:CommandTCursorLeftMap command-t.txt /*g:CommandTCursorLeftMap* +g:CommandTCursorRightMap command-t.txt /*g:CommandTCursorRightMap* +g:CommandTCursorStartMap command-t.txt /*g:CommandTCursorStartMap* +g:CommandTDeleteMap command-t.txt /*g:CommandTDeleteMap* +g:CommandTMatchWindowAtTop command-t.txt /*g:CommandTMatchWindowAtTop* +g:CommandTMatchWindowReverse command-t.txt /*g:CommandTMatchWindowReverse* +g:CommandTMaxCachedDirectories command-t.txt /*g:CommandTMaxCachedDirectories* +g:CommandTMaxDepth command-t.txt /*g:CommandTMaxDepth* +g:CommandTMaxFiles command-t.txt /*g:CommandTMaxFiles* +g:CommandTMaxHeight command-t.txt /*g:CommandTMaxHeight* +g:CommandTMinHeight command-t.txt /*g:CommandTMinHeight* +g:CommandTNeverShowDotFiles command-t.txt /*g:CommandTNeverShowDotFiles* +g:CommandTRefreshMap command-t.txt /*g:CommandTRefreshMap* +g:CommandTScanDotDirectories command-t.txt /*g:CommandTScanDotDirectories* +g:CommandTSelectNextMap command-t.txt /*g:CommandTSelectNextMap* +g:CommandTSelectPrevMap command-t.txt /*g:CommandTSelectPrevMap* +g:CommandTTagIncludeFilenames command-t.txt /*g:CommandTTagIncludeFilenames* +g:CommandTToggleFocusMap command-t.txt /*g:CommandTToggleFocusMap* diff --git a/vimfiles/plugin/command-t.vim b/vimfiles/plugin/command-t.vim new file mode 100644 index 0000000..68cac9e --- /dev/null +++ b/vimfiles/plugin/command-t.vim @@ -0,0 +1,186 @@ +" command-t.vim +" 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. + +if exists("g:command_t_loaded") || &cp + finish +endif +let g:command_t_loaded = 1 + +command CommandTBuffer call CommandTShowBufferFinder() +command CommandTJump call CommandTShowJumpFinder() +command CommandTTag call CommandTShowTagFinder() +command -nargs=? -complete=dir CommandT call CommandTShowFileFinder() +command CommandTFlush call CommandTFlush() + +if !hasmapto(':CommandT') + silent! nnoremap t :CommandT +endif + +if !hasmapto(':CommandTBuffer') + silent! nnoremap b :CommandTBuffer +endif + +function s:CommandTRubyWarning() + echohl WarningMsg + echo "command-t.vim requires Vim to be compiled with Ruby support" + echo "For more information type: :help command-t" + echohl none +endfunction + +function s:CommandTShowBufferFinder() + if has('ruby') + ruby $command_t.show_buffer_finder + else + call s:CommandTRubyWarning() + endif +endfunction + +function s:CommandTShowFileFinder(arg) + if has('ruby') + ruby $command_t.show_file_finder + else + call s:CommandTRubyWarning() + endif +endfunction + +function s:CommandTShowJumpFinder() + if has('ruby') + ruby $command_t.show_jump_finder + else + call s:CommandTRubyWarning() + endif +endfunction + +function s:CommandTShowTagFinder() + if has('ruby') + ruby $command_t.show_tag_finder + else + call s:CommandTRubyWarning() + endif +endfunction + +function s:CommandTFlush() + if has('ruby') + ruby $command_t.flush + else + call s:CommandTRubyWarning() + endif +endfunction + +if !has('ruby') + finish +endif + +function CommandTHandleKey(arg) + ruby $command_t.handle_key +endfunction + +function CommandTBackspace() + ruby $command_t.backspace +endfunction + +function CommandTDelete() + ruby $command_t.delete +endfunction + +function CommandTAcceptSelection() + ruby $command_t.accept_selection +endfunction + +function CommandTAcceptSelectionTab() + ruby $command_t.accept_selection :command => 'tabe' +endfunction + +function CommandTAcceptSelectionSplit() + ruby $command_t.accept_selection :command => 'sp' +endfunction + +function CommandTAcceptSelectionVSplit() + ruby $command_t.accept_selection :command => 'vs' +endfunction + +function CommandTRefresh() + ruby $command_t.refresh +endfunction + +function CommandTToggleFocus() + ruby $command_t.toggle_focus +endfunction + +function CommandTCancel() + ruby $command_t.cancel +endfunction + +function CommandTSelectNext() + ruby $command_t.select_next +endfunction + +function CommandTSelectPrev() + ruby $command_t.select_prev +endfunction + +function CommandTClear() + ruby $command_t.clear +endfunction + +function CommandTCursorLeft() + ruby $command_t.cursor_left +endfunction + +function CommandTCursorRight() + ruby $command_t.cursor_right +endfunction + +function CommandTCursorEnd() + ruby $command_t.cursor_end +endfunction + +function CommandTCursorStart() + ruby $command_t.cursor_start +endfunction + +ruby << EOF + # require Ruby files + begin + # prepare controller + require 'command-t/vim' + require 'command-t/controller' + $command_t = CommandT::Controller.new + rescue LoadError + load_path_modified = false + ::VIM::evaluate('&runtimepath').to_s.split(',').each do |path| + lib = "#{path}/ruby" + if !$LOAD_PATH.include?(lib) and File.exist?(lib) + $LOAD_PATH << lib + load_path_modified = true + end + end + retry if load_path_modified + + # could get here if C extension was not compiled, or was compiled + # for the wrong architecture or Ruby version + require 'command-t/stub' + $command_t = CommandT::Stub.new + end +EOF diff --git a/vimfiles/ruby/command-t/controller.rb b/vimfiles/ruby/command-t/controller.rb new file mode 100644 index 0000000..365f802 --- /dev/null +++ b/vimfiles/ruby/command-t/controller.rb @@ -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 #{key} " \ + ":call CommandT#{function}(#{param})" + 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 "", 'HandleKey', b + end + + # "special" keys (overridable by settings) + { + 'AcceptSelection' => '', + 'AcceptSelectionSplit' => ['', ''], + 'AcceptSelectionTab' => '', + 'AcceptSelectionVSplit' => '', + 'Backspace' => '', + 'Cancel' => ['', ''], + 'Clear' => '', + 'CursorEnd' => '', + 'CursorLeft' => ['', ''], + 'CursorRight' => ['', ''], + 'CursorStart' => '', + 'Delete' => '', + 'Refresh' => '', + 'SelectNext' => ['', '', ''], + 'SelectPrev' => ['', '', ''], + 'ToggleFocus' => '', + }.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 == '' && 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 diff --git a/vimfiles/ruby/command-t/depend b/vimfiles/ruby/command-t/depend new file mode 100644 index 0000000..bfa9552 --- /dev/null +++ b/vimfiles/ruby/command-t/depend @@ -0,0 +1,24 @@ +# Copyright 2010 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. + +CFLAGS += -std=c99 -Wall -Wextra -Wno-unused-parameter diff --git a/vimfiles/ruby/command-t/ext.c b/vimfiles/ruby/command-t/ext.c new file mode 100644 index 0000000..c5026cc --- /dev/null +++ b/vimfiles/ruby/command-t/ext.c @@ -0,0 +1,65 @@ +// Copyright 2010 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. + +#include "match.h" +#include "matcher.h" + +VALUE mCommandT = 0; // module CommandT +VALUE cCommandTMatch = 0; // class CommandT::Match +VALUE cCommandTMatcher = 0; // class CommandT::Matcher + +VALUE CommandT_option_from_hash(const char *option, VALUE hash) +{ + if (NIL_P(hash)) + return Qnil; + VALUE key = ID2SYM(rb_intern(option)); + if (rb_funcall(hash, rb_intern("has_key?"), 1, key) == Qtrue) + return rb_hash_aref(hash, key); + else + return Qnil; +} + +void Init_ext() +{ + // module CommandT + mCommandT = rb_define_module("CommandT"); + + // class CommandT::Match + cCommandTMatch = rb_define_class_under(mCommandT, "Match", rb_cObject); + + // methods + rb_define_method(cCommandTMatch, "initialize", CommandTMatch_initialize, -1); + rb_define_method(cCommandTMatch, "matches?", CommandTMatch_matches, 0); + rb_define_method(cCommandTMatch, "to_s", CommandTMatch_to_s, 0); + + // attributes + rb_define_attr(cCommandTMatch, "score", Qtrue, Qfalse); // reader: true, writer: false + + // class CommandT::Matcher + cCommandTMatcher = rb_define_class_under(mCommandT, "Matcher", rb_cObject); + + // methods + rb_define_method(cCommandTMatcher, "initialize", CommandTMatcher_initialize, -1); + rb_define_method(cCommandTMatcher, "sorted_matches_for", CommandTMatcher_sorted_matches_for, 2); + rb_define_method(cCommandTMatcher, "matches_for", CommandTMatcher_matches_for, 1); +} diff --git a/vimfiles/ruby/command-t/ext.h b/vimfiles/ruby/command-t/ext.h new file mode 100644 index 0000000..89ff076 --- /dev/null +++ b/vimfiles/ruby/command-t/ext.h @@ -0,0 +1,36 @@ +// Copyright 2010 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. + +#include + +extern VALUE mCommandT; // module CommandT +extern VALUE cCommandTMatch; // class CommandT::Match +extern VALUE cCommandTMatcher; // class CommandT::Matcher + +// Encapsulates common pattern of checking for an option in an optional +// options hash. The hash itself may be nil, but an exception will be +// raised if it is not nil and not a hash. +VALUE CommandT_option_from_hash(const char *option, VALUE hash); + +// Debugging macro. +#define ruby_inspect(obj) rb_funcall(rb_mKernel, rb_intern("p"), 1, obj) diff --git a/vimfiles/ruby/command-t/extconf.rb b/vimfiles/ruby/command-t/extconf.rb new file mode 100644 index 0000000..9d2bfb3 --- /dev/null +++ b/vimfiles/ruby/command-t/extconf.rb @@ -0,0 +1,34 @@ +# Copyright 2010 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 'mkmf' + +def missing item + puts "couldn't find #{item} (required)" + exit 1 +end + +RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] + +have_header('ruby.h') or missing('ruby.h') +create_makefile('ext') diff --git a/vimfiles/ruby/command-t/finder.rb b/vimfiles/ruby/command-t/finder.rb new file mode 100644 index 0000000..ff731a0 --- /dev/null +++ b/vimfiles/ruby/command-t/finder.rb @@ -0,0 +1,54 @@ +# 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/ext' # CommandT::Matcher + +module CommandT + # Encapsulates a Scanner instance (which builds up a list of available files + # in a directory) and a Matcher instance (which selects from that list based + # on a search string). + # + # Specialized subclasses use different kinds of scanners adapted for + # different kinds of search (files, buffers). + class Finder + include VIM::PathUtilities + + def initialize path = Dir.pwd, options = {} + raise RuntimeError, 'Subclass responsibility' + end + + # Options: + # :limit (integer): limit the number of returned matches + def sorted_matches_for str, options = {} + @matcher.sorted_matches_for str, options + end + + def open_selection command, selection, options = {} + ::VIM::command "silent #{command} #{selection}" + end + + def path= path + @scanner.path = path + end + end # class Finder +end # CommandT diff --git a/vimfiles/ruby/command-t/finder/buffer_finder.rb b/vimfiles/ruby/command-t/finder/buffer_finder.rb new file mode 100644 index 0000000..2319c24 --- /dev/null +++ b/vimfiles/ruby/command-t/finder/buffer_finder.rb @@ -0,0 +1,35 @@ +# Copyright 2010-2011 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/ext' # CommandT::Matcher +require 'command-t/scanner/buffer_scanner' +require 'command-t/finder' + +module CommandT + class BufferFinder < Finder + def initialize + @scanner = BufferScanner.new + @matcher = Matcher.new @scanner, :always_show_dot_files => true + end + end # class BufferFinder +end # CommandT diff --git a/vimfiles/ruby/command-t/finder/file_finder.rb b/vimfiles/ruby/command-t/finder/file_finder.rb new file mode 100644 index 0000000..03d637b --- /dev/null +++ b/vimfiles/ruby/command-t/finder/file_finder.rb @@ -0,0 +1,39 @@ +# 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/ext' # CommandT::Matcher +require 'command-t/finder' +require 'command-t/scanner/file_scanner' + +module CommandT + class FileFinder < Finder + def initialize path = Dir.pwd, options = {} + @scanner = FileScanner.new path, options + @matcher = Matcher.new @scanner, options + end + + def flush + @scanner.flush + end + end # class FileFinder +end # CommandT diff --git a/vimfiles/ruby/command-t/finder/jump_finder.rb b/vimfiles/ruby/command-t/finder/jump_finder.rb new file mode 100644 index 0000000..19f6c09 --- /dev/null +++ b/vimfiles/ruby/command-t/finder/jump_finder.rb @@ -0,0 +1,35 @@ +# Copyright 2011 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/ext' # CommandT::Matcher +require 'command-t/scanner/jump_scanner' +require 'command-t/finder' + +module CommandT + class JumpFinder < Finder + def initialize + @scanner = JumpScanner.new + @matcher = Matcher.new @scanner, :always_show_dot_files => true + end + end # class JumpFinder +end # module CommandT diff --git a/vimfiles/ruby/command-t/finder/tag_finder.rb b/vimfiles/ruby/command-t/finder/tag_finder.rb new file mode 100644 index 0000000..66777ee --- /dev/null +++ b/vimfiles/ruby/command-t/finder/tag_finder.rb @@ -0,0 +1,44 @@ +# Copyright 2011-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/ext' # CommandT::Matcher +require 'command-t/scanner/tag_scanner' +require 'command-t/finder' + +module CommandT + class TagFinder < Finder + def initialize options = {} + @scanner = TagScanner.new options + @matcher = Matcher.new @scanner, :always_show_dot_files => true + end + + def open_selection command, selection, options = {} + if @scanner.include_filenames + selection = selection[0, selection.index(':')] + end + + # open the tag and center the screen on it + ::VIM::command "silent! tag #{selection} | :normal zz" + end + end # class TagFinder +end # module CommandT diff --git a/vimfiles/ruby/command-t/match.c b/vimfiles/ruby/command-t/match.c new file mode 100644 index 0000000..e32fb0b --- /dev/null +++ b/vimfiles/ruby/command-t/match.c @@ -0,0 +1,189 @@ +// Copyright 2010 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. + +#include "match.h" +#include "ext.h" +#include "ruby_compat.h" + +// use a struct to make passing params during recursion easier +typedef struct +{ + char *str_p; // pointer to string to be searched + long str_len; // length of same + char *abbrev_p; // pointer to search string (abbreviation) + long abbrev_len; // length of same + double max_score_per_char; + int dot_file; // boolean: true if str is a dot-file + int always_show_dot_files; // boolean + int never_show_dot_files; // boolean +} matchinfo_t; + +double recursive_match(matchinfo_t *m, // sharable meta-data + long str_idx, // where in the path string to start + long abbrev_idx, // where in the search string to start + long last_idx, // location of last matched character + double score) // cumulative score so far +{ + double seen_score = 0; // remember best score seen via recursion + int dot_file_match = 0; // true if abbrev matches a dot-file + int dot_search = 0; // true if searching for a dot + + for (long i = abbrev_idx; i < m->abbrev_len; i++) + { + char c = m->abbrev_p[i]; + if (c == '.') + dot_search = 1; + int found = 0; + for (long j = str_idx; j < m->str_len; j++, str_idx++) + { + char d = m->str_p[j]; + if (d == '.') + { + if (j == 0 || m->str_p[j - 1] == '/') + { + m->dot_file = 1; // this is a dot-file + if (dot_search) // and we are searching for a dot + dot_file_match = 1; // so this must be a match + } + } + else if (d >= 'A' && d <= 'Z') + d += 'a' - 'A'; // add 32 to downcase + if (c == d) + { + found = 1; + dot_search = 0; + + // calculate score + double score_for_char = m->max_score_per_char; + long distance = j - last_idx; + if (distance > 1) + { + double factor = 1.0; + char last = m->str_p[j - 1]; + char curr = m->str_p[j]; // case matters, so get again + if (last == '/') + factor = 0.9; + else if (last == '-' || + last == '_' || + last == ' ' || + (last >= '0' && last <= '9')) + factor = 0.8; + else if (last >= 'a' && last <= 'z' && + curr >= 'A' && curr <= 'Z') + factor = 0.8; + else if (last == '.') + factor = 0.7; + else + // if no "special" chars behind char, factor diminishes + // as distance from last matched char increases + factor = (1.0 / distance) * 0.75; + score_for_char *= factor; + } + + if (++j < m->str_len) + { + // bump cursor one char to the right and + // use recursion to try and find a better match + double sub_score = recursive_match(m, j, i, last_idx, score); + if (sub_score > seen_score) + seen_score = sub_score; + } + + score += score_for_char; + last_idx = str_idx++; + break; + } + } + if (!found) + return 0.0; + } + if (m->dot_file) + { + if (m->never_show_dot_files || + (!dot_file_match && !m->always_show_dot_files)) + return 0.0; + } + return (score > seen_score) ? score : seen_score; +} + +// Match.new abbrev, string, options = {} +VALUE CommandTMatch_initialize(int argc, VALUE *argv, VALUE self) +{ + // process arguments: 2 mandatory, 1 optional + VALUE str, abbrev, options; + if (rb_scan_args(argc, argv, "21", &str, &abbrev, &options) == 2) + options = Qnil; + str = StringValue(str); + abbrev = StringValue(abbrev); // already downcased by caller + + // check optional options hash for overrides + VALUE always_show_dot_files = CommandT_option_from_hash("always_show_dot_files", options); + VALUE never_show_dot_files = CommandT_option_from_hash("never_show_dot_files", options); + + matchinfo_t m; + m.str_p = RSTRING_PTR(str); + m.str_len = RSTRING_LEN(str); + m.abbrev_p = RSTRING_PTR(abbrev); + m.abbrev_len = RSTRING_LEN(abbrev); + m.max_score_per_char = (1.0 / m.str_len + 1.0 / m.abbrev_len) / 2; + m.dot_file = 0; + m.always_show_dot_files = always_show_dot_files == Qtrue; + m.never_show_dot_files = never_show_dot_files == Qtrue; + + // calculate score + double score = 1.0; + if (m.abbrev_len == 0) // special case for zero-length search string + { + // filter out dot files + if (!m.always_show_dot_files) + { + for (long i = 0; i < m.str_len; i++) + { + char c = m.str_p[i]; + if (c == '.' && (i == 0 || m.str_p[i - 1] == '/')) + { + score = 0.0; + break; + } + } + } + } + else // normal case + score = recursive_match(&m, 0, 0, 0, 0.0); + + // clean-up and final book-keeping + rb_iv_set(self, "@score", rb_float_new(score)); + rb_iv_set(self, "@str", str); + return Qnil; +} + +VALUE CommandTMatch_matches(VALUE self) +{ + double score = NUM2DBL(rb_iv_get(self, "@score")); + return score > 0 ? Qtrue : Qfalse; +} + +VALUE CommandTMatch_to_s(VALUE self) +{ + return rb_iv_get(self, "@str"); +} diff --git a/vimfiles/ruby/command-t/match.h b/vimfiles/ruby/command-t/match.h new file mode 100644 index 0000000..c3ce929 --- /dev/null +++ b/vimfiles/ruby/command-t/match.h @@ -0,0 +1,29 @@ +// Copyright 2010 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. + +#include + +extern VALUE CommandTMatch_initialize(int argc, VALUE *argv, VALUE self); +extern VALUE CommandTMatch_matches(VALUE self); +extern VALUE CommandTMatch_score(VALUE self); +extern VALUE CommandTMatch_to_s(VALUE self); diff --git a/vimfiles/ruby/command-t/match_window.rb b/vimfiles/ruby/command-t/match_window.rb new file mode 100644 index 0000000..bda7fb1 --- /dev/null +++ b/vimfiles/ruby/command-t/match_window.rb @@ -0,0 +1,445 @@ +# 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 'ostruct' +require 'command-t/settings' + +module CommandT + class MatchWindow + SELECTION_MARKER = '> ' + MARKER_LENGTH = SELECTION_MARKER.length + UNSELECTED_MARKER = ' ' * MARKER_LENGTH + MH_START = '' + MH_END = '' + @@buffer = nil + + def initialize options = {} + @prompt = options[:prompt] + @reverse_list = options[:match_window_reverse] + @min_height = options[:min_height] + + # save existing window dimensions so we can restore them later + @windows = [] + (0..(::VIM::Window.count - 1)).each do |i| + @windows << OpenStruct.new(:index => i, + :height => ::VIM::Window[i].height, + :width => ::VIM::Window[i].width) + end + + # global settings (must manually save and restore) + @settings = Settings.new + ::VIM::set_option 'timeout' # ensure mappings timeout + ::VIM::set_option 'timeoutlen=0' # respond immediately to mappings + ::VIM::set_option 'nohlsearch' # don't highlight search strings + ::VIM::set_option 'noinsertmode' # don't make Insert mode the default + ::VIM::set_option 'noshowcmd' # don't show command info on last line + ::VIM::set_option 'report=9999' # don't show "X lines changed" reports + ::VIM::set_option 'sidescroll=0' # don't sidescroll in jumps + ::VIM::set_option 'sidescrolloff=0' # don't sidescroll automatically + ::VIM::set_option 'noequalalways' # don't auto-balance window sizes + + # show match window + split_location = options[:match_window_at_top] ? 'topleft' : 'botright' + if @@buffer # still have buffer from last time + ::VIM::command "silent! #{split_location} #{@@buffer.number}sbuffer" + raise "Can't re-open GoToFile buffer" unless $curbuf.number == @@buffer.number + $curwin.height = 1 + else # creating match window for first time and set it up + split_command = "silent! #{split_location} 1split GoToFile" + [ + split_command, + 'setlocal bufhidden=unload', # unload buf when no longer displayed + 'setlocal buftype=nofile', # buffer is not related to any file + 'setlocal nomodifiable', # prevent manual edits + 'setlocal noswapfile', # don't create a swapfile + 'setlocal nowrap', # don't soft-wrap + 'setlocal nonumber', # don't show line numbers + 'setlocal nolist', # don't use List mode (visible tabs etc) + 'setlocal foldcolumn=0', # don't show a fold column at side + 'setlocal foldlevel=99', # don't fold anything + 'setlocal nocursorline', # don't highlight line cursor is on + 'setlocal nospell', # spell-checking off + 'setlocal nobuflisted', # don't show up in the buffer list + 'setlocal textwidth=0' # don't hard-wrap (break long lines) + ].each { |command| ::VIM::command command } + + # don't show the color column + ::VIM::command 'setlocal colorcolumn=0' if VIM::exists?('+colorcolumn') + + # don't show relative line numbers + ::VIM::command 'setlocal norelativenumber' if VIM::exists?('+relativenumber') + + # sanity check: make sure the buffer really was created + raise "Can't find GoToFile buffer" unless $curbuf.name.match /GoToFile\z/ + @@buffer = $curbuf + end + + # syntax coloring + if VIM::has_syntax? + ::VIM::command "syntax match CommandTSelection \"^#{SELECTION_MARKER}.\\+$\"" + ::VIM::command 'syntax match CommandTNoEntries "^-- NO MATCHES --$"' + ::VIM::command 'syntax match CommandTNoEntries "^-- NO SUCH FILE OR DIRECTORY --$"' + ::VIM::command 'setlocal synmaxcol=9999' + + if VIM::has_conceal? + ::VIM::command 'setlocal conceallevel=2' + ::VIM::command 'setlocal concealcursor=nvic' + ::VIM::command 'syntax region CommandTCharMatched ' \ + "matchgroup=CommandTCharMatched start=+#{MH_START}+ " \ + "matchgroup=CommandTCharMatchedEnd end=+#{MH_END}+ concealends" + ::VIM::command 'highlight def CommandTCharMatched ' \ + 'term=bold,underline cterm=bold,underline ' \ + 'gui=bold,underline' + end + + ::VIM::command 'highlight link CommandTSelection Visual' + ::VIM::command 'highlight link CommandTNoEntries Error' + ::VIM::evaluate 'clearmatches()' + + # hide cursor + @cursor_highlight = get_cursor_highlight + hide_cursor + end + + # perform cleanup using an autocmd to ensure we don't get caught out + # by some unexpected means of dismissing or leaving the Command-T window + # (eg. , etc) + ::VIM::command 'autocmd! * ' + ::VIM::command 'autocmd BufLeave silent! ruby $command_t.leave' + ::VIM::command 'autocmd BufUnload silent! ruby $command_t.unload' + + @has_focus = false + @selection = nil + @abbrev = '' + @window = $curwin + end + + def close + # Unlisted buffers like those provided by Netrw, NERDTree and Vim's help + # don't actually appear in the buffer list; if they are the only such + # buffers present when Command-T is invoked (for example, when invoked + # immediately after starting Vim with a directory argument, like `vim .`) + # then performing the normal clean-up will yield an "E90: Cannot unload + # last buffer" error. We can work around that by doing a :quit first. + if ::VIM::Buffer.count == 0 + ::VIM::command 'silent quit' + end + + # Workaround for upstream bug in Vim 7.3 on some platforms + # + # On some platforms, $curbuf.number always returns 0. One workaround is + # to build Vim with --disable-largefile, but as this is producing lots of + # support requests, implement the following fallback to the buffer name + # instead, at least until upstream gets fixed. + # + # For more details, see: https://wincent.com/issues/1617 + if $curbuf.number == 0 + # use bwipeout as bunload fails if passed the name of a hidden buffer + ::VIM::command 'silent! bwipeout! GoToFile' + @@buffer = nil + else + ::VIM::command "silent! bunload! #{@@buffer.number}" + end + end + + def leave + close + unload + end + + def unload + restore_window_dimensions + @settings.restore + @prompt.dispose + show_cursor + end + + def add! char + @abbrev += char + end + + def backspace! + @abbrev.chop! + end + + def select_next + if @selection < @matches.length - 1 + @selection += 1 + print_match(@selection - 1) # redraw old selection (removes marker) + print_match(@selection) # redraw new selection (adds marker) + move_cursor_to_selected_line + else + # (possibly) loop or scroll + end + end + + def select_prev + if @selection > 0 + @selection -= 1 + print_match(@selection + 1) # redraw old selection (removes marker) + print_match(@selection) # redraw new selection (adds marker) + move_cursor_to_selected_line + else + # (possibly) loop or scroll + end + end + + def matches= matches + matches = matches.reverse if @reverse_list + if matches != @matches + @matches = matches + @selection = @reverse_list ? @matches.length - 1 : 0 + print_matches + move_cursor_to_selected_line + end + end + + def focus + unless @has_focus + @has_focus = true + if VIM::has_syntax? + ::VIM::command 'highlight link CommandTSelection Search' + end + end + end + + def unfocus + if @has_focus + @has_focus = false + if VIM::has_syntax? + ::VIM::command 'highlight link CommandTSelection Visual' + end + end + end + + def find char + # is this a new search or the continuation of a previous one? + now = Time.now + if @last_key_time.nil? or @last_key_time < (now - 0.5) + @find_string = char + else + @find_string += char + end + @last_key_time = now + + # see if there's anything up ahead that matches + @matches.each_with_index do |match, idx| + if match[0, @find_string.length].casecmp(@find_string) == 0 + old_selection = @selection + @selection = idx + print_match(old_selection) # redraw old selection (removes marker) + print_match(@selection) # redraw new selection (adds marker) + break + end + end + end + + # Returns the currently selected item as a String. + def selection + @matches[@selection] + end + + def print_no_such_file_or_directory + print_error 'NO SUCH FILE OR DIRECTORY' + end + + private + + def move_cursor_to_selected_line + # on some non-GUI terminals, the cursor doesn't hide properly + # so we move the cursor to prevent it from blinking away in the + # upper-left corner in a distracting fashion + @window.cursor = [@selection + 1, 0] + end + + def print_error msg + return unless VIM::Window.select(@window) + unlock + clear + @window.height = @min_height > 0 ? @min_height : 1 + @@buffer[1] = "-- #{msg} --" + lock + end + + def restore_window_dimensions + # sort from tallest to shortest, tie-breaking on window width + @windows.sort! do |a, b| + order = b.height <=> a.height + if order.zero? + b.width <=> a.width + else + order + end + end + + # starting with the tallest ensures that there are no constraints + # preventing windows on the side of vertical splits from regaining + # their original full size + @windows.each do |w| + # beware: window may be nil + if window = ::VIM::Window[w.index] + window.height = w.height + window.width = w.width + end + end + end + + def match_text_for_idx idx + match = truncated_match @matches[idx].to_s + if idx == @selection + prefix = SELECTION_MARKER + suffix = padding_for_selected_match match + else + if VIM::has_syntax? && VIM::has_conceal? + match = match_with_syntax_highlight match + end + prefix = UNSELECTED_MARKER + suffix = '' + end + prefix + match + suffix + end + + # Highlight matching characters within the matched string. + # + # Note that this is only approximate; it will highlight the first matching + # instances within the string, which may not actually be the instances that + # were used by the matching/scoring algorithm to determine the best score + # for the match. + # + def match_with_syntax_highlight match + highlight_chars = @prompt.abbrev.downcase.chars.to_a + match.chars.inject([]) do |output, char| + if char.downcase == highlight_chars.first + highlight_chars.shift + output.concat [MH_START, char, MH_END] + else + output << char + end + end.join + end + + # Print just the specified match. + def print_match idx + return unless VIM::Window.select(@window) + unlock + @@buffer[idx + 1] = match_text_for_idx idx + lock + end + + # Print all matches. + def print_matches + match_count = @matches.length + if match_count == 0 + print_error 'NO MATCHES' + else + return unless VIM::Window.select(@window) + unlock + clear + actual_lines = 1 + @window_width = @window.width # update cached value + max_lines = VIM::Screen.lines - 5 + max_lines = 1 if max_lines < 0 + actual_lines = match_count < @min_height ? @min_height : match_count + actual_lines = max_lines if actual_lines > max_lines + @window.height = actual_lines + (1..actual_lines).each do |line| + idx = line - 1 + if @@buffer.count >= line + @@buffer[line] = match_text_for_idx idx + else + @@buffer.append line - 1, match_text_for_idx(idx) + end + end + lock + end + end + + # Prepare padding for match text (trailing spaces) so that selection + # highlighting extends all the way to the right edge of the window. + def padding_for_selected_match str + len = str.length + if len >= @window_width - MARKER_LENGTH + '' + else + ' ' * (@window_width - MARKER_LENGTH - len) + end + end + + # Convert "really/long/path" into "really...path" based on available + # window width. + def truncated_match str + len = str.length + available_width = @window_width - MARKER_LENGTH + return str if len <= available_width + left = (available_width / 2) - 1 + right = (available_width / 2) - 2 + (available_width % 2) + str[0, left] + '...' + str[-right, right] + end + + def clear + # range = % (whole buffer) + # action = d (delete) + # register = _ (black hole register, don't record deleted text) + ::VIM::command 'silent %d _' + end + + def get_cursor_highlight + # there are 3 possible formats to check for, each needing to be + # transformed in a certain way in order to reapply the highlight: + # Cursor xxx guifg=bg guibg=fg -> :hi! Cursor guifg=bg guibg=fg + # Cursor xxx links to SomethingElse -> :hi! link Cursor SomethingElse + # Cursor xxx cleared -> :hi! clear Cursor + highlight = VIM::capture 'silent! 0verbose highlight Cursor' + + if highlight =~ /^Cursor\s+xxx\s+links to (\w+)/ + "link Cursor #{$~[1]}" + elsif highlight =~ /^Cursor\s+xxx\s+cleared/ + 'clear Cursor' + elsif highlight =~ /Cursor\s+xxx\s+(.+)/ + "Cursor #{$~[1]}" + else # likely cause E411 Cursor highlight group not found + nil + end + end + + def hide_cursor + if @cursor_highlight + ::VIM::command 'highlight Cursor NONE' + end + end + + def show_cursor + if @cursor_highlight + ::VIM::command "highlight #{@cursor_highlight}" + end + end + + def lock + ::VIM::command 'setlocal nomodifiable' + end + + def unlock + ::VIM::command 'setlocal modifiable' + end + end +end diff --git a/vimfiles/ruby/command-t/matcher.c b/vimfiles/ruby/command-t/matcher.c new file mode 100644 index 0000000..7cd8a3e --- /dev/null +++ b/vimfiles/ruby/command-t/matcher.c @@ -0,0 +1,164 @@ +// Copyright 2010 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. + +#include /* for qsort() */ +#include /* for strcmp() */ +#include "matcher.h" +#include "ext.h" +#include "ruby_compat.h" + +// comparison function for use with qsort +int comp_alpha(const void *a, const void *b) +{ + VALUE a_val = *(VALUE *)a; + VALUE b_val = *(VALUE *)b; + ID to_s = rb_intern("to_s"); + + VALUE a_str = rb_funcall(a_val, to_s, 0); + VALUE b_str = rb_funcall(b_val, to_s, 0); + char *a_p = RSTRING_PTR(a_str); + long a_len = RSTRING_LEN(a_str); + char *b_p = RSTRING_PTR(b_str); + long b_len = RSTRING_LEN(b_str); + int order = 0; + if (a_len > b_len) + { + order = strncmp(a_p, b_p, b_len); + if (order == 0) + order = 1; // shorter string (b) wins + } + else if (a_len < b_len) + { + order = strncmp(a_p, b_p, a_len); + if (order == 0) + order = -1; // shorter string (a) wins + } + else + order = strncmp(a_p, b_p, a_len); + return order; +} + +// comparison function for use with qsort +int comp_score(const void *a, const void *b) +{ + VALUE a_val = *(VALUE *)a; + VALUE b_val = *(VALUE *)b; + ID score = rb_intern("score"); + double a_score = RFLOAT_VALUE(rb_funcall(a_val, score, 0)); + double b_score = RFLOAT_VALUE(rb_funcall(b_val, score, 0)); + if (a_score > b_score) + return -1; // a scores higher, a should appear sooner + else if (a_score < b_score) + return 1; // b scores higher, a should appear later + else + return comp_alpha(a, b); +} + +VALUE CommandTMatcher_initialize(int argc, VALUE *argv, VALUE self) +{ + // process arguments: 1 mandatory, 1 optional + VALUE scanner, options; + if (rb_scan_args(argc, argv, "11", &scanner, &options) == 1) + options = Qnil; + if (NIL_P(scanner)) + rb_raise(rb_eArgError, "nil scanner"); + rb_iv_set(self, "@scanner", scanner); + + // check optional options hash for overrides + VALUE always_show_dot_files = CommandT_option_from_hash("always_show_dot_files", options); + if (always_show_dot_files != Qtrue) + always_show_dot_files = Qfalse; + VALUE never_show_dot_files = CommandT_option_from_hash("never_show_dot_files", options); + if (never_show_dot_files != Qtrue) + never_show_dot_files = Qfalse; + rb_iv_set(self, "@always_show_dot_files", always_show_dot_files); + rb_iv_set(self, "@never_show_dot_files", never_show_dot_files); + return Qnil; +} + +VALUE CommandTMatcher_sorted_matches_for(VALUE self, VALUE abbrev, VALUE options) +{ + // process optional options hash + VALUE limit_option = CommandT_option_from_hash("limit", options); + + // get unsorted matches + VALUE matches = CommandTMatcher_matches_for(self, abbrev); + + abbrev = StringValue(abbrev); + if (RSTRING_LEN(abbrev) == 0 || + (RSTRING_LEN(abbrev) == 1 && RSTRING_PTR(abbrev)[0] == '.')) + // alphabetic order if search string is only "" or "." + qsort(RARRAY_PTR(matches), RARRAY_LEN(matches), sizeof(VALUE), comp_alpha); + else + // for all other non-empty search strings, sort by score + qsort(RARRAY_PTR(matches), RARRAY_LEN(matches), sizeof(VALUE), comp_score); + + // apply optional limit option + long limit = NIL_P(limit_option) ? 0 : NUM2LONG(limit_option); + if (limit == 0 || RARRAY_LEN(matches) < limit) + limit = RARRAY_LEN(matches); + + // will return an array of strings, not an array of Match objects + for (long i = 0; i < limit; i++) + { + VALUE str = rb_funcall(RARRAY_PTR(matches)[i], rb_intern("to_s"), 0); + RARRAY_PTR(matches)[i] = str; + } + + // trim off any items beyond the limit + if (limit < RARRAY_LEN(matches)) + (void)rb_funcall(matches, rb_intern("slice!"), 2, LONG2NUM(limit), + LONG2NUM(RARRAY_LEN(matches) - limit)); + return matches; +} + +VALUE CommandTMatcher_matches_for(VALUE self, VALUE abbrev) +{ + if (NIL_P(abbrev)) + rb_raise(rb_eArgError, "nil abbrev"); + VALUE matches = rb_ary_new(); + VALUE scanner = rb_iv_get(self, "@scanner"); + VALUE always_show_dot_files = rb_iv_get(self, "@always_show_dot_files"); + VALUE never_show_dot_files = rb_iv_get(self, "@never_show_dot_files"); + VALUE options = Qnil; + if (always_show_dot_files == Qtrue) + { + options = rb_hash_new(); + rb_hash_aset(options, ID2SYM(rb_intern("always_show_dot_files")), always_show_dot_files); + } + else if (never_show_dot_files == Qtrue) + { + options = rb_hash_new(); + rb_hash_aset(options, ID2SYM(rb_intern("never_show_dot_files")), never_show_dot_files); + } + abbrev = rb_funcall(abbrev, rb_intern("downcase"), 0); + VALUE paths = rb_funcall(scanner, rb_intern("paths"), 0); + for (long i = 0, max = RARRAY_LEN(paths); i < max; i++) + { + VALUE path = RARRAY_PTR(paths)[i]; + VALUE match = rb_funcall(cCommandTMatch, rb_intern("new"), 3, path, abbrev, options); + if (rb_funcall(match, rb_intern("matches?"), 0) == Qtrue) + rb_funcall(matches, rb_intern("push"), 1, match); + } + return matches; +} diff --git a/vimfiles/ruby/command-t/matcher.h b/vimfiles/ruby/command-t/matcher.h new file mode 100644 index 0000000..6207e37 --- /dev/null +++ b/vimfiles/ruby/command-t/matcher.h @@ -0,0 +1,30 @@ +// Copyright 2010 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. + +#include + +extern VALUE CommandTMatcher_initialize(int argc, VALUE *argv, VALUE self); +extern VALUE CommandTMatcher_sorted_matches_for(VALUE self, VALUE abbrev, VALUE options); + +// most likely the function will be subsumed by the sorted_matcher_for function +extern VALUE CommandTMatcher_matches_for(VALUE self, VALUE abbrev); diff --git a/vimfiles/ruby/command-t/prompt.rb b/vimfiles/ruby/command-t/prompt.rb new file mode 100644 index 0000000..743e873 --- /dev/null +++ b/vimfiles/ruby/command-t/prompt.rb @@ -0,0 +1,165 @@ +# Copyright 2010 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. + +module CommandT + # Abuse the status line as a prompt. + class Prompt + attr_accessor :abbrev + + def initialize + @abbrev = '' # abbreviation entered so far + @col = 0 # cursor position + @has_focus = false + end + + # Erase whatever is displayed in the prompt line, + # effectively disposing of the prompt + def dispose + ::VIM::command 'echo' + ::VIM::command 'redraw' + end + + # Clear any entered text. + def clear! + @abbrev = '' + @col = 0 + redraw + end + + # Insert a character at (before) the current cursor position. + def add! char + left, cursor, right = abbrev_segments + @abbrev = left + char + cursor + right + @col += 1 + redraw + end + + # Delete a character to the left of the current cursor position. + def backspace! + if @col > 0 + left, cursor, right = abbrev_segments + @abbrev = left.chop! + cursor + right + @col -= 1 + redraw + end + end + + # Delete a character at the current cursor position. + def delete! + if @col < @abbrev.length + left, cursor, right = abbrev_segments + @abbrev = left + right + redraw + end + end + + def cursor_left + if @col > 0 + @col -= 1 + redraw + end + end + + def cursor_right + if @col < @abbrev.length + @col += 1 + redraw + end + end + + def cursor_end + if @col < @abbrev.length + @col = @abbrev.length + redraw + end + end + + def cursor_start + if @col != 0 + @col = 0 + redraw + end + end + + def redraw + if @has_focus + prompt_highlight = 'Comment' + normal_highlight = 'None' + cursor_highlight = 'Underlined' + else + prompt_highlight = 'NonText' + normal_highlight = 'NonText' + cursor_highlight = 'NonText' + end + left, cursor, right = abbrev_segments + components = [prompt_highlight, '>>', 'None', ' '] + components += [normal_highlight, left] unless left.empty? + components += [cursor_highlight, cursor] unless cursor.empty? + components += [normal_highlight, right] unless right.empty? + components += [cursor_highlight, ' '] if cursor.empty? + set_status *components + end + + def focus + unless @has_focus + @has_focus = true + redraw + end + end + + def unfocus + if @has_focus + @has_focus = false + redraw + end + end + + private + + # Returns the @abbrev string divided up into three sections, any of + # which may actually be zero width, depending on the location of the + # cursor: + # - left segment (to left of cursor) + # - cursor segment (character at cursor) + # - right segment (to right of cursor) + def abbrev_segments + left = @abbrev[0, @col] + cursor = @abbrev[@col, 1] + right = @abbrev[(@col + 1)..-1] || '' + [left, cursor, right] + end + + def set_status *args + # see ':help :echo' for why forcing a redraw here helps + # prevent the status line from getting inadvertantly cleared + # after our echo commands + ::VIM::command 'redraw' + while (highlight = args.shift) and (text = args.shift) do + text = VIM::escape_for_single_quotes text + ::VIM::command "echohl #{highlight}" + ::VIM::command "echon '#{text}'" + end + ::VIM::command 'echohl None' + end + end # class Prompt +end # module CommandT diff --git a/vimfiles/ruby/command-t/ruby_compat.h b/vimfiles/ruby/command-t/ruby_compat.h new file mode 100644 index 0000000..e7960a2 --- /dev/null +++ b/vimfiles/ruby/command-t/ruby_compat.h @@ -0,0 +1,49 @@ +// Copyright 2010 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. + +#include + +// for compatibility with older versions of Ruby which don't declare RSTRING_PTR +#ifndef RSTRING_PTR +#define RSTRING_PTR(s) (RSTRING(s)->ptr) +#endif + +// for compatibility with older versions of Ruby which don't declare RSTRING_LEN +#ifndef RSTRING_LEN +#define RSTRING_LEN(s) (RSTRING(s)->len) +#endif + +// for compatibility with older versions of Ruby which don't declare RARRAY_PTR +#ifndef RARRAY_PTR +#define RARRAY_PTR(a) (RARRAY(a)->ptr) +#endif + +// for compatibility with older versions of Ruby which don't declare RARRAY_LEN +#ifndef RARRAY_LEN +#define RARRAY_LEN(a) (RARRAY(a)->len) +#endif + +// for compatibility with older versions of Ruby which don't declare RFLOAT_VALUE +#ifndef RFLOAT_VALUE +#define RFLOAT_VALUE(f) (RFLOAT(f)->value) +#endif diff --git a/vimfiles/ruby/command-t/scanner.rb b/vimfiles/ruby/command-t/scanner.rb new file mode 100644 index 0000000..5e5e3c9 --- /dev/null +++ b/vimfiles/ruby/command-t/scanner.rb @@ -0,0 +1,28 @@ +# Copyright 2010-2011 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/vim' + +module CommandT + class Scanner; end +end # module CommandT diff --git a/vimfiles/ruby/command-t/scanner/buffer_scanner.rb b/vimfiles/ruby/command-t/scanner/buffer_scanner.rb new file mode 100644 index 0000000..aa85497 --- /dev/null +++ b/vimfiles/ruby/command-t/scanner/buffer_scanner.rb @@ -0,0 +1,42 @@ +# Copyright 2010-2011 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/vim' +require 'command-t/vim/path_utilities' +require 'command-t/scanner' + +module CommandT + # Returns a list of all open buffers. + class BufferScanner < Scanner + include VIM::PathUtilities + + def paths + (0..(::VIM::Buffer.count - 1)).map do |n| + buffer = ::VIM::Buffer[n] + if buffer.name # beware, may be nil + relative_path_under_working_directory buffer.name + end + end.compact + end + end # class BufferScanner +end # module CommandT diff --git a/vimfiles/ruby/command-t/scanner/file_scanner.rb b/vimfiles/ruby/command-t/scanner/file_scanner.rb new file mode 100644 index 0000000..e0dc3bc --- /dev/null +++ b/vimfiles/ruby/command-t/scanner/file_scanner.rb @@ -0,0 +1,101 @@ +# Copyright 2010-2011 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/vim' +require 'command-t/scanner' + +module CommandT + # Reads the current directory recursively for the paths to all regular files. + class FileScanner < Scanner + class FileLimitExceeded < ::RuntimeError; end + attr_accessor :path + + def initialize path = Dir.pwd, options = {} + @paths = {} + @paths_keys = [] + @path = path + @max_depth = options[:max_depth] || 15 + @max_files = options[:max_files] || 10_000 + @max_caches = options[:max_caches] || 1 + @scan_dot_directories = options[:scan_dot_directories] || false + end + + def paths + return @paths[@path] if @paths.has_key?(@path) + begin + ensure_cache_under_limit + @paths[@path] = [] + @depth = 0 + @files = 0 + @prefix_len = @path.chomp('/').length + add_paths_for_directory @path, @paths[@path] + rescue FileLimitExceeded + end + @paths[@path] + end + + def flush + @paths = {} + end + + private + + def ensure_cache_under_limit + # Ruby 1.8 doesn't have an ordered hash, so use a separate stack to + # track and expire the oldest entry in the cache + if @max_caches > 0 && @paths_keys.length >= @max_caches + @paths.delete @paths_keys.shift + end + @paths_keys << @path + end + + def path_excluded? path + # first strip common prefix (@path) from path to match VIM's behavior + path = path[(@prefix_len + 1)..-1] + path = VIM::escape_for_single_quotes path + ::VIM::evaluate("empty(expand(fnameescape('#{path}')))").to_i == 1 + end + + def add_paths_for_directory dir, accumulator + Dir.foreach(dir) do |entry| + next if ['.', '..'].include?(entry) + path = File.join(dir, entry) + unless path_excluded?(path) + if File.file?(path) + @files += 1 + raise FileLimitExceeded if @files > @max_files + accumulator << path[@prefix_len + 1..-1] + elsif File.directory?(path) + next if @depth >= @max_depth + next if (entry.match(/\A\./) && !@scan_dot_directories) + @depth += 1 + add_paths_for_directory path, accumulator + @depth -= 1 + end + end + end + rescue Errno::EACCES + # skip over directories for which we don't have access + end + end # class FileScanner +end # module CommandT diff --git a/vimfiles/ruby/command-t/scanner/jump_scanner.rb b/vimfiles/ruby/command-t/scanner/jump_scanner.rb new file mode 100644 index 0000000..3da0f28 --- /dev/null +++ b/vimfiles/ruby/command-t/scanner/jump_scanner.rb @@ -0,0 +1,54 @@ +# Copyright 2011 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/vim' +require 'command-t/vim/path_utilities' +require 'command-t/scanner' + +module CommandT + # Returns a list of files in the jumplist. + class JumpScanner < Scanner + include VIM::PathUtilities + + def paths + jumps_with_filename = jumps.lines.select do |line| + line_contains_filename?(line) + end + filenames = jumps_with_filename[1..-2].map do |line| + relative_path_under_working_directory line.split[3] + end + + filenames.sort.uniq + end + + private + + def line_contains_filename? line + line.split.count > 3 + end + + def jumps + VIM::capture 'silent jumps' + end + end # class JumpScanner +end # module CommandT diff --git a/vimfiles/ruby/command-t/scanner/tag_scanner.rb b/vimfiles/ruby/command-t/scanner/tag_scanner.rb new file mode 100644 index 0000000..a9b8ddc --- /dev/null +++ b/vimfiles/ruby/command-t/scanner/tag_scanner.rb @@ -0,0 +1,49 @@ +# Copyright 2011-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/vim' +require 'command-t/scanner' + +module CommandT + class TagScanner < Scanner + attr_reader :include_filenames + + def initialize options = {} + @include_filenames = options[:include_filenames] || false + end + + def paths + taglist.map do |tag| + path = tag['name'] + path << ":#{tag['filename']}" if @include_filenames + path + end.uniq.sort + end + + private + + def taglist + ::VIM::evaluate 'taglist(".")' + end + end # class TagScanner +end # module CommandT diff --git a/vimfiles/ruby/command-t/settings.rb b/vimfiles/ruby/command-t/settings.rb new file mode 100644 index 0000000..c15016a --- /dev/null +++ b/vimfiles/ruby/command-t/settings.rb @@ -0,0 +1,77 @@ +# Copyright 2010 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. + +module CommandT + # Convenience class for saving and restoring global settings. + class Settings + def initialize + save + end + + def save + @timeoutlen = get_number 'timeoutlen' + @report = get_number 'report' + @sidescroll = get_number 'sidescroll' + @sidescrolloff = get_number 'sidescrolloff' + @timeout = get_bool 'timeout' + @equalalways = get_bool 'equalalways' + @hlsearch = get_bool 'hlsearch' + @insertmode = get_bool 'insertmode' + @showcmd = get_bool 'showcmd' + end + + def restore + set_number 'timeoutlen', @timeoutlen + set_number 'report', @report + set_number 'sidescroll', @sidescroll + set_number 'sidescrolloff', @sidescrolloff + set_bool 'timeout', @timeout + set_bool 'equalalways', @equalalways + set_bool 'hlsearch', @hlsearch + set_bool 'insertmode', @insertmode + set_bool 'showcmd', @showcmd + end + + private + + def get_number setting + ::VIM::evaluate("&#{setting}").to_i + end + + def get_bool setting + ::VIM::evaluate("&#{setting}").to_i == 1 + end + + def set_number setting, value + ::VIM::set_option "#{setting}=#{value}" + end + + def set_bool setting, value + if value + ::VIM::set_option setting + else + ::VIM::set_option "no#{setting}" + end + end + end # class Settings +end # module CommandT diff --git a/vimfiles/ruby/command-t/stub.rb b/vimfiles/ruby/command-t/stub.rb new file mode 100644 index 0000000..4628b61 --- /dev/null +++ b/vimfiles/ruby/command-t/stub.rb @@ -0,0 +1,42 @@ +# Copyright 2010-2011 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. + +module CommandT + class Stub + @@load_error = ['command-t.vim could not load the C extension', + 'Please see INSTALLATION and TROUBLE-SHOOTING in the help', + 'For more information type: :help command-t'] + + [:flush, :show_buffer_finder, :show_file_finder, :show_tag_finder].each do |method| + define_method(method.to_sym) { warn *@@load_error } + end + + private + + def warn *msg + ::VIM::command 'echohl WarningMsg' + msg.each { |m| ::VIM::command "echo '#{m}'" } + ::VIM::command 'echohl none' + end + end # class Stub +end # module CommandT diff --git a/vimfiles/ruby/command-t/vim.rb b/vimfiles/ruby/command-t/vim.rb new file mode 100644 index 0000000..fc75738 --- /dev/null +++ b/vimfiles/ruby/command-t/vim.rb @@ -0,0 +1,59 @@ +# 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/vim/screen' +require 'command-t/vim/window' + +module CommandT + module VIM + def self.has_syntax? + ::VIM::evaluate('has("syntax")').to_i != 0 + end + + def self.exists? str + ::VIM::evaluate(%{exists("#{str}")}).to_i != 0 + end + + def self.has_conceal? + ::VIM::evaluate('has("conceal")').to_i != 0 + end + + def self.pwd + ::VIM::evaluate 'getcwd()' + end + + # Execute cmd, capturing the output into a variable and returning it. + def self.capture cmd + ::VIM::command 'silent redir => g:command_t_captured_output' + ::VIM::command cmd + ::VIM::command 'silent redir END' + ::VIM::evaluate 'g:command_t_captured_output' + end + + # Escape a string for safe inclusion in a Vim single-quoted string + # (single quotes escaped by doubling, everything else is literal) + def self.escape_for_single_quotes str + str.gsub "'", "''" + end + end # module VIM +end # module CommandT diff --git a/vimfiles/ruby/command-t/vim/path_utilities.rb b/vimfiles/ruby/command-t/vim/path_utilities.rb new file mode 100644 index 0000000..8564300 --- /dev/null +++ b/vimfiles/ruby/command-t/vim/path_utilities.rb @@ -0,0 +1,40 @@ +# Copyright 2010-2011 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/vim' + +module CommandT + module VIM + module PathUtilities + + private + + def relative_path_under_working_directory path + # any path under the working directory will be specified as a relative + # path to improve the readability of the buffer list etc + pwd = File.expand_path(VIM::pwd) + '/' + path.index(pwd) == 0 ? path[pwd.length..-1] : path + end + end # module PathUtilities + end # module VIM +end # module CommandT diff --git a/vimfiles/ruby/command-t/vim/screen.rb b/vimfiles/ruby/command-t/vim/screen.rb new file mode 100644 index 0000000..fb7ba33 --- /dev/null +++ b/vimfiles/ruby/command-t/vim/screen.rb @@ -0,0 +1,32 @@ +# Copyright 2010 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. + +module CommandT + module VIM + module Screen + def self.lines + ::VIM::evaluate('&lines').to_i + end + end # module Screen + end # module VIM +end # module CommandT diff --git a/vimfiles/ruby/command-t/vim/window.rb b/vimfiles/ruby/command-t/vim/window.rb new file mode 100644 index 0000000..1e53d56 --- /dev/null +++ b/vimfiles/ruby/command-t/vim/window.rb @@ -0,0 +1,38 @@ +# Copyright 2010 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. + +module CommandT + module VIM + class Window + def self.select window + return true if $curwin == window + initial = $curwin + while true do + ::VIM::command 'wincmd w' # cycle through windows + return true if $curwin == window # have selected desired window + return false if $curwin == initial # have already looped through all + end + end + end # class Window + end # module VIM +end # module CommandT