Add support for basic languages

coffee, cucumbeer, eruby, haml, haskell, javascript,
json, less, nginx, ocaml, ruby, sass, scss, slim,
stylus, textile, tmux
This commit is contained in:
Adam Stankiewicz
2013-09-12 16:17:03 +02:00
parent dce12af91b
commit 01fe1500df
74 changed files with 9074 additions and 1 deletions

404
ftplugin/coffee.vim Normal file
View File

@@ -0,0 +1,404 @@
" 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
call coffee#CoffeeSetUpVariables()
setlocal formatoptions-=t formatoptions+=croql
setlocal comments=:# commentstring=#\ %s
setlocal omnifunc=javascriptcomplete#CompleteJS
" Create custom augroups.
augroup CoffeeBufUpdate | augroup END
augroup CoffeeBufNew | augroup END
" Enable coffee compiler if a compiler isn't set already.
if !len(&l:makeprg)
compiler coffee
endif
" Switch to the window for buf.
function! s:SwitchWindow(buf)
exec bufwinnr(a:buf) 'wincmd w'
endfunction
" Create a new scratch buffer and return the bufnr of it. After the function
" returns, vim remains in the scratch buffer so more set up can be done.
function! s:ScratchBufBuild(src, vert, size)
if a:size <= 0
if a:vert
let size = winwidth(bufwinnr(a:src)) / 2
else
let size = winheight(bufwinnr(a:src)) / 2
endif
endif
if a:vert
vertical belowright new
exec 'vertical resize' size
else
belowright new
exec 'resize' size
endif
setlocal bufhidden=wipe buftype=nofile nobuflisted noswapfile nomodifiable
nnoremap <buffer> <silent> q :hide<CR>
return bufnr('%')
endfunction
" Replace buffer contents with text and delete the last empty line.
function! s:ScratchBufUpdate(buf, text)
" Move to the scratch buffer.
call s:SwitchWindow(a:buf)
" Double check we're in the scratch buffer before overwriting.
if bufnr('%') != a:buf
throw 'unable to change to scratch buffer'
endif
setlocal modifiable
silent exec '% delete _'
silent put! =a:text
silent exec '$ delete _'
setlocal nomodifiable
endfunction
" Parse the output of coffee into a qflist entry for src buffer.
function! s:ParseCoffeeError(output, src, startline)
" Coffee error is always on first line?
let match = matchlist(a:output,
\ '^\(\f\+\|\[stdin\]\):\(\d\):\(\d\): error: \(.\{-}\)' . "\n")
if !len(match)
return
endif
" Consider the line number from coffee as relative and add it to the beginning
" line number of the range the command was called on, then subtract one for
" zero-based relativity.
call setqflist([{'bufnr': a:src, 'lnum': a:startline + str2nr(match[2]) - 1,
\ 'type': 'E', 'col': str2nr(match[3]), 'text': match[4]}], 'r')
endfunction
" Reset source buffer variables.
function! s:CoffeeCompileResetVars()
" Variables defined in source buffer:
" b:coffee_compile_buf: bufnr of output buffer
" Variables defined in output buffer:
" b:coffee_src_buf: bufnr of source buffer
" b:coffee_compile_pos: previous cursor position in output buffer
let b:coffee_compile_buf = -1
endfunction
function! s:CoffeeWatchResetVars()
" Variables defined in source buffer:
" b:coffee_watch_buf: bufnr of output buffer
" Variables defined in output buffer:
" b:coffee_src_buf: bufnr of source buffer
" b:coffee_watch_pos: previous cursor position in output buffer
let b:coffee_watch_buf = -1
endfunction
function! s:CoffeeRunResetVars()
" Variables defined in CoffeeRun source buffer:
" b:coffee_run_buf: bufnr of output buffer
" Variables defined in CoffeeRun output buffer:
" b:coffee_src_buf: bufnr of source buffer
" b:coffee_run_pos: previous cursor position in output buffer
let b:coffee_run_buf = -1
endfunction
" Clean things up in the source buffers.
function! s:CoffeeCompileClose()
" Switch to the source buffer if not already in it.
silent! call s:SwitchWindow(b:coffee_src_buf)
call s:CoffeeCompileResetVars()
endfunction
function! s:CoffeeWatchClose()
silent! call s:SwitchWindow(b:coffee_src_buf)
silent! autocmd! CoffeeAuWatch * <buffer>
call s:CoffeeWatchResetVars()
endfunction
function! s:CoffeeRunClose()
silent! call s:SwitchWindow(b:coffee_src_buf)
call s:CoffeeRunResetVars()
endfunction
" Compile the lines between startline and endline and put the result into buf.
function! s:CoffeeCompileToBuf(buf, startline, endline)
let src = bufnr('%')
let input = join(getline(a:startline, a:endline), "\n")
" Coffee doesn't like empty input.
if !len(input)
" Function should still return within output buffer.
call s:SwitchWindow(a:buf)
return
endif
" Pipe lines into coffee.
let output = system(g:coffee_compiler .
\ ' -scb' .
\ ' ' . b:coffee_litcoffee .
\ ' 2>&1', input)
" Paste output into output buffer.
call s:ScratchBufUpdate(a:buf, output)
" Highlight as JavaScript if there were no compile errors.
if v:shell_error
call s:ParseCoffeeError(output, src, a:startline)
setlocal filetype=
else
" Clear the quickfix list.
call setqflist([], 'r')
setlocal filetype=javascript
endif
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)
if a:args =~ '\<watch\>'
echoerr 'CoffeeCompile watch is deprecated! Please use CoffeeWatch instead'
sleep 5
call s:CoffeeWatch(a:args)
return
endif
" Switch to the source buffer if not already in it.
silent! call s:SwitchWindow(b:coffee_src_buf)
" Bail if not in source buffer.
if !exists('b:coffee_compile_buf')
return
endif
" Build the output buffer if it doesn't exist.
if bufwinnr(b:coffee_compile_buf) == -1
let src = bufnr('%')
let vert = exists('g:coffee_compile_vert') || a:args =~ '\<vert\%[ical]\>'
let size = str2nr(matchstr(a:args, '\<\d\+\>'))
" Build the output buffer and save the source bufnr.
let buf = s:ScratchBufBuild(src, vert, size)
let b:coffee_src_buf = src
" Set the buffer name.
exec 'silent! file [CoffeeCompile ' . src . ']'
" Clean up the source buffer when the output buffer is closed.
autocmd BufWipeout <buffer> call s:CoffeeCompileClose()
" Save the cursor when leaving the output buffer.
autocmd BufLeave <buffer> let b:coffee_compile_pos = getpos('.')
" Run user-defined commands on new buffer.
silent doautocmd CoffeeBufNew User CoffeeCompile
" Switch back to the source buffer and save the output bufnr. This also
" triggers BufLeave above.
call s:SwitchWindow(src)
let b:coffee_compile_buf = buf
endif
" Fill the scratch buffer.
call s:CoffeeCompileToBuf(b:coffee_compile_buf, a:startline, a:endline)
" Reset cursor to previous position.
call setpos('.', b:coffee_compile_pos)
" Run any user-defined commands on the scratch buffer.
silent doautocmd CoffeeBufUpdate User CoffeeCompile
endfunction
" Update the scratch buffer and switch back to the source buffer.
function! s:CoffeeWatchUpdate()
call s:CoffeeCompileToBuf(b:coffee_watch_buf, 1, '$')
call setpos('.', b:coffee_watch_pos)
silent doautocmd CoffeeBufUpdate User CoffeeWatch
call s:SwitchWindow(b:coffee_src_buf)
endfunction
" Continually compile a source buffer.
function! s:CoffeeWatch(args)
silent! call s:SwitchWindow(b:coffee_src_buf)
if !exists('b:coffee_watch_buf')
return
endif
if bufwinnr(b:coffee_watch_buf) == -1
let src = bufnr('%')
let vert = exists('g:coffee_watch_vert') || a:args =~ '\<vert\%[ical]\>'
let size = str2nr(matchstr(a:args, '\<\d\+\>'))
let buf = s:ScratchBufBuild(src, vert, size)
let b:coffee_src_buf = src
exec 'silent! file [CoffeeWatch ' . src . ']'
autocmd BufWipeout <buffer> call s:CoffeeWatchClose()
autocmd BufLeave <buffer> let b:coffee_watch_pos = getpos('.')
silent doautocmd CoffeeBufNew User CoffeeWatch
call s:SwitchWindow(src)
let b:coffee_watch_buf = buf
endif
" Make sure only one watch autocmd is defined on this buffer.
silent! autocmd! CoffeeAuWatch * <buffer>
augroup CoffeeAuWatch
autocmd InsertLeave <buffer> call s:CoffeeWatchUpdate()
autocmd BufWritePost <buffer> call s:CoffeeWatchUpdate()
augroup END
call s:CoffeeWatchUpdate()
endfunction
" Run a snippet of CoffeeScript between startline and endline.
function! s:CoffeeRun(startline, endline, args)
silent! call s:SwitchWindow(b:coffee_src_buf)
if !exists('b:coffee_run_buf')
return
endif
if bufwinnr(b:coffee_run_buf) == -1
let src = bufnr('%')
let buf = s:ScratchBufBuild(src, exists('g:coffee_run_vert'), 0)
let b:coffee_src_buf = src
exec 'silent! file [CoffeeRun ' . src . ']'
autocmd BufWipeout <buffer> call s:CoffeeRunClose()
autocmd BufLeave <buffer> let b:coffee_run_pos = getpos('.')
silent doautocmd CoffeeBufNew User CoffeeRun
call s:SwitchWindow(src)
let b:coffee_run_buf = buf
endif
if a:startline == 1 && a:endline == line('$')
let output = system(g:coffee_compiler .
\ ' ' . b:coffee_litcoffee .
\ ' ' . fnameescape(expand('%')) .
\ ' ' . a:args)
else
let input = join(getline(a:startline, a:endline), "\n")
if !len(input)
return
endif
let output = system(g:coffee_compiler .
\ ' -s' .
\ ' ' . b:coffee_litcoffee .
\ ' ' . a:args, input)
endif
call s:ScratchBufUpdate(b:coffee_run_buf, output)
call setpos('.', b:coffee_run_pos)
silent doautocmd CoffeeBufUpdate User CoffeeRun
endfunction
" Run coffeelint on a file, and add any errors between startline and endline
" to the quickfix list.
function! s:CoffeeLint(startline, endline, bang, args)
let input = join(getline(a:startline, a:endline), "\n")
if !len(input)
return
endif
let output = system(g:coffee_linter .
\ ' -s --csv' .
\ ' ' . b:coffee_litcoffee .
\ ' ' . g:coffee_lint_options .
\ ' ' . a:args .
\ ' 2>&1', input)
" Convert output into an array and strip off the csv header.
let lines = split(output, "\n")[1:]
let buf = bufnr('%')
let qflist = []
for line in lines
let match = matchlist(line, '^stdin,\(\d\+\),\d*,\(error\|warn\),\(.\+\)$')
" Ignore unmatched lines.
if !len(match)
continue
endif
" The 'type' will result in either 'E' or 'W'.
call add(qflist, {'bufnr': buf, 'lnum': a:startline + str2nr(match[1]) - 1,
\ 'type': toupper(match[2][0]), 'text': match[3]})
endfor
" Replace the quicklist with our items.
call setqflist(qflist, 'r')
" If not given a bang, jump to first error.
if !len(a:bang)
silent! cc 1
endif
endfunction
" Complete arguments for Coffee* commands.
function! s:CoffeeComplete(cmd, cmdline, cursor)
let args = ['vertical']
" If no partial command, return all possibilities.
if !len(a:cmd)
return args
endif
let pat = '^' . a:cmd
for arg in args
if arg =~ pat
return [arg]
endif
endfor
endfunction
" Set initial state variables if they don't exist
if !exists('b:coffee_compile_buf')
call s:CoffeeCompileResetVars()
endif
if !exists('b:coffee_watch_buf')
call s:CoffeeWatchResetVars()
endif
if !exists('b:coffee_run_buf')
call s:CoffeeRunResetVars()
endif
command! -range=% -bar -nargs=* -complete=customlist,s:CoffeeComplete
\ CoffeeCompile call s:CoffeeCompile(<line1>, <line2>, <q-args>)
command! -bar -nargs=* -complete=customlist,s:CoffeeComplete
\ CoffeeWatch call s:CoffeeWatch(<q-args>)
command! -range=% -bar -nargs=* CoffeeRun
\ call s:CoffeeRun(<line1>, <line2>, <q-args>)
command! -range=% -bang -bar -nargs=* CoffeeLint
\ call s:CoffeeLint(<line1>, <line2>, <q-bang>, <q-args>)

