dotfiles/.vim/bundle/vim-racer/autoload/racer.vim
Dongsu Park 0722320162 add dotfiles to be placed under home directories
dotfiles like .bash*, .git*, .vim*, etc.
2017-04-21 12:58:17 +02:00

265 lines
8.1 KiB
VimL

function! s:RacerGetPrefixCol(base)
let col = col('.') - 1
let b:racer_col = col
let b:tmpfname = tempname()
call writefile(s: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 startbyte = split(prefixline[7:], ',')[0]
return startbyte - line2byte(byte2line(startbyte)) + 1
endfunction
function! s:RacerGetExpCompletions(base)
let col = col('.')-1
let b:tmpfname = tempname()
call writefile(s: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'
continue
endif
let completions = split(line[6:], ',')
let kind = get(typeMap, completions[4])
let completion = { 'kind' : kind, 'word' : completions[0], 'dup' : 1 }
let info = join(completions[5:], ',')
if kind ==# 'f'
" function
let completion['menu'] = substitute(
\ substitute(
\ substitute(info, '\(pub\|fn\) ', '', 'g'),
\ '{*$', '', ''
\ ),
\ ' where\s\?.*$', '', ''
\ )
if g:racer_insert_paren == 1
let completion['abbr'] = completions[0]
let completion['word'] .= '('
endif
let completion['info'] = info
elseif kind ==# 's' " struct
let completion['menu'] = substitute(
\ substitute(info, '\(pub\|struct\) ', '', 'g'),
\ '{*$', '', ''
\ )
endif
if stridx(tolower(completions[0]), tolower(a:base)) == 0
let out = add(out, completion)
endif
endfor
call delete(b:tmpfname)
return out
endfunction
function! s:RacerSplitLine(line)
let separator = ';'
let placeholder = '{PLACEHOLDER}'
let line = substitute(a:line, '\\;', placeholder, 'g')
let parts = split(line, separator)
let docs = substitute(
\ substitute(
\ substitute(
\ substitute(get(parts, 7, ''), '^\"\(.*\)\"$', '\1', ''),
\ '\\\"', '\"', 'g'
\ ),
\ '\\''', '''', 'g'
\ ),
\ '\\n', '\n', 'g'
\ )
let parts = add(parts[:6], docs)
let parts = map(copy(parts), 'substitute(v:val, ''{PLACEHOLDER}'', '';'', ''g'')')
return parts
endfunction
function! racer#ShowDocumentation()
let winview = winsaveview() " Save the current cursor position
" Move to the end of the word for the entire token to search.
" Move one char back to avoid moving to the end of the *next* word.
execute 'normal he'
let col = col('.')
let b:tmpfname = tempname()
" Create temporary file with the buffer's current state
call writefile(getline(1, '$'), b:tmpfname)
let fname = expand('%:p')
let cmd = g:racer_cmd . ' complete-with-snippet ' . line('.') . ' ' . col . ' ' . fname . ' ' . b:tmpfname
let res = system(cmd)
" Restore de cursor position
call winrestview(winview)
" Delete the temporary file
call delete(b:tmpfname)
let lines = split(res, '\n')
for line in lines
if line !~# '^MATCH'
continue
endif
let docs = s:RacerSplitLine(line[6:])[7]
if len(docs) == 0
break
endif
" Only open doc buffer if there're docs to show
let bn = bufnr('__doc__')
if bn > 0
let wi = index(tabpagebuflist(tabpagenr()), bn)
if wi >= 0
" If the __doc__ buffer is open in the current tab, jump to it
silent execute (wi+1) . 'wincmd w'
else
silent execute 'sbuffer ' . bn
endif
else
split '__doc__'
endif
setlocal nobuflisted
setlocal modifiable
setlocal noswapfile
setlocal buftype=nofile
silent normal! ggdG
silent $put=docs
silent normal! 1Gdd
setlocal nomodifiable
setlocal nomodified
setlocal filetype=rustdoc
break
endfor
endfunction
function! s:RacerGetCompletions(base)
let col = col('.') - 1
let b:tmpfname = tempname()
" HACK: Special case to offer autocompletion on a string literal
if getline('.')[:col-1] =~# '".*"\.$'
call writefile(['fn main() {', ' let x: &str = "";', ' x.', '}'], b:tmpfname)
let fname = expand('%:p')
let cmd = g:racer_cmd . ' complete 3 6 "' . fname . '" "' . b:tmpfname . '"'
else
call writefile(s:RacerGetBufferContents(a:base), b:tmpfname)
let fname = expand('%:p')
let cmd = g:racer_cmd . ' complete ' . line('.') . ' ' . col . ' "' . fname . '" "' . b:tmpfname . '"'
endif
let res = system(cmd)
let lines = split(res, '\n')
let out = []
for line in lines
if line !~# '^MATCH'
continue
endif
let completion = split(line[6:], ',')[0]
if stridx(tolower(completion), tolower(a:base)) == 0
let out = add(out, completion)
endif
endfor
call delete(b:tmpfname)
return out
endfunction
function! racer#GoToDefinition()
if s:ErrorCheck()
return
endif
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 res =~# ' error: ' && line !=# 'END'
call s:Warn(line)
elseif line =~# '^MATCH'
let linenum = split(line[6:], ',')[1]
let colnum = split(line[6:], ',')[2]
let fname = split(line[6:], ',')[3]
call s:RacerJumpToLocation(fname, linenum, colnum)
break
endif
endfor
call delete(tmpfname)
endfunction
function! s: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! s:RacerJumpToLocation(filename, linenum, colnum)
if a:filename == ''
return
endif
" Record jump mark
normal! m`
if a:filename != bufname('%')
try
exec 'keepjumps e ' . fnameescape(a:filename)
catch /^Vim\%((\a\+)\)\=:E37/
" When the buffer is not saved, E37 is thrown. We can ignore it.
endtry
endif
call cursor(a:linenum, a:colnum + 1)
" Center definition on screen
normal! zz
endfunction
function! racer#RacerComplete(findstart, base)
if a:findstart
if s:ErrorCheck()
return -1
endif
return s:RacerGetPrefixCol(a:base)
else
if s:ErrorCheck()
return []
endif
if g:racer_experimental_completer == 1
return s:RacerGetExpCompletions(a:base)
else
return s:RacerGetCompletions(a:base)
endif
endif
endfunction
function! s:Warn(msg)
echohl WarningMsg | echomsg a:msg | echohl NONE
endfunction
function! s:ErrorCheck()
if !executable(g:racer_cmd)
call s:Warn('No racer executable found in $PATH (' . $PATH . ')')
return 1
endif
endfunction