diff options
Diffstat (limited to 'vim/bundle/vim-racer/autoload')
-rw-r--r-- | vim/bundle/vim-racer/autoload/racer.vim | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/vim/bundle/vim-racer/autoload/racer.vim b/vim/bundle/vim-racer/autoload/racer.vim new file mode 100644 index 0000000..5cb80d7 --- /dev/null +++ b/vim/bundle/vim-racer/autoload/racer.vim @@ -0,0 +1,265 @@ +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 |