148
ftplugin/cucumber.vim Normal file
View File

@@ -0,0 +1,148 @@
" Vim filetype plugin
" Language: Cucumber
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2010 Aug 09
" Only do this when not done yet for this buffer
if (exists("b:did_ftplugin"))
finish
endif
let b:did_ftplugin = 1
setlocal formatoptions-=t formatoptions+=croql
setlocal comments=:# commentstring=#\ %s
setlocal omnifunc=CucumberComplete
let b:undo_ftplugin = "setl fo< com< cms< ofu<"
let b:cucumber_root = expand('%:p:h:s?.*[\/]\%(features\|stories\)\zs[\/].*??')
if !exists("g:no_plugin_maps") && !exists("g:no_cucumber_maps")
nnoremap <silent><buffer> <C-]> :<C-U>exe <SID>jump('edit',v:count)<CR>
nnoremap <silent><buffer> [<C-D> :<C-U>exe <SID>jump('edit',v:count)<CR>
nnoremap <silent><buffer> ]<C-D> :<C-U>exe <SID>jump('edit',v:count)<CR>
nnoremap <silent><buffer> <C-W>] :<C-U>exe <SID>jump('split',v:count)<CR>
nnoremap <silent><buffer> <C-W><C-]> :<C-U>exe <SID>jump('split',v:count)<CR>
nnoremap <silent><buffer> <C-W>d :<C-U>exe <SID>jump('split',v:count)<CR>
nnoremap <silent><buffer> <C-W><C-D> :<C-U>exe <SID>jump('split',v:count)<CR>
nnoremap <silent><buffer> <C-W>} :<C-U>exe <SID>jump('pedit',v:count)<CR>
nnoremap <silent><buffer> [d :<C-U>exe <SID>jump('pedit',v:count)<CR>
nnoremap <silent><buffer> ]d :<C-U>exe <SID>jump('pedit',v:count)<CR>
let b:undo_ftplugin .=
\ "|sil! nunmap <buffer> <C-]>" .
\ "|sil! nunmap <buffer> [<C-D>" .
\ "|sil! nunmap <buffer> ]<C-D>" .
\ "|sil! nunmap <buffer> <C-W>]" .
\ "|sil! nunmap <buffer> <C-W><C-]>" .
\ "|sil! nunmap <buffer> <C-W>d" .
\ "|sil! nunmap <buffer> <C-W><C-D>" .
\ "|sil! nunmap <buffer> <C-W>}" .
\ "|sil! nunmap <buffer> [d" .
\ "|sil! nunmap <buffer> ]d"
endif
function! s:jump(command,count)
let steps = s:steps('.')
if len(steps) == 0 || len(steps) < a:count
return 'echoerr "No matching step found"'
elseif len(steps) > 1 && !a:count
return 'echoerr "Multiple matching steps found"'
else
let c = a:count ? a:count-1 : 0
return a:command.' +'.steps[c][1].' '.escape(steps[c][0],' %#')
endif
endfunction
function! s:allsteps()
let step_pattern = '\C^\s*\K\k*\>\s*(\=\s*\zs\S.\{-\}\ze\s*)\=\s*\%(do\|{\)\s*\%(|[^|]*|\s*\)\=\%($\|#\)'
let steps = []
for file in split(glob(b:cucumber_root.'/**/*.rb'),"\n")
let lines = readfile(file)
let num = 0
for line in lines
let num += 1
if line =~ step_pattern
let type = matchstr(line,'\w\+')
let steps += [[file,num,type,matchstr(line,step_pattern)]]
endif
endfor
endfor
return steps
endfunction
function! s:steps(lnum)
let c = match(getline(a:lnum), '\S') + 1
while synIDattr(synID(a:lnum,c,1),'name') !~# '^$\|Region$'
let c = c + 1
endwhile
let step = matchstr(getline(a:lnum)[c-1 : -1],'^\s*\zs.\{-\}\ze\s*$')
return filter(s:allsteps(),'s:stepmatch(v:val[3],step)')
endfunction
function! s:stepmatch(receiver,target)
if a:receiver =~ '^[''"].*[''"]$'
let pattern = '^'.escape(substitute(a:receiver[1:-2],'$\w\+','(.*)','g'),'/').'$'
elseif a:receiver =~ '^/.*/$'
let pattern = a:receiver[1:-2]
elseif a:receiver =~ '^%r..*.$'
let pattern = escape(a:receiver[3:-2],'/')
else
return 0
endif
try
let vimpattern = substitute(substitute(pattern,'\\\@<!(?:','%(','g'),'\\\@<!\*?','{-}','g')
if a:target =~# '\v'.vimpattern
return 1
endif
catch
endtry
if has("ruby") && pattern !~ '\\\@<!#{'
ruby VIM.command("return #{if (begin; Kernel.eval('/'+VIM.evaluate('pattern')+'/'); rescue SyntaxError; end) === VIM.evaluate('a:target') then 1 else 0 end}")
else
return 0
endif
endfunction
function! s:bsub(target,pattern,replacement)
return substitute(a:target,'\C\\\@<!'.a:pattern,a:replacement,'g')
endfunction
function! CucumberComplete(findstart,base) abort
let indent = indent('.')
let group = synIDattr(synID(line('.'),indent+1,1),'name')
let type = matchstr(group,'\Ccucumber\zs\%(Given\|When\|Then\)')
let e = matchend(getline('.'),'^\s*\S\+\s')
if type == '' || col('.') < col('$') || e < 0
return -1
endif
if a:findstart
return e
endif
let steps = []
for step in s:allsteps()
if step[2] ==# type
if step[3] =~ '^[''"]'
let steps += [step[3][1:-2]]
elseif step[3] =~ '^/\^.*\$/$'
let pattern = step[3][2:-3]
let pattern = substitute(pattern,'\C^(?:|I )','I ','')
let pattern = s:bsub(pattern,'\\[Sw]','w')
let pattern = s:bsub(pattern,'\\d','1')
let pattern = s:bsub(pattern,'\\[sWD]',' ')
let pattern = s:bsub(pattern,'\[\^\\\="\]','_')
let pattern = s:bsub(pattern,'[[:alnum:]. _-][?*]?\=','')
let pattern = s:bsub(pattern,'\[\([^^]\).\{-\}\]','\1')
let pattern = s:bsub(pattern,'+?\=','')
let pattern = s:bsub(pattern,'(\([[:alnum:]. -]\{-\}\))','\1')
let pattern = s:bsub(pattern,'\\\([[:punct:]]\)','\1')
if pattern !~ '[\\()*?]'
let steps += [pattern]
endif
endif
endif
endfor
call filter(steps,'strpart(v:val,0,strlen(a:base)) ==# a:base')
return sort(steps)
endfunction
" vim:set sts=2 sw=2:

