blob: 53f7f8336309bfc27f9742cbc11b6bfb190af440 [file] [log] [blame]
Riley Bruins0a083062024-06-03 20:40:45 +02001" Language: Rust
2" Description: Vim ftplugin for Rust
3" Maintainer: Chris Morgan <me@chrismorgan.info>
4" Last Change: 2024 Mar 17
5" 2024 May 23 by Riley Bruins <ribru17@gmail.com ('commentstring')
Konfekt4ac995b2025-03-31 20:45:26 +02006" 2025 Mar 31 by Vim project (set 'formatprg' option)
Gregory Andersfc935942023-09-12 13:23:38 -05007" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
Bram Moolenaar3c2881d2017-03-21 19:18:29 +01008
9if exists("b:did_ftplugin")
Gregory Andersfc935942023-09-12 13:23:38 -050010 finish
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010011endif
12let b:did_ftplugin = 1
13
Gregory Andersfc935942023-09-12 13:23:38 -050014" vint: -ProhibitAbbreviationOption
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010015let s:save_cpo = &cpo
16set cpo&vim
Gregory Andersfc935942023-09-12 13:23:38 -050017" vint: +ProhibitAbbreviationOption
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010018
Gregory Andersfc935942023-09-12 13:23:38 -050019if get(b:, 'current_compiler', '') ==# ''
20 if strlen(findfile('Cargo.toml', '.;')) > 0
21 compiler cargo
22 else
23 compiler rustc
24 endif
25endif
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010026
27" Variables {{{1
28
29" The rust source code at present seems to typically omit a leader on /*!
30" comments, so we'll use that as our default, but make it easy to switch.
31" This does not affect indentation at all (I tested it with and without
32" leader), merely whether a leader is inserted by default or not.
Gregory Andersfc935942023-09-12 13:23:38 -050033if get(g:, 'rust_bang_comment_leader', 0)
34 " Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why,
35 " but without it, */ gets indented one space even if there were no
36 " leaders. I'm fairly sure that's a Vim bug.
37 setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,://
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010038else
Gregory Andersfc935942023-09-12 13:23:38 -050039 setlocal comments=s0:/*!,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010040endif
Riley Bruins0a083062024-06-03 20:40:45 +020041setlocal commentstring=//\ %s
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010042setlocal formatoptions-=t formatoptions+=croqnl
43" j was only added in 7.3.541, so stop complaints about its nonexistence
44silent! setlocal formatoptions+=j
45
46" smartindent will be overridden by indentexpr if filetype indent is on, but
47" otherwise it's better than nothing.
48setlocal smartindent nocindent
49
Gregory Andersfc935942023-09-12 13:23:38 -050050if get(g:, 'rust_recommended_style', 1)
51 let b:rust_set_style = 1
52 setlocal shiftwidth=4 softtabstop=4 expandtab
53 setlocal textwidth=99
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010054endif
55
Gregory Andersfc935942023-09-12 13:23:38 -050056setlocal include=\\v^\\s*(pub\\s+)?use\\s+\\zs(\\f\|:)+
57setlocal includeexpr=rust#IncludeExpr(v:fname)
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010058
59setlocal suffixesadd=.rs
60
Konfekt4ac995b2025-03-31 20:45:26 +020061if executable(get(g:, 'rustfmt_command', 'rustfmt'))
62 if get(g:, "rustfmt_fail_silently", 0)
63 augroup rust.vim.FailSilently
64 autocmd! * <buffer>
65 autocmd ShellFilterPost <buffer> if v:shell_error | execute 'echom "shell filter returned error " . v:shell_error . ", undoing changes"' | undo | endif
66 augroup END
67 endif
68
69 let &l:formatprg = get(g:, 'rustfmt_command', 'rustfmt') . ' ' .
70 \ get(g:, 'rustfmt_options', '') . ' ' .
71 \ rustfmt#RustfmtConfigOptions()
72endif
73
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010074if exists("g:ftplugin_rust_source_path")
75 let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
76endif
77
78if exists("g:loaded_delimitMate")
Gregory Andersfc935942023-09-12 13:23:38 -050079 if exists("b:delimitMate_excluded_regions")
80 let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
81 endif
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010082
Gregory Andersfc935942023-09-12 13:23:38 -050083 augroup rust.vim.DelimitMate
84 autocmd!
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010085
Gregory Andersfc935942023-09-12 13:23:38 -050086 autocmd User delimitMate_map :call rust#delimitmate#onMap()
87 autocmd User delimitMate_unmap :call rust#delimitmate#onUnmap()
88 augroup END
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010089endif
90
Gregory Andersfc935942023-09-12 13:23:38 -050091" Integration with auto-pairs (https://github.com/jiangmiao/auto-pairs)
92if exists("g:AutoPairsLoaded") && !get(g:, 'rust_keep_autopairs_default', 0)
93 let b:AutoPairs = {'(':')', '[':']', '{':'}','"':'"', '`':'`'}
Bram Moolenaar3c2881d2017-03-21 19:18:29 +010094endif
95
Gregory Andersfc935942023-09-12 13:23:38 -050096if has("folding") && get(g:, 'rust_fold', 0)
97 let b:rust_set_foldmethod=1
98 setlocal foldmethod=syntax
99 if g:rust_fold == 2
100 setlocal foldlevel<
101 else
102 setlocal foldlevel=99
103 endif
104endif
105
106if has('conceal') && get(g:, 'rust_conceal', 0)
107 let b:rust_set_conceallevel=1
108 setlocal conceallevel=2
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100109endif
110
111" Motion Commands {{{1
MyyPoef21bca2024-03-18 20:38:09 +0200112if !exists("g:no_plugin_maps") && !exists("g:no_rust_maps")
113 " Bind motion commands to support hanging indents
114 nnoremap <silent> <buffer> [[ :call rust#Jump('n', 'Back')<CR>
115 nnoremap <silent> <buffer> ]] :call rust#Jump('n', 'Forward')<CR>
116 xnoremap <silent> <buffer> [[ :call rust#Jump('v', 'Back')<CR>
117 xnoremap <silent> <buffer> ]] :call rust#Jump('v', 'Forward')<CR>
118 onoremap <silent> <buffer> [[ :call rust#Jump('o', 'Back')<CR>
119 onoremap <silent> <buffer> ]] :call rust#Jump('o', 'Forward')<CR>
120endif
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100121
122" Commands {{{1
123
124" See |:RustRun| for docs
125command! -nargs=* -complete=file -bang -buffer RustRun call rust#Run(<bang>0, <q-args>)
126
127" See |:RustExpand| for docs
128command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -buffer RustExpand call rust#Expand(<bang>0, <q-args>)
129
130" See |:RustEmitIr| for docs
131command! -nargs=* -buffer RustEmitIr call rust#Emit("llvm-ir", <q-args>)
132
133" See |:RustEmitAsm| for docs
134command! -nargs=* -buffer RustEmitAsm call rust#Emit("asm", <q-args>)
135
136" See |:RustPlay| for docs
Gregory Andersfc935942023-09-12 13:23:38 -0500137command! -range=% -buffer RustPlay :call rust#Play(<count>, <line1>, <line2>, <f-args>)
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100138
139" See |:RustFmt| for docs
Gregory Andersfc935942023-09-12 13:23:38 -0500140command! -bar -buffer RustFmt call rustfmt#Format()
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100141
142" See |:RustFmtRange| for docs
143command! -range -buffer RustFmtRange call rustfmt#FormatRange(<line1>, <line2>)
144
Gregory Andersfc935942023-09-12 13:23:38 -0500145" See |:RustInfo| for docs
146command! -bar -buffer RustInfo call rust#debugging#Info()
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100147
Gregory Andersfc935942023-09-12 13:23:38 -0500148" See |:RustInfoToClipboard| for docs
149command! -bar -buffer RustInfoToClipboard call rust#debugging#InfoToClipboard()
150
151" See |:RustInfoToFile| for docs
152command! -bar -nargs=1 -buffer RustInfoToFile call rust#debugging#InfoToFile(<f-args>)
153
154" See |:RustTest| for docs
155command! -buffer -nargs=* -count -bang RustTest call rust#Test(<q-mods>, <count>, <bang>0, <q-args>)
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100156
157if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args")
Gregory Andersfc935942023-09-12 13:23:38 -0500158 let b:rust_last_rustc_args = []
159 let b:rust_last_args = []
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100160endif
161
162" Cleanup {{{1
163
164let b:undo_ftplugin = "
Konfekt7c3f9af2024-10-05 17:26:46 +0200165 \ compiler make |
Konfekt4ac995b2025-03-31 20:45:26 +0200166 \ setlocal formatoptions< comments< commentstring< include< includeexpr< suffixesadd< formatprg<
Gregory Andersfc935942023-09-12 13:23:38 -0500167 \|if exists('b:rust_set_style')
168 \|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth<
169 \|endif
170 \|if exists('b:rust_original_delimitMate_excluded_regions')
171 \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
172 \|unlet b:rust_original_delimitMate_excluded_regions
173 \|else
174 \|unlet! b:delimitMate_excluded_regions
175 \|endif
176 \|if exists('b:rust_set_foldmethod')
177 \|setlocal foldmethod< foldlevel<
178 \|unlet b:rust_set_foldmethod
179 \|endif
180 \|if exists('b:rust_set_conceallevel')
181 \|setlocal conceallevel<
182 \|unlet b:rust_set_conceallevel
183 \|endif
184 \|unlet! b:rust_last_rustc_args b:rust_last_args
185 \|delcommand -buffer RustRun
186 \|delcommand -buffer RustExpand
187 \|delcommand -buffer RustEmitIr
188 \|delcommand -buffer RustEmitAsm
189 \|delcommand -buffer RustPlay
190 \|delcommand -buffer RustFmt
191 \|delcommand -buffer RustFmtRange
192 \|delcommand -buffer RustInfo
193 \|delcommand -buffer RustInfoToClipboard
194 \|delcommand -buffer RustInfoToFile
195 \|delcommand -buffer RustTest
MyyPoef21bca2024-03-18 20:38:09 +0200196 \|silent! nunmap <buffer> [[
197 \|silent! nunmap <buffer> ]]
198 \|silent! xunmap <buffer> [[
199 \|silent! xunmap <buffer> ]]
200 \|silent! ounmap <buffer> [[
201 \|silent! ounmap <buffer> ]]
Gregory Andersfc935942023-09-12 13:23:38 -0500202 \|setlocal matchpairs-=<:>
203 \|unlet b:match_skip
204 \"
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100205
206" }}}1
207
208" Code formatting on save
Gregory Andersfc935942023-09-12 13:23:38 -0500209augroup rust.vim.PreWrite
210 autocmd!
211 autocmd BufWritePre *.rs silent! call rustfmt#PreWrite()
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100212augroup END
213
Gregory Andersfc935942023-09-12 13:23:38 -0500214setlocal matchpairs+=<:>
215" For matchit.vim (rustArrow stops `Fn() -> X` messing things up)
216let b:match_skip = 's:comment\|string\|rustCharacter\|rustArrow'
217
218command! -buffer -nargs=+ Cargo call cargo#cmd(<q-args>)
219command! -buffer -nargs=* Cbuild call cargo#build(<q-args>)
220command! -buffer -nargs=* Ccheck call cargo#check(<q-args>)
221command! -buffer -nargs=* Cclean call cargo#clean(<q-args>)
222command! -buffer -nargs=* Cdoc call cargo#doc(<q-args>)
223command! -buffer -nargs=+ Cnew call cargo#new(<q-args>)
224command! -buffer -nargs=* Cinit call cargo#init(<q-args>)
225command! -buffer -nargs=* Crun call cargo#run(<q-args>)
226command! -buffer -nargs=* Ctest call cargo#test(<q-args>)
227command! -buffer -nargs=* Cbench call cargo#bench(<q-args>)
228command! -buffer -nargs=* Cupdate call cargo#update(<q-args>)
229command! -buffer -nargs=* Csearch call cargo#search(<q-args>)
230command! -buffer -nargs=* Cpublish call cargo#publish(<q-args>)
231command! -buffer -nargs=* Cinstall call cargo#install(<q-args>)
232command! -buffer -nargs=* Cruntarget call cargo#runtarget(<q-args>)
233
234let b:undo_ftplugin .= '
235 \|delcommand -buffer Cargo
236 \|delcommand -buffer Cbuild
237 \|delcommand -buffer Ccheck
238 \|delcommand -buffer Cclean
239 \|delcommand -buffer Cdoc
240 \|delcommand -buffer Cnew
241 \|delcommand -buffer Cinit
242 \|delcommand -buffer Crun
243 \|delcommand -buffer Ctest
244 \|delcommand -buffer Cbench
245 \|delcommand -buffer Cupdate
246 \|delcommand -buffer Csearch
247 \|delcommand -buffer Cpublish
248 \|delcommand -buffer Cinstall
249 \|delcommand -buffer Cruntarget'
250
251" vint: -ProhibitAbbreviationOption
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100252let &cpo = s:save_cpo
253unlet s:save_cpo
Gregory Andersfc935942023-09-12 13:23:38 -0500254" vint: +ProhibitAbbreviationOption
Bram Moolenaar3c2881d2017-03-21 19:18:29 +0100255
Gregory Andersfc935942023-09-12 13:23:38 -0500256" vim: set et sw=4 sts=4 ts=8: