summaryrefslogtreecommitdiff
path: root/vim/bundle/vim-racer/autoload/racer.vim
diff options
context:
space:
mode:
Diffstat (limited to 'vim/bundle/vim-racer/autoload/racer.vim')
-rw-r--r--vim/bundle/vim-racer/autoload/racer.vim265
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