102
ftplugin/eruby.vim Normal file
View File

@@ -0,0 +1,102 @@
" Vim filetype plugin
" Language: eRuby
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" URL: https://github.com/vim-ruby/vim-ruby
" Release Coordinator: Doug Kearns <dougkearns@gmail.com>
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let s:save_cpo = &cpo
set cpo-=C
" Define some defaults in case the included ftplugins don't set them.
let s:undo_ftplugin = ""
let s:browsefilter = "All Files (*.*)\t*.*\n"
let s:match_words = ""
if !exists("g:eruby_default_subtype")
let g:eruby_default_subtype = "html"
endif
if &filetype =~ '^eruby\.'
let b:eruby_subtype = matchstr(&filetype,'^eruby\.\zs\w\+')
elseif !exists("b:eruby_subtype")
let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")
let b:eruby_subtype = matchstr(s:lines,'eruby_subtype=\zs\w\+')
if b:eruby_subtype == ''
let b:eruby_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.erb\|\.eruby\|\.erubis\)\+$','',''),'\.\zs\w\+$')
endif
if b:eruby_subtype == 'rhtml'
let b:eruby_subtype = 'html'
elseif b:eruby_subtype == 'rb'
let b:eruby_subtype = 'ruby'
elseif b:eruby_subtype == 'yml'
let b:eruby_subtype = 'yaml'
elseif b:eruby_subtype == 'js'
let b:eruby_subtype = 'javascript'
elseif b:eruby_subtype == 'txt'
" Conventional; not a real file type
let b:eruby_subtype = 'text'
elseif b:eruby_subtype == ''
let b:eruby_subtype = g:eruby_default_subtype
endif
endif
if exists("b:eruby_subtype") && b:eruby_subtype != ''
exe "runtime! ftplugin/".b:eruby_subtype.".vim ftplugin/".b:eruby_subtype."_*.vim ftplugin/".b:eruby_subtype."/*.vim"
else
runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
endif
unlet! b:did_ftplugin
" Override our defaults if these were set by an included ftplugin.
if exists("b:undo_ftplugin")
let s:undo_ftplugin = b:undo_ftplugin
unlet b:undo_ftplugin
endif
if exists("b:browsefilter")
let s:browsefilter = b:browsefilter
unlet b:browsefilter
endif
if exists("b:match_words")
let s:match_words = b:match_words
unlet b:match_words
endif
runtime! ftplugin/ruby.vim ftplugin/ruby_*.vim ftplugin/ruby/*.vim
let b:did_ftplugin = 1
" Combine the new set of values with those previously included.
if exists("b:undo_ftplugin")
let s:undo_ftplugin = b:undo_ftplugin . " | " . s:undo_ftplugin
endif
if exists ("b:browsefilter")
let s:browsefilter = substitute(b:browsefilter,'\cAll Files (\*\.\*)\t\*\.\*\n','','') . s:browsefilter
endif
if exists("b:match_words")
let s:match_words = b:match_words . ',' . s:match_words
endif
" Change the browse dialog on Win32 to show mainly eRuby-related files
if has("gui_win32")
let b:browsefilter="eRuby Files (*.erb, *.rhtml)\t*.erb;*.rhtml\n" . s:browsefilter
endif
" Load the combined list of match_words for matchit.vim
if exists("loaded_matchit")
let b:match_words = s:match_words
endif
" TODO: comments=
setlocal commentstring=<%#%s%>
let b:undo_ftplugin = "setl cms< "
\ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: nowrap sw=2 sts=2 ts=8:

68
ftplugin/haml.vim Normal file
View File

@@ -0,0 +1,68 @@
" Vim filetype plugin
" Language: Haml
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2010 May 21
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let s:save_cpo = &cpo
set cpo-=C
" Define some defaults in case the included ftplugins don't set them.
let s:undo_ftplugin = ""
let s:browsefilter = "All Files (*.*)\t*.*\n"
let s:match_words = ""
runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
unlet! b:did_ftplugin
set matchpairs-=<:>
" Override our defaults if these were set by an included ftplugin.
if exists("b:undo_ftplugin")
let s:undo_ftplugin = b:undo_ftplugin
unlet b:undo_ftplugin
endif
if exists("b:browsefilter")
let s:browsefilter = b:browsefilter
unlet b:browsefilter
endif
if exists("b:match_words")
let s:match_words = b:match_words
unlet b:match_words
endif
runtime! ftplugin/ruby.vim ftplugin/ruby_*.vim ftplugin/ruby/*.vim
let b:did_ftplugin = 1
" Combine the new set of values with those previously included.
if exists("b:undo_ftplugin")
let s:undo_ftplugin = b:undo_ftplugin . " | " . s:undo_ftplugin
endif
if exists ("b:browsefilter")
let s:browsefilter = substitute(b:browsefilter,'\cAll Files (\*\.\*)\t\*\.\*\n','','') . s:browsefilter
endif
if exists("b:match_words")
let s:match_words = b:match_words . ',' . s:match_words
endif
" Change the browse dialog on Win32 to show mainly Haml-related files
if has("gui_win32")
let b:browsefilter="Haml Files (*.haml)\t*.haml\nSass Files (*.sass)\t*.sass\n" . s:browsefilter
endif
" Load the combined list of match_words for matchit.vim
if exists("loaded_matchit")
let b:match_words = s:match_words
endif
setlocal comments= commentstring=-#\ %s
let b:undo_ftplugin = "setl cms< com< "
\ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
let &cpo = s:save_cpo
" vim:set sw=2:

13
ftplugin/haskell.vim Normal file
View File

@@ -0,0 +1,13 @@
"
" general Haskell source settings
" (shared functions are in autoload/haskellmode.vim)
"
" (Claus Reinke, last modified: 28/04/2009)
"
" part of haskell plugins: http://projects.haskell.org/haskellmode-vim
" please send patches to <claus.reinke@talk21.com>
" try gf on import line, or ctrl-x ctrl-i, or [I, [i, ..
setlocal include=^import\\s*\\(qualified\\)\\?\\s*
setlocal includeexpr=substitute(v:fname,'\\.','/','g').'.'
setlocal suffixesadd=hs,lhs,hsc

25
ftplugin/less.vim Normal file
View File

@@ -0,0 +1,25 @@
" Vim filetype plugin
" Language: LessCSS
" Author: Tim Pope <vimNOSPAM@tpope.org>
" Maintainer: Leonard Ehrenfried <leonard.ehrenfried@web.de>
" Last Change: 2011 Sep 30
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
let b:undo_ftplugin = "setl cms< def< inc< inex< ofu< sua<"
setlocal iskeyword+=-
setlocal commentstring=//\ %s
setlocal define=^\\s*\\%(@mixin\\\|=\\)
setlocal includeexpr=substitute(v:fname,'\\%(.*/\\\|^\\)\\zs','_','')
setlocal omnifunc=csscomplete#CompleteCSS
setlocal suffixesadd=.less
setlocal comments=s1:/*,mb:*,ex:*/
let &l:include = '^\s*@import\s\+\%(url(\)\=["'']\='
" vim:set sw=2:

