runtime(rust): sync rust runtime files with upstream (#13075)

Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/ftplugin/rust.vim b/runtime/ftplugin/rust.vim
index ececcce..7f1a86e 100644
--- a/runtime/ftplugin/rust.vim
+++ b/runtime/ftplugin/rust.vim
@@ -1,20 +1,26 @@
 " Language:     Rust
 " Description:  Vim ftplugin for Rust
 " Maintainer:   Chris Morgan <me@chrismorgan.info>
-" Maintainer:   Lily Ballard <lily@ballards.net>
-" Last Change:  June 08, 2016
-" For bugs, patches and license go to https://github.com/rust-lang/rust.vim 
+" Last Change:  2023-09-11
+" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
 
 if exists("b:did_ftplugin")
-	finish
+    finish
 endif
 let b:did_ftplugin = 1
 
+" vint: -ProhibitAbbreviationOption
 let s:save_cpo = &cpo
 set cpo&vim
+" vint: +ProhibitAbbreviationOption
 
-augroup rust.vim
-autocmd!
+if get(b:, 'current_compiler', '') ==# ''
+    if strlen(findfile('Cargo.toml', '.;')) > 0
+        compiler cargo
+    else
+        compiler rustc
+    endif
+endif
 
 " Variables {{{1
 
@@ -22,13 +28,13 @@
 " 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 != 0
-	" 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:*/,:///,://!,://
+if get(g:, 'rust_bang_comment_leader', 0)
+    " 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:*/,:///,://!,://
+    setlocal comments=s0:/*!,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
 endif
 setlocal commentstring=//%s
 setlocal formatoptions-=t formatoptions+=croqnl
@@ -39,13 +45,14 @@
 " otherwise it's better than nothing.
 setlocal smartindent nocindent
 
-if !exists("g:rust_recommended_style") || g:rust_recommended_style != 0
-	setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
-	setlocal textwidth=99
+if get(g:, 'rust_recommended_style', 1)
+    let b:rust_set_style = 1
+    setlocal 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')
+setlocal include=\\v^\\s*(pub\\s+)?use\\s+\\zs(\\f\|:)+
+setlocal includeexpr=rust#IncludeExpr(v:fname)
 
 setlocal suffixesadd=.rs
 
@@ -54,51 +61,36 @@
 endif
 
 if exists("g:loaded_delimitMate")
-	if exists("b:delimitMate_excluded_regions")
-		let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
-	endif
+    if exists("b:delimitMate_excluded_regions")
+        let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
+    endif
 
-	let s:delimitMate_extra_excluded_regions = ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
+    augroup rust.vim.DelimitMate
+        autocmd!
 
-	" 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.
-	autocmd User <buffer>
-		\ if expand('<afile>') ==# 'delimitMate_map' && match(
-		\     delimitMate#Get("excluded_regions"),
-		\     s:delimitMate_extra_excluded_regions) == -1
-		\|  let b:delimitMate_excluded_regions =
-		\       delimitMate#Get("excluded_regions")
-		\       . s:delimitMate_extra_excluded_regions
-		\|endif
-
-	" 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).
-	autocmd User <buffer>
-		\ if expand('<afile>') ==# 'delimitMate_unmap'
-		\|  let b:delimitMate_excluded_regions = substitute(
-		\       delimitMate#Get("excluded_regions"),
-		\       '\C\V' . s:delimitMate_extra_excluded_regions,
-		\       '', 'g')
-		\|endif
+        autocmd User delimitMate_map   :call rust#delimitmate#onMap()
+        autocmd User delimitMate_unmap :call rust#delimitmate#onUnmap()
+    augroup END
 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
+" Integration with auto-pairs (https://github.com/jiangmiao/auto-pairs)
+if exists("g:AutoPairsLoaded") && !get(g:, 'rust_keep_autopairs_default', 0)
+    let b:AutoPairs = {'(':')', '[':']', '{':'}','"':'"', '`':'`'}
 endif
 
-if has('conceal') && exists('g:rust_conceal') && g:rust_conceal != 0
-	let b:rust_set_conceallevel=1
-	setlocal conceallevel=2
+if has("folding") && get(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') && get(g:, 'rust_conceal', 0)
+    let b:rust_set_conceallevel=1
+    setlocal conceallevel=2
 endif
 
 " Motion Commands {{{1
@@ -126,72 +118,122 @@
 command! -nargs=* -buffer RustEmitAsm call rust#Emit("asm", <q-args>)
 
 " See |:RustPlay| for docs
-command! -range=% RustPlay :call rust#Play(<count>, <line1>, <line2>, <f-args>)
+command! -range=% -buffer RustPlay :call rust#Play(<count>, <line1>, <line2>, <f-args>)
 
 " See |:RustFmt| for docs
-command! -buffer RustFmt call rustfmt#Format()
+command! -bar -buffer RustFmt call rustfmt#Format()
 
 " See |:RustFmtRange| for docs
 command! -range -buffer RustFmtRange call rustfmt#FormatRange(<line1>, <line2>)
 
-" Mappings {{{1
+" See |:RustInfo| for docs
+command! -bar -buffer RustInfo call rust#debugging#Info()
 
-" Bind ⌘R in MacVim to :RustRun
-nnoremap <silent> <buffer> <D-r> :RustRun<CR>
-" Bind ⌘⇧R in MacVim to :RustRun! pre-filled with the last args
-nnoremap <buffer> <D-R> :RustRun! <C-r>=join(b:rust_last_rustc_args)<CR><C-\>erust#AppendCmdLine(' -- ' . join(b:rust_last_args))<CR>
+" See |:RustInfoToClipboard| for docs
+command! -bar -buffer RustInfoToClipboard call rust#debugging#InfoToClipboard()
+
+" See |:RustInfoToFile| for docs
+command! -bar -nargs=1 -buffer RustInfoToFile call rust#debugging#InfoToFile(<f-args>)
+
+" See |:RustTest| for docs
+command! -buffer -nargs=* -count -bang RustTest call rust#Test(<q-mods>, <count>, <bang>0, <q-args>)
 
 if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args")
-	let b:rust_last_rustc_args = []
-	let 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
-		\|delcommand RustPlay
-		\|nunmap <buffer> <D-r>
-		\|nunmap <buffer> <D-R>
-		\|nunmap <buffer> [[
-		\|nunmap <buffer> ]]
-		\|xunmap <buffer> [[
-		\|xunmap <buffer> ]]
-		\|ounmap <buffer> [[
-		\|ounmap <buffer> ]]
-		\|set matchpairs-=<:>
-		\"
+            \ setlocal formatoptions< comments< commentstring< include< includeexpr< suffixesadd<
+            \|if exists('b:rust_set_style')
+                \|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth<
+                \|endif
+                \|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 -buffer RustRun
+                                \|delcommand -buffer RustExpand
+                                \|delcommand -buffer RustEmitIr
+                                \|delcommand -buffer RustEmitAsm
+                                \|delcommand -buffer RustPlay
+                                \|delcommand -buffer RustFmt
+                                \|delcommand -buffer RustFmtRange
+                                \|delcommand -buffer RustInfo
+                                \|delcommand -buffer RustInfoToClipboard
+                                \|delcommand -buffer RustInfoToFile
+                                \|delcommand -buffer RustTest
+                                \|nunmap <buffer> [[
+                                \|nunmap <buffer> ]]
+                                \|xunmap <buffer> [[
+                                \|xunmap <buffer> ]]
+                                \|ounmap <buffer> [[
+                                \|ounmap <buffer> ]]
+                                \|setlocal matchpairs-=<:>
+                                \|unlet b:match_skip
+                                \"
 
 " }}}1
 
 " Code formatting on save
-if get(g:, "rustfmt_autosave", 0)
-	autocmd BufWritePre *.rs silent! call rustfmt#Format()
-endif
-
+augroup rust.vim.PreWrite
+    autocmd!
+    autocmd BufWritePre *.rs silent! call rustfmt#PreWrite()
 augroup END
 
+setlocal matchpairs+=<:>
+" For matchit.vim (rustArrow stops `Fn() -> X` messing things up)
+let b:match_skip = 's:comment\|string\|rustCharacter\|rustArrow'
+
+command! -buffer -nargs=+ Cargo call cargo#cmd(<q-args>)
+command! -buffer -nargs=* Cbuild call cargo#build(<q-args>)
+command! -buffer -nargs=* Ccheck call cargo#check(<q-args>)
+command! -buffer -nargs=* Cclean call cargo#clean(<q-args>)
+command! -buffer -nargs=* Cdoc call cargo#doc(<q-args>)
+command! -buffer -nargs=+ Cnew call cargo#new(<q-args>)
+command! -buffer -nargs=* Cinit call cargo#init(<q-args>)
+command! -buffer -nargs=* Crun call cargo#run(<q-args>)
+command! -buffer -nargs=* Ctest call cargo#test(<q-args>)
+command! -buffer -nargs=* Cbench call cargo#bench(<q-args>)
+command! -buffer -nargs=* Cupdate call cargo#update(<q-args>)
+command! -buffer -nargs=* Csearch  call cargo#search(<q-args>)
+command! -buffer -nargs=* Cpublish call cargo#publish(<q-args>)
+command! -buffer -nargs=* Cinstall call cargo#install(<q-args>)
+command! -buffer -nargs=* Cruntarget call cargo#runtarget(<q-args>)
+
+let b:undo_ftplugin .= '
+            \|delcommand -buffer Cargo
+            \|delcommand -buffer Cbuild
+            \|delcommand -buffer Ccheck
+            \|delcommand -buffer Cclean
+            \|delcommand -buffer Cdoc
+            \|delcommand -buffer Cnew
+            \|delcommand -buffer Cinit
+            \|delcommand -buffer Crun
+            \|delcommand -buffer Ctest
+            \|delcommand -buffer Cbench
+            \|delcommand -buffer Cupdate
+            \|delcommand -buffer Csearch
+            \|delcommand -buffer Cpublish
+            \|delcommand -buffer Cinstall
+            \|delcommand -buffer Cruntarget'
+
+" vint: -ProhibitAbbreviationOption
 let &cpo = s:save_cpo
 unlet s:save_cpo
+" vint: +ProhibitAbbreviationOption
 
-" vim: set noet sw=8 ts=8:
+" vim: set et sw=4 sts=4 ts=8: