Bläddra i källkod

First version

Taddeus Kroes 12 år sedan
incheckning
af7a6adb30
97 ändrade filer med 14352 tillägg och 0 borttagningar
  1. 112 0
      bashrc
  2. 21 0
      packages
  3. 0 0
      vim/.VimballRecord
  4. 7 0
      vim/.netrwhist
  5. 35 0
      vim/after/plugin/snipMate.vim
  6. 9 0
      vim/after/syntax/haml.vim
  7. 11 0
      vim/after/syntax/html.vim
  8. 435 0
      vim/autoload/snipMate.vim
  9. 146 0
      vim/colors/darkspectrum.vim
  10. 68 0
      vim/compiler/coffee.vim
  11. 599 0
      vim/doc/CSApprox.txt
  12. 116 0
      vim/doc/coffee-script.txt
  13. 1183 0
      vim/doc/command-t.txt
  14. 286 0
      vim/doc/snipMate.txt
  15. 125 0
      vim/doc/tags
  16. 8 0
      vim/ftdetect/coffee.vim
  17. 1 0
      vim/ftdetect/eco.vim
  18. 221 0
      vim/ftplugin/coffee.vim
  19. 10 0
      vim/ftplugin/html_snip_helper.vim
  20. 338 0
      vim/indent/coffee.vim
  21. 291 0
      vim/indent/ocaml.vim
  22. 495 0
      vim/plugin/clang_complete.vim
  23. 194 0
      vim/plugin/command-t.vim
  24. 1778 0
      vim/plugin/fugitive.vim
  25. 313 0
      vim/plugin/guicolorscheme.vim
  26. 271 0
      vim/plugin/snipMate.vim
  27. 274 0
      vim/plugin/unimpaired.vim
  28. 181 0
      vim/ruby/command-t/Makefile
  29. 396 0
      vim/ruby/command-t/controller.rb
  30. 24 0
      vim/ruby/command-t/depend
  31. 60 0
      vim/ruby/command-t/ext.c
  32. 37 0
      vim/ruby/command-t/ext.h
  33. BIN
      vim/ruby/command-t/ext.o
  34. BIN
      vim/ruby/command-t/ext.so
  35. 56 0
      vim/ruby/command-t/extconf.rb
  36. 54 0
      vim/ruby/command-t/finder.rb
  37. 35 0
      vim/ruby/command-t/finder/buffer_finder.rb
  38. 51 0
      vim/ruby/command-t/finder/file_finder.rb
  39. 35 0
      vim/ruby/command-t/finder/jump_finder.rb
  40. 44 0
      vim/ruby/command-t/finder/tag_finder.rb
  41. 201 0
      vim/ruby/command-t/match.c
  42. 36 0
      vim/ruby/command-t/match.h
  43. BIN
      vim/ruby/command-t/match.o
  44. 446 0
      vim/ruby/command-t/match_window.rb
  45. 242 0
      vim/ruby/command-t/matcher.c
  46. 27 0
      vim/ruby/command-t/matcher.h
  47. BIN
      vim/ruby/command-t/matcher.o
  48. 92 0
      vim/ruby/command-t/mkmf.log
  49. 165 0
      vim/ruby/command-t/prompt.rb
  50. 49 0
      vim/ruby/command-t/ruby_compat.h
  51. 28 0
      vim/ruby/command-t/scanner.rb
  52. 42 0
      vim/ruby/command-t/scanner/buffer_scanner.rb
  53. 83 0
      vim/ruby/command-t/scanner/file_scanner.rb
  54. 77 0
      vim/ruby/command-t/scanner/file_scanner/find_file_scanner.rb
  55. 78 0
      vim/ruby/command-t/scanner/file_scanner/ruby_file_scanner.rb
  56. 82 0
      vim/ruby/command-t/scanner/file_scanner/watchman_file_scanner.rb
  57. 54 0
      vim/ruby/command-t/scanner/jump_scanner.rb
  58. 49 0
      vim/ruby/command-t/scanner/tag_scanner.rb
  59. 128 0
      vim/ruby/command-t/settings.rb
  60. 42 0
      vim/ruby/command-t/stub.rb
  61. 114 0
      vim/ruby/command-t/util.rb
  62. 63 0
      vim/ruby/command-t/vim.rb
  63. 40 0
      vim/ruby/command-t/vim/path_utilities.rb
  64. 32 0
      vim/ruby/command-t/vim/screen.rb
  65. 38 0
      vim/ruby/command-t/vim/window.rb
  66. 660 0
      vim/ruby/command-t/watchman.c
  67. 52 0
      vim/ruby/command-t/watchman.h
  68. BIN
      vim/ruby/command-t/watchman.o
  69. 7 0
      vim/snippets/_.snippets
  70. 66 0
      vim/snippets/autoit.snippets
  71. 110 0
      vim/snippets/c.snippets
  72. 30 0
      vim/snippets/cpp.snippets
  73. 190 0
      vim/snippets/html.snippets
  74. 78 0
      vim/snippets/java.snippets
  75. 74 0
      vim/snippets/javascript.snippets
  76. 54 0
      vim/snippets/mako.snippets
  77. 184 0
      vim/snippets/objc.snippets
  78. 91 0
      vim/snippets/perl.snippets
  79. 216 0
      vim/snippets/php.snippets
  80. 86 0
      vim/snippets/python.snippets
  81. 420 0
      vim/snippets/ruby.snippets
  82. 28 0
      vim/snippets/sh.snippets
  83. 7 0
      vim/snippets/snippet.snippets
  84. 92 0
      vim/snippets/tcl.snippets
  85. 115 0
      vim/snippets/tex.snippets
  86. 32 0
      vim/snippets/vim.snippets
  87. 58 0
      vim/snippets/zsh.snippets
  88. 50 0
      vim/spell/en.utf-8.add
  89. BIN
      vim/spell/en.utf-8.add.spl
  90. BIN
      vim/spell/nl.utf-8.spl
  91. BIN
      vim/spell/nl.utf-8.sug
  92. 217 0
      vim/syntax/coffee.vim
  93. 62 0
      vim/syntax/eco.vim
  94. 305 0
      vim/syntax/less.vim
  95. 331 0
      vim/syntax/ocaml.vim
  96. 19 0
      vim/syntax/snippet.vim
  97. 190 0
      vimrc

+ 112 - 0
bashrc

@@ -0,0 +1,112 @@
+# ~/.bashrc: executed by bash(1) for non-login shells.
+
+#
+# Bash history and shell options
+#
+
+# if not running interactively, don't do anything
+[ -z "$PS1" ] && return
+
+# don't put duplicate lines or lines starting with space in the history.
+# See bash(1) for more options
+HISTCONTROL=ignoreboth
+
+# append to the history file, don't overwrite it
+shopt -s histappend
+
+# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
+HISTSIZE=1000
+HISTFILESIZE=2000
+
+# check the window size after each command and, if necessary,
+# update the values of LINES and COLUMNS.
+shopt -s checkwinsize
+
+# make less more friendly for non-text input files, see lesspipe(1)
+[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
+
+# enable programmable completion features (you don't need to enable
+# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
+# sources /etc/bash.bashrc).
+if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
+    . /etc/bash_completion
+fi
+
+#
+# Setting PS1
+#
+
+# set variable identifying the chroot you work in (used in the prompt below)
+if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
+    debian_chroot=$(cat /etc/debian_chroot)
+fi
+
+# comment for uncolored terminal
+color_prompt=yes
+
+if [ $UID -eq 0 ]; then
+    USERCOLOR="\[\e[01;31m\]"  # Red if running as root
+    INDICATOR="#"
+else
+    USERCOLOR="\[\e[01;32m\]"  # Green otherwise
+    INDICATOR="$"
+fi
+
+if [ "$color_prompt" = yes ]; then
+    PS1="${debian_chroot:+($debian_chroot)}$USERCOLOR\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$INDICATOR "
+else
+    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$INDICATOR '
+fi
+unset color_prompt
+
+#
+# Aliases
+#
+
+# enable color support of ls and grep
+if [ -x /usr/bin/dircolors ]; then
+    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
+    alias ls='ls --color=auto'
+    #alias dir='dir --color=auto'
+    #alias vdir='vdir --color=auto'
+
+    alias grep='grep --color=auto'
+    alias fgrep='fgrep --color=auto'
+    alias egrep='egrep --color=auto'
+fi
+
+# ls shortcuts
+alias ll='ls -alFh'
+alias la='ls -A'
+alias l='ls -CF'
+
+# ssh shortcuts for multivac
+alias smv='ssh mv -tt screen -Uxr'
+alias mvv='mosh mv -p 8215 -- screen -Uxr'
+
+# more alias fancyness
+alias cdhere='cd $(realpath $(pwd))'
+alias ocaml='rlwrap ocaml'
+
+# Add an "alert" alias for long running commands.  Use like so:
+#   sleep 10; alert
+alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
+
+#
+# Environment
+#
+
+export TERM="xterm-256color"
+
+export LC_ALL="en_US.UTF-8"
+export LANG="$LC_ALL"
+
+export EDITOR=vim
+
+export PATH=$PATH:$HOME/.local/bin
+
+#
+# local, installation-specific config
+#
+
+[ -f ~/.bashrc_local ] && . ~/.bashrc_local

+ 21 - 0
packages

@@ -0,0 +1,21 @@
+awesome vim vim-gui-common vim-nox git tig radiotray chromium-browser thunar
+gmail-notify numlockx htop mosh mupdf
+
+ranger gimp meld imagemagick curl bpython gparted tree graphviz realpath
+
+python-tornado pyflakes pep8 feh python-numpy python-scipy python-pygame
+python-cairo python-setuptools python-coverage python-gtk2 python-mysqldb
+python-sqlalchemy python-pip python-matplotlib python-docutils
+
+mpi-default-dev build-essential subversion gettext liblua5.1-dev libsdl1.2-dev
+libsigc++-2.0-dev binutils-dev nasm libasound2 ocaml ocaml-native-compilers
+opam camlp4-extra menhir g++-multilib bison flex mysql-server mysql-workbench
+ruby-sass
+
+texlive-base texlive-latex-extra texlive-fonts-recommended texlive-extra-utils
+texlive-bibtex-extra kbibtex
+
+gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly gstreamer0.10-plugins-good
+gconf-editor
+
+libncurses5-dev openjdk-7-jdk ant libnotify-bin

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
vim/.VimballRecord


+ 7 - 0
vim/.netrwhist

@@ -0,0 +1,7 @@
+let g:netrw_dirhistmax  =10
+let g:netrw_dirhist_cnt =5
+let g:netrw_dirhist_1='/home/taddeus/programming/s2e/s2e/qemu/s2e'
+let g:netrw_dirhist_2='/home/taddeus/programming/s2e/s2e/qemu'
+let g:netrw_dirhist_3='/home/taddeus/programming/s2e/s2e/qemu/s2e'
+let g:netrw_dirhist_4='/home/taddeus/programming/s2e/s2e/qemu/s2e/Plugins/thesis'
+let g:netrw_dirhist_5='/etc/wpa_supplicant'

+ 35 - 0
vim/after/plugin/snipMate.vim

@@ -0,0 +1,35 @@
+" These are the mappings for snipMate.vim. Putting it here ensures that it
+" will be mapped after other plugins such as supertab.vim.
+if !exists('loaded_snips') || exists('s:did_snips_mappings')
+	finish
+endif
+let s:did_snips_mappings = 1
+
+ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
+snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
+ino <silent> <s-tab> <c-r>=BackwardsSnippet()<cr>
+snor <silent> <s-tab> <esc>i<right><c-r>=BackwardsSnippet()<cr>
+ino <silent> <c-r><tab> <c-r>=ShowAvailableSnips()<cr>
+
+" The default mappings for these are annoying & sometimes break snipMate.
+" You can change them back if you want, I've put them here for convenience.
+snor <bs> b<bs>
+snor <right> <esc>a
+snor <left> <esc>bi
+snor ' b<bs>'
+snor ` b<bs>`
+snor % b<bs>%
+snor U b<bs>U
+snor ^ b<bs>^
+snor \ b<bs>\
+snor <c-x> b<bs><c-x>
+
+" By default load snippets in snippets_dir
+if empty(snippets_dir)
+	finish
+endif
+
+call GetSnippets(snippets_dir, '_') " Get global snippets
+
+au FileType * if &ft != 'help' | call GetSnippets(snippets_dir, &ft) | endif
+" vim:noet:sw=4:ts=4:ft=vim

+ 9 - 0
vim/after/syntax/haml.vim

@@ -0,0 +1,9 @@
+" Language:    CoffeeScript
+" Maintainer:  Sven Felix Oberquelle <Svelix.Github@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+" Inherit coffee from html so coffeeComment isn't redefined and given higher
+" priority than hamlInterpolation.
+syn cluster hamlCoffeescript contains=@htmlCoffeeScript
+syn region  hamlCoffeescriptFilter matchgroup=hamlFilter start="^\z(\s*\):coffeescript\s*$" end="^\%(\z1 \| *$\)\@!" contains=@hamlCoffeeScript,hamlInterpolation keepend

+ 11 - 0
vim/after/syntax/html.vim

@@ -0,0 +1,11 @@
+" Language:    CoffeeScript
+" Maintainer:  Mick Koch <kchmck@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+" Syntax highlighting for text/coffeescript script tags
+syn include @htmlCoffeeScript syntax/coffee.vim
+syn region coffeeScript start=+<script [^>]*type *=[^>]*text/coffeescript[^>]*>+
+\                       end=+</script>+me=s-1 keepend
+\                       contains=@htmlCoffeeScript,htmlScriptTag,@htmlPreproc
+\                       containedin=htmlHead

+ 435 - 0
vim/autoload/snipMate.vim

@@ -0,0 +1,435 @@
+fun! Filename(...)
+	let filename = expand('%:t:r')
+	if filename == '' | return a:0 == 2 ? a:2 : '' | endif
+	return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g')
+endf
+
+fun s:RemoveSnippet()
+	unl! g:snipPos s:curPos s:snipLen s:endCol s:endLine s:prevLen
+	     \ s:lastBuf s:oldWord
+	if exists('s:update')
+		unl s:startCol s:origWordLen s:update
+		if exists('s:oldVars') | unl s:oldVars s:oldEndCol | endif
+	endif
+	aug! snipMateAutocmds
+endf
+
+fun snipMate#expandSnip(snip, col)
+	let lnum = line('.') | let col = a:col
+
+	let snippet = s:ProcessSnippet(a:snip)
+	" Avoid error if eval evaluates to nothing
+	if snippet == '' | return '' | endif
+
+	" Expand snippet onto current position with the tab stops removed
+	let snipLines = split(substitute(snippet, '$\d\+\|${\d\+.\{-}}', '', 'g'), "\n", 1)
+
+	let line = getline(lnum)
+	let afterCursor = strpart(line, col - 1)
+	" Keep text after the cursor
+	if afterCursor != "\t" && afterCursor != ' '
+		let line = strpart(line, 0, col - 1)
+		let snipLines[-1] .= afterCursor
+	else
+		let afterCursor = ''
+		" For some reason the cursor needs to move one right after this
+		if line != '' && col == 1 && &ve != 'all' && &ve != 'onemore'
+			let col += 1
+		endif
+	endif
+
+	call setline(lnum, line.snipLines[0])
+
+	" Autoindent snippet according to previous indentation
+	let indent = matchend(line, '^.\{-}\ze\(\S\|$\)') + 1
+	call append(lnum, map(snipLines[1:], "'".strpart(line, 0, indent - 1)."'.v:val"))
+
+	" Open any folds snippet expands into
+	if &fen | sil! exe lnum.','.(lnum + len(snipLines) - 1).'foldopen' | endif
+
+	let [g:snipPos, s:snipLen] = s:BuildTabStops(snippet, lnum, col - indent, indent)
+
+	if s:snipLen
+		aug snipMateAutocmds
+			au CursorMovedI * call s:UpdateChangedSnip(0)
+			au InsertEnter * call s:UpdateChangedSnip(1)
+		aug END
+		let s:lastBuf = bufnr(0) " Only expand snippet while in current buffer
+		let s:curPos = 0
+		let s:endCol = g:snipPos[s:curPos][1]
+		let s:endLine = g:snipPos[s:curPos][0]
+
+		call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1])
+		let s:prevLen = [line('$'), col('$')]
+		if g:snipPos[s:curPos][2] != -1 | return s:SelectWord() | endif
+	else
+		unl g:snipPos s:snipLen
+		" Place cursor at end of snippet if no tab stop is given
+		let newlines = len(snipLines) - 1
+		call cursor(lnum + newlines, indent + len(snipLines[-1]) - len(afterCursor)
+					\ + (newlines ? 0: col - 1))
+	endif
+	return ''
+endf
+
+" Prepare snippet to be processed by s:BuildTabStops
+fun s:ProcessSnippet(snip)
+	let snippet = a:snip
+	" Evaluate eval (`...`) expressions.
+	" Backquotes prefixed with a backslash "\" are ignored.
+	" Using a loop here instead of a regex fixes a bug with nested "\=".
+	if stridx(snippet, '`') != -1
+		while match(snippet, '\(^\|[^\\]\)`.\{-}[^\\]`') != -1
+			let snippet = substitute(snippet, '\(^\|[^\\]\)\zs`.\{-}[^\\]`\ze',
+		                \ substitute(eval(matchstr(snippet, '\(^\|[^\\]\)`\zs.\{-}[^\\]\ze`')),
+		                \ "\n\\%$", '', ''), '')
+		endw
+		let snippet = substitute(snippet, "\r", "\n", 'g')
+		let snippet = substitute(snippet, '\\`', '`', 'g')
+	endif
+
+	" Place all text after a colon in a tab stop after the tab stop
+	" (e.g. "${#:foo}" becomes "${:foo}foo").
+	" This helps tell the position of the tab stops later.
+	let snippet = substitute(snippet, '${\d\+:\(.\{-}\)}', '&\1', 'g')
+
+	" Update the a:snip so that all the $# become the text after
+	" the colon in their associated ${#}.
+	" (e.g. "${1:foo}" turns all "$1"'s into "foo")
+	let i = 1
+	while stridx(snippet, '${'.i) != -1
+		let s = matchstr(snippet, '${'.i.':\zs.\{-}\ze}')
+		if s != ''
+			let snippet = substitute(snippet, '$'.i, s.'&', 'g')
+		endif
+		let i += 1
+	endw
+
+	if &et " Expand tabs to spaces if 'expandtab' is set.
+		return substitute(snippet, '\t', repeat(' ', &sts ? &sts : &sw), 'g')
+	endif
+	return snippet
+endf
+
+" Counts occurences of haystack in needle
+fun s:Count(haystack, needle)
+	let counter = 0
+	let index = stridx(a:haystack, a:needle)
+	while index != -1
+		let index = stridx(a:haystack, a:needle, index+1)
+		let counter += 1
+	endw
+	return counter
+endf
+
+" Builds a list of a list of each tab stop in the snippet containing:
+" 1.) The tab stop's line number.
+" 2.) The tab stop's column number
+"     (by getting the length of the string between the last "\n" and the
+"     tab stop).
+" 3.) The length of the text after the colon for the current tab stop
+"     (e.g. "${1:foo}" would return 3). If there is no text, -1 is returned.
+" 4.) If the "${#:}" construct is given, another list containing all
+"     the matches of "$#", to be replaced with the placeholder. This list is
+"     composed the same way as the parent; the first item is the line number,
+"     and the second is the column.
+fun s:BuildTabStops(snip, lnum, col, indent)
+	let snipPos = []
+	let i = 1
+	let withoutVars = substitute(a:snip, '$\d\+', '', 'g')
+	while stridx(a:snip, '${'.i) != -1
+		let beforeTabStop = matchstr(withoutVars, '^.*\ze${'.i.'\D')
+		let withoutOthers = substitute(withoutVars, '${\('.i.'\D\)\@!\d\+.\{-}}', '', 'g')
+
+		let j = i - 1
+		call add(snipPos, [0, 0, -1])
+		let snipPos[j][0] = a:lnum + s:Count(beforeTabStop, "\n")
+		let snipPos[j][1] = a:indent + len(matchstr(withoutOthers, '.*\(\n\|^\)\zs.*\ze${'.i.'\D'))
+		if snipPos[j][0] == a:lnum | let snipPos[j][1] += a:col | endif
+
+		" Get all $# matches in another list, if ${#:name} is given
+		if stridx(withoutVars, '${'.i.':') != -1
+			let snipPos[j][2] = len(matchstr(withoutVars, '${'.i.':\zs.\{-}\ze}'))
+			let dots = repeat('.', snipPos[j][2])
+			call add(snipPos[j], [])
+			let withoutOthers = substitute(a:snip, '${\d\+.\{-}}\|$'.i.'\@!\d\+', '', 'g')
+			while match(withoutOthers, '$'.i.'\(\D\|$\)') != -1
+				let beforeMark = matchstr(withoutOthers, '^.\{-}\ze'.dots.'$'.i.'\(\D\|$\)')
+				call add(snipPos[j][3], [0, 0])
+				let snipPos[j][3][-1][0] = a:lnum + s:Count(beforeMark, "\n")
+				let snipPos[j][3][-1][1] = a:indent + (snipPos[j][3][-1][0] > a:lnum
+				                           \ ? len(matchstr(beforeMark, '.*\n\zs.*'))
+				                           \ : a:col + len(beforeMark))
+				let withoutOthers = substitute(withoutOthers, '$'.i.'\ze\(\D\|$\)', '', '')
+			endw
+		endif
+		let i += 1
+	endw
+	return [snipPos, i - 1]
+endf
+
+fun snipMate#jumpTabStop(backwards)
+	let leftPlaceholder = exists('s:origWordLen')
+	                      \ && s:origWordLen != g:snipPos[s:curPos][2]
+	if leftPlaceholder && exists('s:oldEndCol')
+		let startPlaceholder = s:oldEndCol + 1
+	endif
+
+	if exists('s:update')
+		call s:UpdatePlaceholderTabStops()
+	else
+		call s:UpdateTabStops()
+	endif
+
+	" Don't reselect placeholder if it has been modified
+	if leftPlaceholder && g:snipPos[s:curPos][2] != -1
+		if exists('startPlaceholder')
+			let g:snipPos[s:curPos][1] = startPlaceholder
+		else
+			let g:snipPos[s:curPos][1] = col('.')
+			let g:snipPos[s:curPos][2] = 0
+		endif
+	endif
+
+	let s:curPos += a:backwards ? -1 : 1
+	" Loop over the snippet when going backwards from the beginning
+	if s:curPos < 0 | let s:curPos = s:snipLen - 1 | endif
+
+	if s:curPos == s:snipLen
+		let sMode = s:endCol == g:snipPos[s:curPos-1][1]+g:snipPos[s:curPos-1][2]
+		call s:RemoveSnippet()
+		return sMode ? "\<tab>" : TriggerSnippet()
+	endif
+
+	call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1])
+
+	let s:endLine = g:snipPos[s:curPos][0]
+	let s:endCol = g:snipPos[s:curPos][1]
+	let s:prevLen = [line('$'), col('$')]
+
+	return g:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord()
+endf
+
+fun s:UpdatePlaceholderTabStops()
+	let changeLen = s:origWordLen - g:snipPos[s:curPos][2]
+	unl s:startCol s:origWordLen s:update
+	if !exists('s:oldVars') | return | endif
+	" Update tab stops in snippet if text has been added via "$#"
+	" (e.g., in "${1:foo}bar$1${2}").
+	if changeLen != 0
+		let curLine = line('.')
+
+		for pos in g:snipPos
+			if pos == g:snipPos[s:curPos] | continue | endif
+			let changed = pos[0] == curLine && pos[1] > s:oldEndCol
+			let changedVars = 0
+			let endPlaceholder = pos[2] - 1 + pos[1]
+			" Subtract changeLen from each tab stop that was after any of
+			" the current tab stop's placeholders.
+			for [lnum, col] in s:oldVars
+				if lnum > pos[0] | break | endif
+				if pos[0] == lnum
+					if pos[1] > col || (pos[2] == -1 && pos[1] == col)
+						let changed += 1
+					elseif col < endPlaceholder
+						let changedVars += 1
+					endif
+				endif
+			endfor
+			let pos[1] -= changeLen * changed
+			let pos[2] -= changeLen * changedVars " Parse variables within placeholders
+                                                  " e.g., "${1:foo} ${2:$1bar}"
+
+			if pos[2] == -1 | continue | endif
+			" Do the same to any placeholders in the other tab stops.
+			for nPos in pos[3]
+				let changed = nPos[0] == curLine && nPos[1] > s:oldEndCol
+				for [lnum, col] in s:oldVars
+					if lnum > nPos[0] | break | endif
+					if nPos[0] == lnum && nPos[1] > col
+						let changed += 1
+					endif
+				endfor
+				let nPos[1] -= changeLen * changed
+			endfor
+		endfor
+	endif
+	unl s:endCol s:oldVars s:oldEndCol
+endf
+
+fun s:UpdateTabStops()
+	let changeLine = s:endLine - g:snipPos[s:curPos][0]
+	let changeCol = s:endCol - g:snipPos[s:curPos][1]
+	if exists('s:origWordLen')
+		let changeCol -= s:origWordLen
+		unl s:origWordLen
+	endif
+	let lnum = g:snipPos[s:curPos][0]
+	let col = g:snipPos[s:curPos][1]
+	" Update the line number of all proceeding tab stops if <cr> has
+	" been inserted.
+	if changeLine != 0
+		let changeLine -= 1
+		for pos in g:snipPos
+			if pos[0] >= lnum
+				if pos[0] == lnum | let pos[1] += changeCol | endif
+				let pos[0] += changeLine
+			endif
+			if pos[2] == -1 | continue | endif
+			for nPos in pos[3]
+				if nPos[0] >= lnum
+					if nPos[0] == lnum | let nPos[1] += changeCol | endif
+					let nPos[0] += changeLine
+				endif
+			endfor
+		endfor
+	elseif changeCol != 0
+		" Update the column of all proceeding tab stops if text has
+		" been inserted/deleted in the current line.
+		for pos in g:snipPos
+			if pos[1] >= col && pos[0] == lnum
+				let pos[1] += changeCol
+			endif
+			if pos[2] == -1 | continue | endif
+			for nPos in pos[3]
+				if nPos[0] > lnum | break | endif
+				if nPos[0] == lnum && nPos[1] >= col
+					let nPos[1] += changeCol
+				endif
+			endfor
+		endfor
+	endif
+endf
+
+fun s:SelectWord()
+	let s:origWordLen = g:snipPos[s:curPos][2]
+	let s:oldWord = strpart(getline('.'), g:snipPos[s:curPos][1] - 1,
+				\ s:origWordLen)
+	let s:prevLen[1] -= s:origWordLen
+	if !empty(g:snipPos[s:curPos][3])
+		let s:update = 1
+		let s:endCol = -1
+		let s:startCol = g:snipPos[s:curPos][1] - 1
+	endif
+	if !s:origWordLen | return '' | endif
+	let l = col('.') != 1 ? 'l' : ''
+	if &sel == 'exclusive'
+		return "\<esc>".l.'v'.s:origWordLen."l\<c-g>"
+	endif
+	return s:origWordLen == 1 ? "\<esc>".l.'gh'
+							\ : "\<esc>".l.'v'.(s:origWordLen - 1)."l\<c-g>"
+endf
+
+" This updates the snippet as you type when text needs to be inserted
+" into multiple places (e.g. in "${1:default text}foo$1bar$1",
+" "default text" would be highlighted, and if the user types something,
+" UpdateChangedSnip() would be called so that the text after "foo" & "bar"
+" are updated accordingly)
+"
+" It also automatically quits the snippet if the cursor is moved out of it
+" while in insert mode.
+fun s:UpdateChangedSnip(entering)
+	if exists('g:snipPos') && bufnr(0) != s:lastBuf
+		call s:RemoveSnippet()
+	elseif exists('s:update') " If modifying a placeholder
+		if !exists('s:oldVars') && s:curPos + 1 < s:snipLen
+			" Save the old snippet & word length before it's updated
+			" s:startCol must be saved too, in case text is added
+			" before the snippet (e.g. in "foo$1${2}bar${1:foo}").
+			let s:oldEndCol = s:startCol
+			let s:oldVars = deepcopy(g:snipPos[s:curPos][3])
+		endif
+		let col = col('.') - 1
+
+		if s:endCol != -1
+			let changeLen = col('$') - s:prevLen[1]
+			let s:endCol += changeLen
+		else " When being updated the first time, after leaving select mode
+			if a:entering | return | endif
+			let s:endCol = col - 1
+		endif
+
+		" If the cursor moves outside the snippet, quit it
+		if line('.') != g:snipPos[s:curPos][0] || col < s:startCol ||
+					\ col - 1 > s:endCol
+			unl! s:startCol s:origWordLen s:oldVars s:update
+			return s:RemoveSnippet()
+		endif
+
+		call s:UpdateVars()
+		let s:prevLen[1] = col('$')
+	elseif exists('g:snipPos')
+		if !a:entering && g:snipPos[s:curPos][2] != -1
+			let g:snipPos[s:curPos][2] = -2
+		endif
+
+		let col = col('.')
+		let lnum = line('.')
+		let changeLine = line('$') - s:prevLen[0]
+
+		if lnum == s:endLine
+			let s:endCol += col('$') - s:prevLen[1]
+			let s:prevLen = [line('$'), col('$')]
+		endif
+		if changeLine != 0
+			let s:endLine += changeLine
+			let s:endCol = col
+		endif
+
+		" Delete snippet if cursor moves out of it in insert mode
+		if (lnum == s:endLine && (col > s:endCol || col < g:snipPos[s:curPos][1]))
+			\ || lnum > s:endLine || lnum < g:snipPos[s:curPos][0]
+			call s:RemoveSnippet()
+		endif
+	endif
+endf
+
+" This updates the variables in a snippet when a placeholder has been edited.
+" (e.g., each "$1" in "${1:foo} $1bar $1bar")
+fun s:UpdateVars()
+	let newWordLen = s:endCol - s:startCol + 1
+	let newWord = strpart(getline('.'), s:startCol, newWordLen)
+	if newWord == s:oldWord || empty(g:snipPos[s:curPos][3])
+		return
+	endif
+
+	let changeLen = g:snipPos[s:curPos][2] - newWordLen
+	let curLine = line('.')
+	let startCol = col('.')
+	let oldStartSnip = s:startCol
+	let updateTabStops = changeLen != 0
+	let i = 0
+
+	for [lnum, col] in g:snipPos[s:curPos][3]
+		if updateTabStops
+			let start = s:startCol
+			if lnum == curLine && col <= start
+				let s:startCol -= changeLen
+				let s:endCol -= changeLen
+			endif
+			for nPos in g:snipPos[s:curPos][3][(i):]
+				" This list is in ascending order, so quit if we've gone too far.
+				if nPos[0] > lnum | break | endif
+				if nPos[0] == lnum && nPos[1] > col
+					let nPos[1] -= changeLen
+				endif
+			endfor
+			if lnum == curLine && col > start
+				let col -= changeLen
+				let g:snipPos[s:curPos][3][i][1] = col
+			endif
+			let i += 1
+		endif
+
+		" "Very nomagic" is used here to allow special characters.
+		call setline(lnum, substitute(getline(lnum), '\%'.col.'c\V'.
+						\ escape(s:oldWord, '\'), escape(newWord, '\&'), ''))
+	endfor
+	if oldStartSnip != s:startCol
+		call cursor(0, startCol + s:startCol - oldStartSnip)
+	endif
+
+	let s:oldWord = newWord
+	let g:snipPos[s:curPos][2] = newWordLen
+endf
+" vim:noet:sw=4:ts=4:ft=vim

+ 146 - 0
vim/colors/darkspectrum.vim

@@ -0,0 +1,146 @@
+" Vim color file
+"
+" Author: Brian Mock <mock.brian@gmail.com>
+" Author: Sander Mathijs van Veen <smvv@kompiler.org>
+"
+" Note: Based on Oblivion color scheme for gedit (gtk-source-view)
+"       and based on Brian Mock's darkspectrum color theme.
+"
+" cool help screens
+" :he group-name
+" :he highlight-groups
+" :he cterm-colors
+
+hi clear
+
+if version > 580
+    " no guarantees for version 5.8 and below, but this makes it stop
+    " complaining
+    hi clear
+
+    if exists("syntax_on")
+        syntax reset
+    endif
+endif
+
+set background=dark
+
+let g:colors_name="darkspectrum"
+
+hi Normal guifg=#efefef guibg=#000000 ctermbg=none gui=none
+
+" highlight groups
+hi Cursor       guibg=#ffffff guifg=#000000
+hi CursorLine   guibg=#000000
+"hi CursorColumn guibg=#464646
+
+"hi diffText     guibg=#4e9a06 guifg=#FFFFFF gui=bold
+"hi diffChange   guibg=#4e9a06 guifg=#FFFFFF gui=bold
+"hi diffAdd      guibg=#204a87 guifg=#FFFFFF gui=bold
+"hi diffDelete   guibg=#5c3566 guifg=#FFFFFF gui=bold
+
+
+hi diffFile     guifg=#aaaaaa gui=none
+hi diffNewFile  guifg=#aaaaaa gui=none
+""hi DiffAdd      guifg=#ffcc7f guibg=#a67429 gui=none
+hi diffAdded    guifg=#44cc44 gui=none
+hi diffChange   guifg=#7fbdff gui=none
+hi diffRemoved  guifg=#aa2723 gui=none
+
+"hi DiffAdd    gui=none guifg=#ffcc7f guibg=none
+"hi DiffChange gui=none guifg=bg guibg=none
+"hi DiffDelete gui=none guifg=bg guibg=none
+"hi DiffText   gui=none guifg=bg guibg=none
+
+hi Number       guifg=#fce94f
+
+hi Folded       guibg=#000000 guifg=#FFFFFF gui=bold
+hi vimFold      guibg=#000000 guifg=#FFFFFF gui=bold
+hi FoldColumn   guibg=#000000 guifg=#FFFFFF gui=bold
+
+hi LineNr       guifg=#636363
+hi NonText      guifg=#636363
+hi Folded       guifg=#666666 gui=bold
+hi FoldeColumn  guifg=#636363 gui=bold
+"hi VertSplit   guibg=#ffffff gui=none
+
+hi VertSplit    guifg=#3C3C3C gui=none
+hi StatusLine   guifg=#FFFFFF gui=none
+hi StatusLineNC guifg=#808080 gui=none
+
+hi ModeMsg      guifg=#fce94f
+hi MoreMsg      guifg=#fce94f
+hi Visual       guifg=#FFFFFF guibg=#3465a4 gui=none
+hi VisualNOS    guifg=#FFFFFF guibg=#204a87 gui=none
+"hi IncSearch   guibg=#FFFFFF guifg=#5f6400
+hi IncSearch    guibg=#FFFFFF guifg=#ef5939
+"hi Search      guibg=#ad7fa8 guifg=#FFFFFF
+hi Search       guibg=#818800 guifg=#FFFFFF
+hi SpecialKey   guifg=#8ae234
+
+hi Title        guifg=#ef5939
+hi WarningMsg   guifg=#ef5939
+hi Number       guifg=#fcaf3e
+
+hi MatchParen   guibg=#ad7fa8 guifg=#FFFFFF
+hi Comment      guifg=#b3b3b3
+hi Constant     guifg=#ef5939 gui=none
+hi String       guifg=#fce94f
+hi Identifier   guifg=#729fcf
+hi Statement    guifg=#ffffff gui=bold
+hi PreProc      guifg=#ffffff gui=bold
+hi Type         guifg=#8ae234 gui=bold
+hi Special      guifg=#e9b96e
+hi Underlined   guifg=#ad7fa8 gui=underline
+hi Directory    guifg=#729fcf
+hi Ignore       guifg=#555753
+hi Todo         guifg=#FFFFFF guibg=#ef5939 gui=bold
+hi Function     guifg=#ad7fa8
+
+"hi WildMenu     guibg=#2e3436 guifg=#ffffff gui=bold
+"hi WildMenu     guifg=#7fbdff guibg=#425c78 gui=none
+hi WildMenu     guifg=#ffffff guibg=#3465a4 gui=none
+
+hi Pmenu        guibg=#000000 guifg=#c0c0c0
+hi PmenuSel     guibg=#3465a4 guifg=#ffffff
+hi PmenuSbar    guibg=#444444 guifg=#444444
+hi PmenuThumb   guibg=#888888 guifg=#888888
+
+hi cppSTLType   guifg=#729fcf gui=bold
+
+"hi SpellBad     guifg=#fcaf3e
+hi SpellBad     gui=underline
+hi SpellCap     guifg=#73d216
+hi SpellRare    guifg=#ad7fa8
+hi SpellLocal   guifg=#729fcf
+
+hi link cppSTL          Function
+hi link Error           Todo
+hi link Character       Number
+hi link rubySymbol      Number
+hi link htmlTag         htmlEndTag
+"hi link htmlTagName     htmlTag
+hi link htmlLink        Underlined
+hi link pythonFunction  Identifier
+hi link Question        Type
+hi link CursorIM        Cursor
+hi link VisualNOS       Visual
+hi link xmlTag          Identifier
+hi link xmlTagName      Identifier
+hi link shDeref         Identifier
+hi link shVariable      Function
+hi link rubySharpBang   Special
+hi link perlSharpBang   Special
+hi link schemeFunc      Statement
+"hi link shSpecialVariables Constant
+"hi link bashSpecialVariables Constant
+
+" tabs (non gui)
+hi TabLine      guifg=#A3A3A3 guibg=#202020 gui=none
+hi TabLineFill  guifg=#535353 guibg=#202020 gui=none
+hi TabLineSel   guifg=#FFFFFF gui=bold
+
+" Pyflakes warning and errors
+hi pyflakes     guifg=#ccaa00 gui=underline
+
+" vim: sw=4 ts=4

+ 68 - 0
vim/compiler/coffee.vim

@@ -0,0 +1,68 @@
+" Language:    CoffeeScript
+" Maintainer:  Mick Koch <kchmck@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+if exists('current_compiler')
+  finish
+endif
+
+let current_compiler = 'coffee'
+" Pattern to check if coffee is the compiler
+let s:pat = '^' . current_compiler
+
+" Extra options passed to CoffeeMake
+if !exists("coffee_make_options")
+  let coffee_make_options = ""
+endif
+
+" Get a `makeprg` for the current filename. This is needed to support filenames
+" with spaces and quotes, but also not break generic `make`.
+function! s:GetMakePrg()
+  return 'coffee -c ' . g:coffee_make_options . ' $* ' . fnameescape(expand('%'))
+endfunction
+
+" Set `makeprg` and return 1 if coffee is still the compiler, else return 0.
+function! s:SetMakePrg()
+  if &l:makeprg =~ s:pat
+    let &l:makeprg = s:GetMakePrg()
+  elseif &g:makeprg =~ s:pat
+    let &g:makeprg = s:GetMakePrg()
+  else
+    return 0
+  endif
+
+  return 1
+endfunction
+
+" Set a dummy compiler so we can check whether to set locally or globally.
+CompilerSet makeprg=coffee
+call s:SetMakePrg()
+
+CompilerSet errorformat=Error:\ In\ %f\\,\ %m\ on\ line\ %l,
+                       \Error:\ In\ %f\\,\ Parse\ error\ on\ line\ %l:\ %m,
+                       \SyntaxError:\ In\ %f\\,\ %m,
+                       \%-G%.%#
+
+" Compile the current file.
+command! -bang -bar -nargs=* CoffeeMake make<bang> <args>
+
+" Set `makeprg` on rename since we embed the filename in the setting.
+augroup CoffeeUpdateMakePrg
+  autocmd!
+
+  " Update `makeprg` if coffee is still the compiler, else stop running this
+  " function.
+  function! s:UpdateMakePrg()
+    if !s:SetMakePrg()
+      autocmd! CoffeeUpdateMakePrg
+    endif
+  endfunction
+
+  " Set autocmd locally if compiler was set locally.
+  if &l:makeprg =~ s:pat
+    autocmd BufFilePost,BufWritePost <buffer> call s:UpdateMakePrg()
+  else
+    autocmd BufFilePost,BufWritePost          call s:UpdateMakePrg()
+  endif
+augroup END

+ 599 - 0
vim/doc/CSApprox.txt

@@ -0,0 +1,599 @@
+*CSApprox.txt*  Bringing GVim colorschemes to the terminal!
+
+                                                     *csapprox* *csapprox.vim*
+
+                  _____ ____ ___                               ~
+                 / ___// __// _ |  ___   ___   ____ ___  __ __ ~
+                / /__ _\ \ / __ | / _ \ / _ \ / __// _ \ \ \ / ~
+                \___//___//_/ |_|/ .__// .__//_/   \___//_\_\  ~
+                                /_/   /_/                      ~
+                                                  For Vim version 7.0 or newer
+                                                      Last changed 01 Apr 2009
+
+                               By Matt Wozniski
+                                mjw@drexel.edu
+
+                              Reference Manual~
+
+                                                                *csapprox-toc*
+
+1. Introduction                                       |csapprox-intro|
+2. Requirements                                       |csapprox-requirements|
+3. Configuration                                      |csapprox-configure|
+4. Rationale/Design                                   |csapprox-design|
+5. Known Bugs and Limitations                         |csapprox-limitations|
+6. Appendix - Terminals and Palettes                  |csapprox-terminal-list|
+7. Changelog                                          |csapprox-changelog|
+8. Contact Info                                       |csapprox-author|
+
+The functionality mentioned here is a plugin, see |add-plugin|.
+You can avoid loading this plugin by setting the "CSApprox_loaded" global
+variable in your |vimrc| file: >
+    :let g:CSApprox_loaded = 1
+
+==============================================================================
+1. Introduction                                               *csapprox-intro*
+
+It's hard to find colorschemes for terminal Vim.  Most colorschemes are
+written to only support GVim, and don't work at all in terminal Vim.
+
+This plugin makes GVim-only colorschemes Just Work in terminal Vim, as long
+as the terminal supports 88 or 256 colors - and most do these days.  This
+usually requires no user interaction (but see below for what to do if things
+don't Just Work).  After getting this plugin happily installed, any time you
+use :colorscheme it will do its magic and make the colorscheme Just Work.
+
+Whenever you change colorschemes using the :colorscheme command this script
+will be executed.  It will take the colors that the scheme specified for use
+in the GUI and use an approximation algorithm to try to gracefully degrade
+them to the closest color available in your terminal.  If you are running in
+a GUI or if your terminal doesn't support 88 or 256 colors, no changes are
+made.  Also, no changes will be made if the colorscheme seems to have been
+high color already.
+
+If for some reason this transparent method isn't suitable to you (for instance
+if your environment can't be configured to meet the |csapprox-requirements|,
+or you need to work in Vim 6), another option is also available: using the
+|:CSApproxSnapshot| command to create a new GUI/88-/256-color terminal
+colorscheme.  To use this command, a user would generally start GVim, choose a
+colorscheme that sets up the desired colors, and then use |:CSApproxSnapshot|
+to create a new colorscheme based on those colors that works in high color
+terminals.  This method is more flexible than the transparent mode and works
+in more places, but also requires more user intervention, and makes it harder
+to deal with colorschemes being updated and such.
+                                                           *:CSApproxSnapshot*
+The full syntax for the command is: >
+    :CSApproxSnapshot[!] /path/to/new/colorscheme
+<       For example: >
+    :CSApproxSnapshot ~/.vim/colors/foobar.vim
+<
+NOTE: The generated colorscheme will only work in 88- and 256-color terminals,
+      and in GVim.  It will not work at all in a terminal with 16 or fewer
+      colors.  There's just no reliable way to approximate down from
+      16,777,216 colors to 16 colors, especially without there being any
+      standard for what those 16 colors look like other than 'orange-ish',
+      'red-ish', etc.
+
+NOTE: Although :CSApproxSnapshot can be used in both GVim and terminal Vim,
+      the resulting colors might be slightly off when run from terminal Vim.
+      I can find no way around this; Vim internally sets different colors when
+      running in a terminal than running in the GUI, and there's no way for
+      terminal Vim to figure out what color would have been used in GVim.
+
+==============================================================================
+2. Requirements                                        *csapprox-requirements*
+
+For CSApprox to work, there are 2 major requirements that must be met.
+
+a) GUI support                          *csapprox-gui-support* *csapprox-+gui*
+
+If CSApprox is being used to adjust a scheme's colors transparently, then the
+terminal "vim" binary that is being run must be built with GUI support (see
+|csapprox-limitations| for an explanation).  If |:CSApproxSnapshot| is being
+used to create a terminal colorscheme for high color terminals, then the
+"vim" binary being used to create the scheme must be built with +gui, but the
+scheme can be used in terminal "vim" binaries that weren't built with +gui.
+NOTE that creating snapshots with GVim will work better than making them with
+Vim, and (obviously) all "gvim" binaries are built with +gui.
+
+Unfortunately, several Linux distributions only include GUI support in their
+"gvim" binary, and not in their "vim" binary.  You can check if GUI support is
+available with the following command:
+    :echo has('gui')
+
+If that prints 0, the first thing to try would be searching for a larger vim
+package provided by your distribution, like "vim-enhanced" on RedHat/CentOS
+or "vim-gtk" or "vim-gnome" on Debian/Ubuntu.
+
+If you are unable to obtain a "vim" binary that includes GUI support, but
+have a "gvim" binary available, you can probably launch Vim with GUI support
+anyway by calling gvim with the |-v| flag in the shell: >
+    gvim -v
+
+If the above works, you can remove the need to call "gvim -v" instead of "vim"
+all the time by creating a symbolic link from your "gvim" binary to "vim"
+somewhere in your $PATH, for example:
+    sudo ln -s $(which gvim) $(which vim)
+
+If launching as "gvim -v" doesn"t work, and no package with GUI support is
+available, you will need to compile Vim yourself and ensure that GUI support
+is included to use CSApprox in its transparent mode, or create a snapshotted
+scheme from GVim to use its snapshot mode.  If this is inconvenient for you,
+make sure that the Vim maintainer for your distribution knows it; they made a
+conscious decision to build "vim" without +gui and "gvim" without terminal
+support.
+
+b) Properly configured terminal                            *csapprox-terminal*
+
+As said above, many modern terminals support 88 or 256 colors, but most of
+these default to setting $TERM to something generic (usually "xterm").  Since
+Vim uses the value of the "colors" attribute for the current $TERM in terminfo
+to figure out the number of colors used internally as 't_Co', this plugin will
+either need for 't_Co' to be set to 88 or 256 in |vimrc|, or for $TERM to be
+set to something that implies high color support.  Possible choices include
+"xterm-256color" for 256 color support and "rxvt-unicode" for 88 color
+support.
+                                                              *csapprox-palettes*
+Also, there are three different 256 color cube palettes available and CSApprox
+has no way to tell which you're using unless $TERM is set to something that is
+specific to the terminal, like "konsole-256color" or "Eterm".  Because of this, the
+most sane behavior is assuming the user is using the most popular palette,
+which is used by all but Konsole and Eterm, whenever $TERM is set to something
+generic like "xterm" or "screen".  You can override this default, however -
+see |csapprox-configure|.
+                                                   *csapprox-terminal-example*
+To turn on high color support without fixing $TERM, you can change t_Co in
+your .vimrc, and set either CSApprox_konsole or CSApprox_eterm if appropriate.
+One way would be to put something like this into your |vimrc|:
+>
+    if (&term == 'xterm' || &term =~? '^screen') && hostname() == 'my-machine'
+        " On my machine, I use Konsole with 256 color support
+        set t_Co=256
+        let g:CSApprox_konsole = 1
+    endif
+
+Gnome Terminal, as of the time that I am writing this, doesn't support having
+the terminal emulator set $TERM to something adequately descriptive.  In cases
+like this, something like the following would be appropriate:
+>
+    if &term =~ '^\(xterm\|screen\)$' && $COLORTERM == 'gnome-terminal'
+      set t_Co=256
+    endif
+
+==============================================================================
+3. Configuration                                          *csapprox-configure*
+
+There are several global variables that can be set to configure the behavior
+of CSApprox.  They are listed roughly based on the likelihood that the end
+user might want to know about them.
+
+g:CSApprox_loaded                                          *g:CSApprox_loaded*
+    If set in your |vimrc|, CSApprox is not loaded.  Has no effect on
+    snapshotted schemes.
+
+g:CSApprox_verbose_level                            *g:CSApprox_verbose_level*
+    When CSApprox is run, the 'verbose' option will be temporarily raised to
+    the value held in this variable unless it is already greater.  The default
+    value is 1, which allows CSApprox to default to warning whenever something
+    is wrong, even if it is recoverable, but allows the user to quiet us if he
+    wants by changing this variable to 0.  The most important messages will be
+    shown at verbosity level 1; some less important ones will be shown at
+    higher verbosity levels.  Has no effect on snapshotted schemes.
+
+g:CSApprox_eterm                                            *g:CSApprox_eterm*
+    If set to a non-zero number, CSApprox will use the Eterm palette when
+    'term' is set to "xterm" or begins with "screen".  Otherwise, the xterm
+    palette would be used.  This also affects snapshotted schemes.
+
+g:CSApprox_konsole                                        *g:CSApprox_konsole*
+    If set to a non-zero number, CSApprox will use the Konsole palette when
+    'term' is set to "xterm" or begins with "screen".  Otherwise, the xterm
+    palette would be used.  This also affects snapshotted schemes.
+
+g:CSApprox_attr_map                                      *g:CSApprox_attr_map*
+    Since some attributes (like 'guisp') can't be used in a terminal, and
+    others (like 'italic') are often very ugly in terminals, a generic way to
+    map between a requested attribute and another attribute is included.  This
+    variable should be set to a Dictionary, where the keys are strings
+    representing the attributes the author wanted set, and the values are the
+    strings that the user wants set instead.  If a value is '', it means the
+    attribute should just be ignored.  The default is to replace 'italic' with
+    'underline', and to use 'fg' instead of 'sp': >
+        let g:CSApprox_attr_map = { 'italic' : 'underline', 'sp' : 'fg' }
+<
+    Your author prefers disabling bold and italic entirely, so uses this: >
+        let g:CSApprox_attr_map = { 'bold' : '', 'italic' : '', 'sp' : 'fg' }
+<
+
+    Note: This transformation is considered at the time a snapshotted scheme
+          is created, rather than when it is used.
+
+    Note: You can only map an attribute representing a color to another
+          attribute representing a color; likewise with boolean attributes.
+          After all, sp -> bold and italic -> fg would be nonsensical.
+
+                          *g:CSApprox_hook_pre* *g:CSApprox_hook_{scheme}_pre*
+                        *g:CSApprox_hook_post* *g:CSApprox_hook_{scheme}_post*
+g:CSApprox_hook_pre
+g:CSApprox_hook_post
+g:CSApprox_hook_{scheme}_pre
+g:CSApprox_hook_{scheme}_post                                 *csapprox-hooks*
+    These variables provide a method for adjusting tweaking the approximation
+    algorithm, either for all schemes, or on a per scheme basis.  For
+    snapshotted schemes, these will only take effect when the snapshotted
+    scheme is created, rather than when it is used.  Each of these variables
+    may be set to either a String containing a command to be :execute'd, or a
+    List of such Strings.  The _pre hooks are executed before any
+    approximations have been done.  In order to affect the approximation at
+    this stage, you would need to change the gui colors for a group; the cterm
+    colors will then be approximated from those gui colors.  Example:
+>
+      let g:CSApprox_hook_pre = 'hi Comment guibg=#ffddff'
+<
+    The advantage to tweaking the colors at this stage is that CSApprox will
+    handle approximating the given gui colors to the proper cterm colors,
+    regardless of the number of colors the terminal supports.  The
+    disadvantage is that certain things aren't possible, including clearing
+    the background or foreground color for a group, selecting a precise cterm
+    color to be used, and overriding the mappings made by g:CSApprox_attr_map.
+    Another notable disadvantage is that overriding things at this level will
+    actually affect the gui colors, in case the :gui is used to start gvim
+    from the running vim instance.
+
+    To overcome these disadvantages, the _post hooks are provided.  These
+    hooks will be executed only after all approximations have been completed.
+    At this stage, in order to have changes appear the cterm* colors must be
+    modified.  For example:
+                                                       *csapprox-transparency*
+>
+      let g:CSApprox_hook_post = ['hi Normal  ctermbg=NONE ctermfg=NONE',
+                                \ 'hi NonText ctermbg=NONE ctermfg=NONE' ]
+<
+    Setting g:CSApprox_hook_post as shown above will clear the background of
+    the Normal and NonText groups, forcing the terminal's default background
+    color to be used instead, including any pseudotransparency done by that
+    terminal emulator.  As noted, though, the _post functions do not allow
+    CSApprox to approximate the colors.  This may be desired, but if this is
+    an inconvenience the function named by g:CSApprox_approximator_function
+    can still be called manually.  For example:
+>
+      let g:CSApprox_hook_post = 'exe "hi Comment ctermbg="'
+                      \ . '. g:CSApprox_approximator_function(0xA0,0x50,0x35)'
+<
+    The _{scheme}_ versions are exactly like their counterparts, except that
+    they will only be executed if the value of g:colors_name matches the
+    scheme name embedded in the variable name.  They will be executed after
+    the corresponding hook without _{scheme}_, which provides a way to
+    override a less specific hook with a more specific one.  For example, to
+    clear the Normal and NonText groups, but only for the colorscheme
+    "desert", one could do the following:
+>
+    let g:CSApprox_hook_desert_post = ['hi Normal ctermbg=NONE ctermfg=NONE',
+                                    \ 'hi NonText ctermbg=NONE ctermfg=NONE' ]
+<
+    One final example: If you want CSApprox to be active for nearly all
+    colorschemes, but want one or two particular schemes to be ignored, you
+    can take advantage of the CSApprox logic that skips over any color scheme
+    that is already high color by setting a color to a number above 255.  Note
+    that most colors greater than 15 will work, but some will not - 256 should
+    always work.  For instance, you can prevent CSApprox from modifying the
+    colors of the zellner colorscheme like this:
+>
+    let g:CSApprox_hook_zellner_pre = 'hi _FakeGroup ctermbg=256'
+<
+    NOTE: Any characters that would stop the string stored in g:colors_name
+          from being a valid variable name will be removed before the
+          _{scheme}_ hook is searched.  Basically, this means that first all
+          characters that are neither alphanumeric nor underscore will be
+          removed, then any leading digits will be removed.  So, for a
+          colorscheme named "123 foo_bar-baz456.vim", the hook searched for
+          will be, eg, g:CSApprox_hook_foo_barbaz456_post
+
+g:CSApprox_use_showrgb                                *g:CSApprox_use_showrgb*
+    By default, CSApprox will use a built in mapping of color names to values.
+    This optimization greatly helps speed, but means that colors addressed by
+    name might not match up perfectly between gvim (which uses the system's
+    real rgb database) and CSApprox (which uses the builtin database).  To
+    force CSApprox to try the systemwide database first, and only fall back on
+    the builtin database if it isn't available, set this variable non-zero.
+
+g:CSApprox_approximator_function            *g:CSApprox_approximator_function*
+    If the default approximation function doesn't work well enough, the user
+    (or another author wishing to extend this plugin) can write another
+    approximation function.  This function should take three numbers,
+    representing r, g, and b in decimal, and return the index on the color
+    cube that best matches those colors.  Assigning a |Funcref| to this
+    variable will override the default approximator with the one the Funcref
+    references.  This option will take effect at the time a snapshotted scheme
+    is created, rather than when it's used.
+
+g:CSApprox_redirfallback                            *g:CSApprox_redirfallback*
+    Until Vim 7.2.052, there was a bug in the Vim function synIDattr() that
+    made it impossible to determine syntax information about the |guisp|
+    attribute.  CSApprox includes a workaround for this problem, as well as a
+    test that ought to disable this workaround if synIDattr() works properly.
+    If this test should happen to give improper results somehow, the user can
+    force the behavior with this variable.  When set to 1, the workaround will
+    always be used, and when set to 0, synIDattr() is blindly used.  Needless
+    to say, if this automatic detection should ever fail, the author would
+    like to be notified!  This option will take effect at the time a
+    snapshotted scheme is created, rather than when it's used.
+
+==============================================================================
+4. Rationale/Design                                          *csapprox-design*
+
+There is a wealth of colorschemes available for Vim.  Unfortunately, since
+traditional terminal emulators have only supported 2, 8 or 16 colors,
+colorscheme authors have tended to avoid writing colorschemes for terminal
+Vim, sticking instead to GVim.  Even now that nearly every popular terminal
+supports either 88 or 256 colors, few colorschemes are written to support
+them.  This may be because the terminal color codes are just numbers from 0 to
+87 or 255 with no semantic meaning, or because the same number doesn't yield
+the same color in all terminals, or simply because the colorscheme author
+doesn't use the terminal and doesn't want to take the time to support
+terminals.
+
+Whatever the reason, this leaves users of many modern terminal emulators in
+the awkward position of having a terminal emulator that supports many colors,
+but having very few colorschemes that were written to utilize those colors.
+
+This is where CSApprox comes in.  It attempts to fill this void allowing GVim
+colorschemes to be used in terminal Vim.  CSApprox has two distinct modes of
+operation.  In the first mode, it attempts to make GVim colorschemes
+transparently backwards compatible with terminal Vim in a high color terminal.
+Basically, whenever a colorscheme is run it should set some colors for the
+GUI, and this script will then run and attempt to figure out the closest color
+available in the terminal's color palette to the color the scheme author asked
+for.  Unfortunately, this does not work well all the time, and it has some
+limitations (see |csapprox-limitations|).  Most of the time, however, this
+gives a very close approximation to the GVim colors without requiring any
+changes to the colorscheme, or any user interaction.  It only requires that
+the plugin be installed on the machine where Vim is being run, and that the
+user's environment meets the needs specified at |csapprox-requirements|.  In
+the event that this doesn't work, a second option - using :CSApproxSnapshot
+to create a new, 88-/256-color capable colorscheme - is available.
+
+Ideally, the aim is for CSApprox to be completely transparent to the user.
+This is why the approach I take is entirely different from the GuiColorScheme
+script, which will break on any but the simplest colorschemes.  Unfortunately,
+given the difficulty of determining exactly which terminal emulator the user
+is running, and what features it supports, and which color palette it's using,
+perfect transparency is difficult.  So, to this end, I've attempted to default
+to settings that make it unlikely that this script ever makes things worse
+(this is why I chose not to override t_Co to 256 myself), and I've attempted
+to make it easy to override my choice of defaults when necessary (through
+g:CSApprox_approximator_function, g:CSApprox_konsole, g:CSApprox_eterm,
+g:CSApprox_attr_map, etc).
+
+In the event that the transparent solution is undesirable, or that the user's
+environment can't be configured to allow it (no GVim and no Vim with +gui, for
+instance), |:CSApproxSnapshot| should provide a workable alternative - less
+cool, and less flexible, but it will work in more environments, and the
+snapshotted colorscheme will even work in Vim 6.
+
+If any of my design choices seem to be causing extra work with no real
+advantages, though, I'd like to hear about it.  Feel free to email me with any
+improvements or complaints.
+
+==============================================================================
+5. Known Bugs and Limitations                           *csapprox-limitations*
+
+GUI support is required for transparently adapting schemes.
+
+  There is nothing I can do about this given my chosen design.  CSApprox works
+  by being notified every time a colorscheme sets some GUI colors, then
+  approximating those colors to similar terminal colors.  Unfortunately, when
+  Vim is not built with GUI support, it doesn't bother to store the GUI
+  colors, so querying for them fails.  This leaves me completely unable to
+  tell what the colorscheme was trying to do.  See |csapprox-+gui| for some
+  potential workarounds if your distribution doesn't provide a Vim with +gui.
+
+User intervention is sometimes required for information about the terminal.
+
+  This is really an insurmountable problem.  Unfortunately, most terminal
+  emulators default to setting $TERM to 'xterm', even when they're not really
+  compatible with an xterm.  $TERM is really the only reliable way to
+  find anything at all out about the terminal you're running in, so there's no
+  way to know if the terminal supports 88 or 256 colors without either the
+  terminal telling me (using $TERM) or the user telling me (using 't_Co').
+  Similarly, unless $TERM is set to something that implies a certain color
+  palette ought to be used, there's no way for me to know, so I'm forced to
+  default to the most common, xterm's palette, and allow the user to override
+  my choice with |g:CSApprox_konsole| or |g:CSApprox_eterm|.  An example of
+  configuring Vim to work around a terminal where $TERM is set to something
+  generic without configuring the terminal properly is shown at
+  |csapprox-terminal-example|.
+
+Some colorschemes could fail to be converted if they try to be too smart.
+
+  A colorscheme could decide to only set colors for the mode Vim is running
+  in.  If a scheme only sets GUI colors when the GUI is running, instead of
+  using the usual approach of setting all colors and letting Vim choose which
+  to use, my approach falls apart.  My method for figuring out what the scheme
+  author wants the scheme to look like absolutely depends upon him setting the
+  GUI colors in all modes.  Fortunately, the few colorschemes that do this
+  seem to be, by and large, intended for 256 color terminals already, meaning
+  that skipping them is the proper behavior.  Note that this will only affect
+  transparently adapted schemes and snapshots made from terminal Vim;
+  snapshots made from GVim are immune to this problem.
+
+Transparently adapting schemes is slow.
+
+  For me, it takes Vim's startup time from 0.15 seconds to 0.35 seconds.  This
+  is probably still acceptable, but it is definitely worth trying to cut down
+  on this time in future versions.  Snapshotted schemes are faster to use,
+  since all of the hard evaluations are made when they're made instead of when
+  they're used.
+
+  NOTE: As of CSApprox 3.50, the overhead is down to about 0.10 seconds on my
+        test machine.
+
+==============================================================================
+6. Appendix - Terminals and Palettes                  *csapprox-terminal-list*
+
+What follows is a list of terminals known to have and known not to have high
+color support.  This list is certainly incomplete; feel free to contact me
+with more to add to either list.
+
+                                                     *csapprox-terminals-good*
+------------------------------- Good Terminals -------------------------------
+
+The most recent versions of each of these terminals can be compiled with
+either 88 or 256 color support.
+
+                                                              *csapprox-xterm*
+xterm:
+    256 color palette
+    Colors composed of: [ 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF ]
+    Greys composed of:  [ 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E,
+                          0x58, 0x62, 0x6C, 0x76, 0x80, 0x8A, 0x94, 0x9E,
+                          0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE ]
+
+                                                              *csapprox-urxvt*
+rxvt-unicode (urxvt):
+    88 colors by default (but a patch is available to use xterm's palette)
+    Colors composed of: [ 0x00, 0x8B, 0xCD, 0xFF ]
+    Greys composed of:  [ 0x2E, 0x5C, 0x73, 0x8B, 0xA2, 0xB9, 0xD0, 0xE7 ]
+
+                                               *csapprox-pterm* *csapprox-putty*
+PuTTY (pterm; putty.exe):
+    256 colors; same palette as xterm
+
+                                                              *csapprox-mrxvt*
+Mrxvt (mrxvt):
+    256 colors; same palette as xterm
+
+                                                     *csapprox-gnome-terminal*
+GNOME Terminal (gnome-terminal):
+    256 colors; same palette as xterm
+
+                                                            *csapprox-roxterm*
+ROXTerm (roxterm):
+    256 colors; same palette as xterm
+
+                                                     *csapprox-xfce4-terminal*
+Terminal (xfce4-terminal):
+    256 colors; same palette as xterm
+
+                                                          *csapprox-iterm.app*
+iTerm (iTerm.app):
+    256 colors; same palette as xterm
+                                                            *csapprox-konsole*
+Konsole (konsole):
+    256 color palette
+    Colors composed of: [ 0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF ]
+    Same greyscales as xterm
+    You should set the g:CSApprox_konsole variable unless $TERM begins with
+    'konsole', case insensitive
+
+                                                              *csapprox-eterm*
+eterm (Eterm):
+    256 color palette
+    Colors composed of: [ 0x00, 0x2A, 0x55, 0x7F, 0xAA, 0xD4 ]
+    Same greyscales as xterm
+    You should set the g:CSApprox_eterm variable unless $TERM begins with
+    'eterm', case insensitive
+
+                                                             *csapprox-screen*
+GNU Screen (screen):
+    256 color support.  Internally, uses the xterm palette, but this is only
+    relevant when running screen inside a terminal with fewer than 256 colors,
+    in which case screen will attempt to map between its own 256 color cube
+    and the colors supported by the real terminal to the best of its ability,
+    in much the same way as CSApprox maps between GUI and terminal colors.
+
+                                                      *csapprox-terminals-bad*
+-------------------------------- Bad Terminals -------------------------------
+This is a list of terminals known _not_ to have high color support.  If any of
+these terminals have high color support added at some point in the future,
+please tell me and I'll update this information.
+
+                                                       *csapprox-terminal.app*
+Terminal.app (as of OS X 10.5.2)
+
+                                                              *csapprox-aterm*
+aterm (as of version 1.00.01)
+
+                                                             *csapprox-xiterm*
+xiterm (as of version 0.5)
+
+                                                              *csapprox-wterm*
+wterm (as of version 6.2.9)
+
+                                                             *csapprox-mlterm*
+mlterm (as of version 2.9.4)
+
+                                                              *csapprox-kterm*
+kterm (as of version 6.2.0)
+
+==============================================================================
+7. Changelog                                              *csapprox-changelog*
+
+ 3.50   01 Apr 2009   Fix a major regression that prevented the Eterm and
+                      Konsole colors from being correctly snapshotted
+
+                      Fix a related bug causing incorrect terminal colors
+                      after calling :CSApproxSnapshot
+
+                      Fix a bug causing black to be used instead of dark grey
+
+                      Have snapshots calculate g:colors_name programmatically
+
+                      Introduce many tweaks for better speed
+
+                      Clarify some things at :help csapprox-terminal-example
+
+                      Default to using our own list of rgb.txt colors rather
+                      than searching, for performance.  Add a new variable,
+                      g:CSApprox_use_showrgb, which forces us to try finding
+                      the colors using the "showrgb" program instead, and fall
+                      back on our own list if it isn't available
+
+                      Remove g:CSApprox_extra_rgb_txt_dirs - not needed in
+                      light of the above change
+
+ 3.05   31 Jan 2009   Fix a harmless "Undefined variable" error in
+                      :CSApproxSnapshot
+
+                      Fix a behavioral bug when dumping out colors defined
+                      external to the scheme.
+
+ 3.00   21 Jan 2009   Update the docs for better info on :CSApproxSnapshot
+
+                      Allow snapshotted schemes to work on Vim 6, and work
+                      properly in Konsole and Eterm (thanks David Majnemer!)
+
+                      Fix a bug causing a syntax error when using GVim while
+                      CSApprox was loaded.  (thanks again, David Majnemer!)
+
+ 2.00   14 Dec 2008   Add a hooks system, allowing users to specify a command
+                      to run, either before or after the approximation
+                      algorithm is run, for all schemes or one specific one.
+
+                      Also rewrite :CSApproxSnapshot to be more maintainable
+                      and less of a hack, and fix several bugs that it
+                      contained.
+
+ 1.50   19 Nov 2008   Add CSApproxSnapshot command, as an alternative solution
+                      when the user has gvim or a vim with gui support, but
+                      sometimes needs to use a vim without gui support.
+
+ 1.10   28 Oct 2008   Enable running on systems with no rgb.txt (Penn Su)
+                      Begin distributing a copy of rgb.txt with CSApprox
+
+ 1.00   04 Oct 2008   First public release
+
+ 0.90   14 Sep 2008   Initial beta release
+
+==============================================================================
+8. Contact Info                                              *csapprox-author*
+
+Your author, a Vim nerd with some free time, was sick of seeing terminals
+always get the short end of the stick.  He'd like to be notified of any
+problems you find - after all, he took the time to write all this lovely
+documentation, and this plugin, which took more time than you could possibly
+imagine to get working transparently for every colorscheme he could get his
+hands on.  You can contact him with any problems or praises at mjw@drexel.edu
+
+==============================================================================
+vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl:

+ 116 - 0
vim/doc/coffee-script.txt

@@ -0,0 +1,116 @@
+*coffee-script.txt*                                         For Vim version 7.3
+
+=============================================================================
+Author:  Mick Koch <kchmck@gmail.com>		*coffee-script-author*
+License: WTFPL (see |coffee-script-license|)
+=============================================================================
+
+CONTENTS					*coffee-script-contents*
+
+|coffee-script-introduction|		Introduction and Feature Summary
+|coffee-script-commands|			Commands
+|coffee-script-settings|			Settings
+
+{Vi does not have any of this}
+
+=============================================================================
+
+INTRODUCTION					*coffee-script*
+						*coffee-script-introduction*
+
+This plugin adds support for CoffeeScript syntax, indenting, and compiling.
+Also included is an eco syntax and support for CoffeeScript in Haml and HTML.
+
+COMMANDS					*coffee-script-commands*
+
+						*:CoffeeMake*
+:CoffeeMake[!] {opts}	Wrapper around |:make| that also passes options in
+                        |g:coffee_make_options| to the compiler. Use |:silent|
+                        to hide compiler output. See |:make| for more
+                        information about the bang and other helpful commands.
+
+						*:CoffeeCompile*
+:[range]CoffeeCompile [vertical] [{win-size}]
+			Shows how the current file or [range] is compiled
+			to JavaScript. [vertical] (or vert) splits the
+			compile buffer vertically instead of horizontally, and
+			{win-size} sets the initial size of the buffer. It can
+			be closed quickly with the "q" key.
+
+:CoffeeCompile {watch} [vertical] [{win-size}]
+			The watch mode of :CoffeeCompile emulates the "Try
+			CoffeeScript" live preview on the CoffeeScript web
+			site. After making changes to the source file,
+			exiting insert mode will cause the preview buffer to
+			update automatically. {watch} should be given as
+                        "watch" or "unwatch," where the latter will stop the
+                        automatic updating. [vertical] is recommended, and
+                        'scrollbind' is useful.
+
+						*:CoffeeRun*
+:[range]CoffeeRun	Compiles the file or [range] and runs the resulting
+			JavaScript, displaying the output.
+
+SETTINGS					*coffee-script-settings*
+
+You can configure plugin behavior using global variables and syntax commands
+in your |vimrc|.
+
+Global Settings~
+
+						*g:coffee_make_options*
+Set default options |CoffeeMake| should pass to the compiler.
+>
+	let coffee_make_options = '--bare'
+<
+						*g:coffee_compile_vert*
+Split the CoffeeCompile buffer vertically by default.
+>
+	let coffee_compile_vert = 1
+
+Syntax Highlighting~
+						*ft-coffee-script-syntax*
+Trailing whitespace is highlighted as an error by default. This can be
+disabled with:
+>
+	hi link coffeeSpaceError NONE
+
+Trailing semicolons are also considered an error (for help transitioning from
+JavaScript.) This can be disabled with:
+>
+	hi link coffeeSemicolonError NONE
+
+Reserved words like {function} and {var} are highlighted where they're not
+allowed in CoffeeScript. This can be disabled with:
+>
+        hi link coffeeReservedError NONE
+
+COMPILER					*compiler-coffee-script*
+
+A CoffeeScript compiler is provided as a wrapper around {coffee} and can be
+loaded with;
+>
+    compiler coffee
+
+This is done automatically when a CoffeeScript file is opened if no other
+compiler is loaded.
+
+=============================================================================
+
+LICENSE							*coffee-script-license*
+
+		DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+			Version 2, December 2004
+
+     Copyright (C) 2010 to 2011 Mick Koch <kchmck@gmail.com>
+
+     Everyone is permitted to copy and distribute verbatim or modified
+     copies of this license document, and changing it is allowed as long
+     as the name is changed.
+
+		DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+       TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+      0. You just DO WHAT THE FUCK YOU WANT TO.
+
+ vim:tw=78:ts=8:ft=help:norl:

+ 1183 - 0
vim/doc/command-t.txt

@@ -0,0 +1,1183 @@
+*command-t.txt* Command-T plug-in for Vim         *command-t*
+
+CONTENTS                                        *command-t-contents*
+
+ 1. Introduction            |command-t-intro|
+ 2. Requirements            |command-t-requirements|
+ 3. Installation            |command-t-installation|
+ 3. Managing using Pathogen |command-t-pathogen|
+ 4. Trouble-shooting        |command-t-trouble-shooting|
+ 5. Usage                   |command-t-usage|
+ 6. Commands                |command-t-commands|
+ 7. Mappings                |command-t-mappings|
+ 8. Options                 |command-t-options|
+ 9. FAQ                     |command-t-faq|
+10. Tips                    |command-t-tips|
+11. Authors                 |command-t-authors|
+12. Development             |command-t-development|
+13. Website                 |command-t-website|
+14. Donations               |command-t-donations|
+15. License                 |command-t-license|
+16. History                 |command-t-history|
+
+
+INTRODUCTION                                    *command-t-intro*
+
+The Command-T plug-in provides an extremely fast, intuitive mechanism for
+opening files and buffers with a minimal number of keystrokes. It's named
+"Command-T" because it is inspired by the "Go to File" window bound to
+Command-T in TextMate.
+
+Files are selected by typing characters that appear in their paths, and are
+ordered by an algorithm which knows that characters that appear in certain
+locations (for example, immediately after a path separator) should be given
+more weight.
+
+To search efficiently, especially in large projects, you should adopt a
+"path-centric" rather than a "filename-centric" mentality. That is you should
+think more about where the desired file is found rather than what it is
+called. This means narrowing your search down by including some characters
+from the upper path components rather than just entering characters from the
+filename itself.
+
+Screencasts demonstrating the plug-in can be viewed at:
+
+  https://wincent.com/products/command-t
+
+
+REQUIREMENTS                                    *command-t-requirements*
+
+The plug-in requires Vim compiled with Ruby support, a compatible Ruby
+installation at the operating system level, and a C compiler to build
+the Ruby extension.
+
+
+1. Vim compiled with Ruby support ~
+
+You can check for Ruby support by launching Vim with the --version switch:
+
+  vim --version
+
+If "+ruby" appears in the version information then your version of Vim has
+Ruby support.
+
+Another way to check is to simply try using the :ruby command from within Vim
+itself:
+
+  :ruby 1
+
+If your Vim lacks support you'll see an error message like this:
+
+  E319: Sorry, the command is not available in this version
+
+The version of Vim distributed with OS X may not include Ruby support (for
+example, Snow Leopard, which was the current version of OS X when Command-T
+was first released, did not support Ruby in the system Vim, but the current
+version of OS X at the time of writing, Mavericks, does). All recent versions
+of MacVim come with Ruby support; it is available from:
+
+  http://github.com/b4winckler/macvim/downloads
+
+For Windows users, the Vim 7.2 executable available from www.vim.org does
+include Ruby support, and is recommended over version 7.3 (which links against
+Ruby 1.9, but apparently has some bugs that need to be resolved).
+
+
+2. Ruby ~
+
+In addition to having Ruby support in Vim, your system itself must have a
+compatible Ruby install. "Compatible" means the same version as Vim itself
+links against. If you use a different version then Command-T is unlikely
+to work (see |command-t-trouble-shooting| below).
+
+On OS X Snow Leopard, Lion and Mountain Lion, the system comes with Ruby 1.8.7
+and all recent versions of MacVim (the 7.2 snapshots and 7.3) are linked
+against it.
+
+On OS X Mavericks, the default system ruby is 2.0, but MacVim continues to
+link against 1.8.7, which is also present on the system at:
+
+  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
+
+On Linux and similar platforms, the linked version of Ruby will depend on
+your distribution. You can usually find this out by examining the
+compilation and linking flags displayed by the |:version| command in Vim, and
+by looking at the output of:
+
+  :ruby puts "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
+
+A suitable Ruby environment for Windows can be installed using the Ruby
+1.8.7-p299 RubyInstaller available at:
+
+  http://rubyinstaller.org/downloads/archives
+
+If using RubyInstaller be sure to download the installer executable, not the
+7-zip archive. When installing mark the checkbox "Add Ruby executables to your
+PATH" so that Vim can find them.
+
+
+3. C compiler ~
+
+Part of Command-T is implemented in C as a Ruby extension for speed, allowing
+it to work responsively even on directory hierarchies containing enormous
+numbers of files. As such, a C compiler is required in order to build the
+extension and complete the installation.
+
+On OS X, this can be obtained by installing the Xcode Tools from the App
+Store.
+
+On Windows, the RubyInstaller Development Kit can be used to conveniently
+install the necessary tool chain:
+
+  http://rubyinstaller.org/downloads/archives
+
+At the time of writing, the appropriate development kit for use with Ruby
+1.8.7 is DevKit-3.4.5r3-20091110.
+
+To use the Development Kit extract the archive contents to your C:\Ruby
+folder.
+
+
+INSTALLATION                                    *command-t-installation*
+
+You can install Command-T by obtaining the source files and building the C
+extension. The recommended way to get the source is by using a plug-in
+management system such as Pathogen (see |command-t-pathogen|).
+
+Command-T is also distributed as a "vimball" which means that it can be
+installed by opening it in Vim and then sourcing it:
+
+  :e command-t.vba
+  :so %
+
+The files will be installed in your |'runtimepath'|. To check where this is
+you can issue:
+
+  :echo &rtp
+
+The C extension must then be built, which can be done from the shell. If you
+use a typical |'runtimepath'| then the files were installed inside ~/.vim and
+you can build the extension with:
+
+  cd ~/.vim/ruby/command-t
+  ruby extconf.rb
+  make
+
+Note: If you are an RVM or rbenv user, you must perform the build using the
+same version of Ruby that Vim itself is linked against. This will often be the
+system Ruby, which can be selected before issuing the "make" command with one
+of the following commands:
+
+  rvm use system
+  rbenv local system
+
+Note: If you are on OS X Mavericks and compiling against MacVim, the default
+system Ruby is 2.0 but MacVim still links against the older 1.8.7 Ruby that is
+also bundled with the system; in this case the build command becomes:
+
+  cd ~/.vim/ruby/command-t
+  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb
+  make
+
+Note: Make sure you compile targeting the same architecture Vim was built for.
+For instance, MacVim binaries are built for i386, but sometimes GCC compiles
+for x86_64. First you have to check the platform Vim was built for:
+
+  vim --version
+  ...
+  Compilation: gcc ... -arch i386 ...
+  ...
+
+and make sure you use the correct ARCHFLAGS during compilation:
+
+  export ARCHFLAGS="-arch i386"
+  make
+
+Note: If you are on Fedora 17+, you can install Command-T from the system
+repository with:
+
+  su -c 'yum install vim-command-t'
+
+MANAGING USING PATHOGEN                         *command-t-pathogen*
+
+Pathogen is a plugin that allows you to maintain plugin installations in
+separate, isolated subdirectories under the "bundle" directory in your
+|'runtimepath'|. The following examples assume that you already have
+Pathogen installed and configured, and that you are installing into
+~/.vim/bundle. For more information about Pathogen, see:
+
+  http://www.vim.org/scripts/script.php?script_id=2332
+
+If you manage your entire ~/.vim folder using Git then you can add the
+Command-T repository as a submodule:
+
+  cd ~/.vim
+  git submodule add git://git.wincent.com/command-t.git bundle/command-t
+  git submodule init
+
+Or if you just wish to do a simple clone instead of using submodules:
+
+  cd ~/.vim
+  git clone git://git.wincent.com/command-t.git bundle/command-t
+
+Once you have a local copy of the repository you can update it at any time
+with:
+
+  cd ~/.vim/bundle/command-t
+  git pull
+
+Or you can switch to a specific release with:
+
+  cd ~/.vim/bundle/command-t
+  git checkout 0.8b
+
+After installing or updating you must build the extension:
+
+  cd ~/.vim/bundle/command-t/ruby/command-t
+  ruby extconf.rb
+  make
+
+While the Vimball installation automatically generates the help tags, under
+Pathogen it is necessary to do so explicitly from inside Vim:
+
+  :call pathogen#helptags()
+
+
+TROUBLE-SHOOTING                                *command-t-trouble-shooting*
+
+Most installation problems are caused by a mismatch between the version of
+Ruby on the host operating system, and the version of Ruby that Vim itself
+linked against at compile time. For example, if one is 32-bit and the other is
+64-bit, or one is from the Ruby 1.9 series and the other is from the 1.8
+series, then the plug-in is not likely to work.
+
+As such, on OS X, I recommend using the standard Ruby that comes with the
+system (currently 1.8.7) along with the latest version of MacVim (currently
+version 7.3). If you wish to use custom builds of Ruby or of MacVim (not
+recommmended) then you will have to take extra care to ensure that the exact
+same Ruby environment is in effect when building Ruby, Vim and the Command-T
+extension.
+
+For Windows, the following combination is known to work:
+
+  - Vim 7.2 from http://www.vim.org/download.php:
+      ftp://ftp.vim.org/pub/vim/pc/gvim72.exe
+  - Ruby 1.8.7-p299 from http://rubyinstaller.org/downloads/archives:
+      http://rubyforge.org/frs/download.php/71492/rubyinstaller-1.8.7-p299.exe
+  - DevKit 3.4.5r3-20091110 from http://rubyinstaller.org/downloads/archives:
+      http://rubyforge.org/frs/download.php/66888/devkit-3.4.5r3-20091110.7z
+
+If a problem occurs the first thing you should do is inspect the output of:
+
+  ruby extconf.rb
+  make
+
+During the installation, and:
+
+  vim --version
+
+And compare the compilation and linker flags that were passed to the
+extension and to Vim itself when they were built. If the Ruby-related
+flags or architecture flags are different then it is likely that something
+has changed in your Ruby environment and the extension may not work until
+you eliminate the discrepancy.
+
+
+USAGE                                           *command-t-usage*
+
+Bring up the Command-T file window by typing:
+
+  <Leader>t
+
+This mapping is set up automatically for you, provided you do not already have
+a mapping for <Leader>t or |:CommandT|. You can also bring up the file window
+by issuing the command:
+
+  :CommandT
+
+A prompt will appear at the bottom of the screen along with a file window
+showing all of the files in the current directory (as returned by the
+|:pwd| command).
+
+For the most efficient file navigation within a project it's recommended that
+you |:cd| into the root directory of your project when starting to work on it.
+If you wish to open a file from outside of the project folder you can pass in
+an optional path argument (relative or absolute) to |:CommandT|:
+
+  :CommandT ../path/to/other/files
+
+Type letters in the prompt to narrow down the selection, showing only the
+files whose paths contain those letters in the specified order. Letters do not
+need to appear consecutively in a path in order for it to be classified as a
+match.
+
+Once the desired file has been selected it can be opened by pressing <CR>.
+(By default files are opened in the current window, but there are other
+mappings that you can use to open in a vertical or horizontal split, or in
+a new tab.) Note that if you have |'nohidden'| set and there are unsaved
+changes in the current window when you press <CR> then opening in the current
+window would fail; in this case Command-T will open the file in a new split.
+
+The following mappings are active when the prompt has focus:
+
+    <BS>        delete the character to the left of the cursor
+    <Del>       delete the character at the cursor
+    <Left>      move the cursor one character to the left
+    <C-h>       move the cursor one character to the left
+    <Right>     move the cursor one character to the right
+    <C-l>       move the cursor one character to the right
+    <C-a>       move the cursor to the start (left)
+    <C-e>       move the cursor to the end (right)
+    <C-u>       clear the contents of the prompt
+    <Tab>       change focus to the file listing
+
+The following mappings are active when the file listing has focus:
+
+    <Tab>       change focus to the prompt
+
+The following mappings are active when either the prompt or the file listing
+has focus:
+
+    <CR>        open the selected file
+    <C-CR>      open the selected file in a new split window
+    <C-s>       open the selected file in a new split window
+    <C-v>       open the selected file in a new vertical split window
+    <C-t>       open the selected file in a new tab
+    <C-j>       select next file in the file listing
+    <C-n>       select next file in the file listing
+    <Down>      select next file in the file listing
+    <C-k>       select previous file in the file listing
+    <C-p>       select previous file in the file listing
+    <Up>        select previous file in the file listing
+    <C-f>       flush the cache (see |:CommandTFlush| for details)
+    <C-q>       place the current matches in the quickfix window
+    <C-c>       cancel (dismisses file listing)
+
+The following is also available on terminals which support it:
+
+    <Esc>       cancel (dismisses file listing)
+
+Note that the default mappings can be overriden by setting options in your
+~/.vimrc file (see the OPTIONS section for a full list of available options).
+
+In addition, when the file listing has focus, typing a character will cause
+the selection to jump to the first path which begins with that character.
+Typing multiple characters consecutively can be used to distinguish between
+paths which begin with the same prefix.
+
+
+COMMANDS                                        *command-t-commands*
+
+                                                *:CommandT*
+|:CommandT|     Brings up the Command-T file window, starting in the
+                current working directory as returned by the|:pwd|
+                command.
+
+                                                *:CommandTBuffer*
+|:CommandTBuffer|Brings up the Command-T buffer window.
+                This works exactly like the standard file window,
+                except that the selection is limited to files that
+                you already have open in buffers.
+
+                                                *:CommandTJumps*
+|:CommandTJump| Brings up the Command-T jumplist window.
+                This works exactly like the standard file window,
+                except that the selection is limited to files that
+                you already have in the jumplist. Note that jumps
+                can persist across Vim sessions (see Vim's |jumplist|
+                documentation for more info).
+
+                                                *:CommandTTag*
+|:CommandTTag| Brings up the Command-T window tags window, which can
+                be used to select from the tags, if any, returned by
+                Vim's |taglist()| function. See Vim's |tag| documentation
+                for general info on tags.
+
+                                                *:CommandTFlush*
+|:CommandTFlush|Instructs the plug-in to flush its path cache, causing
+                the directory to be rescanned for new or deleted paths
+                the next time the file window is shown (pressing <C-f> when
+                a match listing is visible flushes the cache immediately; this
+                mapping is configurable via the |g:CommandTRefreshMap|
+                setting). In addition, all configuration settings are
+                re-evaluated, causing any changes made to settings via the
+                |:let| command to be picked up.
+
+
+MAPPINGS                                        *command-t-mappings*
+
+By default Command-T comes with only two mappings:
+
+  <Leader>t     bring up the Command-T file window
+  <Leader>b     bring up the Command-T buffer window
+
+However, Command-T won't overwrite a pre-existing mapping so if you prefer
+to define different mappings use lines like these in your ~/.vimrc:
+
+  nnoremap <silent> <Leader>t :CommandT<CR>
+  nnoremap <silent> <Leader>b :CommandTBuffer<CR>
+
+Replacing "<Leader>t" or "<Leader>b" with your mapping of choice.
+
+Note that in the case of MacVim you actually can map to Command-T (written
+as <D-t> in Vim) in your ~/.gvimrc file if you first unmap the existing menu
+binding of Command-T to "New Tab":
+
+  if has("gui_macvim")
+    macmenu &File.New\ Tab key=<nop>
+    map <D-t> :CommandT<CR>
+  endif
+
+When the Command-T window is active a number of other additional mappings
+become available for doing things like moving between and selecting matches.
+These are fully described above in the USAGE section, and settings for
+overriding the mappings are listed below under OPTIONS.
+
+
+OPTIONS                                         *command-t-options*
+
+A number of options may be set in your ~/.vimrc to influence the behaviour of
+the plug-in. To set an option, you include a line like this in your ~/.vimrc:
+
+    let g:CommandTMaxFiles=20000
+
+To have Command-T pick up new settings immediately (that is, without having
+to restart Vim) you can issue the |:CommandTFlush| command after making
+changes via |:let|.
+
+Following is a list of all available options:
+
+                                               *g:CommandTMaxFiles*
+  |g:CommandTMaxFiles|                           number (default 30000)
+
+      The maximum number of files that will be considered when scanning the
+      current directory. Upon reaching this number scanning stops. This
+      limit applies only to file listings and is ignored for buffer
+      listings.
+
+                                               *g:CommandTMaxDepth*
+  |g:CommandTMaxDepth|                           number (default 15)
+
+      The maximum depth (levels of recursion) to be explored when scanning the
+      current directory. Any directories at levels beyond this depth will be
+      skipped.
+
+                                               *g:CommandTMaxCachedDirectories*
+  |g:CommandTMaxCachedDirectories|               number (default 1)
+
+      The maximum number of directories whose contents should be cached when
+      recursively scanning. With the default value of 1, each time you change
+      directories the cache will be emptied and Command-T will have to
+      rescan. Higher values will make Command-T hold more directories in the
+      cache, bringing performance at the cost of memory usage. If set to 0,
+      there is no limit on the number of cached directories.
+
+                                               *g:CommandTMaxHeight*
+  |g:CommandTMaxHeight|                          number (default: 0)
+
+      The maximum height in lines the match window is allowed to expand to.
+      If set to 0, the window will occupy as much of the available space as
+      needed to show matching entries.
+
+                                               *g:CommandTInputDebounce*
+  |g:CommandTInputDebounce|                      number (default: 50)
+
+      The number of milliseconds to wait before updating the match listing
+      following a key-press. This can be used to avoid wasteful recomputation
+      when making a rapid series of key-presses in a directory with many tens
+      (or hundreds) of thousands of files.
+
+                                               *g:CommandTFileScanner*
+  |g:CommandTFileScanner|                        string (default: 'ruby')
+
+      The underlying scanner implementation that should be used to explore the
+      filesystem. Possible values are:
+
+      - "ruby": uses built-in Ruby and should work everywhere, albeit slowly
+        on large (many tens of thousands of files) hierarchies.
+
+      - "find": uses the command-line tool of the same name, which can be much
+        faster on large projects because it is written in pure C, but may not
+        work on systems without the tool or with an incompatible version of
+        the tool.
+
+      - "watchman": uses Watchman (https://github.com/facebook/watchman) if
+        available; otherwise falls back to "find". Note that this scanner is
+        intended for use with very large hierarchies (hundreds of thousands of
+        files) and so the task of deciding which files should be included is
+        entirely delegated to Watchman; this means that settings which
+        Command-T would usually consult, such as 'wildignore' and
+        |g:CommandTScanDotDirectories| are ignored.
+
+                                               *g:CommandTMinHeight*
+  |g:CommandTMinHeight|                          number (default: 0)
+
+      The minimum height in lines the match window is allowed to shrink to.
+      If set to 0, will default to a single line. If set above the max height,
+      will default to |g:CommandTMaxHeight|.
+
+                                               *g:CommandTAlwaysShowDotFiles*
+  |g:CommandTAlwaysShowDotFiles|                 boolean (default: 0)
+
+      When showing the file listing Command-T will by default show dot-files
+      only if the entered search string contains a dot that could cause a
+      dot-file to match. When set to a non-zero value, this setting instructs
+      Command-T to always include matching dot-files in the match list
+      regardless of whether the search string contains a dot. See also
+      |g:CommandTNeverShowDotFiles|. Note that this setting only influences
+      the file listing; the buffer listing treats dot-files like any other
+      file.
+
+                                               *g:CommandTNeverShowDotFiles*
+  |g:CommandTNeverShowDotFiles|                  boolean (default: 0)
+
+      In the file listing, Command-T will by default show dot-files if the
+      entered search string contains a dot that could cause a dot-file to
+      match. When set to a non-zero value, this setting instructs Command-T to
+      never show dot-files under any circumstances. Note that it is
+      contradictory to set both this setting and
+      |g:CommandTAlwaysShowDotFiles| to true, and if you do so Vim will suffer
+      from headaches, nervous twitches, and sudden mood swings. This setting
+      has no effect in buffer listings, where dot files are treated like any
+      other file.
+
+                                               *g:CommandTScanDotDirectories*
+  |g:CommandTScanDotDirectories|                 boolean (default: 0)
+
+      Normally Command-T will not recurse into "dot-directories" (directories
+      whose names begin with a dot) while performing its initial scan. Set
+      this setting to a non-zero value to override this behavior and recurse.
+      Note that this setting is completely independent of the
+      |g:CommandTAlwaysShowDotFiles| and |g:CommandTNeverShowDotFiles|
+      settings; those apply only to the selection and display of matches
+      (after scanning has been performed), whereas
+      |g:CommandTScanDotDirectories| affects the behaviour at scan-time.
+
+      Note also that even with this setting off you can still use Command-T to
+      open files inside a "dot-directory" such as ~/.vim, but you have to use
+      the |:cd| command to change into that directory first. For example:
+
+        :cd ~/.vim
+        :CommandT
+
+                                               *g:CommandTMatchWindowAtTop*
+  |g:CommandTMatchWindowAtTop|                   boolean (default: 0)
+
+      When this setting is off (the default) the match window will appear at
+      the bottom so as to keep it near to the prompt. Turning it on causes the
+      match window to appear at the top instead. This may be preferable if you
+      want the best match (usually the first one) to appear in a fixed location
+      on the screen rather than moving as the number of matches changes during
+      typing.
+
+                                                *g:CommandTMatchWindowReverse*
+  |g:CommandTMatchWindowReverse|                  boolean (default: 0)
+
+      When this setting is off (the default) the matches will appear from
+      top to bottom with the topmost being selected. Turning it on causes the
+      matches to be reversed so the best match is at the bottom and the
+      initially selected match is the bottom most. This may be preferable if
+      you want the best match to appear in a fixed location on the screen
+      but still be near the prompt at the bottom.
+
+                                                *g:CommandTTagIncludeFilenames*
+  |g:CommandTTagIncludeFilenames|                 boolean (default: 0)
+
+      When this setting is off (the default) the matches in the |:CommandTTag|
+      listing do not include filenames.
+
+                                                *g:CommandTHighlightColor*
+  |g:CommandTHighlightColor|                      string (default: 'PmenuSel')
+
+      Specifies the highlight color that will be used to show the currently
+      selected item in the match listing window.
+
+                                                *g:CommandTWildIgnore*
+  |g:CommandTWildIgnore|                          string (default: none)
+
+      Optionally override Vim's global |'wildignore'| setting during Command-T
+      searches. If you wish to supplement rather than replace the global
+      setting, you can use a syntax like:
+
+        let g:CommandTWildIgnore=&wildignore . ",**/bower_components/*"
+
+      See also |command-t-wildignore|.
+
+As well as the basic options listed above, there are a number of settings that
+can be used to override the default key mappings used by Command-T. For
+example, to set <C-x> as the mapping for cancelling (dismissing) the Command-T
+window, you would add the following to your ~/.vimrc:
+
+  let g:CommandTCancelMap='<C-x>'
+
+Multiple, alternative mappings may be specified using list syntax:
+
+  let g:CommandTCancelMap=['<C-x>', '<C-c>']
+
+Following is a list of all map settings and their defaults:
+
+                              Setting   Default mapping(s)
+
+                                      *g:CommandTBackspaceMap*
+              |g:CommandTBackspaceMap|  <BS>
+
+                                      *g:CommandTDeleteMap*
+                 |g:CommandTDeleteMap|  <Del>
+
+                                      *g:CommandTAcceptSelectionMap*
+        |g:CommandTAcceptSelectionMap|  <CR>
+
+                                      *g:CommandTAcceptSelectionSplitMap*
+   |g:CommandTAcceptSelectionSplitMap|  <C-CR>
+                                      <C-s>
+
+                                      *g:CommandTAcceptSelectionTabMap*
+     |g:CommandTAcceptSelectionTabMap|  <C-t>
+
+                                      *g:CommandTAcceptSelectionVSplitMap*
+  |g:CommandTAcceptSelectionVSplitMap|  <C-v>
+
+                                      *g:CommandTToggleFocusMap*
+            |g:CommandTToggleFocusMap|  <Tab>
+
+                                      *g:CommandTCancelMap*
+                 |g:CommandTCancelMap|  <C-c>
+                                      <Esc> (not on all terminals)
+
+                                      *g:CommandTSelectNextMap*
+             |g:CommandTSelectNextMap|  <C-n>
+                                      <C-j>
+                                      <Down>
+
+                                      *g:CommandTSelectPrevMap*
+             |g:CommandTSelectPrevMap|  <C-p>
+                                      <C-k>
+                                      <Up>
+
+                                      *g:CommandTClearMap*
+                  |g:CommandTClearMap|  <C-u>
+
+                                      *g:CommandTRefreshMap*
+                |g:CommandTRefreshMap|  <C-f>
+
+                                      *g:CommandTQuickfixMap*
+               |g:CommandTQuickfixMap|  <C-q>
+
+                                      *g:CommandTCursorLeftMap*
+             |g:CommandTCursorLeftMap|  <Left>
+                                      <C-h>
+
+                                      *g:CommandTCursorRightMap*
+            |g:CommandTCursorRightMap|  <Right>
+                                      <C-l>
+
+                                      *g:CommandTCursorEndMap*
+              |g:CommandTCursorEndMap|  <C-e>
+
+                                      *g:CommandTCursorStartMap*
+            |g:CommandTCursorStartMap|  <C-a>
+
+In addition to the options provided by Command-T itself, some of Vim's own
+settings can be used to control behavior:
+
+                                               *command-t-wildignore*
+  |'wildignore'|                                 string (default: '')
+
+      Vim's |'wildignore'| setting is used to determine which files should be
+      excluded from listings. This is a comma-separated list of glob patterns.
+      It defaults to the empty string, but common settings include "*.o,*.obj"
+      (to exclude object files) or ".git,.svn" (to exclude SCM metadata
+      directories). For example:
+
+        :set wildignore+=*.o,*.obj,.git
+
+      A pattern such as "vendor/rails/**" would exclude all files and
+      subdirectories inside the "vendor/rails" directory (relative to
+      directory Command-T starts in).
+
+      See the |'wildignore'| documentation for more information.
+
+      If you want to influence Command-T's file exclusion behavior without
+      changing your global |'wildignore'| setting, you can use the
+      |g:CommandTWildIgnore| setting to apply an override that takes effect
+      only during Command-T searches.
+
+
+FAQ                                             *command-t-faq*
+
+Why does my build fail with "unknown argument -multiply_definedsuppress"? ~
+
+You may see this on OS X Mavericks when building with the Clang compiler
+against the system Ruby. This is an unfortunate Apple bug that breaks
+compilation of many Ruby gems with native extensions on Mavericks. It has been
+worked around in the upstream Ruby version, but won't be fixed in OS X until
+Apple updates their supplied version of Ruby (most likely this won't be until
+the next major release):
+
+  https://bugs.ruby-lang.org/issues/9624
+
+Workarounds include building your own Ruby (and then your own Vim and
+Command-T), or more simply, building with the following `ARCHFLAGS` set:
+
+  ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future ruby extconf.rb
+  make
+
+Why can't I open in a split with <C-CR> and <C-s> in the terminal? ~
+
+It's likely that <C-CR> won't work in most terminals, because the keycode that
+is sent to processes running inside them is identical to <CR>; when you type
+<C-CR>, terminal Vim literally "sees" <CR>. Unfortunately, there is no
+workaround for this.
+
+If you find that <C-s> also doesn't work the most likely explanation is that
+XON/XOFF flow control is enabled; this is the default in many environments.
+This means that when you press <C-s> all input to the terminal is suspended
+until you release it by hitting <C-q>. While input is suspended you may think
+your terminal has frozen, but it hasn't.
+
+To disable flow control, add the following to your `.zshrc` or
+`.bash_profile`:
+
+  stty -ixon
+
+See the `stty` man page for more details.
+
+
+TIPS                                            *command-t-tips*
+
+Working with very large repositories ~
+
+One of the primary motivations for writing Command-T was to get fast, robust
+high-quality matches even on large hierarchies. The larger the hierarchy, the
+more important having good file navigation becomes. This is why Command-T's
+performance-critical sections are written in C. This requires a compilation
+step and makes Command-T harder to install than similar plug-ins which are
+written in pure Vimscript, and can be a disincentive against use. This is a
+conscious trade-off; the goal isn't to have as many users as possible, but
+rather to provide the best performance at the highest quality.
+
+The speed of the core is high enough that Command-T can afford to burn a bunch
+of extra cycles -- using its recursive matching algorithm -- looking for a
+higher-quality, more intuitive ranking of search results. Again, the larger
+the hierarchy, the more important the quality of result ranking becomes.
+
+Nevertheless, for extremely large hierarchies (of the order of 500,000 files)
+some tuning is required in order to get useful and usable performance levels.
+Here are some useful example settings:
+
+    let g:CommandTMaxHeight = 30
+
+You want the match listing window to be large enough that you can get useful
+feedback about how your search query is going; in large hierarchies there may
+be many, many matches for a given query. At the same time, you don't want Vim
+wasting valuable cycles repainting a large portion of the screen area,
+especially on a large display. Setting the limit to 30 or similar is a
+reasonable compromise.
+
+    let g:CommandTMaxFiles = 500000
+
+The default limit of 30,000 files prevents Command-T from "seeing" many of the
+files in a large directory hierarchy so you need to increase this limit.
+
+    let g:CommandTInputDebounce = 200
+
+Wait for 200ms of keyboard inactivity before computing search results. For
+example, if you are enter "foobar" quickly (ie. within 1 second), there is
+little sense in fetching the results for "f", "fo", "foo", "foob", "fooba" and
+finally "foobar". Instead, we can just fetch the results for "foobar". This
+setting trades off some immediate responsiveness at the micro level for
+better performance (real and perceived) and a better search experience
+overall.
+
+    let g:CommandTFileScanner = 'watchman'
+
+On a large hierarchy with of the order of 500,000 files, scanning a directory
+tree with a tool like the `find` executable may take literally minutes with a
+cold cache. Once the cache is warm, the same `find` run may take only a second
+or two. Command-T provides a "find" scanner to leverage this performance, but
+there is still massive overhead in passing the results through Vim internal
+functions that apply 'wildignore' settings and such, so for truly immense
+repos the "watchman" scanner is the tool of choice.
+
+This scanner delegates the task of finding files to Facebook's `watchman` tool
+(https://github.com/facebook/watchman), which can return results for a 500,000
+file hierarchy within about a second.
+
+Note that Watchman has a range of configuration options that can be applied by
+files such as `/etc/watchman.json` or per-direcory `.watchmanconfig` files and
+which may affect how Command-T works. For example, if your configuration has a
+`root_restrict_files` setting that makes Watchman only work with roots that
+look like Git or Mercurial repos, then Command-T will fall back to using the
+"find" scanner any time you invoke it on a non-repo directory. For
+simplicity's sake, it is probably a good idea to use Vim and Command-T
+anchored at the root level of your repository in any case.
+
+    let g:CommandTMaxCachedDirectories = 10
+
+Command-T will internally cache up to 10 different directories, so even if you
+|cd| repeatedly, it should only need to scan each directory once.
+
+It's advisable to keep a long-running Vim instance in place and let it cache
+the directory listings rather than repeatedly closing and re-opening Vim in
+order to edit every file. On those occasions when you do need to flush the
+cache (ie. with |CommandTFlush| or <C-f> in the match listing window), use of
+the Watchman scanner should make the delay barely noticeable.
+
+As noted in the introduction, Command-T works best when you adopt a
+"path-centric" mentality. This is especially true on very large hierarchies.
+For example, if you're looking for a file at:
+
+  lib/third-party/adapters/restful-services/foobar/foobar-manager.js
+
+you'll be able to narrow your search results down more narrowly if you search
+with a query like "librestfoofooman" than "foobar-manager.js". This evidently
+requires that you know where the file you're wanting to open exists, but
+again, this is a concious design decision: Command-T is made to enable people
+who know what they want to open and where it is to open it as quickly as
+possible; other tools such as NERDTree exist for visually exploring an unknown
+hierarchy.
+
+Over time, you will get a feel for how economical you can afford to be with
+your search queries in a given repo. In the example above, if "foo" is not a
+very common pattern in your hierarchy, then you may find that you can find
+what you need with a very concise query such as "foomanjs". With time, this
+kind of ongoing calibration will come quite naturally.
+
+Finally, it is important to be on a relatively recent version of Command-T to
+fully benefit from the available performance enhancements:
+
+- version 1.8 (March 2013) sped up the Watchman file scanner by switching its
+  communication from the JSON to the binary Watchman protocol
+- version 1.7 (February 2014) added the |g:CommandTInputDebounce| and
+  |g:CommandTFileScanner| settings, along with support for the Watchman file
+  scanner
+- version 1.6 (December 2013) added parallelized search
+- version 1.5 (September 2013) added memoization to the matching algorithm,
+  improving general performance on large hierarchies, but delivering
+  spectacular gains on hierarchies with "pathological" characteristics that
+  lead the algorithm to exhibit degenerate behavior
+
+AUTHORS                                         *command-t-authors*
+
+Command-T is written and maintained by Wincent Colaiuta <win@wincent.com>.
+Other contributors that have submitted patches include (in alphabetical
+order):
+
+  Andy Waite              Mike Lundy              Shlomi Fish
+  Anthony Panozzo         Nadav Samet             Steven Moazami
+  Daniel Hahler           Nate Kane               Sung Pae
+  Felix Tjandrawibawa     Nicholas Alpi           Thomas Pelletier
+  Gary Bernhardt          Noon Silk               Victor Hugo Borja
+  Ivan Ukhov              Paul Jolly              Vít Ondruch
+  Jeff Kreeftmeijer       Pavel Sergeev           Woody Peterson
+  Lucas de Vries          Rainux Luo              Yan Pritzker
+  Marcus Brito            Roland Puntaier         Yiding Jia
+  Marian Schubert         Scott Bronson           Zak Johnson
+  Matthew Todd            Seth Fowler
+
+As this was the first Vim plug-in I had ever written I was heavily influenced
+by the design of the LustyExplorer plug-in by Stephen Bach, which I understand
+was one of the largest Ruby-based Vim plug-ins at the time.
+
+While the Command-T codebase doesn't contain any code directly copied from
+LustyExplorer, I did use it as a reference for answers to basic questions (like
+"How do you do 'X' in a Ruby-based Vim plug-in?"), and also copied some basic
+architectural decisions (like the division of the code into Prompt, Settings
+and MatchWindow classes).
+
+LustyExplorer is available from:
+
+  http://www.vim.org/scripts/script.php?script_id=1890
+
+
+DEVELOPMENT                                     *command-t-development*
+
+Development in progress can be inspected via the project's Git web-based
+repository browser at:
+
+  https://wincent.com/repos/command-t
+
+the clone URL for which is:
+
+  git://git.wincent.com/command-t.git
+
+Mirrors exist on GitHub and Gitorious; these are automatically updated once
+per hour from the authoritative repository:
+
+  https://github.com/wincent/command-t
+  https://gitorious.org/command-t/command-t
+
+Patches are welcome via the usual mechanisms (pull requests, email, posting to
+the project issue tracker etc).
+
+As many users choose to track Command-T using Pathogen, which often means
+running a version later than the last official release, the intention is that
+the "master" branch should be kept in a stable and reliable state as much as
+possible.
+
+Riskier changes are first cooked on the "next" branch for a period before
+being merged into master. You can track this branch if you're feeling wild and
+experimental, but note that the "next" branch may periodically be rewound
+(force-updated) to keep it in sync with the "master" branch after each
+official release.
+
+
+WEBSITE                                         *command-t-website*
+
+The official website for Command-T is:
+
+  https://wincent.com/products/command-t
+
+The latest release will always be available from there.
+
+A copy of each release is also available from the official Vim scripts site
+at:
+
+  http://www.vim.org/scripts/script.php?script_id=3025
+
+Bug reports should be submitted to the issue tracker at:
+
+  https://wincent.com/issues
+
+
+DONATIONS                                       *command-t-donations*
+
+Command-T itself is free software released under the terms of the BSD license.
+If you would like to support further development you can make a donation via
+PayPal to win@wincent.com:
+
+  https://wincent.com/products/command-t/donations
+
+
+LICENSE                                         *command-t-license*
+
+Copyright 2010-2014 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.
+
+HISTORY                                         *command-t-history*
+
+1.8 (31 March 2014)
+
+- taught Watchman file scanner to use the binary protocol instead of JSON,
+  roughly doubling its speed
+- build changes to accommodate MinGW (patch from Roland Puntaier)
+
+1.7 (9 March 2014)
+
+- added |g:CommandTInputDebounce|, which can be used to improve responsiveness
+  in large file hierarchies (based on patch from Yiding Jia)
+- added a potentially faster file scanner which uses the `find` executable
+  (based on patch from Yiding Jia)
+- added a file scanner that knows how to talk to Watchman
+  (https://github.com/facebook/watchman)
+- added |g:CommandTFileScanner|, which can be used to switch file scanners
+- fix processor count detection on some platforms (patch from Pavel Sergeev)
+
+1.6.1 (22 December 2013)
+
+- defer processor count detection until runtime (makes it possible to sensibly
+  build Command-T on one machine and use it on another)
+
+1.6 (16 December 2013)
+
+- on systems with POSIX threads (such as OS X and Linux), Command-T will use
+  threads to compute match results in parallel, resulting in a large speed
+  boost that is especially noticeable when navigating large projects
+
+1.5.1 (23 September 2013)
+
+- exclude large benchmark fixture file from source exports (patch from Vít
+  Ondruch)
+
+1.5 (18 September 2013)
+
+- don't scan "pathological" filesystem structures (ie. circular or
+  self-referential symlinks; patch from Marcus Brito)
+- gracefully handle files starting with "+" (patch from Ivan Ukhov)
+- switch default selection highlight color for better readability (suggestion
+  from André Arko), but make it possible to configure via the
+  |g:CommandTHighlightColor| setting
+- added a mapping to take the current matches and put then in the quickfix
+  window
+- performance improvements, particularly noticeable with large file
+  hierarchies
+- added |g:CommandTWildIgnore| setting (patch from Paul Jolly)
+
+1.4 (20 June 2012)
+
+- added |:CommandTTag| command (patches from Noon Silk)
+- turn off |'colorcolumn'| and |'relativenumber'| in the match window (patch
+  from Jeff Kreeftmeijer)
+- documentation update (patch from Nicholas Alpi)
+- added |:CommandTMinHeight| option (patch from Nate Kane)
+- highlight (by underlining) matched characters in the match listing (requires
+  Vim to have been compiled with the +conceal feature, which is available in
+  Vim 7.3 or later; patch from Steven Moazami)
+- added the ability to flush the cache while the match window is open using
+  <C-f>
+
+1.3.1 (18 December 2011)
+
+- fix jumplist navigation under Ruby 1.9.x (patch from Woody Peterson)
+
+1.3 (27 November 2011)
+
+- added the option to maintain multiple caches when changing among
+  directories; see the accompanying |g:CommandTMaxCachedDirectories| setting
+- added the ability to navigate using the Vim jumplist (patch from Marian
+  Schubert)
+
+1.2.1 (30 April 2011)
+
+- Remove duplicate copy of the documentation that was causing "Duplicate tag"
+  errors
+- Mitigate issue with distracting blinking cursor in non-GUI versions of Vim
+  (patch from Steven Moazami)
+
+1.2 (30 April 2011)
+
+- added |g:CommandTMatchWindowReverse| option, to reverse the order of items
+  in the match listing (patch from Steven Moazami)
+
+1.1b2 (26 March 2011)
+
+- fix a glitch in the release process; the plugin itself is unchanged since
+  1.1b
+
+1.1b (26 March 2011)
+
+- add |:CommandTBuffer| command for quickly selecting among open buffers
+
+1.0.1 (5 January 2011)
+
+- work around bug when mapping |:CommandTFlush|, wherein the default mapping
+  for |:CommandT| would not be set up
+- clean up when leaving the Command-T buffer via unexpected means (such as
+  with <C-W k> or similar)
+
+1.0 (26 November 2010)
+
+- make relative path simplification work on Windows
+
+1.0b (5 November 2010)
+
+- work around platform-specific Vim 7.3 bug seen by some users (wherein
+  Vim always falsely reports to Ruby that the buffer numbers is 0)
+- re-use the buffer that is used to show the match listing, rather than
+  throwing it away and recreating it each time Command-T is shown; this
+  stops the buffer numbers from creeping up needlessly
+
+0.9 (8 October 2010)
+
+- use relative paths when opening files inside the current working directory
+  in order to keep buffer listings as brief as possible (patch from Matthew
+  Todd)
+
+0.8.1 (14 September 2010)
+
+- fix mapping issues for users who have set |'notimeout'| (patch from Sung
+  Pae)
+
+0.8 (19 August 2010)
+
+- overrides for the default mappings can now be lists of strings, allowing
+  multiple mappings to be defined for any given action
+- <Leader>t mapping only set up if no other map for |:CommandT| exists
+  (patch from Scott Bronson)
+- prevent folds from appearing in the match listing
+- tweaks to avoid the likelihood of "Not enough room" errors when trying to
+  open files
+- watch out for "nil" windows when restoring window dimensions
+- optimizations (avoid some repeated downcasing)
+- move all Ruby files under the "command-t" subdirectory and avoid polluting
+  the "Vim" module namespace
+
+0.8b (11 July 2010)
+
+- large overhaul of the scoring algorithm to make the ordering of returned
+  results more intuitive; given the scope of the changes and room for
+  optimization of the new algorithm, this release is labelled as "beta"
+
+0.7 (10 June 2010)
+
+- handle more |'wildignore'| patterns by delegating to Vim's own |expand()|
+  function; with this change it is now viable to exclude patterns such as
+  'vendor/rails/**' in addition to filename-only patterns like '*.o' and
+  '.git' (patch from Mike Lundy)
+- always sort results alphabetically for empty search strings; this eliminates
+  filesystem-specific variations (patch from Mike Lundy)
+
+0.6 (28 April 2010)
+
+- |:CommandT| now accepts an optional parameter to specify the starting
+  directory, temporarily overriding the usual default of Vim's |:pwd|
+- fix truncated paths when operating from root directory
+
+0.5.1 (11 April 2010)
+
+- fix for Ruby 1.9 compatibility regression introduced in 0.5
+- documentation enhancements, specifically targetted at Windows users
+
+0.5 (3 April 2010)
+
+- |:CommandTFlush| now re-evaluates settings, allowing changes made via |let|
+  to be picked up without having to restart Vim
+- fix premature abort when scanning very deep directory hierarchies
+- remove broken |<Esc>| key mapping on vt100 and xterm terminals
+- provide settings for overriding default mappings
+- minor performance optimization
+
+0.4 (27 March 2010)
+
+- add |g:CommandTMatchWindowAtTop| setting (patch from Zak Johnson)
+- documentation fixes and enhancements
+- internal refactoring and simplification
+
+0.3 (24 March 2010)
+
+- add |g:CommandTMaxHeight| setting for controlling the maximum height of the
+  match window (patch from Lucas de Vries)
+- fix bug where |'list'| setting might be inappropriately set after dismissing
+  Command-T
+- compatibility fix for different behaviour of "autoload" under Ruby 1.9.1
+- avoid "highlight group not found" warning when run under a version of Vim
+  that does not have syntax highlighting support
+- open in split when opening normally would fail due to |'hidden'| and
+  |'modified'| values
+
+0.2 (23 March 2010)
+
+- compatibility fixes for compilation under Ruby 1.9 series
+- compatibility fixes for compilation under Ruby 1.8.5
+- compatibility fixes for Windows and other non-UNIX platforms
+- suppress "mapping already exists" message if <Leader>t mapping is already
+  defined when plug-in is loaded
+- exclude paths based on |'wildignore'| setting rather than a hardcoded
+  regular expression
+
+0.1 (22 March 2010)
+
+- initial public release
+
+------------------------------------------------------------------------------
+vim:tw=78:ft=help:

+ 286 - 0
vim/doc/snipMate.txt

@@ -0,0 +1,286 @@
+*snipMate.txt*  Plugin for using TextMate-style snippets in Vim.
+
+snipMate                                       *snippet* *snippets* *snipMate*
+Last Change: July 13, 2009
+
+|snipMate-description|   Description
+|snipMate-syntax|        Snippet syntax
+|snipMate-usage|         Usage
+|snipMate-settings|      Settings
+|snipMate-features|      Features
+|snipMate-disadvantages| Disadvantages to TextMate
+|snipMate-contact|       Contact
+
+For Vim version 7.0 or later.
+This plugin only works if 'compatible' is not set.
+{Vi does not have any of these features.}
+
+==============================================================================
+DESCRIPTION                                             *snipMate-description*
+
+snipMate.vim implements some of TextMate's snippets features in Vim. A
+snippet is a piece of often-typed text that you can insert into your
+document using a trigger word followed by a <tab>.
+
+For instance, in a C file using the default installation of snipMate.vim, if
+you type "for<tab>" in insert mode, it will expand a typical for loop in C: >
+
+ for (i = 0; i < count; i++) {
+
+ }
+
+
+To go to the next item in the loop, simply <tab> over to it; if there is
+repeated code, such as the "i" variable in this example, you can simply
+start typing once it's highlighted and all the matches specified in the
+snippet will be updated. To go in reverse, use <shift-tab>.
+
+==============================================================================
+SYNTAX                                                        *snippet-syntax*
+
+Snippets can be defined in two ways. They can be in their own file, named
+after their trigger in 'snippets/<filetype>/<trigger>.snippet', or they can be
+defined together in a 'snippets/<filetype>.snippets' file. Note that dotted
+'filetype' syntax is supported -- e.g., you can use >
+
+	:set ft=html.eruby
+
+to activate snippets for both HTML and eRuby for the current file.
+
+The syntax for snippets in *.snippets files is the following: >
+
+ snippet trigger
+ 	expanded text
+	more expanded text
+
+Note that the first hard tab after the snippet trigger is required, and not
+expanded in the actual snippet. The syntax for *.snippet files is the same,
+only without the trigger declaration and starting indentation.
+
+Also note that snippets must be defined using hard tabs. They can be expanded
+to spaces later if desired (see |snipMate-indenting|).
+
+"#" is used as a line-comment character in *.snippets files; however, they can
+only be used outside of a snippet declaration. E.g.: >
+
+ # this is a correct comment
+ snippet trigger
+ 	expanded text
+ snippet another_trigger
+ 	# this isn't a comment!
+	expanded text
+<
+This should hopefully be obvious with the included syntax highlighting.
+
+                                                               *snipMate-${#}*
+Tab stops ~
+
+By default, the cursor is placed at the end of a snippet. To specify where the
+cursor is to be placed next, use "${#}", where the # is the number of the tab
+stop. E.g., to place the cursor first on the id of a <div> tag, and then allow
+the user to press <tab> to go to the middle of it:
+ >
+ snippet div
+ 	<div id="${1}">
+		${2}
+	</div>
+<
+                        *snipMate-placeholders* *snipMate-${#:}* *snipMate-$#*
+Placeholders ~
+
+Placeholder text can be supplied using "${#:text}", where # is the number of
+the tab stop. This text then can be copied throughout the snippet using "$#",
+given # is the same number as used before. So, to make a C for loop: >
+
+ snippet for
+ 	for (${2:i}; $2 < ${1:count}; $1++) {
+		${4}
+	}
+
+This will cause "count" to first be selected and change if the user starts
+typing. When <tab> is pressed, the "i" in ${2}'s position will be selected;
+all $2 variables will default to "i" and automatically be updated if the user
+starts typing.
+NOTE: "$#" syntax is used only for variables, not for tab stops as in TextMate.
+
+Variables within variables are also possible. For instance: >
+
+ snippet opt
+ 	<option value="${1:option}">${2:$1}</option>
+
+Will, as usual, cause "option" to first be selected and update all the $1
+variables if the user starts typing. Since one of these variables is inside of
+${2}, this text will then be used as a placeholder for the next tab stop,
+allowing the user to change it if he wishes.
+
+To copy a value throughout a snippet without supplying default text, simply
+use the "${#:}" construct without the text; e.g.: >
+
+ snippet foo
+ 	${1:}bar$1
+<                                                          *snipMate-commands*
+Interpolated Vim Script ~
+
+Snippets can also contain Vim script commands that are executed (via |eval()|)
+when the snippet is inserted. Commands are given inside backticks (`...`); for
+TextMates's functionality, use the |system()| function. E.g.: >
+
+ snippet date
+ 	`system("date +%Y-%m-%d")`
+
+will insert the current date, assuming you are on a Unix system. Note that you
+can also (and should) use |strftime()| for this example.
+
+Filename([{expr}] [, {defaultText}])             *snipMate-filename* *Filename()*
+
+Since the current filename is used often in snippets, a default function
+has been defined for it in snipMate.vim, appropriately called Filename().
+
+With no arguments, the default filename without an extension is returned;
+the first argument specifies what to place before or after the filename,
+and the second argument supplies the default text to be used if the file
+has not been named. "$1" in the first argument is replaced with the filename;
+if you only want the filename to be returned, the first argument can be left
+blank. Examples: >
+
+ snippet filename
+ 	`Filename()`
+ snippet filename_with_default
+ 	`Filename('', 'name')`
+ snippet filename_foo
+ 	`filename('$1_foo')`
+
+The first example returns the filename if it the file has been named, and an
+empty string if it hasn't. The second returns the filename if it's been named,
+and "name" if it hasn't. The third returns the filename followed by "_foo" if
+it has been named, and an empty string if it hasn't.
+
+                                                                   *multi_snip*
+To specify that a snippet can have multiple matches in a *.snippets file, use
+this syntax: >
+
+ snippet trigger A description of snippet #1
+ 	expand this text
+ snippet trigger A description of snippet #2
+ 	expand THIS text!
+
+In this example, when "trigger<tab>" is typed, a numbered menu containing all
+of the descriptions of the "trigger" will be shown; when the user presses the
+corresponding number, that snippet will then be expanded.
+
+To create a snippet with multiple matches using *.snippet files,
+simply place all the snippets in a subdirectory with the trigger name:
+'snippets/<filetype>/<trigger>/<name>.snippet'.
+
+==============================================================================
+USAGE                                                         *snipMate-usage*
+
+                                                 *'snippets'* *g:snippets_dir*
+Snippets are by default looked for any 'snippets' directory in your
+'runtimepath'. Typically, it is located at '~/.vim/snippets/' on *nix or
+'$HOME\vimfiles\snippets\' on Windows. To change that location or add another
+one, change the g:snippets_dir variable in your |.vimrc| to your preferred
+directory, or use the |ExtractSnips()|function. This will be used by the
+|globpath()| function, and so accepts the same syntax as it (e.g.,
+comma-separated paths).
+
+ExtractSnipsFile({directory}, {filetype})     *ExtractSnipsFile()* *.snippets*
+
+ExtractSnipsFile() extracts the specified *.snippets file for the given
+filetype. A .snippets file contains multiple snippet declarations for the
+filetype. It is further explained above, in |snippet-syntax|.
+
+ExtractSnips({directory}, {filetype})             *ExtractSnips()* *.snippet*
+
+ExtractSnips() extracts *.snippet files from the specified directory and
+defines them as snippets for the given filetype. The directory tree should
+look like this: 'snippets/<filetype>/<trigger>.snippet'. If the snippet has
+multiple matches, it should look like this:
+'snippets/<filetype>/<trigger>/<name>.snippet' (see |multi_snip|).
+
+                                                            *ResetSnippets()*
+The ResetSnippets() function removes all snippets from memory. This is useful
+to put at the top of a snippet setup file for if you would like to |:source|
+it multiple times.
+
+                                             *list-snippets* *i_CTRL-R_<Tab>*
+If you would like to see what snippets are available, simply type <c-r><tab>
+in the current buffer to show a list via |popupmenu-completion|.
+
+==============================================================================
+SETTINGS                                  *snipMate-settings* *g:snips_author*
+
+The g:snips_author string (similar to $TM_FULLNAME in TextMate) should be set
+to your name; it can then be used in snippets to automatically add it. E.g.: >
+
+ let g:snips_author = 'Hubert Farnsworth'
+ snippet name
+ 	`g:snips_author`
+<
+                                     *snipMate-expandtab* *snipMate-indenting*
+If you would like your snippets to be expanded using spaces instead of tabs,
+just enable 'expandtab' and set 'softtabstop' to your preferred amount of
+spaces. If 'softtabstop' is not set, 'shiftwidth' is used instead.
+
+                                                              *snipMate-remap*
+snipMate does not come with a setting to customize the trigger key, but you
+can remap it easily in the two lines it's defined in the 'after' directory
+under 'plugin/snipMate.vim'. For instance, to change the trigger key
+to CTRL-J, just change this: >
+
+ ino <tab> <c-r>=TriggerSnippet()<cr>
+ snor <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
+
+to this: >
+ ino <c-j> <c-r>=TriggerSnippet()<cr>
+ snor <c-j> <esc>i<right><c-r>=TriggerSnippet()<cr>
+
+==============================================================================
+FEATURES                                                   *snipMate-features*
+
+snipMate.vim has the following features among others:
+  - The syntax of snippets is very similar to TextMate's, allowing
+    easy conversion.
+  - The position of the snippet is kept transparently (i.e. it does not use
+    markers/placeholders written to the buffer), which allows you to escape
+    out of an incomplete snippet, something particularly useful in Vim.
+  - Variables in snippets are updated as-you-type.
+  - Snippets can have multiple matches.
+  - Snippets can be out of order. For instance, in a do...while loop, the
+    condition can be added before the code.
+  - [New] File-based snippets are supported.
+  - [New] Triggers after non-word delimiters are expanded, e.g. "foo"
+    in "bar.foo".
+  - [New] <shift-tab> can now be used to jump tab stops in reverse order.
+
+==============================================================================
+DISADVANTAGES                                         *snipMate-disadvantages*
+
+snipMate.vim currently has the following disadvantages to TextMate's snippets:
+    - There is no $0; the order of tab stops must be explicitly stated.
+    - Placeholders within placeholders are not possible. E.g.: >
+
+      '<div${1: id="${2:some_id}}">${3}</div>'
+<
+      In TextMate this would first highlight ' id="some_id"', and if
+      you hit delete it would automatically skip ${2} and go to ${3}
+      on the next <tab>, but if you didn't delete it it would highlight
+      "some_id" first. You cannot do this in snipMate.vim.
+    - Regex cannot be performed on variables, such as "${1/.*/\U&}"
+    - Placeholders cannot span multiple lines.
+    - Activating snippets in different scopes of the same file is
+      not possible.
+
+Perhaps some of these features will be added in a later release.
+
+==============================================================================
+CONTACT                                   *snipMate-contact* *snipMate-author*
+
+To contact the author (Michael Sanders), please email:
+ msanders42+snipmate <at> gmail <dot> com
+
+I greatly appreciate any suggestions or improvements offered for the script.
+
+==============================================================================
+
+vim:tw=78:ts=8:ft=help:norl:

+ 125 - 0
vim/doc/tags

@@ -0,0 +1,125 @@
+:CSApproxSnapshot	CSApprox.txt	/*:CSApproxSnapshot*
+:CoffeeCompile	coffee-script.txt	/*:CoffeeCompile*
+:CoffeeMake	coffee-script.txt	/*:CoffeeMake*
+:CoffeeRun	coffee-script.txt	/*:CoffeeRun*
+: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*
+CSApprox.txt	CSApprox.txt	/*CSApprox.txt*
+coffee-script	coffee-script.txt	/*coffee-script*
+coffee-script-author	coffee-script.txt	/*coffee-script-author*
+coffee-script-commands	coffee-script.txt	/*coffee-script-commands*
+coffee-script-contents	coffee-script.txt	/*coffee-script-contents*
+coffee-script-introduction	coffee-script.txt	/*coffee-script-introduction*
+coffee-script-license	coffee-script.txt	/*coffee-script-license*
+coffee-script-settings	coffee-script.txt	/*coffee-script-settings*
+coffee-script.txt	coffee-script.txt	/*coffee-script.txt*
+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-faq	command-t.txt	/*command-t-faq*
+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-tips	command-t.txt	/*command-t-tips*
+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*
+compiler-coffee-script	coffee-script.txt	/*compiler-coffee-script*
+csapprox	CSApprox.txt	/*csapprox*
+csapprox-+gui	CSApprox.txt	/*csapprox-+gui*
+csapprox-aterm	CSApprox.txt	/*csapprox-aterm*
+csapprox-author	CSApprox.txt	/*csapprox-author*
+csapprox-changelog	CSApprox.txt	/*csapprox-changelog*
+csapprox-configure	CSApprox.txt	/*csapprox-configure*
+csapprox-design	CSApprox.txt	/*csapprox-design*
+csapprox-eterm	CSApprox.txt	/*csapprox-eterm*
+csapprox-gnome-terminal	CSApprox.txt	/*csapprox-gnome-terminal*
+csapprox-gui-support	CSApprox.txt	/*csapprox-gui-support*
+csapprox-hooks	CSApprox.txt	/*csapprox-hooks*
+csapprox-intro	CSApprox.txt	/*csapprox-intro*
+csapprox-iterm.app	CSApprox.txt	/*csapprox-iterm.app*
+csapprox-konsole	CSApprox.txt	/*csapprox-konsole*
+csapprox-kterm	CSApprox.txt	/*csapprox-kterm*
+csapprox-limitations	CSApprox.txt	/*csapprox-limitations*
+csapprox-mlterm	CSApprox.txt	/*csapprox-mlterm*
+csapprox-mrxvt	CSApprox.txt	/*csapprox-mrxvt*
+csapprox-palettes	CSApprox.txt	/*csapprox-palettes*
+csapprox-pterm	CSApprox.txt	/*csapprox-pterm*
+csapprox-putty	CSApprox.txt	/*csapprox-putty*
+csapprox-requirements	CSApprox.txt	/*csapprox-requirements*
+csapprox-roxterm	CSApprox.txt	/*csapprox-roxterm*
+csapprox-screen	CSApprox.txt	/*csapprox-screen*
+csapprox-terminal	CSApprox.txt	/*csapprox-terminal*
+csapprox-terminal-example	CSApprox.txt	/*csapprox-terminal-example*
+csapprox-terminal-list	CSApprox.txt	/*csapprox-terminal-list*
+csapprox-terminal.app	CSApprox.txt	/*csapprox-terminal.app*
+csapprox-terminals-bad	CSApprox.txt	/*csapprox-terminals-bad*
+csapprox-terminals-good	CSApprox.txt	/*csapprox-terminals-good*
+csapprox-toc	CSApprox.txt	/*csapprox-toc*
+csapprox-transparency	CSApprox.txt	/*csapprox-transparency*
+csapprox-urxvt	CSApprox.txt	/*csapprox-urxvt*
+csapprox-wterm	CSApprox.txt	/*csapprox-wterm*
+csapprox-xfce4-terminal	CSApprox.txt	/*csapprox-xfce4-terminal*
+csapprox-xiterm	CSApprox.txt	/*csapprox-xiterm*
+csapprox-xterm	CSApprox.txt	/*csapprox-xterm*
+csapprox.vim	CSApprox.txt	/*csapprox.vim*
+ft-coffee-script-syntax	coffee-script.txt	/*ft-coffee-script-syntax*
+g:CSApprox_approximator_function	CSApprox.txt	/*g:CSApprox_approximator_function*
+g:CSApprox_attr_map	CSApprox.txt	/*g:CSApprox_attr_map*
+g:CSApprox_eterm	CSApprox.txt	/*g:CSApprox_eterm*
+g:CSApprox_hook_post	CSApprox.txt	/*g:CSApprox_hook_post*
+g:CSApprox_hook_pre	CSApprox.txt	/*g:CSApprox_hook_pre*
+g:CSApprox_hook_{scheme}_post	CSApprox.txt	/*g:CSApprox_hook_{scheme}_post*
+g:CSApprox_hook_{scheme}_pre	CSApprox.txt	/*g:CSApprox_hook_{scheme}_pre*
+g:CSApprox_konsole	CSApprox.txt	/*g:CSApprox_konsole*
+g:CSApprox_loaded	CSApprox.txt	/*g:CSApprox_loaded*
+g:CSApprox_redirfallback	CSApprox.txt	/*g:CSApprox_redirfallback*
+g:CSApprox_use_showrgb	CSApprox.txt	/*g:CSApprox_use_showrgb*
+g:CSApprox_verbose_level	CSApprox.txt	/*g:CSApprox_verbose_level*
+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:CommandTFileScanner	command-t.txt	/*g:CommandTFileScanner*
+g:CommandTHighlightColor	command-t.txt	/*g:CommandTHighlightColor*
+g:CommandTInputDebounce	command-t.txt	/*g:CommandTInputDebounce*
+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:CommandTQuickfixMap	command-t.txt	/*g:CommandTQuickfixMap*
+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*
+g:CommandTWildIgnore	command-t.txt	/*g:CommandTWildIgnore*
+g:coffee_compile_vert	coffee-script.txt	/*g:coffee_compile_vert*
+g:coffee_make_options	coffee-script.txt	/*g:coffee_make_options*

+ 8 - 0
vim/ftdetect/coffee.vim

@@ -0,0 +1,8 @@
+" Language:    CoffeeScript
+" Maintainer:  Mick Koch <kchmck@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+autocmd BufNewFile,BufRead *.coffee set filetype=coffee
+autocmd BufNewFile,BufRead *Cakefile set filetype=coffee
+autocmd BufNewFile,BufRead *.coffeekup set filetype=coffee

+ 1 - 0
vim/ftdetect/eco.vim

@@ -0,0 +1 @@
+autocmd BufNewFile,BufRead *.eco set filetype=eco

+ 221 - 0
vim/ftplugin/coffee.vim

@@ -0,0 +1,221 @@
+" Language:    CoffeeScript
+" Maintainer:  Mick Koch <kchmck@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+if exists("b:did_ftplugin")
+  finish
+endif
+
+let b:did_ftplugin = 1
+
+setlocal formatoptions-=t formatoptions+=croql
+setlocal comments=:#
+setlocal commentstring=#\ %s
+setlocal omnifunc=javascriptcomplete#CompleteJS
+
+" Enable CoffeeMake if it won't overwrite any settings.
+if !len(&l:makeprg)
+  compiler coffee
+endif
+
+" Reset the global variables used by CoffeeCompile.
+function! s:CoffeeCompileResetVars()
+  " Position in the source buffer
+  let s:coffee_compile_src_buf = -1
+  let s:coffee_compile_src_pos = []
+
+  " Position in the CoffeeCompile buffer
+  let s:coffee_compile_buf = -1
+  let s:coffee_compile_win = -1
+  let s:coffee_compile_pos = []
+
+  " If CoffeeCompile is watching a buffer
+  let s:coffee_compile_watch = 0
+endfunction
+
+" Save the cursor position when moving to and from the CoffeeCompile buffer.
+function! s:CoffeeCompileSavePos()
+  let buf = bufnr('%')
+  let pos = getpos('.')
+
+  if buf == s:coffee_compile_buf
+    let s:coffee_compile_pos = pos
+  else
+    let s:coffee_compile_src_buf = buf
+    let s:coffee_compile_src_pos = pos
+  endif
+endfunction
+
+" Restore the cursor to the source buffer.
+function! s:CoffeeCompileRestorePos()
+  let win = bufwinnr(s:coffee_compile_src_buf)
+
+  if win != -1
+    exec win 'wincmd w'
+    call setpos('.', s:coffee_compile_src_pos)
+  endif
+endfunction
+
+" Close the CoffeeCompile buffer and clean things up.
+function! s:CoffeeCompileClose()
+  silent! autocmd! CoffeeCompileAuPos
+  silent! autocmd! CoffeeCompileAuWatch
+
+  call s:CoffeeCompileRestorePos()
+  call s:CoffeeCompileResetVars()
+endfunction
+
+" Update the CoffeeCompile buffer given some input lines.
+function! s:CoffeeCompileUpdate(startline, endline)
+  let input = join(getline(a:startline, a:endline), "\n")
+
+  " Coffee doesn't like empty input.
+  if !len(input)
+    return
+  endif
+
+  " Compile input.
+  let output = system('coffee -scb 2>&1', input)
+
+  " Move to the CoffeeCompile buffer.
+  exec s:coffee_compile_win 'wincmd w'
+
+  " Replace buffer contents with new output and delete the last empty line.
+  setlocal modifiable
+    exec '% delete _'
+    put! =output
+    exec '$ delete _'
+  setlocal nomodifiable
+
+  " Highlight as JavaScript if there is no compile error.
+  if v:shell_error
+    setlocal filetype=
+  else
+    setlocal filetype=javascript
+  endif
+
+  " Restore the cursor in the compiled output.
+  call setpos('.', s:coffee_compile_pos)
+endfunction
+
+" Update the CoffeeCompile buffer with the whole source buffer and restore the
+" cursor.
+function! s:CoffeeCompileWatchUpdate()
+  call s:CoffeeCompileSavePos()
+  call s:CoffeeCompileUpdate(1, '$')
+  call s:CoffeeCompileRestorePos()
+endfunction
+
+" Peek at compiled CoffeeScript in a scratch buffer. We handle ranges like this
+" to prevent the cursor from being moved (and its position saved) before the
+" function is called.
+function! s:CoffeeCompile(startline, endline, args)
+  " Don't compile the CoffeeCompile buffer.
+  if bufnr('%') == s:coffee_compile_buf
+    return
+  endif
+
+  " Parse arguments.
+  let watch = a:args =~ '\<watch\>'
+  let unwatch = a:args =~ '\<unwatch\>'
+  let size = str2nr(matchstr(a:args, '\<\d\+\>'))
+   
+  " Determine default split direction.
+  if exists("g:coffee_compile_vert")
+    let vert = 1
+  else
+    let vert = a:args =~ '\<vert\%[ical]\>'
+  endif
+
+  " Remove any watch listeners.
+  silent! autocmd! CoffeeCompileAuWatch
+
+  " If just unwatching, don't compile.
+  if unwatch
+    let s:coffee_compile_watch = 0
+    return
+  endif
+
+  if watch
+    let s:coffee_compile_watch = 1
+  endif
+
+  call s:CoffeeCompileSavePos()
+
+  " Build the CoffeeCompile buffer if it doesn't exist.
+  if s:coffee_compile_buf == -1
+    let src_win = bufwinnr(s:coffee_compile_src_buf)
+
+    " Create the new window and resize it.
+    if vert
+      let width = size ? size : winwidth(src_win) / 2
+
+      vertical new
+      exec 'vertical resize' width
+    else
+      " Try to guess the compiled output's height.
+      let height = size ? size : min([winheight(src_win) / 2,
+      \                               a:endline - a:startline + 2])
+
+      botright new
+      exec 'resize' height
+    endif
+
+    " Set up scratch buffer.
+    setlocal bufhidden=wipe buftype=nofile
+    setlocal nobuflisted nomodifiable noswapfile nowrap
+
+    autocmd BufWipeout <buffer> call s:CoffeeCompileClose()
+    nnoremap <buffer> <silent> q :hide<CR>
+
+    " Save the cursor position on each buffer switch.
+    augroup CoffeeCompileAuPos
+      autocmd BufEnter,BufLeave * call s:CoffeeCompileSavePos()
+    augroup END
+
+    let s:coffee_compile_buf = bufnr('%')
+    let s:coffee_compile_win = bufwinnr(s:coffee_compile_buf)
+  endif
+
+  " Go back to the source buffer and do the initial compile.
+  call s:CoffeeCompileRestorePos()
+
+  if s:coffee_compile_watch
+    call s:CoffeeCompileWatchUpdate()
+
+    augroup CoffeeCompileAuWatch
+      autocmd InsertLeave <buffer> call s:CoffeeCompileWatchUpdate()
+    augroup END
+  else
+    call s:CoffeeCompileUpdate(a:startline, a:endline)
+  endif
+endfunction
+
+" Complete arguments for the CoffeeCompile command.
+function! s:CoffeeCompileComplete(arg, cmdline, cursor)
+  let args = ['unwatch', 'vertical', 'watch']
+
+  if !len(a:arg)
+    return args
+  endif
+
+  let match = '^' . a:arg
+
+  for arg in args
+    if arg =~ match
+      return [arg]
+    endif
+  endfor
+endfunction
+
+" Don't let new windows overwrite the CoffeeCompile variables.
+if !exists("s:coffee_compile_buf")
+  call s:CoffeeCompileResetVars()
+endif
+
+" Peek at compiled CoffeeScript.
+command! -range=% -bar -nargs=* -complete=customlist,s:CoffeeCompileComplete
+\        CoffeeCompile call s:CoffeeCompile(<line1>, <line2>, <q-args>)
+" Run some CoffeeScript.
+command! -range=% -bar CoffeeRun <line1>,<line2>:w !coffee -s

+ 10 - 0
vim/ftplugin/html_snip_helper.vim

@@ -0,0 +1,10 @@
+" Helper function for (x)html snippets
+if exists('s:did_snip_helper') || &cp || !exists('loaded_snips')
+	finish
+endif
+let s:did_snip_helper = 1
+
+" Automatically closes tag if in xhtml
+fun! Close()
+	return stridx(&ft, 'xhtml') == -1 ? '' : ' /'
+endf

+ 338 - 0
vim/indent/coffee.vim

@@ -0,0 +1,338 @@
+" Language:    CoffeeScript
+" Maintainer:  Mick Koch <kchmck@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+if exists("b:did_indent")
+  finish
+endif
+
+let b:did_indent = 1
+
+setlocal autoindent
+setlocal indentexpr=GetCoffeeIndent(v:lnum)
+" Make sure GetCoffeeIndent is run when these are typed so they can be
+" indented or outdented.
+setlocal indentkeys+=0],0),0.,=else,=when,=catch,=finally
+
+" Only define the function once.
+if exists("*GetCoffeeIndent")
+  finish
+endif
+
+" Keywords to indent after
+let s:INDENT_AFTER_KEYWORD = '^\%(if\|unless\|else\|for\|while\|until\|'
+\                          . 'loop\|switch\|when\|try\|catch\|finally\|'
+\                          . 'class\)\>'
+
+" Operators to indent after
+let s:INDENT_AFTER_OPERATOR = '\%([([{:=]\|[-=]>\)$'
+
+" Keywords and operators that continue a line
+let s:CONTINUATION = '\<\%(is\|isnt\|and\|or\)\>$'
+\                  . '\|'
+\                  . '\%(-\@<!-\|+\@<!+\|<\|[-=]\@<!>\|\*\|/\@<!/\|%\||\|'
+\                  . '&\|,\|\.\@<!\.\)$'
+
+" Operators that block continuation indenting
+let s:CONTINUATION_BLOCK = '[([{:=]$'
+
+" A continuation dot access
+let s:DOT_ACCESS = '^\.'
+
+" Keywords to outdent after
+let s:OUTDENT_AFTER = '^\%(return\|break\|continue\|throw\)\>'
+
+" A compound assignment like `... = if ...`
+let s:COMPOUND_ASSIGNMENT = '[:=]\s*\%(if\|unless\|for\|while\|until\|'
+\                         . 'switch\|try\|class\)\>'
+
+" A postfix condition like `return ... if ...`.
+let s:POSTFIX_CONDITION = '\S\s\+\zs\<\%(if\|unless\)\>'
+
+" A single-line else statement like `else ...` but not `else if ...
+let s:SINGLE_LINE_ELSE = '^else\s\+\%(\<\%(if\|unless\)\>\)\@!'
+
+" Max lines to look back for a match
+let s:MAX_LOOKBACK = 50
+
+" Syntax names for strings
+let s:SYNTAX_STRING = 'coffee\%(String\|AssignString\|Embed\|Regex\|Heregex\|'
+\                   . 'Heredoc\)'
+
+" Syntax names for comments
+let s:SYNTAX_COMMENT = 'coffee\%(Comment\|BlockComment\|HeregexComment\)'
+
+" Syntax names for strings and comments
+let s:SYNTAX_STRING_COMMENT = s:SYNTAX_STRING . '\|' . s:SYNTAX_COMMENT
+
+" Get the linked syntax name of a character.
+function! s:SyntaxName(linenum, col)
+  return synIDattr(synID(a:linenum, a:col, 1), 'name')
+endfunction
+
+" Check if a character is in a comment.
+function! s:IsComment(linenum, col)
+  return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_COMMENT
+endfunction
+
+" Check if a character is in a string.
+function! s:IsString(linenum, col)
+  return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING
+endfunction
+
+" Check if a character is in a comment or string.
+function! s:IsCommentOrString(linenum, col)
+  return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING_COMMENT
+endfunction
+
+" Check if a whole line is a comment.
+function! s:IsCommentLine(linenum)
+  " Check the first non-whitespace character.
+  return s:IsComment(a:linenum, indent(a:linenum) + 1)
+endfunction
+
+" Repeatedly search a line for a regex until one is found outside a string or
+" comment.
+function! s:SmartSearch(linenum, regex)
+  " Start at the first column.
+  let col = 0
+
+  " Search until there are no more matches, unless a good match is found.
+  while 1
+    call cursor(a:linenum, col + 1)
+    let [_, col] = searchpos(a:regex, 'cn', a:linenum)
+
+    " No more matches.
+    if !col
+      break
+    endif
+
+    if !s:IsCommentOrString(a:linenum, col)
+      return 1
+    endif
+  endwhile
+
+  " No good match found.
+  return 0
+endfunction
+
+" Skip a match if it's in a comment or string, is a single-line statement that
+" isn't adjacent, or is a postfix condition.
+function! s:ShouldSkip(startlinenum, linenum, col)
+  if s:IsCommentOrString(a:linenum, a:col)
+    return 1
+  endif
+
+  " Check for a single-line statement that isn't adjacent.
+  if s:SmartSearch(a:linenum, '\<then\>') && a:startlinenum - a:linenum > 1
+    return 1
+  endif
+
+  if s:SmartSearch(a:linenum, s:POSTFIX_CONDITION) &&
+  \ !s:SmartSearch(a:linenum, s:COMPOUND_ASSIGNMENT)
+    return 1
+  endif
+
+  return 0
+endfunction
+
+" Find the farthest line to look back to, capped to line 1 (zero and negative
+" numbers cause bad things).
+function! s:MaxLookback(startlinenum)
+  return max([1, a:startlinenum - s:MAX_LOOKBACK])
+endfunction
+
+" Get the skip expression for searchpair().
+function! s:SkipExpr(startlinenum)
+  return "s:ShouldSkip(" . a:startlinenum . ", line('.'), col('.'))"
+endfunction
+
+" Search for pairs of text.
+function! s:SearchPair(start, end)
+  " The cursor must be in the first column for regexes to match.
+  call cursor(0, 1)
+
+  let startlinenum = line('.')
+
+  " Don't need the W flag since MaxLookback caps the search to line 1.
+  return searchpair(a:start, '', a:end, 'bcn',
+  \                 s:SkipExpr(startlinenum),
+  \                 s:MaxLookback(startlinenum))
+endfunction
+
+" Try to find a previous matching line.
+function! s:GetMatch(curline)
+  let firstchar = a:curline[0]
+
+  if firstchar == '}'
+    return s:SearchPair('{', '}')
+  elseif firstchar == ')'
+    return s:SearchPair('(', ')')
+  elseif firstchar == ']'
+    return s:SearchPair('\[', '\]')
+  elseif a:curline =~ '^else\>'
+    return s:SearchPair('\<\%(if\|unless\|when\)\>', '\<else\>')
+  elseif a:curline =~ '^catch\>'
+    return s:SearchPair('\<try\>', '\<catch\>')
+  elseif a:curline =~ '^finally\>'
+    return s:SearchPair('\<try\>', '\<finally\>')
+  endif
+
+  return 0
+endfunction
+
+" Get the nearest previous line that isn't a comment.
+function! s:GetPrevNormalLine(startlinenum)
+  let curlinenum = a:startlinenum
+
+  while curlinenum > 0
+    let curlinenum = prevnonblank(curlinenum - 1)
+
+    if !s:IsCommentLine(curlinenum)
+      return curlinenum
+    endif
+  endwhile
+
+  return 0
+endfunction
+
+" Try to find a comment in a line.
+function! s:FindComment(linenum)
+  let col = 0
+
+  while 1
+    call cursor(a:linenum, col + 1)
+    let [_, col] = searchpos('#', 'cn', a:linenum)
+
+    if !col
+      break
+    endif
+
+    if s:IsComment(a:linenum, col)
+      return col
+    endif
+  endwhile
+
+  return 0
+endfunction
+
+" Get a line without comments or surrounding whitespace.
+function! s:GetTrimmedLine(linenum)
+  let comment = s:FindComment(a:linenum)
+  let line = getline(a:linenum)
+
+  if comment
+    " Subtract 1 to get to the column before the comment and another 1 for
+    " zero-based indexing.
+    let line = line[:comment - 2]
+  endif
+
+  return substitute(substitute(line, '^\s\+', '', ''),
+  \                                  '\s\+$', '', '')
+endfunction
+
+function! s:GetCoffeeIndent(curlinenum)
+  let prevlinenum = s:GetPrevNormalLine(a:curlinenum)
+
+  " Don't do anything if there's no previous line.
+  if !prevlinenum
+    return -1
+  endif
+
+  let curline = s:GetTrimmedLine(a:curlinenum)
+
+  " Try to find a previous matching statement. This handles outdenting.
+  let matchlinenum = s:GetMatch(curline)
+
+  if matchlinenum
+    return indent(matchlinenum)
+  endif
+
+  " Try to find a matching `when`.
+  if curline =~ '^when\>' && !s:SmartSearch(prevlinenum, '\<switch\>')
+    let linenum = a:curlinenum
+
+    while linenum > 0
+      let linenum = s:GetPrevNormalLine(linenum)
+
+      if getline(linenum) =~ '^\s*when\>'
+        return indent(linenum)
+      endif
+    endwhile
+
+    return -1
+  endif
+
+  let prevline = s:GetTrimmedLine(prevlinenum)
+  let previndent = indent(prevlinenum)
+
+  " Always indent after these operators.
+  if prevline =~ s:INDENT_AFTER_OPERATOR
+    return previndent + &shiftwidth
+  endif
+
+  " Indent after a continuation if it's the first.
+  if prevline =~ s:CONTINUATION
+    " If the line ends in a slash, make sure it isn't a regex.
+    if prevline =~ '/$'
+      " Move to the line so we can get the last column.
+      call cursor(prevlinenum)
+
+      if s:IsString(prevlinenum, col('$') - 1)
+        return -1
+      endif
+    endif
+
+    let prevprevlinenum = s:GetPrevNormalLine(prevlinenum)
+
+    " If the continuation is the first in the file, don't run the other checks.
+    if !prevprevlinenum
+      return previndent + &shiftwidth
+    endif
+
+    let prevprevline = s:GetTrimmedLine(prevprevlinenum)
+
+    if prevprevline !~ s:CONTINUATION && prevprevline !~ s:CONTINUATION_BLOCK
+      return previndent + &shiftwidth
+    endif
+
+    return -1
+  endif
+
+  " Indent after these keywords and compound assignments if they aren't a
+  " single-line statement.
+  if prevline =~ s:INDENT_AFTER_KEYWORD || prevline =~ s:COMPOUND_ASSIGNMENT
+    if !s:SmartSearch(prevlinenum, '\<then\>') && prevline !~ s:SINGLE_LINE_ELSE
+      return previndent + &shiftwidth
+    endif
+
+    return -1
+  endif
+
+  " Indent a dot access if it's the first.
+  if curline =~ s:DOT_ACCESS && prevline !~ s:DOT_ACCESS
+    return previndent + &shiftwidth
+  endif
+
+  " Outdent after these keywords if they don't have a postfix condition or are
+  " a single-line statement.
+  if prevline =~ s:OUTDENT_AFTER
+    if !s:SmartSearch(prevlinenum, s:POSTFIX_CONDITION) ||
+    \   s:SmartSearch(prevlinenum, '\<then\>')
+      return previndent - &shiftwidth
+    endif
+  endif
+
+  " No indenting or outdenting is needed.
+  return -1
+endfunction
+
+" Wrap s:GetCoffeeIndent to keep the cursor position.
+function! GetCoffeeIndent(curlinenum)
+  let oldcursor = getpos('.')
+  let indent = s:GetCoffeeIndent(a:curlinenum)
+  call setpos('.', oldcursor)
+
+  return indent
+endfunction

+ 291 - 0
vim/indent/ocaml.vim

@@ -0,0 +1,291 @@
+" Vim indent file
+" Language:     OCaml
+" Maintainers:  Jean-Francois Yuen   <jfyuen@happycoders.org>
+"               Mike Leary           <leary@nwlink.com>
+"               Markus Mottl         <markus.mottl@gmail.com>
+" URL:          http://www.ocaml.info/vim/indent/ocaml.vim
+" Last Change:  2010 Sep 04 - Added an indentation improvement by Mark Weber
+"               2005 Jun 25 - Fixed multiple bugs due to 'else\nreturn ind' working
+"               2005 May 09 - Added an option to not indent OCaml-indents specially (MM)
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal expandtab
+setlocal indentexpr=GetOCamlIndent()
+setlocal indentkeys+=0=and,0=class,0=constraint,0=done,0=else,0=end,0=exception,0=external,0=if,0=in,0=include,0=inherit,0=initializer,0=let,0=method,0=open,0=then,0=type,0=val,0=with,0;;,0>\],0\|\],0>},0\|,0},0\],0)
+setlocal nolisp
+setlocal nosmartindent
+setlocal textwidth=80
+setlocal shiftwidth=2
+
+" Comment formatting
+if !exists("no_ocaml_comments")
+ if (has("comments"))
+   setlocal comments=sr:(**,mb:\ ,ex:*),sr:(*,m:*,ex:*)
+   setlocal fo=cqort
+ endif
+endif
+
+" Only define the function once.
+if exists("*GetOCamlIndent")
+ finish
+endif
+
+" Define some patterns:
+let s:beflet = '^\s*\(initializer\|method\|try\)\|\(\<\(begin\|do\|else\|in\|then\|try\)\|->\|<-\|=\|;\|(\)\s*$'
+let s:letpat = '^\s*\(let\|type\|module\|class\|open\|exception\|val\|include\|external\)\>'
+let s:letlim = '\(\<\(sig\|struct\)\|;;\)\s*$'
+let s:lim = '^\s*\(exception\|external\|include\|let\|module\|open\|type\|val\)\>'
+let s:module = '\<\%(begin\|sig\|struct\|object\)\>'
+let s:obj = '^\s*\(constraint\|inherit\|initializer\|method\|val\)\>\|\<\(object\|object\s*(.*)\)\s*$'
+let s:type = '^\s*\%(class\|let\|type\)\>.*='
+
+" Skipping pattern, for comments
+function! s:GetLineWithoutFullComment(lnum)
+ let lnum = prevnonblank(a:lnum - 1)
+ let lline = substitute(getline(lnum), '(\*.*\*)\s*$', '', '')
+ while lline =~ '^\s*$' && lnum > 0
+   let lnum = prevnonblank(lnum - 1)
+   let lline = substitute(getline(lnum), '(\*.*\*)\s*$', '', '')
+ endwhile
+ return lnum
+endfunction
+
+" Indent for ';;' to match multiple 'let'
+function! s:GetInd(lnum, pat, lim)
+ let llet = search(a:pat, 'bW')
+ let old = indent(a:lnum)
+ while llet > 0
+   let old = indent(llet)
+   let nb = s:GetLineWithoutFullComment(llet)
+   if getline(nb) =~ a:lim
+     return old
+   endif
+   let llet = search(a:pat, 'bW')
+ endwhile
+ return old
+endfunction
+
+" Indent pairs
+function! s:FindPair(pstart, pmid, pend)
+ call search(a:pend, 'bW')
+ return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
+endfunction
+
+" Indent 'let'
+function! s:FindLet(pstart, pmid, pend)
+ call search(a:pend, 'bW')
+ return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") =~ "^\\s*let\\>.*=.*\\<in\\s*$" || getline(prevnonblank(".") - 1) =~ s:beflet'))
+endfunction
+
+function! GetOCamlIndent()
+ " Find a non-commented line above the current line.
+ let lnum = s:GetLineWithoutFullComment(v:lnum)
+
+ " At the start of the file use zero indent.
+ if lnum == 0
+   return 0
+ endif
+
+ let ind = indent(lnum)
+ let lline = substitute(getline(lnum), '(\*.*\*)\s*$', '', '')
+
+ " Return double 'shiftwidth' after lines matching:
+ "if lline =~ '^\s*|.*->\s*$'
+ "  return ind + &sw + &sw
+ "endif
+
+ let line = getline(v:lnum)
+
+ " Indent if line ends with 'match ... with':
+ "if lline =~ '\<match\>.*\<with\s*$'
+ "  return ind + &sw
+
+ " Indent if current line begins with 'end':
+ if line =~ '^\s*end\>'
+   return s:FindPair(s:module, '','\<end\>')
+
+ " Indent if current line begins with 'done' for 'do':
+ elseif line =~ '^\s*done\>'
+   return s:FindPair('\<do\>', '','\<done\>')
+
+ " Indent if current line begins with '}' or '>}':
+ elseif line =~ '^\s*\(\|>\)}'
+   return s:FindPair('{', '','}')
+
+ " Indent if current line begins with ']', '|]' or '>]':
+ elseif line =~ '^\s*\(\||\|>\)\]'
+   return s:FindPair('\[', '','\]')
+
+ " Indent if current line begins with ')':
+ elseif line =~ '^\s*)'
+   return s:FindPair('(', '',')')
+
+ " Indent if current line begins with 'let':
+ elseif line =~ '^\s*let\>'
+   if lline !~ s:lim . '\|' . s:letlim . '\|' . s:beflet
+     return s:FindLet(s:type, '','\<let\s*$')
+   endif
+
+ " Indent if current line begins with 'class' or 'type':
+ elseif line =~ '^\s*\(class\|type\)\>'
+   if lline !~ s:lim . '\|\<and\s*$\|' . s:letlim
+     return s:FindLet(s:type, '','\<\(class\|type\)\s*$')
+   endif
+
+ " Indent for pattern matching:
+ elseif line =~ '^\s*|'
+   if lline !~ '^\s*\(|[^\]]\|\(match\|type\|with\)\>\)\|\<\(function\|parser\|private\|with\)\s*$'
+     call search('|', 'bW')
+     return indent(searchpair('^\s*\(match\|type\)\>\|\<\(function\|parser\|private\|with\)\s*$', '', '^\s*|', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") !~ "^\\s*|.*->"'))
+   endif
+
+ " Indent if current line begins with ';;':
+ elseif line =~ '^\s*;;'
+   if lline !~ ';;\s*$'
+     return s:GetInd(v:lnum, s:letpat, s:letlim)
+   endif
+
+ " Indent if current line begins with 'in':
+ elseif line =~ '^\s*in\>'
+   if lline !~ '^\s*\(let\|and\)\>'
+     return s:FindPair('\<let\>', '', '\<in\>')
+   endif
+
+ " Indent if current line begins with 'else':
+ elseif line =~ '^\s*else\>'
+   if lline !~ '^\s*\(if\|then\)\>'
+     return s:FindPair('\<if\>', '', '\<else\>')
+   endif
+
+ " Indent if current line begins with 'then':
+ elseif line =~ '^\s*then\>'
+   if lline !~ '^\s*\(if\|else\)\>'
+     return s:FindPair('\<if\>', '', '\<then\>')
+   endif
+
+ " Indent if current line begins with 'and':
+ elseif line =~ '^\s*and\>'
+   if lline !~ '^\s*\(and\|let\|type\)\>\|\<end\s*$'
+     return ind - &sw
+   endif
+
+ " Indent if current line begins with 'with':
+ elseif line =~ '^\s*with\>'
+   if lline !~ '^\s*\(match\|try\)\>'
+     return s:FindPair('\<\%(match\|try\)\>', '','\<with\>')
+   endif
+
+ " Indent if current line begins with 'exception', 'external', 'include' or
+ " 'open':
+ elseif line =~ '^\s*\(exception\|external\|include\|open\)\>'
+   if lline !~ s:lim . '\|' . s:letlim
+     call search(line)
+     return indent(search('^\s*\(\(exception\|external\|include\|open\|type\)\>\|val\>.*:\)', 'bW'))
+   endif
+
+ " Indent if current line begins with 'val':
+ elseif line =~ '^\s*val\>'
+   if lline !~ '^\s*\(exception\|external\|include\|open\)\>\|' . s:obj . '\|' . s:letlim
+     return indent(search('^\s*\(\(exception\|include\|initializer\|method\|open\|type\|val\)\>\|external\>.*:\)', 'bW'))
+   endif
+
+ " Indent if current line begins with 'constraint', 'inherit', 'initializer'
+ " or 'method':
+ elseif line =~ '^\s*\(constraint\|inherit\|initializer\|method\)\>'
+   if lline !~ s:obj
+     return indent(search('\<\(object\|object\s*(.*)\)\s*$', 'bW')) + &sw
+   endif
+
+ endif
+
+ " Add a 'shiftwidth' after lines ending with:
+ if lline =~ '\(:\|=\|->\|<-\|(\|\[\|{\|{<\|\[|\|\[<\|\<\(begin\|do\|else\|fun\|function\|functor\|if\|initializer\|object\|parser\|private\|sig\|struct\|then\|try\)\|\<object\s*(.*)\)\s*$'
+   let ind = ind + &sw
+
+ " Back to normal indent after lines ending with ';;':
+ elseif lline =~ ';;\s*$' && lline !~ '^\s*;;'
+   let ind = s:GetInd(v:lnum, s:letpat, s:letlim)
+
+ " Back to normal indent after lines ending with 'end':
+ elseif lline =~ '\<end\s*$'
+   let ind = s:FindPair(s:module, '','\<end\>')
+
+ " Back to normal indent after lines ending with 'in':
+ elseif lline =~ '\<in\s*$' && lline !~ '^\s*in\>'
+   let ind = s:FindPair('\<let\>', '', '\<in\>')
+
+ " Back to normal indent after lines ending with 'done':
+ elseif lline =~ '\<done\s*$'
+   let ind = s:FindPair('\<do\>', '','\<done\>')
+
+ " Back to normal indent after lines ending with '}' or '>}':
+ elseif lline =~ '\(\|>\)}\s*$'
+   let ind = s:FindPair('{', '', '}')
+
+ " Back to normal indent after lines ending with ']', '|]' or '>]':
+ elseif lline =~ '\(\||\|>\)\]\s*$'
+   let ind = s:FindPair('\[', '', '\]')
+
+ " Back to normal indent after comments:
+ elseif lline =~ '\*)\s*$'
+   call search('\*)', 'bW')
+   let ind = indent(searchpair('(\*', '', '\*)', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"'))
+
+ " Back to normal indent after lines ending with ')':
+ elseif lline =~ ')\s*$'
+   let ind = s:FindPair('(', '', ')')
+
+ " Indent closing brachet for ocamldoc comment properly
+ "elseif lline =~ '^\s*(\*\*' && line =~ '^\s*\*)'
+ "  let ind = s:FindPair('(\*\*', '', '\*)') + 1
+
+ " If this is an ocamldoc comment then indent with 4 spaces
+ elseif lline =~ '^\s*(\*\*'
+   let ind = 4
+
+ " If this is a multiline comment then align '*':
+ "elseif lline =~ '^\s*(\*' && line =~ '^\s*\*'
+ "  let ind = ind + 1
+
+ " String with continuation character -> indent continuation on next line
+ elseif lline =~ '\\\s*$'
+   call search('\\', 'bW')
+   let ind = searchpairpos('"', '', '"', 'bWn', 'getline(".")[col(".")-2] =~ "\\"')[1]
+
+ " Return to original indent when string ends
+ elseif lline =~ '"\s*$'
+   call search('"', 'bW')
+   let ind = indent(searchpair('"', '', '"', 'bWn', 'getline(".")[col(".")-2] =~ "\\"'))
+   "let ind = searchpairpos('"', '', '"', 'bWn', 'getline(".")[col(".")-2] =~ "\\"')[1] - 1
+
+ else
+ " Don't change indentation of this line
+ " for new lines (indent==0) use indentation of previous line
+
+ " This is for preventing removing indentation of these args:
+ "   let f x =
+ "     let y = x + 1 in
+ "     Printf.printf
+ "       "o"           << here
+ "       "oeuth"       << don't touch indentation
+
+   let i = indent(v:lnum)
+   return i == 0 ? ind : i
+
+ endif
+
+ " Subtract a 'shiftwidth' after lines matching 'match ... with parser':
+ if lline =~ '\<match\>.*\<with\>\s*\<parser\s*$'
+   let ind = ind - &sw
+ endif
+
+ return ind
+
+endfunction
+
+" vim:sw=2

+ 495 - 0
vim/plugin/clang_complete.vim

@@ -0,0 +1,495 @@
+"
+" File: clang_complete.vim
+" Author: Xavier Deguillard <deguilx@gmail.com>
+"
+" Description: Use of clang to complete in C/C++.
+"
+" Configuration: Each project can have a .clang_complete at his root,
+"                containing the compiler options. This is useful if
+"                you're using some non-standard include paths.
+"                For simplicity, please don't put relative and
+"                absolute include path on the same line. It is not
+"                currently correctly handled.
+"
+" Options:
+"  - g:clang_complete_auto:
+"       if equal to 1, automatically complete after ->, ., ::
+"       Default: 1
+"
+"  - g:clang_complete_copen:
+"       if equal to 1, open quickfix window on error.
+"       Default: 0
+"
+"  - g:clang_hl_errors:
+"       if equal to 1, it will highlight the warnings and errors the
+"       same way clang does it.
+"       Default: 1
+"
+"  - g:clang_periodic_quickfix:
+"       if equal to 1, it will periodically update the quickfix window
+"       Note: You could use the g:ClangUpdateQuickFix() to do the same
+"             with a mapping.
+"       Default: 0
+"
+"  - g:clang_snippets:
+"       if equal to 1, it will do some snippets magic after a ( or a ,
+"       inside function call. Not currently fully working.
+"       Default: 0
+"
+"  - g:clang_conceal_snippets:
+"       if equal to 1, vim will use vim 7.3 conceal feature to hide <#
+"       and #> which delimit a snippets.
+"       Note: See concealcursor and conceallevel for conceal configuration.
+"       Default: 1 (0 if conceal not available)
+"
+"  - g:clang_exec:
+"       Name or path of clang executable.
+"       Note: Use this if clang has a non-standard name, or isn't in the
+"       path.
+"       Default: 'clang'
+"
+"  - g:clang_user_options:
+"       Option added at the end of clang command. Useful if you want to
+"       filter the result, or if you want to ignore the error code
+"       returned by clang: on error, the completion is not shown.
+"       Default: ''
+"       Example: '|| exit 0' (it will discard clang return value)
+"
+" Todo: - Fix bugs
+"       - Parse fix-its and do something useful with it.
+"       - -code-completion-macros -code-completion-patterns
+"
+
+au FileType c,cpp,objc,objcpp call s:ClangCompleteInit()
+
+let b:clang_parameters = ''
+let b:clang_user_options = ''
+let b:my_changedtick = 0
+
+function s:ClangCompleteInit()
+    let l:local_conf = findfile(".clang_complete", '.;')
+    let b:clang_user_options = ''
+    if l:local_conf != ""
+        let l:opts = readfile(l:local_conf)
+        for l:opt in l:opts
+            " Better handling of absolute path
+            " I don't know if those pattern will work on windows
+            " platform
+            if matchstr(l:opt, '\C-I\s*/') != ""
+                let l:opt = substitute(l:opt, '\C-I\s*\(/\%(\w\|\\\s\)*\)',
+                            \ '-I' . '\1', "g")
+            else
+                let l:opt = substitute(l:opt, '\C-I\s*\(\%(\w\|\\\s\)*\)',
+                            \ '-I' . l:local_conf[:-16] . '\1', "g")
+            endif
+            let b:clang_user_options .= " " . l:opt
+        endfor
+    endif
+
+    if !exists('g:clang_complete_auto')
+        let g:clang_complete_auto = 1
+    endif
+
+    if !exists('g:clang_complete_copen')
+        let g:clang_complete_copen = 0
+    endif
+
+    if !exists('g:clang_hl_errors')
+        let g:clang_hl_errors = 1
+    endif
+
+    if !exists('g:clang_periodic_quickfix')
+        let g:clang_periodic_quickfix = 0
+    endif
+
+    if !exists('g:clang_snippets')
+        let g:clang_snippets = 0
+    endif
+
+    if !exists('g:clang_conceal_snippets')
+        let g:clang_conceal_snippets = has("conceal")
+    endif
+
+    if !exists('g:clang_exec')
+        let g:clang_exec = 'clang'
+    endif
+
+    if !exists('g:clang_user_options')
+        let g:clang_user_options = ''
+    endif
+    let b:clang_user_options .= ' ' . g:clang_user_options
+
+    if g:clang_complete_auto == 1
+        inoremap <expr> <buffer> <C-X><C-U> LaunchCompletion()
+        inoremap <expr> <buffer> . CompleteDot()
+        inoremap <expr> <buffer> > CompleteArrow()
+        inoremap <expr> <buffer> : CompleteColon()
+    endif
+
+    if g:clang_snippets == 1
+        noremap <expr> <buffer> <tab> UpdateSnips()
+        snoremap <expr> <buffer> <tab> UpdateSnips()
+        if g:clang_conceal_snippets == 1
+            syntax match Conceal /<#/ conceal
+            syntax match Conceal /#>/ conceal
+        endif
+    endif
+
+    " Disable every autocmd that could have been set.
+    augroup ClangComplete
+        autocmd!
+    augroup end
+
+    let b:should_overload = 0
+    let b:my_changedtick = b:changedtick
+    let b:clang_parameters = '-x c'
+
+    if &filetype == 'objc'
+        let b:clang_parameters = '-x objective-c'
+    endif
+
+    if &filetype == 'cpp' || &filetype == 'objcpp'
+        let b:clang_parameters .= '++'
+    endif
+
+    if expand('%:e') =~ 'h*'
+        let b:clang_parameters .= '-header'
+    endif
+
+    setlocal completefunc=ClangComplete
+
+    if g:clang_periodic_quickfix == 1
+        augroup ClangComplete
+            au CursorHold,CursorHoldI <buffer> call s:DoPeriodicQuickFix()
+        augroup end
+    endif
+endfunction
+
+function s:GetKind(proto)
+    if a:proto == ""
+        return 't'
+    endif
+    let l:ret = match(a:proto, '^\[#')
+    let l:params = match(a:proto, '(')
+    if l:ret == -1 && l:params == -1
+        return 't'
+    endif
+    if l:ret != -1 && l:params == -1
+        return 'v'
+    endif
+    if l:params != -1
+        return 'f'
+    endif
+    return 'm'
+endfunction
+
+function s:DoPeriodicQuickFix()
+    " Don't do any superfluous reparsing.
+    if b:my_changedtick == b:changedtick
+        return
+    endif
+    let b:my_changedtick = b:changedtick
+
+    let l:buf = getline(1, '$')
+    let l:tempfile = expand('%:p:h') . '/' . localtime() . expand('%:t')
+    try
+        call writefile(l:buf, l:tempfile)
+    catch /^Vim\%((\a\+)\)\=:E482/
+        return
+    endtry
+    let l:escaped_tempfile = shellescape(l:tempfile)
+
+    let l:command = g:clang_exec . " -cc1 -fsyntax-only"
+                \ . " -fno-caret-diagnostics -fdiagnostics-print-source-range-info"
+                \ . " " . l:escaped_tempfile
+                \ . " " . b:clang_parameters . " " . b:clang_user_options
+
+    let l:clang_output = split(system(l:command), "\n")
+    call delete(l:tempfile)
+    call s:ClangQuickFix(l:clang_output, l:tempfile)
+endfunction
+
+function s:ClangQuickFix(clang_output, tempfname)
+    " Clear the bad spell, the user may have corrected them.
+    syntax clear SpellBad
+    syntax clear SpellLocal
+    let l:list = []
+    for l:line in a:clang_output
+        let l:erridx = match(l:line, '\%(error\|warning\): ')
+        if l:erridx == -1
+            " Error are always at the beginning.
+            if l:line[:11] == 'COMPLETION: ' || l:line[:9] == 'OVERLOAD: '
+                break
+            endif
+            continue
+        endif
+        let l:pattern = '^\(.*\):\(\d*\):\(\d*\):\(\%({\d\+:\d\+-\d\+:\d\+}\)*\)'
+        let l:tmp = matchstr(l:line, l:pattern)
+        let l:fname = substitute(l:tmp, l:pattern, '\1', '')
+        if l:fname == a:tempfname
+            let l:fname = "%"
+        endif
+        let l:bufnr = bufnr(l:fname, 1)
+        let l:lnum = substitute(l:tmp, l:pattern, '\2', '')
+        let l:col = substitute(l:tmp, l:pattern, '\3', '')
+        let l:errors = substitute(l:tmp, l:pattern, '\4', '')
+        if l:line[l:erridx] == 'e'
+            let l:text = l:line[l:erridx + 7:]
+            let l:type = 'E'
+            let l:hlgroup = " SpellBad "
+        else
+            let l:text = l:line[l:erridx + 9:]
+            let l:type = 'W'
+            let l:hlgroup = " SpellLocal "
+        endif
+        let l:item = {
+                    \ "bufnr": l:bufnr,
+                    \ "lnum": l:lnum,
+                    \ "col": l:col,
+                    \ "text": l:text,
+                    \ "type": l:type }
+        let l:list = add(l:list, l:item)
+
+        if g:clang_hl_errors == 0 || l:fname != "%"
+            continue
+        endif
+
+        " Highlighting the ^
+        let l:pat = '/\%' . l:lnum . 'l' . '\%' . l:col . 'c./'
+        exe "syntax match" . l:hlgroup . l:pat
+
+        if l:errors == ""
+            continue
+        endif
+        let l:ranges = split(l:errors, '}')
+        for l:range in l:ranges
+            " Doing precise error and warning handling.
+            " The highlight will be the same as clang's carets.
+            let l:pattern = '{\%(\d\+\):\(\d\+\)-\%(\d\+\):\(\d\+\)'
+            let l:tmp = matchstr(l:range, l:pattern)
+            let l:startcol = substitute(l:tmp, l:pattern, '\1', '')
+            let l:endcol = substitute(l:tmp, l:pattern, '\2', '')
+            " Highlighting the ~~~~
+            let l:pat = '/\%' . l:lnum . 'l'
+                        \ . '\%' . l:startcol . 'c'
+                        \ . '.*'
+                        \ . '\%' . l:endcol . 'c/'
+            exe "syntax match" . l:hlgroup . l:pat
+        endfor
+    endfor
+    call setqflist(l:list)
+    doautocmd QuickFixCmdPost make
+    if g:clang_complete_copen == 1
+        " We should get back to the original buffer
+        let l:bufnr = bufnr("%")
+        cwindow
+        let l:winbufnr = bufwinnr(l:bufnr)
+        exe l:winbufnr . "wincmd w"
+    endif
+endfunction
+
+function s:DemangleProto(prototype)
+    let l:proto = substitute(a:prototype, '[#', "", "g")
+    let l:proto = substitute(l:proto, '#]', ' ', "g")
+    let l:proto = substitute(l:proto, '#>', "", "g")
+    let l:proto = substitute(l:proto, '<#', "", "g")
+    " TODO: add a candidate for each optional parameter
+    let l:proto = substitute(l:proto, '{#', "", "g")
+    let l:proto = substitute(l:proto, '#}', "", "g")
+
+    return l:proto
+endfunction
+
+let b:col = 0
+function ClangComplete(findstart, base)
+    if a:findstart
+        let l:line = getline('.')
+        let l:start = col('.') - 1
+        let l:wsstart = l:start
+        if l:line[l:wsstart - 1] =~ '\s'
+            while l:wsstart > 0 && l:line[l:wsstart - 1] =~ '\s'
+                let l:wsstart -= 1
+            endwhile
+        endif
+        if l:line[l:wsstart - 1] =~ '[(,]'
+            let b:should_overload = 1
+            let b:col = l:wsstart + 1
+            return l:wsstart
+        endif
+        let b:should_overload = 0
+        while l:start > 0 && l:line[l:start - 1] =~ '\i'
+            let l:start -= 1
+        endwhile
+        let b:col = l:start + 1
+        return l:start
+    else
+        let l:buf = getline(1, '$')
+        let l:tempfile = expand('%:p:h') . '/' . localtime() . expand('%:t')
+        try
+            call writefile(l:buf, l:tempfile)
+        catch /^Vim\%((\a\+)\)\=:E482/
+            return {}
+        endtry
+        let l:escaped_tempfile = shellescape(l:tempfile)
+
+        let l:command = g:clang_exec . " -cc1 -fsyntax-only"
+                    \ . " -fno-caret-diagnostics -fdiagnostics-print-source-range-info"
+                    \ . " -code-completion-at=" . l:escaped_tempfile . ":"
+                    \ . line('.') . ":" . b:col . " " . l:escaped_tempfile
+                    \ . " " . b:clang_parameters . " " . b:clang_user_options
+        let l:clang_output = split(system(l:command), "\n")
+        call delete(l:tempfile)
+
+        call s:ClangQuickFix(l:clang_output, l:tempfile)
+        if v:shell_error
+            return {}
+        endif
+        if l:clang_output == []
+            return {}
+        endif
+
+        let l:res = []
+        for l:line in l:clang_output
+            if l:line[:11] == 'COMPLETION: ' && b:should_overload != 1
+                let l:value = l:line[12:]
+
+                if l:value =~ 'Pattern'
+                    if g:clang_snippets != 1
+                        continue
+                    endif
+
+                    let l:value = l:value[10:]
+                endif
+
+                if l:value !~ '^' . a:base
+                    continue
+                endif
+
+                let l:colonidx = stridx(l:value, " : ")
+                if l:colonidx == -1
+                    let l:wabbr = s:DemangleProto(l:value)
+                    let l:word = l:value
+                    let l:proto = l:value
+                else
+                    let l:word = l:value[:l:colonidx - 1]
+                    " WTF is that?
+                    if l:word =~ '(Hidden)'
+                        let l:word = l:word[:-10]
+                    endif
+                    let l:wabbr = l:word
+                    let l:proto = l:value[l:colonidx + 3:]
+                endif
+
+                let l:kind = s:GetKind(l:proto)
+                if g:clang_snippets == 1
+                    let l:word = substitute(l:proto, '\[#[^#]*#\]', "", "g")
+                else
+                    let l:word = l:wabbr
+                endif
+                let l:proto = s:DemangleProto(l:proto)
+
+            elseif l:line[:9] == 'OVERLOAD: ' && b:should_overload == 1
+                        \ && g:clang_snippets == 1
+
+                let l:value = l:line[10:]
+                if match(l:value, '<#') == -1
+                    continue
+                endif
+                " TODO: handle optionnal parameters correctly.
+                let l:word = substitute(l:value, '.*<#', '<#', "g")
+                let l:word = substitute(l:word, '#>.*', '#>', "g")
+                let l:wabbr = substitute(l:word, '<#\([^#]*\)#>', '\1', "g")
+                let l:proto = s:DemangleProto(l:value)
+                let l:kind = ""
+
+            else
+                continue
+            endif
+
+            let l:item = {
+                        \ "word": l:word,
+                        \ "abbr": l:wabbr,
+                        \ "menu": l:proto,
+                        \ "info": l:proto,
+                        \ "dup": 1,
+                        \ "kind": l:kind }
+
+            call add(l:res, l:item)
+        endfor
+        if g:clang_snippets == 1
+            augroup ClangComplete
+                au CursorMovedI <buffer> call BeginSnips()
+            augroup end
+        endif
+        return l:res
+    endif
+endfunction
+
+function ShouldComplete()
+    if (getline(".") =~ '#\s*\(include\|import\)')
+        return 0
+    else
+        return match(synIDattr(synID(line("."), col(".") - 1, 1), "name"),
+                    \'\C\<cComment\|\<cCppString\|\<cString\|\<cNumber') == -1
+endfunction
+
+function LaunchCompletion()
+    if ShouldComplete()
+        return "\<C-X>\<C-U>"
+    else
+        return ""
+    endif
+endfunction
+
+function CompleteDot()
+    return '.' . LaunchCompletion()
+endfunction
+
+function CompleteArrow()
+    if getline('.')[col('.') - 2] != '-'
+        return '>'
+    endif
+    return '>' . LaunchCompletion()
+endfunction
+
+function CompleteColon()
+    if getline('.')[col('.') - 2] != ':'
+        return ':'
+    endif
+    return ':' . LaunchCompletion()
+endfunction
+
+function UpdateSnips()
+    let l:line = getline(".")
+    let l:pattern = '<#[^#]*#>'
+    if match(l:line, l:pattern) == -1
+        return ""
+    endif
+    " Is it possible to use f/t/F/T on multiple chars?
+    "return "\<esc>f<va>\<C-G>"
+    return "\<esc>/<#\<CR>v/#>\<CR>l\<C-G>"
+endfunction
+
+function BeginSnips()
+    if pumvisible() != 0
+        return ""
+    endif
+    augroup ClangComplete
+        au! CursorMovedI <buffer>
+    augroup end
+
+    " Do we need to launch UpdateSnippets()?
+    let l:line = getline(".")
+    let l:pattern = '<#[^#]*#>'
+    if match(l:line, l:pattern) == -1
+        return ""
+    endif
+    call feedkeys("\<esc>^\<tab>")
+    return ""
+endfunction
+
+" May be used in a mapping to update the quickfix window.
+function g:ClangUpdateQuickFix()
+    call s:DoPeriodicQuickFix()
+    return ""
+endfunction

+ 194 - 0
vim/plugin/command-t.vim

@@ -0,0 +1,194 @@
+" command-t.vim
+" Copyright 2010-2014 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 <SID>CommandTShowBufferFinder()
+command CommandTJump call <SID>CommandTShowJumpFinder()
+command CommandTTag call <SID>CommandTShowTagFinder()
+command -nargs=? -complete=dir CommandT call <SID>CommandTShowFileFinder(<q-args>)
+command CommandTFlush call <SID>CommandTFlush()
+
+if !hasmapto(':CommandT<CR>')
+  silent! nnoremap <unique> <silent> <Leader>t :CommandT<CR>
+endif
+
+if !hasmapto(':CommandTBuffer<CR>')
+  silent! nnoremap <unique> <silent> <Leader>b :CommandTBuffer<CR>
+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 CommandTListMatches()
+  ruby $command_t.list_matches
+endfunction
+
+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 CommandTQuickfix()
+  ruby $command_t.quickfix
+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

+ 1778 - 0
vim/plugin/fugitive.vim

@@ -0,0 +1,1778 @@
+" fugitive.vim - A Git wrapper so awesome, it should be illegal
+" Maintainer:   Tim Pope <vimNOSPAM@tpope.org>
+" Version:      1.1
+" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
+
+if exists('g:loaded_fugitive') || &cp
+  finish
+endif
+let g:loaded_fugitive = 1
+
+if !exists('g:fugitive_git_executable')
+  let g:fugitive_git_executable = 'git'
+endif
+
+" Utility {{{1
+
+function! s:function(name) abort
+  return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
+endfunction
+
+function! s:sub(str,pat,rep) abort
+  return substitute(a:str,'\v\C'.a:pat,a:rep,'')
+endfunction
+
+function! s:gsub(str,pat,rep) abort
+  return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
+endfunction
+
+function! s:shellesc(arg) abort
+  if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
+    return a:arg
+  elseif &shell =~# 'cmd' && a:arg !~# '"'
+    return '"'.a:arg.'"'
+  else
+    return shellescape(a:arg)
+  endif
+endfunction
+
+function! s:fnameescape(file) abort
+  if exists('*fnameescape')
+    return fnameescape(a:file)
+  else
+    return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
+  endif
+endfunction
+
+function! s:throw(string) abort
+  let v:errmsg = 'fugitive: '.a:string
+  throw v:errmsg
+endfunction
+
+function! s:warn(str)
+  echohl WarningMsg
+  echomsg a:str
+  echohl None
+  let v:warningmsg = a:str
+endfunction
+
+function! s:shellslash(path)
+  if exists('+shellslash') && !&shellslash
+    return s:gsub(a:path,'\\','/')
+  else
+    return a:path
+  endif
+endfunction
+
+function! s:add_methods(namespace, method_names) abort
+  for name in a:method_names
+    let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
+  endfor
+endfunction
+
+let s:commands = []
+function! s:command(definition) abort
+  let s:commands += [a:definition]
+endfunction
+
+function! s:define_commands()
+  for command in s:commands
+    exe 'command! -buffer '.command
+  endfor
+endfunction
+
+function! s:compatibility_check()
+  if exists('b:git_dir') && exists('*GitBranchInfoCheckGitDir') && !exists('g:fugitive_did_compatibility_warning')
+    let g:fugitive_did_compatibility_warning = 1
+    call s:warn("See http://github.com/tpope/vim-fugitive/issues#issue/1 for why you should remove git-branch-info.vim")
+  endif
+endfunction
+
+augroup fugitive_utility
+  autocmd!
+  autocmd User Fugitive call s:define_commands()
+  autocmd VimEnter * call s:compatibility_check()
+augroup END
+
+let s:abstract_prototype = {}
+
+" }}}1
+" Initialization {{{1
+
+function! s:ExtractGitDir(path) abort
+  let path = s:shellslash(a:path)
+  if path =~? '^fugitive://.*//'
+    return matchstr(path,'fugitive://\zs.\{-\}\ze//')
+  endif
+  let fn = fnamemodify(path,':s?[\/]$??')
+  let ofn = ""
+  let nfn = fn
+  while fn != ofn
+    if isdirectory(fn . '/.git')
+      return s:sub(simplify(fnamemodify(fn . '/.git',':p')),'\W$','')
+    elseif fn =~ '\.git$' && filereadable(fn . '/HEAD')
+      return s:sub(simplify(fnamemodify(fn,':p')),'\W$','')
+    endif
+    let ofn = fn
+    let fn = fnamemodify(ofn,':h')
+  endwhile
+  return ''
+endfunction
+
+function! s:Detect(path)
+  if exists('b:git_dir') && b:git_dir ==# ''
+    unlet b:git_dir
+  endif
+  if !exists('b:git_dir')
+    let dir = s:ExtractGitDir(a:path)
+    if dir != ''
+      let b:git_dir = dir
+    endif
+  endif
+  if exists('b:git_dir')
+    silent doautocmd User Fugitive
+    cnoremap <expr> <buffer> <C-R><C-G> fugitive#buffer().rev()
+    let buffer = fugitive#buffer()
+    if expand('%:p') =~# '//'
+      call buffer.setvar('&path',s:sub(buffer.getvar('&path'),'^\.%(,|$)',''))
+    endif
+    if b:git_dir !~# ',' && stridx(buffer.getvar('&tags'),b:git_dir.'/tags') == -1
+      call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/tags')
+    endif
+  endif
+endfunction
+
+augroup fugitive
+  autocmd!
+  autocmd BufNewFile,BufReadPost * call s:Detect(expand('<amatch>:p'))
+  autocmd FileType           netrw call s:Detect(expand('<afile>:p'))
+  autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
+  autocmd BufWinLeave * execute getwinvar(+winnr(), 'fugitive_restore')
+augroup END
+
+" }}}1
+" Repository {{{1
+
+let s:repo_prototype = {}
+let s:repos = {}
+
+function! s:repo(...) abort
+  let dir = a:0 ? a:1 : (exists('b:git_dir') && b:git_dir !=# '' ? b:git_dir : s:ExtractGitDir(expand('%:p')))
+  if dir !=# ''
+    if has_key(s:repos,dir)
+      let repo = get(s:repos,dir)
+    else
+      let repo = {'git_dir': dir}
+      let s:repos[dir] = repo
+    endif
+    return extend(extend(repo,s:repo_prototype,'keep'),s:abstract_prototype,'keep')
+  endif
+  call s:throw('not a git repository: '.expand('%:p'))
+endfunction
+
+function! s:repo_dir(...) dict abort
+  return join([self.git_dir]+a:000,'/')
+endfunction
+
+function! s:repo_tree(...) dict abort
+  if !self.bare()
+    let dir = fnamemodify(self.git_dir,':h')
+    return join([dir]+a:000,'/')
+  endif
+  call s:throw('no work tree')
+endfunction
+
+function! s:repo_bare() dict abort
+  return self.dir() !~# '/\.git$'
+endfunction
+
+function! s:repo_translate(spec) dict abort
+  if a:spec ==# '.' || a:spec ==# '/.'
+    return self.bare() ? self.dir() : self.tree()
+  elseif a:spec =~# '^/'
+    return fnamemodify(self.dir(),':h').a:spec
+  elseif a:spec =~# '^:[0-3]:'
+    return 'fugitive://'.self.dir().'//'.a:spec[1].'/'.a:spec[3:-1]
+  elseif a:spec ==# ':'
+    if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(s:repo().dir())] ==# s:repo().dir('') && filereadable($GIT_INDEX_FILE)
+      return fnamemodify($GIT_INDEX_FILE,':p')
+    else
+      return self.dir('index')
+    endif
+  elseif a:spec =~# '^:/'
+    let ref = self.rev_parse(matchstr(a:spec,'.[^:]*'))
+    return 'fugitive://'.self.dir().'//'.ref
+  elseif a:spec =~# '^:'
+    return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
+  elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec))
+    return self.dir(a:spec)
+  elseif filereadable(s:repo().dir('refs/'.a:spec))
+    return self.dir('refs/'.a:spec)
+  elseif filereadable(s:repo().dir('refs/tags/'.a:spec))
+    return self.dir('refs/tags/'.a:spec)
+  elseif filereadable(s:repo().dir('refs/heads/'.a:spec))
+    return self.dir('refs/heads/'.a:spec)
+  elseif filereadable(s:repo().dir('refs/remotes/'.a:spec))
+    return self.dir('refs/remotes/'.a:spec)
+  elseif filereadable(s:repo().dir('refs/remotes/'.a:spec.'/HEAD'))
+    return self.dir('refs/remotes/'.a:spec,'/HEAD')
+  else
+    try
+      let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
+      let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
+      return 'fugitive://'.self.dir().'//'.ref.path
+    catch /^fugitive:/
+      return self.tree(a:spec)
+    endtry
+  endif
+endfunction
+
+call s:add_methods('repo',['dir','tree','bare','translate'])
+
+function! s:repo_git_command(...) dict abort
+  let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
+  return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
+endfunction
+
+function! s:repo_git_chomp(...) dict abort
+  return s:sub(system(call(self.git_command,a:000,self)),'\n$','')
+endfunction
+
+function! s:repo_git_chomp_in_tree(...) dict abort
+  let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+  let dir = getcwd()
+  try
+    execute cd.'`=s:repo().tree()`'
+    return call(s:repo().git_chomp, a:000, s:repo())
+  finally
+    execute cd.'`=dir`'
+  endtry
+endfunction
+
+function! s:repo_rev_parse(rev) dict abort
+  let hash = self.git_chomp('rev-parse','--verify',a:rev)
+  if hash =~ '^\x\{40\}$'
+    return hash
+  endif
+  call s:throw('rev-parse '.a:rev.': '.hash)
+endfunction
+
+call s:add_methods('repo',['git_command','git_chomp','git_chomp_in_tree','rev_parse'])
+
+function! s:repo_dirglob(base) dict abort
+  let base = s:sub(a:base,'^/','')
+  let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*/')),"\n")
+  call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
+  return matches
+endfunction
+
+function! s:repo_superglob(base) dict abort
+  if a:base =~# '^/' || a:base !~# ':'
+    let results = []
+    if a:base !~# '^/'
+      let heads = ["HEAD","ORIG_HEAD","FETCH_HEAD","MERGE_HEAD"]
+      let heads += sort(split(s:repo().git_chomp("rev-parse","--symbolic","--branches","--tags","--remotes"),"\n"))
+      call filter(heads,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
+      let results += heads
+    endif
+    if !self.bare()
+      let base = s:sub(a:base,'^/','')
+      let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*')),"\n")
+      call map(matches,'s:shellslash(v:val)')
+      call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
+      call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
+      let results += matches
+    endif
+    return results
+
+  elseif a:base =~# '^:'
+    let entries = split(self.git_chomp('ls-files','--stage'),"\n")
+    call map(entries,'s:sub(v:val,".*(\\d)\\t(.*)",":\\1:\\2")')
+    if a:base !~# '^:[0-3]\%(:\|$\)'
+      call filter(entries,'v:val[1] == "0"')
+      call map(entries,'v:val[2:-1]')
+    endif
+    call filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
+    return entries
+
+  else
+    let tree = matchstr(a:base,'.*[:/]')
+    let entries = split(self.git_chomp('ls-tree',tree),"\n")
+    call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
+    call map(entries,'tree.s:sub(v:val,".*\t","")')
+    return filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
+  endif
+endfunction
+
+call s:add_methods('repo',['dirglob','superglob'])
+
+function! s:repo_keywordprg() dict abort
+  let args = ' --git-dir='.escape(self.dir(),"\\\"' ").' show'
+  if has('gui_running') && !has('win32')
+    return g:fugitive_git_executable . ' --no-pager' . args
+  else
+    return g:fugitive_git_executable . args
+  endif
+endfunction
+
+call s:add_methods('repo',['keywordprg'])
+
+" }}}1
+" Buffer {{{1
+
+let s:buffer_prototype = {}
+
+function! s:buffer(...) abort
+  let buffer = {'#': bufnr(a:0 ? a:1 : '%')}
+  call extend(extend(buffer,s:buffer_prototype,'keep'),s:abstract_prototype,'keep')
+  if buffer.getvar('git_dir') !=# ''
+    return buffer
+  endif
+  call s:throw('not a git repository: '.expand('%:p'))
+endfunction
+
+function! fugitive#buffer(...) abort
+  return s:buffer(a:0 ? a:1 : '%')
+endfunction
+
+function! s:buffer_getvar(var) dict abort
+  return getbufvar(self['#'],a:var)
+endfunction
+
+function! s:buffer_setvar(var,value) dict abort
+  return setbufvar(self['#'],a:var,a:value)
+endfunction
+
+function! s:buffer_getline(lnum) dict abort
+  return getbufline(self['#'],a:lnum)[0]
+endfunction
+
+function! s:buffer_repo() dict abort
+  return s:repo(self.getvar('git_dir'))
+endfunction
+
+function! s:buffer_type(...) dict abort
+  if self.getvar('fugitive_type') != ''
+    let type = self.getvar('fugitive_type')
+  elseif fnamemodify(self.spec(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
+    let type = 'head'
+  elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == ''
+    let type = 'tree'
+  elseif self.getline(1) =~ '^\d\{6\} \w\{4\} \x\{40\}\>\t'
+    let type = 'tree'
+  elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t'
+    let type = 'index'
+  elseif isdirectory(self.spec())
+    let type = 'directory'
+  elseif self.spec() == ''
+    let type = 'null'
+  elseif filereadable(self.spec())
+    let type = 'file'
+  else
+    let type = ''
+  endif
+  if a:0
+    return !empty(filter(copy(a:000),'v:val ==# type'))
+  else
+    return type
+  endif
+endfunction
+
+function! s:buffer_spec() dict abort
+  let bufname = bufname(self['#'])
+  return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
+endfunction
+
+function! s:buffer_name() dict abort
+  return self.spec()
+endfunction
+
+function! s:buffer_commit() dict abort
+  return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*')
+endfunction
+
+function! s:buffer_path(...) dict abort
+  let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
+  if rev != ''
+    let rev = s:sub(rev,'\w*','')
+  else
+    let rev = self.spec()[strlen(self.repo().tree()) : -1]
+  endif
+  return s:sub(rev,'^/',a:0 ? a:1 : '')
+endfunction
+
+function! s:buffer_rev() dict abort
+  let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
+  if rev =~ '^\x/'
+    return ':'.rev[0].':'.rev[2:-1]
+  elseif rev =~ '.'
+    return s:sub(rev,'/',':')
+  elseif self.spec() =~ '\.git/index$'
+    return ':'
+  elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
+    return self.spec()[strlen(self.repo().dir())+1 : -1]
+  else
+    return self.path()
+  endif
+endfunction
+
+function! s:buffer_sha1() dict abort
+  if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
+    return self.repo().rev_parse(self.rev())
+  else
+    return ''
+  endif
+endfunction
+
+function! s:buffer_expand(rev) dict abort
+  if a:rev =~# '^:[0-3]$'
+    let file = a:rev.self.path(':')
+  elseif a:rev =~# '^-'
+    let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
+  elseif a:rev =~# '^@{'
+    let file = 'HEAD'.a:rev.self.path(':')
+  elseif a:rev =~# '^[~^]'
+    let commit = s:sub(self.commit(),'^\d=$','HEAD')
+    let file = commit.a:rev.self.path(':')
+  else
+    let file = a:rev
+  endif
+  return s:sub(file,'\%$',self.path())
+endfunction
+
+function! s:buffer_containing_commit() dict abort
+  if self.commit() =~# '^\d$'
+    return ':'
+  elseif self.commit() =~# '.'
+    return self.commit()
+  else
+    return 'HEAD'
+  endif
+endfunction
+
+call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit'])
+
+" }}}1
+" Git {{{1
+
+call s:command("-bang -nargs=? -complete=customlist,s:GitComplete Git :execute s:Git(<bang>0,<q-args>)")
+
+function! s:ExecuteInTree(cmd) abort
+  let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+  let dir = getcwd()
+  try
+    execute cd.'`=s:repo().tree()`'
+    execute a:cmd
+  finally
+    execute cd.'`=dir`'
+  endtry
+endfunction
+
+function! s:Git(bang,cmd) abort
+  let git = s:repo().git_command()
+  if has('gui_running') && !has('win32')
+    let git .= ' --no-pager'
+  endif
+  let cmd = matchstr(a:cmd,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
+  call s:ExecuteInTree('!'.git.' '.cmd)
+  call fugitive#reload_status()
+  return matchstr(a:cmd,'\v\C\\@<!%(\\\\)*\|\zs.*')
+endfunction
+
+function! s:GitComplete(A,L,P) abort
+  if !exists('s:exec_path')
+    let s:exec_path = s:sub(system(g:fugitive_git_executable.' --exec-path'),'\n$','')
+  endif
+  let cmds = map(split(glob(s:exec_path.'/git-*'),"\n"),'s:sub(v:val[strlen(s:exec_path)+5 : -1],"\\.exe$","")')
+  if a:L =~ ' [[:alnum:]-]\+ '
+    return s:repo().superglob(a:A)
+  elseif a:A == ''
+    return cmds
+  else
+    return filter(cmds,'v:val[0 : strlen(a:A)-1] ==# a:A')
+  endif
+endfunction
+
+" }}}1
+" Gcd, Glcd {{{1
+
+function! s:DirComplete(A,L,P) abort
+  let matches = s:repo().dirglob(a:A)
+  return matches
+endfunction
+
+call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Gcd  :cd<bang>  `=s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>)`")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :lcd<bang> `=s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>)`")
+
+" }}}1
+" Gstatus {{{1
+
+call s:command("-bar Gstatus :execute s:Status()")
+
+function! s:Status() abort
+  try
+    Gpedit :
+    wincmd P
+    nnoremap <buffer> <silent> q    :<C-U>bdelete<CR>
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+  return ''
+endfunction
+
+function! fugitive#reload_status() abort
+  let mytab = tabpagenr()
+  for tab in [mytab] + range(1,tabpagenr('$'))
+    for winnr in range(1,tabpagewinnr(tab,'$'))
+      if getbufvar(tabpagebuflist(tab)[winnr-1],'fugitive_type') ==# 'index'
+        execute 'tabnext '.tab
+        if winnr != winnr()
+          execute winnr.'wincmd w'
+          let restorewinnr = 1
+        endif
+        try
+          if !&modified
+            call s:BufReadIndex()
+          endif
+        finally
+          if exists('restorewinnr')
+            wincmd p
+          endif
+          execute 'tabnext '.mytab
+        endtry
+      endif
+    endfor
+  endfor
+endfunction
+
+function! s:StageDiff(bang) abort
+  let section = getline(search('^# .*:$','bnW'))
+  let line = getline('.')
+  let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
+  if filename ==# '' && section == '# Changes to be committed:'
+    return 'Git diff --cached'
+  elseif filename ==# ''
+    return 'Git diff'
+  elseif line =~# '^#\trenamed:' && filename =~ ' -> '
+    let [old, new] = split(filename,' -> ')
+    execute 'Gedit '.s:fnameescape(':0:'.new)
+    return 'Gdiff'.a:bang.' HEAD:'.s:fnameescape(old)
+  elseif section == '# Changes to be committed:'
+    execute 'Gedit '.s:fnameescape(':0:'.filename)
+    return 'Gdiff'.a:bang.' -'
+  else
+    execute 'Gedit '.s:fnameescape('/'.filename)
+    return 'Gdiff'.a:bang
+  endif
+endfunction
+
+function! s:StageToggle(lnum1,lnum2) abort
+  try
+    let output = ''
+    for lnum in range(a:lnum1,a:lnum2)
+      let line = getline(lnum)
+      if getline('.') == '# Changes to be committed:'
+        return 'Gcommit'
+      endif
+      let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
+      if filename ==# ''
+        continue
+      endif
+      if !exists('first_filename')
+        let first_filename = filename
+      endif
+      execute lnum
+      let section = getline(search('^# .*:$','bnW'))
+      if line =~# '^#\trenamed:' && filename =~ ' -> '
+        let cmd = ['mv','--'] + reverse(split(filename,' -> '))
+        let filename = cmd[-1]
+      elseif section =~? ' to be '
+        let cmd = ['reset','-q','--',filename]
+      elseif line =~# '^#\tdeleted:'
+        let cmd = ['rm','--',filename]
+      else
+        let cmd = ['add','--',filename]
+      endif
+      let output .= call(s:repo().git_chomp_in_tree,cmd,s:repo())."\n"
+    endfor
+    if exists('first_filename')
+      let jump = first_filename
+      let f = matchstr(getline(a:lnum1-1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
+      if f !=# '' | let jump = f | endif
+      let f = matchstr(getline(a:lnum2+1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
+      if f !=# '' | let jump = f | endif
+      silent! edit!
+      1
+      redraw
+      call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\$','W')
+    endif
+    echo s:sub(s:gsub(output,'\n+','\n'),'\n$','')
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+  return 'checktime'
+endfunction
+
+function! s:StagePatch(lnum1,lnum2) abort
+  let add = []
+  let reset = []
+
+  for lnum in range(a:lnum1,a:lnum2)
+    let line = getline(lnum)
+    if line == '# Changes to be committed:'
+      return 'Git reset --patch'
+    elseif line == '# Changed but not updated:'
+      return 'Git add --patch'
+    endif
+    let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
+    if filename ==# ''
+      continue
+    endif
+    if !exists('first_filename')
+      let first_filename = filename
+    endif
+    execute lnum
+    let section = getline(search('^# .*:$','bnW'))
+    if line =~# '^#\trenamed:' && filename =~ ' -> '
+      let reset += [split(filename,' -> ')[1]]
+    elseif section =~? ' to be '
+      let reset += [filename]
+    elseif line !~# '^#\tdeleted:'
+      let add += [filename]
+    endif
+  endfor
+  try
+    if !empty(add)
+      execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)'))
+    endif
+    if !empty(reset)
+      execute "Git reset --patch -- ".join(map(add,'s:shellesc(v:val)'))
+    endif
+    if exists('first_filename')
+      silent! edit!
+      1
+      redraw
+      call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\$','W')
+    endif
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+  return 'checktime'
+endfunction
+
+" }}}1
+" Gcommit {{{1
+
+call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit(<q-args>)")
+
+function! s:Commit(args) abort
+  let old_type = s:buffer().type()
+  let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+  let dir = getcwd()
+  let msgfile = s:repo().dir('COMMIT_EDITMSG')
+  let outfile = tempname()
+  let errorfile = tempname()
+  try
+    execute cd.'`=s:repo().tree()`'
+    let command = ''
+    if &shell =~# 'cmd'
+      let old_editor = $GIT_EDITOR
+      let $GIT_EDITOR = 'false'
+    elseif &shell !~# 'csh'
+      let command = 'GIT_EDITOR=false '
+    endif
+    let command .= s:repo().git_command('commit').' '.a:args
+    if &shell =~# 'csh'
+      silent execute '!setenv GIT_EDITOR false; ('.command.' > '.outfile.') >& '.errorfile
+    elseif a:args =~# '\%(^\| \)--interactive\>'
+      execute '!'.command.' 2> '.errorfile
+    else
+      silent execute '!'.command.' > '.outfile.' 2> '.errorfile
+    endif
+    if !v:shell_error
+      if filereadable(outfile)
+        for line in readfile(outfile)
+          echo line
+        endfor
+      endif
+      return ''
+    else
+      let errors = readfile(errorfile)
+      let error = get(errors,-2,get(errors,-1,'!'))
+      if error =~# "'false'\\.$"
+        let args = a:args
+        let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[se]|--edit|--interactive)%($| )','')
+        let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
+        let args = s:gsub(args,'%(^| )@<=[%#]%(:\w)*','\=expand(submatch(0))')
+        let args = '-F '.s:shellesc(msgfile).' '.args
+        if args !~# '\%(^\| \)--cleanup\>'
+          let args = '--cleanup=strip '.args
+        endif
+        if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
+          edit `=msgfile`
+        else
+          split `=msgfile`
+        endif
+        if old_type ==# 'index'
+          bdelete #
+        endif
+        let b:fugitive_commit_arguments = args
+        setlocal bufhidden=delete filetype=gitcommit
+        return '1'
+      elseif error ==# '!'
+        return s:Status()
+      else
+        call s:throw(error)
+      endif
+    endif
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  finally
+    if exists('old_editor')
+      let $GIT_EDITOR = old_editor
+    endif
+    call delete(outfile)
+    call delete(errorfile)
+    execute cd.'`=dir`'
+    call fugitive#reload_status()
+  endtry
+endfunction
+
+function! s:CommitComplete(A,L,P) abort
+  if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
+    let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--template=', '--untracked-files', '--verbose']
+    return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
+  else
+    return s:repo().superglob(a:A)
+  endif
+endfunction
+
+function! s:FinishCommit()
+  let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
+  if !empty(args)
+    call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
+    return s:Commit(args)
+  endif
+  return ''
+endfunction
+
+augroup fugitive_commit
+  autocmd!
+  autocmd VimLeavePre,BufDelete *.git/COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE')
+augroup END
+
+" }}}1
+" Ggrep, Glog {{{1
+
+if !exists('g:fugitive_summary_format')
+  let g:fugitive_summary_format = '%s'
+endif
+
+call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep(<bang>0,<q-args>)")
+call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Glog :execute s:Log('grep<bang>',<f-args>)")
+
+function! s:Grep(bang,arg) abort
+  let grepprg = &grepprg
+  let grepformat = &grepformat
+  let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+  let dir = getcwd()
+  try
+    execute cd.'`=s:repo().tree()`'
+    let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n')
+    let &grepformat = '%f:%l:%m'
+    exe 'grep! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
+    let list = getqflist()
+    for entry in list
+      if bufname(entry.bufnr) =~ ':'
+        let entry.filename = s:repo().translate(bufname(entry.bufnr))
+        unlet! entry.bufnr
+      elseif a:arg =~# '\%(^\| \)--cached\>'
+        let entry.filename = s:repo().translate(':0:'.bufname(entry.bufnr))
+        unlet! entry.bufnr
+      endif
+    endfor
+    call setqflist(list,'r')
+    if !a:bang && !empty(list)
+      return 'cfirst'.matchstr(a:arg,'\v\C[''" ]\zs\|.*')
+    else
+      return matchstr(a:arg,'\v\C[''" ]\|\zs.*')
+    endif
+  finally
+    let &grepprg = grepprg
+    let &grepformat = grepformat
+    execute cd.'`=dir`'
+  endtry
+endfunction
+
+function! s:Log(cmd,...)
+  let path = s:buffer().path('/')
+  if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1
+    let path = ''
+  endif
+  let cmd = ['--no-pager', 'log', '--no-color']
+  let cmd += [escape('--pretty=format:fugitive://'.s:repo().dir().'//%H'.path.'::'.g:fugitive_summary_format,'%')]
+  if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"'))
+    if s:buffer().commit() =~# '\x\{40\}'
+      let cmd += [s:buffer().commit()]
+    elseif s:buffer().path() =~# '^\.git/refs/\|^\.git/.*HEAD$'
+      let cmd += [s:buffer().path()[5:-1]]
+    endif
+  end
+  let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().path(),submatch(1))")')
+  if path =~# '/.'
+    let cmd += ['--',path[1:-1]]
+  endif
+  let grepformat = &grepformat
+  let grepprg = &grepprg
+  let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+  let dir = getcwd()
+  try
+    execute cd.'`=s:repo().tree()`'
+    let &grepprg = call(s:repo().git_command,cmd,s:repo())
+    let &grepformat = '%f::%m'
+    exe a:cmd
+  finally
+    let &grepformat = grepformat
+    let &grepprg = grepprg
+    execute cd.'`=dir`'
+  endtry
+endfunction
+
+" }}}1
+" Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread {{{1
+
+function! s:Edit(cmd,...) abort
+  if a:0 && a:1 == ''
+    return ''
+  elseif a:0
+    let file = s:buffer().expand(a:1)
+  elseif s:buffer().commit() ==# '' && s:buffer().path('/') !~# '^/.git\>'
+    let file = s:buffer().path(':')
+  else
+    let file = s:buffer().path('/')
+  endif
+  try
+    let file = s:repo().translate(file)
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+  if a:cmd =~# 'read!$' || a:cmd ==# 'read'
+    if a:cmd =~# '!$'
+      call s:warn(':Gread! is deprecated. Use :Gread')
+    endif
+    return 'silent %delete|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
+  else
+    if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
+      wincmd p
+    endif
+    return a:cmd.' '.s:fnameescape(file)
+  endif
+endfunction
+
+function! s:EditComplete(A,L,P) abort
+  return s:repo().superglob(a:A)
+endfunction
+
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ge       :execute s:Edit('edit<bang>',<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit    :execute s:Edit('edit<bang>',<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit   :execute s:Edit('pedit<bang>',<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit   :execute s:Edit('split<bang>',<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit  :execute s:Edit('vsplit<bang>',<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit<bang>',<f-args>)")
+call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read<bang>',<f-args>)")
+
+" }}}1
+" Gwrite {{{1
+
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwrite :execute s:Write(<bang>0,<f-args>)")
+
+function! s:Write(force,...) abort
+  if exists('b:fugitive_commit_arguments')
+    return 'write|bdelete'
+  elseif expand('%:t') == 'COMMIT_EDITMSG' && $GIT_INDEX_FILE != ''
+    return 'wq'
+  elseif s:buffer().type() == 'index'
+    return 'Gcommit'
+  endif
+  let mytab = tabpagenr()
+  let mybufnr = bufnr('')
+  let path = a:0 ? a:1 : s:buffer().path()
+  if path =~# '^:\d\>'
+    return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path)))
+  endif
+  let always_permitted = (s:buffer().path() ==# path && s:buffer().commit() =~# '^0\=$')
+  if !always_permitted && !a:force && s:repo().git_chomp_in_tree('diff','--name-status','HEAD','--',path) . s:repo().git_chomp_in_tree('ls-files','--others','--',path) !=# ''
+    let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
+    return 'echoerr v:errmsg'
+  endif
+  let file = s:repo().translate(path)
+  let treebufnr = 0
+  for nr in range(1,bufnr('$'))
+    if fnamemodify(bufname(nr),':p') ==# file
+      let treebufnr = nr
+    endif
+  endfor
+
+  if treebufnr > 0 && treebufnr != bufnr('')
+    let temp = tempname()
+    silent execute '%write '.temp
+    for tab in [mytab] + range(1,tabpagenr('$'))
+      for winnr in range(1,tabpagewinnr(tab,'$'))
+        if tabpagebuflist(tab)[winnr-1] == treebufnr
+          execute 'tabnext '.tab
+          if winnr != winnr()
+            execute winnr.'wincmd w'
+            let restorewinnr = 1
+          endif
+          try
+            let lnum = line('.')
+            let last = line('$')
+            silent execute '$read '.temp
+            silent execute '1,'.last.'delete_'
+            silent write!
+            silent execute lnum
+            let did = 1
+          finally
+            if exists('restorewinnr')
+              wincmd p
+            endif
+            execute 'tabnext '.mytab
+          endtry
+        endif
+      endfor
+    endfor
+    if !exists('did')
+      call writefile(readfile(temp,'b'),file,'b')
+    endif
+  else
+    execute 'write! '.s:fnameescape(s:repo().translate(path))
+  endif
+
+  if a:force
+    let error = s:repo().git_chomp_in_tree('add', '--force', file)
+  else
+    let error = s:repo().git_chomp_in_tree('add', file)
+  endif
+  if v:shell_error
+    let v:errmsg = 'fugitive: '.error
+    return 'echoerr v:errmsg'
+  endif
+  if s:buffer().path() ==# path && s:buffer().commit() =~# '^\d$'
+    set nomodified
+  endif
+
+  let one = s:repo().translate(':1:'.path)
+  let two = s:repo().translate(':2:'.path)
+  let three = s:repo().translate(':3:'.path)
+  for nr in range(1,bufnr('$'))
+    if bufloaded(nr) && !getbufvar(nr,'&modified') && (bufname(nr) == one || bufname(nr) == two || bufname(nr) == three)
+      execute nr.'bdelete'
+    endif
+  endfor
+
+  unlet! restorewinnr
+  let zero = s:repo().translate(':0:'.path)
+  for tab in range(1,tabpagenr('$'))
+    for winnr in range(1,tabpagewinnr(tab,'$'))
+      let bufnr = tabpagebuflist(tab)[winnr-1]
+      let bufname = bufname(bufnr)
+      if bufname ==# zero && bufnr != mybufnr
+        execute 'tabnext '.tab
+        if winnr != winnr()
+          execute winnr.'wincmd w'
+          let restorewinnr = 1
+        endif
+        try
+          let lnum = line('.')
+          let last = line('$')
+          silent $read `=file`
+          silent execute '1,'.last.'delete_'
+          silent execute lnum
+          set nomodified
+          diffupdate
+        finally
+          if exists('restorewinnr')
+            wincmd p
+          endif
+          execute 'tabnext '.mytab
+        endtry
+        break
+      endif
+    endfor
+  endfor
+  call fugitive#reload_status()
+  return 'checktime'
+endfunction
+
+" }}}1
+" Gdiff {{{1
+
+call s:command("-bang -bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<bang>0,<f-args>)")
+call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gvdiff :execute s:Diff(0,<f-args>)")
+call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gsdiff :execute s:Diff(1,<f-args>)")
+
+augroup fugitive_diff
+  autocmd!
+  autocmd BufWinLeave * if s:diff_window_count() == 2 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | call s:diff_off_all(getbufvar(+expand('<abuf>'), 'git_dir')) | endif
+  autocmd BufWinEnter * if s:diff_window_count() == 1 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff | endif
+augroup END
+
+function! s:diff_window_count()
+  let c = 0
+  for nr in range(1,winnr('$'))
+    let c += getwinvar(nr,'&diff')
+  endfor
+  return c
+endfunction
+
+function! s:diff_off_all(dir)
+  for nr in range(1,winnr('$'))
+    if getwinvar(nr,'&diff')
+      if nr != winnr()
+        execute nr.'wincmd w'
+        let restorewinnr = 1
+      endif
+      if exists('b:git_dir') && b:git_dir ==# a:dir
+        diffoff
+      endif
+      if exists('restorewinnr')
+        wincmd p
+      endif
+    endif
+  endfor
+endfunction
+
+function! s:buffer_compare_age(commit) dict abort
+  let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
+  let my_score    = get(scores,':'.self.commit(),0)
+  let their_score = get(scores,':'.a:commit,0)
+  if my_score || their_score
+    return my_score < their_score ? -1 : my_score != their_score
+  elseif self.commit() ==# a:commit
+    return 0
+  endif
+  let base = self.repo().git_chomp('merge-base',self.commit(),a:commit)
+  if base ==# self.commit()
+    return -1
+  elseif base ==# a:commit
+    return 1
+  endif
+  let my_time    = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',self.commit())
+  let their_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',a:commit)
+  return my_time < their_time ? -1 : my_time != their_time
+endfunction
+
+call s:add_methods('buffer',['compare_age'])
+
+function! s:Diff(bang,...) abort
+  let split = a:bang ? 'split' : 'vsplit'
+  if exists(':DiffGitCached')
+    return 'DiffGitCached'
+  elseif (!a:0 || a:1 == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
+    execute 'leftabove '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
+    diffthis
+    wincmd p
+    execute 'rightbelow '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
+    diffthis
+    wincmd p
+    diffthis
+    return ''
+  elseif a:0
+    if a:1 ==# ''
+      return ''
+    elseif a:1 ==# '/'
+      let file = s:buffer().path('/')
+    elseif a:1 ==# ':'
+      let file = s:buffer().path(':0:')
+    elseif a:1 =~# '^:/'
+      try
+        let file = s:repo().rev_parse(a:1).s:buffer().path(':')
+      catch /^fugitive:/
+        return 'echoerr v:errmsg'
+      endtry
+    else
+      let file = s:buffer().expand(a:1)
+    endif
+    if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
+      let file = file.s:buffer().path(':')
+    endif
+  else
+    let file = s:buffer().path(s:buffer().commit() == '' ? ':0:' : '/')
+  endif
+  try
+    let spec = s:repo().translate(file)
+    let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
+    if s:buffer().compare_age(commit) < 0
+      execute 'rightbelow '.split.' `=spec`'
+    else
+      execute 'leftabove '.split.' `=spec`'
+    endif
+    diffthis
+    wincmd p
+    diffthis
+    return ''
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+" }}}1
+" Gmove, Gremove {{{1
+
+function! s:Move(force,destination)
+  if a:destination =~# '^/'
+    let destination = a:destination[1:-1]
+  else
+    let destination = fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p')
+    if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
+      let destination = destination[strlen(s:repo().tree('')):-1]
+    endif
+  endif
+  let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
+  if v:shell_error
+    let v:errmsg = 'fugitive: '.message
+    return 'echoerr v:errmsg'
+  endif
+  let destination = s:repo().tree(destination)
+  if isdirectory(destination)
+    let destination = fnamemodify(s:sub(destination,'/$','').'/'.expand('%:t'),':.')
+  endif
+  call fugitive#reload_status()
+  if s:buffer().commit() == ''
+    return 'saveas! '.s:fnameescape(destination)
+  else
+    return 'file '.s:fnameescape(s:repo().translate(':0:'.destination)
+  endif
+endfunction
+
+function! s:MoveComplete(A,L,P)
+  if a:A =~ '^/'
+    return s:repo().superglob(a:A)
+  else
+    let matches = split(glob(a:A.'*'),"\n")
+    call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
+    return matches
+  endif
+endfunction
+
+function! s:Remove(force)
+  if s:buffer().commit() ==# ''
+    let cmd = ['rm']
+  elseif s:buffer().commit() ==# '0'
+    let cmd = ['rm','--cached']
+  else
+    let v:errmsg = 'fugitive: rm not supported here'
+    return 'echoerr v:errmsg'
+  endif
+  if a:force
+    let cmd += ['--force']
+  endif
+  let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().path()],s:repo())
+  if v:shell_error
+    let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
+    return 'echoerr '.string(v:errmsg)
+  else
+    call fugitive#reload_status()
+    return 'bdelete'.(a:force ? '!' : '')
+  endif
+endfunction
+
+augroup fugitive_remove
+  autocmd!
+  autocmd User Fugitive if s:buffer().commit() =~# '^0\=$' |
+        \ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:MoveComplete Gmove :execute s:Move(<bang>0,<q-args>)" |
+        \ exe "command! -buffer -bar -bang Gremove :execute s:Remove(<bang>0)" |
+        \ endif
+augroup END
+
+" }}}1
+" Gblame {{{1
+
+augroup fugitive_blame
+  autocmd!
+  autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame
+  autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif
+  autocmd Syntax fugitiveblame call s:BlameSyntax()
+  autocmd User Fugitive if s:buffer().type('file', 'blob') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,[<f-args>])" | endif
+augroup END
+
+function! s:Blame(bang,line1,line2,count,args) abort
+  try
+    if s:buffer().path() == ''
+      call s:throw('file or blob required')
+    endif
+    if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltwfs]\\|[MC]\\d*\\)\\+\\)$"') != []
+      call s:throw('unsupported option')
+    endif
+    call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")')
+    let git_dir = s:repo().dir()
+    let cmd = ['--no-pager', 'blame', '--show-number'] + a:args
+    if s:buffer().commit() =~# '\D\|..'
+      let cmd += [s:buffer().commit()]
+    else
+      let cmd += ['--contents', '-']
+    endif
+    let basecmd = call(s:repo().git_command,cmd+['--',s:buffer().path()],s:repo())
+    try
+      let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+      if !s:repo().bare()
+        let dir = getcwd()
+        execute cd.'`=s:repo().tree()`'
+      endif
+      if a:count
+        execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g')
+      else
+        let error = tempname()
+        let temp = error.'.fugitiveblame'
+        if &shell =~# 'csh'
+          silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
+        else
+          silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
+        endif
+        if exists('l:dir')
+          execute cd.'`=dir`'
+          unlet dir
+        endif
+        if v:shell_error
+          call s:throw(join(readfile(error),"\n"))
+        endif
+        let bufnr = bufnr('')
+        let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
+        if &l:wrap
+          let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)'
+        endif
+        if &l:foldenable
+          let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)'
+        endif
+        let winnr = winnr()
+        windo set noscrollbind
+        exe winnr.'wincmd w'
+        setlocal scrollbind nowrap nofoldenable
+        let top = line('w0') + &scrolloff
+        let current = line('.')
+        exe 'leftabove vsplit '.temp
+        let b:git_dir = git_dir
+        let b:fugitive_type = 'blame'
+        let b:fugitive_blamed_bufnr = bufnr
+        let w:fugitive_restore = restore
+        let b:fugitive_blame_arguments = join(a:args,' ')
+        call s:Detect(expand('%:p'))
+        execute top
+        normal! zt
+        execute current
+        execute "vertical resize ".(match(getline('.'),'\s\+\d\+)')+1)
+        setlocal nomodified nomodifiable bufhidden=delete nonumber scrollbind nowrap foldcolumn=0 nofoldenable filetype=fugitiveblame
+        nnoremap <buffer> <silent> q    :<C-U>bdelete<CR>
+        nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>BlameJump('')<CR>
+        nnoremap <buffer> <silent> P    :<C-U>exe <SID>BlameJump('^'.v:count1)<CR>
+        nnoremap <buffer> <silent> ~    :<C-U>exe <SID>BlameJump('~'.v:count1)<CR>
+        nnoremap <buffer> <silent> o    :<C-U>exe <SID>Edit((&splitbelow ? "botright" : "topleft")." split", matchstr(getline('.'),'\x\+'))<CR>
+        nnoremap <buffer> <silent> O    :<C-U>exe <SID>Edit("tabedit", matchstr(getline('.'),'\x\+'))<CR>
+        syncbind
+      endif
+    finally
+      if exists('l:dir')
+        execute cd.'`=dir`'
+      endif
+    endtry
+    return ''
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+function! s:BlameJump(suffix) abort
+  let commit = matchstr(getline('.'),'^\^\=\zs\x\+')
+  if commit =~# '^0\+$'
+    let commit = ':0'
+  endif
+  let lnum = matchstr(getline('.'),'\d\+\ze\s\+[([:digit:]]')
+  let path = matchstr(getline('.'),'^\^\=\zs\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
+  if path ==# ''
+    let path = s:buffer(b:fugitive_blamed_bufnr).path()
+  endif
+  let args = b:fugitive_blame_arguments
+  let offset = line('.') - line('w0')
+  let bufnr = bufnr('%')
+  let winnr = bufwinnr(b:fugitive_blamed_bufnr)
+  if winnr > 0
+    exe winnr.'wincmd w'
+  endif
+  execute s:Edit('edit',commit.a:suffix.':'.path)
+  if winnr > 0
+    exe bufnr.'bdelete'
+  endif
+  execute 'Gblame '.args
+  execute lnum
+  let delta = line('.') - line('w0') - offset
+  if delta > 0
+    execute 'norm! 'delta."\<C-E>"
+  elseif delta < 0
+    execute 'norm! '(-delta)."\<C-Y>"
+  endif
+  syncbind
+  return ''
+endfunction
+
+function! s:BlameSyntax() abort
+  let b:current_syntax = 'fugitiveblame'
+  syn match FugitiveblameBoundary "^\^"
+  syn match FugitiveblameBlank                      "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
+  syn match FugitiveblameHash       "\%(^\^\=\)\@<=\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
+  syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
+  syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline
+  syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
+  syn match FugitiveblameLineNumber         " \@<=\d\+)\@=" contained containedin=FugitiveblameAnnotation
+  syn match FugitiveblameOriginalFile       " \%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite
+  syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite
+  syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite
+  syn match FugitiveblameShort              "\d\+)" contained contains=FugitiveblameLineNumber
+  syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation
+  hi def link FugitiveblameBoundary           Keyword
+  hi def link FugitiveblameHash               Identifier
+  hi def link FugitiveblameUncommitted        Function
+  hi def link FugitiveblameTime               PreProc
+  hi def link FugitiveblameLineNumber         Number
+  hi def link FugitiveblameOriginalFile       String
+  hi def link FugitiveblameOriginalLineNumber Float
+  hi def link FugitiveblameShort              FugitiveblameDelimiter
+  hi def link FugitiveblameDelimiter          Delimiter
+  hi def link FugitiveblameNotCommittedYet    Comment
+endfunction
+
+" }}}1
+" File access {{{1
+
+function! s:ReplaceCmd(cmd,...) abort
+  let fn = bufname('')
+  let tmp = tempname()
+  let aw = &autowrite
+  let prefix = ''
+  try
+    if a:0 && a:1 != ''
+      if &shell =~# 'cmd'
+        let old_index = $GIT_INDEX_FILE
+        let $GIT_INDEX_FILE = a:1
+      elseif &shell =~# 'csh'
+        let prefix = 'setenv GIT_INDEX_FILE '.s:shellesc(a:1).'; '
+      else
+        let prefix = 'GIT_INDEX_FILE='.s:shellesc(a:1).' '
+      endif
+    endif
+    set noautowrite
+    silent exe '!'.escape(prefix.a:cmd,'%#').' > '.tmp
+  finally
+    let &autowrite = aw
+    if exists('old_index')
+      let $GIT_INDEX_FILE = old_index
+    endif
+  endtry
+  silent exe 'keepalt file '.tmp
+  silent edit!
+  silent exe 'keepalt file '.s:fnameescape(fn)
+  call delete(tmp)
+  silent exe 'doau BufReadPost '.s:fnameescape(fn)
+endfunction
+
+function! s:BufReadIndex()
+  if !exists('b:fugitive_display_format')
+    let b:fugitive_display_format = filereadable(expand('%').'.lock')
+  endif
+  let b:fugitive_display_format = b:fugitive_display_format % 2
+  let b:fugitive_type = 'index'
+  try
+    let b:git_dir = s:repo().dir()
+    setlocal noro ma
+    if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p')
+      let index = ''
+    else
+      let index = expand('%:p')
+    endif
+    if b:fugitive_display_format
+      call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
+      set ft=git nospell
+    else
+      let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+      let dir = getcwd()
+      try
+        execute cd.'`=s:repo().tree()`'
+        call s:ReplaceCmd(s:repo().git_command('status'),index)
+      finally
+        execute cd.'`=dir`'
+      endtry
+      set ft=gitcommit
+    endif
+    setlocal ro noma nomod nomodeline bufhidden=delete
+    nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
+    nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
+    nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff('')<CR>
+    nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff('')<CR>
+    nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('!')<CR>
+    nnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
+    xnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line("'<"),line("'>"))<CR>
+    nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
+    xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
+    nnoremap <buffer> <silent> <C-N> :call search('^#\t.*','W')<Bar>.<CR>
+    nnoremap <buffer> <silent> <C-P> :call search('^#\t.*','Wbe')<Bar>.<CR>
+    call s:JumpInit()
+    nunmap   <buffer>          P
+    nunmap   <buffer>          ~
+    nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+function! s:FileRead()
+  try
+    let repo = s:repo(s:ExtractGitDir(expand('<amatch>')))
+    let path = s:sub(s:sub(matchstr(expand('<amatch>'),'fugitive://.\{-\}//\zs.*'),'/',':'),'^\d:',':&')
+    let hash = repo.rev_parse(path)
+    if path =~ '^:'
+      let type = 'blob'
+    else
+      let type = repo.git_chomp('cat-file','-t',hash)
+    endif
+    " TODO: use count, if possible
+    return "read !".escape(repo.git_command('cat-file',type,hash),'%#\')
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+function! s:BufReadIndexFile()
+  try
+    let b:fugitive_type = 'blob'
+    let b:git_dir = s:repo().dir()
+    call s:ReplaceCmd(s:repo().git_command('cat-file','blob',s:buffer().sha1()))
+    return ''
+  catch /^fugitive: rev-parse/
+    silent exe 'doau BufNewFile '.s:fnameescape(bufname(''))
+    return ''
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+function! s:BufWriteIndexFile()
+  let tmp = tempname()
+  try
+    let path = matchstr(expand('<amatch>'),'//\d/\zs.*')
+    let stage = matchstr(expand('<amatch>'),'//\zs\d')
+    silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp
+    let sha1 = readfile(tmp)[0]
+    let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+')
+    if old_mode == ''
+      let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644'
+    endif
+    let info = old_mode.' '.sha1.' '.stage."\t".path
+    call writefile([info],tmp)
+    if has('win32')
+      let error = system('type '.tmp.'|'.s:repo().git_command('update-index','--index-info'))
+    else
+      let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
+    endif
+    if v:shell_error == 0
+      setlocal nomodified
+      silent execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p'))
+      call fugitive#reload_status()
+      return ''
+    else
+      return 'echoerr '.string('fugitive: '.error)
+    endif
+  finally
+    call delete(tmp)
+  endtry
+endfunction
+
+function! s:BufReadObject()
+  try
+    setlocal noro ma
+    let b:git_dir = s:repo().dir()
+    let hash = s:buffer().sha1()
+    if !exists("b:fugitive_type")
+      let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash)
+    endif
+    if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
+      return "echoerr 'fugitive: unrecognized git type'"
+    endif
+    let firstline = getline('.')
+    if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
+      let b:fugitive_display_format = +getbufvar('#','fugitive_display_format')
+    endif
+
+    let pos = getpos('.')
+    silent %delete
+    setlocal endofline
+
+    if b:fugitive_type == 'tree'
+      let b:fugitive_display_format = b:fugitive_display_format % 2
+      if b:fugitive_display_format
+        call s:ReplaceCmd(s:repo().git_command('ls-tree',hash))
+      else
+        call s:ReplaceCmd(s:repo().git_command('show',hash))
+      endif
+    elseif b:fugitive_type == 'tag'
+      let b:fugitive_display_format = b:fugitive_display_format % 2
+      if b:fugitive_display_format
+        call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
+      else
+        call s:ReplaceCmd(s:repo().git_command('cat-file','-p',hash))
+      endif
+    elseif b:fugitive_type == 'commit'
+      let b:fugitive_display_format = b:fugitive_display_format % 2
+      if b:fugitive_display_format
+        call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
+      else
+        call s:ReplaceCmd(s:repo().git_command('show','--pretty=format:tree %T%nparent %P%nauthor %an <%ae> %ad%ncommitter %cn <%ce> %cd%nencoding %e%n%n%s%n%n%b',hash))
+        call search('^parent ')
+        if getline('.') ==# 'parent '
+          silent delete_
+        else
+          silent s/\%(^parent\)\@<! /\rparent /ge
+        endif
+        if search('^encoding \%(<unknown>\)\=$','W',line('.')+3)
+          silent delete_
+        end
+        1
+      endif
+    elseif b:fugitive_type ==# 'blob'
+      call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
+    endif
+    call setpos('.',pos)
+    setlocal ro noma nomod nomodeline
+    if b:fugitive_type !=# 'blob'
+      set filetype=git
+      nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe <SID>BufReadObject()<CR>
+      nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe <SID>BufReadObject()<CR>
+    else
+      call s:JumpInit()
+    endif
+
+    return ''
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+augroup fugitive_files
+  autocmd!
+  autocmd BufReadCmd  *.git/index                      exe s:BufReadIndex()
+  autocmd BufReadCmd  *.git/*index*.lock               exe s:BufReadIndex()
+  autocmd FileReadCmd fugitive://**//[0-3]/**          exe s:FileRead()
+  autocmd BufReadCmd  fugitive://**//[0-3]/**          exe s:BufReadIndexFile()
+  autocmd BufWriteCmd fugitive://**//[0-3]/**          exe s:BufWriteIndexFile()
+  autocmd BufReadCmd  fugitive://**//[0-9a-f][0-9a-f]* exe s:BufReadObject()
+  autocmd FileReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:FileRead()
+  autocmd FileType git       call s:JumpInit()
+augroup END
+
+" }}}1
+" Go to file {{{1
+
+function! s:JumpInit() abort
+  nnoremap <buffer> <silent> <CR>    :<C-U>exe <SID>GF("edit")<CR>
+  if !&modifiable
+    nnoremap <buffer> <silent> o     :<C-U>exe <SID>GF("split")<CR>
+    nnoremap <buffer> <silent> O     :<C-U>exe <SID>GF("tabedit")<CR>
+    nnoremap <buffer> <silent> P     :<C-U>exe <SID>Edit('edit',<SID>buffer().commit().'^'.v:count1.<SID>buffer().path(':'))<CR>
+    nnoremap <buffer> <silent> ~     :<C-U>exe <SID>Edit('edit',<SID>buffer().commit().'~'.v:count1.<SID>buffer().path(':'))<CR>
+    nnoremap <buffer> <silent> C     :<C-U>exe <SID>Edit('edit',<SID>buffer().containing_commit())<CR>
+    nnoremap <buffer> <silent> cc    :<C-U>exe <SID>Edit('edit',<SID>buffer().containing_commit())<CR>
+    nnoremap <buffer> <silent> co    :<C-U>exe <SID>Edit('split',<SID>buffer().containing_commit())<CR>
+    nnoremap <buffer> <silent> cO    :<C-U>exe <SID>Edit('tabedit',<SID>buffer().containing_commit())<CR>
+    nnoremap <buffer> <silent> cp    :<C-U>exe <SID>Edit('pedit',<SID>buffer().containing_commit())<CR>
+  endif
+endfunction
+
+function! s:GF(mode) abort
+  try
+    let buffer = s:buffer()
+    let myhash = buffer.sha1()
+
+    if buffer.type('tree')
+      let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
+      if showtree && line('.') == 1
+        return ""
+      elseif showtree && line('.') > 2
+        return s:Edit(a:mode,buffer.commit().':'.(buffer.path() == '' ? '' : buffer.path().'/').s:sub(getline('.'),'/$',''))
+      elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
+        return s:Edit(a:mode,buffer.commit().':'.(buffer.path() == '' ? '' : buffer.path().'/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
+      endif
+
+    elseif buffer.type('blob')
+      let ref = expand("<cfile>")
+      try
+        let sha1 = buffer.repo().rev_parse(ref)
+      catch /^fugitive:/
+      endtry
+      if exists('sha1')
+        return s:Edit(a:mode,ref)
+      endif
+
+    else
+
+      " Index
+      if getline('.') =~# '^\d\{6\} \x\{40\} \d\t'
+        let ref = matchstr(getline('.'),'\x\{40\}')
+        let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':')
+        return s:Edit(a:mode,file)
+
+      elseif getline('.') =~# '^#\trenamed:.* -> '
+        let file = '/'.matchstr(getline('.'),' -> \zs.*')
+        return s:Edit(a:mode,file)
+      elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
+        let file = '/'.matchstr(getline('.'),': *\zs.*')
+        return s:Edit(a:mode,file)
+      elseif getline('.') =~# '^#\t.'
+        let file = '/'.matchstr(getline('.'),'#\t\zs.*')
+        return s:Edit(a:mode,file)
+      elseif getline('.') =~# ': needs merge$'
+        let file = '/'.matchstr(getline('.'),'.*\ze: needs merge$')
+        return s:Edit(a:mode,file).'|Gdiff'
+
+      elseif getline('.') ==# '# Not currently on any branch.'
+        return s:Edit(a:mode,'HEAD')
+      elseif getline('.') =~# '^# On branch '
+        let file = 'refs/heads/'.getline('.')[12:]
+        return s:Edit(a:mode,file)
+      elseif getline('.') =~# "^# Your branch .*'"
+        let file = matchstr(getline('.'),"'\\zs\\S\\+\\ze'")
+        return s:Edit(a:mode,file)
+      endif
+
+      let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
+
+      if getline('.') =~# '^ref: '
+        let ref = strpart(getline('.'),5)
+
+      elseif getline('.') =~# '^parent \x\{40\}\>'
+        let ref = matchstr(getline('.'),'\x\{40\}')
+        let line = line('.')
+        let parent = 0
+        while getline(line) =~# '^parent '
+          let parent += 1
+          let line -= 1
+        endwhile
+        return s:Edit(a:mode,ref)
+
+      elseif getline('.') =~ '^tree \x\{40\}$'
+        let ref = matchstr(getline('.'),'\x\{40\}')
+        if s:repo().rev_parse(myhash.':') == ref
+          let ref = myhash.':'
+        endif
+        return s:Edit(a:mode,ref)
+
+      elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
+        let ref = matchstr(getline('.'),'\x\{40\}')
+        let type = matchstr(getline(line('.')+1),'type \zs.*')
+
+      elseif getline('.') =~# '^\l\{3,8\} '.myhash.'$'
+        return ''
+
+      elseif getline('.') =~# '^\l\{3,8\} \x\{40\}\>'
+        let ref = matchstr(getline('.'),'\x\{40\}')
+        echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
+
+      elseif getline('.') =~# '^[+-]\{3\} [ab/]'
+        let ref = getline('.')[4:]
+
+      elseif getline('.') =~# '^rename from '
+        let ref = 'a/'.getline('.')[12:]
+      elseif getline('.') =~# '^rename to '
+        let ref = 'b/'.getline('.')[10:]
+
+      elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
+        let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
+        let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
+        let dcmd = 'Gdiff'
+
+      elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
+        let line = getline(line('.')-1)
+        let dref = matchstr(line,'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
+        let ref = matchstr(line,'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
+        let dcmd = 'Gdiff!'
+
+      elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
+        let ref = getline('.')
+      else
+        let ref = ''
+      endif
+
+      if myhash ==# ''
+        let ref = s:sub(ref,'^a/','HEAD:')
+        let ref = s:sub(ref,'^b/',':0:')
+        if exists('dref')
+          let dref = s:sub(dref,'^a/','HEAD:')
+        endif
+      else
+        let ref = s:sub(ref,'^a/',myhash.'^:')
+        let ref = s:sub(ref,'^b/',myhash.':')
+        if exists('dref')
+          let dref = s:sub(dref,'^a/',myhash.'^:')
+        endif
+      endif
+
+      if ref ==# '/dev/null'
+        " Empty blob
+        let ref = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
+      endif
+
+      if exists('dref')
+        return s:Edit(a:mode,ref) . '|'.dcmd.' '.s:fnameescape(dref)
+      elseif ref != ""
+        return s:Edit(a:mode,ref)
+      endif
+
+    endif
+    return ''
+  catch /^fugitive:/
+    return 'echoerr v:errmsg'
+  endtry
+endfunction
+
+" }}}1
+" Statusline {{{1
+
+function! s:repo_head_ref() dict abort
+  return readfile(s:repo().dir('HEAD'))[0]
+endfunction
+
+call s:add_methods('repo',['head_ref'])
+
+function! fugitive#statusline(...)
+  if !exists('b:git_dir')
+    return ''
+  endif
+  let status = ''
+  if s:buffer().commit() != ''
+    let status .= ':' . s:buffer().commit()[0:7]
+  endif
+  let head = s:repo().head_ref()
+  if head =~# '^ref: '
+    let status .= s:sub(head,'^ref: %(refs/%(heads/|remotes/|tags/)=)=','(').')'
+  elseif head =~# '^\x\{40\}$'
+    let status .= '('.head[0:7].')'
+  endif
+  if &statusline =~# '%[MRHWY]' && &statusline !~# '%[mrhwy]'
+    return ',GIT'.status
+  else
+    return '[Git'.status.']'
+  endif
+endfunction
+
+function! s:repo_config(conf) dict abort
+  return matchstr(system(s:repo().git_command('config').' '.a:conf),"[^\r\n]*")
+endfun
+
+function! s:repo_user() dict abort
+  let username = s:repo().config('user.name')
+  let useremail = s:repo().config('user.email')
+  return username.' <'.useremail.'>'
+endfun
+
+call s:add_methods('repo',['config', 'user'])
+
+" }}}1
+
+" vim:set ft=vim ts=8 sw=2 sts=2:

+ 313 - 0
vim/plugin/guicolorscheme.vim

@@ -0,0 +1,313 @@
+" guicolorscheme.vim: Convert GUI only color schems
+"
+" Maintainer:	 Aaron Griffin <aaron@archlinux.org>
+" Last Modified: Mon Feb 26 22:52:34 UTC 2007
+" Version:       1.2
+" URL:           http://www.vim.org/script.php?script_id=39
+"
+" Convert a GUI-only colorscheme to support 88 and 256 color terminals
+" This should also work on the GUI, so using it 100% of the time, assuming
+" you always have a non 8/16 color terminal should work fine
+
+" conversion functions {{{
+" canibalized from desert256.vim
+
+function! s:greynum(x) "{{{
+    if &t_Co == 88
+        if a:x < 23
+            return 0
+        elseif a:x < 69
+            return 1
+        elseif a:x < 103
+            return 2
+        elseif a:x < 127
+            return 3
+        elseif a:x < 150
+            return 4
+        elseif a:x < 173
+            return 5
+        elseif a:x < 196
+            return 6
+        elseif a:x < 219
+            return 7
+        elseif a:x < 243
+            return 8
+        else
+            return 9
+        endif
+    else
+        if a:x < 14
+            return 0
+        else
+            let l:n = (a:x - 8) / 10
+            let l:m = (a:x - 8) % 10
+            if l:m < 5
+                return l:n
+            else
+                return l:n + 1
+            endif
+        endif
+    endif
+endfunction "}}}
+function! s:greylvl(n) "{{{
+    if &t_Co == 88
+        if a:n == 0
+            return 0
+        elseif a:n == 1
+            return 46
+        elseif a:n == 2
+            return 92
+        elseif a:n == 3
+            return 115
+        elseif a:n == 4
+            return 139
+        elseif a:n == 5
+            return 162
+        elseif a:n == 6
+            return 185
+        elseif a:n == 7
+            return 208
+        elseif a:n == 8
+            return 231
+        else
+            return 255
+        endif
+    else
+        if a:n == 0
+            return 0
+        else
+            return 8 + (a:n * 10)
+        endif
+    endif
+endfunction "}}}
+function! s:grey(n) "{{{
+    if &t_Co == 88
+        if a:n == 0
+            return 16
+        elseif a:n == 9
+            return 79
+        else
+            return 79 + a:n
+        endif
+    else
+        if a:n == 0
+            return 16
+        elseif a:n == 25
+            return 231
+        else
+            return 231 + a:n
+        endif
+    endif
+endfunction "}}}
+
+function! s:rgbnum(x) "{{{
+    if &t_Co == 88
+        if a:x < 69
+            return 0
+        elseif a:x < 172
+            return 1
+        elseif a:x < 230
+            return 2
+        else
+            return 3
+        endif
+    else
+        if a:x < 75
+            return 0
+        else
+            let l:n = (a:x - 55) / 40
+            let l:m = (a:x - 55) % 40
+            if l:m < 20
+                return l:n
+            else
+                return l:n + 1
+            endif
+        endif
+    endif
+endfunction "}}}
+function! s:rgblvl(n) "{{{
+    if &t_Co == 88
+        if a:n == 0
+            return 0
+        elseif a:n == 1
+            return 139
+        elseif a:n == 2
+            return 205
+        else
+            return 255
+        endif
+    else
+        if a:n == 0
+            return 0
+        else
+            return 55 + (a:n * 40)
+        endif
+    endif
+endfunction "}}}
+function! s:rgb(r, g, b) "{{{
+    if &t_Co == 88
+        return 16 + (a:r * 16) + (a:g * 4) + a:b
+    else
+        return 16 + (a:r * 36) + (a:g * 6) + a:b
+    endif
+endfunction "}}}
+
+function! s:color(r, g, b) "{{{
+    " get the closest grey
+    let l:gx = s:greynum(a:r)
+    let l:gy = s:greynum(a:g)
+    let l:gz = s:greynum(a:b)
+
+    " get the closest color
+    let l:x = s:rgbnum(a:r)
+    let l:y = s:rgbnum(a:g)
+    let l:z = s:rgbnum(a:b)
+
+    let l:level = (a:r * a:r) + (a:g * a:g) + (a:b * a:b)
+    if l:gx == l:gy && l:gy == l:gz
+        " there are two possibilities
+        let l:dgr = s:greylvl(l:gx)
+        let l:dgg = s:greylvl(l:gy)
+        let l:dgb = s:greylvl(l:gz)
+        let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb) - l:level
+
+        let l:dr = s:rgblvl(l:gx)
+        let l:dg = s:rgblvl(l:gy)
+        let l:db = s:rgblvl(l:gz)
+        let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db) - l:level
+
+        if l:dgrey < l:drgb
+            " use the grey
+            return s:grey(l:gx)
+        else
+            " use the color
+            return s:rgb(l:x, l:y, l:z)
+        endif
+    else
+        " only one possibility
+        return s:rgb(l:x, l:y, l:z)
+    endif
+endfunction "}}}
+function! s:cindex(rgb) "{{{
+    "convert RRGGBB to a terminal (numeric) index
+    let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
+    let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
+    let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
+
+    return s:color(l:r, l:g, l:b)
+endfunction "}}}
+
+function! s:HL(group, fg, bg, attr) "{{{
+    "The main highlight (HL) function
+    exec "hi clear " . a:group
+    if a:fg != ""
+        exec "hi " . a:group . " guifg=#" . a:fg . " ctermfg=" . s:cindex(a:fg)
+    endif
+    if a:bg != ""
+        exec "hi " . a:group . " guibg=#" . a:bg . " ctermbg=" . s:cindex(a:bg)
+    endif
+    if a:attr != ""
+        exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr
+    endif
+endfunction "}}}
+
+"}}}
+
+" Completion Helpers {{{
+function! s:Colorscheme_Complete(A,L,P)
+    let l:files = split(globpath(&runtimepath, "colors/" . a:A . "*"), "\n")
+    let l:retlist = []
+    for file in l:files
+        let l:basename = substitute(file, ".*/", "", "")
+        let l:basename = substitute(l:basename, "\.vim", "", "")
+        call add(l:retlist, l:basename)
+    endfor
+    return l:retlist
+endfunction
+
+function! s:GetColorschemeFile(fname)
+    let l:files = split(globpath(&runtimepath, "colors/" . a:fname . ".vim"), "\n")
+    if len(l:files) == 0
+        echoerr "Colorscheme ".a:fname." not found"
+        return ""
+    else
+        return l:files[0]
+    endif
+endfunction
+
+command! -complete=customlist,s:Colorscheme_Complete -nargs=1 GuiColorScheme :call s:GuiColorScheme("<args>")
+" }}}
+
+function! s:GuiColorScheme(fname)
+    let l:file = s:GetColorschemeFile(a:fname)
+    if l:file == ""
+        return 1
+    endif
+
+    if has("gui_running")
+        exec "colorscheme " . l:file
+        return 0
+    endif
+
+    for line in readfile(l:file)
+        if line =~ '\s*hi'
+            let l:name = ""
+            let l:fg = ""
+            let l:bg = ""
+            let l:attr = ""
+
+            " get highlight name
+            let l:start = match(line, "hi")
+            let l:end = match(line, "[ \t]", l:start)
+            let l:start = l:end +1
+            let l:end = match(line, "[ \t]", l:start)
+            let l:name = strpart(line, l:start, l:end - l:start)
+
+            " strip foreground color
+            let l:start = match(line, "guifg=")
+            if l:start != -1
+                let l:start = l:start + 6 "strlen(guifg=)
+                let l:end = match(line, "[ \t]", l:start)
+                if l:end == -1
+                    let l:fg = strpart(line, l:start)
+                else
+                    let l:fg = strpart(line, l:start, l:end - l:start)
+                endif
+                if strpart(l:fg, 0, 1) == "#"
+                    let l:fg = strpart(l:fg, 1)
+                endif
+            endif
+
+            " strip background color
+            let l:start = match(line, "guibg=")
+            if l:start != -1
+                let l:start = l:start + 6 "strlen(guibg=)
+                let l:end = match(line, "[ \t]", l:start)
+                if l:end == -1
+                    let l:bg = strpart(line, l:start)
+                else
+                    let l:bg = strpart(line, l:start, l:end - l:start)
+                endif
+                if strpart(l:bg, 0, 1) == "#"
+                    let l:bg = strpart(l:bg, 1)
+                endif
+            endif
+
+            " strip attribute
+            let l:start = match(line, "gui=")
+            if l:start != -1
+                let l:start = l:start + 4 "strlen(gui=)
+                let l:end = match(line, "[ \t]", l:start)
+                if l:end == -1
+                    let l:attr = strpart(line, l:start)
+                else
+                    let l:attr = strpart(line, l:start, l:end - l:start)
+                endif
+            endif
+
+            call s:HL(l:name, l:fg, l:bg, l:attr)
+        endif
+    endfor
+endfunction
+
+" vim:ft=vim:fdl=0:fdm=marker:ts=4:sw=4

+ 271 - 0
vim/plugin/snipMate.vim

@@ -0,0 +1,271 @@
+" File:          snipMate.vim
+" Author:        Michael Sanders
+" Version:       0.84
+" Description:   snipMate.vim implements some of TextMate's snippets features in
+"                Vim. A snippet is a piece of often-typed text that you can
+"                insert into your document using a trigger word followed by a "<tab>".
+"
+"                For more help see snipMate.txt; you can do this by using:
+"                :helptags ~/.vim/doc
+"                :h snipMate.txt
+
+if exists('loaded_snips') || &cp || version < 700
+	finish
+endif
+let loaded_snips = 1
+if !exists('snips_author') | let snips_author = 'Me' | endif
+
+au BufRead,BufNewFile *.snippets\= set ft=snippet
+au FileType snippet setl noet fdm=indent
+
+let s:snippets = {} | let s:multi_snips = {}
+
+if !exists('snippets_dir')
+	let snippets_dir = substitute(globpath(&rtp, 'snippets/'), "\n", ',', 'g')
+endif
+
+fun! MakeSnip(scope, trigger, content, ...)
+	let multisnip = a:0 && a:1 != ''
+	let var = multisnip ? 's:multi_snips' : 's:snippets'
+	if !has_key({var}, a:scope) | let {var}[a:scope] = {} | endif
+	if !has_key({var}[a:scope], a:trigger)
+		let {var}[a:scope][a:trigger] = multisnip ? [[a:1, a:content]] : a:content
+	elseif multisnip | let {var}[a:scope][a:trigger] += [[a:1, a:content]]
+	else
+		echom 'Warning in snipMate.vim: Snippet '.a:trigger.' is already defined.'
+				\ .' See :h multi_snip for help on snippets with multiple matches.'
+	endif
+endf
+
+fun! ExtractSnips(dir, ft)
+	for path in split(globpath(a:dir, '*'), "\n")
+		if isdirectory(path)
+			let pathname = fnamemodify(path, ':t')
+			for snipFile in split(globpath(path, '*.snippet'), "\n")
+				call s:ProcessFile(snipFile, a:ft, pathname)
+			endfor
+		elseif fnamemodify(path, ':e') == 'snippet'
+			call s:ProcessFile(path, a:ft)
+		endif
+	endfor
+endf
+
+" Processes a single-snippet file; optionally add the name of the parent
+" directory for a snippet with multiple matches.
+fun s:ProcessFile(file, ft, ...)
+	let keyword = fnamemodify(a:file, ':t:r')
+	if keyword  == '' | return | endif
+	try
+		let text = join(readfile(a:file), "\n")
+	catch /E484/
+		echom "Error in snipMate.vim: couldn't read file: ".a:file
+	endtry
+	return a:0 ? MakeSnip(a:ft, a:1, text, keyword)
+			\  : MakeSnip(a:ft, keyword, text)
+endf
+
+fun! ExtractSnipsFile(file, ft)
+	if !filereadable(a:file) | return | endif
+	let text = readfile(a:file)
+	let inSnip = 0
+	for line in text + ["\n"]
+		if inSnip && (line[0] == "\t" || line == '')
+			let content .= strpart(line, 1)."\n"
+			continue
+		elseif inSnip
+			call MakeSnip(a:ft, trigger, content[:-2], name)
+			let inSnip = 0
+		endif
+
+		if line[:6] == 'snippet'
+			let inSnip = 1
+			let trigger = strpart(line, 8)
+			let name = ''
+			let space = stridx(trigger, ' ') + 1
+			if space " Process multi snip
+				let name = strpart(trigger, space)
+				let trigger = strpart(trigger, 0, space - 1)
+			endif
+			let content = ''
+		endif
+	endfor
+endf
+
+" Reset snippets for filetype.
+fun! ResetSnippets(ft)
+	let ft = a:ft == '' ? '_' : a:ft
+	for dict in [s:snippets, s:multi_snips, g:did_ft]
+		if has_key(dict, ft)
+			unlet dict[ft]
+		endif
+	endfor
+endf
+
+" Reset snippets for all filetypes.
+fun! ResetAllSnippets()
+	let s:snippets = {} | let s:multi_snips = {} | let g:did_ft = {}
+endf
+
+" Reload snippets for filetype.
+fun! ReloadSnippets(ft)
+	let ft = a:ft == '' ? '_' : a:ft
+	call ResetSnippets(ft)
+	call GetSnippets(g:snippets_dir, ft)
+endf
+
+" Reload snippets for all filetypes.
+fun! ReloadAllSnippets()
+	for ft in keys(g:did_ft)
+		call ReloadSnippets(ft)
+	endfor
+endf
+
+let g:did_ft = {}
+fun! GetSnippets(dir, filetypes)
+	for ft in split(a:filetypes, '\.')
+		if has_key(g:did_ft, ft) | continue | endif
+		call s:DefineSnips(a:dir, ft, ft)
+		if ft == 'objc' || ft == 'cpp' || ft == 'cs'
+			call s:DefineSnips(a:dir, 'c', ft)
+		elseif ft == 'xhtml'
+			call s:DefineSnips(a:dir, 'html', 'xhtml')
+		endif
+		let g:did_ft[ft] = 1
+	endfor
+endf
+
+" Define "aliasft" snippets for the filetype "realft".
+fun s:DefineSnips(dir, aliasft, realft)
+	for path in split(globpath(a:dir, a:aliasft.'/')."\n".
+					\ globpath(a:dir, a:aliasft.'-*/'), "\n")
+		call ExtractSnips(path, a:realft)
+	endfor
+	for path in split(globpath(a:dir, a:aliasft.'.snippets')."\n".
+					\ globpath(a:dir, a:aliasft.'-*.snippets'), "\n")
+		call ExtractSnipsFile(path, a:realft)
+	endfor
+endf
+
+fun! TriggerSnippet()
+	if exists('g:SuperTabMappingForward')
+		if g:SuperTabMappingForward == "<tab>"
+			let SuperTabKey = "\<c-n>"
+		elseif g:SuperTabMappingBackward == "<tab>"
+			let SuperTabKey = "\<c-p>"
+		endif
+	endif
+
+	if pumvisible() " Update snippet if completion is used, or deal with supertab
+		if exists('SuperTabKey')
+			call feedkeys(SuperTabKey) | return ''
+		endif
+		call feedkeys("\<esc>a", 'n') " Close completion menu
+		call feedkeys("\<tab>") | return ''
+	endif
+
+	if exists('g:snipPos') | return snipMate#jumpTabStop(0) | endif
+
+	let word = matchstr(getline('.'), '\S\+\%'.col('.').'c')
+	for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
+		let [trigger, snippet] = s:GetSnippet(word, scope)
+		" If word is a trigger for a snippet, delete the trigger & expand
+		" the snippet.
+		if snippet != ''
+			let col = col('.') - len(trigger)
+			sil exe 's/\V'.escape(trigger, '/\.').'\%#//'
+			return snipMate#expandSnip(snippet, col)
+		endif
+	endfor
+
+	if exists('SuperTabKey')
+		call feedkeys(SuperTabKey)
+		return ''
+	endif
+	return "\<tab>"
+endf
+
+fun! BackwardsSnippet()
+	if exists('g:snipPos') | return snipMate#jumpTabStop(1) | endif
+
+	if exists('g:SuperTabMappingForward')
+		if g:SuperTabMappingBackward == "<s-tab>"
+			let SuperTabKey = "\<c-p>"
+		elseif g:SuperTabMappingForward == "<s-tab>"
+			let SuperTabKey = "\<c-n>"
+		endif
+	endif
+	if exists('SuperTabKey')
+		call feedkeys(SuperTabKey)
+		return ''
+	endif
+	return "\<s-tab>"
+endf
+
+" Check if word under cursor is snippet trigger; if it isn't, try checking if
+" the text after non-word characters is (e.g. check for "foo" in "bar.foo")
+fun s:GetSnippet(word, scope)
+	let word = a:word | let snippet = ''
+	while snippet == ''
+		if exists('s:snippets["'.a:scope.'"]["'.escape(word, '\"').'"]')
+			let snippet = s:snippets[a:scope][word]
+		elseif exists('s:multi_snips["'.a:scope.'"]["'.escape(word, '\"').'"]')
+			let snippet = s:ChooseSnippet(a:scope, word)
+			if snippet == '' | break | endif
+		else
+			if match(word, '\W') == -1 | break | endif
+			let word = substitute(word, '.\{-}\W', '', '')
+		endif
+	endw
+	if word == '' && a:word != '.' && stridx(a:word, '.') != -1
+		let [word, snippet] = s:GetSnippet('.', a:scope)
+	endif
+	return [word, snippet]
+endf
+
+fun s:ChooseSnippet(scope, trigger)
+	let snippet = []
+	let i = 1
+	for snip in s:multi_snips[a:scope][a:trigger]
+		let snippet += [i.'. '.snip[0]]
+		let i += 1
+	endfor
+	if i == 2 | return s:multi_snips[a:scope][a:trigger][0][1] | endif
+	let num = inputlist(snippet) - 1
+	return num == -1 ? '' : s:multi_snips[a:scope][a:trigger][num][1]
+endf
+
+fun! ShowAvailableSnips()
+	let line  = getline('.')
+	let col   = col('.')
+	let word  = matchstr(getline('.'), '\S\+\%'.col.'c')
+	let words = [word]
+	if stridx(word, '.')
+		let words += split(word, '\.', 1)
+	endif
+	let matchlen = 0
+	let matches = []
+	for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
+		let triggers = has_key(s:snippets, scope) ? keys(s:snippets[scope]) : []
+		if has_key(s:multi_snips, scope)
+			let triggers += keys(s:multi_snips[scope])
+		endif
+		for trigger in triggers
+			for word in words
+				if word == ''
+					let matches += [trigger] " Show all matches if word is empty
+				elseif trigger =~ '^'.word
+					let matches += [trigger]
+					let len = len(word)
+					if len > matchlen | let matchlen = len | endif
+				endif
+			endfor
+		endfor
+	endfor
+
+	" This is to avoid a bug with Vim when using complete(col - matchlen, matches)
+	" (Issue#46 on the Google Code snipMate issue tracker).
+	call setline(line('.'), substitute(line, repeat('.', matchlen).'\%'.col.'c', '', ''))
+	call complete(col, matches)
+	return ''
+endf
+" vim:noet:sw=4:ts=4:ft=vim

+ 274 - 0
vim/plugin/unimpaired.vim

@@ -0,0 +1,274 @@
+" unimpaired.vim - Pairs of handy bracket mappings
+" Maintainer:   Tim Pope <vimNOSPAM@tpope.org>
+" Version:      1.1
+
+if exists("g:loaded_unimpaired") || &cp || v:version < 700
+  finish
+endif
+let g:loaded_unimpaired = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Next and previous {{{1
+
+function! s:MapNextFamily(map,cmd)
+  let map = '<Plug>unimpaired'.toupper(a:map)
+  let end = ' ".(v:count ? v:count : "")<CR>'
+  execute 'nmap <silent> '.map.'Previous :<C-U>exe "'.a:cmd.'previous'.end
+  execute 'nmap <silent> '.map.'Next     :<C-U>exe "'.a:cmd.'next'.end
+  execute 'nmap <silent> '.map.'First    :<C-U>exe "'.a:cmd.'first'.end
+  execute 'nmap <silent> '.map.'Last     :<C-U>exe "'.a:cmd.'last'.end
+  execute 'nmap <silent> ['.        a:map .' '.map.'Previous'
+  execute 'nmap <silent> ]'.        a:map .' '.map.'Next'
+  execute 'nmap <silent> ['.toupper(a:map).' '.map.'First'
+  execute 'nmap <silent> ]'.toupper(a:map).' '.map.'Last'
+endfunction
+
+call s:MapNextFamily('a','')
+call s:MapNextFamily('b','b')
+call s:MapNextFamily('l','l')
+call s:MapNextFamily('q','c')
+
+function! s:entries(path)
+  let path = substitute(a:path,'[\\/]$','','')
+  let files = split(glob(path."/.*"),"\n")
+  let files += split(glob(path."/*"),"\n")
+  call map(files,'substitute(v:val,"[\\/]$","","")')
+  call filter(files,'v:val !~# "[\\\\/]\\.\\.\\=$"')
+  call filter(files,'v:val[-4:-1] !=# ".swp" && v:val[-1:-1] !=# "~"')
+  return files
+endfunction
+
+function! s:FileByOffset(num)
+  let file = expand('%:p')
+  let num = a:num
+  while num
+    let files = s:entries(fnamemodify(file,':h'))
+    if a:num < 0
+      call reverse(sort(filter(files,'v:val < file')))
+    else
+      call sort(filter(files,'v:val > file'))
+    endif
+    let temp = get(files,0,'')
+    if temp == ''
+      let file = fnamemodify(file,':h')
+    else
+      let file = temp
+      while isdirectory(file)
+        let files = s:entries(file)
+        if files == []
+          " TODO: walk back up the tree and continue
+          break
+        endif
+        let file = files[num > 0 ? 0 : -1]
+      endwhile
+      let num += num > 0 ? -1 : 1
+    endif
+  endwhile
+  return file
+endfunction
+
+nnoremap <silent> <Plug>unimpairedONext     :<C-U>edit `=<SID>FileByOffset(v:count1)`<CR>
+nnoremap <silent> <Plug>unimpairedOPrevious :<C-U>edit `=<SID>FileByOffset(-v:count1)`<CR>
+
+nmap ]o <Plug>unimpairedONext
+nmap [o <Plug>unimpairedOPrevious
+
+" }}}1
+" Line operations {{{1
+
+nnoremap <silent> <Plug>unimpairedBlankUp   :<C-U>put!=repeat(nr2char(10),v:count)<Bar>']+1<CR>
+nnoremap <silent> <Plug>unimpairedBlankDown :<C-U>put =repeat(nr2char(10),v:count)<Bar>'[-1<CR>
+
+nmap [<Space> <Plug>unimpairedBlankUp
+nmap ]<Space> <Plug>unimpairedBlankDown
+
+nnoremap <silent> <Plug>unimpairedMoveUp   :<C-U>exe 'norm m`'<Bar>exe 'move--'.v:count1<CR>``
+nnoremap <silent> <Plug>unimpairedMoveDown :<C-U>exe 'norm m`'<Bar>exe 'move+'.v:count1<CR>``
+xnoremap <silent> <Plug>unimpairedMoveUp   :<C-U>exe 'norm m`'<Bar>exe '''<,''>move--'.v:count1<CR>``
+xnoremap <silent> <Plug>unimpairedMoveDown :<C-U>exe 'norm m`'<Bar>exe '''<,''>move''>+'.v:count1<CR>``
+
+nmap [e <Plug>unimpairedMoveUp
+nmap ]e <Plug>unimpairedMoveDown
+xmap [e <Plug>unimpairedMoveUp
+xmap ]e <Plug>unimpairedMoveDown
+
+" }}}1
+" Encoding and decoding {{{1
+
+function! s:StringEncode(str)
+  let map = {"\n": 'n', "\r": 'r', "\t": 't', "\b": 'b', "\f": '\f', '"': '"', '\': '\'}
+  return substitute(a:str,"[\001-\033\\\\\"]",'\="\\".get(map,submatch(0),printf("%03o",char2nr(submatch(0))))','g')
+endfunction
+
+function! s:StringDecode(str)
+  let map = {'n': "\n", 'r': "\r", 't': "\t", 'b': "\b", 'f': "\f", 'e': "\e", 'a': "\001", 'v': "\013", '"': '"', '\': '\', "'": "'"}
+  let str = a:str
+  if str =~ '^\s*".\{-\}\\\@<!\%(\\\\\)*"\s*\n\=$'
+    let str = substitute(substitute(str,'^\s*\zs"','',''),'"\ze\s*\n\=$','','')
+  endif
+  let str = substitute(str,'\\n\%(\n$\)\=','\n','g')
+  return substitute(str,'\\\(\o\{1,3\}\|x\x\{1,2\}\|u\x\{1,4\}\|.\)','\=get(map,submatch(1),nr2char("0".substitute(submatch(1),"^[Uu]","x","")))','g')
+endfunction
+
+function! s:UrlEncode(str)
+  return substitute(a:str,'[^A-Za-z0-9_.~-]','\="%".printf("%02X",char2nr(submatch(0)))','g')
+endfunction
+
+function! s:UrlDecode(str)
+  let str = substitute(substitute(substitute(a:str,'%0[Aa]\n$','%0A',''),'%0[Aa]','\n','g'),'+',' ','g')
+  return substitute(str,'%\(\x\x\)','\=nr2char("0x".submatch(1))','g')
+endfunction
+
+" HTML entities {{{2
+
+let g:unimpaired_html_entities = {
+      \ 'nbsp':     160, 'iexcl':    161, 'cent':     162, 'pound':    163,
+      \ 'curren':   164, 'yen':      165, 'brvbar':   166, 'sect':     167,
+      \ 'uml':      168, 'copy':     169, 'ordf':     170, 'laquo':    171,
+      \ 'not':      172, 'shy':      173, 'reg':      174, 'macr':     175,
+      \ 'deg':      176, 'plusmn':   177, 'sup2':     178, 'sup3':     179,
+      \ 'acute':    180, 'micro':    181, 'para':     182, 'middot':   183,
+      \ 'cedil':    184, 'sup1':     185, 'ordm':     186, 'raquo':    187,
+      \ 'frac14':   188, 'frac12':   189, 'frac34':   190, 'iquest':   191,
+      \ 'Agrave':   192, 'Aacute':   193, 'Acirc':    194, 'Atilde':   195,
+      \ 'Auml':     196, 'Aring':    197, 'AElig':    198, 'Ccedil':   199,
+      \ 'Egrave':   200, 'Eacute':   201, 'Ecirc':    202, 'Euml':     203,
+      \ 'Igrave':   204, 'Iacute':   205, 'Icirc':    206, 'Iuml':     207,
+      \ 'ETH':      208, 'Ntilde':   209, 'Ograve':   210, 'Oacute':   211,
+      \ 'Ocirc':    212, 'Otilde':   213, 'Ouml':     214, 'times':    215,
+      \ 'Oslash':   216, 'Ugrave':   217, 'Uacute':   218, 'Ucirc':    219,
+      \ 'Uuml':     220, 'Yacute':   221, 'THORN':    222, 'szlig':    223,
+      \ 'agrave':   224, 'aacute':   225, 'acirc':    226, 'atilde':   227,
+      \ 'auml':     228, 'aring':    229, 'aelig':    230, 'ccedil':   231,
+      \ 'egrave':   232, 'eacute':   233, 'ecirc':    234, 'euml':     235,
+      \ 'igrave':   236, 'iacute':   237, 'icirc':    238, 'iuml':     239,
+      \ 'eth':      240, 'ntilde':   241, 'ograve':   242, 'oacute':   243,
+      \ 'ocirc':    244, 'otilde':   245, 'ouml':     246, 'divide':   247,
+      \ 'oslash':   248, 'ugrave':   249, 'uacute':   250, 'ucirc':    251,
+      \ 'uuml':     252, 'yacute':   253, 'thorn':    254, 'yuml':     255,
+      \ 'OElig':    338, 'oelig':    339, 'Scaron':   352, 'scaron':   353,
+      \ 'Yuml':     376, 'circ':     710, 'tilde':    732, 'ensp':    8194,
+      \ 'emsp':    8195, 'thinsp':  8201, 'zwnj':    8204, 'zwj':     8205,
+      \ 'lrm':     8206, 'rlm':     8207, 'ndash':   8211, 'mdash':   8212,
+      \ 'lsquo':   8216, 'rsquo':   8217, 'sbquo':   8218, 'ldquo':   8220,
+      \ 'rdquo':   8221, 'bdquo':   8222, 'dagger':  8224, 'Dagger':  8225,
+      \ 'permil':  8240, 'lsaquo':  8249, 'rsaquo':  8250, 'euro':    8364,
+      \ 'fnof':     402, 'Alpha':    913, 'Beta':     914, 'Gamma':    915,
+      \ 'Delta':    916, 'Epsilon':  917, 'Zeta':     918, 'Eta':      919,
+      \ 'Theta':    920, 'Iota':     921, 'Kappa':    922, 'Lambda':   923,
+      \ 'Mu':       924, 'Nu':       925, 'Xi':       926, 'Omicron':  927,
+      \ 'Pi':       928, 'Rho':      929, 'Sigma':    931, 'Tau':      932,
+      \ 'Upsilon':  933, 'Phi':      934, 'Chi':      935, 'Psi':      936,
+      \ 'Omega':    937, 'alpha':    945, 'beta':     946, 'gamma':    947,
+      \ 'delta':    948, 'epsilon':  949, 'zeta':     950, 'eta':      951,
+      \ 'theta':    952, 'iota':     953, 'kappa':    954, 'lambda':   955,
+      \ 'mu':       956, 'nu':       957, 'xi':       958, 'omicron':  959,
+      \ 'pi':       960, 'rho':      961, 'sigmaf':   962, 'sigma':    963,
+      \ 'tau':      964, 'upsilon':  965, 'phi':      966, 'chi':      967,
+      \ 'psi':      968, 'omega':    969, 'thetasym': 977, 'upsih':    978,
+      \ 'piv':      982, 'bull':    8226, 'hellip':  8230, 'prime':   8242,
+      \ 'Prime':   8243, 'oline':   8254, 'frasl':   8260, 'weierp':  8472,
+      \ 'image':   8465, 'real':    8476, 'trade':   8482, 'alefsym': 8501,
+      \ 'larr':    8592, 'uarr':    8593, 'rarr':    8594, 'darr':    8595,
+      \ 'harr':    8596, 'crarr':   8629, 'lArr':    8656, 'uArr':    8657,
+      \ 'rArr':    8658, 'dArr':    8659, 'hArr':    8660, 'forall':  8704,
+      \ 'part':    8706, 'exist':   8707, 'empty':   8709, 'nabla':   8711,
+      \ 'isin':    8712, 'notin':   8713, 'ni':      8715, 'prod':    8719,
+      \ 'sum':     8721, 'minus':   8722, 'lowast':  8727, 'radic':   8730,
+      \ 'prop':    8733, 'infin':   8734, 'ang':     8736, 'and':     8743,
+      \ 'or':      8744, 'cap':     8745, 'cup':     8746, 'int':     8747,
+      \ 'there4':  8756, 'sim':     8764, 'cong':    8773, 'asymp':   8776,
+      \ 'ne':      8800, 'equiv':   8801, 'le':      8804, 'ge':      8805,
+      \ 'sub':     8834, 'sup':     8835, 'nsub':    8836, 'sube':    8838,
+      \ 'supe':    8839, 'oplus':   8853, 'otimes':  8855, 'perp':    8869,
+      \ 'sdot':    8901, 'lceil':   8968, 'rceil':   8969, 'lfloor':  8970,
+      \ 'rfloor':  8971, 'lang':    9001, 'rang':    9002, 'loz':     9674,
+      \ 'spades':  9824, 'clubs':   9827, 'hearts':  9829, 'diams':   9830,
+      \ 'apos':      39}
+
+" }}}2
+
+function! s:XmlEncode(str)
+  let str = a:str
+  let str = substitute(str,'&','\&amp;','g')
+  let str = substitute(str,'<','\&lt;','g')
+  let str = substitute(str,'>','\&gt;','g')
+  let str = substitute(str,'"','\&quot;','g')
+  return str
+endfunction
+
+function! s:XmlEntityDecode(str)
+  let str = substitute(a:str,'\c&#\%(0*38\|x0*26\);','&amp;','g')
+  let str = substitute(str,'\c&#\(\d\+\);','\=nr2char(submatch(1))','g')
+  let str = substitute(str,'\c&#\(x\x\+\);','\=nr2char("0".submatch(1))','g')
+  let str = substitute(str,'\c&apos;',"'",'g')
+  let str = substitute(str,'\c&quot;','"','g')
+  let str = substitute(str,'\c&gt;','>','g')
+  let str = substitute(str,'\c&lt;','<','g')
+  let str = substitute(str,'\C&\(\%(amp;\)\@!\w*\);','\=nr2char(get(g:unimpaired_html_entities,submatch(1),63))','g')
+  return substitute(str,'\c&amp;','\&','g')
+endfunction
+
+function! s:XmlDecode(str)
+  let str = substitute(a:str,'<\%([[:alnum:]-]\+=\%("[^"]*"\|''[^'']*''\)\|.\)\{-\}>','','g')
+  return s:XmlEntityDecode(str)
+endfunction
+
+function! s:Transform(algorithm,type)
+  let sel_save = &selection
+  let cb_save = &clipboard
+  set selection=inclusive clipboard-=unnamed
+  let reg_save = @@
+  if a:type =~ '^\d\+$'
+    silent exe 'norm! ^v'.a:type.'$hy'
+  elseif a:type =~ '^.$'
+    silent exe "normal! `<" . a:type . "`>y"
+  elseif a:type == 'line'
+    silent exe "normal! '[V']y"
+  elseif a:type == 'block'
+    silent exe "normal! `[\<C-V>`]y"
+  else
+    silent exe "normal! `[v`]y"
+  endif
+  let @@ = s:{a:algorithm}(@@)
+  norm! gvp
+  let @@ = reg_save
+  let &selection = sel_save
+  let &clipboard = cb_save
+  if a:type =~ '^\d\+$'
+    silent! call repeat#set("\<Plug>unimpairedLine".a:algorithm,a:type)
+  endif
+endfunction
+
+function! s:TransformOpfunc(type)
+  return s:Transform(s:encode_algorithm, a:type)
+endfunction
+
+function! s:TransformSetup(algorithm)
+  let s:encode_algorithm = a:algorithm
+  let &opfunc = matchstr(expand('<sfile>'), '<SNR>\d\+_').'TransformOpfunc'
+endfunction
+
+function! s:MapTransform(algorithm, key)
+  exe 'nnoremap <silent> <Plug>unimpaired'    .a:algorithm.' :<C-U>call <SID>TransformSetup("'.a:algorithm.'")<CR>g@'
+  exe 'xnoremap <silent> <Plug>unimpaired'    .a:algorithm.' :<C-U>call <SID>Transform("'.a:algorithm.'",visualmode())<CR>'
+  exe 'nnoremap <silent> <Plug>unimpairedLine'.a:algorithm.' :<C-U>call <SID>Transform("'.a:algorithm.'",v:count1)<CR>'
+  exe 'nmap '.a:key.'  <Plug>unimpaired'.a:algorithm
+  exe 'xmap '.a:key.'  <Plug>unimpaired'.a:algorithm
+  exe 'nmap '.a:key.a:key[strlen(a:key)-1].' <Plug>unimpairedLine'.a:algorithm
+endfunction
+
+call s:MapTransform('StringEncode','[y')
+call s:MapTransform('StringDecode',']y')
+call s:MapTransform('UrlEncode','[u')
+call s:MapTransform('UrlDecode',']u')
+call s:MapTransform('XmlEncode','[x')
+call s:MapTransform('XmlDecode',']x')
+
+" }}}1
+
+let &cpo = s:cpo_save
+
+" vim:set ft=vim ts=8 sw=2 sts=2:

+ 181 - 0
vim/ruby/command-t/Makefile

@@ -0,0 +1,181 @@
+
+SHELL = /bin/sh
+
+#### Start of system configuration section. ####
+
+srcdir = .
+topdir = /usr/lib/ruby/1.8/i686-linux
+hdrdir = $(topdir)
+VPATH = $(srcdir):$(topdir):$(hdrdir)
+prefix = $(DESTDIR)/usr
+exec_prefix = $(prefix)
+oldincludedir = $(DESTDIR)/usr/include
+localstatedir = $(DESTDIR)/var
+localedir = $(datarootdir)/locale
+pdfdir = $(docdir)
+libdir = $(exec_prefix)/lib
+sbindir = $(exec_prefix)/sbin
+sitearchdir = $(sitelibdir)/$(sitearch)
+vendorlibdir = $(vendordir)/$(ruby_version)
+datarootdir = $(prefix)/share
+docdir = $(datarootdir)/doc/$(PACKAGE)
+sitelibdir = $(sitedir)/$(ruby_version)
+sitedir = $(DESTDIR)/usr/local/lib/site_ruby
+sharedstatedir = $(prefix)/com
+dvidir = $(docdir)
+psdir = $(docdir)
+libexecdir = $(prefix)/lib/ruby1.8
+archdir = $(rubylibdir)/$(arch)
+includedir = $(prefix)/include
+vendorarchdir = $(vendorlibdir)/$(sitearch)
+sysconfdir = $(DESTDIR)/etc
+bindir = $(exec_prefix)/bin
+htmldir = $(docdir)
+mandir = $(prefix)/share/man
+datadir = $(datarootdir)
+rubylibdir = $(libdir)/ruby/$(ruby_version)
+vendordir = $(libdir)/ruby/vendor_ruby
+infodir = $(prefix)/share/info
+
+CC = gcc
+LIBRUBY = $(LIBRUBY_SO)
+LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
+LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
+LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
+
+RUBY_EXTCONF_H = 
+CFLAGS   =  -fPIC -fno-strict-aliasing -g -g -O2  -fPIC $(cflags) 
+INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir)
+DEFS     = -D_FILE_OFFSET_BITS=64 -DWATCHMAN_BUILD
+CPPFLAGS = -DHAVE_FCNTL_H -DHAVE_SYS_ERRNO_H -DHAVE_SYS_SOCKET_H -DHAVE_ST_H -D_FORTIFY_SOURCE=2 $(DEFS) $(cppflags)
+CXXFLAGS = $(CFLAGS) 
+ldflags  = -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -rdynamic -Wl,-export-dynamic
+dldflags = 
+archflag = 
+DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
+LDSHARED = $(CC) -shared
+AR = ar
+EXEEXT = 
+
+RUBY_INSTALL_NAME = ruby1.8
+RUBY_SO_NAME = ruby1.8
+arch = i686-linux
+sitearch = i686-linux
+ruby_version = 1.8
+ruby = /usr/bin/ruby1.8
+RUBY = $(ruby)
+RM = rm -f
+MAKEDIRS = mkdir -p
+INSTALL = /usr/bin/install -c
+INSTALL_PROG = $(INSTALL) -m 0755
+INSTALL_DATA = $(INSTALL) -m 644
+COPY = cp
+
+#### End of system configuration section. ####
+
+preload = 
+
+libpath = . $(libdir)
+LIBPATH =  -L. -L$(libdir)
+DEFFILE = 
+
+CLEANFILES = mkmf.log
+DISTCLEANFILES = 
+
+extout = 
+extout_prefix = 
+target_prefix = 
+LOCAL_LIBS = 
+LIBS = $(LIBRUBYARG_SHARED)  -lpthread -lrt -ldl -lcrypt -lm   -lc
+SRCS = watchman.c match.c matcher.c ext.c
+OBJS = watchman.o match.o matcher.o ext.o
+TARGET = ext
+DLLIB = $(TARGET).so
+EXTSTATIC = 
+STATIC_LIB = 
+
+BINDIR        = $(bindir)
+RUBYCOMMONDIR = $(sitedir)$(target_prefix)
+RUBYLIBDIR    = $(sitelibdir)$(target_prefix)
+RUBYARCHDIR   = $(sitearchdir)$(target_prefix)
+
+TARGET_SO     = $(DLLIB)
+CLEANLIBS     = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
+CLEANOBJS     = *.o *.a *.s[ol] *.pdb *.exp *.bak
+
+all:		$(DLLIB)
+static:		$(STATIC_LIB)
+
+clean:
+		@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
+
+distclean:	clean
+		@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
+		@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
+
+realclean:	distclean
+install: install-so install-rb
+
+install-so: $(RUBYARCHDIR)
+install-so: $(RUBYARCHDIR)/$(DLLIB)
+$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
+	$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
+install-rb: pre-install-rb install-rb-default
+install-rb-default: pre-install-rb-default
+pre-install-rb: Makefile
+pre-install-rb-default: Makefile
+$(RUBYARCHDIR):
+	$(MAKEDIRS) $@
+
+site-install: site-install-so site-install-rb
+site-install-so: install-so
+site-install-rb: install-rb
+
+.SUFFIXES: .c .m .cc .cxx .cpp .C .o
+
+.cc.o:
+	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
+
+.cxx.o:
+	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
+
+.cpp.o:
+	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
+
+.C.o:
+	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
+
+.c.o:
+	$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
+
+$(DLLIB): $(OBJS) Makefile
+	@-$(RM) $@
+	$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
+
+
+
+###
+# Copyright 2010-2014 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 += -Wall -Wextra -Wno-unused-parameter

+ 396 - 0
vim/ruby/command-t/controller.rb

@@ -0,0 +1,396 @@
+# Copyright 2010-2014 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'
+require 'command-t/util'
+
+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
+
+    # Take current matches and stick them in the quickfix window.
+    def quickfix
+      hide
+
+      matches = @matches.map do |match|
+        "{ 'filename': '#{VIM::escape_for_single_quotes match}' }"
+      end.join(', ')
+
+      ::VIM::command 'call setqflist([' + matches + '])'
+      ::VIM::command 'cope'
+    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
+        @needs_update = true
+      else
+        @match_window.find key
+      end
+    end
+
+    def backspace
+      if @focus == @prompt
+        @prompt.backspace!
+        @needs_update = true
+      end
+    end
+
+    def delete
+      if @focus == @prompt
+        @prompt.delete!
+        @needs_update = true
+      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
+
+    def list_matches(options = {})
+      return unless @needs_update || options[:force]
+
+      @matches = @active_finder.sorted_matches_for(
+        @prompt.abbrev,
+        :limit   => match_limit,
+        :threads => CommandT::Util.processor_count
+      )
+      @match_window.matches = @matches
+
+      @needs_update = false
+    end
+
+  private
+
+    def list_matches!
+      list_matches(:force => true)
+    end
+
+    def show
+      @initial_window   = $curwin
+      @initial_buffer   = $curbuf
+      @match_window     = MatchWindow.new \
+        :highlight_color      => get_string('g:CommandTHighlightColor'),
+        :match_window_at_top  => get_bool('g:CommandTMatchWindowAtTop'),
+        :match_window_reverse => get_bool('g:CommandTMatchWindowReverse'),
+        :min_height           => min_height,
+        :debounce_interval    => get_number('g:CommandTInputDebounce', 50),
+        :prompt               => @prompt
+      @focus            = @prompt
+      @prompt.focus
+      register_for_key_presses
+      set_up_autocmds
+      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, default = nil)
+      VIM::exists?(name) ? ::VIM::evaluate("#{name}").to_i : default
+    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
+      selection = File.join('.', selection) if selection =~ /^\+/
+      ensure_appropriate_window_selection
+
+      @active_finder.open_selection command, selection, options
+    end
+
+    def map key, function, param = nil
+      ::VIM::command "noremap <silent> <buffer> #{key} " \
+        ":call CommandT#{function}(#{param})<CR>"
+    end
+
+    def term
+      @term ||= ::VIM::evaluate('&term')
+    end
+
+    def register_for_key_presses
+      # "normal" keys (interpreted literally)
+      numbers     = ('0'..'9').to_a.join
+      lowercase   = ('a'..'z').to_a.join
+      uppercase   = lowercase.upcase
+      punctuation = '<>`@#~!"$%&/()=+*-_.,;:?\\\'{}[] ' # and space
+      (numbers + lowercase + uppercase + punctuation).each_byte do |b|
+        map "<Char-#{b}>", 'HandleKey', b
+      end
+
+      # "special" keys (overridable by settings)
+      {
+        'AcceptSelection'       => '<CR>',
+        'AcceptSelectionSplit'  => ['<C-CR>', '<C-s>'],
+        'AcceptSelectionTab'    => '<C-t>',
+        'AcceptSelectionVSplit' => '<C-v>',
+        'Backspace'             => '<BS>',
+        'Cancel'                => ['<C-c>', '<Esc>'],
+        'Clear'                 => '<C-u>',
+        'CursorEnd'             => '<C-e>',
+        'CursorLeft'            => ['<Left>', '<C-h>'],
+        'CursorRight'           => ['<Right>', '<C-l>'],
+        'CursorStart'           => '<C-a>',
+        'Delete'                => '<Del>',
+        'Quickfix'              => '<C-q>',
+        'Refresh'               => '<C-f>',
+        'SelectNext'            => ['<C-n>', '<C-j>', '<Down>'],
+        'SelectPrev'            => ['<C-p>', '<C-k>', '<Up>'],
+        'ToggleFocus'           => '<Tab>',
+      }.each do |key, value|
+        if override = get_list_or_string("g:CommandT#{key}Map")
+          Array(override).each do |mapping|
+            map mapping, key
+          end
+        else
+          Array(value).each do |mapping|
+            unless mapping == '<Esc>' && term =~ /\A(screen|xterm|vt100)/
+              map mapping, key
+            end
+          end
+        end
+      end
+    end
+
+    def set_up_autocmds
+      ::VIM::command 'augroup Command-T'
+      ::VIM::command 'au!'
+      ::VIM::command 'autocmd CursorHold <buffer> :call CommandTListMatches()'
+      ::VIM::command 'augroup 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 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'),
+        :wild_ignore            => get_string('g:CommandTWildIgnore'),
+        :scanner                => get_string('g:CommandTFileScanner')
+    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

+ 24 - 0
vim/ruby/command-t/depend

@@ -0,0 +1,24 @@
+# Copyright 2010-2014 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 += -Wall -Wextra -Wno-unused-parameter

+ 60 - 0
vim/ruby/command-t/ext.c

@@ -0,0 +1,60 @@
+// Copyright 2010-2014 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 "matcher.h"
+#include "watchman.h"
+
+VALUE mCommandT              = 0; // module CommandT
+VALUE cCommandTMatcher       = 0; // class CommandT::Matcher
+VALUE mCommandTWatchman      = 0; // module CommandT::Watchman
+VALUE mCommandTWatchmanUtils = 0; // module CommandT::Watchman::Utils
+
+VALUE CommandT_option_from_hash(const char *option, VALUE hash)
+{
+    VALUE key;
+    if (NIL_P(hash))
+        return Qnil;
+    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::Matcher
+    cCommandTMatcher = rb_define_class_under(mCommandT, "Matcher", rb_cObject);
+    rb_define_method(cCommandTMatcher, "initialize", CommandTMatcher_initialize, -1);
+    rb_define_method(cCommandTMatcher, "sorted_matches_for", CommandTMatcher_sorted_matches_for, -1);
+
+    // module CommandT::Watchman::Utils
+    mCommandTWatchman = rb_define_module_under(mCommandT, "Watchman");
+    mCommandTWatchmanUtils = rb_define_module_under(mCommandTWatchman, "Utils");
+    rb_define_singleton_method(mCommandTWatchmanUtils, "load", CommandTWatchmanUtils_load, 1);
+    rb_define_singleton_method(mCommandTWatchmanUtils, "dump", CommandTWatchmanUtils_dump, 1);
+    rb_define_singleton_method(mCommandTWatchmanUtils, "query", CommandTWatchmanUtils_query, 2);
+}

+ 37 - 0
vim/ruby/command-t/ext.h

@@ -0,0 +1,37 @@
+// Copyright 2010-2014 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 <ruby.h>
+
+extern VALUE mCommandT;              // module CommandT
+extern VALUE cCommandTMatcher;       // class CommandT::Matcher
+extern VALUE mCommandTWatchman;      // module CommandT::Watchman
+extern VALUE mCommandTWatchmanUtils; // module CommandT::Watchman::Utils
+
+// 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)

BIN
vim/ruby/command-t/ext.o


BIN
vim/ruby/command-t/ext.so


+ 56 - 0
vim/ruby/command-t/extconf.rb

@@ -0,0 +1,56 @@
+# Copyright 2010-2014 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 header(item)
+  unless find_header(item)
+    puts "couldn't find #{item} (required)"
+    exit 1
+  end
+end
+
+# mandatory headers
+header('float.h')
+header('ruby.h')
+header('stdlib.h')
+header('string.h')
+
+# optional headers (for CommandT::Watchman::Utils)
+if have_header('fcntl.h') &&
+  have_header('sys/errno.h') &&
+  have_header('sys/socket.h')
+  RbConfig::MAKEFILE_CONFIG['DEFS'] += ' -DWATCHMAN_BUILD'
+
+  have_header('ruby/st.h') # >= 1.9; sets HAVE_RUBY_ST_H
+  have_header('st.h')      # 1.8; sets HAVE_ST_H
+end
+
+# optional
+if RbConfig::CONFIG['THREAD_MODEL'] == 'pthread'
+  have_library('pthread', 'pthread_create') # sets HAVE_PTHREAD_H if found
+end
+
+RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
+
+create_makefile('ext')

+ 54 - 0
vim/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

+ 35 - 0
vim/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

+ 51 - 0
vim/ruby/command-t/finder/file_finder.rb

@@ -0,0 +1,51 @@
+# Copyright 2010-2014 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/ruby_file_scanner'
+require 'command-t/scanner/file_scanner/find_file_scanner'
+require 'command-t/scanner/file_scanner/watchman_file_scanner'
+
+module CommandT
+  class FileFinder < Finder
+    def initialize(path = Dir.pwd, options = {})
+      case options.delete(:scanner)
+      when 'ruby', nil # ruby is the default
+        @scanner = FileScanner::RubyFileScanner.new(path, options)
+      when 'find'
+        @scanner = FileScanner::FindFileScanner.new(path, options)
+      when 'watchman'
+        @scanner = FileScanner::WatchmanFileScanner.new(path, options)
+      else
+        raise ArgumentError, "unknown scanner type '#{options[:scanner]}'"
+      end
+
+      @matcher = Matcher.new @scanner, options
+    end
+
+    def flush
+      @scanner.flush
+    end
+  end # class FileFinder
+end # module CommandT

+ 35 - 0
vim/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

+ 44 - 0
vim/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

+ 201 - 0
vim/ruby/command-t/match.c

@@ -0,0 +1,201 @@
+// Copyright 2010-2013 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 <float.h> /* for DBL_MAX */
+#include "match.h"
+#include "ext.h"
+#include "ruby_compat.h"
+
+// use a struct to make passing params during recursion easier
+typedef struct {
+    char    *haystack_p;            // pointer to the path string to be searched
+    long    haystack_len;           // length of same
+    char    *needle_p;              // pointer to search string (needle)
+    long    needle_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
+    double  *memo;                  // memoization
+} matchinfo_t;
+
+double recursive_match(matchinfo_t *m,    // sharable meta-data
+                       long haystack_idx, // where in the path string to start
+                       long needle_idx,   // where in the needle 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 needle matches a dot-file
+    int dot_search = 0;     // true if searching for a dot
+    long i, j, distance;
+    int found;
+    double score_for_char;
+
+    // do we have a memoized result we can return?
+    double memoized = m->memo[needle_idx * m->needle_len + haystack_idx];
+    if (memoized != DBL_MAX)
+        return memoized;
+
+    // bail early if not enough room (left) in haystack for (rest of) needle
+    if (m->haystack_len - haystack_idx < m->needle_len - needle_idx) {
+        score = 0.0;
+        goto memoize;
+    }
+
+    for (i = needle_idx; i < m->needle_len; i++) {
+        char c = m->needle_p[i];
+        if (c == '.')
+            dot_search = 1;
+        found = 0;
+
+        // similar to above, we'll stop iterating when we know we're too close
+        // to the end of the string to possibly match
+        for (j = haystack_idx;
+             j <= m->haystack_len - (m->needle_len - i);
+             j++, haystack_idx++) {
+            char d = m->haystack_p[j];
+            if (d == '.') {
+                if (j == 0 || m->haystack_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
+                score_for_char = m->max_score_per_char;
+                distance = j - last_idx;
+
+                if (distance > 1) {
+                    double factor = 1.0;
+                    char last = m->haystack_p[j - 1];
+                    char curr = m->haystack_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->haystack_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 = haystack_idx + 1;
+                break;
+            }
+        }
+
+        if (!found) {
+            score = 0.0;
+            goto memoize;
+        }
+    }
+
+    if (m->dot_file &&
+        (m->never_show_dot_files ||
+         (!dot_file_match && !m->always_show_dot_files))) {
+        score = 0.0;
+        goto memoize;
+    }
+    score = score > seen_score ? score : seen_score;
+
+memoize:
+    m->memo[needle_idx * m->needle_len + haystack_idx] = score;
+    return score;
+}
+
+void calculate_match(VALUE str,
+                     VALUE needle,
+                     VALUE always_show_dot_files,
+                     VALUE never_show_dot_files,
+                     match_t *out)
+{
+    long i, max;
+    double score;
+    matchinfo_t m;
+    m.haystack_p            = RSTRING_PTR(str);
+    m.haystack_len          = RSTRING_LEN(str);
+    m.needle_p              = RSTRING_PTR(needle);
+    m.needle_len            = RSTRING_LEN(needle);
+    m.max_score_per_char    = (1.0 / m.haystack_len + 1.0 / m.needle_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
+    score = 1.0;
+
+    // special case for zero-length search string
+    if (m.needle_len == 0) {
+
+        // filter out dot files
+        if (!m.always_show_dot_files) {
+            for (i = 0; i < m.haystack_len; i++) {
+                char c = m.haystack_p[i];
+
+                if (c == '.' && (i == 0 || m.haystack_p[i - 1] == '/')) {
+                    score = 0.0;
+                    break;
+                }
+            }
+        }
+    } else if (m.haystack_len > 0) { // normal case
+
+        // prepare for memoization
+        double memo[m.haystack_len * m.needle_len];
+        for (i = 0, max = m.haystack_len * m.needle_len; i < max; i++)
+            memo[i] = DBL_MAX;
+        m.memo = memo;
+
+        score = recursive_match(&m, 0, 0, 0, 0.0);
+    }
+
+    // final book-keeping
+    out->path  = str;
+    out->score = score;
+}

+ 36 - 0
vim/ruby/command-t/match.h

@@ -0,0 +1,36 @@
+// Copyright 2010-2013 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 <ruby.h>
+
+// struct for representing an individual match
+typedef struct {
+    VALUE   path;
+    double  score;
+} match_t;
+
+extern void calculate_match(VALUE str,
+                            VALUE needle,
+                            VALUE always_show_dot_files,
+                            VALUE never_show_dot_files,
+                            match_t *out);

BIN
vim/ruby/command-t/match.o


+ 446 - 0
vim/ruby/command-t/match_window.rb

@@ -0,0 +1,446 @@
+# Copyright 2010-2014 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          = '<commandt>'
+    MH_END            = '</commandt>'
+    @@buffer          = nil
+
+    def initialize options = {}
+      @highlight_color = options[:highlight_color] || 'PmenuSel'
+      @min_height      = options[:min_height]
+      @prompt          = options[:prompt]
+      @reverse_list    = options[:match_window_reverse]
+
+      # 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
+
+      set 'timeout', true        # ensure mappings timeout
+      set 'hlsearch', false      # don't highlight search strings
+      set 'insertmode', false    # don't make Insert mode the default
+      set 'showcmd', false       # don't show command info on last line
+      set 'equalalways', false   # don't auto-balance window sizes
+      set 'timeoutlen', 0        # respond immediately to mappings
+      set 'report', 9999         # don't show "X lines changed" reports
+      set 'sidescroll', 0        # don't sidescroll in jumps
+      set 'sidescrolloff', 0     # don't sidescroll automatically
+      set 'updatetime', options[:debounce_interval]
+
+      # 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
+        ::VIM::command "silent! #{split_location} 1split GoToFile"
+        set 'bufhidden', 'unload' # unload buf when no longer displayed
+        set 'buftype', 'nofile'   # buffer is not related to any file
+        set 'modifiable', false   # prevent manual edits
+        set 'swapfile', false     # don't create a swapfile
+        set 'wrap', false         # don't soft-wrap
+        set 'number', false       # don't show line numbers
+        set 'list', false         # don't use List mode (visible tabs etc)
+        set 'foldcolumn', 0       # don't show a fold column at side
+        set 'foldlevel', 99       # don't fold anything
+        set 'cursorline', false   # don't highlight line cursor is on
+        set 'spell', false        # spell-checking off
+        set 'buflisted', false    # don't show up in the buffer list
+        set 'textwidth', 0        # don't hard-wrap (break long lines)
+
+        # don't show the color column
+        set 'colorcolumn', 0 if VIM::exists?('+colorcolumn')
+
+        # don't show relative line numbers
+        set 'relativenumber', false 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 --$"'
+        set 'synmaxcol', 9999
+
+        if VIM::has_conceal?
+          set 'conceallevel', 2
+          set '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 #{@highlight_color}"
+        ::VIM::command 'highlight link CommandTNoEntries Error'
+
+        # 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. <C-W q>, <C-W k> etc)
+      ::VIM::command 'autocmd! * <buffer>'
+      ::VIM::command 'autocmd BufLeave <buffer> silent! ruby $command_t.leave'
+      ::VIM::command 'autocmd BufUnload <buffer> 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 #{@highlight_color}"
+        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 set(setting, value)
+      @settings ||= Settings.new
+      @settings.set(setting, value)
+    end
+
+    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
+      set 'modifiable', false
+    end
+
+    def unlock
+      set 'modifiable', true
+    end
+  end
+end

+ 242 - 0
vim/ruby/command-t/matcher.c

@@ -0,0 +1,242 @@
+// Copyright 2010-2014 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 <stdlib.h>  /* for qsort() */
+#include <string.h>  /* for strncmp() */
+#include "matcher.h"
+#include "match.h"
+#include "ext.h"
+#include "ruby_compat.h"
+
+// order matters; we want this to be evaluated only after ruby.h
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h> /* for pthread_create, pthread_join etc */
+#endif
+
+// comparison function for use with qsort
+int cmp_alpha(const void *a, const void *b)
+{
+    match_t a_match = *(match_t *)a;
+    match_t b_match = *(match_t *)b;
+    VALUE   a_str   = a_match.path;
+    VALUE   b_str   = b_match.path;
+    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 cmp_score(const void *a, const void *b)
+{
+    match_t a_match = *(match_t *)a;
+    match_t b_match = *(match_t *)b;
+
+    if (a_match.score > b_match.score)
+        return -1; // a scores higher, a should appear sooner
+    else if (a_match.score < b_match.score)
+        return 1;  // b scores higher, a should appear later
+    else
+        return cmp_alpha(a, b);
+}
+
+VALUE CommandTMatcher_initialize(int argc, VALUE *argv, VALUE self)
+{
+    VALUE always_show_dot_files;
+    VALUE never_show_dot_files;
+    VALUE options;
+    VALUE scanner;
+
+    // process arguments: 1 mandatory, 1 optional
+    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
+    always_show_dot_files = CommandT_option_from_hash("always_show_dot_files", options);
+    never_show_dot_files = CommandT_option_from_hash("never_show_dot_files", options);
+
+    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;
+}
+
+typedef struct {
+    int thread_count;
+    int thread_index;
+    match_t *matches;
+    long path_count;
+    VALUE paths;
+    VALUE abbrev;
+    VALUE always_show_dot_files;
+    VALUE never_show_dot_files;
+} thread_args_t;
+
+void *match_thread(void *thread_args)
+{
+    long i;
+    thread_args_t *args = (thread_args_t *)thread_args;
+    for (i = args->thread_index; i < args->path_count; i += args->thread_count) {
+        VALUE path = RARRAY_PTR(args->paths)[i];
+        calculate_match(path,
+                        args->abbrev,
+                        args->always_show_dot_files,
+                        args->never_show_dot_files,
+                        &args->matches[i]);
+    }
+
+    return NULL;
+}
+
+
+VALUE CommandTMatcher_sorted_matches_for(int argc, VALUE *argv, VALUE self)
+{
+    long i, limit, path_count, thread_count;
+#ifdef HAVE_PTHREAD_H
+    long err;
+#endif
+    match_t *matches;
+    thread_args_t *thread_args;
+    VALUE abbrev;
+    VALUE always_show_dot_files;
+    VALUE limit_option;
+    VALUE never_show_dot_files;
+    VALUE options;
+    VALUE paths;
+    VALUE results;
+    VALUE scanner;
+    VALUE threads_option;
+
+    // process arguments: 1 mandatory, 1 optional
+    if (rb_scan_args(argc, argv, "11", &abbrev, &options) == 1)
+        options = Qnil;
+    if (NIL_P(abbrev))
+        rb_raise(rb_eArgError, "nil abbrev");
+
+    abbrev = StringValue(abbrev);
+    abbrev = rb_funcall(abbrev, rb_intern("downcase"), 0);
+
+    // check optional options has for overrides
+    limit_option = CommandT_option_from_hash("limit", options);
+    threads_option = CommandT_option_from_hash("threads", options);
+
+    // get unsorted matches
+    scanner = rb_iv_get(self, "@scanner");
+    paths = rb_funcall(scanner, rb_intern("paths"), 0);
+    always_show_dot_files = rb_iv_get(self, "@always_show_dot_files");
+    never_show_dot_files = rb_iv_get(self, "@never_show_dot_files");
+
+    path_count = RARRAY_LEN(paths);
+    matches = malloc(path_count * sizeof(match_t));
+    if (!matches)
+        rb_raise(rb_eNoMemError, "memory allocation failed");
+
+    thread_count = NIL_P(threads_option) ? 1 : NUM2LONG(threads_option);
+
+#ifdef HAVE_PTHREAD_H
+#define THREAD_THRESHOLD 1000 /* avoid the overhead of threading when search space is small */
+    if (path_count < THREAD_THRESHOLD)
+        thread_count = 1;
+    pthread_t *threads = malloc(sizeof(pthread_t) * thread_count);
+    if (!threads)
+        rb_raise(rb_eNoMemError, "memory allocation failed");
+#endif
+
+    thread_args = malloc(sizeof(thread_args_t) * thread_count);
+    if (!thread_args)
+        rb_raise(rb_eNoMemError, "memory allocation failed");
+    for (i = 0; i < thread_count; i++) {
+        thread_args[i].thread_count = thread_count;
+        thread_args[i].thread_index = i;
+        thread_args[i].matches = matches;
+        thread_args[i].path_count = path_count;
+        thread_args[i].paths = paths;
+        thread_args[i].abbrev = abbrev;
+        thread_args[i].always_show_dot_files = always_show_dot_files;
+        thread_args[i].never_show_dot_files = never_show_dot_files;
+
+#ifdef HAVE_PTHREAD_H
+        if (i == thread_count - 1) {
+#endif
+            // for the last "worker", we'll just use the main thread
+            (void)match_thread(&thread_args[i]);
+#ifdef HAVE_PTHREAD_H
+        } else {
+            err = pthread_create(&threads[i], NULL, match_thread, (void *)&thread_args[i]);
+            if (err != 0)
+                rb_raise(rb_eSystemCallError, "pthread_create() failure (%d)", (int)err);
+        }
+#endif
+    }
+
+#ifdef HAVE_PTHREAD_H
+    for (i = 0; i < thread_count - 1; i++) {
+        err = pthread_join(threads[i], NULL);
+        if (err != 0)
+            rb_raise(rb_eSystemCallError, "pthread_join() failure (%d)", (int)err);
+    }
+    free(threads);
+#endif
+
+    if (RSTRING_LEN(abbrev) == 0 ||
+        (RSTRING_LEN(abbrev) == 1 && RSTRING_PTR(abbrev)[0] == '.'))
+        // alphabetic order if search string is only "" or "."
+        qsort(matches, path_count, sizeof(match_t), cmp_alpha);
+    else
+        // for all other non-empty search strings, sort by score
+        qsort(matches, path_count, sizeof(match_t), cmp_score);
+
+    results = rb_ary_new();
+
+    limit = NIL_P(limit_option) ? 0 : NUM2LONG(limit_option);
+    if (limit == 0)
+        limit = path_count;
+    for (i = 0; i < path_count && limit > 0; i++) {
+        if (matches[i].score > 0.0) {
+            rb_funcall(results, rb_intern("push"), 1, matches[i].path);
+            limit--;
+        }
+    }
+
+    free(matches);
+    return results;
+}

+ 27 - 0
vim/ruby/command-t/matcher.h

@@ -0,0 +1,27 @@
+// Copyright 2010-2013 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 <ruby.h>
+
+extern VALUE CommandTMatcher_initialize(int argc, VALUE *argv, VALUE self);
+extern VALUE CommandTMatcher_sorted_matches_for(int argc, VALUE *argv, VALUE self);

BIN
vim/ruby/command-t/matcher.o


+ 92 - 0
vim/ruby/command-t/mkmf.log

@@ -0,0 +1,92 @@
+find_header: checking for float.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <float.h>
+/* end */
+
+--------------------
+
+find_header: checking for ruby.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <ruby.h>
+/* end */
+
+--------------------
+
+find_header: checking for stdlib.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <stdlib.h>
+/* end */
+
+--------------------
+
+find_header: checking for string.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <string.h>
+/* end */
+
+--------------------
+
+have_header: checking for fcntl.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <fcntl.h>
+/* end */
+
+--------------------
+
+have_header: checking for sys/errno.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <sys/errno.h>
+/* end */
+
+--------------------
+
+have_header: checking for sys/socket.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <sys/socket.h>
+/* end */
+
+--------------------
+
+have_header: checking for ruby/st.h... -------------------- no
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+conftest.c:1:21: fatal error: ruby/st.h: No such file or directory
+compilation terminated.
+checked program was:
+/* begin */
+1: #include <ruby/st.h>
+/* end */
+
+--------------------
+
+have_header: checking for st.h... -------------------- yes
+
+"gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -D_FORTIFY_SOURCE=2 -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -g -g -O2  -fPIC    conftest.c -o conftest.i"
+checked program was:
+/* begin */
+1: #include <st.h>
+/* end */
+
+--------------------
+

+ 165 - 0
vim/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

+ 49 - 0
vim/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 <ruby.h>
+
+// 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

+ 28 - 0
vim/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

+ 42 - 0
vim/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

+ 83 - 0
vim/ruby/command-t/scanner/file_scanner.rb

@@ -0,0 +1,83 @@
+# Copyright 2010-2014 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.
+  #
+  # This is an abstract superclass; the real work is done by subclasses which
+  # obtain file listings via different strategies (for examples, see the
+  # RubyFileScanner and FindFileScanner subclasses).
+  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] || 30_000
+      @max_caches           = options[:max_caches] || 1
+      @scan_dot_directories = options[:scan_dot_directories] || false
+      @wild_ignore          = options[:wild_ignore]
+      @base_wild_ignore     = VIM::wild_ignore
+    end
+
+    def paths
+      @paths[@path] || begin
+        ensure_cache_under_limit
+        @prefix_len = @path.chomp('/').length
+        nil
+      end
+    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 set_wild_ignore(ignore)
+      ::VIM::command("set wildignore=#{ignore}") if @wild_ignore
+    end
+  end # class FileScanner
+end # module CommandT

+ 77 - 0
vim/ruby/command-t/scanner/file_scanner/find_file_scanner.rb

@@ -0,0 +1,77 @@
+# Copyright 2014 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 'open3'
+require 'command-t/vim'
+require 'command-t/vim/path_utilities'
+require 'command-t/scanner/file_scanner'
+
+module CommandT
+  class FileScanner
+    # A FileScanner which shells out to the `find` executable in order to scan.
+    class FindFileScanner < FileScanner
+      include VIM::PathUtilities
+
+      def paths
+        super || begin
+          set_wild_ignore(@wild_ignore)
+
+          # temporarily set field separator to NUL byte; this setting is
+          # respected by both `readlines` and `chomp!` below, and makes it easier
+          # to parse the output of `find -print0`
+          separator = $/
+          $/ = "\x00"
+
+          unless @scan_dot_directories
+            dot_directory_filter = [
+              '-not', '-path', "#{@path}/.*/*",           # top-level dot dir
+              '-and', '-not', '-path', "#{@path}/*/.*/*"  # lower-level dot dir
+            ]
+          end
+
+          Open3.popen3(*([
+            'find', '-L',                 # follow symlinks
+            @path,                        # anchor search here
+            '-maxdepth', @max_depth.to_s, # limit depth of DFS
+            '-type', 'f',                 # only show regular files (not dirs etc)
+            dot_directory_filter,         # possibly skip out dot directories
+            '-print0'                     # NUL-terminate results
+          ].flatten.compact)) do |stdin, stdout, stderr|
+            counter = 1
+            paths = []
+            stdout.readlines.each do |line|
+              next if path_excluded?(line.chomp!)
+              paths << line[@prefix_len + 1..-1]
+              break if (counter += 1) > @max_files
+            end
+            @paths[@path] = paths
+          end
+        ensure
+          $/ = separator
+          set_wild_ignore(@base_wild_ignore)
+        end
+        @paths[@path]
+      end
+    end # class FindFileScanner
+  end # class FileScanner
+end # module CommandT

+ 78 - 0
vim/ruby/command-t/scanner/file_scanner/ruby_file_scanner.rb

@@ -0,0 +1,78 @@
+# Copyright 2010-2014 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/file_scanner'
+
+module CommandT
+  class FileScanner
+    # Pure Ruby implementation of a file scanner.
+    class RubyFileScanner < FileScanner
+      def paths
+        super || begin
+          @paths[@path] = []
+          @depth        = 0
+          @files        = 0
+          set_wild_ignore(@wild_ignore)
+          add_paths_for_directory @path, @paths[@path]
+        rescue FileLimitExceeded
+        ensure
+          set_wild_ignore(@base_wild_ignore)
+        end
+        @paths[@path]
+      end
+
+    private
+
+      def looped_symlink? path
+        if File.symlink?(path)
+          target = File.expand_path(File.readlink(path), File.dirname(path))
+          target.include?(@path) || @path.include?(target)
+        end
+      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)
+              next if looped_symlink?(path)
+              @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 RubyFileScanner
+  end # class FileScanner
+end # module CommandT

+ 82 - 0
vim/ruby/command-t/scanner/file_scanner/watchman_file_scanner.rb

@@ -0,0 +1,82 @@
+# Copyright 2014 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 'pathname'
+require 'socket'
+require 'command-t/vim'
+require 'command-t/vim/path_utilities'
+require 'command-t/scanner/file_scanner'
+require 'command-t/scanner/file_scanner/find_file_scanner'
+
+module CommandT
+  class FileScanner
+    # A FileScanner which delegates the heavy lifting to Watchman
+    # (https://github.com/facebook/watchman); useful for very large hierarchies.
+    #
+    # Inherits from FindFileScanner so that it can fall back to it in the event
+    # that Watchman isn't available or able to fulfil the request.
+    class WatchmanFileScanner < FindFileScanner
+      # Exception raised when Watchman is unavailable or unable to process the
+      # requested path.
+      class WatchmanUnavailable < RuntimeError; end
+
+      def paths
+        @paths[@path] ||= begin
+          ensure_cache_under_limit
+          sockname = Watchman::Utils.load(
+            %x{watchman --output-encoding=bser get-sockname}
+          )['sockname']
+          raise WatchmanUnavailable unless $?.exitstatus.zero?
+
+          UNIXSocket.open(sockname) do |socket|
+            root = Pathname.new(@path).realpath.to_s
+            roots = Watchman::Utils.query(['watch-list'], socket)['roots']
+            if !roots.include?(root)
+              # this path isn't being watched yet; try to set up watch
+              result = Watchman::Utils.query(['watch', root], socket)
+
+              # root_restrict_files setting may prevent Watchman from working
+              raise WatchmanUnavailable if result.has_key?('error')
+            end
+
+            query = ['query', root, {
+              'expression' => ['type', 'f'],
+              'fields'     => ['name'],
+            }]
+            paths = Watchman::Utils.query(query, socket)
+
+            # could return error if watch is removed
+            raise WatchmanUnavailable if paths.has_key?('error')
+
+            @paths[@path] = paths['files']
+          end
+        end
+
+        @paths[@path]
+      rescue Errno::ENOENT, WatchmanUnavailable
+        # watchman executable not present, or unable to fulfil request
+        super
+      end
+    end # class WatchmanFileScanner
+  end # class FileScanner
+end # module CommandT

+ 54 - 0
vim/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

+ 49 - 0
vim/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

+ 128 - 0
vim/ruby/command-t/settings.rb

@@ -0,0 +1,128 @@
+# Copyright 2010-2014 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
+    # Settings which apply globally and so must be manually saved and restored
+    GLOBAL_SETTINGS = %w[
+      equalalways
+      hlsearch
+      insertmode
+      report
+      showcmd
+      sidescroll
+      sidescrolloff
+      timeout
+      timeoutlen
+      updatetime
+    ]
+
+    # Settings which can be made locally to the Command-T buffer or window
+    LOCAL_SETTINGS = %w[
+      bufhidden
+      buflisted
+      buftype
+      colorcolumn
+      concealcursor
+      conceallevel
+      cursorline
+      foldcolumn
+      foldlevel
+      list
+      modifiable
+      number
+      relativenumber
+      spell
+      swapfile
+      synmaxcol
+      textwidth
+      wrap
+    ]
+
+    KNOWN_SETTINGS = GLOBAL_SETTINGS + LOCAL_SETTINGS
+
+    def initialize
+      @settings = []
+    end
+
+    def set(setting, value)
+      raise "Unknown setting #{setting}" unless KNOWN_SETTINGS.include?(setting)
+
+      case value
+      when TrueClass, FalseClass
+        @settings.push([setting, get_bool(setting)]) if global?(setting)
+        set_bool setting, value
+      when Numeric
+        @settings.push([setting, get_number(setting)]) if global?(setting)
+        set_number setting, value
+      when String
+        @settings.push([setting, get_string(setting)]) if global?(setting)
+        set_string setting, value
+      end
+    end
+
+    def restore
+      @settings.each do |setting, value|
+        case value
+        when TrueClass, FalseClass
+          set_bool setting, value
+        when Numeric
+          set_number setting, value
+        when String
+          set_string setting, value
+        end
+      end
+    end
+
+  private
+
+    def global?(setting)
+      GLOBAL_SETTINGS.include?(setting)
+    end
+
+    def get_bool(setting)
+      ::VIM::evaluate("&#{setting}").to_i == 1
+    end
+
+    def get_number(setting)
+      ::VIM::evaluate("&#{setting}").to_i
+    end
+
+    def get_string(name)
+      ::VIM::evaluate("&#{name}").to_s
+    end
+
+    def set_bool(setting, value)
+      command = global?(setting) ? 'set' : 'setlocal'
+      setting = value ? setting : "no#{setting}"
+      ::VIM::command "#{command} #{setting}"
+    end
+
+    def set_number(setting, value)
+      command = global?(setting) ? 'set' : 'setlocal'
+      ::VIM::command "#{command} #{setting}=#{value}"
+    end
+    alias set_string set_number
+  end # class Settings
+end # module CommandT

+ 42 - 0
vim/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

+ 114 - 0
vim/ruby/command-t/util.rb

@@ -0,0 +1,114 @@
+# Copyright 2013-2014 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 'rbconfig'
+
+module CommandT
+  module Util
+    class << self
+      def processor_count
+        @processor_count ||= begin
+          count = processor_count!
+          count = 1 if count < 1   # sanity check
+          count = 32 if count > 32 # sanity check
+          count
+        end
+      end
+
+    private
+
+      # This method derived from:
+      #
+      #   https://github.com/grosser/parallel/blob/d11e4a3c8c1a/lib/parallel.rb
+      #
+      # Number of processors seen by the OS and used for process scheduling.
+      #
+      # * AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
+      # * BSD: /sbin/sysctl
+      # * Cygwin: /proc/cpuinfo
+      # * Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
+      # * HP-UX: /usr/sbin/ioscan
+      # * IRIX: /usr/sbin/sysconf
+      # * Linux: /proc/cpuinfo
+      # * Minix 3+: /proc/cpuinfo
+      # * Solaris: /usr/sbin/psrinfo
+      # * Tru64 UNIX: /usr/sbin/psrinfo
+      # * UnixWare: /usr/sbin/psrinfo
+      #
+      # Copyright (C) 2013 Michael Grosser <michael@grosser.it>
+      #
+      # Permission is hereby granted, free of charge, to any person obtaining
+      # a copy of this software and associated documentation files (the
+      # "Software"), to deal in the Software without restriction, including
+      # without limitation the rights to use, copy, modify, merge, publish,
+      # distribute, sublicense, and/or sell copies of the Software, and to
+      # permit persons to whom the Software is furnished to do so, subject to
+      # the following conditions:
+      #
+      # The above copyright notice and this permission notice shall be
+      # included in all copies or substantial portions of the Software.
+      #
+      # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+      # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+      # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+      # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+      # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+      # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+      #
+      def processor_count!
+        os_name = RbConfig::CONFIG['target_os']
+        if os_name =~ /mingw|mswin/
+          require 'win32ole'
+          result = WIN32OLE.connect('winmgmts://').ExecQuery(
+              'select NumberOfLogicalProcessors from Win32_Processor')
+          result.to_enum.collect(&:NumberOfLogicalProcessors).reduce(:+)
+        elsif File.readable?('/proc/cpuinfo')
+          IO.read('/proc/cpuinfo').scan(/^processor/).size
+        elsif File.executable?('/usr/bin/hwprefs')
+          IO.popen(%w[/usr/bin/hwprefs thread_count]).read.to_i
+        elsif File.executable?('/usr/sbin/psrinfo')
+          IO.popen('/usr/sbin/psrinfo').read.scan(/^.*on-*line/).size
+        elsif File.executable?('/usr/sbin/ioscan')
+          IO.popen(%w[/usr/sbin/ioscan -kC processor]) do |out|
+            out.read.scan(/^.*processor/).size
+          end
+        elsif File.executable?('/usr/sbin/pmcycles')
+          IO.popen(%w[/usr/sbin/pmcycles -m]).read.count("\n")
+        elsif File.executable?('/usr/sbin/lsdev')
+          IO.popen(%w[/usr/sbin/lsdev -Cc processor -S 1]).read.count("\n")
+        elsif File.executable?('/usr/sbin/sysconf') and os_name =~ /irix/i
+          IO.popen(%w[/usr/sbin/sysconf NPROC_ONLN]).read.to_i
+        elsif File.executable?('/usr/sbin/sysctl')
+          IO.popen(%w[/usr/sbin/sysctl -n hw.ncpu]).read.to_i
+        elsif File.executable?('/sbin/sysctl')
+          IO.popen(%w[/sbin/sysctl -n hw.ncpu]).read.to_i
+        else # unknown platform
+          1
+        end
+      rescue
+        1
+      end
+    end
+  end # module Util
+end # module commandT

+ 63 - 0
vim/ruby/command-t/vim.rb

@@ -0,0 +1,63 @@
+# Copyright 2010-2013 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
+
+    def self.wild_ignore
+      exists?('&wildignore') && ::VIM::evaluate('&wildignore').to_s
+    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

+ 40 - 0
vim/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

+ 32 - 0
vim/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

+ 38 - 0
vim/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

+ 660 - 0
vim/ruby/command-t/watchman.c

@@ -0,0 +1,660 @@
+// Copyright 2014 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 "watchman.h"
+
+#ifdef WATCHMAN_BUILD
+
+#if defined(HAVE_RUBY_ST_H)
+#include <ruby/st.h>
+#elif defined(HAVE_ST_H)
+#include <st.h>
+#else
+#error no st.h header found
+#endif
+
+#include <fcntl.h>      /* for fcntl() */
+#include <sys/errno.h>  /* for errno */
+#include <sys/socket.h> /* for recv(), MSG_PEEK */
+
+typedef struct {
+    uint8_t *data;  // payload
+    size_t cap;     // total capacity
+    size_t len;     // current length
+} watchman_t;
+
+// Forward declarations:
+VALUE watchman_load(char **ptr, char *end);
+void watchman_dump(watchman_t *w, VALUE serializable);
+
+/**
+ * Inspect a ruby object (debugging aid)
+ */
+#define ruby_inspect(obj) rb_funcall(rb_mKernel, rb_intern("p"), 1, obj)
+
+/**
+ * Print `count` bytes of memory at `address` (debugging aid)
+ */
+#define dump(address, count) \
+    do { \
+        for (int i = 0; i < count; i++) { \
+            printf("%02x ", ((unsigned char *)address)[i]); printf("\n"); \
+        } \
+    } while(0)
+
+#define WATCHMAN_DEFAULT_STORAGE 4096
+
+#define WATCHMAN_BINARY_MARKER   "\x00\x01"
+#define WATCHMAN_ARRAY_MARKER    0x00
+#define WATCHMAN_HASH_MARKER     0x01
+#define WATCHMAN_STRING_MARKER   0x02
+#define WATCHMAN_INT8_MARKER     0x03
+#define WATCHMAN_INT16_MARKER    0x04
+#define WATCHMAN_INT32_MARKER    0x05
+#define WATCHMAN_INT64_MARKER    0x06
+#define WATCHMAN_FLOAT_MARKER    0x07
+#define WATCHMAN_TRUE            0x08
+#define WATCHMAN_FALSE           0x09
+#define WATCHMAN_NIL             0x0a
+#define WATCHMAN_TEMPLATE_MARKER 0x0b
+#define WATCHMAN_SKIP_MARKER     0x0c
+
+#define WATCHMAN_HEADER \
+        WATCHMAN_BINARY_MARKER \
+        "\x06" \
+        "\x00\x00\x00\x00\x00\x00\x00\x00"
+
+static const char watchman_array_marker  = WATCHMAN_ARRAY_MARKER;
+static const char watchman_hash_marker   = WATCHMAN_HASH_MARKER;
+static const char watchman_string_marker = WATCHMAN_STRING_MARKER;
+static const char watchman_true          = WATCHMAN_TRUE;
+static const char watchman_false         = WATCHMAN_FALSE;
+static const char watchman_nil           = WATCHMAN_NIL;
+
+/**
+ * Appends `len` bytes, starting at `data`, to the watchman_t struct `w`
+ *
+ * Will attempt to reallocate the underlying storage if it is not sufficient.
+ */
+void watchman_append(watchman_t *w, const char *data, size_t len) {
+    if (w->len + len > w->cap) {
+        w->cap += w->len + WATCHMAN_DEFAULT_STORAGE;
+        REALLOC_N(w->data, uint8_t, w->cap);
+    }
+    memcpy(w->data + w->len, data, len);
+    w->len += len;
+}
+
+/**
+ * Allocate a new watchman_t struct
+ *
+ * The struct has a small amount of extra capacity preallocated, and a blank
+ * header that can be filled in later to describe the PDU.
+ */
+watchman_t *watchman_init() {
+    watchman_t *w = ALLOC(watchman_t);
+    w->cap = WATCHMAN_DEFAULT_STORAGE;
+    w->len = 0;
+    w->data = ALLOC_N(uint8_t, WATCHMAN_DEFAULT_STORAGE);
+
+    watchman_append(w, WATCHMAN_HEADER, sizeof(WATCHMAN_HEADER) - 1);
+    return w;
+}
+
+/**
+ * Free a watchman_t struct `w` that was previously allocated with
+ * `watchman_init`
+ */
+void watchman_free(watchman_t *w) {
+    xfree(w->data);
+    xfree(w);
+}
+
+/**
+ * Encodes and appends the integer `num` to `w`
+ */
+void watchman_dump_int(watchman_t *w, int64_t num) {
+    char encoded[1 + sizeof(int64_t)];
+
+    if (num == (int8_t)num) {
+        encoded[0] = WATCHMAN_INT8_MARKER;
+        encoded[1] = (int8_t)num;
+        watchman_append(w, encoded, 1 + sizeof(int8_t));
+    } else if (num == (int16_t)num) {
+        encoded[0] = WATCHMAN_INT16_MARKER;
+        *(int16_t *)(encoded + 1) = (int16_t)num;
+        watchman_append(w, encoded, 1 + sizeof(int16_t));
+    } else if (num == (int32_t)num) {
+        encoded[0] = WATCHMAN_INT32_MARKER;
+        *(int32_t *)(encoded + 1) = (int32_t)num;
+        watchman_append(w, encoded, 1 + sizeof(int32_t));
+    } else {
+        encoded[0] = WATCHMAN_INT64_MARKER;
+        *(int64_t *)(encoded + 1) = (int64_t)num;
+        watchman_append(w, encoded, 1 + sizeof(int64_t));
+    }
+}
+
+/**
+ * Encodes and appends the string `string` to `w`
+ */
+void watchman_dump_string(watchman_t *w, VALUE string) {
+    watchman_append(w, &watchman_string_marker, sizeof(watchman_string_marker));
+    watchman_dump_int(w, RSTRING_LEN(string));
+    watchman_append(w, RSTRING_PTR(string), RSTRING_LEN(string));
+}
+
+/**
+ * Encodes and appends the double `num` to `w`
+ */
+void watchman_dump_double(watchman_t *w, double num) {
+    char encoded[1 + sizeof(double)];
+    encoded[0] = WATCHMAN_FLOAT_MARKER;
+    *(double *)(encoded + 1) = num;
+    watchman_append(w, encoded, sizeof(encoded));
+}
+
+/**
+ * Encodes and appends the array `array` to `w`
+ */
+void watchman_dump_array(watchman_t *w, VALUE array) {
+    long i;
+    watchman_append(w, &watchman_array_marker, sizeof(watchman_array_marker));
+    watchman_dump_int(w, RARRAY_LEN(array));
+    for (i = 0; i < RARRAY_LEN(array); i++) {
+        watchman_dump(w, rb_ary_entry(array, i));
+    }
+}
+
+/**
+ * Helper method that encodes and appends a key/value pair (`key`, `value`) from
+ * a hash to the watchman_t struct passed in via `data`
+ */
+int watchman_dump_hash_iterator(VALUE key, VALUE value, VALUE data) {
+    watchman_t *w = (watchman_t *)data;
+    watchman_dump_string(w, StringValue(key));
+    watchman_dump(w, value);
+    return ST_CONTINUE;
+}
+
+/**
+ * Encodes and appends the hash `hash` to `w`
+ */
+void watchman_dump_hash(watchman_t *w, VALUE hash) {
+    watchman_append(w, &watchman_hash_marker, sizeof(watchman_hash_marker));
+    watchman_dump_int(w, RHASH_SIZE(hash));
+    rb_hash_foreach(hash, watchman_dump_hash_iterator, (VALUE)w);
+}
+
+/**
+ * Encodes and appends the serialized Ruby object `serializable` to `w`
+ *
+ * Examples of serializable objects include arrays, hashes, strings, numbers
+ * (integers, floats), booleans, and nil.
+ */
+void watchman_dump(watchman_t *w, VALUE serializable) {
+    switch (TYPE(serializable)) {
+        case T_ARRAY:
+            return watchman_dump_array(w, serializable);
+        case T_HASH:
+            return watchman_dump_hash(w, serializable);
+        case T_STRING:
+            return watchman_dump_string(w, serializable);
+        case T_FIXNUM: // up to 63 bits
+            return watchman_dump_int(w, FIX2LONG(serializable));
+        case T_BIGNUM:
+            return watchman_dump_int(w, NUM2LL(serializable));
+        case T_FLOAT:
+            return watchman_dump_double(w, NUM2DBL(serializable));
+        case T_TRUE:
+            return watchman_append(w, &watchman_true, sizeof(watchman_true));
+        case T_FALSE:
+            return watchman_append(w, &watchman_false, sizeof(watchman_false));
+        case T_NIL:
+            return watchman_append(w, &watchman_nil, sizeof(watchman_nil));
+        default:
+            rb_raise(rb_eTypeError, "unsupported type");
+    }
+}
+
+/**
+ * Extract and return the int encoded at `ptr`
+ *
+ * Moves `ptr` past the extracted int.
+ *
+ * Will raise an ArgumentError if extracting the int would take us beyond the
+ * end of the buffer indicated by `end`, or if there is no int encoded at `ptr`.
+ *
+ * @returns The extracted int
+ */
+int64_t watchman_load_int(char **ptr, char *end) {
+    char *val_ptr = *ptr + sizeof(int8_t);
+    int64_t val = 0;
+
+    if (val_ptr >= end) {
+        rb_raise(rb_eArgError, "insufficient int storage");
+    }
+
+    switch (*ptr[0]) {
+        case WATCHMAN_INT8_MARKER:
+            if (val_ptr + sizeof(int8_t) > end) {
+                rb_raise(rb_eArgError, "overrun extracting int8_t");
+            }
+            val = *(int8_t *)val_ptr;
+            *ptr = val_ptr + sizeof(int8_t);
+            break;
+        case WATCHMAN_INT16_MARKER:
+            if (val_ptr + sizeof(int16_t) > end) {
+                rb_raise(rb_eArgError, "overrun extracting int16_t");
+            }
+            val = *(int16_t *)val_ptr;
+            *ptr = val_ptr + sizeof(int16_t);
+            break;
+        case WATCHMAN_INT32_MARKER:
+            if (val_ptr + sizeof(int32_t) > end) {
+                rb_raise(rb_eArgError, "overrun extracting int32_t");
+            }
+            val = *(int32_t *)val_ptr;
+            *ptr = val_ptr + sizeof(int32_t);
+            break;
+        case WATCHMAN_INT64_MARKER:
+            if (val_ptr + sizeof(int64_t) > end) {
+                rb_raise(rb_eArgError, "overrun extracting int64_t");
+            }
+            val = *(int64_t *)val_ptr;
+            *ptr = val_ptr + sizeof(int64_t);
+            break;
+        default:
+            rb_raise(rb_eArgError, "bad integer marker 0x%02x", (unsigned int)*ptr[0]);
+            break;
+    }
+
+    return val;
+}
+
+/**
+ * Reads and returns a string encoded in the Watchman binary protocol format,
+ * starting at `ptr` and finishing at or before `end`
+ */
+VALUE watchman_load_string(char **ptr, char *end) {
+    if (*ptr >= end) {
+        rb_raise(rb_eArgError, "unexpected end of input");
+    }
+
+    if (*ptr[0] != WATCHMAN_STRING_MARKER) {
+        rb_raise(rb_eArgError, "not a number");
+    }
+
+    *ptr += sizeof(int8_t);
+    if (*ptr >= end) {
+        rb_raise(rb_eArgError, "invalid string header");
+    }
+
+    int64_t len = watchman_load_int(ptr, end);
+    if (len == 0) { // special case for zero-length strings
+        return rb_str_new2("");
+    } else if (*ptr + len > end) {
+        rb_raise(rb_eArgError, "insufficient string storage");
+    }
+
+    VALUE string = rb_str_new(*ptr, len);
+    *ptr += len;
+    return string;
+}
+
+/**
+ * Reads and returns a double encoded in the Watchman binary protocol format,
+ * starting at `ptr` and finishing at or before `end`
+ */
+double watchman_load_double(char **ptr, char *end) {
+    *ptr += sizeof(int8_t); // caller has already verified the marker
+    if (*ptr + sizeof(double) > end) {
+        rb_raise(rb_eArgError, "insufficient double storage");
+    }
+    double val = *(double *)*ptr;
+    *ptr += sizeof(double);
+    return val;
+}
+
+/**
+ * Helper method which returns length of the array encoded in the Watchman
+ * binary protocol format, starting at `ptr` and finishing at or before `end`
+ */
+int64_t watchman_load_array_header(char **ptr, char *end) {
+    if (*ptr >= end) {
+        rb_raise(rb_eArgError, "unexpected end of input");
+    }
+
+    // verify and consume marker
+    if (*ptr[0] != WATCHMAN_ARRAY_MARKER) {
+        rb_raise(rb_eArgError, "not an array");
+    }
+    *ptr += sizeof(int8_t);
+
+    // expect a count
+    if (*ptr + sizeof(int8_t) * 2 > end) {
+        rb_raise(rb_eArgError, "incomplete array header");
+    }
+    return watchman_load_int(ptr, end);
+}
+
+/**
+ * Reads and returns an array encoded in the Watchman binary protocol format,
+ * starting at `ptr` and finishing at or before `end`
+ */
+VALUE watchman_load_array(char **ptr, char *end) {
+    int64_t count, i;
+    VALUE array;
+
+    count = watchman_load_array_header(ptr, end);
+    array = rb_ary_new2(count);
+
+    for (i = 0; i < count; i++) {
+        rb_ary_push(array, watchman_load(ptr, end));
+    }
+
+    return array;
+}
+
+/**
+ * Reads and returns a hash encoded in the Watchman binary protocol format,
+ * starting at `ptr` and finishing at or before `end`
+ */
+VALUE watchman_load_hash(char **ptr, char *end) {
+    int64_t count, i;
+    VALUE hash, key, value;
+
+    *ptr += sizeof(int8_t); // caller has already verified the marker
+
+    // expect a count
+    if (*ptr + sizeof(int8_t) * 2 > end) {
+        rb_raise(rb_eArgError, "incomplete hash header");
+    }
+    count = watchman_load_int(ptr, end);
+
+    hash = rb_hash_new();
+
+    for (i = 0; i < count; i++) {
+        key = watchman_load_string(ptr, end);
+        value = watchman_load(ptr, end);
+        rb_hash_aset(hash, key, value);
+    }
+
+    return hash;
+}
+
+/**
+ * Reads and returns a templated array encoded in the Watchman binary protocol
+ * format, starting at `ptr` and finishing at or before `end`
+ *
+ * Templated arrays are arrays of hashes which have repetitive key information
+ * pulled out into a separate "headers" prefix.
+ *
+ * @see https://github.com/facebook/watchman/blob/master/BSER.markdown
+ */
+VALUE watchman_load_template(char **ptr, char *end) {
+    int64_t header_items_count, i, row_count;
+    VALUE array, hash, header, key, value;
+
+    *ptr += sizeof(int8_t); // caller has already verified the marker
+
+    // process template header array
+    header_items_count = watchman_load_array_header(ptr, end);
+    header = rb_ary_new2(header_items_count);
+    for (i = 0; i < header_items_count; i++) {
+        rb_ary_push(header, watchman_load_string(ptr, end));
+    }
+
+    // process row items
+    row_count = watchman_load_int(ptr, end);
+    array = rb_ary_new2(header_items_count);
+    while (row_count--) {
+        hash = rb_hash_new();
+        for (i = 0; i < header_items_count; i++) {
+            if (*ptr >= end) {
+                rb_raise(rb_eArgError, "unexpected end of input");
+            }
+
+            if (*ptr[0] == WATCHMAN_SKIP_MARKER) {
+                *ptr += sizeof(uint8_t);
+            } else {
+                value = watchman_load(ptr, end);
+                key = rb_ary_entry(header, i);
+                rb_hash_aset(hash, key, value);
+            }
+        }
+        rb_ary_push(array, hash);
+    }
+    return array;
+}
+
+/**
+ * Reads and returns an object encoded in the Watchman binary protocol format,
+ * starting at `ptr` and finishing at or before `end`
+ */
+VALUE watchman_load(char **ptr, char *end) {
+    if (*ptr >= end) {
+        rb_raise(rb_eArgError, "unexpected end of input");
+    }
+
+    switch (*ptr[0]) {
+        case WATCHMAN_ARRAY_MARKER:
+            return watchman_load_array(ptr, end);
+        case WATCHMAN_HASH_MARKER:
+            return watchman_load_hash(ptr, end);
+        case WATCHMAN_STRING_MARKER:
+            return watchman_load_string(ptr, end);
+        case WATCHMAN_INT8_MARKER:
+        case WATCHMAN_INT16_MARKER:
+        case WATCHMAN_INT32_MARKER:
+        case WATCHMAN_INT64_MARKER:
+            return LL2NUM(watchman_load_int(ptr, end));
+        case WATCHMAN_FLOAT_MARKER:
+            return rb_float_new(watchman_load_double(ptr, end));
+        case WATCHMAN_TRUE:
+            *ptr += 1;
+            return Qtrue;
+        case WATCHMAN_FALSE:
+            *ptr += 1;
+            return Qfalse;
+        case WATCHMAN_NIL:
+            *ptr += 1;
+            return Qnil;
+        case WATCHMAN_TEMPLATE_MARKER:
+            return watchman_load_template(ptr, end);
+        default:
+            rb_raise(rb_eTypeError, "unsupported type");
+    }
+
+    return Qnil; // keep the compiler happy
+}
+
+/**
+ * CommandT::Watchman::Utils.load(serialized)
+ *
+ * Converts the binary object, `serialized`, from the Watchman binary protocol
+ * format into a normal Ruby object.
+ */
+VALUE CommandTWatchmanUtils_load(VALUE self, VALUE serialized) {
+    serialized = StringValue(serialized);
+    long len = RSTRING_LEN(serialized);
+    char *ptr = RSTRING_PTR(serialized);
+    char *end = ptr + len;
+
+    // expect at least the binary marker and a int8_t length counter
+    if ((size_t)len < sizeof(WATCHMAN_BINARY_MARKER) - 1 + sizeof(int8_t) * 2) {
+        rb_raise(rb_eArgError, "undersized header");
+    }
+
+    if (memcmp(ptr, WATCHMAN_BINARY_MARKER, sizeof(WATCHMAN_BINARY_MARKER) - 1)) {
+        rb_raise(rb_eArgError, "missing binary marker");
+    }
+
+    // get size marker
+    ptr += sizeof(WATCHMAN_BINARY_MARKER) - 1;
+    uint64_t payload_size = watchman_load_int(&ptr, end);
+    if (!payload_size) {
+        rb_raise(rb_eArgError, "empty payload");
+    }
+
+    // sanity check length
+    if (ptr + payload_size != end) {
+        rb_raise(rb_eArgError, "payload size mismatch (%lu)", end - (ptr + payload_size));
+    }
+
+    VALUE loaded = watchman_load(&ptr, end);
+
+    // one more sanity check
+    if (ptr != end) {
+        rb_raise(rb_eArgError, "payload termination mismatch (%lu)", end - ptr);
+    }
+
+    return loaded;
+}
+
+/**
+ * CommandT::Watchman::Utils.dump(serializable)
+ *
+ * Converts the Ruby object, `serializable`, into a binary string in the
+ * Watchman binary protocol format.
+ *
+ * Examples of serializable objects include arrays, hashes, strings, numbers
+ * (integers, floats), booleans, and nil.
+ */
+VALUE CommandTWatchmanUtils_dump(VALUE self, VALUE serializable) {
+    watchman_t *w = watchman_init();
+    watchman_dump(w, serializable);
+
+    // update header with final length information
+    uint64_t *len = (uint64_t *)(w->data + sizeof(WATCHMAN_HEADER) - sizeof(uint64_t) - 1);
+    *len = w->len - sizeof(WATCHMAN_HEADER) + 1;
+
+    // prepare final return value
+    VALUE serialized = rb_str_buf_new(w->len);
+    rb_str_buf_cat(serialized, (const char*)w->data, w->len);
+    watchman_free(w);
+    return serialized;
+}
+
+/**
+ * Helper method for raising a SystemCallError wrapping a lower-level error code
+ * coming from the `errno` global variable.
+ */
+void watchman_raise_system_call_error(int number) {
+    VALUE error = INT2FIX(number);
+    rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
+}
+
+// How far we have to look to figure out the size of the PDU header
+#define WATCHMAN_SNIFF_BUFFER_SIZE sizeof(WATCHMAN_BINARY_MARKER) - 1 + sizeof(int8_t)
+
+// How far we have to peek, at most, to figure out the size of the PDU itself
+#define WATCHMAN_PEEK_BUFFER_SIZE \
+    sizeof(WATCHMAN_BINARY_MARKER) - 1 + \
+    sizeof(WATCHMAN_INT64_MARKER) + \
+    sizeof(int64_t)
+
+/**
+ * CommandT::Watchman::Utils.query(query, socket)
+ *
+ * Converts `query`, a Watchman query comprising Ruby objects, into the Watchman
+ * binary protocol format, transmits it over socket, and unserializes and
+ * returns the result.
+ */
+VALUE CommandTWatchmanUtils_query(VALUE self, VALUE query, VALUE socket) {
+    int fileno = NUM2INT(rb_funcall(socket, rb_intern("fileno"), 0));
+
+    // do blocking I/O to simplify the following logic
+    int flags = fcntl(fileno, F_GETFL);
+    if (fcntl(fileno, F_SETFL, flags & ~O_NONBLOCK) == -1) {
+        rb_raise(rb_eRuntimeError, "unable to clear O_NONBLOCK flag");
+    }
+
+    // send the message
+    VALUE serialized = CommandTWatchmanUtils_dump(self, query);
+    long query_len = RSTRING_LEN(serialized);
+    ssize_t sent = send(fileno, RSTRING_PTR(serialized), query_len, 0);
+    if (sent == -1) {
+        watchman_raise_system_call_error(errno);
+    } else if (sent != query_len) {
+        rb_raise(rb_eRuntimeError, "expected to send %ld bytes but sent %ld",
+            query_len, sent);
+    }
+
+    // sniff to see how large the header is
+    int8_t peek[WATCHMAN_PEEK_BUFFER_SIZE];
+    ssize_t received = recv(fileno, peek, WATCHMAN_SNIFF_BUFFER_SIZE, MSG_PEEK | MSG_WAITALL);
+    if (received == -1) {
+        watchman_raise_system_call_error(errno);
+    } else if (received != WATCHMAN_SNIFF_BUFFER_SIZE) {
+        rb_raise(rb_eRuntimeError, "failed to sniff PDU header");
+    }
+
+    // peek at size of PDU
+    int8_t sizes[] = { 0, 0, 0, 1, 2, 4, 8 };
+    ssize_t peek_size = sizeof(WATCHMAN_BINARY_MARKER) - 1 + sizeof(int8_t) +
+        sizes[peek[sizeof(WATCHMAN_BINARY_MARKER) - 1]];
+
+    received = recv(fileno, peek, peek_size, MSG_PEEK);
+    if (received == -1) {
+        watchman_raise_system_call_error(errno);
+    } else if (received != peek_size) {
+        rb_raise(rb_eRuntimeError, "failed to peek at PDU header");
+    }
+    int8_t *pdu_size_ptr = peek + sizeof(WATCHMAN_BINARY_MARKER) - sizeof(int8_t);
+    int64_t payload_size =
+        peek_size +
+        watchman_load_int((char **)&pdu_size_ptr, (char *)peek + peek_size);
+
+    // actually read the PDU
+    void *buffer = xmalloc(payload_size);
+    if (!buffer) {
+        rb_raise(rb_eNoMemError, "failed to allocate %lld bytes", payload_size);
+    }
+    received = recv(fileno, buffer, payload_size, MSG_WAITALL);
+    if (received == -1) {
+        watchman_raise_system_call_error(errno);
+    } else if (received != payload_size) {
+        rb_raise(rb_eRuntimeError, "failed to load PDU");
+    }
+    char *payload = buffer + peek_size;
+    VALUE loaded = watchman_load(&payload, payload + payload_size);
+    free(buffer);
+    return loaded;
+}
+
+#else /* don't build Watchman utils; supply stubs only*/
+
+VALUE CommandTWatchmanUtils_load(VALUE self, VALUE serialized) {
+    rb_raise(rb_eRuntimeError, "unsupported operation");
+}
+
+VALUE CommandTWatchmanUtils_dump(VALUE self, VALUE serializable) {
+    rb_raise(rb_eRuntimeError, "unsupported operation");
+}
+
+VALUE CommandTWatchmanUtils_query(VALUE self, VALUE query, VALUE socket) {
+    rb_raise(rb_eRuntimeError, "unsupported operation");
+}
+
+#endif

+ 52 - 0
vim/ruby/command-t/watchman.h

@@ -0,0 +1,52 @@
+// Copyright 2014 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 <ruby.h>
+
+/**
+ * @module CommandT::Watchman::Utils
+ *
+ * Methods for working with the Watchman binary protocol
+ *
+ * @see https://github.com/facebook/watchman/blob/master/BSER.markdown
+ */
+
+/**
+ * Convert an object serialized using the Watchman binary protocol[0] into an
+ * unpacked Ruby object
+ */
+extern VALUE CommandTWatchmanUtils_load(VALUE self, VALUE serialized);
+
+/**
+ * Serialize a Ruby object into the Watchman binary protocol format
+ */
+extern VALUE CommandTWatchmanUtils_dump(VALUE self, VALUE serializable);
+
+/**
+ * Issue `query` to the Watchman instance listening on `socket` (a `UNIXSocket`
+ * instance) and return the result
+ *
+ * The query is serialized following the Watchman binary protocol and the
+ * result is converted to native Ruby objects before returning to the caller.
+ */
+extern VALUE CommandTWatchmanUtils_query(VALUE self, VALUE query, VALUE socket);

BIN
vim/ruby/command-t/watchman.o


+ 7 - 0
vim/snippets/_.snippets

@@ -0,0 +1,7 @@
+# Global snippets
+
+# (c) holds no legal value ;)
+snippet c)
+	`&enc[:2] == "utf" ? "©" : "(c)"` Copyright `strftime("%Y")` ${1:`g:snips_author`}. All Rights Reserved.${2}
+snippet date
+	`strftime("%Y-%m-%d")`

+ 66 - 0
vim/snippets/autoit.snippets

@@ -0,0 +1,66 @@
+snippet if
+	If ${1:condition} Then
+		${2:; True code}
+	EndIf
+snippet el
+	Else
+		${1}
+snippet elif
+	ElseIf ${1:condition} Then
+		${2:; True code}
+# If/Else block
+snippet ifel
+	If ${1:condition} Then
+		${2:; True code}
+	Else
+		${3:; Else code}
+	EndIf
+# If/ElseIf/Else block
+snippet ifelif
+	If ${1:condition 1} Then
+		${2:; True code}
+	ElseIf ${3:condition 2} Then
+		${4:; True code}
+	Else
+		${5:; Else code}
+	EndIf
+# Switch block
+snippet switch
+	Switch (${1:condition})
+	Case {$2:case1}:
+		{$3:; Case 1 code}
+	Case Else:
+		{$4:; Else code}
+	EndSwitch
+# Select block
+snippet select
+	Select (${1:condition})
+	Case {$2:case1}:
+		{$3:; Case 1 code}
+	Case Else:
+		{$4:; Else code}
+	EndSelect
+# While loop
+snippet while
+	While (${1:condition})
+		${2:; code...}
+	WEnd
+# For loop
+snippet for
+	For ${1:n} = ${3:1} to ${2:count}
+		${4:; code...}
+	Next
+# New Function
+snippet func
+	Func ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
+		${4:Return}
+	EndFunc
+# Message box
+snippet msg
+	MsgBox(${3:MsgType}, ${1:"Title"}, ${2:"Message Text"})
+# Debug Message
+snippet debug
+	MsgBox(0, "Debug", ${1:"Debug Message"})
+# Show Variable Debug Message
+snippet showvar
+	MsgBox(0, "${1:VarName}", $1)

+ 110 - 0
vim/snippets/c.snippets

@@ -0,0 +1,110 @@
+# main()
+snippet main
+	int main(int argc, const char *argv[])
+	{
+		${1}
+		return 0;
+	}
+# #include <...>
+snippet inc
+	#include <${1:stdio}.h>${2}
+# #include "..."
+snippet Inc
+	#include "${1:`Filename("$1.h")`}"${2}
+# #ifndef ... #define ... #endif
+snippet Def
+	#ifndef $1
+	#define ${1:SYMBOL} ${2:value}
+	#endif${3}
+snippet def
+	#define 
+snippet ifdef
+	#ifdef ${1:FOO}
+		${2:#define }
+	#endif
+snippet #if
+	#if ${1:FOO}
+		${2}
+	#endif
+# Header Include-Guard
+# (the randomizer code is taken directly from TextMate; it could probably be
+# cleaner, I don't know how to do it in vim script)
+snippet once
+	#ifndef ${1:`toupper(Filename('', 'UNTITLED').'_'.system("/usr/bin/ruby -e 'print (rand * 2821109907455).round.to_s(36)'"))`}
+
+	#define $1
+
+	${2}
+
+	#endif /* end of include guard: $1 */
+# If Condition
+snippet if
+	if (${1:/* condition */}) {
+		${2:/* code */}
+	}
+snippet el
+	else {
+		${1}
+	}
+# Tertiary conditional
+snippet t
+	${1:/* condition */} ? ${2:a} : ${3:b}
+# Do While Loop
+snippet do
+	do {
+		${2:/* code */}
+	} while (${1:/* condition */});
+# While Loop
+snippet wh
+	while (${1:/* condition */}) {
+		${2:/* code */}
+	}
+# For Loop
+snippet for
+	for (${2:i} = 0; $2 < ${1:count}; $2${3:++}) {
+		${4:/* code */}
+	}
+# Custom For Loop
+snippet forr
+	for (${1:i} = ${2:0}; ${3:$1 < 10}; $1${4:++}) {
+		${5:/* code */}
+	}
+# Function
+snippet fun
+	${1:void} ${2:function_name}(${3})
+	{
+		${4:/* code */}
+	}
+# Function Declaration
+snippet fund
+	${1:void} ${2:function_name}(${3});${4}
+# Typedef
+snippet td
+	typedef ${1:int} ${2:MyCustomType};${3}
+# Struct
+snippet st
+	struct ${1:`Filename('$1_t', 'name')`} {
+		${2:/* data */}
+	}${3: /* optional variable list */};${4}
+# Typedef struct
+snippet tds
+	typedef struct ${2:_$1 }{
+		${3:/* data */}
+	} ${1:`Filename('$1_t', 'name')`};
+# Typdef enum
+snippet tde
+	typedef enum {
+		${1:/* data */}
+	} ${2:foo};
+# printf
+# unfortunately version this isn't as nice as TextMates's, given the lack of a
+# dynamic `...`
+snippet pr
+	printf("${1:%s}\n"${2});${3}
+# fprintf (again, this isn't as nice as TextMate's version, but it works)
+snippet fpr
+	fprintf(${1:stderr}, "${2:%s}\n"${3});${4}
+snippet .
+	[${1}]${2}
+snippet un
+	unsigned

+ 30 - 0
vim/snippets/cpp.snippets

@@ -0,0 +1,30 @@
+# Read File Into Vector
+snippet readfile
+	std::vector<char> v;
+	if (FILE *${2:fp} = fopen(${1:"filename"}, "r")) {
+		char buf[1024];
+		while (size_t len = fread(buf, 1, sizeof(buf), $2))
+			v.insert(v.end(), buf, buf + len);
+		fclose($2);
+	}${3}
+# std::map
+snippet map
+	std::map<${1:key}, ${2:value}> map${3};
+# std::vector
+snippet vector
+	std::vector<${1:char}> v${2};
+# Namespace
+snippet ns
+	namespace ${1:`Filename('', 'my')`} {
+		${2}
+	} /* $1 */
+# Class
+snippet cl
+	class ${1:`Filename('$1_t', 'name')`} {
+	public:
+		$1 (${2:arguments});
+		virtual ~$1 ();
+	
+	private:
+		${3:/* data */}
+	};

+ 190 - 0
vim/snippets/html.snippets

@@ -0,0 +1,190 @@
+# Some useful Unicode entities
+# Non-Breaking Space
+snippet nbs
+	&nbsp;
+# ←
+snippet left
+	&#x2190;
+# →
+snippet right
+	&#x2192;
+# ↑
+snippet up
+	&#x2191;
+# ↓
+snippet down
+	&#x2193;
+# ↩
+snippet return
+	&#x21A9;
+# ⇤
+snippet backtab
+	&#x21E4;
+# ⇥
+snippet tab
+	&#x21E5;
+# ⇧
+snippet shift
+	&#x21E7;
+# ⌃
+snippet control
+	&#x2303;
+# ⌅
+snippet enter
+	&#x2305;
+# ⌘
+snippet command
+	&#x2318;
+# ⌥
+snippet option
+	&#x2325;
+# ⌦
+snippet delete
+	&#x2326;
+# ⌫
+snippet backspace
+	&#x232B;
+# ⎋
+snippet escape
+	&#x238B;
+# Generic Doctype
+snippet doctype HTML 4.01 Strict
+	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""
+	"http://www.w3.org/TR/html4/strict.dtd">
+snippet doctype HTML 4.01 Transitional
+	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""
+	"http://www.w3.org/TR/html4/loose.dtd">
+snippet doctype HTML 5
+	<!DOCTYPE HTML>
+snippet doctype XHTML 1.0 Frameset
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+snippet doctype XHTML 1.0 Strict
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+snippet doctype XHTML 1.0 Transitional
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+snippet doctype XHTML 1.1
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+# HTML Doctype 4.01 Strict
+snippet docts
+	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""
+	"http://www.w3.org/TR/html4/strict.dtd">
+# HTML Doctype 4.01 Transitional
+snippet doct
+	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""
+	"http://www.w3.org/TR/html4/loose.dtd">
+# HTML Doctype 5
+snippet doct5
+	<!DOCTYPE HTML>
+# XHTML Doctype 1.0 Frameset
+snippet docxf
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+# XHTML Doctype 1.0 Strict
+snippet docxs
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+# XHTML Doctype 1.0 Transitional
+snippet docxt
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+# XHTML Doctype 1.1
+snippet docx
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+snippet html
+	<html>
+	${1}
+	</html>
+snippet xhtml
+	<html xmlns="http://www.w3.org/1999/xhtml">
+	${1}
+	</html>
+snippet body
+	<body>
+		${1}
+	</body>
+snippet head
+	<head>
+		<meta http-equiv="content-type" content="text/html; charset=utf-8"`Close()`>
+
+		<title>${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}</title>
+		${2}
+	</head>
+snippet title
+	<title>${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}</title>${2}
+snippet script
+	<script type="text/javascript" charset="utf-8">
+		${1}
+	</script>${2}
+snippet scriptsrc
+	<script src="${1}.js" type="text/javascript" charset="utf-8"></script>${2}
+snippet style
+	<style type="text/css" media="${1:screen}">
+		${2}
+	</style>${3}
+snippet base
+	<base href="${1}" target="${2}"`Close()`>
+snippet r
+	<br`Close()[1:]`>
+snippet div
+	<div id="${1:name}">
+		${2}
+	</div>
+# Embed QT Movie
+snippet movie
+	<object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
+	 codebase="http://www.apple.com/qtactivex/qtplugin.cab">
+		<param name="src" value="$1"`Close()`>
+		<param name="controller" value="$4"`Close()`>
+		<param name="autoplay" value="$5"`Close()`>
+		<embed src="${1:movie.mov}"
+			width="${2:320}" height="${3:240}"
+			controller="${4:true}" autoplay="${5:true}"
+			scale="tofit" cache="true"
+			pluginspage="http://www.apple.com/quicktime/download/"
+		`Close()[1:]`>
+	</object>${6}
+snippet fieldset
+	<fieldset id="$1">
+		<legend>${1:name}</legend>
+
+		${3}
+	</fieldset>
+snippet form
+	<form action="${1:`Filename('$1_submit')`}" method="${2:get}" accept-charset="utf-8">
+		${3}
+
+
+	<p><input type="submit" value="Continue &rarr;"`Close()`></p>
+	</form>
+snippet h1
+	<h1 id="${1:heading}">${2:$1}</h1>
+snippet input
+	<input type="${1:text/submit/hidden/button}" name="${2:some_name}" value="${3}"`Close()`>${4}
+snippet label
+	<label for="${2:$1}">${1:name}</label><input type="${3:text/submit/hidden/button}" name="${4:$2}" value="${5}" id="${6:$2}"`Close()`>${7}
+snippet link
+	<link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" charset="utf-8"`Close()`>${4}
+snippet mailto
+	<a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a>
+snippet meta
+	<meta name="${1:name}" content="${2:content}"`Close()`>${3}
+snippet opt
+	<option value="${1:option}">${2:$1}</option>${3}
+snippet optt
+	<option>${1:option}</option>${2}
+snippet select
+	<select name="${1:some_name}" id="${2:$1}">
+		<option value="${3:option}">${4:$3}</option>
+	</select>${5}
+snippet table
+	<table border="${1:0}">
+		<tr><th>${2:Header}</th></tr>
+		<tr><th>${3:Data}</th></tr>
+	</table>${4}
+snippet textarea
+	<textarea name="${1:Name}" rows="${2:8}" cols="${3:40}">${4}</textarea>${5}

+ 78 - 0
vim/snippets/java.snippets

@@ -0,0 +1,78 @@
+snippet main
+	public static void main (String [] args)
+	{
+		${1:/* code */}
+	}
+snippet pu
+	public
+snippet po
+	protected
+snippet pr
+	private
+snippet st
+	static
+snippet fi
+	final
+snippet ab
+	abstract
+snippet re
+	return
+snippet br
+	break;
+snippet de
+	default:
+		${1}
+snippet ca
+	catch(${1:Exception} ${2:e}) ${3}
+snippet th
+	throw 
+snippet sy
+	synchronized
+snippet im
+	import
+snippet j.u
+	java.util
+snippet j.i
+	java.io.
+snippet j.b
+	java.beans.
+snippet j.n
+	java.net.
+snippet j.m
+	java.math.
+snippet if
+	if (${1}) ${2}
+snippet el
+	else 
+snippet elif
+	else if (${1}) ${2}
+snippet wh
+	while (${1}) ${2}
+snippet for
+	for (${1}; ${2}; ${3}) ${4}
+snippet fore
+	for (${1} : ${2}) ${3}
+snippet sw
+	switch (${1}) ${2}
+snippet cs
+	case ${1}:
+		${2}
+	${3}
+snippet tc
+	public class ${1:`Filename()`} extends ${2:TestCase}
+snippet t
+	public void test${1:Name}() throws Exception ${2}
+snippet cl
+	class ${1:`Filename("", "untitled")`} ${2}
+snippet in
+	interface ${1:`Filename("", "untitled")`} ${2:extends Parent}${3}
+snippet m
+	${1:void} ${2:method}(${3}) ${4:throws }${5}
+snippet v
+	${1:String} ${2:var}${3: = null}${4};${5}
+snippet co
+	static public final ${1:String} ${2:var} = ${3};${4}
+snippet cos
+	static public final String ${1:var} = "${2}";${3}
+snippet as
+	assert ${1:test} : "${2:Failure message}";${3}

+ 74 - 0
vim/snippets/javascript.snippets

@@ -0,0 +1,74 @@
+# Prototype
+snippet proto
+	${1:class_name}.prototype.${2:method_name} =
+	function(${3:first_argument}) {
+		${4:// body...}
+	};
+# Function
+snippet fun
+	function ${1:function_name} (${2:argument}) {
+		${3:// body...}
+	}
+# Anonymous Function
+snippet f
+	function(${1}) {${2}};
+# if
+snippet if
+	if (${1:true}) {${2}};
+# if ... else
+snippet ife
+	if (${1:true}) {${2}}
+	else{${3}};
+# tertiary conditional
+snippet t
+	${1:/* condition */} ? ${2:a} : ${3:b}
+# switch
+snippet switch
+	switch(${1:expression}) {
+		case '${3:case}':
+			${4:// code}
+			break;
+		${5}
+		default:
+			${2:// code}
+	}
+# case
+snippet case
+	case '${1:case}':
+		${2:// code}
+		break;
+	${3}
+# for (...) {...}
+snippet for
+	for (var ${2:i} = 0; $2 < ${1:Things}.length; $2${3:++}) {
+		${4:$1[$2]}
+	};
+# for (...) {...} (Improved Native For-Loop)
+snippet forr
+	for (var ${2:i} = ${1:Things}.length - 1; $2 >= 0; $2${3:--}) {
+		${4:$1[$2]}
+	};
+# while (...) {...}
+snippet wh
+	while (${1:/* condition */}) {
+		${2:/* code */}
+	}
+# do...while
+snippet do
+	do {
+		${2:/* code */}
+	} while (${1:/* condition */});
+# Object Method
+snippet :f
+	${1:method_name}: function(${2:attribute}) {
+		${4}
+	}${3:,}
+# setTimeout function
+snippet timeout
+	setTimeout(function() {${3}}${2}, ${1:10};
+# Get Elements
+snippet get
+	getElementsBy${1:TagName}('${2}')${3}
+# Get Element
+snippet gett
+	getElementBy${1:Id}('${2}')${3}

+ 54 - 0
vim/snippets/mako.snippets

@@ -0,0 +1,54 @@
+snippet def
+	<%def name="${1:name}">
+		${2:}
+	</%def>
+snippet call
+	<%call expr="${1:name}">
+		${2:}
+	</%call>
+snippet doc
+	<%doc>
+		${1:}
+	</%doc>
+snippet text
+	<%text>
+		${1:}
+	</%text>
+snippet for
+	% for ${1:i} in ${2:iter}:
+		${3:}
+	% endfor
+snippet if if
+	% if ${1:condition}:
+		${2:}
+	% endif
+snippet if if/else
+	% if ${1:condition}:
+		${2:}
+	% else:
+		${3:}
+	% endif
+snippet try
+	% try:
+		${1:}
+	% except${2:}:
+		${3:pass}
+	% endtry
+snippet wh
+	% while ${1:}:
+		${2:}
+	% endwhile
+snippet $
+	${ ${1:} }
+snippet <%
+	<% ${1:} %>
+snippet <!%
+	<!% ${1:} %>
+snippet inherit
+	<%inherit file="${1:filename}" />
+snippet include
+	<%include file="${1:filename}" />
+snippet namespace
+	<%namespace file="${1:name}" />
+snippet page
+	<%page args="${1:}" />

+ 184 - 0
vim/snippets/objc.snippets

@@ -0,0 +1,184 @@
+# #import <...>
+snippet Imp
+	#import <${1:Cocoa/Cocoa.h}>${2}
+# #import "..."
+snippet imp
+	#import "${1:`Filename()`.h}"${2}
+# @selector(...)
+snippet sel
+	@selector(${1:method}:)${3}
+# @"..." string
+snippet s
+	@"${1}"${2}
+# Object
+snippet o
+	${1:NSObject} *${2:foo} = [${3:$1 alloc}]${4};${5}
+# NSLog(...)
+snippet log
+	NSLog(@"${1:%@}"${2});${3}
+# Class
+snippet objc
+	@interface ${1:`Filename('', 'someClass')`} : ${2:NSObject}
+	{
+	}
+	@end
+
+	@implementation $1
+	${3}
+	@end
+# Class Interface
+snippet int
+	@interface ${1:`Filename('', 'someClass')`} : ${2:NSObject}
+	{${3}
+	}
+	${4}
+	@end
+# Class Implementation
+snippet impl
+	@implementation ${1:`Filename('', 'someClass')`}
+	${2}
+	@end
+snippet init
+	- (id)init
+	{
+		[super init];
+		return self;
+	}
+snippet ifself
+	if (self = [super init]) {
+		${1:/* code */}
+	}
+	return self;
+snippet ibo
+	IBOutlet ${1:NSSomeClass} *${2:$1};${3}
+# Category
+snippet cat
+	@interface ${1:NSObject} (${2:Category})
+	@end
+
+	@implementation $1 ($2)
+	${3}
+	@end
+# Category Interface
+snippet cath
+	@interface ${1:NSObject} (${2:Category})
+	${3}
+	@end
+# NSArray
+snippet array
+	NSMutableArray *${1:array} = [NSMutable array];${2}
+# NSDictionary
+snippet dict
+	NSMutableDictionary *${1:dict} = [NSMutableDictionary dictionary];${2}
+# NSBezierPath
+snippet bez
+	NSBezierPath *${1:path} = [NSBezierPath bezierPath];${2}
+# Method
+snippet m
+	- (${1:id})${2:method}
+	{
+		${3}
+	}
+# Method declaration
+snippet md
+	- (${1:id})${2:method};${3}
+# IBAction declaration
+snippet ibad
+	- (IBAction)${1:method}:(${2:id})sender;${3}
+# IBAction method
+snippet iba
+	- (IBAction)${1:method}:(${2:id})sender
+	{
+		${3}
+	}
+# awakeFromNib method
+snippet wake
+	- (void)awakeFromNib
+	{
+		${1}
+	}
+# Class Method
+snippet M
+	+ (${1:id})${2:method}
+	{${3}
+		return nil;
+	}
+# Sub-method (Call super)
+snippet sm
+	- (${1:id})${2:method}
+	{
+		[super $2];${3}
+		return self;
+	}
+# Method: Initialize
+snippet I
+	+ (void) initialize
+	{
+		[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWIthObjectsAndKeys:
+			${1}@"value", @"key",
+			nil]];
+	}
+# Accessor Methods For:
+# Object
+snippet objacc
+	- (${1:id})${2:thing}
+	{
+		return $2;
+	}
+
+	- (void)set$2:($1)${3:new$2}
+	{
+		[$3 retain];
+		[$2 release];
+		$2 = $3;
+	}${4}
+# for (object in array)
+snippet forin
+	for (${1:Class} *${2:some$1} in ${3:array}) {
+		${4}
+	}
+snippet forarray
+	unsigned int ${1:object}Count = [${2:array} count];
+
+	for (unsigned int index = 0; index < $1Count; index++) {
+		${3:id} $1 = [$2 $1AtIndex:index];
+		${4}
+	}
+# IBOutlet
+# @property (Objective-C 2.0)
+snippet prop
+	@property (${1:retain}) ${2:NSSomeClass} ${3:*$2};${4}
+# @synthesize (Objective-C 2.0)
+snippet syn
+	@synthesize ${1:property};${2}
+# [[ alloc] init]
+snippet alloc
+	[[${1:foo} alloc] init${2}];${3}
+# retain
+snippet ret
+	[${1:foo} retain];${2}
+# release
+snippet rel
+	[${1:foo} release];
+	${2:$1 = nil;}
+# autorelease
+snippet arel
+	[${1:foo} autorelease];
+# autorelease pool
+snippet pool
+	NSAutoreleasePool *${1:pool} = [[NSAutoreleasePool alloc] init];
+	${2:/* code */}
+	[$1 drain];
+# Throw an exception
+snippet except
+	NSException *${1:badness};
+	$1 = [NSException exceptionWithName:@"${2:$1Name}"
+	                             reason:@"${3}"
+	                           userInfo:nil];
+	[$1 raise];
+snippet prag
+	#pragma mark ${1:foo}
+snippet cl
+	@class ${1:Foo};${2}
+snippet color
+	[[NSColor ${1:blackColor}] set];

+ 91 - 0
vim/snippets/perl.snippets

@@ -0,0 +1,91 @@
+# #!/usr/bin/perl
+snippet #!
+	#!/usr/bin/perl
+	
+# Hash Pointer
+snippet .
+	 =>
+# Function
+snippet sub
+	sub ${1:function_name} {
+		${2:#body ...}
+	}
+# Conditional
+snippet if
+	if (${1}) {
+		${2:# body...}
+	}
+# Conditional if..else
+snippet ife
+	if (${1}) {
+		${2:# body...}
+	} else {
+		${3:# else...}
+	}
+# Conditional if..elsif..else
+snippet ifee
+	if (${1}) {
+		${2:# body...}
+	} elsif (${3}) {
+		${4:# elsif...}
+	} else {
+		${5:# else...}
+	}
+# Conditional One-line
+snippet xif
+	${1:expression} if ${2:condition};${3}
+# Unless conditional
+snippet unless
+	unless (${1}) {
+		${2:# body...}
+	}
+# Unless conditional One-line
+snippet xunless
+	${1:expression} unless ${2:condition};${3}
+# Try/Except
+snippet eval
+	eval {
+		${1:# do something risky...}
+	};
+	if ($@) {
+		${2:# handle failure...}
+	}
+# While Loop
+snippet wh
+	while (${1}) {
+		${2:# body...}
+	}
+# While Loop One-line
+snippet xwh
+	${1:expression} while ${2:condition};${3}
+# For Loop
+snippet for
+	for (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) {
+		${4:# body...}
+	}
+# Foreach Loop
+snippet fore
+	foreach my $${1:x} (@${2:array}) {
+		${3:# body...}
+	}
+# Foreach Loop One-line
+snippet xfore
+	${1:expression} foreach @${2:array};${3}
+# Package
+snippet cl
+	package ${1:ClassName};
+	
+	use base qw(${2:ParentClass});
+	
+	sub new {
+		my $class = shift;
+		$class = ref $class if ref $class;
+		my $self = bless {}, $class;
+		$self;
+	}
+	
+	1;${3}
+# Read File
+snippet slurp
+	my $${1:var};
+	{ local $/ = undef; local *FILE; open FILE, "<${2:file}"; $$1 = <FILE>; close FILE }${3}

+ 216 - 0
vim/snippets/php.snippets

@@ -0,0 +1,216 @@
+snippet php
+	<?php
+	${1}
+	?>
+snippet ec
+	echo "${1:string}"${2};
+snippet inc
+	include '${1:file}';${2}
+snippet inc1
+	include_once '${1:file}';${2}
+snippet req
+	require '${1:file}';${2}
+snippet req1
+	require_once '${1:file}';${2}
+# $GLOBALS['...']
+snippet globals
+	$GLOBALS['${1:variable}']${2: = }${3:something}${4:;}${5}
+snippet $_ COOKIE['...']
+	$_COOKIE['${1:variable}']${2}
+snippet $_ ENV['...']
+	$_ENV['${1:variable}']${2}
+snippet $_ FILES['...']
+	$_FILES['${1:variable}']${2}
+snippet $_ Get['...']
+	$_GET['${1:variable}']${2}
+snippet $_ POST['...']
+	$_POST['${1:variable}']${2}
+snippet $_ REQUEST['...']
+	$_REQUEST['${1:variable}']${2}
+snippet $_ SERVER['...']
+	$_SERVER['${1:variable}']${2}
+snippet $_ SESSION['...']
+	$_SESSION['${1:variable}']${2}
+# Start Docblock
+snippet /*
+	/**
+	 * ${1}
+	 **/
+# Class - post doc
+snippet doc_cp
+	/**
+	 * ${1:undocumented class}
+	 *
+	 * @package ${2:default}
+	 * @author ${3:`g:snips_author`}
+	**/${4}
+# Class Variable - post doc
+snippet doc_vp
+	/**
+	 * ${1:undocumented class variable}
+	 *
+	 * @var ${2:string}
+	 **/${3}
+# Class Variable
+snippet doc_v
+	/**
+	 * ${3:undocumented class variable}
+	 *
+	 * @var ${4:string}
+	 **/
+	${1:var} $${2};${5}
+# Class
+snippet doc_c
+	/**
+	 * ${3:undocumented class}
+	 *
+	 * @packaged ${4:default}
+	 * @author ${5:`g:snips_author`}
+	 **/
+	${1:}class ${2:}
+	{${6}
+	} // END $1class $2
+# Constant Definition - post doc
+snippet doc_dp
+	/**
+	 * ${1:undocumented constant}
+	 **/${2}
+# Constant Definition
+snippet doc_d
+	/**
+	 * ${3:undocumented constant}
+	 **/
+	define(${1}, ${2});${4}
+# Function - post doc
+snippet doc_fp
+	/**
+	 * ${1:undocumented function}
+	 *
+	 * @return ${2:void}
+	 * @author ${3:`g:snips_author`}
+	 **/${4}
+# Function signature
+snippet doc_s
+	/**
+	 * ${4:undocumented function}
+	 *
+	 * @return ${5:void}
+	 * @author ${6:`g:snips_author`}
+	 **/
+	${1}function ${2}(${3});${7}
+# Function
+snippet doc_f
+	/**
+	 * ${4:undocumented function}
+	 *
+	 * @return ${5:void}
+	 * @author ${6:`g:snips_author`}
+	 **/
+	${1}function ${2}(${3})
+	{${7}
+	}
+# Header
+snippet doc_h
+	/**
+	 * ${1}
+	 *
+	 * @author ${2:`g:snips_author`}
+	 * @version ${3:$Id$}
+	 * @copyright ${4:$2}, `strftime('%d %B, %Y')`
+	 * @package ${5:default}
+	 **/
+	
+	/**
+	 * Define DocBlock
+	 *//
+# Interface
+snippet doc_i
+	/**
+	 * ${2:undocumented class}
+	 *
+	 * @package ${3:default}
+	 * @author ${4:`g:snips_author`}
+	 **/
+	interface ${1:}
+	{${5}
+	} // END interface $1
+# class ...
+snippet class
+	/**
+	 * ${1}
+	 **/
+	class ${2:ClassName}
+	{
+		${3}
+		function ${4:__construct}(${5:argument})
+		{
+			${6:// code...}
+		}
+	}
+# define(...)
+snippet def
+	define('${1}'${2});${3}
+# defined(...)
+snippet def?
+	${1}defined('${2}')${3}
+snippet wh
+	while (${1:/* condition */}) {
+		${2:// code...}
+	}
+# do ... while
+snippet do
+	do {
+		${2:// code... }
+	} while (${1:/* condition */});
+snippet if
+	if (${1:/* condition */}) {
+		${2:// code...}
+	}
+snippet ife
+	if (${1:/* condition */}) {
+		${2:// code...}
+	} else {
+		${3:// code...}
+	}
+	${4}
+snippet else
+	else {
+		${1:// code...}
+	}
+snippet elseif
+	elseif (${1:/* condition */}) {
+		${2:// code...}
+	}
+# Tertiary conditional
+snippet t
+	$${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};${5}
+snippet switch
+	switch ($${1:variable}) {
+		case '${2:value}':
+			${3:// code...}
+			break;
+		${5}
+		default:
+			${4:// code...}
+			break;
+	}
+snippet case
+	case '${1:value}':
+		${2:// code...}
+		break;${3}
+snippet for
+	for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) {
+		${4: // code...}
+	}
+snippet foreach
+	foreach ($${1:variable} as $${2:key}) {
+		${3:// code...}
+	}
+snippet fun
+	${1:public }function ${2:FunctionName}(${3})
+	{
+		${4:// code...}
+	}
+# $... = array (...)
+snippet array
+	$${1:arrayName} = array('${2}' => ${3});${4}

+ 86 - 0
vim/snippets/python.snippets

@@ -0,0 +1,86 @@
+snippet #!
+	#!/usr/bin/python
+
+snippet imp
+	import ${1:module}
+# Module Docstring
+snippet docs
+	'''
+	File: ${1:`Filename('$1.py', 'foo.py')`}
+	Author: ${2:`g:snips_author`}
+	Description: ${3}
+	'''
+snippet wh
+	while ${1:condition}:
+		${2:# code...}
+snippet for
+	for ${1:needle} in ${2:haystack}:
+		${3:# code...}
+# New Class
+snippet cl
+	class ${1:ClassName}(${2:object}):
+		"""${3:docstring for $1}"""
+		def __init__(self, ${4:arg}):
+			${5:super($1, self).__init__()}
+			self.$4 = $4
+			${6}
+# New Function
+snippet def
+	def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
+		"""${3:docstring for $1}"""
+		${4:pass}
+snippet deff
+	def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
+		${3}
+# New Method
+snippet defs
+	def ${1:mname}(self, ${2:arg}):
+		${3:pass}
+# New Property
+snippet property
+	def ${1:foo}():
+		doc = "${2:The $1 property.}"
+		def fget(self):
+			${3:return self._$1}
+		def fset(self, value):
+			${4:self._$1 = value}
+# Lambda
+snippet ld
+	${1:var} = lambda ${2:vars} : ${3:action}
+snippet .
+	self.
+snippet try Try/Except
+	try:
+		${1:pass}
+	except ${2:Exception}, ${3:e}:
+		${4:raise $3}
+snippet try Try/Except/Else
+	try:
+		${1:pass}
+	except ${2:Exception}, ${3:e}:
+		${4:raise $3}
+	else:
+		${5:pass}
+snippet try Try/Except/Finally
+	try:
+		${1:pass}
+	except ${2:Exception}, ${3:e}:
+		${4:raise $3}
+	finally:
+		${5:pass}
+snippet try Try/Except/Else/Finally
+	try:
+		${1:pass}
+	except ${2:Exception}, ${3:e}:
+		${4:raise $3}
+	else:
+		${5:pass}
+	finally:
+		${6:pass}
+# if __name__ == '__main__':
+snippet ifmain
+	if __name__ == '__main__':
+		${1:main()}
+# __magic__
+snippet _
+	__${1:init}__${2}

+ 420 - 0
vim/snippets/ruby.snippets

@@ -0,0 +1,420 @@
+# #!/usr/bin/ruby
+snippet #!
+	#!/usr/bin/ruby
+
+# New Block
+snippet =b
+	=begin rdoc
+		${1}
+	=end
+snippet y
+	:yields: ${1:arguments}
+snippet rb
+	#!/usr/bin/env ruby -wKU
+
+snippet req
+	require "${1}"${2}
+snippet #
+	# =>
+snippet end
+	__END__
+snippet case
+	case ${1:object}
+	when ${2:condition}
+		${3}
+	end
+snippet when
+	when ${1:condition}
+		${2}
+snippet def
+	def ${1:method_name}
+		${2}
+	end
+snippet deft
+	def test_${1:case_name}
+		${2}
+	end
+snippet if
+	if ${1:condition}
+		${2}
+	end
+snippet ife
+	if ${1:condition}
+		${2}
+	else
+		${3}
+	end
+snippet elsif
+	elsif ${1:condition}
+		${2}
+snippet unless
+	unless ${1:condition}
+		${2}
+	end
+snippet while
+	while ${1:condition}
+		${2}
+	end
+snippet until
+	until ${1:condition}
+		${2}
+	end
+snippet cla class .. end
+	class ${1:`substitute(Filename(), '^.', '\u&', '')`}
+		${2}
+	end
+snippet cla class .. initialize .. end
+	class ${1:`substitute(Filename(), '^.', '\u&', '')`}
+		def initialize(${2:args})
+			${3}
+		end
+
+
+	end
+snippet cla class .. < ParentClass .. initialize .. end
+	class ${1:`substitute(Filename(), '^.', '\u&', '')`} < ${2:ParentClass}
+		def initialize(${3:args})
+			${4}
+		end
+
+
+	end
+snippet cla ClassName = Struct .. do .. end
+	${1:`substitute(Filename(), '^.', '\u&', '')`} = Struct.new(:${2:attr_names}) do
+		def ${3:method_name}
+			${4}
+		end
+
+
+	end
+snippet cla class BlankSlate .. initialize .. end
+	class ${1:BlankSlate}
+		instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A__/ }
+snippet cla class << self .. end
+	class << ${1:self}
+		${2}
+	end
+# class .. < DelegateClass .. initialize .. end
+snippet cla-
+	class ${1:`substitute(Filename(), '^.', '\u&', '')`} < DelegateClass(${2:ParentClass})
+		def initialize(${3:args})
+			super(${4:del_obj})
+
+			${5}
+		end
+
+
+	end
+snippet mod module .. end
+	module ${1:`substitute(Filename(), '^.', '\u&', '')`}
+		${2}
+	end
+snippet mod module .. module_function .. end
+	module ${1:`substitute(Filename(), '^.', '\u&', '')`}
+		module_function
+
+		${2}
+	end
+snippet mod module .. ClassMethods .. end
+	module ${1:`substitute(Filename(), '^.', '\u&', '')`}
+		module ClassMethods
+			${2}
+		end
+
+		module InstanceMethods
+
+		end
+
+		def self.included(receiver)
+			receiver.extend         ClassMethods
+			receiver.send :include, InstanceMethods
+		end
+	end
+# attr_reader
+snippet r
+	attr_reader :${1:attr_names}
+# attr_writer
+snippet w
+	attr_writer :${1:attr_names}
+# attr_accessor
+snippet rw
+	attr_accessor :${1:attr_names}
+# include Enumerable
+snippet Enum
+	include Enumerable
+
+	def each(&block)
+		${1}
+	end
+# include Comparable
+snippet Comp
+	include Comparable
+
+	def <=>(other)
+		${1}
+	end
+# extend Forwardable
+snippet Forw-
+	extend Forwardable
+# def self
+snippet defs
+	def self.${1:class_method_name}
+		${2}
+	end
+# def method_missing
+snippet defmm
+	def method_missing(meth, *args, &blk)
+		${1}
+	end
+snippet defd
+	def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}
+snippet defds
+	def_delegators :${1:@del_obj}, :${2:del_methods}
+snippet am
+	alias_method :${1:new_name}, :${2:old_name}
+snippet app
+	if __FILE__ == $PROGRAM_NAME
+		${1}
+	end
+# usage_if()
+snippet usai
+	if ARGV.${1}
+		abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}
+	end
+# usage_unless()
+snippet usau
+	unless ARGV.${1}
+		abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}
+	end
+snippet array
+	Array.new(${1:10}) { |${2:i}| ${3} }
+snippet hash
+	Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }
+snippet file File.foreach() { |line| .. }
+	File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }
+snippet file File.read()
+	File.read(${1:"path/to/file"})${2}
+snippet Dir Dir.global() { |file| .. }
+	Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }
+snippet Dir Dir[".."]
+	Dir[${1:"glob/**/*.rb"}]${2}
+snippet dir
+	Filename.dirname(__FILE__)
+snippet deli
+	delete_if { |${1:e}| ${2} }
+snippet fil
+	fill(${1:range}) { |${2:i}| ${3} }
+# flatten_once()
+snippet flao
+	inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}
+snippet zip
+	zip(${1:enums}) { |${2:row}| ${3} }
+# downto(0) { |n| .. }
+snippet dow
+	downto(${1:0}) { |${2:n}| ${3} }
+snippet ste
+	step(${1:2}) { |${2:n}| ${3} }
+snippet tim
+	times { |${1:n}| ${2} }
+snippet upt
+	upto(${1:1.0/0.0}) { |${2:n}| ${3} }
+snippet loo
+	loop { ${1} }
+snippet ea
+	each { |${1:e}| ${2} }
+snippet eab
+	each_byte { |${1:byte}| ${2} }
+snippet eac- each_char { |chr| .. }
+	each_char { |${1:chr}| ${2} }
+snippet eac- each_cons(..) { |group| .. }
+	each_cons(${1:2}) { |${2:group}| ${3} }
+snippet eai
+	each_index { |${1:i}| ${2} }
+snippet eak
+	each_key { |${1:key}| ${2} }
+snippet eal
+	each_line { |${1:line}| ${2} }
+snippet eap
+	each_pair { |${1:name}, ${2:val}| ${3} }
+snippet eas-
+	each_slice(${1:2}) { |${2:group}| ${3} }
+snippet eav
+	each_value { |${1:val}| ${2} }
+snippet eawi
+	each_with_index { |${1:e}, ${2:i}| ${3} }
+snippet reve
+	reverse_each { |${1:e}| ${2} }
+snippet inj
+	inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }
+snippet map
+	map { |${1:e}| ${2} }
+snippet mapwi-
+	enum_with_index.map { |${1:e}, ${2:i}| ${3} }
+snippet sor
+	sort { |a, b| ${1} }
+snippet sorb
+	sort_by { |${1:e}| ${2} }
+snippet ran
+	sort_by { rand }
+snippet all
+	all? { |${1:e}| ${2} }
+snippet any
+	any? { |${1:e}| ${2} }
+snippet cl
+	classify { |${1:e}| ${2} }
+snippet col
+	collect { |${1:e}| ${2} }
+snippet det
+	detect { |${1:e}| ${2} }
+snippet fet
+	fetch(${1:name}) { |${2:key}| ${3} }
+snippet fin
+	find { |${1:e}| ${2} }
+snippet fina
+	find_all { |${1:e}| ${2} }
+snippet gre
+	grep(${1:/pattern/}) { |${2:match}| ${3} }
+snippet sub
+	${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }
+snippet sca
+	scan(${1:/pattern/}) { |${2:match}| ${3} }
+snippet max
+	max { |a, b|, ${1} }
+snippet min
+	min { |a, b|, ${1} }
+snippet par
+	partition { |${1:e}|, ${2} }
+snippet rej
+	reject { |${1:e}|, ${2} }
+snippet sel
+	select { |${1:e}|, ${2} }
+snippet lam
+	lambda { |${1:args}| ${2} }
+snippet do
+	do |${1:variable}|
+		${2}
+	end
+snippet :
+	:${1:key} => ${2:"value"}${3}
+snippet ope
+	open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }
+# path_from_here()
+snippet patfh
+	File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}
+# unix_filter {}
+snippet unif
+	ARGF.each_line${1} do |${2:line}|
+		${3}
+	end
+# option_parse {}
+snippet optp
+	require "optparse"
+
+	options = {${1:default => "args"}}
+
+	ARGV.options do |opts|
+		opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}
+snippet opt
+	opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},
+	         "${4:Option description.}") do |${5:opt}|
+		${6}
+	end
+snippet tc
+	require "test/unit"
+
+	require "${1:library_file_name}"
+
+	class Test${2:$1} < Test::Unit::TestCase
+		def test_${3:case_name}
+			${4}
+		end
+	end
+snippet ts
+	require "test/unit"
+
+	require "tc_${1:test_case_file}"
+	require "tc_${2:test_case_file}"${3}
+snippet as
+	assert(${1:test}, "${2:Failure message.}")${3}
+snippet ase
+	assert_equal(${1:expected}, ${2:actual})${3}
+snippet asne
+	assert_not_equal(${1:unexpected}, ${2:actual})${3}
+snippet asid
+	assert_in_delta(${1:expected_float}, ${2:actual_float}, ${3:2 ** -20})${4}
+snippet asio
+	assert_instance_of(${1:ExpectedClass}, ${2:actual_instance})${3}
+snippet asko
+	assert_kind_of(${1:ExpectedKind}, ${2:actual_instance})${3}
+snippet asn
+	assert_nil(${1:instance})${2}
+snippet asnn
+	assert_not_nil(${1:instance})${2}
+snippet asm
+	assert_match(/${1:expected_pattern}/, ${2:actual_string})${3}
+snippet asnm
+	assert_no_match(/${1:unexpected_pattern}/, ${2:actual_string})${3}
+snippet aso
+	assert_operator(${1:left}, :${2:operator}, ${3:right})${4}
+snippet asr
+	assert_raise(${1:Exception}) { ${2} }
+snippet asnr
+	assert_nothing_raised(${1:Exception}) { ${2} }
+snippet asrt
+	assert_respond_to(${1:object}, :${2:method})${3}
+snippet ass assert_same(..)
+	assert_same(${1:expected}, ${2:actual})${3}
+snippet ass assert_send(..)
+	assert_send([${1:object}, :${2:message}, ${3:args}])${4}
+snippet asns
+	assert_not_same(${1:unexpected}, ${2:actual})${3}
+snippet ast
+	assert_throws(:${1:expected}) { ${2} }
+snippet asnt
+	assert_nothing_thrown { ${1} }
+snippet fl
+	flunk("${1:Failure message.}")${2}
+# Benchmark.bmbm do .. end
+snippet bm-
+	TESTS = ${1:10_000}
+	Benchmark.bmbm do |results|
+		${2}
+	end
+snippet rep
+	results.report("${1:name}:") { TESTS.times { ${2} }}
+# Marshal.dump(.., file)
+snippet Md
+	File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}
+# Mashal.load(obj)
+snippet Ml
+	File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}
+# deep_copy(..)
+snippet deec
+	Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}
+snippet Pn-
+	PStore.new(${1:"file_name.pstore"})${2}
+snippet tra
+	transaction(${1:true}) { ${2} }
+# xmlread(..)
+snippet xml-
+	REXML::Document.new(File.read(${1:"path/to/file"}))${2}
+# xpath(..) { .. }
+snippet xpa
+	elements.each(${1:"//Xpath"}) do |${2:node}|
+		${3}
+	end
+# class_from_name()
+snippet clafn
+	split("::").inject(Object) { |par, const| par.const_get(const) }
+# singleton_class()
+snippet sinc
+	class << self; self end
+snippet nam
+	namespace :${1:`Filename()`} do
+		${2}
+	end
+snippet tas
+	desc "${1:Task description\}"
+	task :${2:task_name => [:dependent, :tasks]} do
+		${3}
+	end

+ 28 - 0
vim/snippets/sh.snippets

@@ -0,0 +1,28 @@
+# #!/bin/bash
+snippet #!
+	#!/bin/bash
+	
+snippet if
+	if [[ ${1:condition} ]]; then
+		${2:#statements}
+	fi
+snippet elif
+	elif [[ ${1:condition} ]]; then
+		${2:#statements}
+snippet for
+	for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do
+		${3:#statements}
+	done
+snippet wh
+	while [[ ${1:condition} ]]; do
+		${2:#statements}
+	done
+snippet until
+	until [[ ${1:condition} ]]; do
+		${2:#statements}
+	done
+snippet case
+	case ${1:word} in
+		${2:pattern})
+			${3};;
+	esac

+ 7 - 0
vim/snippets/snippet.snippets

@@ -0,0 +1,7 @@
+# snippets for making snippets :)
+snippet snip
+	snippet ${1:trigger}
+		${2}
+snippet msnip
+	snippet ${1:trigger} ${2:description}
+		${3}

+ 92 - 0
vim/snippets/tcl.snippets

@@ -0,0 +1,92 @@
+# #!/usr/bin/tclsh
+snippet #!
+	#!/usr/bin/tclsh
+	
+# Process
+snippet pro
+	proc ${1:function_name} {${2:args}} {
+		${3:#body ...}
+	}
+#xif
+snippet xif
+	${1:expr}? ${2:true} : ${3:false}
+# Conditional
+snippet if
+	if {${1}} {
+		${2:# body...}
+	}
+# Conditional if..else
+snippet ife
+	if {${1}} {
+		${2:# body...}
+	} else {
+		${3:# else...}
+	}
+# Conditional if..elsif..else
+snippet ifee
+	if {${1}} {
+		${2:# body...}
+	} elseif {${3}} {
+		${4:# elsif...}
+	} else {
+		${5:# else...}
+	}
+# If catch then
+snippet ifc
+	if { [catch {${1:#do something...}} ${2:err}] } {
+		${3:# handle failure...}
+	}
+# Catch
+snippet catch
+	catch {${1}} ${2:err} ${3:options}
+# While Loop
+snippet wh
+	while {${1}} {
+		${2:# body...}
+	}
+# For Loop
+snippet for
+	for {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} {
+		${4:# body...}
+	}
+# Foreach Loop
+snippet fore
+	foreach ${1:x} {${2:#list}} {
+		${3:# body...}
+	}
+# after ms script...
+snippet af
+	after ${1:ms} ${2:#do something}
+# after cancel id
+snippet afc
+	after cancel ${1:id or script}
+# after idle
+snippet afi
+	after idle ${1:script}
+# after info id
+snippet afin
+	after info ${1:id}
+# Expr
+snippet exp
+	expr {${1:#expression here}}
+# Switch
+snippet sw
+	switch ${1:var} {
+		${3:pattern 1} {
+			${4:#do something}
+		}
+		default {
+			${2:#do something}
+		}
+	}
+# Case
+snippet ca
+	${1:pattern} {
+		${2:#do something}
+	}${3}
+# Namespace eval
+snippet ns
+	namespace eval ${1:path} {${2:#script...}}
+# Namespace current
+snippet nsc
+	namespace current

+ 115 - 0
vim/snippets/tex.snippets

@@ -0,0 +1,115 @@
+# \begin{}...\end{}
+snippet begin
+	\begin{${1:env}}
+		${2}
+	\end{$1}
+# Tabular
+snippet tab
+	\begin{${1:tabular}}{${2:c}}
+	${3}
+	\end{$1}
+# Align(ed)
+snippet ali
+	\begin{align${1:ed}}
+		${2}
+	\end{align$1}
+# Gather(ed)
+snippet gat
+	\begin{gather${1:ed}}
+		${2}
+	\end{gather$1}
+# Equation
+snippet eq
+	\begin{equation}
+		${1}
+	\end{equation}
+# Unnumbered Equation
+snippet \
+	\\[
+		${1}
+	\\]
+# Enumerate
+snippet enum
+	\begin{enumerate}
+		\item ${1}
+	\end{enumerate}
+# Itemize
+snippet item
+	\begin{itemize}
+		\item ${1}
+	\end{itemize}
+# Description
+snippet desc
+	\begin{description}
+		\item[${1}] ${2}
+	\end{description}
+# Matrix
+snippet mat
+	\begin{${1:p/b/v/V/B/small}matrix}
+		${2}
+	\end{$1matrix}
+# Cases
+snippet cas
+	\begin{cases}
+		${1:equation}, &\text{ if }${2:case}\\
+		${3}
+	\end{cases}
+# Split
+snippet spl
+	\begin{split}
+		${1}
+	\end{split}
+# Part
+snippet part
+	\part{${1:part name}} % (fold)
+	\label{prt:${2:$1}}
+	${3}
+	% part $2 (end)
+# Chapter
+snippet cha
+	\chapter{${1:chapter name}} % (fold)
+	\label{cha:${2:$1}}
+	${3}
+	% chapter $2 (end)
+# Section
+snippet sec
+	\section{${1:section name}} % (fold)
+	\label{sec:${2:$1}}
+	${3}
+	% section $2 (end)
+# Sub Section
+snippet sub
+	\subsection{${1:subsection name}} % (fold)
+	\label{sub:${2:$1}}
+	${3}
+	% subsection $2 (end)
+# Sub Sub Section
+snippet subs
+	\subsubsection{${1:subsubsection name}} % (fold)
+	\label{ssub:${2:$1}}
+	${3}
+	% subsubsection $2 (end)
+# Paragraph
+snippet par
+	\paragraph{${1:paragraph name}} % (fold)
+	\label{par:${2:$1}}
+	${3}
+	% paragraph $2 (end)
+# Sub Paragraph
+snippet subp
+	\subparagraph{${1:subparagraph name}} % (fold)
+	\label{subp:${2:$1}}
+	${3}
+	% subparagraph $2 (end)
+snippet itd
+	\item[${1:description}] ${2:item}
+snippet figure
+	${1:Figure}~\ref{${2:fig:}}${3}
+snippet table
+	${1:Table}~\ref{${2:tab:}}${3}
+snippet listing
+	${1:Listing}~\ref{${2:list}}${3}
+snippet section
+	${1:Section}~\ref{${2:sec:}}${3}
+snippet page
+	${1:page}~\pageref{${2}}${3}

+ 32 - 0
vim/snippets/vim.snippets

@@ -0,0 +1,32 @@
+snippet header
+	" File: ${1:`expand('%:t')`}
+	" Author: ${2:`g:snips_author`}
+	" Description: ${3}
+	${4:" Last Modified: `strftime("%B %d, %Y")`}
+snippet guard
+	if exists('${1:did_`Filename()`}') || &cp${2: || version < 700}
+		finish
+	endif
+	let $1 = 1${3}
+snippet f
+	fun ${1:function_name}(${2})
+		${3:" code}
+	endf
+snippet for
+	for ${1:needle} in ${2:haystack}
+		${3:" code}
+	endfor
+snippet wh
+	while ${1:condition}
+		${2:" code}
+	endw
+snippet if
+	if ${1:condition}
+		${2:" code}
+	endif
+snippet ife
+	if ${1:condition}
+		${2}
+	else
+		${3}
+	endif

+ 58 - 0
vim/snippets/zsh.snippets

@@ -0,0 +1,58 @@
+# #!/bin/zsh
+snippet #!
+	#!/bin/zsh
+
+snippet if
+	if ${1:condition}; then
+		${2:# statements}
+	fi
+snippet ife
+	if ${1:condition}; then
+		${2:# statements}
+	else
+		${3:# statements}
+	fi
+snippet elif
+	elif ${1:condition} ; then
+		${2:# statements}
+snippet for
+	for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do
+		${3:# statements}
+	done
+snippet fore
+	for ${1:item} in ${2:list}; do
+		${3:# statements}
+	done
+snippet wh
+	while ${1:condition}; do
+		${2:# statements}
+	done
+snippet until
+	until ${1:condition}; do
+		${2:# statements}
+	done
+snippet repeat
+	repeat ${1:integer}; do
+		${2:# statements}
+	done
+snippet case
+	case ${1:word} in
+		${2:pattern})
+			${3};;
+	esac
+snippet select
+	select ${1:answer} in ${2:choices}; do
+		${3:# statements}
+	done
+snippet (
+	( ${1:#statements} )
+snippet {
+	{ ${1:#statements} }
+snippet [
+	[[ ${1:test} ]]
+snippet always
+	{ ${1:try} } always { ${2:always} }
+snippet fun
+	function ${1:name} (${2:args}) {
+		${3:# body}
+	}

+ 50 - 0
vim/spell/en.utf-8.add

@@ -0,0 +1,50 @@
+y
+fiducials
+API
+TUIO
+API's
+interactor
+extendable
+smartphones
+smartphone
+webcams
+Screenshot
+draggable
+timestamp
+preforked
+interpenetrate
+LockFreeTree
+CoarseGrainedList
+FineGrainedList
+LockFreeList
+CoarseGrainedTree
+FineGrainedTree
+runtimes
+pseudocode
+parallelizable
+MPI
+serializable
+virtualized
+virtualization
+leaderboard
+base64
+deobfuscation
+Warshall
+Grayscale
+grayscale
+Malware
+bytecode
+malware
+unobfuscated
+VPC
+obfuscator
+subtrace
+equational
+obfuscators
+deobfuscated
+Concolic
+concolic
+deobfuscate
+deobfuscating
+plugin
+stylesheet

BIN
vim/spell/en.utf-8.add.spl


BIN
vim/spell/nl.utf-8.spl


BIN
vim/spell/nl.utf-8.sug


+ 217 - 0
vim/syntax/coffee.vim

@@ -0,0 +1,217 @@
+" Language:    CoffeeScript
+" Maintainer:  Mick Koch <kchmck@gmail.com>
+" URL:         http://github.com/kchmck/vim-coffee-script
+" License:     WTFPL
+
+" Bail if our syntax is already loaded.
+if exists('b:current_syntax') && b:current_syntax == 'coffee'
+  finish
+endif
+
+" Include JavaScript for coffeeEmbed.
+syn include @coffeeJS syntax/javascript.vim
+
+" Highlight long strings.
+syn sync minlines=100
+
+" CoffeeScript identifiers can have dollar signs.
+setlocal isident+=$
+
+" These are `matches` instead of `keywords` because vim's highlighting
+" priority for keywords is higher than matches. This causes keywords to be
+" highlighted inside matches, even if a match says it shouldn't contain them --
+" like with coffeeAssign and coffeeDot.
+syn match coffeeStatement /\<\%(return\|break\|continue\|throw\)\>/ display
+hi def link coffeeStatement Statement
+
+syn match coffeeRepeat /\<\%(for\|while\|until\|loop\)\>/ display
+hi def link coffeeRepeat Repeat
+
+syn match coffeeConditional /\<\%(if\|else\|unless\|switch\|when\|then\)\>/
+\                           display
+hi def link coffeeConditional Conditional
+
+syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display
+hi def link coffeeException Exception
+
+syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\)\>/
+\                       display
+" The `own` keyword is only a keyword after `for`.
+syn match coffeeKeyword /\<for\s\+own\>/ contained containedin=coffeeRepeat
+\                       display
+hi def link coffeeKeyword Keyword
+
+syn match coffeeOperator /\<\%(instanceof\|typeof\|delete\)\>/ display
+hi def link coffeeOperator Operator
+
+" The first case matches symbol operators only if they have an operand before.
+syn match coffeeExtendedOp /\%(\S\s*\)\@<=[+\-*/%&|\^=!<>?.]\+\|[-=]>\|--\|++\|:/
+\                          display
+syn match coffeeExtendedOp /\<\%(and\|or\)=/ display
+hi def link coffeeExtendedOp coffeeOperator
+
+" This is separate from `coffeeExtendedOp` to help differentiate commas from
+" dots.
+syn match coffeeSpecialOp /[,;]/ display
+hi def link coffeeSpecialOp SpecialChar
+
+syn match coffeeBoolean /\<\%(true\|on\|yes\|false\|off\|no\)\>/ display
+hi def link coffeeBoolean Boolean
+
+syn match coffeeGlobal /\<\%(null\|undefined\)\>/ display
+hi def link coffeeGlobal Type
+
+" A special variable
+syn match coffeeSpecialVar /\<\%(this\|prototype\|arguments\)\>/ display
+" An @-variable
+syn match coffeeSpecialVar /@\%(\I\i*\)\?/ display
+hi def link coffeeSpecialVar Special
+
+" A class-like name that starts with a capital letter
+syn match coffeeObject /\<\u\w*\>/ display
+hi def link coffeeObject Structure
+
+" A constant-like name in SCREAMING_CAPS
+syn match coffeeConstant /\<\u[A-Z0-9_]\+\>/ display
+hi def link coffeeConstant Constant
+
+" A variable name
+syn cluster coffeeIdentifier contains=coffeeSpecialVar,coffeeObject,
+\                                     coffeeConstant
+
+" A non-interpolated string
+syn cluster coffeeBasicString contains=@Spell,coffeeEscape
+" An interpolated string
+syn cluster coffeeInterpString contains=@coffeeBasicString,coffeeInterp
+
+" Regular strings
+syn region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/
+\                       contains=@coffeeInterpString
+syn region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/
+\                       contains=@coffeeBasicString
+hi def link coffeeString String
+
+" A integer, including a leading plus or minus
+syn match coffeeNumber /\i\@<![-+]\?\d\+\%([eE][+-]\?\d\+\)\?/ display
+" A hex number
+syn match coffeeNumber /\<0[xX]\x\+\>/ display
+syn match coffeeNumber /\<0b[01]\+\>/ display
+hi def link coffeeNumber Number
+
+" A floating-point number, including a leading plus or minus
+syn match coffeeFloat /\i\@<![-+]\?\d*\.\@<!\.\d\+\%([eE][+-]\?\d\+\)\?/
+\                     display
+hi def link coffeeFloat Float
+
+" An error for reserved keywords
+if !exists("coffee_no_reserved_words_error")
+  syn match coffeeReservedError /\<\%(case\|default\|function\|var\|void\|with\|const\|let\|enum\|export\|import\|native\|__hasProp\|__extends\|__slice\|__bind\|__indexOf\)\>/
+  \                             display
+  hi def link coffeeReservedError Error
+endif
+
+" A normal object assignment
+syn match coffeeObjAssign /@\?\I\i*\s*\ze::\@!/ contains=@coffeeIdentifier display
+hi def link coffeeObjAssign Identifier
+
+syn keyword coffeeTodo TODO FIXME XXX contained
+hi def link coffeeTodo Todo
+
+syn match coffeeComment /#.*/ contains=@Spell,coffeeTodo
+hi def link coffeeComment Comment
+
+syn region coffeeBlockComment start=/####\@!/ end=/###/
+\                             contains=@Spell,coffeeTodo
+hi def link coffeeBlockComment coffeeComment
+
+" A comment in a heregex
+syn region coffeeHeregexComment start=/#/ end=/\ze\/\/\/\|$/ contained
+\                               contains=@Spell,coffeeTodo
+hi def link coffeeHeregexComment coffeeComment
+
+" Embedded JavaScript
+syn region coffeeEmbed matchgroup=coffeeEmbedDelim
+\                      start=/`/ skip=/\\\\\|\\`/ end=/`/
+\                      contains=@coffeeJS
+hi def link coffeeEmbedDelim Delimiter
+
+syn region coffeeInterp matchgroup=coffeeInterpDelim start=/#{/ end=/}/ contained
+\                       contains=@coffeeAll
+hi def link coffeeInterpDelim PreProc
+
+" A string escape sequence
+syn match coffeeEscape /\\\d\d\d\|\\x\x\{2\}\|\\u\x\{4\}\|\\./ contained display
+hi def link coffeeEscape SpecialChar
+
+" A regex -- must not follow a parenthesis, number, or identifier, and must not
+" be followed by a number
+syn region coffeeRegex start=/\%(\%()\|\i\@<!\d\)\s*\|\i\)\@<!\/=\@!\s\@!/
+\                      skip=/\[[^\]]\{-}\/[^\]]\{-}\]/
+\                      end=/\/[gimy]\{,4}\d\@!/
+\                      oneline contains=@coffeeBasicString
+hi def link coffeeRegex String
+
+" A heregex
+syn region coffeeHeregex start=/\/\/\// end=/\/\/\/[gimy]\{,4}/
+\                        contains=@coffeeInterpString,coffeeHeregexComment
+\                        fold
+hi def link coffeeHeregex coffeeRegex
+
+" Heredoc strings
+syn region coffeeHeredoc start=/"""/ end=/"""/ contains=@coffeeInterpString
+\                        fold
+syn region coffeeHeredoc start=/'''/ end=/'''/ contains=@coffeeBasicString
+\                        fold
+hi def link coffeeHeredoc String
+
+" An error for trailing whitespace, as long as the line isn't just whitespace
+if !exists("coffee_no_trailing_space_error")
+  syn match coffeeSpaceError /\S\@<=\s\+$/ display
+  hi def link coffeeSpaceError Error
+endif
+
+" An error for trailing semicolons, for help transitioning from JavaScript
+if !exists("coffee_no_trailing_semicolon_error")
+  syn match coffeeSemicolonError /;$/ display
+  hi def link coffeeSemicolonError Error
+endif
+
+" Ignore reserved words in dot accesses.
+syn match coffeeDotAccess /\.\@<!\.\s*\I\i*/he=s+1 contains=@coffeeIdentifier
+hi def link coffeeDotAccess coffeeExtendedOp
+
+" Ignore reserved words in prototype accesses.
+syn match coffeeProtoAccess /::\s*\I\i*/he=s+2 contains=@coffeeIdentifier
+hi def link coffeeProtoAccess coffeeExtendedOp
+
+" This is required for interpolations to work.
+syn region coffeeCurlies matchgroup=coffeeCurly start=/{/ end=/}/
+\                        contains=@coffeeAll
+syn region coffeeBrackets matchgroup=coffeeBracket start=/\[/ end=/\]/
+\                         contains=@coffeeAll
+syn region coffeeParens matchgroup=coffeeParen start=/(/ end=/)/
+\                       contains=@coffeeAll
+
+" These are highlighted the same as commas since they tend to go together.
+hi def link coffeeBlock coffeeSpecialOp
+hi def link coffeeBracket coffeeBlock
+hi def link coffeeCurly coffeeBlock
+hi def link coffeeParen coffeeBlock
+
+" This is used instead of TOP to keep things coffee-specific for good
+" embedding. `contained` groups aren't included.
+syn cluster coffeeAll contains=coffeeStatement,coffeeRepeat,coffeeConditional,
+\                              coffeeException,coffeeKeyword,coffeeOperator,
+\                              coffeeExtendedOp,coffeeSpecialOp,coffeeBoolean,
+\                              coffeeGlobal,coffeeSpecialVar,coffeeObject,
+\                              coffeeConstant,coffeeString,coffeeNumber,
+\                              coffeeFloat,coffeeReservedError,coffeeObjAssign,
+\                              coffeeComment,coffeeBlockComment,coffeeEmbed,
+\                              coffeeRegex,coffeeHeregex,coffeeHeredoc,
+\                              coffeeSpaceError,coffeeSemicolonError,
+\                              coffeeDotAccess,coffeeProtoAccess,
+\                              coffeeCurlies,coffeeBrackets,coffeeParens
+
+if !exists('b:current_syntax')
+  let b:current_syntax = 'coffee'
+endif

+ 62 - 0
vim/syntax/eco.vim

@@ -0,0 +1,62 @@
+" Vim syntax file
+" Language:		eco
+" Maintainer:		Jay Adkisson
+" Mostly stolen from eruby.vim
+
+if !exists("g:eco_default_subtype")
+  let g:eco_default_subtype = "html"
+endif
+
+if !exists("b:eco_subtype")
+  let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")
+  let b:eco_subtype = matchstr(s:lines,'eco_subtype=\zs\w\+')
+  if b:eco_subtype == ''
+    let b:eco_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.eco\)\+$','',''),'\.\zs\w\+$')
+  endif
+  if b:eco_subtype == 'rhtml'
+    let b:eco_subtype = 'html'
+  elseif b:eco_subtype == 'jst'
+    let b:eco_subtype = 'html'
+  elseif b:eco_subtype == 'rb'
+    let b:eco_subtype = 'ruby'
+  elseif b:eco_subtype == 'yml'
+    let b:eco_subtype = 'yaml'
+  elseif b:eco_subtype == 'js' || b:eco_subtype == 'json'
+    let b:eco_subtype = 'javascript'
+  elseif b:eco_subtype == 'txt'
+    " Conventional; not a real file type
+    let b:eco_subtype = 'text'
+  elseif b:eco_subtype == ''
+    if exists('b:current_syntax') && b:current_syntax != ''
+      let b:eco_subtype = b:current_syntax
+    else
+      let b:eco_subtype = g:eco_default_subtype
+    endif
+  endif
+endif
+
+if exists("b:eco_subtype") && b:eco_subtype != '' && b:eco_subtype != 'eco'
+  exec "runtime! syntax/".b:eco_subtype.".vim"
+  syn include @coffeeTop syntax/coffee.vim
+endif
+
+syn cluster ecoRegions contains=ecoBlock,ecoExpression,ecoComment
+
+syn region ecoBlock      matchgroup=ecoDelimiter start=/<%/      end=/%>/ contains=@coffeeTop containedin=ALLBUT,@ecoRegions keepend
+syn region ecoExpression matchgroup=ecoDelimiter start=/<%[=\-]/ end=/%>/ contains=@coffeeTop containedin=ALLBUT,@ecoRegions keepend
+syn region ecoComment    matchgroup=ecoComment   start=/<%#/     end=/%>/ contains=@coffeeTodo,@Spell containedin=ALLBUT,@ecoRegions keepend
+
+" eco features not in coffeescript proper
+syn keyword ecoEnd end containedin=@ecoRegions
+syn match ecoIndentColon /\s+\w+:/ containedin=@ecoRegions
+
+" Define the default highlighting.
+
+hi def link ecoDelimiter    Delimiter
+hi def link ecoComment      Comment
+hi def link ecoEnd          coffeeConditional
+hi def link ecoIndentColon  None
+
+let b:current_syntax = 'eco'
+
+" vim: nowrap sw=2 sts=2 ts=8:

+ 305 - 0
vim/syntax/less.vim

@@ -0,0 +1,305 @@
+" Vim syntax file
+" Language:	LESS Cascading Style Sheets
+" Maintainer:	Leaf Corcoran <leafot@gmail.com>
+" Modifier:	Bryan J Swift <bryan@bryanjswift.com>
+" URL: 		http://leafo.net/lessphp/vim/less.vim
+" URL:		http://gist.github.com/161047
+" Last Change:	2009 August 4
+" LESS by Leaf Corcoran
+" CSS2 by Nikolai Weibull
+" Full CSS2, HTML4 support by Yeti
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+  finish
+endif
+  let main_syntax = 'less'
+endif
+
+syn case ignore
+
+
+
+syn keyword cssTagName abbr acronym address applet area a b base
+syn keyword cssTagName basefont bdo big blockquote body br button
+syn keyword cssTagName caption center cite code col colgroup dd del
+syn keyword cssTagName dfn dir div dl dt em fieldset font form frame
+syn keyword cssTagName frameset h1 h2 h3 h4 h5 h6 head hr html img i
+syn keyword cssTagName iframe img input ins isindex kbd label legend li
+syn keyword cssTagName link map menu meta noframes noscript ol optgroup
+syn keyword cssTagName option p param pre q s samp script select small
+syn keyword cssTagName span strike strong style sub sup tbody td
+syn keyword cssTagName textarea tfoot th thead title tr tt ul u var
+syn match cssTagName "\<table\>"
+syn match cssTagName "\*"
+
+syn match cssTagName "@page\>" nextgroup=cssDefinition
+
+syn match cssSelectorOp "[+>.]"
+syn match cssSelectorOp2 "[~|]\?=" contained
+syn region cssAttributeSelector matchgroup=cssSelectorOp start="\[" end="]" transparent contains=cssUnicodeEscape,cssSelectorOp2,cssStringQ,cssStringQQ
+
+try
+syn match cssIdentifier "#[A-Za-zÀ-ÿ_@][A-Za-zÀ-ÿ0-9_@-]*"
+catch /^.*/
+syn match cssIdentifier "#[A-Za-z_@][A-Za-z0-9_@-]*"
+endtry
+
+syn match cssMedia "@media\>" nextgroup=cssMediaType skipwhite skipnl
+syn keyword cssMediaType contained screen print aural braile embosed handheld projection ty tv all nextgroup=cssMediaComma,cssMediaBlock skipwhite skipnl
+syn match cssMediaComma "," nextgroup=cssMediaType skipwhite skipnl
+syn region cssMediaBlock transparent matchgroup=cssBraces start='{' end='}' contains=cssTagName,cssError,cssComment,cssDefinition,cssURL,cssUnicodeEscape,cssIdentifier
+
+syn match cssValueInteger "[-+]\=\d\+"
+syn match cssValueNumber "[-+]\=\d\+\(\.\d*\)\="
+syn match cssValueLength "[-+]\=\d\+\(\.\d*\)\=\(%\|mm\|cm\|in\|pt\|pc\|em\|ex\|px\)"
+
+syn match cssValueAngle contained "[-+]\=\d\+\(\.\d*\)\=\(deg\|grad\|rad\)"
+syn match cssValueTime contained "+\=\d\+\(\.\d*\)\=\(ms\|s\)"
+syn match cssValueFrequency contained "+\=\d\+\(\.\d*\)\=\(Hz\|kHz\)"
+
+syn match cssFontDescriptor "@font-face\>" nextgroup=cssFontDescriptorBlock skipwhite skipnl
+syn region cssFontDescriptorBlock contained transparent matchgroup=cssBraces start="{" end="}" contains=cssComment,cssError,cssUnicodeEscape,cssFontProp,cssFontAttr,cssCommonAttr,cssStringQ,cssStringQQ,cssFontDescriptorProp,cssValue.*,cssFontDescriptorFunction,cssUnicodeRange,cssFontDescriptorAttr
+syn match cssFontDescriptorProp contained "\<\(unicode-range\|unit-per-em\|panose-1\|cap-height\|x-height\|definition-src\)\>"
+syn keyword cssFontDescriptorProp contained src stemv stemh slope ascent descent widths bbox baseline centerline mathline topline
+syn keyword cssFontDescriptorAttr contained all
+syn region cssFontDescriptorFunction contained matchgroup=cssFunctionName start="\<\(uri\|url\|local\|format\)\s*(" end=")" contains=cssStringQ,cssStringQQ oneline keepend
+syn match cssUnicodeRange contained "U+[0-9A-Fa-f?]\+"
+syn match cssUnicodeRange contained "U+\x\+-\x\+"
+
+syn keyword cssColor contained aqua black blue fuchsia gray green lime maroon navy olive purple red silver teal yellow
+" FIXME: These are actually case-insentivie too, but (a) specs recommend using
+" mixed-case (b) it's hard to highlight the word `Background' correctly in
+" all situations
+syn case match
+syn keyword cssColor contained ActiveBorder ActiveCaption AppWorkspace ButtonFace ButtonHighlight ButtonShadow ButtonText CaptionText GrayText Highlight HighlightText InactiveBorder InactiveCaption InactiveCaptionText InfoBackground InfoText Menu MenuText Scrollbar ThreeDDarkShadow ThreeDFace ThreeDHighlight ThreeDLightShadow ThreeDShadow Window WindowFrame WindowText Background
+syn case ignore
+syn match cssColor contained "\<transparent\>"
+syn match cssColor contained "\<white\>"
+syn match cssColor contained "#[0-9A-Fa-f]\{3\}\>"
+syn match cssColor contained "#[0-9A-Fa-f]\{6\}\>"
+"syn match cssColor contained "\<rgb\s*(\s*\d\+\(\.\d*\)\=%\=\s*,\s*\d\+\(\.\d*\)\=%\=\s*,\s*\d\+\(\.\d*\)\=%\=\s*)"
+syn region cssURL contained matchgroup=cssFunctionName start="\<url\s*(" end=")" oneline keepend
+syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgb\|clip\|attr\|counter\|rect\)\s*(" end=")" oneline keepend
+
+syn match cssImportant contained "!\s*important\>"
+
+syn keyword cssCommonAttr contained auto none inherit
+syn keyword cssCommonAttr contained top bottom
+syn keyword cssCommonAttr contained medium normal
+
+syn match cssFontProp contained "\<font\>\(-\(family\|style\|variant\|weight\|size\(-adjust\)\=\|stretch\)\>\)\="
+syn match cssFontAttr contained "\<\(sans-\)\=\<serif\>"
+syn match cssFontAttr contained "\<small\>\(-\(caps\|caption\)\>\)\="
+syn match cssFontAttr contained "\<x\{1,2\}-\(large\|small\)\>"
+syn match cssFontAttr contained "\<message-box\>"
+syn match cssFontAttr contained "\<status-bar\>"
+syn match cssFontAttr contained "\<\(\(ultra\|extra\|semi\|status-bar\)-\)\=\(condensed\|expanded\)\>"
+syn keyword cssFontAttr contained cursive fantasy monospace italic oblique
+syn keyword cssFontAttr contained bold bolder lighter larger smaller
+syn keyword cssFontAttr contained icon menu
+syn match cssFontAttr contained "\<caption\>"
+syn keyword cssFontAttr contained large smaller larger
+syn keyword cssFontAttr contained narrower wider
+
+syn keyword cssColorProp contained color
+syn match cssColorProp contained "\<background\(-\(color\|image\|attachment\|position\)\)\="
+syn keyword cssColorAttr contained center scroll fixed
+syn match cssColorAttr contained "\<repeat\(-[xy]\)\=\>"
+syn match cssColorAttr contained "\<no-repeat\>"
+
+syn match cssTextProp "\<\(\(word\|letter\)-spacing\|text\(-\(decoration\|transform\|align\|index\|shadow\)\)\=\|vertical-align\|unicode-bidi\|line-height\)\>"
+syn match cssTextAttr contained "\<line-through\>"
+syn match cssTextAttr contained "\<text-indent\>"
+syn match cssTextAttr contained "\<\(text-\)\=\(top\|bottom\)\>"
+syn keyword cssTextAttr contained underline overline blink sub super middle
+syn keyword cssTextAttr contained capitalize uppercase lowercase center justify baseline sub super
+
+syn match cssBoxProp contained "\<\(margin\|padding\|border\)\(-\(top\|right\|bottom\|left\)\)\=\>"
+syn match cssBoxProp contained "\<border-\(\(\(top\|right\|bottom\|left\)-\)\=\(width\|color\|style\)\)\=\>"
+syn match cssBoxProp contained "\<\(width\|z-index\)\>"
+syn match cssBoxProp contained "\<\(min\|max\)-\(width\|height\)\>"
+syn keyword cssBoxProp contained width height float clear overflow clip visibility
+syn keyword cssBoxAttr contained thin thick both
+syn keyword cssBoxAttr contained dotted dashed solid double groove ridge inset outset
+syn keyword cssBoxAttr contained hidden visible scroll collapse
+
+syn keyword cssGeneratedContentProp contained content quotes
+syn match cssGeneratedContentProp contained "\<counter-\(reset\|increment\)\>"
+syn match cssGeneratedContentProp contained "\<list-style\(-\(type\|position\|image\)\)\=\>"
+syn match cssGeneratedContentAttr contained "\<\(no-\)\=\(open\|close\)-quote\>"
+syn match cssAuralAttr contained "\<lower\>"
+syn match cssGeneratedContentAttr contained "\<\(lower\|upper\)-\(roman\|alpha\|greek\|latin\)\>"
+syn match cssGeneratedContentAttr contained "\<\(hiragana\|katakana\)\(-iroha\)\=\>"
+syn match cssGeneratedContentAttr contained "\<\(decimal\(-leading-zero\)\=\|cjk-ideographic\)\>"
+syn keyword cssGeneratedContentAttr contained disc circle square hebrew armenian georgian
+syn keyword cssGeneratedContentAttr contained inside outside
+
+syn match cssPagingProp contained "\<page\(-break-\(before\|after\|inside\)\)\=\>"
+syn keyword cssPagingProp contained size marks inside orphans widows
+syn keyword cssPagingAttr contained landscape portrait crop cross always avoid
+
+syn keyword cssUIProp contained cursor
+syn match cssUIProp contained "\<outline\(-\(width\|style\|color\)\)\=\>"
+syn match cssUIAttr contained "\<[ns]\=[ew]\=-resize\>"
+syn keyword cssUIAttr contained default crosshair pointer move wait help
+syn keyword cssUIAttr contained thin thick
+syn keyword cssUIAttr contained dotted dashed solid double groove ridge inset outset
+syn keyword cssUIAttr contained invert
+
+syn match cssRenderAttr contained "\<marker\>"
+syn match cssRenderProp contained "\<\(display\|marker-offset\|unicode-bidi\|white-space\|list-item\|run-in\|inline-table\)\>"
+syn keyword cssRenderProp contained position top bottom direction
+syn match cssRenderProp contained "\<\(left\|right\)\>"
+syn keyword cssRenderAttr contained block inline compact
+syn match cssRenderAttr contained "\<table\(-\(row-gorup\|\(header\|footer\)-group\|row\|column\(-group\)\=\|cell\|caption\)\)\=\>"
+syn keyword cssRenderAttr contained static relative absolute fixed
+syn keyword cssRenderAttr contained ltr rtl embed bidi-override pre nowrap
+syn match cssRenderAttr contained "\<bidi-override\>"
+
+syn match cssAuralProp contained "\<\(pause\|cue\)\(-\(before\|after\)\)\=\>"
+syn match cssAuralProp contained "\<\(play-during\|speech-rate\|voice-family\|pitch\(-range\)\=\|speak\(-\(punctuation\|numerals\)\)\=\)\>"
+syn keyword cssAuralProp contained volume during azimuth elevation stress richness
+syn match cssAuralAttr contained "\<\(x-\)\=\(soft\|loud\)\>"
+syn keyword cssAuralAttr contained silent
+syn match cssAuralAttr contained "\<spell-out\>"
+syn keyword cssAuralAttr contained non mix
+syn match cssAuralAttr contained "\<\(left\|right\)-side\>"
+syn match cssAuralAttr contained "\<\(far\|center\)-\(left\|center\|right\)\>"
+syn keyword cssAuralAttr contained leftwards rightwards behind
+syn keyword cssAuralAttr contained below level above higher
+syn match cssAuralAttr contained "\<\(x-\)\=\(slow\|fast\)\>"
+syn keyword cssAuralAttr contained faster slower
+syn keyword cssAuralAttr contained male female child code digits continuous
+
+syn match cssTableProp contained "\<\(caption-side\|table-layout\|border-collapse\|border-spacing\|empty-cells\|speak-header\)\>"
+syn keyword cssTableAttr contained fixed collapse separate show hide once always
+
+
+
+syn match lessComment "//.*$" contains=@Spell
+syn match lessVariable "@[A-Za-z_-][A-Za-z0-9_-]*" contained
+syn region lessVariableDefinition start="^@" end=";" contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssDefinition,cssClassName,cssTagName,cssIdentifier,lessComment,lessVariable,lessFunction
+
+" captures both the definition and the call
+syn region lessFunction matchgroup=lessFuncDef start="@[A-Za-z_-][A-Za-z0-9_-]*(" end=")" contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssDefinition,cssClassName,cssTagName,cssIdentifier,lessComment,lessVariable,lessFunction
+
+
+
+
+
+" FIXME: This allows cssMediaBlock before the semicolon, which is wrong.
+syn region cssInclude start="@import" end=";" contains=cssComment,cssURL,cssUnicodeEscape,cssMediaType
+syn match cssBraces contained "[{}]"
+syn match cssError contained "{@<>"
+syn region cssDefinition transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssDefinition,cssClassName,cssTagName,cssIdentifier,lessComment,lessVariable,lessFunction
+" syn match cssBraceError "}"
+
+syn match cssPseudoClass ":\S*" contains=cssPseudoClassId,cssUnicodeEscape
+syn keyword cssPseudoClassId contained link visited active hover focus before after left right
+syn match cssPseudoClassId contained "\<first\(-\(line\|letter\|child\)\)\=\>"
+syn region cssPseudoClassLang matchgroup=cssPseudoClassId start=":lang(" end=")" oneline
+
+syn region cssComment start="/\*" end="\*/" contains=@Spell
+
+syn match cssUnicodeEscape "\\\x\{1,6}\s\?"
+syn match cssSpecialCharQQ +\\"+ contained
+syn match cssSpecialCharQ +\\'+ contained
+syn region cssStringQQ start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=cssUnicodeEscape,cssSpecialCharQQ
+syn region cssStringQ start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=cssUnicodeEscape,cssSpecialCharQ
+syn match cssClassName "\.[A-Za-z][A-Za-z0-9_-]\+"
+
+
+
+
+if main_syntax == "css"
+  syn sync minlines=10
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_less_syn_inits")
+  if version < 508
+    let did_less_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink lessComment Comment
+  HiLink lessVariable Special
+  HiLink lessFuncDef Function
+  HiLink cssComment Comment
+  HiLink cssTagName Statement
+  HiLink cssSelectorOp Special
+  HiLink cssSelectorOp2 Special
+  HiLink cssFontProp StorageClass
+  HiLink cssColorProp storageClass
+  HiLink cssTextProp StorageClass
+  HiLink cssBoxProp StorageClass
+  HiLink cssRenderProp StorageClass
+  HiLink cssAuralProp StorageClass
+  HiLink cssRenderProp StorageClass
+  HiLink cssGeneratedContentProp StorageClass
+  HiLink cssPagingProp StorageClass
+  HiLink cssTableProp StorageClass
+  HiLink cssUIProp StorageClass
+  HiLink cssFontAttr Type
+  HiLink cssColorAttr Type
+  HiLink cssTextAttr Type
+  HiLink cssBoxAttr Type
+  HiLink cssRenderAttr Type
+  HiLink cssAuralAttr Type
+  HiLink cssGeneratedContentAttr Type
+  HiLink cssPagingAttr Type
+  HiLink cssTableAttr Type
+  HiLink cssUIAttr Type
+  HiLink cssCommonAttr Type
+  HiLink cssPseudoClassId PreProc
+  HiLink cssPseudoClassLang Constant
+  HiLink cssValueLength Number
+  HiLink cssValueInteger Number
+  HiLink cssValueNumber Number
+  HiLink cssValueAngle Number
+  HiLink cssValueTime Number
+  HiLink cssValueFrequency Number
+  HiLink cssFunction Constant
+  HiLink cssURL String
+  HiLink cssFunctionName Function
+  HiLink cssColor Constant
+  HiLink cssIdentifier Function
+  HiLink cssInclude Include
+  HiLink cssImportant Special
+  HiLink cssBraces SpecialChar
+  HiLink cssBraceError Error
+  HiLink cssError Error
+  HiLink cssInclude Include
+  HiLink cssUnicodeEscape Special
+  HiLink cssStringQQ String
+  HiLink cssStringQ String
+  HiLink cssMedia Special
+  HiLink cssMediaType Special
+  HiLink cssMediaComma Normal
+  HiLink cssFontDescriptor Special
+  HiLink cssFontDescriptorFunction Constant
+  HiLink cssFontDescriptorProp StorageClass
+  HiLink cssFontDescriptorAttr Type
+  HiLink cssUnicodeRange Constant
+  HiLink cssClassName Function
+  delcommand HiLink
+endif
+
+let b:current_syntax = "less"
+
+if main_syntax == 'less'
+  unlet main_syntax
+endif
+
+
+" vim: ts=8
+

+ 331 - 0
vim/syntax/ocaml.vim

@@ -0,0 +1,331 @@
+" Vim syntax file
+" Language:     OCaml
+" Filenames:    *.ml *.mli *.mll *.mly
+" Maintainers:  Markus Mottl      <markus.mottl@gmail.com>
+"               Karl-Heinz Sylla  <Karl-Heinz.Sylla@gmd.de>
+"               Issac Trotts      <ijtrotts@ucdavis.edu>
+" URL:          http://www.ocaml.info/vim/syntax/ocaml.vim
+" Last Change:  2010 Oct 11 - Added highlighting of lnot (MM, thanks to Erick Matsen)
+"               2010 Sep 03 - Fixed escaping bug (MM, thanks to Florent Monnier)
+"               2010 Aug 07 - Fixed module type bug (MM)
+
+" A minor patch was applied to the official version so that object/end
+" can be distinguished from begin/end, which is used for indentation,
+" and folding. (David Baelde)
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax") && b:current_syntax == "ocaml"
+  finish
+endif
+
+" OCaml is case sensitive.
+syn case match
+
+" Access to the method of an object
+syn match    ocamlMethod       "#"
+
+" Script headers highlighted like comments
+syn match    ocamlComment   "^#!.*"
+
+" Scripting directives
+syn match    ocamlScript "^#\<\(quit\|labels\|warnings\|directory\|cd\|load\|use\|install_printer\|remove_printer\|require\|thread\|trace\|untrace\|untrace_all\|print_depth\|print_length\|camlp4o\)\>"
+
+" lowercase identifier - the standard way to match
+syn match    ocamlLCIdentifier /\<\(\l\|_\)\(\w\|'\)*\>/
+
+syn match    ocamlKeyChar    "|"
+
+" Errors
+syn match    ocamlBraceErr   "}"
+syn match    ocamlBrackErr   "\]"
+syn match    ocamlParenErr   ")"
+syn match    ocamlArrErr     "|]"
+
+syn match    ocamlCommentErr "\*)"
+
+syn match    ocamlCountErr   "\<downto\>"
+syn match    ocamlCountErr   "\<to\>"
+
+if !exists("ocaml_revised")
+  syn match    ocamlDoErr      "\<do\>"
+endif
+
+syn match    ocamlDoneErr    "\<done\>"
+syn match    ocamlThenErr    "\<then\>"
+
+" Error-highlighting of "end" without synchronization:
+" as keyword or as error (default)
+if exists("ocaml_noend_error")
+  syn match    ocamlKeyword    "\<end\>"
+else
+  syn match    ocamlEndErr     "\<end\>"
+endif
+
+" Some convenient clusters
+syn cluster  ocamlAllErrs contains=ocamlBraceErr,ocamlBrackErr,ocamlParenErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr
+
+syn cluster  ocamlAENoParen contains=ocamlBraceErr,ocamlBrackErr,ocamlCommentErr,ocamlCountErr,ocamlDoErr,ocamlDoneErr,ocamlEndErr,ocamlThenErr
+
+syn cluster  ocamlContained contains=ocamlTodo,ocamlPreDef,ocamlModParam,ocamlModParam1,ocamlPreMPRestr,ocamlMPRestr,ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3,ocamlModRHS,ocamlFuncWith,ocamlFuncStruct,ocamlModTypeRestr,ocamlModTRWith,ocamlWith,ocamlWithRest,ocamlModType,ocamlFullMod,ocamlVal
+
+
+" Enclosing delimiters
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="(" matchgroup=ocamlKeyword end=")" contains=ALLBUT,@ocamlContained,ocamlParenErr
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="{" matchgroup=ocamlKeyword end="}"  contains=ALLBUT,@ocamlContained,ocamlBraceErr
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="\[" matchgroup=ocamlKeyword end="\]" contains=ALLBUT,@ocamlContained,ocamlBrackErr
+syn region   ocamlEncl transparent matchgroup=ocamlKeyword start="\[|" matchgroup=ocamlKeyword end="|\]" contains=ALLBUT,@ocamlContained,ocamlArrErr
+
+
+" Comments
+syn region   ocamlComment start="(\*" end="\*)" contains=ocamlComment,ocamlTodo
+syn keyword  ocamlTodo contained TODO FIXME XXX NOTE
+
+
+" Objects
+syn region   ocamlEnd matchgroup=ocamlObject start="\<object\>" matchgroup=ocamlObject end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+
+
+" Blocks
+if !exists("ocaml_revised")
+  syn region   ocamlEnd matchgroup=ocamlKeyword start="\<begin\>" matchgroup=ocamlKeyword end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+endif
+
+
+" "for"
+syn region   ocamlNone matchgroup=ocamlKeyword start="\<for\>" matchgroup=ocamlKeyword end="\<\(to\|downto\)\>" contains=ALLBUT,@ocamlContained,ocamlCountErr
+
+
+" "do"
+if !exists("ocaml_revised")
+  syn region   ocamlDo matchgroup=ocamlKeyword start="\<do\>" matchgroup=ocamlKeyword end="\<done\>" contains=ALLBUT,@ocamlContained,ocamlDoneErr
+endif
+
+" "if"
+syn region   ocamlNone matchgroup=ocamlKeyword start="\<if\>" matchgroup=ocamlKeyword end="\<then\>" contains=ALLBUT,@ocamlContained,ocamlThenErr
+
+
+"" Modules
+
+" "sig"
+syn region   ocamlSig matchgroup=ocamlModule start="\<sig\>" matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule
+syn region   ocamlModSpec matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contained contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlModTRWith,ocamlMPRestr
+
+" "open"
+syn region   ocamlNone matchgroup=ocamlKeyword start="\<open\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*\>" contains=@ocamlAllErrs,ocamlComment
+
+" "include"
+syn match    ocamlKeyword "\<include\>" skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
+
+" "module" - somewhat complicated stuff ;-)
+syn region   ocamlModule matchgroup=ocamlKeyword start="\<module\>" matchgroup=ocamlModule end="\<\u\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlPreDef
+syn region   ocamlPreDef start="."me=e-1 matchgroup=ocamlKeyword end="\l\|=\|)"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam,ocamlModTypeRestr,ocamlModTRWith nextgroup=ocamlModPreRHS
+syn region   ocamlModParam start="([^*]" end=")" contained contains=@ocamlAENoParen,ocamlModParam1,ocamlVal
+syn match    ocamlModParam1 "\<\u\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlPreMPRestr
+
+syn region   ocamlPreMPRestr start="."me=e-1 end=")"me=e-1 contained contains=@ocamlAllErrs,ocamlComment,ocamlMPRestr,ocamlModTypeRestr
+
+syn region   ocamlMPRestr start=":" end="."me=e-1 contained contains=@ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr1,ocamlMPRestr2,ocamlMPRestr3
+syn region   ocamlMPRestr1 matchgroup=ocamlModule start="\ssig\s\=" matchgroup=ocamlModule end="\<end\>" contained contains=ALLBUT,@ocamlContained,ocamlEndErr,ocamlModule
+syn region   ocamlMPRestr2 start="\sfunctor\(\s\|(\)\="me=e-1 matchgroup=ocamlKeyword end="->" contained contains=@ocamlAllErrs,ocamlComment,ocamlModParam skipwhite skipempty nextgroup=ocamlFuncWith,ocamlMPRestr2
+syn match    ocamlMPRestr3 "\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*" contained
+syn match    ocamlModPreRHS "=" contained skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
+syn keyword  ocamlKeyword val
+syn region   ocamlVal matchgroup=ocamlKeyword start="\<val\>" matchgroup=ocamlLCIdentifier end="\<\l\(\w\|'\)*\>" contains=@ocamlAllErrs,ocamlComment skipwhite skipempty nextgroup=ocamlMPRestr
+syn region   ocamlModRHS start="." end=".\w\|([^*]"me=e-2 contained contains=ocamlComment skipwhite skipempty nextgroup=ocamlModParam,ocamlFullMod
+syn match    ocamlFullMod "\<\u\(\w\|'\)*\(\.\u\(\w\|'\)*\)*" contained skipwhite skipempty nextgroup=ocamlFuncWith
+
+syn region   ocamlFuncWith start="([^*]"me=e-1 end=")" contained contains=ocamlComment,ocamlWith,ocamlFuncStruct skipwhite skipempty nextgroup=ocamlFuncWith
+syn region   ocamlFuncStruct matchgroup=ocamlModule start="[^a-zA-Z]struct\>"hs=s+1 matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+
+syn match    ocamlModTypeRestr "\<\w\(\w\|'\)*\(\.\w\(\w\|'\)*\)*\>" contained
+syn region   ocamlModTRWith start=":\s*("hs=s+1 end=")" contained contains=@ocamlAENoParen,ocamlWith
+syn match    ocamlWith "\<\(\u\(\w\|'\)*\.\)*\w\(\w\|'\)*\>" contained skipwhite skipempty nextgroup=ocamlWithRest
+syn region   ocamlWithRest start="[^)]" end=")"me=e-1 contained contains=ALLBUT,@ocamlContained
+
+" "struct"
+syn region   ocamlStruct matchgroup=ocamlModule start="\<\(module\s\+\)\=struct\>" matchgroup=ocamlModule end="\<end\>" contains=ALLBUT,@ocamlContained,ocamlEndErr
+
+" "module type"
+syn region   ocamlKeyword start="\<module\>\s*\<type\>\(\s*\<of\>\)\=" matchgroup=ocamlModule end="\<\w\(\w\|'\)*\>" contains=ocamlComment skipwhite skipempty nextgroup=ocamlMTDef
+syn match    ocamlMTDef "=\s*\w\(\w\|'\)*\>"hs=s+1,me=s
+
+syn keyword  ocamlKeyword  and as assert class
+syn keyword  ocamlKeyword  constraint else
+syn keyword  ocamlKeyword  exception external fun
+
+syn keyword  ocamlKeyword  in inherit initializer
+syn keyword  ocamlKeyword  land lazy let match
+syn keyword  ocamlKeyword  method mutable new of
+syn keyword  ocamlKeyword  parser private raise rec
+syn keyword  ocamlKeyword  try type
+syn keyword  ocamlKeyword  virtual when while with
+
+if exists("ocaml_revised")
+  syn keyword  ocamlKeyword  do value
+  syn keyword  ocamlBoolean  True False
+else
+  syn keyword  ocamlKeyword  function
+  syn keyword  ocamlBoolean  true false
+  syn match    ocamlKeyChar  "!"
+endif
+
+syn keyword  ocamlType     array bool char exn float format format4
+syn keyword  ocamlType     int int32 int64 lazy_t list nativeint option
+syn keyword  ocamlType     string unit
+
+syn keyword  ocamlOperator asr lnot lor lsl lsr lxor mod not
+
+syn match    ocamlConstructor  "(\s*)"
+syn match    ocamlConstructor  "\[\s*\]"
+syn match    ocamlConstructor  "\[|\s*>|]"
+syn match    ocamlConstructor  "\[<\s*>\]"
+syn match    ocamlConstructor  "\u\(\w\|'\)*\>"
+
+" Polymorphic variants
+syn match    ocamlConstructor  "`\w\(\w\|'\)*\>"
+
+" Module prefix
+syn match    ocamlModPath      "\u\(\w\|'\)*\."he=e-1
+
+syn match    ocamlCharacter    "'\\\d\d\d'\|'\\[\'ntbr]'\|'.'"
+syn match    ocamlCharacter    "'\\x\x\x'"
+syn match    ocamlCharErr      "'\\\d\d'\|'\\\d'"
+syn match    ocamlCharErr      "'\\[^\'ntbr]'"
+syn region   ocamlString       start=+"+ skip=+\\\\\|\\"+ end=+"+
+
+syn match    ocamlFunDef       "->"
+syn match    ocamlRefAssign    ":="
+syn match    ocamlTopStop      ";;"
+syn match    ocamlOperator     "\^"
+syn match    ocamlOperator     "::"
+
+syn match    ocamlOperator     "&&"
+syn match    ocamlOperator     "<"
+syn match    ocamlOperator     ">"
+syn match    ocamlAnyVar       "\<_\>"
+syn match    ocamlKeyChar      "|[^\]]"me=e-1
+syn match    ocamlKeyChar      ";"
+syn match    ocamlKeyChar      "\~"
+syn match    ocamlKeyChar      "?"
+syn match    ocamlKeyChar      "\*"
+syn match    ocamlKeyChar      "="
+
+if exists("ocaml_revised")
+  syn match    ocamlErr        "<-"
+else
+  syn match    ocamlOperator   "<-"
+endif
+
+syn match    ocamlNumber        "\<-\=\d\(_\|\d\)*[l|L|n]\?\>"
+syn match    ocamlNumber        "\<-\=0[x|X]\(\x\|_\)\+[l|L|n]\?\>"
+syn match    ocamlNumber        "\<-\=0[o|O]\(\o\|_\)\+[l|L|n]\?\>"
+syn match    ocamlNumber        "\<-\=0[b|B]\([01]\|_\)\+[l|L|n]\?\>"
+syn match    ocamlFloat         "\<-\=\d\(_\|\d\)*\.\?\(_\|\d\)*\([eE][-+]\=\d\(_\|\d\)*\)\=\>"
+
+" Labels
+syn match    ocamlLabel        "\~\(\l\|_\)\(\w\|'\)*"lc=1
+syn match    ocamlLabel        "?\(\l\|_\)\(\w\|'\)*"lc=1
+syn region   ocamlLabel transparent matchgroup=ocamlLabel start="?(\(\l\|_\)\(\w\|'\)*"lc=2 end=")"me=e-1 contains=ALLBUT,@ocamlContained,ocamlParenErr
+
+
+" Synchronization
+syn sync minlines=50
+syn sync maxlines=500
+
+if !exists("ocaml_revised")
+  syn sync match ocamlDoSync      grouphere  ocamlDo      "\<do\>"
+  syn sync match ocamlDoSync      groupthere ocamlDo      "\<done\>"
+endif
+
+if exists("ocaml_revised")
+  syn sync match ocamlEndSync     grouphere  ocamlEnd     "\<\(object\)\>"
+else
+  syn sync match ocamlEndSync     grouphere  ocamlEnd     "\<\(begin\|object\)\>"
+endif
+
+syn sync match ocamlEndSync     groupthere ocamlEnd     "\<end\>"
+syn sync match ocamlStructSync  grouphere  ocamlStruct  "\<struct\>"
+syn sync match ocamlStructSync  groupthere ocamlStruct  "\<end\>"
+syn sync match ocamlSigSync     grouphere  ocamlSig     "\<sig\>"
+syn sync match ocamlSigSync     groupthere ocamlSig     "\<end\>"
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_ocaml_syntax_inits")
+  if version < 508
+    let did_ocaml_syntax_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink ocamlBraceErr	   Error
+  HiLink ocamlBrackErr	   Error
+  HiLink ocamlParenErr	   Error
+  HiLink ocamlArrErr	   Error
+
+  HiLink ocamlCommentErr   Error
+
+  HiLink ocamlCountErr	   Error
+  HiLink ocamlDoErr	   Error
+  HiLink ocamlDoneErr	   Error
+  HiLink ocamlEndErr	   Error
+  HiLink ocamlThenErr	   Error
+
+  HiLink ocamlCharErr	   Error
+
+  HiLink ocamlErr	   Error
+
+  HiLink ocamlComment	   Comment
+
+  HiLink ocamlModPath	   Include
+  HiLink ocamlObject	   Include
+  HiLink ocamlModule	   Include
+  HiLink ocamlModParam1    Include
+  HiLink ocamlModType	   Include
+  HiLink ocamlMPRestr3	   Include
+  HiLink ocamlFullMod	   Include
+  HiLink ocamlModTypeRestr Include
+  HiLink ocamlWith	   Include
+  HiLink ocamlMTDef	   Include
+
+  HiLink ocamlScript	   Include
+
+  HiLink ocamlConstructor  Constant
+
+  HiLink ocamlVal          Keyword
+  HiLink ocamlModPreRHS    Keyword
+  HiLink ocamlMPRestr2	   Keyword
+  HiLink ocamlKeyword	   Keyword
+  HiLink ocamlMethod	   Include
+  HiLink ocamlFunDef	   Keyword
+  HiLink ocamlRefAssign    Keyword
+  HiLink ocamlKeyChar	   Keyword
+  HiLink ocamlAnyVar	   Keyword
+  HiLink ocamlTopStop	   Keyword
+  HiLink ocamlOperator	   Keyword
+
+  HiLink ocamlBoolean	   Boolean
+  HiLink ocamlCharacter    Character
+  HiLink ocamlNumber	   Number
+  HiLink ocamlFloat	   Float
+  HiLink ocamlString	   String
+
+  HiLink ocamlLabel	   Identifier
+
+  HiLink ocamlType	   Type
+
+  HiLink ocamlTodo	   Todo
+
+  HiLink ocamlEncl	   Keyword
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "ocaml"
+
+" vim: ts=8

+ 19 - 0
vim/syntax/snippet.vim

@@ -0,0 +1,19 @@
+" Syntax highlighting for snippet files (used for snipMate.vim)
+" Hopefully this should make snippets a bit nicer to write!
+syn match snipComment '^#.*'
+syn match placeHolder '\${\d\+\(:.\{-}\)\=}' contains=snipCommand
+syn match tabStop '\$\d\+'
+syn match snipCommand '[^\\]`.\{-}`'
+syn match snippet '^snippet.*' transparent contains=multiSnipText,snipKeyword
+syn match multiSnipText '\S\+ \zs.*' contained
+syn match snipKeyword '^snippet'me=s+8 contained
+syn match snipError "^[^#s\t].*$"
+
+hi link snipComment   Comment
+hi link multiSnipText String
+hi link snipKeyword   Keyword
+hi link snipComment   Comment
+hi link placeHolder   Special
+hi link tabStop       Special
+hi link snipCommand   String
+hi link snipError     Error

+ 190 - 0
vimrc

@@ -0,0 +1,190 @@
+set ruler
+hi SpellBad     guisp=#fcaf3e cterm=underline
+set expandtab
+set modeline
+
+set tabstop=4     " a tab is four spaces
+set backspace=indent,eol,start
+                  " allow backspacing over everything in insert mode
+set autoindent    " always set autoindenting on
+set copyindent    " copy the previous indentation on autoindenting
+set number        " always show line numbers
+set shiftwidth=4  " number of spaces to use for autoindenting
+set shiftround    " use multiple of shiftwidth when indenting with '<' and '>'
+set ignorecase    " ignore case when searching
+set smartcase     " ignore case if search pattern is all lowercase,
+                  "    case-sensitive otherwise
+set smarttab      " insert tabs on the start of a line according to
+                  "    shiftwidth, not tabstop
+set hlsearch      " highlight search terms
+set incsearch     " show search matches as you type
+
+set history=1000    " remember more commands and search history
+set undolevels=1000 " use many muchos levels of undo
+set wildignore=*.swp,*.bak,*.pyc,*.class,*.old
+
+set textwidth=79
+set vb t_vb=
+
+set ls=2          " always display filename
+
+" IMPORTANT: Uncomment one of the following lines to force
+" using 256 colors (or 88 colors) if your terminal supports it,
+" but does not automatically use 256 colors by default.
+
+" -- run in gnome-terminal: --
+" export TERM="xterm-256color"
+"
+set t_Co=88
+
+if $TERM == 'xterm-256color'
+	set t_Co=256
+endif
+
+" ,rl = run pdflatex (on current file)
+map ,rl :!pdflatex -src -shell-escape -interaction=nonstopmode %
+
+" trigger pdflatex (above) on FileWritePost event
+":autocmd BufWritePost *.tex :!pdflatex -src -shell-escape -interaction=nonstopmode % | grep -A 4 -i "error"
+:autocmd BufNewFile,BufRead *.tex :set spell
+
+"augroup vimrc_autocmds
+"    autocmd BufEnter * highlight OverLength ctermbg=darkgrey guibg=#592929
+"    autocmd BufEnter * match OverLength /\%81v.*/
+"augroup END
+
+" configure tags - add additional tags here or comment out not-used ones
+" cd /usr/include
+" ctags -R --sort=yes --fields=+iaS -f ~/.vim/tags/stdc stdio.h stdlib.h \
+"   pthread.h math.h assert.h errno.h malloc.h strings.h fcntl.h unistd.h
+" ctags -R --sort=yes --fields=+iaS -f ~/.vim/tags/gl GL/
+"set tags+=~/.vim/tags/stdc
+"set tags+=~/.vim/tags/gl
+
+
+" build tags of your own project with CTRL+F12
+"map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
+"noremap <F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<cr>
+"inoremap <F12> <Esc>:!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<cr>
+
+"" OmniCppComplete
+"let OmniCpp_NamespaceSearch = 1
+"let OmniCpp_GlobalScopeSearch = 1
+"let OmniCpp_ShowAccess = 1
+"let OmniCpp_MayCompleteDot = 1
+"let OmniCpp_MayCompleteArrow = 1
+"let OmniCpp_MayCompleteScope = 1
+"let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
+
+"" automatically open and close the popup menu / preview window
+"au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
+""set completeopt=menuone,menu,longest,preview
+"set completeopt=menuone,menu " ,longest,preview
+
+"set nocp
+filetype plugin on
+
+"set background=dark
+"colorscheme darkspectrum
+runtime! plugin/guicolorscheme.vim
+GuiColorScheme darkspectrum
+
+" Wildmenu
+set wildmenu        " use wildmenu
+set wildcharm=<TAB> " autocomplete
+set wildignore=*.swp,*.bak,*.pyc,*.class,*.old
+
+" ------------------
+" Various vim tweaks
+" ------------------
+set title           " change the terminal's title
+set visualbell      " don't beep
+set noerrorbells    " don't beep
+set nocp            " Disable Vi-compatibility
+
+" syntax detection and filetype indention
+filetype plugin indent on
+syntax enable
+
+autocmd BufReadPre *.pdf set ro nowrap
+autocmd BufReadPost *.pdf silent %!pdftotext "%" -nopgbrk -layout -q -eol unix -
+
+" C syntax highlighting for CiviC files
+au BufNewFile,BufRead *.cvc set filetype=c
+
+" Automatically remove all trailing spaces
+autocmd BufWritePre * :%s/\s\+$//e
+
+" -----------------
+" Source completion
+" -----------------
+au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
+"set completeopt=menuone,menu
+
+" --------------
+" Source folding
+" --------------
+"set foldmethod=indent
+
+" -------------
+" File explorer
+" -------------
+
+let g:netrw_liststyle=3    " Use tree-mode as default view
+"let g:netrw_browse_split=4 " Open file in previous buffer
+let g:netrw_preview=1      " Preview window shown in a vertically split
+
+" ------------
+" Key bindings
+" ------------
+
+" skip the press and hold 'shift' + press ';' + release 'shift'.
+" Now you can simply use ';' instead of ':'.
+nnoremap ; :
+
+" Use Q for formatting the current paragraph (or selection)
+vmap Q gq
+nmap Q gqap
+
+" Unbind Shift + up/down
+vmap <s-up> <up>
+nmap <s-up> <up>
+vmap <s-down> <down>
+nmap <s-down> <down>
+
+" If you like long lines with line wrapping enabled, this solves the problem
+" that pressing down jumpes your cursor “over” the current line to the next
+" line. It changes behaviour so that it jumps to the next row in the editor.
+nnoremap j gj
+nnoremap k gk
+
+" Easy window navigation
+map <C-h> <C-w>h
+map <C-j> <C-w>j
+map <C-k> <C-w>k
+map <C-l> <C-w>l
+
+" It clears the search buffer (and highlighting) when you press ,/
+nmap <silent> ,/ :nohlsearch<CR>
+nmap <silent> ,mt :!make check<CR>
+nmap <silent> ,mc :!make coverage<CR>
+nmap <silent> ,ml :!make clean<CR>
+nmap <silent> ,mm :!make<CR>
+nmap <silent> ,mM :!make && make<CR>
+nmap <silent> ,md :!make doc<CR>
+nmap <silent> ,mb :!make -B<CR>
+nmap <silent> ,a :!ant<CR>
+
+" when you forgot to sudo before editing a file that requires root privileges.
+" This lets you use w!! to do that after you opened the file already:
+cmap w!! w !sudo tee % >/dev/null
+
+" Status line highlight
+:hi StatusLine ctermbg=black ctermfg=grey
+
+" Syntax highlighting for .less files
+au BufNewFile,BufRead *.less set filetype=less
+
+set fileformats=unix
+
+let mapleader=","

Vissa filer visades inte eftersom för många filer har ändrats