505
ftplugin/ocaml.vim Normal file
View File

@@ -0,0 +1,505 @@
" Language: OCaml
" Maintainer: David Baelde <firstname.name@ens-lyon.org>
" Mike Leary <leary@nwlink.com>
" Markus Mottl <markus.mottl@gmail.com>
" Stefano Zacchiroli <zack@bononia.it>
" URL: http://www.ocaml.info/vim/ftplugin/ocaml.vim
" Last Change: 2009 Nov 10 - Improved .annot support
" (MM for <radugrigore@gmail.com>)
" 2009 Nov 10 - Added support for looking up definitions
" (MM for <ygrek@autistici.org>)
"
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin=1
" Error handling -- helps moving where the compiler wants you to go
let s:cposet=&cpoptions
set cpo-=C
setlocal efm=
\%EFile\ \"%f\"\\,\ line\ %l\\,\ characters\ %c-%*\\d:,
\%EFile\ \"%f\"\\,\ line\ %l\\,\ character\ %c:%m,
\%+EReference\ to\ unbound\ regexp\ name\ %m,
\%Eocamlyacc:\ e\ -\ line\ %l\ of\ \"%f\"\\,\ %m,
\%Wocamlyacc:\ w\ -\ %m,
\%-Zmake%.%#,
\%C%m,
\%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
\%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
\%D%*\\a:\ Entering\ directory\ `%f',
\%X%*\\a:\ Leaving\ directory\ `%f',
\%DMaking\ %*\\a\ in\ %f
" Add mappings, unless the user didn't want this.
if !exists("no_plugin_maps") && !exists("no_ocaml_maps")
" (un)commenting
if !hasmapto('<Plug>Comment')
nmap <buffer> <LocalLeader>c <Plug>LUncomOn
vmap <buffer> <LocalLeader>c <Plug>BUncomOn
nmap <buffer> <LocalLeader>C <Plug>LUncomOff
vmap <buffer> <LocalLeader>C <Plug>BUncomOff
endif
nnoremap <buffer> <Plug>LUncomOn mz0i(* <ESC>$A *)<ESC>`z
nnoremap <buffer> <Plug>LUncomOff :s/^(\* \(.*\) \*)/\1/<CR>:noh<CR>
vnoremap <buffer> <Plug>BUncomOn <ESC>:'<,'><CR>`<O<ESC>0i(*<ESC>`>o<ESC>0i*)<ESC>`<
vnoremap <buffer> <Plug>BUncomOff <ESC>:'<,'><CR>`<dd`>dd`<
if !hasmapto('<Plug>Abbrev')
iabbrev <buffer> ASF (assert false (* XXX *))
iabbrev <buffer> ASS (assert (0=1) (* XXX *))
endif
endif
" Let % jump between structure elements (due to Issac Trotts)
let b:mw = ''
let b:mw = b:mw . ',\<let\>:\<and\>:\(\<in\>\|;;\)'
let b:mw = b:mw . ',\<if\>:\<then\>:\<else\>'
let b:mw = b:mw . ',\<\(for\|while\)\>:\<do\>:\<done\>,'
let b:mw = b:mw . ',\<\(object\|sig\|struct\|begin\)\>:\<end\>'
let b:mw = b:mw . ',\<\(match\|try\)\>:\<with\>'
let b:match_words = b:mw
let b:match_ignorecase=0
" switching between interfaces (.mli) and implementations (.ml)
if !exists("g:did_ocaml_switch")
let g:did_ocaml_switch = 1
map <LocalLeader>s :call OCaml_switch(0)<CR>
map <LocalLeader>S :call OCaml_switch(1)<CR>
fun OCaml_switch(newwin)
if (match(bufname(""), "\\.mli$") >= 0)
let fname = substitute(bufname(""), "\\.mli$", ".ml", "")
if (a:newwin == 1)
exec "new " . fname
else
exec "arge " . fname
endif
elseif (match(bufname(""), "\\.ml$") >= 0)
let fname = bufname("") . "i"
if (a:newwin == 1)
exec "new " . fname
else
exec "arge " . fname
endif
endif
endfun
endif
" Folding support
" Get the modeline because folding depends on indentation
let s:s = line2byte(line('.'))+col('.')-1
if search('^\s*(\*:o\?caml:')
let s:modeline = getline(".")
else
let s:modeline = ""
endif
if s:s > 0
exe 'goto' s:s
endif
" Get the indentation params
let s:m = matchstr(s:modeline,'default\s*=\s*\d\+')
if s:m != ""
let s:idef = matchstr(s:m,'\d\+')
elseif exists("g:omlet_indent")
let s:idef = g:omlet_indent
else
let s:idef = 2
endif
let s:m = matchstr(s:modeline,'struct\s*=\s*\d\+')
if s:m != ""
let s:i = matchstr(s:m,'\d\+')
elseif exists("g:omlet_indent_struct")
let s:i = g:omlet_indent_struct
else
let s:i = s:idef
endif
" Set the folding method
if exists("g:ocaml_folding")
setlocal foldmethod=expr
setlocal foldexpr=OMLetFoldLevel(v:lnum)
endif
" - Only definitions below, executed once -------------------------------------
if exists("*OMLetFoldLevel")
finish
endif
function s:topindent(lnum)
let l = a:lnum
while l > 0
if getline(l) =~ '\s*\%(\<struct\>\|\<sig\>\|\<object\>\)'
return indent(l)
endif
let l = l-1
endwhile
return -s:i
endfunction
function OMLetFoldLevel(l)
" This is for not merging blank lines around folds to them
if getline(a:l) !~ '\S'
return -1
endif
" We start folds for modules, classes, and every toplevel definition
if getline(a:l) =~ '^\s*\%(\<val\>\|\<module\>\|\<class\>\|\<type\>\|\<method\>\|\<initializer\>\|\<inherit\>\|\<exception\>\|\<external\>\)'
exe 'return ">' (indent(a:l)/s:i)+1 '"'
endif
" Toplevel let are detected thanks to the indentation
if getline(a:l) =~ '^\s*let\>' && indent(a:l) == s:i+s:topindent(a:l)
exe 'return ">' (indent(a:l)/s:i)+1 '"'
endif
" We close fold on end which are associated to struct, sig or object.
" We use syntax information to do that.
if getline(a:l) =~ '^\s*end\>' && synIDattr(synID(a:l, indent(a:l)+1, 0), "name") != "ocamlKeyword"
return (indent(a:l)/s:i)+1
endif
" Folds end on ;;
if getline(a:l) =~ '^\s*;;'
exe 'return "<' (indent(a:l)/s:i)+1 '"'
endif
" Comments around folds aren't merged to them.
if synIDattr(synID(a:l, indent(a:l)+1, 0), "name") == "ocamlComment"
return -1
endif
return '='
endfunction
" Vim support for OCaml .annot files (requires Vim with python support)
"
" Executing OCamlPrintType(<mode>) function will display in the Vim bottom
" line(s) the type of an ocaml value getting it from the corresponding .annot
" file (if any). If Vim is in visual mode, <mode> should be "visual" and the
" selected ocaml value correspond to the highlighted text, otherwise (<mode>
" can be anything else) it corresponds to the literal found at the current
" cursor position.
"
" .annot files are parsed lazily the first time OCamlPrintType is invoked; is
" also possible to force the parsing using the OCamlParseAnnot() function.
"
" Typing '<LocalLeader>t' (usually ',t') will cause OCamlPrintType function
" to be invoked with the right argument depending on the current mode (visual
" or not).
"
" Copyright (C) <2003-2004> Stefano Zacchiroli <zack@bononia.it>
"
" Created: Wed, 01 Oct 2003 18:16:22 +0200 zack
" LastModified: Wed, 25 Aug 2004 18:28:39 +0200 zack
" '<LocalLeader>d' will find the definition of the name under the cursor
" and position cursor on it (only for current file) or print fully qualified name
" (for external definitions). (ocaml >= 3.11)
"
" Additionally '<LocalLeader>t' will show whether function call is tail call
" or not. Current implementation requires selecting the whole function call
" expression (in visual mode) to work. (ocaml >= 3.11)
"
" Copyright (C) 2009 <ygrek@autistici.org>
if !has("python")
finish
endif
python << EOF
import re
import os
import os.path
import string
import time
import vim
debug = False
class AnnExc(Exception):
def __init__(self, reason):
self.reason = reason
no_annotations = AnnExc("No annotations (.annot) file found")
annotation_not_found = AnnExc("No type annotation found for the given text")
definition_not_found = AnnExc("No definition found for the given text")
def malformed_annotations(lineno, reason):
return AnnExc("Malformed .annot file (line = %d, reason = %s)" % (lineno,reason))
class Annotations:
"""
.annot ocaml file representation
File format (copied verbatim from caml-types.el)
file ::= block *
block ::= position <SP> position <LF> annotation *
position ::= filename <SP> num <SP> num <SP> num
annotation ::= keyword open-paren <LF> <SP> <SP> data <LF> close-paren
<SP> is a space character (ASCII 0x20)
<LF> is a line-feed character (ASCII 0x0A)
num is a sequence of decimal digits
filename is a string with the lexical conventions of O'Caml
open-paren is an open parenthesis (ASCII 0x28)
close-paren is a closed parenthesis (ASCII 0x29)
data is any sequence of characters where <LF> is always followed by
at least two space characters.
- in each block, the two positions are respectively the start and the
end of the range described by the block.
- in a position, the filename is the name of the file, the first num
is the line number, the second num is the offset of the beginning
of the line, the third num is the offset of the position itself.
- the char number within the line is the difference between the third
and second nums.
Possible keywords are \"type\", \"ident\" and \"call\".
"""
def __init__(self):
self.__filename = None # last .annot parsed file
self.__ml_filename = None # as above but s/.annot/.ml/
self.__timestamp = None # last parse action timestamp
self.__annot = {}
self.__refs = {}
self.__calls = {}
self.__re = re.compile(
'^"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)$')
self.__re_int_ref = re.compile('^int_ref\s+(\w+)\s"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)')
self.__re_def_full = re.compile(
'^def\s+(\w+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)$')
self.__re_def = re.compile('^def\s+(\w+)\s"[^"]*"\s+(\d+)\s+(\d+)\s+(\d+)\s+')
self.__re_ext_ref = re.compile('^ext_ref\s+(\S+)')
self.__re_kw = re.compile('^(\w+)\($')
def __parse(self, fname):
try:
f = open(fname)
self.__annot = {} # erase internal mappings when file is reparsed
self.__refs = {}
self.__calls = {}
line = f.readline() # position line
lineno = 1
while (line != ""):
m = self.__re.search(line)
if (not m):
raise malformed_annotations(lineno,"re doesn't match")
line1 = int(m.group(1))
col1 = int(m.group(3)) - int(m.group(2))
line2 = int(m.group(4))
col2 = int(m.group(6)) - int(m.group(5))
while 1:
line = f.readline() # keyword or position line
lineno += 1
m = self.__re_kw.search(line)
if (not m):
break
desc = []
line = f.readline() # description
lineno += 1
if (line == ""): raise malformed_annotations(lineno,"no content")
while line != ")\n":
desc.append(string.strip(line))
line = f.readline()
lineno += 1
if (line == ""): raise malformed_annotations(lineno,"bad content")
desc = string.join(desc, "\n")
key = ((line1, col1), (line2, col2))
if (m.group(1) == "type"):
if not self.__annot.has_key(key):
self.__annot[key] = desc
if (m.group(1) == "call"): # region, accessible only in visual mode
if not self.__calls.has_key(key):
self.__calls[key] = desc
if (m.group(1) == "ident"):
m = self.__re_int_ref.search(desc)
if m:
line = int(m.group(2))
col = int(m.group(4)) - int(m.group(3))
name = m.group(1)
else:
line = -1
col = -1
m = self.__re_ext_ref.search(desc)
if m:
name = m.group(1)
else:
line = -2
col = -2
name = desc
if not self.__refs.has_key(key):
self.__refs[key] = (line,col,name)
f.close()
self.__filename = fname
self.__ml_filename = vim.current.buffer.name
self.__timestamp = int(time.time())
except IOError:
raise no_annotations
def parse(self):
annot_file = os.path.splitext(vim.current.buffer.name)[0] + ".annot"
previous_head, head, tail = '***', annot_file, ''
while not os.path.isfile(annot_file) and head != previous_head:
previous_head = head
head, x = os.path.split(head)
if tail == '':
tail = x
else:
os.path.join(x, tail)
annot_file = os.path.join(head, '_build', tail)
self.__parse(annot_file)
def check_file(self):
if vim.current.buffer.name == None:
raise no_annotations
if vim.current.buffer.name != self.__ml_filename or \
os.stat(self.__filename).st_mtime > self.__timestamp:
self.parse()
def get_type(self, (line1, col1), (line2, col2)):
if debug:
print line1, col1, line2, col2
self.check_file()
try:
try:
extra = self.__calls[(line1, col1), (line2, col2)]
if extra == "tail":
extra = " (* tail call *)"
else:
extra = " (* function call *)"
except KeyError:
extra = ""
return self.__annot[(line1, col1), (line2, col2)] + extra
except KeyError:
raise annotation_not_found
def get_ident(self, (line1, col1), (line2, col2)):
if debug:
print line1, col1, line2, col2
self.check_file()
try:
(line,col,name) = self.__refs[(line1, col1), (line2, col2)]
if line >= 0 and col >= 0:
vim.command("normal "+str(line)+"gg"+str(col+1)+"|")
#current.window.cursor = (line,col)
if line == -2:
m = self.__re_def_full.search(name)
if m:
l2 = int(m.group(5))
c2 = int(m.group(7)) - int(m.group(6))
name = m.group(1)
else:
m = self.__re_def.search(name)
if m:
l2 = int(m.group(2))
c2 = int(m.group(4)) - int(m.group(3))
name = m.group(1)
else:
l2 = -1
if False and l2 >= 0:
# select region
if c2 == 0 and l2 > 0:
vim.command("normal v"+str(l2-1)+"gg"+"$")
else:
vim.command("normal v"+str(l2)+"gg"+str(c2)+"|")
return name
except KeyError:
raise definition_not_found
word_char_RE = re.compile("^[\w.]$")
# TODO this function should recognize ocaml literals, actually it's just an
# hack that recognize continuous sequences of word_char_RE above
def findBoundaries(line, col):
""" given a cursor position (as returned by vim.current.window.cursor)
return two integers identify the beggining and end column of the word at
cursor position, if any. If no word is at the cursor position return the
column cursor position twice """
left, right = col, col
line = line - 1 # mismatch vim/python line indexes
(begin_col, end_col) = (0, len(vim.current.buffer[line]) - 1)
try:
while word_char_RE.search(vim.current.buffer[line][left - 1]):
left = left - 1
except IndexError:
pass
try:
while word_char_RE.search(vim.current.buffer[line][right + 1]):
right = right + 1
except IndexError:
pass
return (left, right)
annot = Annotations() # global annotation object
def get_marks(mode):
if mode == "visual": # visual mode: lookup highlighted text
(line1, col1) = vim.current.buffer.mark("<")
(line2, col2) = vim.current.buffer.mark(">")
else: # any other mode: lookup word at cursor position
(line, col) = vim.current.window.cursor
(col1, col2) = findBoundaries(line, col)
(line1, line2) = (line, line)
begin_mark = (line1, col1)
end_mark = (line2, col2 + 1)
return (begin_mark,end_mark)
def printOCamlType(mode):
try:
(begin_mark,end_mark) = get_marks(mode)
print annot.get_type(begin_mark, end_mark)
except AnnExc, exc:
print exc.reason
def gotoOCamlDefinition(mode):
try:
(begin_mark,end_mark) = get_marks(mode)
print annot.get_ident(begin_mark, end_mark)
except AnnExc, exc:
print exc.reason
def parseOCamlAnnot():
try:
annot.parse()
except AnnExc, exc:
print exc.reason
EOF
fun! OCamlPrintType(current_mode)
if (a:current_mode == "visual")
python printOCamlType("visual")
else
python printOCamlType("normal")
endif
endfun
fun! OCamlGotoDefinition(current_mode)
if (a:current_mode == "visual")
python gotoOCamlDefinition("visual")
else
python gotoOCamlDefinition("normal")
endif
endfun
fun! OCamlParseAnnot()
python parseOCamlAnnot()
endfun
map <LocalLeader>t :call OCamlPrintType("normal")<RETURN>
vmap <LocalLeader>t :call OCamlPrintType("visual")<RETURN>
map <LocalLeader>d :call OCamlGotoDefinition("normal")<RETURN>
vmap <LocalLeader>d :call OCamlGotoDefinition("visual")<RETURN>
let &cpoptions=s:cposet
unlet s:cposet
" vim:sw=2

395
ftplugin/ruby.vim Normal file
View File

@@ -0,0 +1,395 @@
" Vim filetype plugin
" Language: Ruby
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" URL: https://github.com/vim-ruby/vim-ruby
" Release Coordinator: Doug Kearns <dougkearns@gmail.com>
" ----------------------------------------------------------------------------
if (exists("b:did_ftplugin"))
finish
endif
let b:did_ftplugin = 1
let s:cpo_save = &cpo
set cpo&vim
if has("gui_running") && !has("gui_win32")
setlocal keywordprg=ri\ -T\ -f\ bs
else
setlocal keywordprg=ri
endif
" Matchit support
if exists("loaded_matchit") && !exists("b:match_words")
let b:match_ignorecase = 0
let b:match_words =
\ '\<\%(if\|unless\|case\|while\|until\|for\|do\|class\|module\|def\|begin\)\>=\@!' .
\ ':' .
\ '\<\%(else\|elsif\|ensure\|when\|rescue\|break\|redo\|next\|retry\)\>' .
\ ':' .
\ '\<end\>' .
\ ',{:},\[:\],(:)'
let b:match_skip =
\ "synIDattr(synID(line('.'),col('.'),0),'name') =~ '" .
\ "\\<ruby\\%(String\\|StringDelimiter\\|ASCIICode\\|Escape\\|" .
\ "Interpolation\\|NoInterpolation\\|Comment\\|Documentation\\|" .
\ "ConditionalModifier\\|RepeatModifier\\|OptionalDo\\|" .
\ "Function\\|BlockArgument\\|KeywordAsMethod\\|ClassVariable\\|" .
\ "InstanceVariable\\|GlobalVariable\\|Symbol\\)\\>'"
endif
setlocal formatoptions-=t formatoptions+=croql
setlocal include=^\\s*\\<\\(load\\>\\\|require\\>\\\|autoload\\s*:\\=[\"']\\=\\h\\w*[\"']\\=,\\)
setlocal includeexpr=substitute(substitute(v:fname,'::','/','g'),'$','.rb','')
setlocal suffixesadd=.rb
if exists("&ofu") && has("ruby")
setlocal omnifunc=rubycomplete#Complete
endif
" To activate, :set ballooneval
if has('balloon_eval') && exists('+balloonexpr')
setlocal balloonexpr=RubyBalloonexpr()
endif
" TODO:
"setlocal define=^\\s*def
setlocal comments=:#
setlocal commentstring=#\ %s
if !exists('g:ruby_version_paths')
let g:ruby_version_paths = {}
endif
function! s:query_path(root)
let code = "print $:.join %q{,}"
if &shell =~# 'sh' && $PATH !~# '\s'
let prefix = 'env PATH='.$PATH.' '
else
let prefix = ''
endif
if &shellxquote == "'"
let path_check = prefix.'ruby -e "' . code . '"'
else
let path_check = prefix."ruby -e '" . code . "'"
endif
let cd = haslocaldir() ? 'lcd' : 'cd'
let cwd = getcwd()
try
exe cd fnameescape(a:root)
let path = split(system(path_check),',')
exe cd fnameescape(cwd)
return path
finally
exe cd fnameescape(cwd)
endtry
endfunction
function! s:build_path(path)
let path = join(map(copy(a:path), 'v:val ==# "." ? "" : v:val'), ',')
if &g:path !~# '\v^\.%(,/%(usr|emx)/include)=,,$'
let path = substitute(&g:path,',,$',',','') . ',' . path
endif
return path
endfunction
if !exists('b:ruby_version') && !exists('g:ruby_path') && isdirectory(expand('%:p:h'))
let s:version_file = findfile('.ruby-version', '.;')
if !empty(s:version_file)
let b:ruby_version = get(readfile(s:version_file, '', 1), '')
if !has_key(g:ruby_version_paths, b:ruby_version)
let g:ruby_version_paths[b:ruby_version] = s:query_path(fnamemodify(s:version_file, ':p:h'))
endif
endif
endif
if exists("g:ruby_path")
let s:ruby_path = type(g:ruby_path) == type([]) ? join(g:ruby_path, ',') : g:ruby_path
elseif has_key(g:ruby_version_paths, get(b:, 'ruby_version', ''))
let s:ruby_paths = g:ruby_version_paths[b:ruby_version]
let s:ruby_path = s:build_path(s:ruby_paths)
else
if !exists('g:ruby_default_path')
if has("ruby") && has("win32")
ruby ::VIM::command( 'let g:ruby_default_path = split("%s",",")' % $:.join(%q{,}) )
elseif executable('ruby')
let g:ruby_default_path = s:query_path($HOME)
else
let g:ruby_default_path = map(split($RUBYLIB,':'), 'v:val ==# "." ? "" : v:val')
endif
endif
let s:ruby_paths = g:ruby_default_path
let s:ruby_path = s:build_path(s:ruby_paths)
endif
if stridx(&l:path, s:ruby_path) == -1
let &l:path = s:ruby_path
endif
if exists('s:ruby_paths') && stridx(&l:tags, join(map(copy(s:ruby_paths),'v:val."/tags"'),',')) == -1
let &l:tags = &tags . ',' . join(map(copy(s:ruby_paths),'v:val."/tags"'),',')
endif
if has("gui_win32") && !exists("b:browsefilter")
let b:browsefilter = "Ruby Source Files (*.rb)\t*.rb\n" .
\ "All Files (*.*)\t*.*\n"
endif
let b:undo_ftplugin = "setl fo< inc< inex< sua< def< com< cms< path< tags< kp<"
\."| unlet! b:browsefilter b:match_ignorecase b:match_words b:match_skip"
\."| if exists('&ofu') && has('ruby') | setl ofu< | endif"
\."| if has('balloon_eval') && exists('+bexpr') | setl bexpr< | endif"
if !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps")
nnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','n')<CR>
nnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','n')<CR>
nnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','n')<CR>
nnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','n')<CR>
xnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','v')<CR>
xnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','v')<CR>
xnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','v')<CR>
xnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','v')<CR>
nnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','n')<CR>
nnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','n')<CR>
nnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','n')<CR>
nnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','n')<CR>
xnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','v')<CR>
xnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','v')<CR>
xnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','v')<CR>
xnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','v')<CR>
let b:undo_ftplugin = b:undo_ftplugin
\."| sil! exe 'unmap <buffer> [[' | sil! exe 'unmap <buffer> ]]' | sil! exe 'unmap <buffer> []' | sil! exe 'unmap <buffer> ]['"
\."| sil! exe 'unmap <buffer> [m' | sil! exe 'unmap <buffer> ]m' | sil! exe 'unmap <buffer> [M' | sil! exe 'unmap <buffer> ]M'"
if maparg('im','n') == ''
onoremap <silent> <buffer> im :<C-U>call <SID>wrap_i('[m',']M')<CR>
onoremap <silent> <buffer> am :<C-U>call <SID>wrap_a('[m',']M')<CR>
xnoremap <silent> <buffer> im :<C-U>call <SID>wrap_i('[m',']M')<CR>
xnoremap <silent> <buffer> am :<C-U>call <SID>wrap_a('[m',']M')<CR>
let b:undo_ftplugin = b:undo_ftplugin
\."| sil! exe 'ounmap <buffer> im' | sil! exe 'ounmap <buffer> am'"
\."| sil! exe 'xunmap <buffer> im' | sil! exe 'xunmap <buffer> am'"
endif
if maparg('iM','n') == ''
onoremap <silent> <buffer> iM :<C-U>call <SID>wrap_i('[[','][')<CR>
onoremap <silent> <buffer> aM :<C-U>call <SID>wrap_a('[[','][')<CR>
xnoremap <silent> <buffer> iM :<C-U>call <SID>wrap_i('[[','][')<CR>
xnoremap <silent> <buffer> aM :<C-U>call <SID>wrap_a('[[','][')<CR>
let b:undo_ftplugin = b:undo_ftplugin
\."| sil! exe 'ounmap <buffer> iM' | sil! exe 'ounmap <buffer> aM'"
\."| sil! exe 'xunmap <buffer> iM' | sil! exe 'xunmap <buffer> aM'"
endif
if maparg("\<C-]>",'n') == ''
nnoremap <silent> <buffer> <C-]> :<C-U>exe v:count1."tag <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> g<C-]> :<C-U>exe "tjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> g] :<C-U>exe "tselect <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> <C-W>] :<C-U>exe v:count1."stag <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> <C-W><C-]> :<C-U>exe v:count1."stag <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> <C-W>g<C-]> :<C-U>exe "stjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> <C-W>g] :<C-U>exe "stselect <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> <C-W>} :<C-U>exe "ptag <C-R>=RubyCursorIdentifier()<CR>"<CR>
nnoremap <silent> <buffer> <C-W>g} :<C-U>exe "ptjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
let b:undo_ftplugin = b:undo_ftplugin
\."| sil! exe 'nunmap <buffer> <C-]>'| sil! exe 'nunmap <buffer> g<C-]>'| sil! exe 'nunmap <buffer> g]'"
\."| sil! exe 'nunmap <buffer> <C-W>]'| sil! exe 'nunmap <buffer> <C-W><C-]>'"
\."| sil! exe 'nunmap <buffer> <C-W>g<C-]>'| sil! exe 'nunmap <buffer> <C-W>g]'"
\."| sil! exe 'nunmap <buffer> <C-W>}'| sil! exe 'nunmap <buffer> <C-W>g}'"
endif
if maparg("gf",'n') == ''
" By using findfile() rather than gf's normal behavior, we prevent
" erroneously editing a directory.
nnoremap <silent> <buffer> gf :<C-U>exe <SID>gf(v:count1,"gf",'edit')<CR>
nnoremap <silent> <buffer> <C-W>f :<C-U>exe <SID>gf(v:count1,"\<Lt>C-W>f",'split')<CR>
nnoremap <silent> <buffer> <C-W><C-F> :<C-U>exe <SID>gf(v:count1,"\<Lt>C-W>\<Lt>C-F>",'split')<CR>
nnoremap <silent> <buffer> <C-W>gf :<C-U>exe <SID>gf(v:count1,"\<Lt>C-W>gf",'tabedit')<CR>
let b:undo_ftplugin = b:undo_ftplugin
\."| sil! exe 'nunmap <buffer> gf' | sil! exe 'nunmap <buffer> <C-W>f' | sil! exe 'nunmap <buffer> <C-W><C-F>' | sil! exe 'nunmap <buffer> <C-W>gf'"
endif
endif
let &cpo = s:cpo_save
unlet s:cpo_save
if exists("g:did_ruby_ftplugin_functions")
finish
endif
let g:did_ruby_ftplugin_functions = 1
function! RubyBalloonexpr()
if !exists('s:ri_found')
let s:ri_found = executable('ri')
endif
if s:ri_found
let line = getline(v:beval_lnum)
let b = matchstr(strpart(line,0,v:beval_col),'\%(\w\|[:.]\)*$')
let a = substitute(matchstr(strpart(line,v:beval_col),'^\w*\%([?!]\|\s*=\)\?'),'\s\+','','g')
let str = b.a
let before = strpart(line,0,v:beval_col-strlen(b))
let after = strpart(line,v:beval_col+strlen(a))
if str =~ '^\.'
let str = substitute(str,'^\.','#','g')
if before =~ '\]\s*$'
let str = 'Array'.str
elseif before =~ '}\s*$'
" False positives from blocks here
let str = 'Hash'.str
elseif before =~ "[\"'`]\\s*$" || before =~ '\$\d\+\s*$'
let str = 'String'.str
elseif before =~ '\$\d\+\.\d\+\s*$'
let str = 'Float'.str
elseif before =~ '\$\d\+\s*$'
let str = 'Integer'.str
elseif before =~ '/\s*$'
let str = 'Regexp'.str
else
let str = substitute(str,'^#','.','')
endif
endif
let str = substitute(str,'.*\.\s*to_f\s*\.\s*','Float#','')
let str = substitute(str,'.*\.\s*to_i\%(nt\)\=\s*\.\s*','Integer#','')
let str = substitute(str,'.*\.\s*to_s\%(tr\)\=\s*\.\s*','String#','')
let str = substitute(str,'.*\.\s*to_sym\s*\.\s*','Symbol#','')
let str = substitute(str,'.*\.\s*to_a\%(ry\)\=\s*\.\s*','Array#','')
let str = substitute(str,'.*\.\s*to_proc\s*\.\s*','Proc#','')
if str !~ '^\w'
return ''
endif
silent! let res = substitute(system("ri -f rdoc -T \"".str.'"'),'\n$','','')
if res =~ '^Nothing known about' || res =~ '^Bad argument:' || res =~ '^More than one method'
return ''
endif
return res
else
return ""
endif
endfunction
function! s:searchsyn(pattern,syn,flags,mode)
norm! m'
if a:mode ==# 'v'
norm! gv
endif
let i = 0
let cnt = v:count ? v:count : 1
while i < cnt
let i = i + 1
let line = line('.')
let col = col('.')
let pos = search(a:pattern,'W'.a:flags)
while pos != 0 && s:synname() !~# a:syn
let pos = search(a:pattern,'W'.a:flags)
endwhile
if pos == 0
call cursor(line,col)
return
endif
endwhile
endfunction
function! s:synname()
return synIDattr(synID(line('.'),col('.'),0),'name')
endfunction
function! s:wrap_i(back,forward)
execute 'norm k'.a:forward
let line = line('.')
execute 'norm '.a:back
if line('.') == line - 1
return s:wrap_a(a:back,a:forward)
endif
execute 'norm jV'.a:forward.'k'
endfunction
function! s:wrap_a(back,forward)
execute 'norm '.a:forward
if line('.') < line('$') && getline(line('.')+1) ==# ''
let after = 1
endif
execute 'norm '.a:back
while getline(line('.')-1) =~# '^\s*#' && line('.')
-
endwhile
if exists('after')
execute 'norm V'.a:forward.'j'
elseif line('.') > 1 && getline(line('.')-1) =~# '^\s*$'
execute 'norm kV'.a:forward
else
execute 'norm V'.a:forward
endif
endfunction
function! RubyCursorIdentifier()
let asciicode = '\%(\w\|[]})\"'."'".']\)\@<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)\)'
let number = '\%(\%(\w\|[]})\"'."'".']\s*\)\@<!-\)\=\%(\<[[:digit:]_]\+\%(\.[[:digit:]_]\+\)\=\%([Ee][[:digit:]_]\+\)\=\>\|\<0[xXbBoOdD][[:xdigit:]_]\+\>\)\|'.asciicode
let operator = '\%(\[\]\|<<\|<=>\|[!<>]=\=\|===\=\|[!=]\~\|>>\|\*\*\|\.\.\.\=\|=>\|[~^&|*/%+-]\)'
let method = '\%(\<[_a-zA-Z]\w*\>\%([?!]\|\s*=>\@!\)\=\)'
let global = '$\%([!$&"'."'".'*+,./:;<=>?@\`~]\|-\=\w\+\>\)'
let symbolizable = '\%(\%(@@\=\)\w\+\>\|'.global.'\|'.method.'\|'.operator.'\)'
let pattern = '\C\s*\%('.number.'\|\%(:\@<!:\)\='.symbolizable.'\)'
let [lnum, col] = searchpos(pattern,'bcn',line('.'))
let raw = matchstr(getline('.')[col-1 : ],pattern)
let stripped = substitute(substitute(raw,'\s\+=$','=',''),'^\s*:\=','','')
return stripped == '' ? expand("<cword>") : stripped
endfunction
function! s:gf(count,map,edit) abort
if getline('.') =~# '^\s*require_relative\s*\(["'']\).*\1\s*$'
let target = matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1')
return a:edit.' %:h/'.target.'.rb'
elseif getline('.') =~# '^\s*\%(require[( ]\|load[( ]\|autoload[( ]:\w\+,\)\s*\s*\%(::\)\=File\.expand_path(\(["'']\)\.\./.*\1,\s*__FILE__)\s*$'
let target = matchstr(getline('.'),'\(["'']\)\.\./\zs.\{-\}\ze\1')
return a:edit.' %:h/'.target.'.rb'
elseif getline('.') =~# '^\s*\%(require \|load \|autoload :\w\+,\)\s*\(["'']\).*\1\s*$'
let target = matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1')
else
let target = expand('<cfile>')
endif
let found = findfile(target, &path, a:count)
if found ==# ''
return 'norm! '.a:count.a:map
else
return a:edit.' '.fnameescape(found)
endif
endfunction
"
" Instructions for enabling "matchit" support:
"
" 1. Look for the latest "matchit" plugin at
"
" http://www.vim.org/scripts/script.php?script_id=39
"
" It is also packaged with Vim, in the $VIMRUNTIME/macros directory.
"
" 2. Copy "matchit.txt" into a "doc" directory (e.g. $HOME/.vim/doc).
"
" 3. Copy "matchit.vim" into a "plugin" directory (e.g. $HOME/.vim/plugin).
"
" 4. Ensure this file (ftplugin/ruby.vim) is installed.
"
" 5. Ensure you have this line in your $HOME/.vimrc:
" filetype plugin on
"
" 6. Restart Vim and create the matchit documentation:
"
" :helptags ~/.vim/doc
"
" Now you can do ":help matchit", and you should be able to use "%" on Ruby
" keywords. Try ":echo b:match_words" to be sure.
"
" Thanks to Mark J. Reed for the instructions. See ":help vimrc" for the
" locations of plugin directories, etc., as there are several options, and it
" differs on Windows. Email gsinclair@soyabean.com.au if you need help.
"
" vim: nowrap sw=2 sts=2 ts=8:

22
ftplugin/sass.vim Normal file
View File

@@ -0,0 +1,22 @@
" Vim filetype plugin
" Language: Sass
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2010 Jul 26
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
let b:undo_ftplugin = "setl cms< def< inc< inex< ofu< sua<"
setlocal commentstring=//\ %s
setlocal define=^\\s*\\%(@mixin\\\|=\\)
setlocal includeexpr=substitute(v:fname,'\\%(.*/\\\|^\\)\\zs','_','')
setlocal omnifunc=csscomplete#CompleteCSS
setlocal suffixesadd=.sass,.scss,.css
let &l:include = '^\s*@import\s\+\%(url(\)\=["'']\='
" vim:set sw=2:

12
ftplugin/scss.vim Normal file
View File

@@ -0,0 +1,12 @@
" Vim filetype plugin
" Language: SCSS
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2010 Jul 26
if exists("b:did_ftplugin")
finish
endif
runtime! ftplugin/sass.vim
" vim:set sw=2:

61
ftplugin/stylus.vim Normal file
View File

@@ -0,0 +1,61 @@
" Vim filetype plugin
" Language: Stylus
" Maintainer: Marc Harter
" Credits: Tim Pope
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let s:save_cpo = &cpo
set cpo-=C
" Define some defaults in case the included ftplugins don't set them.
let s:undo_ftplugin = ""
let s:browsefilter = "All Files (*.*)\t*.*\n"
let s:match_words = ""
runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
unlet! b:did_ftplugin
" Override our defaults if these were set by an included ftplugin.
if exists("b:undo_ftplugin")
let s:undo_ftplugin = b:undo_ftplugin
unlet b:undo_ftplugin
endif
if exists("b:browsefilter")
let s:browsefilter = b:browsefilter
unlet b:browsefilter
endif
if exists("b:match_words")
let s:match_words = b:match_words
unlet b:match_words
endif
" Change the browse dialog on Win32 to show mainly Styl-related files
if has("gui_win32")
let b:browsefilter="Stylus Files (*.styl)\t*.styl\n" . s:browsefilter
endif
" Load the combined list of match_words for matchit.vim
if exists("loaded_matchit")
let b:match_words = s:match_words
endif
setlocal comments= commentstring=//\ %s
" Add '-' and '#' to the what makes up a keyword.
" This means that 'e' and 'w' work properly now, for properties
" and valid variable names.
setl iskeyword+=#,-
let b:undo_ftplugin = "setl cms< com< "
\ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
let &cpo = s:save_cpo
" Add a Stylus command (to see if it's valid)
command! Stylus !clear; cat % | stylus
" vim:set sw=2:

