Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Lua

  • Loading branch information...
commit 64f6e6cd094c750fdaaa5e4ec94af5e48f02ad4a 1 parent 439ab3c
@seejohnrun authored
View
483 .vim/autoload/xolox/lua.vim
@@ -0,0 +1,483 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: November 25, 2011
+" URL: http://peterodding.com/code/vim/lua-ftplugin
+
+let g:xolox#lua#version = '0.7'
+let s:miscdir = expand('<sfile>:p:h:h:h') . '/misc/lua-ftplugin'
+let s:omnicomplete_script = s:miscdir . '/omnicomplete.lua'
+let s:globals_script = s:miscdir . '/globals.lua'
+
+function! xolox#lua#includeexpr(fname) " {{{1
+ " Search module path for matching Lua scripts.
+ let module = substitute(a:fname, '\.', '/', 'g')
+ for template in xolox#lua#getsearchpath('$LUA_PATH', 'package.path')
+ let expanded = substitute(template, '?', module, 'g')
+ call xolox#misc#msg#debug("lua.vim %s: Expanded %s -> %s", g:xolox#lua#version, template, expanded)
+ if filereadable(expanded)
+ call xolox#misc#msg#debug("lua.vim %s: Matched existing file %s", g:xolox#lua#version, expanded)
+ return expanded
+ endif
+ endfor
+ " Default to given name.
+ return a:fname
+endfunction
+
+function! xolox#lua#getsearchpath(envvar, luavar) " {{{1
+ let path = ''
+ if has('lua')
+ " Try to get the search path using the Lua Interface for Vim.
+ try
+ redir => path
+ execute 'silent lua print(' . a:luavar . ')'
+ redir END
+ call xolox#misc#msg#debug("lua.vim %s: Got %s from Lua Interface for Vim", g:xolox#lua#version, a:luavar)
+ catch
+ redir END
+ endtry
+ endif
+ if empty(path)
+ let path = eval(a:envvar)
+ if !empty(path)
+ call xolox#misc#msg#debug("lua.vim %s: Got %s from %s", g:xolox#lua#version, a:luavar, a:envvar)
+ else
+ try
+ let path = xolox#misc#os#exec('lua -e "io.write(' . a:luavar . ')"')[0]
+ call xolox#misc#msg#debug("lua.vim %s: Got %s from external Lua interpreter", g:xolox#lua#version, a:luavar)
+ catch
+ call xolox#misc#msg#warn("lua.vim %s: Failed to get %s from external Lua interpreter: %s", g:xolox#lua#version, a:luavar, v:exception)
+ endtry
+ endif
+ endif
+ return split(xolox#misc#str#trim(path), ';')
+endfunction
+
+function! xolox#lua#autocheck() " {{{1
+ if &filetype == 'lua'
+ if xolox#misc#option#get('lua_check_syntax', 1)
+ call xolox#lua#checksyntax()
+ endif
+ if xolox#misc#option#get('lua_check_globals', 0) && empty(getqflist())
+ call xolox#lua#checkglobals(0)
+ endif
+ endif
+endfunction
+
+function! xolox#lua#checksyntax() " {{{1
+ let compiler_name = xolox#misc#option#get('lua_compiler_name', 'luac')
+ let compiler_args = xolox#misc#option#get('lua_compiler_args', '-p')
+ let error_format = xolox#misc#option#get('lua_error_format', 'luac: %f:%l: %m')
+ if !executable(compiler_name)
+ let message = "lua.vim %s: The configured Lua compiler"
+ let message .= " doesn't seem to be available! I'm disabling"
+ let message .= " automatic syntax checking for Lua scripts."
+ let g:lua_check_syntax = 0
+ call xolox#misc#msg#warn(message, g:xolox#lua#version)
+ return
+ endif
+ " Check for errors using my shell.vim plug-in so that executing
+ " luac.exe on Windows doesn't pop up the nasty console window.
+ let command = [compiler_name, compiler_args, xolox#misc#escape#shell(expand('%'))]
+ let lines = xolox#misc#os#exec(join(command))
+ if empty(lines)
+ " Clear location list.
+ call setloclist(winnr(), [], 'r')
+ lclose
+ return
+ endif
+ " Save the errors to a file we can load with :lgetfile.
+ let errorfile = tempname()
+ call writefile(lines, errorfile)
+ " Remember the original values of these options.
+ let mp_save = &makeprg
+ let efm_save = &errorformat
+ try
+ " Temporarily change the options.
+ let &makeprg = compiler_name
+ let &errorformat = error_format
+ let winnr = winnr()
+ let filename = expand('%:t')
+ execute 'lgetfile' fnameescape(errorfile)
+ lwindow
+ if winnr() != winnr
+ let message = ['Syntax errors reported by', compiler_name, compiler_args, filename]
+ let w:quickfix_title = join(message)
+ execute winnr . 'wincmd w'
+ endif
+ call s:highlighterrors()
+ finally
+ " Restore the options.
+ let &makeprg = mp_save
+ let &errorformat = efm_save
+ " Cleanup the file with errors.
+ call delete(errorfile)
+ endtry
+endfunction
+
+function! s:highlighterrors()
+ let hlgroup = 'luaCompilerError'
+ if !hlexists(hlgroup)
+ execute 'highlight def link' hlgroup 'Error'
+ else
+ call clearmatches()
+ endif
+ let pattern = '^\%%%il.*\n\?'
+ for entry in getqflist()
+ call matchadd(hlgroup, '\%' . min([entry.lnum, line('$')]) . 'l')
+ call xolox#misc#msg#warn("lua.vim %s: Syntax error on line %i: %s", g:xolox#lua#version, entry.lnum, entry.text)
+ endfor
+endfunction
+
+function! xolox#lua#checkglobals(verbose) " {{{1
+ let output = xolox#lua#dofile(s:globals_script, [expand('%'), a:verbose])
+ call setqflist(eval('[' . join(output, ',') . ']'), 'r')
+ cwindow
+endfunction
+
+function! xolox#lua#help() " {{{1
+ " Get the expression under the cursor.
+ let cword = ''
+ try
+ let isk_save = &isk
+ set iskeyword+=.,:
+ let cword = expand('<cword>')
+ finally
+ let &isk = isk_save
+ endtry
+ if cword != ''
+ try
+ call s:lookupmethod(cword, 'lrv-string.', '\v<(byte|char|dump|g?find|format|len|lower|g?match|rep|reverse|g?sub|upper)>')
+ call s:lookupmethod(cword, 'lrv-file:', '\v<(close|flush|lines|read|seek|setvbuf|write)>')
+ call s:lookupmethod(cword, '', '\v:\w+>')
+ call s:lookuptopic('lrv-' . cword)
+ call s:lookuptopic(cword)
+ call s:lookuptopic('luarefvim.txt')
+ help
+ catch /^done$/
+ return
+ endtry
+ endif
+ help
+endfunction
+
+function! s:lookupmethod(cword, prefix, pattern)
+ let method = matchstr(a:cword, a:pattern)
+ if method != ''
+ let identifier = a:prefix . method
+ call xolox#misc#msg#debug("lua.vim %s: Translating '%s' -> '%s'", g:xolox#lua#version, a:cword, identifier)
+ call s:lookuptopic(identifier)
+ endif
+endfunction
+
+function! s:lookuptopic(topic)
+ try
+ " Lookup the given topic in Vim's help files.
+ execute 'help' escape(a:topic, ' []*?')
+ " Abuse exceptions for non local jumping.
+ throw 'done'
+ catch /^Vim\%((\a\+)\)\=:E149/
+ " Ignore E149: Sorry, no help for <keyword>.
+ return
+ endtry
+endfunction
+
+function! xolox#lua#jumpblock(forward) " {{{1
+ let start = '\<\%(for\|function\|if\|repeat\|while\)\>'
+ let middle = '\<\%(elseif\|else\)\>'
+ let end = '\<\%(end\|until\)\>'
+ let flags = a:forward ? '' : 'b'
+ return searchpair(start, middle, end, flags, '!xolox#lua#tokeniscode()')
+endfunction
+
+function! s:getfunscope()
+ let firstpos = [0, 1, 1, 0]
+ let lastpos = getpos('$')
+ while search('\<function\>', 'bW')
+ if xolox#lua#tokeniscode()
+ let firstpos = getpos('.')
+ break
+ endif
+ endwhile
+ if xolox#lua#jumpblock(1)
+ let lastpos = getpos('.')
+ endif
+ return [firstpos, lastpos]
+endfunction
+
+function! xolox#lua#jumpthisfunc(forward) " {{{1
+ let cpos = [line('.'), col('.')]
+ let fpos = [1, 1]
+ let lpos = [line('$'), 1]
+ while search('\<function\>', a:forward ? 'W' : 'bW')
+ if xolox#lua#tokeniscode()
+ break
+ endif
+ endwhile
+ let cursorline = line('.')
+ let [firstpos, lastpos] = s:getfunscope()
+ if cursorline == (a:forward ? lastpos : firstpos)[1]
+ " make the mapping repeatable (line wise at least)
+ execute a:forward ? (lastpos[1] + 1) : (firstpos[1] - 1)
+ let [firstpos, lastpos] = s:getfunscope()
+ endif
+ call setpos('.', a:forward ? lastpos : firstpos)
+endfunction
+
+function! xolox#lua#jumpotherfunc(forward) " {{{1
+ let view = winsaveview()
+ " jump to the start/end of the function
+ call xolox#lua#jumpthisfunc(a:forward)
+ " search for the previous/next function
+ while search('\<function\>', a:forward ? 'W' : 'bW')
+ " ignore strings and comments containing 'function'
+ if xolox#lua#tokeniscode()
+ return 1
+ endif
+ endwhile
+ call winrestview(view)
+endfunction
+
+function! xolox#lua#tokeniscode() " {{{1
+ return s:getsynid(0) !~? 'string\|comment'
+endfunction
+
+function! s:getsynid(transparent)
+ let id = synID(line('.'), col('.') - 1, 1)
+ if a:transparent
+ let id = synIDtrans(id)
+ endif
+ return synIDattr(id, 'name')
+endfunction
+
+if exists('loaded_matchit')
+
+ function! xolox#lua#matchit() " {{{1
+ let cword = expand('<cword>')
+ if cword == 'end'
+ let s = ['function', 'if', 'for', 'while']
+ let e = ['end']
+ unlet! b:match_skip
+ elseif cword =~ '^\(function\|return\|yield\)$'
+ let s = ['function']
+ let m = ['return', 'yield']
+ let e = ['end']
+ let b:match_skip = "xolox#lua#matchit_ignore('^luaCond$')"
+ let b:match_skip .= " || (expand('<cword>') == 'end' && xolox#lua#matchit_ignore('^luaStatement$'))"
+ elseif cword =~ '^\(for\|in\|while\|do\|repeat\|until\|break\)$'
+ let s = ['for', 'repeat', 'while']
+ let m = ['break']
+ let e = ['end', 'until']
+ let b:match_skip = "xolox#lua#matchit_ignore('^\\(luaCond\\|luaFunction\\)$')"
+ elseif cword =~ '\(if\|then\|elseif\|else\)$'
+ let s = ['if']
+ let m = ['elseif', 'else']
+ let e = ['end']
+ let b:match_skip = "xolox#lua#matchit_ignore('^\\(luaFunction\\|luaStatement\\)$')"
+ else
+ let s = ['for', 'function', 'if', 'repeat', 'while']
+ let m = ['break', 'elseif', 'else', 'return']
+ let e = ['eend', 'until']
+ unlet! b:match_skip
+ endif
+ let p = '\<\(' . join(s, '\|') . '\)\>'
+ if exists('m')
+ let p .= ':\<\(' . join(m, '\|') . '\)\>'
+ endif
+ return p . ':\<\(' . join(e, '\|') . '\)\>'
+ endfunction
+
+ function! xolox#lua#matchit_ignore(ignored) " {{{1
+ let word = expand('<cword>')
+ let type = s:getsynid(0)
+ return type =~? a:ignored || type =~? 'string\|comment'
+ endfunction
+
+endif
+
+function! xolox#lua#completefunc(init, base) " {{{1
+ if a:init
+ return s:getcompletionprefix()
+ endif
+ let items = []
+ if xolox#misc#option#get('lua_complete_keywords', 1)
+ call extend(items, g:xolox#lua_data#keywords)
+ endif
+ if xolox#misc#option#get('lua_complete_globals', 1)
+ call extend(items, g:xolox#lua_data#globals)
+ endif
+ if xolox#misc#option#get('lua_complete_library', 1)
+ call extend(items, g:xolox#lua_data#library)
+ endif
+ let pattern = '^' . xolox#misc#escape#pattern(a:base)
+ call filter(items, 'v:val.word =~ pattern')
+ return s:addsignatures(items)
+endfunction
+
+function! s:getcompletionprefix()
+ return match(strpart(getline('.'), 0, col('.') - 1), '\w\+\.\?\w*$')
+endfunction
+
+function! s:addsignatures(entries)
+ for entry in a:entries
+ let signature = xolox#lua#getsignature(entry.word)
+ if !empty(signature) && signature != entry.word
+ let entry.menu = signature
+ endif
+ endfor
+ return a:entries
+endfunction
+
+function! xolox#lua#getsignature(identifier) " {{{1
+ let identifier = substitute(a:identifier, '()$', '', '')
+ let signature = get(g:xolox#lua_data#signatures, identifier, '')
+ if empty(signature)
+ let signature = get(g:xolox#lua_data#signatures, 'string.' . identifier, '')
+ endif
+ if empty(signature)
+ let signature = get(g:xolox#lua_data#signatures, 'file:' . identifier, '')
+ endif
+ return signature
+endfunction
+
+function! xolox#lua#omnifunc(init, base) " {{{1
+ if a:init
+ return s:getcompletionprefix()
+ elseif !xolox#misc#option#get('lua_complete_omni', 0)
+ throw printf("lua.vim %s: omni completion needs to be explicitly enabled, see the readme!", g:xolox#lua#version)
+ endif
+ if !exists('s:omnifunc_modules')
+ let s:omnifunc_modules = xolox#lua#getomnimodules()
+ endif
+ if !exists('s:omnifunc_variables')
+ let s:omnifunc_variables = xolox#lua#getomnivariables(s:omnifunc_modules)
+ call s:addsignatures(s:omnifunc_variables)
+ endif
+ " FIXME When you type "require'" without a space in between
+ " the getline('.') call below returns an empty string?!
+ let pattern = '^' . xolox#misc#escape#pattern(a:base)
+ if getline('.') =~ 'require[^''"]*[''"]'
+ return filter(copy(s:omnifunc_modules), 'v:val =~ pattern')
+ elseif a:base == ''
+ return s:omnifunc_variables
+ else
+ return filter(copy(s:omnifunc_variables), 'v:val.word =~ pattern')
+ endif
+endfunction
+
+function! xolox#lua#getomnimodules() " {{{1
+ let starttime = xolox#misc#timer#start()
+ let modulemap = {}
+ let luapath = xolox#lua#getsearchpath('$LUA_PATH', 'package.path')
+ let luacpath = xolox#lua#getsearchpath('$LUA_CPATH', 'package.cpath')
+ for searchpath in [luapath, luacpath]
+ call s:expandsearchpath(searchpath, modulemap)
+ endfor
+ let modules = keys(modulemap)
+ call sort(modules)
+ let msg = "lua.vim %s: Collected %i module names for omni completion in %s"
+ call xolox#misc#timer#stop(msg, g:xolox#lua#version, len(modules), starttime)
+ return modules
+endfunction
+
+function! s:expandsearchpath(searchpath, modules)
+ " Collect the names of all installed modules by traversing the search paths.
+ for template in a:searchpath
+ let components = split(template, '?')
+ if len(components) != 2
+ let msg = "lua.vim %s: Failed to parse search path entry: %s"
+ call xolox#misc#msg#debug(msg, g:xolox#lua#version, template)
+ continue
+ endif
+ let [prefix, suffix] = components
+ " XXX Never recursively search current working directory because
+ " it might be arbitrarily deep, e.g. when working directory is /
+ if prefix =~ '^.[\\/]$'
+ let msg = "lua.vim %s: Refusing to expand dangerous search path entry: %s"
+ call xolox#misc#msg#debug(msg, g:xolox#lua#version, template)
+ continue
+ endif
+ let pattern = substitute(template, '?', '**/*', 'g')
+ call xolox#misc#msg#debug("lua.vim %s: Transformed %s -> %s", g:xolox#lua#version, template, pattern)
+ let msg = "lua.vim %s: Failed to convert pathname to module name, %s doesn't match! (%s: '%s', pathname: '%s')"
+ for pathname in split(glob(pattern), "\n")
+ if pathname[0 : len(prefix)-1] != prefix
+ " Validate prefix of resulting pathname.
+ call xolox#misc#msg#warn(msg, g:xolox#lua#version, 'prefix', 'prefix', prefix, pathname)
+ elseif pathname[-len(suffix) : -1] != suffix
+ " Validate suffix of resulting pathname.
+ call xolox#misc#msg#warn(msg, g:xolox#lua#version, 'suffix', 'suffix', suffix, pathname)
+ elseif pathname !~ 'test'
+ let relative = pathname[len(prefix) : -len(suffix)-1]
+ let modulename = substitute(relative, '[\\/]\+', '.', 'g')
+ let a:modules[modulename] = 1
+ call xolox#misc#msg#debug("lua.vim %s: Transformed '%s' -> '%s'", g:xolox#lua#version, pathname, modulename)
+ endif
+ endfor
+ endfor
+endfunction
+
+function! xolox#lua#getomnivariables(modules) " {{{1
+ let starttime = xolox#misc#timer#start()
+ let output = xolox#lua#dofile(s:omnicomplete_script, a:modules)
+ let variables = eval('[' . join(output, ',') . ']')
+ call sort(variables, 1)
+ let msg = "lua.vim %s: Collected %i variables for omni completion in %s."
+ call xolox#misc#timer#stop(msg, g:xolox#lua#version, len(variables), starttime)
+ return variables
+endfunction
+
+function! xolox#lua#completedynamic(type) " {{{1
+ if xolox#misc#option#get('lua_complete_dynamic', 1) && s:getsynid(1) !~? 'string\|comment\|keyword'
+ if (a:type == "'" || a:type == '"')
+ let prefix = strpart(getline('.'), 0, col('.') - 1)
+ if xolox#misc#option#get('lua_complete_omni', 0) && prefix =~ '\<require\s*(\?\s*$'
+ return a:type . "\<C-x>\<C-o>"
+ elseif prefix =~ '\<\(dofile\|loadfile\|io\.open\|io\.lines\|os\.remove\)\s*(\?\s*$'
+ return a:type . "\<C-x>\<C-f>"
+ endif
+ elseif a:type == '.'
+ let column = col('.') - 1
+ " Gotcha: even though '.' is remapped it counts as a column?
+ if column && getline('.')[column - 1] =~ '\w'
+ " This results in "Pattern not found" when no completion candidates
+ " are available, which is kind of annoying. But I don't know of an
+ " alternative to :silent that can be used inside of <expr>
+ " mappings?!
+ if xolox#misc#option#get('lua_complete_omni', 0)
+ return a:type . "\<C-x>\<C-o>"
+ else
+ return a:type . "\<C-x>\<C-u>"
+ endif
+ endif
+ endif
+ endif
+ return a:type
+endfunction
+
+function! xolox#lua#tweakoptions() " {{{1
+ if &filetype == 'lua'
+ let s:completeopt_save = &cot
+ set completeopt+=longest
+ elseif exists('s:completeopt_save')
+ let &completeopt = s:completeopt_save
+ endif
+endfunction
+
+function! xolox#lua#dofile(pathname, arguments) " {{{1
+ if has('lua')
+ " Use the Lua Interface for Vim.
+ redir => output
+ lua arg = vim.eval('a:arguments')
+ execute 'silent luafile' fnameescape(a:pathname)
+ redir END
+ return split(output, "\n")
+ else
+ " Use the command line Lua interpreter.
+ let qpath = xolox#misc#escape#shell(a:pathname)
+ let qargs = join(map(a:arguments, 'xolox#misc#escape#shell(v:val)'))
+ " TODO Make name of Lua executable configurable!
+ return xolox#misc#os#exec(printf('lua %s %s', qpath, qargs))
+ endif
+endfunction
+
+" vim: ts=2 sw=2 et
View
376 .vim/autoload/xolox/lua_data.vim
@@ -0,0 +1,376 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: June 15, 2011
+" URL: http://peterodding.com/code/vim/lua-ftplugin
+
+" This script contains static user completion data based
+" on the Lua 5.1 reference manual and implementation.
+
+" Enable line continuation.
+let s:cpo_save = &cpo
+set cpoptions-=C
+
+" Keywords. {{{1
+let g:xolox#lua_data#keywords = [
+ \ { 'word': 'and', 'kind': 'k' },
+ \ { 'word': 'break', 'kind': 'k' },
+ \ { 'word': 'do', 'kind': 'k' },
+ \ { 'word': 'else', 'kind': 'k' },
+ \ { 'word': 'elseif', 'kind': 'k' },
+ \ { 'word': 'end', 'kind': 'k' },
+ \ { 'word': 'false', 'kind': 'k' },
+ \ { 'word': 'for', 'kind': 'k' },
+ \ { 'word': 'function', 'kind': 'k' },
+ \ { 'word': 'if', 'kind': 'k' },
+ \ { 'word': 'in', 'kind': 'k' },
+ \ { 'word': 'local', 'kind': 'k' },
+ \ { 'word': 'nil', 'kind': 'k' },
+ \ { 'word': 'not', 'kind': 'k' },
+ \ { 'word': 'or', 'kind': 'k' },
+ \ { 'word': 'repeat', 'kind': 'k' },
+ \ { 'word': 'return', 'kind': 'k' },
+ \ { 'word': 'then', 'kind': 'k' },
+ \ { 'word': 'true', 'kind': 'k' },
+ \ { 'word': 'until', 'kind': 'k' },
+ \ { 'word': 'while', 'kind': 'k' } ]
+
+" Global variables. {{{1
+let g:xolox#lua_data#globals = [
+ \ { 'word': '_G', 'kind': 'v' },
+ \ { 'word': '_VERSION', 'kind': 'v' },
+ \ { 'word': 'arg', 'kind': 'v' },
+ \ { 'word': 'assert()', 'kind': 'f' },
+ \ { 'word': 'collectgarbage()', 'kind': 'f' },
+ \ { 'word': 'coroutine', 'kind': 'v' },
+ \ { 'word': 'debug', 'kind': 'v' },
+ \ { 'word': 'dofile()', 'kind': 'f' },
+ \ { 'word': 'error()', 'kind': 'f' },
+ \ { 'word': 'gcinfo()', 'kind': 'f' },
+ \ { 'word': 'getfenv()', 'kind': 'f' },
+ \ { 'word': 'getmetatable()', 'kind': 'f' },
+ \ { 'word': 'io', 'kind': 'v' },
+ \ { 'word': 'ipairs()', 'kind': 'f' },
+ \ { 'word': 'load()', 'kind': 'f' },
+ \ { 'word': 'loadfile()', 'kind': 'f' },
+ \ { 'word': 'loadstring()', 'kind': 'f' },
+ \ { 'word': 'math', 'kind': 'v' },
+ \ { 'word': 'module()', 'kind': 'f' },
+ \ { 'word': 'newproxy()', 'kind': 'f' },
+ \ { 'word': 'next()', 'kind': 'f' },
+ \ { 'word': 'os', 'kind': 'v' },
+ \ { 'word': 'package', 'kind': 'v' },
+ \ { 'word': 'pairs()', 'kind': 'f' },
+ \ { 'word': 'pcall()', 'kind': 'f' },
+ \ { 'word': 'prettyprint()', 'kind': 'f' },
+ \ { 'word': 'print()', 'kind': 'f' },
+ \ { 'word': 'rawequal()', 'kind': 'f' },
+ \ { 'word': 'rawget()', 'kind': 'f' },
+ \ { 'word': 'rawset()', 'kind': 'f' },
+ \ { 'word': 'require()', 'kind': 'f' },
+ \ { 'word': 'select()', 'kind': 'f' },
+ \ { 'word': 'setfenv()', 'kind': 'f' },
+ \ { 'word': 'setmetatable()', 'kind': 'f' },
+ \ { 'word': 'string', 'kind': 'v' },
+ \ { 'word': 'table', 'kind': 'v' },
+ \ { 'word': 'tonumber()', 'kind': 'f' },
+ \ { 'word': 'tostring()', 'kind': 'f' },
+ \ { 'word': 'type()', 'kind': 'f' },
+ \ { 'word': 'unpack()', 'kind': 'f' },
+ \ { 'word': 'xpcall()', 'kind': 'f' } ]
+
+" Standard library identifiers. {{{1
+let g:xolox#lua_data#library = [
+ \ { 'word': 'coroutine.create()', 'kind': 'f' },
+ \ { 'word': 'coroutine.resume()', 'kind': 'f' },
+ \ { 'word': 'coroutine.running()', 'kind': 'f' },
+ \ { 'word': 'coroutine.status()', 'kind': 'f' },
+ \ { 'word': 'coroutine.wrap()', 'kind': 'f' },
+ \ { 'word': 'coroutine.yield()', 'kind': 'f' },
+ \ { 'word': 'debug.debug()', 'kind': 'f' },
+ \ { 'word': 'debug.getfenv()', 'kind': 'f' },
+ \ { 'word': 'debug.gethook()', 'kind': 'f' },
+ \ { 'word': 'debug.getinfo()', 'kind': 'f' },
+ \ { 'word': 'debug.getlocal()', 'kind': 'f' },
+ \ { 'word': 'debug.getmetatable()', 'kind': 'f' },
+ \ { 'word': 'debug.getregistry()', 'kind': 'f' },
+ \ { 'word': 'debug.getupvalue()', 'kind': 'f' },
+ \ { 'word': 'debug.setfenv()', 'kind': 'f' },
+ \ { 'word': 'debug.sethook()', 'kind': 'f' },
+ \ { 'word': 'debug.setlocal()', 'kind': 'f' },
+ \ { 'word': 'debug.setmetatable()', 'kind': 'f' },
+ \ { 'word': 'debug.setupvalue()', 'kind': 'f' },
+ \ { 'word': 'debug.traceback()', 'kind': 'f' },
+ \ { 'word': 'io.close()', 'kind': 'f' },
+ \ { 'word': 'io.flush()', 'kind': 'f' },
+ \ { 'word': 'io.input()', 'kind': 'f' },
+ \ { 'word': 'io.lines()', 'kind': 'f' },
+ \ { 'word': 'io.open()', 'kind': 'f' },
+ \ { 'word': 'io.output()', 'kind': 'f' },
+ \ { 'word': 'io.popen()', 'kind': 'f' },
+ \ { 'word': 'io.read()', 'kind': 'f' },
+ \ { 'word': 'io.size()', 'kind': 'f' },
+ \ { 'word': 'io.stderr', 'kind': 'm' },
+ \ { 'word': 'io.stdin', 'kind': 'm' },
+ \ { 'word': 'io.stdout', 'kind': 'm' },
+ \ { 'word': 'io.tmpfile()', 'kind': 'f' },
+ \ { 'word': 'io.type()', 'kind': 'f' },
+ \ { 'word': 'io.write()', 'kind': 'f' },
+ \ { 'word': 'math.abs()', 'kind': 'f' },
+ \ { 'word': 'math.acos()', 'kind': 'f' },
+ \ { 'word': 'math.asin()', 'kind': 'f' },
+ \ { 'word': 'math.atan()', 'kind': 'f' },
+ \ { 'word': 'math.atan2()', 'kind': 'f' },
+ \ { 'word': 'math.ceil()', 'kind': 'f' },
+ \ { 'word': 'math.cos()', 'kind': 'f' },
+ \ { 'word': 'math.cosh()', 'kind': 'f' },
+ \ { 'word': 'math.deg()', 'kind': 'f' },
+ \ { 'word': 'math.exp()', 'kind': 'f' },
+ \ { 'word': 'math.floor()', 'kind': 'f' },
+ \ { 'word': 'math.fmod()', 'kind': 'f' },
+ \ { 'word': 'math.frexp()', 'kind': 'f' },
+ \ { 'word': 'math.huge', 'kind': 'm' },
+ \ { 'word': 'math.ldexp()', 'kind': 'f' },
+ \ { 'word': 'math.log()', 'kind': 'f' },
+ \ { 'word': 'math.log10()', 'kind': 'f' },
+ \ { 'word': 'math.max()', 'kind': 'f' },
+ \ { 'word': 'math.min()', 'kind': 'f' },
+ \ { 'word': 'math.mod()', 'kind': 'f' },
+ \ { 'word': 'math.modf()', 'kind': 'f' },
+ \ { 'word': 'math.pi', 'kind': 'm' },
+ \ { 'word': 'math.pow()', 'kind': 'f' },
+ \ { 'word': 'math.rad()', 'kind': 'f' },
+ \ { 'word': 'math.random()', 'kind': 'f' },
+ \ { 'word': 'math.randomseed()', 'kind': 'f' },
+ \ { 'word': 'math.sin()', 'kind': 'f' },
+ \ { 'word': 'math.sinh()', 'kind': 'f' },
+ \ { 'word': 'math.sqrt()', 'kind': 'f' },
+ \ { 'word': 'math.tan()', 'kind': 'f' },
+ \ { 'word': 'math.tanh()', 'kind': 'f' },
+ \ { 'word': 'os.clock()', 'kind': 'f' },
+ \ { 'word': 'os.date()', 'kind': 'f' },
+ \ { 'word': 'os.difftime()', 'kind': 'f' },
+ \ { 'word': 'os.execute()', 'kind': 'f' },
+ \ { 'word': 'os.exit()', 'kind': 'f' },
+ \ { 'word': 'os.getenv()', 'kind': 'f' },
+ \ { 'word': 'os.remove()', 'kind': 'f' },
+ \ { 'word': 'os.rename()', 'kind': 'f' },
+ \ { 'word': 'os.setlocale()', 'kind': 'f' },
+ \ { 'word': 'os.time()', 'kind': 'f' },
+ \ { 'word': 'os.tmpname()', 'kind': 'f' },
+ \ { 'word': 'package.config', 'kind': 'm' },
+ \ { 'word': 'package.cpath', 'kind': 'm' },
+ \ { 'word': 'package.loaded', 'kind': 'm' },
+ \ { 'word': 'package.loaders', 'kind': 'm' },
+ \ { 'word': 'package.loadlib()', 'kind': 'f' },
+ \ { 'word': 'package.path', 'kind': 'm' },
+ \ { 'word': 'package.preload', 'kind': 'm' },
+ \ { 'word': 'package.seeall()', 'kind': 'f' },
+ \ { 'word': 'string.byte()', 'kind': 'f' },
+ \ { 'word': 'string.char()', 'kind': 'f' },
+ \ { 'word': 'string.dump()', 'kind': 'f' },
+ \ { 'word': 'string.find()', 'kind': 'f' },
+ \ { 'word': 'string.format()', 'kind': 'f' },
+ \ { 'word': 'string.gfind()', 'kind': 'f' },
+ \ { 'word': 'string.gmatch()', 'kind': 'f' },
+ \ { 'word': 'string.gsplit()', 'kind': 'f' },
+ \ { 'word': 'string.gsub()', 'kind': 'f' },
+ \ { 'word': 'string.len()', 'kind': 'f' },
+ \ { 'word': 'string.lower()', 'kind': 'f' },
+ \ { 'word': 'string.match()', 'kind': 'f' },
+ \ { 'word': 'string.rep()', 'kind': 'f' },
+ \ { 'word': 'string.reverse()', 'kind': 'f' },
+ \ { 'word': 'string.sub()', 'kind': 'f' },
+ \ { 'word': 'string.upper()', 'kind': 'f' },
+ \ { 'word': 'table.concat()', 'kind': 'f' },
+ \ { 'word': 'table.foreach()', 'kind': 'f' },
+ \ { 'word': 'table.foreachi()', 'kind': 'f' },
+ \ { 'word': 'table.getn()', 'kind': 'f' },
+ \ { 'word': 'table.insert()', 'kind': 'f' },
+ \ { 'word': 'table.maxn()', 'kind': 'f' },
+ \ { 'word': 'table.remove()', 'kind': 'f' },
+ \ { 'word': 'table.setn()', 'kind': 'f' },
+ \ { 'word': 'table.sort()', 'kind': 'f' } ]
+
+" Function signatures. {{{1
+" Sources:
+" - http://www.lua.org/manual/5.1/manual.html#5
+" - http://w3.impa.br/~diego/software/luasocket/reference.html
+
+let g:xolox#lua_data#signatures = {
+ \ 'assert': 'assert(v [, message])',
+ \ 'collectgarbage': 'collectgarbage(opt [, arg])',
+ \ 'dofile': 'dofile(filename)',
+ \ 'error': 'error(message [, level])',
+ \ 'getfenv': 'getfenv([f])',
+ \ 'getmetatable': 'getmetatable(object)',
+ \ 'ipairs': 'ipairs(t)',
+ \ 'load': 'load(func [, chunkname])',
+ \ 'loadfile': 'loadfile([filename])',
+ \ 'loadstring': 'loadstring(string [, chunkname])',
+ \ 'next': 'next(table [, index])',
+ \ 'pairs': 'pairs(t)',
+ \ 'pcall': 'pcall(f, arg1, ...)',
+ \ 'print': 'print(...)',
+ \ 'rawequal': 'rawequal(v1, v2)',
+ \ 'rawget': 'rawget(table, index)',
+ \ 'rawset': 'rawset(table, index, value)',
+ \ 'select': 'select(index, ...)',
+ \ 'setfenv': 'setfenv(f, table)',
+ \ 'setmetatable': 'setmetatable(table, metatable)',
+ \ 'tonumber': 'tonumber(e [, base])',
+ \ 'tostring': 'tostring(e)',
+ \ 'type': 'type(v)',
+ \ 'unpack': 'unpack(list [, i [, j]])',
+ \ 'xpcall': 'xpcall(f, err)',
+ \ 'coroutine.create': 'coroutine.create(f)',
+ \ 'coroutine.resume': 'coroutine.resume(co [, val1, ...])',
+ \ 'coroutine.running': 'coroutine.running()',
+ \ 'coroutine.status': 'coroutine.status(co)',
+ \ 'coroutine.wrap': 'coroutine.wrap(f)',
+ \ 'coroutine.yield': 'coroutine.yield(...)',
+ \ 'module': 'module(name [, ...])',
+ \ 'require': 'require(modname)',
+ \ 'package.loadlib': 'package.loadlib(libname, funcname)',
+ \ 'package.seeall': 'package.seeall(module)',
+ \ 'string.byte': 'string.byte(s [, i [, j]])',
+ \ 'string.char': 'string.char(...)',
+ \ 'string.dump': 'string.dump(function)',
+ \ 'string.find': 'string.find(s, pattern [, init [, plain]])',
+ \ 'string.format': 'string.format(formatstring, ...)',
+ \ 'string.gmatch': 'string.gmatch(s, pattern)',
+ \ 'string.gsub': 'string.gsub(s, pattern, repl [, n])',
+ \ 'string.len': 'string.len(s)',
+ \ 'string.lower': 'string.lower(s)',
+ \ 'string.match': 'string.match(s, pattern [, init])',
+ \ 'string.rep': 'string.rep(s, n)',
+ \ 'string.reverse': 'string.reverse(s)',
+ \ 'string.sub': 'string.sub(s, i [, j])',
+ \ 'string.upper': 'string.upper(s)',
+ \ 'table.concat': 'table.concat(table [, sep [, i [, j]]])',
+ \ 'table.insert': 'table.insert(table, [pos,] value)',
+ \ 'table.maxn': 'table.maxn(table)',
+ \ 'table.remove': 'table.remove(table [, pos])',
+ \ 'table.sort': 'table.sort(table [, comp])',
+ \ 'math.abs': 'math.abs(x)',
+ \ 'math.acos': 'math.acos(x)',
+ \ 'math.asin': 'math.asin(x)',
+ \ 'math.atan': 'math.atan(x)',
+ \ 'math.atan2': 'math.atan2(y, x)',
+ \ 'math.ceil': 'math.ceil(x)',
+ \ 'math.cos': 'math.cos(x)',
+ \ 'math.cosh': 'math.cosh(x)',
+ \ 'math.deg': 'math.deg(x)',
+ \ 'math.exp': 'math.exp(x)',
+ \ 'math.floor': 'math.floor(x)',
+ \ 'math.fmod': 'math.fmod(x, y)',
+ \ 'math.frexp': 'math.frexp(x)',
+ \ 'math.ldexp': 'math.ldexp(m, e)',
+ \ 'math.log': 'math.log(x)',
+ \ 'math.log10': 'math.log10(x)',
+ \ 'math.max': 'math.max(x, ...)',
+ \ 'math.min': 'math.min(x, ...)',
+ \ 'math.modf': 'math.modf(x)',
+ \ 'math.pow': 'math.pow(x, y)',
+ \ 'math.rad': 'math.rad(x)',
+ \ 'math.random': 'math.random([m [, n]])',
+ \ 'math.randomseed': 'math.randomseed(x)',
+ \ 'math.sin': 'math.sin(x)',
+ \ 'math.sinh': 'math.sinh(x)',
+ \ 'math.sqrt': 'math.sqrt(x)',
+ \ 'math.tan': 'math.tan(x)',
+ \ 'math.tanh': 'math.tanh(x)',
+ \ 'io.close': 'io.close([file])',
+ \ 'io.flush': 'io.flush()',
+ \ 'io.input': 'io.input([file])',
+ \ 'io.lines': 'io.lines([filename])',
+ \ 'io.open': 'io.open(filename [, mode])',
+ \ 'io.output': 'io.output([file])',
+ \ 'io.popen': 'io.popen(prog [, mode])',
+ \ 'io.read': 'io.read(...)',
+ \ 'io.tmpfile': 'io.tmpfile()',
+ \ 'io.type': 'io.type(obj)',
+ \ 'io.write': 'io.write(...)',
+ \ 'file:close': 'file:close()',
+ \ 'file:flush': 'file:flush()',
+ \ 'file:lines': 'file:lines()',
+ \ 'file:read': 'file:read(...)',
+ \ 'file:seek': 'file:seek([whence] [, offset])',
+ \ 'file:setvbuf': 'file:setvbuf(mode [, size])',
+ \ 'file:write': 'file:write(...)',
+ \ 'os.clock': 'os.clock()',
+ \ 'os.date': 'os.date([format [, time]])',
+ \ 'os.difftime': 'os.difftime(t2, t1)',
+ \ 'os.execute': 'os.execute([command])',
+ \ 'os.exit': 'os.exit([code])',
+ \ 'os.getenv': 'os.getenv(varname)',
+ \ 'os.remove': 'os.remove(filename)',
+ \ 'os.rename': 'os.rename(oldname, newname)',
+ \ 'os.setlocale': 'os.setlocale(locale [, category])',
+ \ 'os.time': 'os.time([table])',
+ \ 'os.tmpname': 'os.tmpname()',
+ \ 'debug.debug': 'debug.debug()',
+ \ 'debug.getfenv': 'debug.getfenv(o)',
+ \ 'debug.gethook': 'debug.gethook([thread])',
+ \ 'debug.getinfo': 'debug.getinfo([thread,] function [, what])',
+ \ 'debug.getlocal': 'debug.getlocal([thread,] level, local)',
+ \ 'debug.getmetatable': 'debug.getmetatable(object)',
+ \ 'debug.getregistry': 'debug.getregistry()',
+ \ 'debug.getupvalue': 'debug.getupvalue(func, up)',
+ \ 'debug.setfenv': 'debug.setfenv(object, table)',
+ \ 'debug.sethook': 'debug.sethook([thread,] hook, mask [, count])',
+ \ 'debug.setlocal': 'debug.setlocal([thread,] level, local, value)',
+ \ 'debug.setmetatable': 'debug.setmetatable(object, table)',
+ \ 'debug.setupvalue': 'debug.setupvalue(func, up, value)',
+ \ 'debug.traceback': 'debug.traceback([thread,] [message] [, level])',
+ \
+ \ 'ftp.get': 'ftp.get(url)',
+ \ 'ftp.put': 'ftp.put(url, content)',
+ \ 'http.request': 'http.request(url [, body])',
+ \ 'ltn12.filter.chain': 'ltn12.filter.chain(filter1, filter2 [, ... filterN])',
+ \ 'ltn12.filter.cycle': 'ltn12.filter.cycle(low [, ctx, extra])',
+ \ 'ltn12.pump.all': 'ltn12.pump.all(source, sink)',
+ \ 'ltn12.pump.step': 'ltn12.pump.step(source, sink)',
+ \ 'ltn12.sink.chain': 'ltn12.sink.chain(filter, sink)',
+ \ 'ltn12.sink.error': 'ltn12.sink.error(message)',
+ \ 'ltn12.sink.file': 'ltn12.sink.file(handle, message)',
+ \ 'ltn12.sink.simplify': 'ltn12.sink.simplify(sink)',
+ \ 'ltn12.sink.table': 'ltn12.sink.table([table])',
+ \ 'ltn12.source.cat': 'ltn12.source.cat(source1 [, source2, ..., sourceN])',
+ \ 'ltn12.source.chain': 'ltn12.source.chain(source, filter)',
+ \ 'ltn12.source.empty': 'ltn12.source.empty()',
+ \ 'ltn12.source.error': 'ltn12.source.error(message)',
+ \ 'ltn12.source.file': 'ltn12.source.file(handle, message)',
+ \ 'ltn12.source.simplify': 'ltn12.source.simplify(source)',
+ \ 'ltn12.source.string': 'ltn12.source.string(string)',
+ \ 'mime.decode': "mime.decode('base64' or 'quoted-printable')",
+ \ 'mime.encode': "mime.encode('base64' or 'quoted-printable' [, mode])",
+ \ 'mime.normalize': 'mime.normalize([marker])',
+ \ 'mime.wrap': "mime.wrap('base64' or 'quoted-printable' or 'text' [, length])",
+ \ 'smtp.message': 'smtp.message(mesgt)',
+ \ 'socket.bind': 'socket.bind(address, port [, backlog])',
+ \ 'socket.connect': 'socket.connect(address, port [, locaddr, locport])',
+ \ 'socket.dns.tohostname': 'socket.dns.tohostname(address)',
+ \ 'socket.dns.toip': 'socket.dns.toip(address)',
+ \ 'socket.newtry': 'socket.newtry(finalizer)',
+ \ 'socket.protect': 'socket.protect(func)',
+ \ 'socket.select': 'socket.select(recvt, sendt [, timeout])',
+ \ 'socket.sink': 'socket.sink(mode, socket)',
+ \ 'socket.skip': 'socket.skip(d [, ret1, ret2 ... retN])',
+ \ 'socket.sleep': 'socket.sleep(time)',
+ \ 'socket.source': 'socket.source(mode, socket [, length])',
+ \ 'socket.try': 'socket.try(ret1 [, ret2 ... retN])',
+ \ 'url.absolute': 'url.absolute(base, relative)',
+ \ 'url.build': 'url.build(parsed_url)',
+ \ 'url.build_path': 'url.build_path(segments, unsafe)',
+ \ 'url.escape': 'url.escape(content)',
+ \ 'url.parse': 'url.parse(url, default)',
+ \ 'url.parse_path': 'url.parse_path(path)',
+ \ 'url.unescape': 'url.unescape(content)' }
+
+" }}}
+
+" Restore compatibility options.
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: ts=2 sw=2 et
View
24 .vim/autoload/xolox/misc/README.md
@@ -0,0 +1,24 @@
+# Miscellaneous auto-load Vim scripts
+
+The git repository at <http://github.com/xolox/vim-misc> contains Vim scripts that are used by most of the [Vim plug-ins I've written] [plugins] yet don't really belong with any single one. I include this repository as a subdirectory of my plug-in repositories using the following commands:
+
+ $ git remote add -f vim-misc https://github.com/xolox/vim-misc.git
+ $ git merge -s ours --no-commit vim-misc/master
+ $ git read-tree --prefix=autoload/xolox/misc/ -u vim-misc/master
+ $ git commit -m "Merge vim-misc repository as subdirectory"
+
+To update a plug-in repository to the latest versions of the miscellaneous auto-load scripts I execute the following command:
+
+ $ git pull -s subtree vim-misc master
+
+## Contact
+
+If you have questions, bug reports, suggestions, etc. the author can be contacted at <peter@peterodding.com>. The latest version is available at <http://peterodding.com/code/vim/misc> and <http://github.com/xolox/vim-misc>.
+
+## License
+
+This software is licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License).
+© 2011 Peter Odding &lt;<peter@peterodding.com>&gt;.
+
+
+[plugins]: http://peterodding.com/code/vim/
View
37 .vim/autoload/xolox/misc/buffer.vim
@@ -0,0 +1,37 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: September 4, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#misc#buffer#is_empty()
+ " Check if the current buffer is an empty, unchanged buffer which can be reused.
+ return !&modified && expand('%') == '' && line('$') <= 1 && getline(1) == ''
+endfunction
+
+function! xolox#misc#buffer#prepare(bufname)
+ let bufname = '[' . a:bufname . ']'
+ let buffers = tabpagebuflist()
+ call map(buffers, 'fnamemodify(bufname(v:val), ":t:r")')
+ let idx = index(buffers, bufname)
+ if idx >= 0
+ execute (idx + 1) . 'wincmd w'
+ elseif !(xolox#misc#buffer#is_empty() || expand('%:t') == bufname)
+ vsplit
+ endif
+ silent execute 'edit' fnameescape(bufname)
+ lcd " clear working directory
+ setlocal buftype=nofile bufhidden=hide noswapfile
+ let &l:statusline = bufname
+ call xolox#misc#buffer#unlock()
+ silent %delete
+endfunction
+
+function! xolox#misc#buffer#lock()
+ " Lock a special buffer so it can no longer be edited.
+ setlocal readonly nomodifiable nomodified
+endfunction
+
+function! xolox#misc#buffer#unlock()
+ " Unlock a special buffer so that its content can be updated.
+ setlocal noreadonly modifiable
+endfunction
View
18 .vim/autoload/xolox/misc/complete.vim
@@ -0,0 +1,18 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Keyword completion from the current buffer for user defined commands.
+
+function! xolox#misc#complete#keywords(arglead, cmdline, cursorpos)
+ let words = {}
+ for line in getline(1, '$')
+ for word in split(line, '\W\+')
+ let words[word] = 1
+ endfor
+ endfor
+ return sort(keys(filter(words, 'v:key =~# a:arglead')))
+endfunction
+
+" vim: ts=2 sw=2 et
View
46 .vim/autoload/xolox/misc/escape.vim
@@ -0,0 +1,46 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: November 21, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Convert a string into a :substitute pattern that matches the string literally.
+
+function! xolox#misc#escape#pattern(string)
+ if type(a:string) == type('')
+ let string = escape(a:string, '^$.*\~[]')
+ return substitute(string, '\n', '\\n', 'g')
+ endif
+ return ''
+endfunction
+
+" Convert a string into a :substitute replacement that inserts the string literally.
+
+function! xolox#misc#escape#substitute(string)
+ if type(a:string) == type('')
+ let string = escape(a:string, '\&~%')
+ return substitute(string, '\n', '\\r', 'g')
+ endif
+ return ''
+endfunction
+
+" Convert a string into a quoted command line argument. I was going to add a
+" long rant here about &shellslash, but really, it won't make any difference.
+" Let's just suffice to say that I have yet to encounter a single person out
+" there who uses this option for its intended purpose (running a UNIX-style
+" shell on Windows).
+
+function! xolox#misc#escape#shell(string)
+ if xolox#misc#os#is_win()
+ try
+ let ssl_save = &shellslash
+ set noshellslash
+ return shellescape(a:string)
+ finally
+ let &shellslash = ssl_save
+ endtry
+ else
+ return shellescape(a:string)
+ endif
+endfunction
+
+" vim: ts=2 sw=2 et
View
49 .vim/autoload/xolox/misc/list.vim
@@ -0,0 +1,49 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: August 31, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Remove duplicate values from {list} in-place (preserves order).
+
+function! xolox#misc#list#unique(list)
+ call reverse(a:list)
+ call filter(a:list, 'count(a:list, v:val) == 1')
+ return reverse(a:list)
+endfunction
+
+" Binary insertion (more efficient than calling sort() after each insertion).
+
+function! xolox#misc#list#binsert(list, value, ...)
+ let idx = s:binsert_r(a:list, 0, len(a:list), a:value, exists('a:1') && a:1)
+ return insert(a:list, a:value, idx)
+endfunction
+
+function! s:binsert_r(list, low, high, value, ignorecase)
+ let mid = a:low + (a:high - a:low) / 2
+ if a:low == a:high
+ return a:low
+ elseif a:ignorecase ? a:value >? a:list[mid] : a:value > a:list[mid]
+ return s:binsert_r(a:list, mid + 1, a:high, a:value, a:ignorecase)
+ elseif a:ignorecase ? a:value <? a:list[mid] : a:value < a:list[mid]
+ return s:binsert_r(a:list, a:low, mid, a:value, a:ignorecase)
+ else
+ return mid
+ endif
+endfunction
+
+if 0
+ " Tests for xolox#misc#list#binsert().
+ let s:list = ['a', 'B', 'e']
+ function! s:test(value, expected)
+ call xolox#misc#list#binsert(s:list, a:value, 1)
+ if s:list != a:expected
+ call xolox#misc#msg#warn("list.vim: Test failed! Expected %s, got %s",
+ \ string(a:expected), string(s:list))
+ endif
+ endfunction
+ call s:test('c', ['a', 'B', 'c', 'e'])
+ call s:test('D', ['a', 'B', 'c', 'D', 'e'])
+ call s:test('f', ['a', 'B', 'c', 'D', 'e', 'f'])
+endif
+
+" vim: ts=2 sw=2 et
View
83 .vim/autoload/xolox/misc/msg.vim
@@ -0,0 +1,83 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+if !exists('g:xolox_message_buffer')
+ " For when I lose my :messages history :-\
+ let g:xolox_message_buffer = 100
+endif
+
+if !exists('g:xolox_messages')
+ let g:xolox_messages = []
+endif
+
+" Show a formatted informational message to the user.
+
+function! xolox#misc#msg#info(...)
+ call s:show_message('title', a:000)
+endfunction
+
+" Show a formatted warning message to the user.
+
+function! xolox#misc#msg#warn(...)
+ call s:show_message('warningmsg', a:000)
+endfunction
+
+" Show a formatted debugging message to the user?
+
+function! xolox#misc#msg#debug(...)
+ if &vbs >= 1
+ call s:show_message('question', a:000)
+ endif
+endfunction
+
+" The implementation of info() and warn().
+
+function! s:show_message(hlgroup, args)
+ let nargs = len(a:args)
+ if nargs == 1
+ let message = a:args[0]
+ elseif nargs >= 2
+ let message = call('printf', a:args)
+ endif
+ if exists('message')
+ try
+ " Temporarily disable Vim's |hit-enter| prompt and mode display.
+ if !exists('s:more_save')
+ let s:more_save = &more
+ let s:ruler_save = &ruler
+ let s:smd_save = &showmode
+ endif
+ set nomore noshowmode
+ if winnr('$') == 1 | set noruler | endif
+ augroup PluginXoloxHideMode
+ autocmd! CursorHold,CursorHoldI * call s:clear_message()
+ augroup END
+ execute 'echohl' a:hlgroup
+ " Redraw to avoid |hit-enter| prompt.
+ redraw | echomsg message
+ if g:xolox_message_buffer > 0
+ call add(g:xolox_messages, message)
+ if len(g:xolox_messages) > g:xolox_message_buffer
+ call remove(g:xolox_messages, 0)
+ endif
+ endif
+ finally
+ " Always clear message highlighting, even when interrupted by Ctrl-C.
+ echohl none
+ endtry
+ endif
+endfunction
+
+function! s:clear_message()
+ echo ''
+ let &more = s:more_save
+ let &showmode = s:smd_save
+ let &ruler = s:ruler_save
+ unlet s:more_save s:ruler_save s:smd_save
+ autocmd! PluginXoloxHideMode
+ augroup! PluginXoloxHideMode
+endfunction
+
+" vim: ts=2 sw=2 et
View
70 .vim/autoload/xolox/misc/open.vim
@@ -0,0 +1,70 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: November 21, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+if !exists('s:version')
+ let s:version = '1.1'
+ let s:enoimpl = "open.vim %s: %s() hasn't been implemented for your platform! If you have suggestions, please contact peter@peterodding.com."
+ let s:handlers = ['gnome-open', 'kde-open', 'exo-open', 'xdg-open']
+endif
+
+function! xolox#misc#open#file(path, ...)
+ if xolox#misc#os#is_win()
+ try
+ call xolox#shell#open_with_windows_shell(a:path)
+ catch /^Vim\%((\a\+)\)\=:E117/
+ let command = '!start CMD /C START "" %s'
+ silent execute printf(command, xolox#misc#escape#shell(a:path))
+ endtry
+ return
+ elseif has('macunix')
+ let cmd = 'open ' . shellescape(a:path) . ' 2>&1'
+ call s:handle_error(cmd, system(cmd))
+ return
+ else
+ for handler in s:handlers + a:000
+ if executable(handler)
+ call xolox#misc#msg#debug("open.vim %s: Using '%s' to open '%s'.", s:version, handler, a:path)
+ let cmd = shellescape(handler) . ' ' . shellescape(a:path) . ' 2>&1'
+ call s:handle_error(cmd, system(cmd))
+ return
+ endif
+ endfor
+ endif
+ throw printf(s:enoimpl, s:script, 'xolox#misc#open#file')
+endfunction
+
+function! xolox#misc#open#url(url)
+ let url = a:url
+ if url !~ '^\w\+://'
+ if url !~ '@'
+ let url = 'http://' . url
+ elseif url !~ '^mailto:'
+ let url = 'mailto:' . url
+ endif
+ endif
+ if has('unix') && !has('gui_running') && $DISPLAY == ''
+ for browser in ['lynx', 'links', 'w3m']
+ if executable(browser)
+ execute '!' . browser fnameescape(url)
+ call s:handle_error(browser . ' ' . url, '')
+ return
+ endif
+ endfor
+ endif
+ call xolox#misc#open#file(url, 'firefox', 'google-chrome')
+endfunction
+
+function! s:handle_error(cmd, output)
+ if v:shell_error
+ let message = "open.vim %s: Failed to execute program! (command line: %s%s)"
+ let output = strtrans(xolox#misc#str#trim(a:output))
+ if output != ''
+ let output = ", output: " . string(output)
+ endif
+ throw printf(message, s:version, a:cmd, output)
+ endif
+endfunction
+
+" vim: et ts=2 sw=2 fdm=marker
View
84 .vim/autoload/xolox/misc/option.vim
@@ -0,0 +1,84 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: August 31, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#misc#option#get(name, ...)
+ if exists('b:' . a:name)
+ " Buffer local variable.
+ return eval('b:' . a:name)
+ elseif exists('g:' . a:name)
+ " Global variable.
+ return eval('g:' . a:name)
+ elseif exists('a:1')
+ " Default value.
+ return a:1
+ endif
+endfunction
+
+" Functions to parse multi-valued Vim options like &tags and &runtimepath.
+
+function! xolox#misc#option#split(value)
+ let values = split(a:value, '[^\\]\zs,')
+ return map(values, 's:unescape(v:val)')
+endfunction
+
+function! s:unescape(s)
+ return substitute(a:s, '\\\([\\,]\)', '\1', 'g')
+endfunction
+
+function! xolox#misc#option#join(values)
+ let values = copy(a:values)
+ call map(values, 's:escape(v:val)')
+ return join(values, ',')
+endfunction
+
+function! s:escape(s)
+ return escape(a:s, ',\')
+endfunction
+
+function! xolox#misc#option#split_tags(value)
+ let values = split(a:value, '[^\\]\zs,')
+ return map(values, 's:unescape_tags(v:val)')
+endfunction
+
+function! s:unescape_tags(s)
+ return substitute(a:s, '\\\([\\, ]\)', '\1', 'g')
+endfunction
+
+function! xolox#misc#option#join_tags(values)
+ let values = copy(a:values)
+ call map(values, 's:escape_tags(v:val)')
+ return join(values, ',')
+endfunction
+
+function! s:escape_tags(s)
+ return escape(a:s, ', ')
+endfunction
+
+function! xolox#misc#option#eval_tags(value, ...)
+ let pathnames = []
+ let first_only = exists('a:1') && a:1
+ for pattern in xolox#misc#option#split_tags(a:value)
+ " Make buffer relative pathnames absolute.
+ if pattern =~ '^\./'
+ let directory = xolox#misc#escape#substitute(expand('%:p:h'))
+ let pattern = substitute(pattern, '^.\ze/', directory, '')
+ endif
+ " Make working directory relative pathnames absolute.
+ if xolox#misc#path#is_relative(pattern)
+ let pattern = xolox#misc#path#merge(getcwd(), pattern)
+ endif
+ " Ignore the trailing `;' for recursive upwards searching because we
+ " always want the most specific pathname available.
+ let pattern = substitute(pattern, ';$', '', '')
+ " Expand the pattern.
+ call extend(pathnames, split(expand(pattern), "\n"))
+ if first_only && !empty(pathnames)
+ return pathnames[0]
+ endif
+ endfor
+ return firstonly ? '' : pathnames
+endfunction
+
+" vim: ts=2 sw=2 et
View
30 .vim/autoload/xolox/misc/os.vim
@@ -0,0 +1,30 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: November 24, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+let g:xolox#misc#os#version = '0.1'
+
+" Check whether Vim is running on Microsoft Windows.
+
+function! xolox#misc#os#is_win()
+ return has('win16') || has('win32') || has('win64')
+endfunction
+
+" Execute an external command (hiding the console on Windows when possible).
+
+function! xolox#misc#os#exec(cmdline, ...)
+ try
+ " Try using my shell.vim plug-in.
+ return call('xolox#shell#execute', [a:cmdline, 1] + a:000)
+ catch /^Vim\%((\a\+)\)\=:E117/
+ " Fall back to system() when we get an "unknown function" error.
+ let output = call('system', [a:cmdline] + a:000)
+ if v:shell_error
+ throw printf("os.vim %s: Command %s failed: %s", g:xolox#misc#os#version, a:cmdline, xolox#misc#str#trim(output))
+ endif
+ return split(output, "\n")
+ endtry
+endfunction
+
+" vim: ts=2 sw=2 et
View
194 .vim/autoload/xolox/misc/path.vim
@@ -0,0 +1,194 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: September 26, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+let s:windows_compatible = has('win32') || has('win64')
+
+function! xolox#misc#path#which(...)
+ let extensions = s:windows_compatible ? split($PATHEXT, ';') : ['']
+ let matches = []
+ let checked = {}
+ for directory in split($PATH, s:windows_compatible ? ';' : ':')
+ let directory = xolox#misc#path#absolute(directory)
+ if !has_key(checked, directory)
+ if isdirectory(directory)
+ for program in a:000
+ for extension in extensions
+ let path = xolox#misc#path#merge(directory, program . extension)
+ if executable(path)
+ call add(matches, path)
+ endif
+ endfor
+ endfor
+ endif
+ let checked[directory] = 1
+ endif
+ endfor
+ return matches
+endfunction
+
+" Split a pathname into a list of path components.
+
+function! xolox#misc#path#split(path)
+ if type(a:path) == type('')
+ if s:windows_compatible
+ return split(a:path, '[\/]\+')
+ else
+ let absolute = (a:path =~ '^/')
+ let segments = split(a:path, '/\+')
+ return absolute ? insert(segments, '/') : segments
+ endif
+ endif
+ return []
+endfunction
+
+" Join a list of path components into a pathname.
+
+function! xolox#misc#path#join(parts)
+ if type(a:parts) == type([])
+ if !s:windows_compatible && a:parts[0] == '/'
+ return join(a:parts, '/')[1 : -1]
+ else
+ return join(a:parts, '/')
+ endif
+ endif
+ return ''
+endfunction
+
+" Canonicalize and resolve a pathname.
+
+function! xolox#misc#path#absolute(path)
+ if type(a:path) == type('')
+ let path = fnamemodify(a:path, ':p')
+ " resolve() doesn't work when there's a trailing path separator.
+ if path =~ '/$'
+ let stripped_slash = 1
+ let path = substitute(path, '/$', '', '')
+ endif
+ let path = resolve(path)
+ " Restore the path separator after calling resolve().
+ if exists('stripped_slash') && path !~ '/$'
+ let path .= '/'
+ endif
+ return path
+ endif
+ return ''
+endfunction
+
+" Make an absolute pathname relative.
+
+function! xolox#misc#path#relative(path, base)
+ let path = xolox#misc#path#split(a:path)
+ let base = xolox#misc#path#split(a:base)
+ while path != [] && base != [] && path[0] == base[0]
+ call remove(path, 0)
+ call remove(base, 0)
+ endwhile
+ let distance = repeat(['..'], len(base))
+ return xolox#misc#path#join(distance + path)
+endfunction
+
+" Join a directory and filename into a single pathname.
+
+function! xolox#misc#path#merge(parent, child, ...)
+ " TODO Use isabs()!
+ if type(a:parent) == type('') && type(a:child) == type('')
+ if s:windows_compatible
+ let parent = substitute(a:parent, '[\\/]\+$', '', '')
+ let child = substitute(a:child, '^[\\/]\+', '', '')
+ return parent . '\' . child
+ else
+ let parent = substitute(a:parent, '/\+$', '', '')
+ let child = substitute(a:child, '^/\+', '', '')
+ return parent . '/' . child
+ endif
+ endif
+ return ''
+endfunction
+
+" Find the common prefix of path components in a list of pathnames.
+
+function! xolox#misc#path#commonprefix(paths)
+ let common = xolox#misc#path#split(a:paths[0])
+ for path in a:paths
+ let index = 0
+ for segment in xolox#misc#path#split(path)
+ if len(common) <= index
+ break
+ elseif common[index] != segment
+ call remove(common, index, -1)
+ break
+ endif
+ let index += 1
+ endfor
+ endfor
+ return xolox#misc#path#join(common)
+endfunction
+
+" Encode a pathname so it can be used as a filename.
+
+function! xolox#misc#path#encode(path)
+ let mask = s:windows_compatible ? '[*|\\/:"<>?%]' : '[\\/%]'
+ return substitute(a:path, mask, '\=printf("%%%x", char2nr(submatch(0)))', 'g')
+endfunction
+
+" Decode a pathname previously encoded with xolox#misc#path#encode().
+
+function! xolox#misc#path#decode(encoded_path)
+ return substitute(a:encoded_path, '%\(\x\x\?\)', '\=nr2char("0x" . submatch(1))', 'g')
+endfunction
+
+" Check whether two pathnames point to the same file.
+
+if s:windows_compatible
+ function! xolox#misc#path#equals(a, b)
+ return a:a ==? a:b || xolox#misc#path#absolute(a:a) ==? xolox#misc#path#absolute(a:b)
+ endfunction
+else
+ function! xolox#misc#path#equals(a, b)
+ return a:a ==# a:b || xolox#misc#path#absolute(a:a) ==# xolox#misc#path#absolute(a:b)
+ endfunction
+endif
+
+" Check whether a path is relative.
+
+function! xolox#misc#path#is_relative(path)
+ if a:path =~ '^\w\+://'
+ return 0
+ elseif s:windows_compatible
+ return a:path !~ '^\(\w:\|[\\/]\)'
+ else
+ return a:path !~ '^/'
+ endif
+endfunction
+
+" Create a temporary directory and return the path.
+
+function! xolox#misc#path#tempdir()
+ if !exists('s:tempdir_counter')
+ let s:tempdir_counter = 1
+ endif
+ if exists('*mkdir')
+ if s:windows_compatible
+ let template = $TMP . '\vim_tempdir_'
+ elseif filewritable('/tmp') == 2
+ let template = '/tmp/vim_tempdir_'
+ endif
+ endif
+ if !exists('template')
+ throw "xolox#misc#path#tempdir() hasn't been implemented on your platform!"
+ endif
+ while 1
+ let directory = template . s:tempdir_counter
+ try
+ call mkdir(directory, '', 0700)
+ return directory
+ catch /\<E739\>/
+ " Keep looking for a non-existing directory.
+ endtry
+ let s:tempdir_counter += 1
+ endwhile
+endfunction
+
+" vim: ts=2 sw=2 et
View
12 .vim/autoload/xolox/misc/str.vim
@@ -0,0 +1,12 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: June 14, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Trim whitespace from start and end of string.
+
+function! xolox#misc#str#trim(s)
+ return substitute(a:s, '^\_s*\(.\{-}\)\_s*$', '\1', '')
+endfunction
+
+" vim: ts=2 sw=2 et
View
85 .vim/autoload/xolox/misc/timer.vim
@@ -0,0 +1,85 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+if !exists('g:timer_enabled')
+ let g:timer_enabled = 0
+endif
+
+if !exists('g:timer_verbosity')
+ let g:timer_verbosity = 1
+endif
+
+let s:has_reltime = has('reltime')
+
+" Start a timer.
+
+function! xolox#misc#timer#start()
+ if g:timer_enabled || &verbose >= g:timer_verbosity
+ return s:has_reltime ? reltime() : [localtime()]
+ endif
+ return []
+endfunction
+
+" Stop a timer and print the elapsed time (only if the user is interested).
+
+function! xolox#misc#timer#stop(...)
+ if (g:timer_enabled || &verbose >= g:timer_verbosity)
+ call call('xolox#misc#msg#info', map(copy(a:000), 's:convert_value(v:val)'))
+ endif
+endfunction
+
+function! s:convert_value(value)
+ if type(a:value) != type([])
+ return a:value
+ elseif !empty(a:value)
+ if s:has_reltime
+ let ts = xolox#misc#str#trim(reltimestr(reltime(a:value)))
+ else
+ let ts = localtime() - a:value[0]
+ endif
+ return xolox#misc#timer#format_timespan(ts)
+ else
+ return '?'
+ endif
+endfunction
+
+" Format number of seconds as human friendly description.
+
+let s:units = [['day', 60 * 60 * 24], ['hour', 60 * 60], ['minute', 60], ['second', 1]]
+
+function! xolox#misc#timer#format_timespan(ts)
+
+ " Convert timespan to integer.
+ let seconds = a:ts + 0
+
+ " Fast common case with extra precision from reltime().
+ if seconds < 5
+ let extract = matchstr(a:ts, '^\d\+\(\.0*[1-9][1-9]\?\)\?')
+ if extract =~ '[123456789]'
+ return extract . ' second' . (extract != '1' ? 's' : '')
+ endif
+ endif
+
+ " Generic but slow code.
+ let result = []
+ for [name, size] in s:units
+ if seconds >= size
+ let counter = seconds / size
+ let seconds = seconds % size
+ let suffix = counter != 1 ? 's' : ''
+ call add(result, printf('%i %s%s', counter, name, suffix))
+ endif
+ endfor
+
+ " Format the resulting text?
+ if len(result) == 1
+ return result[0]
+ else
+ return join(result[0:-2], ', ') . ' and ' . result[-1]
+ endif
+
+endfunction
+
+" vim: ts=2 sw=2 et
View
202 .vim/doc/ft_lua.txt
@@ -0,0 +1,202 @@
+*ft_lua.txt* Lua file type plug-in for the Vim text editor
+
+The Lua [1] file type plug-in for Vim makes it easier to work with Lua source
+code in Vim by providing the following features:
+
+ - The |'includeexpr'| option is set so that the |gf| (go to file) mapping knows
+ how to resolve Lua module names using package.path [2]
+
+ - The |'include'| option is set so that Vim follows dofile() [3], loadfile() [4]
+ and require() [5] calls when looking for identifiers in included files
+ (this works together with the |'includeexpr'| option)
+
+ - An automatic command is installed that runs 'luac -p' when you save your Lua
+ scripts. If 'luac' reports any errors they are shown in the quick-fix list
+ and Vim jumps to the line of the first error. If 'luac -p' doesn't report
+ any errors a check for undefined global variables is performed by parsing
+ the output of 'luac -p -l'
+
+ - '<F1>' on a Lua function or 'method' call will try to open the relevant
+ documentation in the Lua Reference for Vim [6]
+
+ - The |'completefunc'| option is set to allow completion of Lua 5.1 keywords,
+ global variables and library members using Control-X Control-U
+
+ - The |'omnifunc'| option is set to allow dynamic completion of the variables
+ defined in all modules installed on the system using Control-X Control-O,
+ however it needs to be explicitly enabled by setting the
+ |lua_complete_omni| option because this functionality may have undesired
+ side effects! When you invoke omni completion after typing 'require '' or
+ 'require('' you get completion of module names
+
+ Screenshot of omni completion, see reference [7]
+
+ - Several |text-objects| are defined so you can jump between blocks and
+ functions
+
+ - A pretty nifty hack of the matchit plug-in (see |matchit-install|) is
+ included: When the cursor is on a 'function' or 'return' keyword the '%'
+ mapping cycles between the relevant keywords ('function', 'return', 'end'),
+ this also works for branching statements ('if', 'elseif', 'else', 'end')
+ and looping statements ('for', 'while', 'repeat', 'until', 'end')
+
+===============================================================================
+ *ft_lua-installation*
+Installation ~
+
+Unzip the most recent ZIP archive [8] file inside your Vim profile directory
+(usually this is '~/.vim' on UNIX and '%USERPROFILE%\vimfiles' on Windows),
+restart Vim and execute the command ':helptags ~/.vim/doc' (use ':helptags
+~\vimfiles\doc' instead on Windows). Now try it out: Edit a Lua script and try
+any of the features documented above.
+
+Note that on Windows a command prompt window pops up whenever Lua is run as an
+external process. If this bothers you then you can install my shell.vim [9]
+plug-in which includes a DLL [10] that works around this issue. Once you've
+installed both plug-ins it should work out of the box!
+
+===============================================================================
+ *ft_lua-options*
+Options ~
+
+The Lua file type plug-in handles options as follows: First it looks at buffer
+local variables, then it looks at global variables and if neither exists a
+default is chosen. This means you can change how the plug-in works for
+individual buffers. For example to change the location of the Lua compiler
+used to check the syntax:
+>
+ " This sets the default value for all buffers.
+ :let g:lua_compiler_name = '/usr/local/bin/luac'
+
+ " This is how you change the value for one buffer.
+ :let b:lua_compiler_name = '/usr/local/bin/lualint'
+
+-------------------------------------------------------------------------------
+The *lua_path* option
+
+This option contains the value of 'package.path' as a string. You shouldn't
+need to change this because the plug-in is aware of $LUA_PATH [2] and if that
+isn't set the plug-in will run a Lua interpreter to get the value of
+package.path [2].
+
+-------------------------------------------------------------------------------
+The *lua_check_syntax* option
+
+When you write a Lua script to disk the plug-in automatically runs the Lua
+compiler to check for syntax errors. To disable this behavior you can set this
+option to false (0):
+>
+ let g:lua_check_syntax = 0
+
+You can manually check the syntax using the ':CheckSyntax' command.
+
+-------------------------------------------------------------------------------
+The *lua_check_globals* option
+
+When you write a Lua script to disk the plug-in automatically runs the Lua
+compiler to check for undefined global variables. To disable this behavior you
+can set this option to false (0):
+>
+ let g:lua_check_globals = 0
+
+You can manually check the globals using the ':CheckGlobals' command.
+
+-------------------------------------------------------------------------------
+The *lua_compiler_name* option
+
+The name or path of the Lua compiler used to check for syntax errors (defaults
+to 'luac'). You can set this option to run the Lua compiler from a
+non-standard location or to run a dedicated syntax checker like lualint [11].
+
+-------------------------------------------------------------------------------
+The *lua_compiler_args* option
+
+The argument(s) required by the compiler or syntax checker (defaults to '-p').
+
+-------------------------------------------------------------------------------
+The *lua_error_format* option
+
+If you use a dedicated syntax checker you may need to change this option to
+reflect the format of the messages printed by the syntax checker.
+
+-------------------------------------------------------------------------------
+The *lua_complete_keywords* option
+
+To disable completion of keywords you can set this option to false (0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_globals* option
+
+To disable completion of global functions you can set this option to false
+(0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_library* option
+
+To disable completion of library functions you can set this option to false
+(0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_dynamic* option
+
+When you type a dot after a word the Lua file type plug-in will automatically
+start completion. To disable this behavior you can set this option to false
+(0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_omni* option
+
+This option is disabled by default for two reasons:
+
+ - The omni completion support works by enumerating and loading all installed
+ modules. If module loading has side effects this can have unintended
+ consequences!
+
+ - Because all modules installed on the system are loaded, collecting the
+ completion candidates can be slow. After the first run the completion
+ candidates are cached so this will only bother you once (until you restart
+ Vim).
+
+If you want to use the omni completion despite the warnings above, execute the
+following command:
+>
+ :let g:lua_complete_omni = 1
+
+Now when you type Control-X Control-O Vim will hang for a moment, after which
+you should be presented with an enormous list of completion candidates :-)
+
+===============================================================================
+ *ft_lua-contact*
+Contact ~
+
+If you have questions, bug reports, suggestions, etc. the author can be
+contacted at peter@peterodding.com. The latest version is available at
+http://peterodding.com/code/vim/lua-ftplugin and http://github.com/xolox/vim-lua-ftplugin.
+If you like this plug-in please vote for it on Vim Online [12].
+
+===============================================================================
+ *ft_lua-license*
+License ~
+
+This software is licensed under the MIT license [13]. Copyright 2011 Peter
+Odding <peter@peterodding.com>.
+
+===============================================================================
+ *ft_lua-references*
+References ~
+
+[1] http://www.lua.org/
+[2] http://www.lua.org/manual/5.1/manual.html#pdf-package.path
+[3] http://www.lua.org/manual/5.1/manual.html#pdf-dofile
+[4] http://www.lua.org/manual/5.1/manual.html#pdf-loadfile
+[5] http://www.lua.org/manual/5.1/manual.html#pdf-require
+[6] http://www.vim.org/scripts/script.php?script_id=1291
+[7] http://peterodding.com/code/vim/lua-ftplugin/screenshots/omni-completion.png
+[8] http://peterodding.com/code/vim/downloads/lua-ftplugin.zip
+[9] http://peterodding.com/code/vim/shell/
+[10] http://en.wikipedia.org/wiki/Dynamic-link_library
+[11] http://lua-users.org/wiki/LuaLint
+[12] http://www.vim.org/scripts/script.php?script_id=3625
+[13] http://en.wikipedia.org/wiki/MIT_License
+
+vim: ft=help
View
195 .vim/doc/lua-ftplugin.txt
@@ -0,0 +1,195 @@
+*lua-ftplugin.txt* Lua file type plug-in for the Vim text editor
+
+The Lua [1] file type plug-in for Vim makes it easier to work with Lua source
+code in Vim by providing the following features:
+
+ - The |'includeexpr'| option is set so that the |gf| (go to file) mapping knows
+ how to resolve Lua module names using package.path [2]
+
+ - The |'include'| option is set so that Vim follows dofile() [3], loadfile() [4]
+ and require() [5] calls when looking for identifiers in included files
+ (this works together with the |'includeexpr'| option)
+
+ - An automatic command is installed that runs 'luac -p' when you save your Lua
+ scripts. If 'luac' reports any errors they are shown in the quick-fix list
+ and Vim jumps to the line of the first error. If 'luac -p' doesn't report
+ any errors a check for undefined global variables is performed by parsing
+ the output of 'luac -p -l'
+
+ - '<F1>' on a Lua function or 'method' call will try to open the relevant
+ documentation in the Lua Reference for Vim [6]
+
+ - The |'completefunc'| option is set to allow completion of Lua 5.1 keywords,
+ global variables and library members using Control-X Control-U
+
+ - The |'omnifunc'| option is set to allow dynamic completion of the variables
+ defined in all modules installed on the system using Control-X Control-O,
+ however it needs to be explicitly enabled by setting the
+ |lua_complete_omni| option because this functionality may have undesired
+ side effects! When you invoke omni completion after typing 'require '' or
+ 'require('' you get completion of module names
+
+ Screenshot of omni completion, see reference [7]
+
+ - Several |text-objects| are defined so you can jump between blocks and
+ functions
+
+ - A pretty nifty hack of the matchit plug-in (see |matchit-install|) is
+ included: When the cursor is on a 'function' or 'return' keyword the '%'
+ mapping cycles between the relevant keywords ('function', 'return', 'end'),
+ this also works for branching statements ('if', 'elseif', 'else', 'end')
+ and looping statements ('for', 'while', 'repeat', 'until', 'end')
+
+===============================================================================
+ *lua-ftplugin-installation*
+Installation ~
+
+Unzip the most recent ZIP archive [8] file inside your Vim profile directory
+(usually this is '~/.vim' on UNIX and '%USERPROFILE%\vimfiles' on Windows),
+restart Vim and execute the command ':helptags ~/.vim/doc' (use ':helptags
+~\vimfiles\doc' instead on Windows). Now try it out: Edit a Lua script and try
+any of the features documented above.
+
+===============================================================================
+ *lua-ftplugin-options*
+Options ~
+
+The Lua file type plug-in handles options as follows: First it looks at buffer
+local variables, then it looks at global variables and if neither exists a
+default is chosen. This means you can change how the plug-in works for
+individual buffers. For example to change the location of the Lua compiler
+used to check the syntax:
+>
+ " This sets the default value for all buffers.
+ :let g:lua_compiler_name = '/usr/local/bin/luac'
+
+ " This is how you change the value for one buffer.
+ :let b:lua_compiler_name = '/usr/local/bin/lualint'
+
+-------------------------------------------------------------------------------
+The *lua_path* option
+
+This option contains the value of 'package.path' as a string. You shouldn't
+need to change this because the plug-in is aware of $LUA_PATH [2] and if that
+isn't set the plug-in will run a Lua interpreter to get the value of
+package.path [2].
+
+-------------------------------------------------------------------------------
+The *lua_check_syntax* option
+
+When you write a Lua script to disk the plug-in automatically runs the Lua
+compiler to check for syntax errors. To disable this behavior you can set this
+option to false (0):
+>
+ let g:lua_check_syntax = 0
+
+You can manually check the syntax using the ':CheckSyntax' command.
+
+-------------------------------------------------------------------------------
+The *lua_check_globals* option
+
+When you write a Lua script to disk the plug-in automatically runs the Lua
+compiler to check for undefined global variables. To disable this behavior you
+can set this option to false (0):
+>
+ let g:lua_check_globals = 0
+
+You can manually check the globals using the ':CheckGlobals' command.
+
+-------------------------------------------------------------------------------
+The *lua_compiler_name* option
+
+The name or path of the Lua compiler used to check for syntax errors (defaults
+to 'luac'). You can set this option to run the Lua compiler from a
+non-standard location or to run a dedicated syntax checker like lualint [9].
+
+-------------------------------------------------------------------------------
+The *lua_compiler_args* option
+
+The argument(s) required by the compiler or syntax checker (defaults to '-p').
+
+-------------------------------------------------------------------------------
+The *lua_error_format* option
+
+If you use a dedicated syntax checker you may need to change this option to
+reflect the format of the messages printed by the syntax checker.
+
+-------------------------------------------------------------------------------
+The *lua_complete_keywords* option
+
+To disable completion of keywords you can set this option to false (0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_globals* option
+
+To disable completion of global functions you can set this option to false
+(0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_library* option
+
+To disable completion of library functions you can set this option to false
+(0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_dynamic* option
+
+When you type a dot after a word the Lua file type plug-in will automatically
+start completion. To disable this behavior you can set this option to false
+(0).
+
+-------------------------------------------------------------------------------
+The *lua_complete_omni* option
+
+This option is disabled by default for two reasons:
+
+ - The omni completion support works by enumerating and loading all installed
+ modules. If module loading has side effects this can have unintended
+ consequences!
+
+ - Because all modules installed on the system are loaded, collecting the
+ completion candidates can be slow. After the first run the completion
+ candidates are cached so this will only bother you once (until you restart
+ Vim).
+
+If you want to use the omni completion despite the warnings above, execute the
+following command:
+>
+ :let g:lua_complete_omni = 1
+
+Now when you type Control-X Control-O Vim will hang for a moment, after which
+you should be presented with an enormous list of completion candidates :-)
+
+===============================================================================
+ *lua-ftplugin-contact*
+Contact ~
+
+If you have questions, bug reports, suggestions, etc. the author can be
+contacted at peter@peterodding.com. The latest version is available at
+http://peterodding.com/code/vim/lua-ftplugin and http://github.com/xolox/vim-lua-ftplugin.
+If you like this plug-in please vote for it on Vim Online [10].
+
+===============================================================================
+ *lua-ftplugin-license*
+License ~
+
+This software is licensed under the MIT license [11]. Copyright 2011 Peter
+Odding <peter@peterodding.com>.
+
+===============================================================================
+ *lua-ftplugin-references*
+References ~
+
+[1] http://www.lua.org/
+[2] http://www.lua.org/manual/5.1/manual.html#pdf-package.path
+[3] http://www.lua.org/manual/5.1/manual.html#pdf-dofile
+[4] http://www.lua.org/manual/5.1/manual.html#pdf-loadfile
+[5] http://www.lua.org/manual/5.1/manual.html#pdf-require
+[6] http://www.vim.org/scripts/script.php?script_id=1291
+[7] http://peterodding.com/code/vim/lua-ftplugin/screenshots/omni-completion.png
+[8] http://peterodding.com/code/vim/downloads/lua-ftplugin.zip
+[9] http://lua-users.org/wiki/LuaLint
+[10] http://www.vim.org/scripts/script.php?script_id=3625
+[11] http://en.wikipedia.org/wiki/MIT_License
+
+vim: ft=help
View
2  .vim/ftdetect/ruby.vim
@@ -5,7 +5,7 @@ au BufNewFile,BufRead *.rb,*.rbw,*.gem,*.gemspec set filetype=ruby
au BufNewFile,BufRead *.builder,*.rxml,*.rjs set filetype=ruby
" Rakefile
-au BufNewFile,BufRead [rR]akefile,*.rake,Capfile set filetype=ruby
+au BufNewFile,BufRead [rR]akefile,*.rake,Capfile,VagrantFile set filetype=ruby
" Rantfile
au BufNewFile,BufRead [rR]antfile,*.rant set filetype=ruby
View
96 .vim/ftplugin/lua.vim
@@ -0,0 +1,96 @@
+" Vim file type plug-in
+" Language: Lua 5.1
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: June 18, 2011
+" URL: http://peterodding.com/code/vim/lua-ftplugin
+
+if exists('b:did_ftplugin')
+ finish
+else
+ let b:did_ftplugin = 1
+endif
+
+" A list of commands that undo buffer local changes made below.
+let s:undo_ftplugin = []
+
+" Set comment (formatting) related options. {{{1
+setlocal fo-=t fo+=c fo+=r fo+=o fo+=q fo+=l
+setlocal cms=--%s com=s:--[[,m:\ ,e:]],:--
+call add(s:undo_ftplugin, 'setlocal fo< cms< com<')
+
+" Tell Vim how to follow dofile(), loadfile() and require() calls. {{{1
+let &l:include = '\v<((do|load)file|require)[^''"]*[''"]\zs[^''"]+'
+let &l:includeexpr = 'xolox#lua#includeexpr(v:fname)'
+call add(s:undo_ftplugin, 'setlocal inc< inex<')
+
+" Enable completion of Lua keywords, globals and library members. {{{1
+setlocal completefunc=xolox#lua#completefunc
+call add(s:undo_ftplugin, 'setlocal completefunc<')
+
+" Enable dynamic completion by searching "package.path" and "package.cpath". {{{1
+setlocal omnifunc=xolox#lua#omnifunc
+call add(s:undo_ftplugin, 'setlocal omnifunc<')
+
+" Set a filename filter for the Windows file open/save dialogs. {{{1
+if has('gui_win32') && !exists('b:browsefilter')
+ let b:browsefilter = "Lua Files (*.lua)\t*.lua\nAll Files (*.*)\t*.*\n"
+ call add(s:undo_ftplugin, 'unlet! b:browsefilter')
+endif
+
+" Define a buffer local command to manually check the syntax.
+command! -bar -buffer CheckSyntax call xolox#lua#checksyntax()
+call add(s:undo_ftplugin, 'delcommand CheckSyntax')
+
+" Define a buffer local command to manually check for global variables.
+command! -bar -bang -buffer CheckGlobals call xolox#lua#checkglobals(<q-bang> == '!')
+call add(s:undo_ftplugin, 'delcommand CheckGlobals')
+
+" Define mappings for context-sensitive help using Lua Reference for Vim. {{{1
+imap <buffer> <F1> <C-o>:call xolox#lua#help()<Cr>
+nmap <buffer> <F1> :call xolox#lua#help()<Cr>
+call add(s:undo_ftplugin, 'iunmap <buffer> <F1>')
+call add(s:undo_ftplugin, 'nunmap <buffer> <F1>')
+
+" Define custom text objects to navigate Lua source code. {{{1
+noremap <buffer> <silent> [{ m':call xolox#lua#jumpblock(0)<Cr>
+noremap <buffer> <silent> ]} m':call xolox#lua#jumpblock(1)<Cr>
+noremap <buffer> <silent> [[ m':call xolox#lua#jumpthisfunc(0)<Cr>
+noremap <buffer> <silent> ][ m':call xolox#lua#jumpthisfunc(1)<Cr>
+noremap <buffer> <silent> [] m':call xolox#lua#jumpotherfunc(0)<Cr>
+noremap <buffer> <silent> ]] m':call xolox#lua#jumpotherfunc(1)<Cr>
+call add(s:undo_ftplugin, 'unmap <buffer> [{')
+call add(s:undo_ftplugin, 'unmap <buffer> ]}')
+call add(s:undo_ftplugin, 'unmap <buffer> [[')
+call add(s:undo_ftplugin, 'unmap <buffer> ][')
+call add(s:undo_ftplugin, 'unmap <buffer> []')
+call add(s:undo_ftplugin, 'unmap <buffer> ]]')
+
+" Enable extended matching with "%" using the "matchit" plug-in. {{{1
+if exists('loaded_matchit')
+ let b:match_ignorecase = 0
+ let b:match_words = 'xolox#lua#matchit()'
+ call add(s:undo_ftplugin, 'unlet! b:match_ignorecase b:match_words b:match_skip')
+endif
+
+" Enable dynamic completion on typing "require('" or "variable."? {{{1
+inoremap <buffer> <silent> <expr> . xolox#lua#completedynamic('.')
+call add(s:undo_ftplugin, 'iunmap <buffer> .')
+inoremap <buffer> <silent> <expr> ' xolox#lua#completedynamic("'")
+call add(s:undo_ftplugin, "iunmap <buffer> '")
+inoremap <buffer> <silent> <expr> " xolox#lua#completedynamic('"')
+call add(s:undo_ftplugin, 'iunmap <buffer> "')
+
+" Enable tool tips with function signatures? {{{1
+if has('balloon_eval')
+ setlocal ballooneval balloonexpr=xolox#lua#getsignature(v:beval_text)
+ call add(s:undo_ftplugin, 'setlocal ballooneval< balloonexpr<')
+endif
+
+" }}}1
+
+" Let Vim know how to disable the plug-in.
+call map(s:undo_ftplugin, "'execute ' . string(v:val)")
+let b:undo_ftplugin = join(s:undo_ftplugin, ' | ')
+unlet s:undo_ftplugin
+
+" vim: ts=2 sw=2 et
View
75 .vim/misc/lua-ftplugin/complete.lua
@@ -0,0 +1,75 @@
+#!/usr/bin/env lua
+
+--[[
+
+Author: Peter Odding <peter@peterodding.com>
+Last Change: June 14, 2011
+URL: http://peterodding.com/code/vim/lua-ftplugin
+
+This Lua script prints a few hundred lines of Vim script to standard output.
+These lines are used by my Lua file type plug-in for the Vim text editor to
+provide completion of Lua keywords, globals and library identifiers.
+
+]]
+
+local function sorted(input)
+ local keys = {}
+ for key in pairs(input) do table.insert(keys, key) end
+ table.sort(keys)
+ local index = 1
+ return function()
+ local key = keys[index]
+ index = index + 1
+ return key, input[key]
+ end
+end
+
+local keywords = {
+ ['and'] = true, ['break'] = true, ['do'] = true, ['else'] = true,
+ ['elseif'] = true, ['end'] = true, ['false'] = true, ['for'] = true,
+ ['function'] = true, ['if'] = true, ['in'] = true, ['local'] = true,
+ ['nil'] = true, ['not'] = true, ['or'] = true, ['repeat'] = true,
+ ['return'] = true, ['then'] = true, ['true'] = true,
+ ['until'] = true, ['while'] = true
+}
+
+io.write 'let s:keywords = ['
+for keyword in sorted(keywords) do
+ io.write(("\n \\ { 'word': %q, 'kind': 'k' },"):format(keyword))
+end
+io.write ']\n'
+
+local function identifier(value)
+ -- TODO This pattern does *not* match identifiers outside of the C locale
+ local pattern = '^[A-Za-z_][A-Za-z_0-9]*$'
+ return type(value) == 'string' and value:find(pattern) and not keywords[value]
+end
+
+local globals = {}
+local libraries = {}
+
+for global, value in pairs(_G) do
+ if identifier(global) then
+ globals[global .. (type(value) == 'function' and '()' or '')] = type(value) == 'function' and 'f' or 'v'
+ if type(value) == 'table' and value ~= _G then
+ for member, value in pairs(value) do
+ if identifier(member) then
+ member = global .. '.' .. member
+ libraries[member .. (type(value) == 'function' and '()' or '')] = type(value) == 'function' and 'f' or 'm'
+ end
+ end
+ end
+ end
+end
+
+io.write '\nlet s:globals = ['
+for global, kind in sorted(globals) do
+ io.write(("\n \\ { 'word': %q, 'kind': '%s' },"):format(global, kind))
+end
+io.write ']\n\nlet s:library = ['
+for member, kind in sorted(libraries) do
+ io.write(("\n \\ { 'word': %q, 'kind': '%s' },"):format(member, kind))
+end
+io.write ']'
+
+-- vim: ts=2 sw=2 et
View
14 .vim/misc/lua-ftplugin/getsignatures.lua
@@ -0,0 +1,14 @@
+#!/usr/bin/env lua
+
+local http = require 'socket.http'
+local webpage = http.request 'http://www.lua.org/manual/5.1/manual.html'
+local matches = {}
+for anchor, signature in webpage:gmatch '<h3>%s*<a%s+name="pdf%-(.-)">%s*<code>%s*(.-)%s*</code>%s*</a>%s*</h3>' do
+ if anchor ~= signature then
+ signature = signature:gsub('&middot;', '.')
+ signature = signature:gsub('%s+%(', '(')
+ table.insert(matches, string.format("'%s': '%s'", anchor, signature))
+ end
+end
+local newline = '\n \\ '
+print(string.format('let g:xolox#lua_data#signatures = {%s%s }', newline, table.concat(matches, ',' .. newline)))
View
35 .vim/misc/lua-ftplugin/globals.lua
@@ -0,0 +1,35 @@
+#!/usr/bin/env lua
+
+-- Parse output of "luac -l" for GETGLOBAL/SETGLOBAL instructions.
+local command = string.format('luac -p -l "%s"', arg[1])
+local verbose = tonumber(arg[2]) ~= 0
+local compiler = io.popen(command)
+local matches = {}
+for line in compiler:lines() do
+ local inst = line:match '%]%s+([GS]ETGLOBAL)'
+ if inst then
+ local lnum = tonumber(line:match '%[(%d+)%]') or 0
+ local varname = line:match '(%S+)$' or ''
+ if lnum > 0 and varname ~= '' then
+ matches[#matches + 1] = {inst=inst, lnum=lnum, varname=varname}
+ end
+ end
+end
+
+-- Sort matched globals by ascending line numbers.
+table.sort(matches, function(a, b) return a.lnum < b.lnum end)
+
+-- Pass results to vim.
+local template = "{'filename': '%s', 'lnum': %i, 'text': '%s %s global %s', 'type': '%s'}"
+for _, match in ipairs(matches) do
+ local read = match.inst == 'GETGLOBAL'
+ local operation = read and 'Read of' or 'Write to'
+ local status, type = 'known', 'I'
+ if not _G[match.varname] then
+ status = 'unknown'
+ type = read and 'E' or 'W'
+ end
+ if type == 'E' or type == 'W' or verbose then
+ print(template:format(arg[1], match.lnum, operation, status, match.varname, type))
+ end
+end
View
87 .vim/misc/lua-ftplugin/omnicomplete.lua
@@ -0,0 +1,87 @@
+#!/usr/bin/env lua
+
+--[[
+
+Author: Peter Odding <peter@peterodding.com>
+Last Change: November 25, 2011
+URL: http://peterodding.com/code/vim/lua-ftplugin
+
+This Lua script is executed by the Lua file type plug-in for Vim to provide
+dynamic completion of function names defined by installed Lua modules. This
+works by expanding package.path and package.cpath in Vim script, loading every
+module found on the search path into this Lua script and then dumping the
+global state.
+
+]]
+
+local keywords = { ['and'] = true, ['break'] = true, ['do'] = true,
+ ['else'] = true, ['elseif'] = true, ['end'] = true, ['false'] = true,
+ ['for'] = true, ['function'] = true, ['if'] = true, ['in'] = true,
+ ['local'] = true, ['nil'] = true, ['not'] = true, ['or'] = true,
+ ['repeat'] = true, ['return'] = true, ['then'] = true, ['true'] = true,
+ ['until'] = true, ['while'] = true }
+
+local function isident(s)
+ return type(s) == 'string' and s:find('^[A-Za-z_][A-Za-z_0-9]*$') and not keywords[s]
+end
+
+local function addmatch(word, kind, desc)
+ if not desc then
+ print(string.format("{'word':'%s','kind':'%s'}", word, kind))
+ else
+ print(string.format("{'word':'%s','kind':'%s','menu':'%s'}", word, kind, (desc:gsub('\n', ' '))))
+