diff options
Diffstat (limited to 'autoload')
-rw-r--r-- | autoload/cargo.vim | 16 | ||||
-rw-r--r-- | autoload/crystal/indent.vim | 371 | ||||
-rw-r--r-- | autoload/csv.vim | 4 | ||||
-rw-r--r-- | autoload/dart.vim | 12 | ||||
-rw-r--r-- | autoload/ecrystal.vim | 34 | ||||
-rw-r--r-- | autoload/fish.vim | 2 | ||||
-rw-r--r-- | autoload/go/config.vim | 20 | ||||
-rw-r--r-- | autoload/graphql.vim | 2 | ||||
-rw-r--r-- | autoload/jsx_pretty/comment.vim | 16 | ||||
-rw-r--r-- | autoload/rubycomplete.vim | 9 | ||||
-rw-r--r-- | autoload/rust.vim | 33 |
11 files changed, 483 insertions, 36 deletions
diff --git a/autoload/cargo.vim b/autoload/cargo.vim index fefd28de..bd453ac7 100644 --- a/autoload/cargo.vim +++ b/autoload/cargo.vim @@ -102,6 +102,22 @@ function! cargo#bench(args) call cargo#cmd("bench " . a:args) endfunction +function! cargo#update(args) + call cargo#cmd("update " . a:args) +endfunction + +function! cargo#search(args) + call cargo#cmd("search " . a:args) +endfunction + +function! cargo#publish(args) + call cargo#cmd("publish " . a:args) +endfunction + +function! cargo#install(args) + call cargo#cmd("install " . a:args) +endfunction + function! cargo#runtarget(args) let l:filename = expand('%:p') let l:read_manifest = system('cargo read-manifest') diff --git a/autoload/crystal/indent.vim b/autoload/crystal/indent.vim new file mode 100644 index 00000000..dbf4c141 --- /dev/null +++ b/autoload/crystal/indent.vim @@ -0,0 +1,371 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1 + +" Variables {{{1 +" ========= + +" Regex of syntax group names that are strings or characters. +let g:crystal#indent#syng_string = + \ '\<crystal\%(String\|Interpolation\|NoInterpolation\|StringEscape\|CharLiteral\|ASCIICode\)\>' +lockvar g:crystal#indent#syng_string + +" Regex of syntax group names that are strings, characters, symbols, +" regexps, or comments. +let g:crystal#indent#syng_strcom = + \ g:crystal#indent#syng_string.'\|' . + \ '\<crystal\%(Regexp\|RegexpEscape\|Symbol\|Comment\)\>' +lockvar g:crystal#indent#syng_strcom + +" Expression used to check whether we should skip a match with searchpair(). +let g:crystal#indent#skip_expr = + \ 'synIDattr(synID(line("."), col("."), 1), "name") =~# "'.g:crystal#indent#syng_strcom.'"' +lockvar g:crystal#indent#skip_expr + +" Regex for the start of a line: +" start of line + whitespace + optional opening macro delimiter +let g:crystal#indent#sol = '^\s*\zs\%(\\\={%\s*\)\=' +lockvar g:crystal#indent#sol + +" Regex for the end of a line: +" whitespace + optional closing macro delimiter + whitespace + +" optional comment + end of line +let g:crystal#indent#eol = '\s*\%(%}\)\=\ze\s*\%(#.*\)\=$' +lockvar g:crystal#indent#eol + +" Regex that defines the start-match for the 'end' keyword. +" NOTE: This *should* properly match the 'do' only at the end of the +" line +let g:crystal#indent#end_start_regex = + \ g:crystal#indent#sol . + \ '\%(' . + \ '\%(\<\%(private\|protected\)\s\+\)\=' . + \ '\%(\<\%(abstract\s\+\)\=\%(class\|struct\)\>\|\<\%(def\|module\|macro\|lib\|enum\)\>\)' . + \ '\|' . + \ '\<\%(if\|unless\|while\|until\|case\|begin\|for\|union\)\>' . + \ '\)' . + \ '\|' . + \ '.\{-}\zs\<do\s*\%(|.*|\)\='.g:crystal#indent#eol +lockvar g:crystal#indent#end_start_regex + +" Regex that defines the middle-match for the 'end' keyword. +let g:crystal#indent#end_middle_regex = + \ g:crystal#indent#sol . + \ '\<\%(else\|elsif\|rescue\|ensure\|when\)\>' +lockvar g:crystal#indent#end_middle_regex + +" Regex that defines the end-match for the 'end' keyword. +let g:crystal#indent#end_end_regex = + \ g:crystal#indent#sol . + \ '\<end\>' +lockvar g:crystal#indent#end_end_regex + +" Regex used for words that add a level of indent. +let g:crystal#indent#crystal_indent_keywords = + \ g:crystal#indent#end_start_regex . + \ '\|' . + \ g:crystal#indent#end_middle_regex +lockvar g:crystal#indent#crystal_indent_keywords + +" Regex used for words that remove a level of indent. +let g:crystal#indent#crystal_deindent_keywords = + \ g:crystal#indent#end_middle_regex . + \ '\|' . + \ g:crystal#indent#end_end_regex +lockvar g:crystal#indent#crystal_deindent_keywords + +" Regex that defines a type declaration +let g:crystal#indent#crystal_type_declaration = + \ '@\=\h\k*\s\+:\s\+\S.*' +lockvar g:crystal#indent#crystal_type_declaration + +" Regex that defines continuation lines, not including (, {, or [. +let g:crystal#indent#non_bracket_continuation_regex = + \ '\%(' . + \ '[\\.,:/%+\-=~<>|&^]' . + \ '\|' . + \ '\W?' . + \ '\|' . + \ '\<\%(if\|unless\)\>' . + \ '\|' . + \ '\%('.g:crystal#indent#sol.g:crystal#indent#crystal_type_declaration.'\h\k*\)\@<!\*' . + \ '\)' . + \ g:crystal#indent#eol +lockvar g:crystal#indent#non_bracket_continuation_regex + +" Regex that defines bracket continuations +let g:crystal#indent#bracket_continuation_regex = '%\@1<!\%([({[]\)\s*\%(#.*\)\=$' +lockvar g:crystal#indent#bracket_continuation_regex + +" Regex that defines continuation lines. +let g:crystal#indent#continuation_regex = + \ g:crystal#indent#non_bracket_continuation_regex . + \ '\|' . + \ g:crystal#indent#bracket_continuation_regex +lockvar g:crystal#indent#continuation_regex + +" Regex that defines end of bracket continuation followed by another continuation +let g:crystal#indent#bracket_switch_continuation_regex = + \ '^\([^(]\+\zs).\+\)\+'.g:crystal#indent#continuation_regex +lockvar g:crystal#indent#bracket_switch_continuation_regex + +" Regex that defines continuable keywords +let g:crystal#indent#continuable_regex = + \ '\%(^\s*\|[=,*/%+\-|;{]\|<<\|>>\|:\s\)\s*\zs' . + \ '\<\%(if\|for\|while\|until\|unless\):\@!\>' +lockvar g:crystal#indent#continuable_regex + +" Regex that defines the first part of a splat pattern +let g:crystal#indent#splat_regex = '[[,(]\s*\*\s*\%(#.*\)\=$' +lockvar g:crystal#indent#splat_regex + +" Regex that defines blocks. +" +" Note that there's a slight problem with this regex and crystal#indent#continuation_regex. +" Code like this will be matched by both: +" +" method_call do |(a, b)| +" +" The reason is that the pipe matches a hanging "|" operator. +" +let g:crystal#indent#block_regex = + \ '\%(\<do:\@!\>\|%\@1<!{\)\s*\%(|\s*(*\s*\%([*@&]\=\h\w*,\=\s*\)\%(,\s*(*\s*[*@&]\=\h\w*\s*)*\s*\)*|\)\=\s*\%(%}\)\=\s*\%(#.*\)\=$' +lockvar g:crystal#indent#block_regex + +let g:crystal#indent#block_continuation_regex = '^\s*[^])}\t ].*'.g:crystal#indent#block_regex +lockvar g:crystal#indent#block_continuation_regex + +" Regex that describes a leading operator (only a method call's dot for now) +let g:crystal#indent#leading_operator_regex = '^\s*[.]' +lockvar g:crystal#indent#leading_operator_regex + +" Auxiliary Functions {{{1 +" =================== + +" Check if the character at lnum:col is inside a string, comment, or is ascii. +function! crystal#indent#IsInStringOrComment(lnum, col) abort + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~# g:crystal#indent#syng_strcom +endfunction + +" Check if the character at lnum:col is inside a string or character. +function! crystal#indent#IsInString(lnum, col) abort + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~# g:crystal#indent#syng_string +endfunction + +" Check if the character at lnum:col is inside a string or regexp +" delimiter +function! crystal#indent#IsInStringDelimiter(lnum, col) abort + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~# '\<crystal\%(StringDelimiter\|RegexpDelimiter\)\>' +endfunction + +" Find line above 'lnum' that isn't empty, in a comment, or in a string. +function! crystal#indent#PrevNonBlankNonString(lnum) abort + let lnum = prevnonblank(a:lnum) + + while lnum > 0 + let line = getline(lnum) + let start = match(line, '\S') + + if !crystal#indent#IsInStringOrComment(lnum, start + 1) + break + endif + + let lnum = prevnonblank(lnum - 1) + endwhile + + return lnum +endfunction + +" Find line above 'lnum' that started the continuation 'lnum' may be part of. +function! crystal#indent#GetMSL(lnum) abort + " Start on the line we're at and use its indent. + let msl = a:lnum + let msl_body = getline(msl) + let lnum = crystal#indent#PrevNonBlankNonString(a:lnum - 1) + + while lnum > 0 + " If we have a continuation line, or we're in a string, use line as MSL. + " Otherwise, terminate search as we have found our MSL already. + let line = getline(lnum) + + if crystal#indent#Match(msl, g:crystal#indent#leading_operator_regex) + " If the current line starts with a leading operator, keep its indent + " and keep looking for an MSL. + let msl = lnum + elseif crystal#indent#Match(lnum, g:crystal#indent#splat_regex) + " If the above line looks like the "*" of a splat, use the current one's + " indentation. + " + " Example: + " Hash[* + " method_call do + " something + " + return msl + elseif crystal#indent#Match(lnum, g:crystal#indent#non_bracket_continuation_regex) && + \ crystal#indent#Match(msl, g:crystal#indent#non_bracket_continuation_regex) + " If the current line is a non-bracket continuation and so is the + " previous one, keep its indent and continue looking for an MSL. + " + " Example: + " method_call one, + " two, + " three + " + let msl = lnum + elseif crystal#indent#Match(lnum, g:crystal#indent#non_bracket_continuation_regex) && + \ ( + \ crystal#indent#Match(msl, g:crystal#indent#bracket_continuation_regex) || + \ crystal#indent#Match(msl, g:crystal#indent#block_continuation_regex) + \ ) + " If the current line is a bracket continuation or a block-starter, but + " the previous is a non-bracket one, respect the previous' indentation, + " and stop here. + " + " Example: + " method_call one, + " two { + " three + " + return lnum + elseif crystal#indent#Match(lnum, g:crystal#indent#bracket_continuation_regex) && + \ ( + \ crystal#indent#Match(msl, g:crystal#indent#bracket_continuation_regex) || + \ crystal#indent#Match(msl, g:crystal#indent#block_continuation_regex) + \ ) + " If both lines are bracket continuations (the current may also be a + " block-starter), use the current one's and stop here + " + " Example: + " method_call( + " other_method_call( + " foo + return msl + elseif crystal#indent#Match(lnum, g:crystal#indent#block_regex) && + \ !crystal#indent#Match(msl, g:crystal#indent#continuation_regex) && + \ !crystal#indent#Match(msl, g:crystal#indent#block_continuation_regex) + " If the previous line is a block-starter and the current one is + " mostly ordinary, use the current one as the MSL. + " + " Example: + " method_call do + " something + " something_else + return msl + else + let col = match(line, g:crystal#indent#continuation_regex) + 1 + + if (col > 0 && !crystal#indent#IsInStringOrComment(lnum, col)) + \ || crystal#indent#IsInString(lnum, strlen(line)) + let msl = lnum + else + break + endif + endif + + let msl_body = getline(msl) + let lnum = crystal#indent#PrevNonBlankNonString(lnum - 1) + endwhile + + return msl +endfunction + +" Check if line 'lnum' has more opening brackets than closing ones. +function! crystal#indent#ExtraBrackets(lnum) abort + let opening = {'parentheses': [], 'braces': [], 'brackets': []} + let closing = {'parentheses': [], 'braces': [], 'brackets': []} + + let line = getline(a:lnum) + let pos = match(line, '[][(){}]', 0) + + " Save any encountered opening brackets, and remove them once a matching + " closing one has been found. If a closing bracket shows up that doesn't + " close anything, save it for later. + while pos != -1 + if !crystal#indent#IsInStringOrComment(a:lnum, pos + 1) + if line[pos] ==# '(' + call add(opening.parentheses, {'type': '(', 'pos': pos}) + elseif line[pos] ==# ')' + if empty(opening.parentheses) + call add(closing.parentheses, {'type': ')', 'pos': pos}) + else + let opening.parentheses = opening.parentheses[0:-2] + endif + elseif line[pos] ==# '{' + call add(opening.braces, {'type': '{', 'pos': pos}) + elseif line[pos] ==# '}' + if empty(opening.braces) + call add(closing.braces, {'type': '}', 'pos': pos}) + else + let opening.braces = opening.braces[0:-2] + endif + elseif line[pos] ==# '[' + call add(opening.brackets, {'type': '[', 'pos': pos}) + elseif line[pos] ==# ']' + if empty(opening.brackets) + call add(closing.brackets, {'type': ']', 'pos': pos}) + else + let opening.brackets = opening.brackets[0:-2] + endif + endif + endif + + let pos = match(line, '[][(){}]', pos + 1) + endwhile + + " Find the rightmost brackets, since they're the ones that are important in + " both opening and closing cases + let rightmost_opening = {'type': '(', 'pos': -1} + let rightmost_closing = {'type': ')', 'pos': -1} + + for opening in opening.parentheses + opening.braces + opening.brackets + if opening.pos > rightmost_opening.pos + let rightmost_opening = opening + endif + endfor + + for closing in closing.parentheses + closing.braces + closing.brackets + if closing.pos > rightmost_closing.pos + let rightmost_closing = closing + endif + endfor + + return [rightmost_opening, rightmost_closing] +endfunction + +function! crystal#indent#Match(lnum, regex) abort + let regex = '\C'.a:regex + + let line = getline(a:lnum) + let col = match(line, regex) + 1 + + while col && + \ crystal#indent#IsInStringOrComment(a:lnum, col) || + \ crystal#indent#IsInStringDelimiter(a:lnum, col) + let col = match(line, regex, col) + 1 + endwhile + + return col +endfunction + +" Locates the containing class/module/struct/enum/lib's definition line, +" ignoring nested classes along the way. +function! crystal#indent#FindContainingClass() abort + let saved_position = getcurpos() + + while searchpair( + \ g:crystal#indent#end_start_regex, + \ g:crystal#indent#end_middle_regex, + \ g:crystal#indent#end_end_regex, + \ 'bWz', + \ g:crystal#indent#skip_expr) > 0 + if expand('<cword>') =~# '\<\%(class\|module\|struct\|enum\|lib\)\>' + let found_lnum = line('.') + call setpos('.', saved_position) + return found_lnum + endif + endwhile + + call setpos('.', saved_position) + return 0 +endfunction + +endif diff --git a/autoload/csv.vim b/autoload/csv.vim index 5d63a24d..5926c59a 100644 --- a/autoload/csv.vim +++ b/autoload/csv.vim @@ -69,6 +69,10 @@ fu! csv#Init(start, end, ...) "{{{3 else let b:csv_cmt = split(g:csv_comment, '%s') endif + " Make sure it is a list with 2 chars + if b:csv_cmt == [] + let b:csv_cmt = ["", ""] + endif if empty(b:delimiter) && !exists("b:csv_fixed_width") call csv#Warn("No delimiter found. See :h csv-delimiter to set it manually!") diff --git a/autoload/dart.vim b/autoload/dart.vim index 3776da4e..367e54e4 100644 --- a/autoload/dart.vim +++ b/autoload/dart.vim @@ -86,7 +86,7 @@ endfunction " If the path cannot be resolved, or is not a package: uri, returns the " original. function! dart#resolveUri(uri) abort - if a:uri !~ 'package:' + if a:uri !~# 'package:' return a:uri endif let package_name = substitute(a:uri, 'package:\(\w\+\)\/.*', '\1', '') @@ -118,20 +118,20 @@ function! s:PackageMap() abort let lines = readfile(dot_packages) let map = {} for line in lines - if line =~ '\s*#' + if line =~# '\s*#' continue endif let package = substitute(line, ':.*$', '', '') let lib_dir = substitute(line, '^[^:]*:', '', '') - if lib_dir =~ 'file:/' + if lib_dir =~# 'file:/' let lib_dir = substitute(lib_dir, 'file://', '', '') - if lib_dir =~ '/[A-Z]:/' + if lib_dir =~# '/[A-Z]:/' let lib_dir = lib_dir[1:] endif else let lib_dir = resolve(dot_packages_dir.'/'.lib_dir) endif - if lib_dir =~ '/$' + if lib_dir =~# '/$' let lib_dir = lib_dir[:len(lib_dir) - 2] endif let map[package] = lib_dir @@ -141,7 +141,7 @@ endfunction " Toggle whether dartfmt is run on save or not. function! dart#ToggleFormatOnSave() abort - if get(g:, "dart_format_on_save", 0) + if get(g:, 'dart_format_on_save', 0) let g:dart_format_on_save = 0 return endif diff --git a/autoload/ecrystal.vim b/autoload/ecrystal.vim new file mode 100644 index 00000000..1a00b894 --- /dev/null +++ b/autoload/ecrystal.vim @@ -0,0 +1,34 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1 + +let s:ecrystal_extensions = { + \ 'cr': 'crystal', + \ 'yml': 'yaml', + \ 'js': 'javascript', + \ 'txt': 'text', + \ 'md': 'markdown' + \ } + +if exists('g:ecrystal_extensions') + call extend(s:ecrystal_extensions, g:ecrystal_extensions, 'force') +endif + +function! ecrystal#SetSubtype() abort + if exists('b:ecrystal_subtype') + return + endif + + let b:ecrystal_subtype = matchstr(substitute(expand('%:t'), '\c\%(\.ecr\)\+$', '', ''), '\.\zs\w\+\%(\ze+\w\+\)\=$') + + let b:ecrystal_subtype = get(s:ecrystal_extensions, b:ecrystal_subtype, b:ecrystal_subtype) + + if b:ecrystal_subtype ==# '' + let b:ecrystal_subtype = get(g:, 'ecrystal_default_subtype', 'html') + endif + + if b:ecrystal_subtype !=# '' + exec 'setlocal filetype=ecrystal.' . b:ecrystal_subtype + exec 'setlocal syntax=ecrystal.' . b:ecrystal_subtype + endif +endfunction + +endif diff --git a/autoload/fish.vim b/autoload/fish.vim index fcf10bd1..33b03e6b 100644 --- a/autoload/fish.vim +++ b/autoload/fish.vim @@ -54,7 +54,7 @@ function! fish#Complete(findstart, base) let l:completions = \ system('fish -c "complete -C'.shellescape(a:base).'"') let l:cmd = substitute(a:base, '\v\S+$', '', '') - for l:line in split(l:completions, '\n') + for l:line in filter(split(l:completions, '\n'), 'len(v:val)') let l:tokens = split(l:line, '\t') call add(l:results, {'word': l:cmd.l:tokens[0], \'abbr': l:tokens[0], diff --git a/autoload/go/config.vim b/autoload/go/config.vim index 9599ebb0..a2df286f 100644 --- a/autoload/go/config.vim +++ b/autoload/go/config.vim @@ -309,6 +309,10 @@ function! go#config#FmtAutosave() abort return get(g:, "go_fmt_autosave", 1) endfunction +function! go#config#ImportsAutosave() abort + return get(g:, 'go_imports_autosave', 1) +endfunction + function! go#config#SetFmtAutosave(value) abort let g:go_fmt_autosave = a:value endfunction @@ -353,6 +357,10 @@ function! go#config#FmtCommand() abort return get(g:, "go_fmt_command", "gofmt") endfunction +function! go#config#ImportsMode() abort + return get(g:, "go_imports_mode", "goimports") +endfunction + function! go#config#FmtOptions() abort return get(b:, "go_fmt_options", get(g:, "go_fmt_options", {})) endfunction @@ -509,6 +517,10 @@ function! go#config#ReferrersMode() abort return get(g:, 'go_referrers_mode', 'gopls') endfunction +function! go#config#ImplementsMode() abort + return get(g:, 'go_implements_mode', 'guru') +endfunction + function! go#config#GoplsCompleteUnimported() abort return get(g:, 'go_gopls_complete_unimported', v:null) endfunction @@ -536,6 +548,14 @@ function! go#config#GoplsTempModfile() abort return get(g:, 'go_gopls_temp_modfile', v:null) endfunction +function! go#config#GoplsAnalyses() abort + return get(g:, 'go_gopls_analyses', v:null) +endfunction + +function! go#config#GoplsLocal() abort + return get(g:, 'go_gopls_local', v:null) +endfunction + function! go#config#GoplsEnabled() abort return get(g:, 'go_gopls_enabled', 1) endfunction diff --git a/autoload/graphql.vim b/autoload/graphql.vim index 820a83c3..5a0a8c54 100644 --- a/autoload/graphql.vim +++ b/autoload/graphql.vim @@ -1,6 +1,6 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'graphql') == -1 -" Copyright (c) 2016-2019 Jon Parise <jon@indelible.org> +" Copyright (c) 2016-2020 Jon Parise <jon@indelible.org> " " Permission is hereby granted, free of charge, to any person obtaining a copy " of this software and associated documentation files (the "Software"), to diff --git a/autoload/jsx_pretty/comment.vim b/autoload/jsx_pretty/comment.vim index c202ebf4..98eab5e3 100644 --- a/autoload/jsx_pretty/comment.vim +++ b/autoload/jsx_pretty/comment.vim @@ -1,20 +1,20 @@ if !exists('g:polyglot_disabled') || !(index(g:polyglot_disabled, 'typescript') != -1 || index(g:polyglot_disabled, 'typescript') != -1 || index(g:polyglot_disabled, 'jsx') != -1) function! jsx_pretty#comment#update_commentstring(original) - let syn_current = s:syn_name(line('.'), col('.')) - let syn_start = s:syn_name(line('.'), 1) + let line = getline(".") + let col = col('.') + if line !~# '^\s*$' && line[: col - 1] =~# '^\s*$' " skip indent + let col = indent('.') + 1 + endif + let syn_start = s:syn_name(line('.'), col) let save_cursor = getcurpos() if syn_start =~? '^jsx' - let line = getline(".") - let start = len(matchstr(line, '^\s*')) - let syn_name = s:syn_name(line('.'), start + 1) - if line =~ '^\s*//' let &l:commentstring = '// %s' - elseif s:syn_contains(line('.'), col('.'), 'jsxTaggedRegion') + elseif s:syn_contains(line('.'), col, 'jsxTaggedRegion') let &l:commentstring = '<!-- %s -->' - elseif syn_name =~? '^jsxAttrib' + elseif syn_start =~? '^jsxAttrib' let &l:commentstring = '// %s' else let &l:commentstring = '{/* %s */}' diff --git a/autoload/rubycomplete.vim b/autoload/rubycomplete.vim index 98f3b275..54b7e1b8 100644 --- a/autoload/rubycomplete.vim +++ b/autoload/rubycomplete.vim @@ -502,13 +502,8 @@ class VimRubyCompletion return if rails_base == nil $:.push rails_base unless $:.index( rails_base ) - rails_config = rails_base + "config/" - rails_lib = rails_base + "lib/" - $:.push rails_config unless $:.index( rails_config ) - $:.push rails_lib unless $:.index( rails_lib ) - - bootfile = rails_config + "boot.rb" - envfile = rails_config + "environment.rb" + bootfile = rails_base + "config/boot.rb" + envfile = rails_base + "config/environment.rb" if File.exists?( bootfile ) && File.exists?( envfile ) begin require bootfile diff --git a/autoload/rust.vim b/autoload/rust.vim index 8bb2b126..373be590 100644 --- a/autoload/rust.vim +++ b/autoload/rust.vim @@ -501,7 +501,15 @@ function! s:SearchTestFunctionNameUnderCursor() abort " Search the end of test function (closing brace) to ensure that the " cursor position is within function definition - normal! % + if maparg('<Plug>(MatchitNormalForward)') ==# '' + normal! % + else + " Prefer matchit.vim official plugin to native % since the plugin + " provides better behavior than original % (#391) + " To load the plugin, run: + " :packadd matchit + execute 'normal' "\<Plug>(MatchitNormalForward)" + endif if line('.') < cursor_line return '' endif @@ -543,21 +551,20 @@ function! rust#Test(mods, winsize, all, options) abort let saved = getpos('.') try let func_name = s:SearchTestFunctionNameUnderCursor() - if func_name ==# '' - echohl ErrorMsg - echomsg 'No test function was found under the cursor. Please add ! to command if you want to run all tests' - echohl None - return - endif - if a:options ==# '' - execute cmd . 'cargo test --manifest-path' manifest func_name - else - execute cmd . 'cargo test --manifest-path' manifest func_name a:options - endif - return finally call setpos('.', saved) endtry + if func_name ==# '' + echohl ErrorMsg + echomsg 'No test function was found under the cursor. Please add ! to command if you want to run all tests' + echohl None + return + endif + if a:options ==# '' + execute cmd . 'cargo test --manifest-path' manifest func_name + else + execute cmd . 'cargo test --manifest-path' manifest func_name a:options + endif endfunction " }}}1 |