59
ftplugin/textile.vim Normal file
View File

@@ -0,0 +1,59 @@
" textile.vim
"
" Tim Harper (tim.theenchanter.com)
command! -nargs=0 TextileRenderFile call TextileRenderBufferToFile()
command! -nargs=0 TextileRenderTab call TextileRenderBufferToTab()
command! -nargs=0 TextilePreview call TextileRenderBufferToPreview()
noremap <buffer> <Leader>rp :TextilePreview<CR>
noremap <buffer> <Leader>rf :TextileRenderFile<CR>
noremap <buffer> <Leader>rt :TextileRenderTab<CR>
setlocal ignorecase
setlocal wrap
setlocal lbr
function! TextileRender(lines)
if (system('which ruby') == "")
throw "Could not find ruby!"
end
let text = join(a:lines, "\n")
let html = system("ruby -e \"def e(msg); puts msg; exit 1; end; begin; require 'rubygems'; rescue LoadError; e('rubygems not found'); end; begin; require 'redcloth'; rescue LoadError; e('RedCloth gem not installed. Run this from the terminal: sudo gem install RedCloth'); end; puts(RedCloth.new(\\$stdin.read).to_html(:textile))\"", text)
return html
endfunction
function! TextileRenderFile(lines, filename)
let html = TextileRender(getbufline(bufname("%"), 1, '$'))
let html = "<html><head><title>" . bufname("%") . "</title></head><body>\n" . html . "\n</body></html>"
return writefile(split(html, "\n"), a:filename)
endfunction
function! TextileRenderBufferToPreview()
let filename = "/tmp/textile-preview.html"
call TextileRenderFile(getbufline(bufname("%"), 1, '$'), filename)
" Verify if browser was set
if !exists("g:TextileBrowser")
let g:TextileBrowser='Safari'
endif
" call configured browser according OS
if !exists("g:TextileOS") || g:TextileOS == 'mac'
call system("open -a \"".g:TextileBrowser."\" ".filename)
else
echo g:TextileBrowser." ".filename
call system(g:TextileBrowser." ".filename)
endif
endfunction
function! TextileRenderBufferToFile()
let filename = input("Filename:", substitute(bufname("%"), "textile$", "html", ""), "file")
call TextileRenderFile(getbufline(bufname("%"), 1, '$'), filename)
echo "Rendered to '" . filename . "'"
endfunction
function! TextileRenderBufferToTab()
let html = TextileRender(getbufline(bufname("%"), 1, '$'))
tabnew
call append("^", split(html, "\n"))
set syntax=html
endfunction