diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2018-10-08 19:00:59 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2018-10-08 19:00:59 +0200 |
commit | fd74d8b2b170b540680a9bbf6c64990f8ebafd08 (patch) | |
tree | b1fdef6203a78a21053d1b8e0666ab7a38c36df2 /autoload/rust | |
parent | 055f7710b65dfa2df52fc0b5be2486ae36ac5751 (diff) | |
download | vim-polyglot-3.3.3.tar.gz vim-polyglot-3.3.3.zip |
Updatev3.3.3
Diffstat (limited to '')
-rw-r--r-- | autoload/rust.vim | 91 | ||||
-rw-r--r-- | autoload/rust/debugging.vim | 1 | ||||
-rw-r--r-- | autoload/rust/delimitmate.vim | 48 | ||||
-rw-r--r-- | autoload/rustfmt.vim | 142 |
4 files changed, 226 insertions, 56 deletions
diff --git a/autoload/rust.vim b/autoload/rust.vim index 7e766da1..77c38b7c 100644 --- a/autoload/rust.vim +++ b/autoload/rust.vim @@ -86,7 +86,7 @@ function! s:Run(dict, rustc_args, args) let pwd = a:dict.istemp ? a:dict.tmpdir : '' let output = s:system(pwd, shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)'))) - if output != '' + if output !=# '' echohl WarningMsg echo output echohl None @@ -153,7 +153,7 @@ function! s:Expand(dict, pretty, args) endfunction function! rust#CompleteExpand(lead, line, pos) - if a:line[: a:pos-1] =~ '^RustExpand!\s*\S*$' + if a:line[: a:pos-1] =~# '^RustExpand!\s*\S*$' " first argument and it has a ! let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph=", "everybody_loops"] if !empty(a:lead) @@ -182,7 +182,7 @@ function! s:Emit(dict, type, args) let args = [relpath, '--emit', a:type, '-o', output_path] + a:args let pwd = a:dict.istemp ? a:dict.tmpdir : '' let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)'))) - if output != '' + if output !=# '' echohl WarningMsg echo output echohl None @@ -192,10 +192,10 @@ function! s:Emit(dict, type, args) exe 'silent keepalt read' fnameescape(output_path) 1 d - if a:type == "llvm-ir" + if a:type ==# "llvm-ir" setl filetype=llvm let extension = 'll' - elseif a:type == "asm" + elseif a:type ==# "asm" setl filetype=asm let extension = 's' endif @@ -261,8 +261,8 @@ function! s:WithPath(func, ...) let dict.tmpdir_relpath = filename let dict.path = dict.tmpdir.'/'.filename - let saved.mod = &mod - set nomod + let saved.mod = &modified + set nomodified silent exe 'keepalt write! ' . fnameescape(dict.path) if pathisempty @@ -343,7 +343,7 @@ function! s:ShellTokenize(text) endif let l:state = 3 elseif l:state == 5 " single-quoted - if l:c == "'" + if l:c ==# "'" let l:state = 1 else let l:current .= l:c @@ -361,7 +361,7 @@ function! s:RmDir(path) if empty(a:path) echoerr 'Attempted to delete empty path' return 0 - elseif a:path == '/' || a:path == $HOME + elseif a:path ==# '/' || a:path ==# $HOME echoerr 'Attempted to delete protected path: ' . a:path return 0 endif @@ -414,22 +414,83 @@ function! rust#Play(count, line1, line2, ...) abort call setreg('"', save_regcont, save_regtype) endif - let body = l:rust_playpen_url."?code=".webapi#http#encodeURI(content) + let url = l:rust_playpen_url."?code=".webapi#http#encodeURI(content) - if strlen(body) > 5000 - echohl ErrorMsg | echomsg 'Buffer too large, max 5000 encoded characters ('.strlen(body).')' | echohl None + if strlen(url) > 5000 + echohl ErrorMsg | echomsg 'Buffer too large, max 5000 encoded characters ('.strlen(url).')' | echohl None return endif - let payload = "format=simple&url=".webapi#http#encodeURI(body) + let payload = "format=simple&url=".webapi#http#encodeURI(url) let res = webapi#http#post(l:rust_shortener_url.'create.php', payload, {}) - let url = res.content + if res.status[0] ==# '2' + let url = res.content + endif + let footer = '' if exists('g:rust_clip_command') call system(g:rust_clip_command, url) + if !v:shell_error + let footer = ' (copied to clipboard)' + endif endif + redraw | echomsg 'Done: '.url.footer +endfunction - redraw | echomsg 'Done: '.url +" Run a test under the cursor or all tests {{{1 + +" Finds a test function name under the cursor. Returns empty string when a +" test function is not found. +function! s:SearchTestFunctionNameUnderCursor() abort + let cursor_line = line('.') + + " Find #[test] attribute + if search('#\[test]', 'bcW') is 0 + return '' + endif + + " Move to an opening brace of the test function + let test_func_line = search('^\s*fn\s\+\h\w*\s*(.\+{$', 'eW') + if test_func_line is 0 + return '' + endif + + " Search the end of test function (closing brace) to ensure that the + " cursor position is within function definition + normal! % + if line('.') < cursor_line + return '' + endif + + return matchstr(getline(test_func_line), '^\s*fn\s\+\zs\h\w*') +endfunction + +function! rust#Test(all, options) abort + let pwd = expand('%:p:h') + if findfile('Cargo.toml', pwd . ';') ==# '' + return rust#Run(1, '--test ' . a:options) + endif + + let pwd = shellescape(pwd) + + if a:all + execute '!cd ' . pwd . ' && cargo test ' . a:options + return + endif + + let saved = getpos('.') + try + let func_name = s:SearchTestFunctionNameUnderCursor() + if func_name ==# '' + echohl ErrorMsg + echo 'No test function was found under the cursor. Please add ! to command if you want to run all tests' + echohl None + return + endif + execute '!cd ' . pwd . ' && cargo test ' . func_name . ' ' . a:options + finally + call setpos('.', saved) + endtry endfunction " }}}1 diff --git a/autoload/rust/debugging.vim b/autoload/rust/debugging.vim index 352556d7..ff88e00c 100644 --- a/autoload/rust/debugging.vim +++ b/autoload/rust/debugging.vim @@ -18,6 +18,7 @@ let s:global_variable_list = [ \ 'rust_last_rustc_args', \ 'rust_original_delimitMate_excluded_regions', \ 'rust_playpen_url', + \ 'rust_prev_delimitMate_quotes', \ 'rust_recent_nearest_cargo_tol', \ 'rust_recent_root_cargo_toml', \ 'rust_recommended_style', diff --git a/autoload/rust/delimitmate.vim b/autoload/rust/delimitmate.vim new file mode 100644 index 00000000..e99cc87d --- /dev/null +++ b/autoload/rust/delimitmate.vim @@ -0,0 +1,48 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 + +let s:delimitMate_extra_excluded_regions = ',rustLifetimeCandidate,rustGenericLifetimeCandidate' + +" For this buffer, when delimitMate issues the `User delimitMate_map` +" event in the autocommand system, add the above-defined extra excluded +" regions to delimitMate's state, if they have not already been added. +function! rust#delimitmate#onMap() abort + if &filetype !=# 'rust' + return + endif + + if get(b:, "delimitMate_quotes") + let b:rust_prev_delimitMate_quotes = b:delimitMate_quotes + endif + let b:delimitMate_quotes = "\" `" + + if match(delimitMate#Get("excluded_regions"), + \ s:delimitMate_extra_excluded_regions) == -1 + call delimitMate#Set("excluded_regions", + \delimitMate#Get("excluded_regions").s:delimitMate_extra_excluded_regions) + endif +endfunction + +" For this buffer, when delimitMate issues the `User delimitMate_unmap` +" event in the autocommand system, delete the above-defined extra excluded +" regions from delimitMate's state (the deletion being idempotent and +" having no effect if the extra excluded regions are not present in the +" targeted part of delimitMate's state). +function! rust#delimitmate#onUnmap() abort + if &filetype !=# 'rust' + return + endif + + if get(b:, "rust_prev_delimitMate_quotes") + let b:delimitMate_quotes = b:rust_prev_delimitMate_quotes + endif + + call delimitMate#Set("excluded_regions", substitute( + \ delimitMate#Get("excluded_regions"), + \ '\C\V' . s:delimitMate_extra_excluded_regions, + \ '', 'g')) +endfunction + +" vim: set et sw=4 sts=4 ts=8: + + +endif diff --git a/autoload/rustfmt.vim b/autoload/rustfmt.vim index c0335173..916736c0 100644 --- a/autoload/rustfmt.vim +++ b/autoload/rustfmt.vim @@ -63,6 +63,20 @@ function! s:RustfmtWriteMode() endif endfunction +function! s:RustfmtConfig() + let l:rustfmt_toml = findfile('rustfmt.toml', expand('%:p:h') . ';') + if l:rustfmt_toml !=# '' + return '--config-path '.l:rustfmt_toml + endif + + let l:_rustfmt_toml = findfile('.rustfmt.toml', expand('%:p:h') . ';') + if l:_rustfmt_toml !=# '' + return '--config-path '.l:_rustfmt_toml + endif + + return '' +endfunction + function! s:RustfmtCommandRange(filename, line1, line2) if g:rustfmt_file_lines == 0 echo "--file-lines is not supported in the installed `rustfmt` executable" @@ -71,6 +85,7 @@ function! s:RustfmtCommandRange(filename, line1, line2) let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]} let l:write_mode = s:RustfmtWriteMode() + let l:rustfmt_config = s:RustfmtConfig() " FIXME: When --file-lines gets to be stable, enhance this version range checking " accordingly. @@ -78,34 +93,73 @@ function! s:RustfmtCommandRange(filename, line1, line2) \ (s:rustfmt_unstable_features && (s:rustfmt_version < '1.')) \ ? '--unstable-features' : '' - let l:cmd = printf("%s %s %s %s --file-lines '[%s]' %s", g:rustfmt_command, - \ l:write_mode, g:rustfmt_options, - \ l:unstable_features, json_encode(l:arg), shellescape(a:filename)) + let l:cmd = printf("%s %s %s %s %s --file-lines '[%s]' %s", g:rustfmt_command, + \ l:write_mode, g:rustfmt_options, + \ l:unstable_features, l:rustfmt_config, + \ json_encode(l:arg), shellescape(a:filename)) return l:cmd endfunction -function! s:RustfmtCommand(filename) - let l:write_mode = s:RustfmtWriteMode() - return g:rustfmt_command . " ". l:write_mode . " " . g:rustfmt_options . " " . shellescape(a:filename) +function! s:RustfmtCommand() + if g:rustfmt_emit_files + let l:write_mode = "--emit=stdout" + else + let l:write_mode = "--write-mode=display" + endif + " rustfmt will pick on the right config on its own due to the + " current directory change. + return g:rustfmt_command . " ". l:write_mode . " " . g:rustfmt_options +endfunction + +function! s:DeleteLines(start, end) abort + silent! execute a:start . ',' . a:end . 'delete _' endfunction function! s:RunRustfmt(command, tmpname, fail_silently) mkview! - if exists("*systemlist") - let out = systemlist(a:command) + let l:stderr_tmpname = tempname() + let l:command = a:command . ' 2> ' . l:stderr_tmpname + + if a:tmpname ==# '' + " Rustfmt in stdin/stdout mode + + " chdir to the directory of the file + let l:has_lcd = haslocaldir() + let l:prev_cd = getcwd() + execute 'lchdir! '.expand('%:h') + + let l:buffer = getline(1, '$') + if exists("*systemlist") + silent let out = systemlist(l:command, l:buffer) + else + silent let out = split(system(l:command, l:buffer), '\r\?\n') + endif else - let out = split(system(a:command), '\r\?\n') + if exists("*systemlist") + silent let out = systemlist(l:command) + else + silent let out = split(system(l:command), '\r\?\n') + endif endif - if v:shell_error == 0 || v:shell_error == 3 + let l:stderr = readfile(l:stderr_tmpname) + + call delete(l:stderr_tmpname) + + if v:shell_error == 0 " remove undo point caused via BufWritePre try | silent undojoin | catch | endtry - " take the tmpfile's content, this is better than rename - " because it preserves file modes. - let l:content = readfile(a:tmpname) - 1,$d _ + if a:tmpname ==# '' + let l:content = l:out + else + " take the tmpfile's content, this is better than rename + " because it preserves file modes. + let l:content = readfile(a:tmpname) + endif + + call s:DeleteLines(len(l:content), line('$')) call setline(1, l:content) " only clear location list if it was previously filled to prevent @@ -117,61 +171,69 @@ function! s:RunRustfmt(command, tmpname, fail_silently) endif elseif g:rustfmt_fail_silently == 0 && a:fail_silently == 0 " otherwise get the errors and put them in the location list - let errors = [] + let l:errors = [] - let prev_line = "" - for line in out + let l:prev_line = "" + for l:line in l:stderr " error: expected one of `;` or `as`, found `extern` " --> src/main.rs:2:1 - let tokens = matchlist(line, '^\s-->\s\(.\{-}\):\(\d\+\):\(\d\+\)$') + let tokens = matchlist(l:line, '^\s\+-->\s\(.\{-}\):\(\d\+\):\(\d\+\)$') if !empty(tokens) - call add(errors, {"filename": @%, + call add(l:errors, {"filename": @%, \"lnum": tokens[2], \"col": tokens[3], - \"text": prev_line}) + \"text": l:prev_line}) endif - let prev_line = line + let l:prev_line = l:line endfor - if empty(errors) - % | " Couldn't detect rustfmt error format, output errors - endif - - if !empty(errors) - call setloclist(0, errors, 'r') + if !empty(l:errors) + call setloclist(0, l:errors, 'r') echohl Error | echomsg "rustfmt returned error" | echohl None + else + echo "rust.vim: was not able to parse rustfmt messages. Here is the raw output:" + echo "\n" + for l:line in l:stderr + echo l:line + endfor endif let s:got_fmt_error = 1 lwindow endif - call delete(a:tmpname) + " Restore the current directory if needed + if a:tmpname ==# '' + if l:has_lcd + execute 'lchdir! '.l:prev_cd + else + execute 'chdir! '.l:prev_cd + endif + endif silent! loadview endfunction -function! s:rustfmtSaveToTmp() +function! rustfmt#FormatRange(line1, line2) let l:tmpname = tempname() call writefile(getline(1, '$'), l:tmpname) - return l:tmpname -endfunction - -function! rustfmt#FormatRange(line1, line2) - let l:tmpname = s:rustfmtSaveToTmp() let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2) call s:RunRustfmt(command, l:tmpname, 0) + call delete(l:tmpname) endfunction function! rustfmt#Format() - let l:tmpname = s:rustfmtSaveToTmp() - let command = s:RustfmtCommand(l:tmpname) - call s:RunRustfmt(command, l:tmpname, 0) + call s:RunRustfmt(s:RustfmtCommand(), '', 0) +endfunction + +function! rustfmt#Cmd() + " Mainly for debugging + return s:RustfmtCommand() endfunction function! rustfmt#PreWrite() if rust#GetConfigVar('rustfmt_autosave_if_config_present', 0) - if findfile('rustfmt.toml', '.;') !=# '' + if findfile('rustfmt.toml', '.;') !=# '' || findfile('.rustfmt.toml', '.;') !=# '' let b:rustfmt_autosave = 1 let b:rustfmt_autosave_because_of_config = 1 endif @@ -181,9 +243,7 @@ function! rustfmt#PreWrite() return endif - let l:tmpname = s:rustfmtSaveToTmp() - let command = s:RustfmtCommand(l:tmpname) - call s:RunRustfmt(command, l:tmpname, 1) + call s:RunRustfmt(s:RustfmtCommand(), '', 1) endfunction |