1
0
Fork 0
mirror of synced 2024-11-23 17:25:35 -05:00
ultimate-vim/sources_non_forked/vim-racer/plugin/racer.vim
2016-05-06 04:09:18 -07:00

196 lines
6.5 KiB
VimL

" Vim plugin for Racer
" (by Phil Dawes)
"
" 1. Edit the variables below (or override in .vimrc)
" 2. copy this file into .vim/plugin/
" 3. - now in insert mode do 'C-x C-o' to autocomplete the thing at the cursor
" - in normal mode do 'gd' to go to definition
" - 'gD' goes to the definition in a new vertical split
"
" (This plugin is best used with the 'hidden' option enabled so that switching buffers doesn't force you to save)
if exists('g:loaded_racer')
finish
endif
let g:loaded_racer = 1
let s:save_cpo = &cpo
set cpo&vim
if !exists('g:racer_cmd')
let path = escape(expand('<sfile>:p:h'), '\') . '/../target/release/'
if isdirectory(path)
let s:pathsep = has("win32") ? ';' : ':'
let $PATH .= s:pathsep . path
endif
let g:racer_cmd = 'racer'
if !(executable(g:racer_cmd))
echohl WarningMsg | echomsg "No racer executable found in $PATH (" . $PATH . ")"
endif
endif
if !exists('$RUST_SRC_PATH')
let s:rust_src_default = 1
if isdirectory("/usr/local/src/rust/src")
let $RUST_SRC_PATH="/usr/local/src/rust/src"
endif
if isdirectory("/usr/src/rust/src")
let $RUST_SRC_PATH="/usr/src/rust/src"
endif
if isdirectory("C:\\rust\\src")
let $RUST_SRC_PATH="C:\\rust\\src"
endif
endif
if !isdirectory($RUST_SRC_PATH)
if exists('s:rust_src_default')
echohl WarningMsg | echomsg "No RUST_SRC_PATH environment variable present, nor could default installation be found at: " . $RUST_SRC_PATH
else
echohl WarningMsg | echomsg "No directory was found at provided RUST_SRC_PATH: " . $RUST_SRC_PATH
endif
endif
if !exists('g:racer_experimental_completer')
let g:racer_experimental_completer = 0
endif
if !exists('g:racer_insert_paren')
let g:racer_insert_paren = 1
endif
function! RacerGetPrefixCol(base)
let col = col(".")-1
let b:racer_col = col
let b:tmpfname = tempname()
call writefile(RacerGetBufferContents(a:base), b:tmpfname)
let cmd = g:racer_cmd." prefix ".line(".")." ".col." ".b:tmpfname
let res = system(cmd)
let prefixline = split(res, "\\n")[0]
let startcol = split(prefixline[7:], ",")[0]
return startcol
endfunction
function! RacerGetExpCompletions(base)
let col = strlen(getline('.')) + strlen(a:base) " use the column from the previous RacerGetPrefixCol() call, since vim ammends it afterwards
call writefile(RacerGetBufferContents(a:base), b:tmpfname)
let fname = expand("%:p")
let cmd = g:racer_cmd." complete ".line(".")." ".col." ".fname." ".b:tmpfname
let res = system(cmd)
let typeMap = {
\ 'Struct' : 's', 'Module' : 'M', 'Function' : 'f',
\ 'Crate' : 'C', 'Let' : 'v', 'StructField' : 'm',
\ 'Impl' : 'i', 'Enum' : 'e', 'EnumVariant' : 'E',
\ 'Type' : 't', 'FnArg' : 'v', 'Trait' : 'T'
\ }
let lines = split(res, "\\n")
let out = []
for line in lines
if line =~ "^MATCH"
let completions = split(line[6:], ",")
let kind = get(typeMap, completions[4])
let completion = {'kind' : kind, 'word' : completions[0], 'dup':1 }
if kind ==# 'f' " function
let completion['menu'] = substitute(substitute(substitute(join(completions[5:], ','), '\(pub\|fn\) ',"","g"), '{*$', "", ""), ' where\s\?.*$', "", "")
if g:racer_insert_paren == 1
let completion['abbr'] = completions[0]
let completion['word'] .= "("
endif
let completion['info'] = join(completions[5:], ',')
elseif kind ==# 's' " struct
let completion['menu'] = substitute(substitute(join(completions[5:], ','), '\(pub\|struct\) ',"","g"), '{*$', "", "")
endif
let out = add(out, completion)
endif
endfor
call delete(b:tmpfname)
return out
endfunction
function! RacerGetCompletions(base)
let col = strlen(getline('.')) + strlen(a:base) " use the column from the previous RacerGetPrefixCol() call, since vim ammends it afterwards
call writefile(RacerGetBufferContents(a:base), b:tmpfname)
let fname = expand("%:p")
let cmd = g:racer_cmd." complete ".line(".")." ".col." ".fname." ".b:tmpfname
let res = system(cmd)
let lines = split(res, "\\n")
let out = []
for line in lines
if line =~ "^MATCH"
let completion = split(line[6:], ",")[0]
let out = add(out, completion)
endif
endfor
call delete(b:tmpfname)
return out
endfunction
function! RacerGoToDefinition()
let col = col(".")-1
let b:racer_col = col
let fname = expand("%:p")
let tmpfname = tempname()
call writefile(getline(1, '$'), tmpfname)
let cmd = g:racer_cmd." find-definition ".line(".")." ".col." ".fname." ".tmpfname
let res = system(cmd)
let lines = split(res, "\\n")
for line in lines
if line =~ "^MATCH"
let linenum = split(line[6:], ",")[1]
let colnum = split(line[6:], ",")[2]
let fname = split(line[6:], ",")[3]
call RacerJumpToLocation(fname, linenum, colnum)
break
endif
endfor
call delete(tmpfname)
endfunction
function! RacerGetBufferContents(base)
" Re-combine the completion base word from omnicomplete with the current
" line contents. Since the base word gets remove from the buffer before
" this function is invoked we have to put it back in to out tmpfile.
let col = col(".")-1
let buf_lines = getline(1, '$')
let line_contents = getline('.')
let buf_lines[line('.') - 1] = strpart(line_contents, 0, col).a:base.strpart(line_contents, col, len(line_contents))
return buf_lines
endfunction
function! RacerJumpToLocation(filename, linenum, colnum)
if(a:filename != '')
" Record jump mark
normal! m`
if a:filename != bufname('%')
exec 'keepjumps e ' . fnameescape(a:filename)
endif
call cursor(a:linenum, a:colnum+1)
" Center definition on screen
normal! zz
endif
endfunction
function! RacerComplete(findstart, base)
if a:findstart
return RacerGetPrefixCol(a:base)
else
if g:racer_experimental_completer == 1
return RacerGetExpCompletions(a:base)
else
return RacerGetCompletions(a:base)
endif
endif
endfunction
autocmd FileType rust setlocal omnifunc=RacerComplete
autocmd FileType rust nnoremap <buffer>gd :call RacerGoToDefinition()<cr>
autocmd FileType rust nnoremap <buffer>gD :vsplit<cr>:call RacerGoToDefinition()<cr>
let &cpo = s:save_cpo
unlet s:save_cpo