From c1aa392b3cb8034b2e3e221671d14a7109b13457 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 5 Feb 2016 00:52:39 -0700 Subject: [PATCH] Add plugins for Rust support. --- sources_non_forked/rust.vim/.gitignore | 1 + sources_non_forked/rust.vim/README.md | 30 ++ .../rust.vim/after/syntax/rust.vim | 31 +++ sources_non_forked/rust.vim/autoload/rust.vim | 225 +++++++++++++++ .../rust.vim/compiler/cargo.vim | 65 +++++ .../rust.vim/compiler/rustc.vim | 33 +++ sources_non_forked/rust.vim/doc/rust.txt | 178 ++++++++++++ sources_non_forked/rust.vim/ftdetect/rust.vim | 1 + sources_non_forked/rust.vim/ftplugin/rust.vim | 150 ++++++++++ sources_non_forked/rust.vim/indent/rust.vim | 196 +++++++++++++ sources_non_forked/rust.vim/plugin/rust.vim | 22 ++ sources_non_forked/rust.vim/syntax/rust.vim | 262 ++++++++++++++++++ .../rust.vim/syntax_checkers/rust/rustc.vim | 35 +++ sources_non_forked/vim-racer/.gitignore | 1 + sources_non_forked/vim-racer/README.md | 36 +++ sources_non_forked/vim-racer/plugin/racer.vim | 196 +++++++++++++ .../rplugin/python3/deoplete/sources/racer.py | 103 +++++++ 17 files changed, 1565 insertions(+) create mode 100644 sources_non_forked/rust.vim/.gitignore create mode 100644 sources_non_forked/rust.vim/README.md create mode 100644 sources_non_forked/rust.vim/after/syntax/rust.vim create mode 100644 sources_non_forked/rust.vim/autoload/rust.vim create mode 100644 sources_non_forked/rust.vim/compiler/cargo.vim create mode 100644 sources_non_forked/rust.vim/compiler/rustc.vim create mode 100644 sources_non_forked/rust.vim/doc/rust.txt create mode 100644 sources_non_forked/rust.vim/ftdetect/rust.vim create mode 100644 sources_non_forked/rust.vim/ftplugin/rust.vim create mode 100644 sources_non_forked/rust.vim/indent/rust.vim create mode 100644 sources_non_forked/rust.vim/plugin/rust.vim create mode 100644 sources_non_forked/rust.vim/syntax/rust.vim create mode 100644 sources_non_forked/rust.vim/syntax_checkers/rust/rustc.vim create mode 100644 sources_non_forked/vim-racer/.gitignore create mode 100644 sources_non_forked/vim-racer/README.md create mode 100644 sources_non_forked/vim-racer/plugin/racer.vim create mode 100644 sources_non_forked/vim-racer/rplugin/python3/deoplete/sources/racer.py diff --git a/sources_non_forked/rust.vim/.gitignore b/sources_non_forked/rust.vim/.gitignore new file mode 100644 index 00000000..0a56e3fc --- /dev/null +++ b/sources_non_forked/rust.vim/.gitignore @@ -0,0 +1 @@ +/doc/tags diff --git a/sources_non_forked/rust.vim/README.md b/sources_non_forked/rust.vim/README.md new file mode 100644 index 00000000..481db9f3 --- /dev/null +++ b/sources_non_forked/rust.vim/README.md @@ -0,0 +1,30 @@ +# rust.vim + +## Description + +This is a vim plugin provides [Rust][r] file detection and syntax highlighting. + +It is synchronized daily to the vim support code in [rust-lang/rust][rr]'s +master branch via cronjob. + +## Installation + +### Using [Vundle][v] + +1. Add `Plugin 'wting/rust.vim'` to `~/.vimrc` +2. `vim +PluginInstall +qall` + +*Note:* Vundle will not automatically detect Rust files properly if `filetype +on` is executed before Vundle. Please check the [quickstart][vqs] for more +details. + +### Using [Pathogen][p] + +1. `cd ~/.vim/bundle` +2. `git clone https://github.com/wting/rust.vim.git` + +[rr]: https://github.com/rust-lang/rust +[p]: https://github.com/tpope/vim-pathogen +[r]: https://en.wikipedia.org/wiki/Rust_language +[v]: https://github.com/gmarik/vundle +[vqs]: https://github.com/gmarik/vundle#quick-start diff --git a/sources_non_forked/rust.vim/after/syntax/rust.vim b/sources_non_forked/rust.vim/after/syntax/rust.vim new file mode 100644 index 00000000..735c1e15 --- /dev/null +++ b/sources_non_forked/rust.vim/after/syntax/rust.vim @@ -0,0 +1,31 @@ +if !exists('g:rust_conceal') || !has('conceal') || &enc != 'utf-8' + finish +endif + +" For those who don't want to see `::`... +if exists('g:rust_conceal_mod_path') + syn match rustNiceOperator "::" conceal cchar=ㆍ +endif + +syn match rustRightArrowHead contained ">" conceal cchar=  +syn match rustRightArrowTail contained "-" conceal cchar=⟶ +syn match rustNiceOperator "->" contains=rustRightArrowHead,rustRightArrowTail + +syn match rustFatRightArrowHead contained ">" conceal cchar=  +syn match rustFatRightArrowTail contained "=" conceal cchar=⟹ +syn match rustNiceOperator "=>" contains=rustFatRightArrowHead,rustFatRightArrowTail + +syn match rustNiceOperator /\<\@!_\(_*\>\)\@=/ conceal cchar=′ + +" For those who don't want to see `pub`... +if exists('g:rust_conceal_pub') + syn match rustPublicSigil contained "pu" conceal cchar=* + syn match rustPublicRest contained "b" conceal cchar=  + syn match rustNiceOperator "pub " contains=rustPublicSigil,rustPublicRest +endif + +hi link rustNiceOperator Operator + +if !exists('g:rust_conceal_mod_path') + hi! link Conceal Operator +endif diff --git a/sources_non_forked/rust.vim/autoload/rust.vim b/sources_non_forked/rust.vim/autoload/rust.vim new file mode 100644 index 00000000..fe8e743e --- /dev/null +++ b/sources_non_forked/rust.vim/autoload/rust.vim @@ -0,0 +1,225 @@ +" Author: Kevin Ballard +" Description: Helper functions for Rust commands/mappings +" Last Modified: May 27, 2014 + +" Jump {{{1 + +function! rust#Jump(mode, function) range + let cnt = v:count1 + normal! m' + if a:mode ==# 'v' + norm! gv + endif + let foldenable = &foldenable + set nofoldenable + while cnt > 0 + execute "call Jump_" . a:function . "()" + let cnt = cnt - 1 + endwhile + let &foldenable = foldenable +endfunction + +function! s:Jump_Back() + call search('{', 'b') + keepjumps normal! w99[{ +endfunction + +function! s:Jump_Forward() + normal! j0 + call search('{', 'b') + keepjumps normal! w99[{% + call search('{') +endfunction + +" Run {{{1 + +function! rust#Run(bang, args) + if a:bang + let idx = index(a:args, '--') + if idx != -1 + let rustc_args = idx == 0 ? [] : a:args[:idx-1] + let args = a:args[idx+1:] + else + let rustc_args = a:args + let args = [] + endif + else + let rustc_args = [] + let args = a:args + endif + + let b:rust_last_rustc_args = rustc_args + let b:rust_last_args = args + + call s:WithPath(function("s:Run"), rustc_args, args) +endfunction + +function! s:Run(path, rustc_args, args) + try + let exepath = tempname() + if has('win32') + let exepath .= '.exe' + endif + + let rustc_args = [a:path, '-o', exepath] + a:rustc_args + + let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc" + + let output = system(shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)'))) + if output != '' + echohl WarningMsg + echo output + echohl None + endif + if !v:shell_error + exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)')) + endif + finally + if exists("exepath") + silent! call delete(exepath) + endif + endtry +endfunction + +" Expand {{{1 + +function! rust#Expand(bang, args) + if a:bang && !empty(a:args) + let pretty = a:args[0] + let args = a:args[1:] + else + let pretty = "expanded" + let args = a:args + endif + call s:WithPath(function("s:Expand"), pretty, args) +endfunction + +function! s:Expand(path, pretty, args) + try + let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc" + + let args = [a:path, '--pretty', a:pretty] + a:args + let output = system(shellescape(rustc) . " " . join(map(args, "shellescape(v:val)"))) + if v:shell_error + echohl WarningMsg + echo output + echohl None + else + new + silent put =output + 1 + d + setl filetype=rust + setl buftype=nofile + setl bufhidden=hide + setl noswapfile + endif + endtry +endfunction + +function! rust#CompleteExpand(lead, line, pos) + if a:line[: a:pos-1] =~ '^RustExpand!\s*\S*$' + " first argument and it has a ! + let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph="] + if !empty(a:lead) + call filter(list, "v:val[:len(a:lead)-1] == a:lead") + endif + return list + endif + + return glob(escape(a:lead, "*?[") . '*', 0, 1) +endfunction + +" Emit {{{1 + +function! rust#Emit(type, args) + call s:WithPath(function("s:Emit"), a:type, a:args) +endfunction + +function! s:Emit(path, type, args) + try + let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc" + + let args = [a:path, '--emit', a:type, '-o', '-'] + a:args + let output = system(shellescape(rustc) . " " . join(map(args, "shellescape(v:val)"))) + if v:shell_error + echohl WarningMsg + echo output + echohl None + else + new + silent put =output + 1 + d + if a:type == "ir" + setl filetype=llvm + elseif a:type == "asm" + setl filetype=asm + endif + setl buftype=nofile + setl bufhidden=hide + setl noswapfile + endif + endtry +endfunction + +" Utility functions {{{1 + +function! s:WithPath(func, ...) + try + let save_write = &write + set write + let path = expand('%') + let pathisempty = empty(path) + if pathisempty || !save_write + " use a temporary file named 'unnamed.rs' inside a temporary + " directory. This produces better error messages + let tmpdir = tempname() + call mkdir(tmpdir) + + let save_cwd = getcwd() + silent exe 'lcd' fnameescape(tmpdir) + + let path = 'unnamed.rs' + + let save_mod = &mod + set nomod + + silent exe 'keepalt write! ' . fnameescape(path) + if pathisempty + silent keepalt 0file + endif + else + update + endif + + call call(a:func, [path] + a:000) + finally + if exists("save_mod") | let &mod = save_mod | endif + if exists("save_write") | let &write = save_write | endif + if exists("save_cwd") | silent exe 'lcd' fnameescape(save_cwd) | endif + if exists("tmpdir") | silent call s:RmDir(tmpdir) | endif + endtry +endfunction + +function! rust#AppendCmdLine(text) + call setcmdpos(getcmdpos()) + let cmd = getcmdline() . a:text + return cmd +endfunction + +function! s:RmDir(path) + " sanity check; make sure it's not empty, /, or $HOME + if empty(a:path) + echoerr 'Attempted to delete empty path' + return 0 + elseif a:path == '/' || a:path == $HOME + echoerr 'Attempted to delete protected path: ' . a:path + return 0 + endif + silent exe "!rm -rf " . shellescape(a:path) +endfunction + +" }}}1 + +" vim: set noet sw=4 ts=4: diff --git a/sources_non_forked/rust.vim/compiler/cargo.vim b/sources_non_forked/rust.vim/compiler/cargo.vim new file mode 100644 index 00000000..ed487a30 --- /dev/null +++ b/sources_non_forked/rust.vim/compiler/cargo.vim @@ -0,0 +1,65 @@ +" Vim compiler file +" Compiler: Cargo Compiler +" Maintainer: Damien Radtke +" Latest Revision: 2014 Sep 24 + +if exists('current_compiler') + finish +endif +runtime compiler/rustc.vim +let current_compiler = "cargo" + +if exists(':CompilerSet') != 2 + command -nargs=* CompilerSet setlocal +endif + +if exists('g:cargo_makeprg_params') + execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*' +else + CompilerSet makeprg=cargo\ $* +endif + +" Allow a configurable global Cargo.toml name. This makes it easy to +" support variations like 'cargo.toml'. +let s:cargo_manifest_name = get(g:, 'cargo_manifest_name', 'Cargo.toml') + +function! s:is_absolute(path) + return a:path[0] == '/' || a:path =~ '[A-Z]\+:' +endfunction + +let s:local_manifest = findfile(s:cargo_manifest_name, '.;') +if s:local_manifest != '' + let s:local_manifest = fnamemodify(s:local_manifest, ':p:h').'/' + augroup cargo + au! + au QuickfixCmdPost make call s:FixPaths() + augroup END + + " FixPaths() is run after Cargo, and is used to change the file paths + " to be relative to the current directory instead of Cargo.toml. + function! s:FixPaths() + let qflist = getqflist() + let manifest = s:local_manifest + for qf in qflist + if !qf.valid + let m = matchlist(qf.text, '(file://\(.*\))$') + if !empty(m) + let manifest = m[1].'/' + " Manually strip another slash if needed; usually just an + " issue on Windows. + if manifest =~ '^/[A-Z]\+:/' + let manifest = manifest[1:] + endif + endif + continue + endif + let filename = bufname(qf.bufnr) + if s:is_absolute(filename) + continue + endif + let qf.filename = simplify(manifest.filename) + call remove(qf, 'bufnr') + endfor + call setqflist(qflist, 'r') + endfunction +endif diff --git a/sources_non_forked/rust.vim/compiler/rustc.vim b/sources_non_forked/rust.vim/compiler/rustc.vim new file mode 100644 index 00000000..f9b854ed --- /dev/null +++ b/sources_non_forked/rust.vim/compiler/rustc.vim @@ -0,0 +1,33 @@ +" Vim compiler file +" Compiler: Rust Compiler +" Maintainer: Chris Morgan +" Latest Revision: 2013 Jul 12 + +if exists("current_compiler") + finish +endif +let current_compiler = "rustc" + +let s:cpo_save = &cpo +set cpo&vim + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +if exists("g:rustc_makeprg_no_percent") && g:rustc_makeprg_no_percent == 1 + CompilerSet makeprg=rustc +else + CompilerSet makeprg=rustc\ \% +endif + +CompilerSet errorformat= + \%f:%l:%c:\ %t%*[^:]:\ %m, + \%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m, + \%-G%f:%l\ %s, + \%-G%*[\ ]^, + \%-G%*[\ ]^%*[~], + \%-G%*[\ ]... + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/sources_non_forked/rust.vim/doc/rust.txt b/sources_non_forked/rust.vim/doc/rust.txt new file mode 100644 index 00000000..e117b0c1 --- /dev/null +++ b/sources_non_forked/rust.vim/doc/rust.txt @@ -0,0 +1,178 @@ +*rust.txt* Filetype plugin for Rust + +============================================================================== +CONTENTS *rust* *ft-rust* + +1. Introduction |rust-intro| +2. Settings |rust-settings| +3. Commands |rust-commands| +4. Mappings |rust-mappings| + +============================================================================== +INTRODUCTION *rust-intro* + +This plugin provides syntax and supporting functionality for the Rust +filetype. + +============================================================================== +SETTINGS *rust-settings* + +This plugin has a few variables you can define in your vimrc that change the +behavior of the plugin. + + *g:rustc_path* +g:rustc_path~ + Set this option to the path to rustc for use in the |:RustRun| and + |:RustExpand| commands. If unset, "rustc" will be located in $PATH: > + let g:rustc_path = $HOME."/bin/rustc" +< + + *g:rustc_makeprg_no_percent* +g:rustc_makeprg_no_percent~ + Set this option to 1 to have 'makeprg' default to "rustc" instead of + "rustc %": > + let g:rustc_makeprg_no_percent = 1 +< + + *g:rust_conceal* +g:rust_conceal~ + Set this option to turn on the basic |conceal| support: > + let g:rust_conceal = 1 +< + + *g:rust_conceal_mod_path* +g:rust_conceal_mod_path~ + Set this option to turn on |conceal| for the path connecting token + "::": > + let g:rust_conceal_mod_path = 1 +< + + *g:rust_conceal_pub* +g:rust_conceal_pub~ + Set this option to turn on |conceal| for the "pub" token: > + let g:rust_conceal_pub = 1 +< + + *g:rust_recommended_style* +g:rust_recommended_style~ + Set this option to enable vim indentation and textwidth settings to + conform to style conventions of the rust standard library (i.e. use 4 + spaces for indents and sets 'textwidth' to 99). This option is enabled + by default. To disable it: > + let g:rust_recommended_style = 0 +< + + *g:rust_fold* +g:rust_fold~ + Set this option to turn on |folding|: > + let g:rust_fold = 1 +< + Value Effect ~ + 0 No folding + 1 Braced blocks are folded. All folds are open by + default. + 2 Braced blocks are folded. 'foldlevel' is left at the + global value (all folds are closed by default). + + *g:rust_bang_comment_leader* +g:rust_bang_comment_leader~ + Set this option to 1 to preserve the leader on multi-line doc comments + using the /*! syntax: > + let g:rust_bang_comment_leader = 1 +< + + *g:ftplugin_rust_source_path* +g:ftplugin_rust_source_path~ + Set this option to a path that should be prepended to 'path' for Rust + source files: > + let g:ftplugin_rust_source_path = $HOME.'/dev/rust' +< + + *g:cargo_manifest_name* +g:cargo_manifest_name~ + Set this option to the name of the manifest file for your projects. If + not specified it defaults to 'Cargo.toml' : > + let g:cargo_manifest_name = 'Cargo.toml' +< + +============================================================================== +COMMANDS *rust-commands* + +:RustRun [args] *:RustRun* +:RustRun! [rustc-args] [--] [args] + Compiles and runs the current file. If it has unsaved changes, + it will be saved first using |:update|. If the current file is + an unnamed buffer, it will be written to a temporary file + first. The compiled binary is always placed in a temporary + directory, but is run from the current directory. + + The arguments given to |:RustRun| will be passed to the + compiled binary. + + If ! is specified, the arguments are passed to rustc instead. + A "--" argument will separate the rustc arguments from the + arguments passed to the binary. + + If |g:rustc_path| is defined, it is used as the path to rustc. + Otherwise it is assumed rustc can be found in $PATH. + +:RustExpand [args] *:RustExpand* +:RustExpand! [TYPE] [args] + Expands the current file using --pretty and displays the + results in a new split. If the current file has unsaved + changes, it will be saved first using |:update|. If the + current file is an unnamed buffer, it will be written to a + temporary file first. + + The arguments given to |:RustExpand| will be passed to rustc. + This is largely intended for specifying various --cfg + configurations. + + If ! is specified, the first argument is the expansion type to + pass to rustc --pretty. Otherwise it will default to + "expanded". + + If |g:rustc_path| is defined, it is used as the path to rustc. + Otherwise it is assumed rustc can be found in $PATH. + +:RustEmitIr [args] *:RustEmitIr* + Compiles the current file to LLVM IR and displays the results + in a new split. If the current file has unsaved changes, it + will be saved first using |:update|. If the current file is an + unnamed buffer, it will be written to a temporary file first. + + The arguments given to |:RustEmitIr| will be passed to rustc. + + If |g:rustc_path| is defined, it is used as the path to rustc. + Otherwise it is assumed rustc can be found in $PATH. + +:RustEmitAsm [args] *:RustEmitAsm* + Compiles the current file to assembly and displays the results + in a new split. If the current file has unsaved changes, it + will be saved first using |:update|. If the current file is an + unnamed buffer, it will be written to a temporary file first. + + The arguments given to |:RustEmitAsm| will be passed to rustc. + + If |g:rustc_path| is defined, it is used as the path to rustc. + Otherwise it is assumed rustc can be found in $PATH. + +============================================================================== +MAPPINGS *rust-mappings* + +This plugin defines mappings for |[[| and |]]| to support hanging indents. + +It also has a few other mappings: + + *rust_* + Executes |:RustRun| with no arguments. + Note: This binding is only available in MacVim. + + *rust_* + Populates the command line with |:RustRun|! using the + arguments given to the last invocation, but does not + execute it. + Note: This binding is only available in MacVim. + +============================================================================== + vim:tw=78:sw=4:noet:ts=8:ft=help:norl: diff --git a/sources_non_forked/rust.vim/ftdetect/rust.vim b/sources_non_forked/rust.vim/ftdetect/rust.vim new file mode 100644 index 00000000..bf685d43 --- /dev/null +++ b/sources_non_forked/rust.vim/ftdetect/rust.vim @@ -0,0 +1 @@ +au BufRead,BufNewFile *.rs set filetype=rust diff --git a/sources_non_forked/rust.vim/ftplugin/rust.vim b/sources_non_forked/rust.vim/ftplugin/rust.vim new file mode 100644 index 00000000..5d556994 --- /dev/null +++ b/sources_non_forked/rust.vim/ftplugin/rust.vim @@ -0,0 +1,150 @@ +" Language: Rust +" Description: Vim syntax file for Rust +" Maintainer: Chris Morgan +" Maintainer: Kevin Ballard +" Last Change: Jul 07, 2014 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:save_cpo = &cpo +set cpo&vim + +" Variables {{{1 + +" The rust source code at present seems to typically omit a leader on /*! +" comments, so we'll use that as our default, but make it easy to switch. +" This does not affect indentation at all (I tested it with and without +" leader), merely whether a leader is inserted by default or not. +if exists("g:rust_bang_comment_leader") && g:rust_bang_comment_leader == 1 + " Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why, + " but without it, */ gets indented one space even if there were no + " leaders. I'm fairly sure that's a Vim bug. + setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,:// +else + setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,:// +endif +setlocal commentstring=//%s +setlocal formatoptions-=t formatoptions+=croqnl +" j was only added in 7.3.541, so stop complaints about its nonexistence +silent! setlocal formatoptions+=j + +" smartindent will be overridden by indentexpr if filetype indent is on, but +" otherwise it's better than nothing. +setlocal smartindent nocindent + +if !exists("g:rust_recommended_style") || g:rust_recommended_style == 1 + setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab + setlocal textwidth=99 +endif + +" This includeexpr isn't perfect, but it's a good start +setlocal includeexpr=substitute(v:fname,'::','/','g') + +" NOT adding .rc as it's being phased out (0.7) +setlocal suffixesadd=.rs + +if exists("g:ftplugin_rust_source_path") + let &l:path=g:ftplugin_rust_source_path . ',' . &l:path +endif + +if exists("g:loaded_delimitMate") + if exists("b:delimitMate_excluded_regions") + let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions + endif + let b:delimitMate_excluded_regions = delimitMate#Get("excluded_regions") . ',rustLifetimeCandidate,rustGenericLifetimeCandidate' +endif + +if has("folding") && exists('g:rust_fold') && g:rust_fold != 0 + let b:rust_set_foldmethod=1 + setlocal foldmethod=syntax + if g:rust_fold == 2 + setlocal foldlevel< + else + setlocal foldlevel=99 + endif +endif + +if has('conceal') && exists('g:rust_conceal') + let b:rust_set_conceallevel=1 + setlocal conceallevel=2 +endif + +" Motion Commands {{{1 + +" Bind motion commands to support hanging indents +nnoremap [[ :call rust#Jump('n', 'Back') +nnoremap ]] :call rust#Jump('n', 'Forward') +xnoremap [[ :call rust#Jump('v', 'Back') +xnoremap ]] :call rust#Jump('v', 'Forward') +onoremap [[ :call rust#Jump('o', 'Back') +onoremap ]] :call rust#Jump('o', 'Forward') + +" Commands {{{1 + +" See |:RustRun| for docs +command! -nargs=* -complete=file -bang -bar -buffer RustRun call rust#Run(0, []) + +" See |:RustExpand| for docs +command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -bar -buffer RustExpand call rust#Expand(0, []) + +" See |:RustEmitIr| for docs +command! -nargs=* -bar -buffer RustEmitIr call rust#Emit("ir", []) + +" See |:RustEmitAsm| for docs +command! -nargs=* -bar -buffer RustEmitAsm call rust#Emit("asm", []) + +" Mappings {{{1 + +" Bind ⌘R in MacVim to :RustRun +nnoremap :RustRun +" Bind ⌘⇧R in MacVim to :RustRun! pre-filled with the last args +nnoremap :RustRun! =join(b:rust_last_rustc_args)erust#AppendCmdLine(' -- ' . join(b:rust_last_args)) + +if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args") + let b:rust_last_rustc_args = [] + let b:rust_last_args = [] +endif + +" Cleanup {{{1 + +let b:undo_ftplugin = " + \ setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd< + \|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth< + \|if exists('b:rust_original_delimitMate_excluded_regions') + \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions + \|unlet b:rust_original_delimitMate_excluded_regions + \|else + \|unlet! b:delimitMate_excluded_regions + \|endif + \|if exists('b:rust_set_foldmethod') + \|setlocal foldmethod< foldlevel< + \|unlet b:rust_set_foldmethod + \|endif + \|if exists('b:rust_set_conceallevel') + \|setlocal conceallevel< + \|unlet b:rust_set_conceallevel + \|endif + \|unlet! b:rust_last_rustc_args b:rust_last_args + \|delcommand RustRun + \|delcommand RustExpand + \|delcommand RustEmitIr + \|delcommand RustEmitAsm + \|nunmap + \|nunmap + \|nunmap [[ + \|nunmap ]] + \|xunmap [[ + \|xunmap ]] + \|ounmap [[ + \|ounmap ]] + \" + +" }}}1 + +let &cpo = s:save_cpo +unlet s:save_cpo + +" vim: set noet sw=4 ts=4: diff --git a/sources_non_forked/rust.vim/indent/rust.vim b/sources_non_forked/rust.vim/indent/rust.vim new file mode 100644 index 00000000..300d7dac --- /dev/null +++ b/sources_non_forked/rust.vim/indent/rust.vim @@ -0,0 +1,196 @@ +" Vim indent file +" Language: Rust +" Author: Chris Morgan +" Last Change: 2014 Sep 13 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal cindent +setlocal cinoptions=L0,(0,Ws,J1,j1 +setlocal cinkeys=0{,0},!^F,o,O,0[,0] +" Don't think cinwords will actually do anything at all... never mind +setlocal cinwords=for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern + +" Some preliminary settings +setlocal nolisp " Make sure lisp indenting doesn't supersede us +setlocal autoindent " indentexpr isn't much help otherwise +" Also do indentkeys, otherwise # gets shoved to column 0 :-/ +setlocal indentkeys=0{,0},!^F,o,O,0[,0] + +setlocal indentexpr=GetRustIndent(v:lnum) + +" Only define the function once. +if exists("*GetRustIndent") + finish +endif + +" Come here when loading the script the first time. + +function! s:get_line_trimmed(lnum) + " Get the line and remove a trailing comment. + " Use syntax highlighting attributes when possible. + " NOTE: this is not accurate; /* */ or a line continuation could trick it + let line = getline(a:lnum) + let line_len = strlen(line) + if has('syntax_items') + " If the last character in the line is a comment, do a binary search for + " the start of the comment. synID() is slow, a linear search would take + " too long on a long line. + if synIDattr(synID(a:lnum, line_len, 1), "name") =~ 'Comment\|Todo' + let min = 1 + let max = line_len + while min < max + let col = (min + max) / 2 + if synIDattr(synID(a:lnum, col, 1), "name") =~ 'Comment\|Todo' + let max = col + else + let min = col + 1 + endif + endwhile + let line = strpart(line, 0, min - 1) + endif + return substitute(line, "\s*$", "", "") + else + " Sorry, this is not complete, nor fully correct (e.g. string "//"). + " Such is life. + return substitute(line, "\s*//.*$", "", "") + endif +endfunction + +function! s:is_string_comment(lnum, col) + if has('syntax_items') + for id in synstack(a:lnum, a:col) + let synname = synIDattr(id, "name") + if synname == "rustString" || synname =~ "^rustComment" + return 1 + endif + endfor + else + " without syntax, let's not even try + return 0 + endif +endfunction + +function GetRustIndent(lnum) + + " Starting assumption: cindent (called at the end) will do it right + " normally. We just want to fix up a few cases. + + let line = getline(a:lnum) + + if has('syntax_items') + let synname = synIDattr(synID(a:lnum, 1, 1), "name") + if synname == "rustString" + " If the start of the line is in a string, don't change the indent + return -1 + elseif synname =~ '\(Comment\|Todo\)' + \ && line !~ '^\s*/\*' " not /* opening line + if synname =~ "CommentML" " multi-line + if line !~ '^\s*\*' && getline(a:lnum - 1) =~ '^\s*/\*' + " This is (hopefully) the line after a /*, and it has no + " leader, so the correct indentation is that of the + " previous line. + return GetRustIndent(a:lnum - 1) + endif + endif + " If it's in a comment, let cindent take care of it now. This is + " for cases like "/*" where the next line should start " * ", not + " "* " as the code below would otherwise cause for module scope + " Fun fact: " /*\n*\n*/" takes two calls to get right! + return cindent(a:lnum) + endif + endif + + " cindent gets second and subsequent match patterns/struct members wrong, + " as it treats the comma as indicating an unfinished statement:: + " + " match a { + " b => c, + " d => e, + " f => g, + " }; + + " Search backwards for the previous non-empty line. + let prevlinenum = prevnonblank(a:lnum - 1) + let prevline = s:get_line_trimmed(prevlinenum) + while prevlinenum > 1 && prevline !~ '[^[:blank:]]' + let prevlinenum = prevnonblank(prevlinenum - 1) + let prevline = s:get_line_trimmed(prevlinenum) + endwhile + if prevline[len(prevline) - 1] == "," + \ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]' + \ && prevline !~ '^\s*fn\s' + \ && prevline !~ '([^()]\+,$' + " Oh ho! The previous line ended in a comma! I bet cindent will try to + " take this too far... For now, let's normally use the previous line's + " indent. + + " One case where this doesn't work out is where *this* line contains + " square or curly brackets; then we normally *do* want to be indenting + " further. + " + " Another case where we don't want to is one like a function + " definition with arguments spread over multiple lines: + " + " fn foo(baz: Baz, + " baz: Baz) // <-- cindent gets this right by itself + " + " Another case is similar to the previous, except calling a function + " instead of defining it, or any conditional expression that leaves + " an open paren: + " + " foo(baz, + " baz); + " + " if baz && (foo || + " bar) { + " + " There are probably other cases where we don't want to do this as + " well. Add them as needed. + return indent(prevlinenum) + endif + + if !has("patch-7.4.355") + " cindent before 7.4.355 doesn't do the module scope well at all; e.g.:: + " + " static FOO : &'static [bool] = [ + " true, + " false, + " false, + " true, + " ]; + " + " uh oh, next statement is indented further! + + " Note that this does *not* apply the line continuation pattern properly; + " that's too hard to do correctly for my liking at present, so I'll just + " start with these two main cases (square brackets and not returning to + " column zero) + + call cursor(a:lnum, 1) + if searchpair('{\|(', '', '}\|)', 'nbW', + \ 's:is_string_comment(line("."), col("."))') == 0 + if searchpair('\[', '', '\]', 'nbW', + \ 's:is_string_comment(line("."), col("."))') == 0 + " Global scope, should be zero + return 0 + else + " At the module scope, inside square brackets only + "if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum + if line =~ "^\\s*]" + " It's the closing line, dedent it + return 0 + else + return &shiftwidth + endif + endif + endif + endif + + " Fall back on cindent, which does it mostly right + return cindent(a:lnum) +endfunction diff --git a/sources_non_forked/rust.vim/plugin/rust.vim b/sources_non_forked/rust.vim/plugin/rust.vim new file mode 100644 index 00000000..4ec4f33d --- /dev/null +++ b/sources_non_forked/rust.vim/plugin/rust.vim @@ -0,0 +1,22 @@ +" Vim syntastic plugin helper +" Language: Rust +" Maintainer: Andrew Gallant + +if exists("g:loaded_syntastic_rust_filetype") + finish +endif +let g:loaded_syntastic_rust_filetype = 1 +let s:save_cpo = &cpo +set cpo&vim + +" This is to let Syntastic know about the Rust filetype. +" It enables tab completion for the 'SyntasticInfo' command. +" (This does not actually register the syntax checker.) +if exists('g:syntastic_extra_filetypes') + call add(g:syntastic_extra_filetypes, 'rust') +else + let g:syntastic_extra_filetypes = ['rust'] +endif + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/sources_non_forked/rust.vim/syntax/rust.vim b/sources_non_forked/rust.vim/syntax/rust.vim new file mode 100644 index 00000000..a37b7b6d --- /dev/null +++ b/sources_non_forked/rust.vim/syntax/rust.vim @@ -0,0 +1,262 @@ +" Vim syntax file +" Language: Rust +" Maintainer: Patrick Walton +" Maintainer: Ben Blum +" Maintainer: Chris Morgan +" Last Change: January 5, 2015 + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" Syntax definitions {{{1 +" Basic keywords {{{2 +syn keyword rustConditional match if else +syn keyword rustOperator as + +syn match rustAssert "\(); + +" This is merely a convention; note also the use of [A-Z], restricting it to +" latin identifiers rather than the full Unicode uppercase. I have not used +" [:upper:] as it depends upon 'noignorecase' +"syn match rustCapsIdent display "[A-Z]\w\(\w\)*" + +syn match rustOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?" +" This one isn't *quite* right, as we could have binary-& with a reference +syn match rustSigil display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1 +syn match rustSigil display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1 +" This isn't actually correct; a closure with no arguments can be `|| { }`. +" Last, because the & in && isn't a sigil +syn match rustOperator display "&&\|||" + +syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustPanic +syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustPanic + +syn match rustEscapeError display contained /\\./ +syn match rustEscape display contained /\\\([nrt0\\'"]\|x\x\{2}\)/ +syn match rustEscapeUnicode display contained /\\\(u\x\{4}\|U\x\{8}\)/ +syn match rustEscapeUnicode display contained /\\u{\x\{1,6}}/ +syn match rustStringContinuation display contained /\\\n\s*/ +syn region rustString start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation +syn region rustString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell +syn region rustString start='b\?r\z(#*\)"' end='"\z1' contains=@Spell + +syn region rustAttribute start="#!\?\[" end="\]" contains=rustString,rustDerive +syn region rustDerive start="derive(" end=")" contained contains=rustTrait + +" Number literals +syn match rustDecNumber display "\<[0-9][0-9_]*\%([iu]\%(s\|8\|16\|32\|64\)\)\=" +syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\%([iu]\%(s\|8\|16\|32\|64\)\)\=" +syn match rustOctNumber display "\<0o[0-7_]\+\%([iu]\%(s\|8\|16\|32\|64\)\)\=" +syn match rustBinNumber display "\<0b[01_]\+\%([iu]\%(s\|8\|16\|32\|64\)\)\=" + +" Special case for numbers of the form "1." which are float literals, unless followed by +" an identifier, which makes them integer literals with a method call or field access, +" or by another ".", which makes them integer literals followed by the ".." token. +" (This must go first so the others take precedence.) +syn match rustFloat display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!" +" To mark a number as a normal float, it must have at least one of the three things integral values don't have: +" a decimal point and more numbers; an exponent; and a type suffix. +syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\=" +syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\=" +syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)" + +" For the benefit of delimitMate +syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime +syn region rustGenericRegion display start=/<\%('\|[^[cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate +syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime + +"rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting +syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" +syn match rustCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/ +" The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII). +syn match rustCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/ +syn match rustCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode +syn match rustCharacter /'\([^\\]\|\\\(.\|x\x\{2}\|u\x\{4}\|U\x\{8}\|u{\x\{1,6}}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid + +syn region rustCommentLine start="//" end="$" contains=rustTodo,@Spell +syn region rustCommentLineDoc start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell +syn region rustCommentBlock matchgroup=rustCommentBlock start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell +syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell +syn region rustCommentBlockNest matchgroup=rustCommentBlock start="/\*" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent +syn region rustCommentBlockDocNest matchgroup=rustCommentBlockDoc start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent +" FIXME: this is a really ugly and not fully correct implementation. Most +" importantly, a case like ``/* */*`` should have the final ``*`` not being in +" a comment, but in practice at present it leaves comments open two levels +" deep. But as long as you stay away from that particular case, I *believe* +" the highlighting is correct. Due to the way Vim's syntax engine works +" (greedy for start matches, unlike Rust's tokeniser which is searching for +" the earliest-starting match, start or end), I believe this cannot be solved. +" Oh you who would fix it, don't bother with things like duplicating the Block +" rules and putting ``\*\@ +" +" See for details on how to add an external Syntastic checker: +" https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide#external + +if exists("g:loaded_syntastic_rust_rustc_checker") + finish +endif +let g:loaded_syntastic_rust_rustc_checker = 1 + +let s:save_cpo = &cpo +set cpo&vim + +function! SyntaxCheckers_rust_rustc_GetLocList() dict + let makeprg = self.makeprgBuild({ 'args': '-Zparse-only' }) + + let errorformat = + \ '%E%f:%l:%c: %\d%#:%\d%# %.%\{-}error:%.%\{-} %m,' . + \ '%W%f:%l:%c: %\d%#:%\d%# %.%\{-}warning:%.%\{-} %m,' . + \ '%C%f:%l %m,' . + \ '%-Z%.%#' + + return SyntasticMake({ + \ 'makeprg': makeprg, + \ 'errorformat': errorformat }) +endfunction + +call g:SyntasticRegistry.CreateAndRegisterChecker({ + \ 'filetype': 'rust', + \ 'name': 'rustc'}) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/sources_non_forked/vim-racer/.gitignore b/sources_non_forked/vim-racer/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/sources_non_forked/vim-racer/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/sources_non_forked/vim-racer/README.md b/sources_non_forked/vim-racer/README.md new file mode 100644 index 00000000..ef47c0c6 --- /dev/null +++ b/sources_non_forked/vim-racer/README.md @@ -0,0 +1,36 @@ +# Vim Racer Plugin + +This plugin allows vim to use [Racer](http://github.com/phildawes/racer) for Rust code completion and navigation. + +## Installation + +1. Build / Install [Racer](http://github.com/phildawes/racer) + +1. Install using Pathogen, Vundle or NeoBundle. Or, copy `plugin/racer.vim` into your `~/.vim/plugin` directory. + + Vundle users: + ``` + Plugin 'racer-rust/vim-racer' + ``` + + NeoBundle users: + ``` + NeoBundle 'racer-rust/vim-racer' + ``` + + vim-plug users: + ``` + Plug 'racer-rust/vim-racer' + ``` + +2. Add `g:racer_cmd` and `$RUST_SRC_PATH` variables to your `.vimrc`. Also it's worth turning on 'hidden' mode for buffers otherwise you need to save the current buffer every time you do a goto-definition. E.g.: + + ``` + set hidden + let g:racer_cmd = "/target/release/racer" + let $RUST_SRC_PATH="/src/" + ``` + +3. In insert mode use `C-x-C-o` to search for completions + +4. In normal mode type `gd` to go to a definition diff --git a/sources_non_forked/vim-racer/plugin/racer.vim b/sources_non_forked/vim-racer/plugin/racer.vim new file mode 100644 index 00000000..c42fb3d5 --- /dev/null +++ b/sources_non_forked/vim-racer/plugin/racer.vim @@ -0,0 +1,196 @@ +" 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(':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 gd :call RacerGoToDefinition() +autocmd FileType rust nnoremap gD :vsplit:call RacerGoToDefinition() + +let &cpo = s:save_cpo +unlet s:save_cpo + diff --git a/sources_non_forked/vim-racer/rplugin/python3/deoplete/sources/racer.py b/sources_non_forked/vim-racer/rplugin/python3/deoplete/sources/racer.py new file mode 100644 index 00000000..7af86ac7 --- /dev/null +++ b/sources_non_forked/vim-racer/rplugin/python3/deoplete/sources/racer.py @@ -0,0 +1,103 @@ +#============================================================================= +# FILE: racer.py +# AUTHOR: Shougo Matsushita +# License: MIT license {{{ +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# }}} +#============================================================================= + +import re +import os +import subprocess +from .base import Base + +class Source(Base): + def __init__(self, vim): + Base.__init__(self, vim) + + self.name = 'racer' + self.mark = '[racer]' + self.filetypes = ['rust'] + self.input_pattern = r'(\.|::)\w*' + self.__executable_racer = self.vim.funcs.executable( + self.vim.eval('g:racer_cmd')) + self.__racer = self.vim.eval('g:racer_cmd') + self.__encoding = self.vim.eval('&encoding') + + def get_complete_position(self, context): + if not self.__executable_racer: + return -1 + + results = self.get_results('prefix', self.vim.funcs.col('.')) + if not results: + return -1 + prefixline = results[0] + return int(prefixline[7:].split(',')[0]) + + def gather_candidates(self, context): + 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' + } + + candidates = [] + insert_paren = int(self.vim.eval('g:racer_insert_paren')) + for line in [l[6:] for l + in self.get_results('complete-with-snippet', + context['complete_position'] + 1) + if l.startswith('MATCH')]: + completions = line.split(';', 6) + kind = typeMap[completions[5]] + completion = { 'kind': kind, 'word': completions[0], 'dup': 1 } + if kind == 'f': # function + completion['menu'] = completions[6].replace( + 'pub ', '').replace('fn ', '').rstrip('{') + if ' where ' in completion['menu'] or completion[ + 'menu'].endswith(' where') : + where = completion['menu'].rindex(' where') + completion['menu'] = completion['menu'][: where] + if insert_paren: + completion['abbr'] = completions[0] + completion['word'] += '(' + elif kind == 's' : # struct + completion['menu'] = completions[6].replace( + 'pub ', '').replace( 'struct ', '').rstrip('{') + candidates.append(completion) + return candidates + + def get_results(self, command, col): + temp = self.vim.funcs.tempname() + with open(temp, 'w') as f: + for l in self.vim.current.buffer: + f.write(l + "\n") + try: + results = subprocess.check_output([ + self.__racer, command, + str(self.vim.funcs.line('.')), + str(col - 1), + temp + ]).decode(self.__encoding).splitlines() + except subprocess.CalledProcessError: + return [] + finally: + os.remove(temp) + return results