rust.vim 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. " Language: Rust
  2. " Description: Vim ftplugin for Rust
  3. " Maintainer: Chris Morgan <me@chrismorgan.info>
  4. " Maintainer: Kevin Ballard <kevin@sb.org>
  5. " Last Change: June 08, 2016
  6. " For bugs, patches and license go to https://github.com/rust-lang/rust.vim
  7. if exists("b:did_ftplugin")
  8. finish
  9. endif
  10. let b:did_ftplugin = 1
  11. let s:save_cpo = &cpo
  12. set cpo&vim
  13. augroup rust.vim
  14. autocmd!
  15. " Variables {{{1
  16. " The rust source code at present seems to typically omit a leader on /*!
  17. " comments, so we'll use that as our default, but make it easy to switch.
  18. " This does not affect indentation at all (I tested it with and without
  19. " leader), merely whether a leader is inserted by default or not.
  20. if exists("g:rust_bang_comment_leader") && g:rust_bang_comment_leader != 0
  21. " Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why,
  22. " but without it, */ gets indented one space even if there were no
  23. " leaders. I'm fairly sure that's a Vim bug.
  24. setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,://
  25. else
  26. setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
  27. endif
  28. setlocal commentstring=//%s
  29. setlocal formatoptions-=t formatoptions+=croqnl
  30. " j was only added in 7.3.541, so stop complaints about its nonexistence
  31. silent! setlocal formatoptions+=j
  32. " smartindent will be overridden by indentexpr if filetype indent is on, but
  33. " otherwise it's better than nothing.
  34. setlocal smartindent nocindent
  35. if !exists("g:rust_recommended_style") || g:rust_recommended_style != 0
  36. setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
  37. setlocal textwidth=99
  38. endif
  39. " This includeexpr isn't perfect, but it's a good start
  40. setlocal includeexpr=substitute(v:fname,'::','/','g')
  41. setlocal suffixesadd=.rs
  42. if exists("g:ftplugin_rust_source_path")
  43. let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
  44. endif
  45. if exists("g:loaded_delimitMate")
  46. if exists("b:delimitMate_excluded_regions")
  47. let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
  48. endif
  49. let s:delimitMate_extra_excluded_regions = ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
  50. " For this buffer, when delimitMate issues the `User delimitMate_map`
  51. " event in the autocommand system, add the above-defined extra excluded
  52. " regions to delimitMate's state, if they have not already been added.
  53. autocmd User <buffer>
  54. \ if expand('<afile>') ==# 'delimitMate_map' && match(
  55. \ delimitMate#Get("excluded_regions"),
  56. \ s:delimitMate_extra_excluded_regions) == -1
  57. \| let b:delimitMate_excluded_regions =
  58. \ delimitMate#Get("excluded_regions")
  59. \ . s:delimitMate_extra_excluded_regions
  60. \|endif
  61. " For this buffer, when delimitMate issues the `User delimitMate_unmap`
  62. " event in the autocommand system, delete the above-defined extra excluded
  63. " regions from delimitMate's state (the deletion being idempotent and
  64. " having no effect if the extra excluded regions are not present in the
  65. " targeted part of delimitMate's state).
  66. autocmd User <buffer>
  67. \ if expand('<afile>') ==# 'delimitMate_unmap'
  68. \| let b:delimitMate_excluded_regions = substitute(
  69. \ delimitMate#Get("excluded_regions"),
  70. \ '\C\V' . s:delimitMate_extra_excluded_regions,
  71. \ '', 'g')
  72. \|endif
  73. endif
  74. if has("folding") && exists('g:rust_fold') && g:rust_fold != 0
  75. let b:rust_set_foldmethod=1
  76. setlocal foldmethod=syntax
  77. if g:rust_fold == 2
  78. setlocal foldlevel<
  79. else
  80. setlocal foldlevel=99
  81. endif
  82. endif
  83. if has('conceal') && exists('g:rust_conceal') && g:rust_conceal != 0
  84. let b:rust_set_conceallevel=1
  85. setlocal conceallevel=2
  86. endif
  87. " Motion Commands {{{1
  88. " Bind motion commands to support hanging indents
  89. nnoremap <silent> <buffer> [[ :call rust#Jump('n', 'Back')<CR>
  90. nnoremap <silent> <buffer> ]] :call rust#Jump('n', 'Forward')<CR>
  91. xnoremap <silent> <buffer> [[ :call rust#Jump('v', 'Back')<CR>
  92. xnoremap <silent> <buffer> ]] :call rust#Jump('v', 'Forward')<CR>
  93. onoremap <silent> <buffer> [[ :call rust#Jump('o', 'Back')<CR>
  94. onoremap <silent> <buffer> ]] :call rust#Jump('o', 'Forward')<CR>
  95. " Commands {{{1
  96. " See |:RustRun| for docs
  97. command! -nargs=* -complete=file -bang -buffer RustRun call rust#Run(<bang>0, <q-args>)
  98. " See |:RustExpand| for docs
  99. command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -buffer RustExpand call rust#Expand(<bang>0, <q-args>)
  100. " See |:RustEmitIr| for docs
  101. command! -nargs=* -buffer RustEmitIr call rust#Emit("llvm-ir", <q-args>)
  102. " See |:RustEmitAsm| for docs
  103. command! -nargs=* -buffer RustEmitAsm call rust#Emit("asm", <q-args>)
  104. " See |:RustPlay| for docs
  105. command! -range=% RustPlay :call rust#Play(<count>, <line1>, <line2>, <f-args>)
  106. " See |:RustFmt| for docs
  107. command! -buffer RustFmt call rustfmt#Format()
  108. " See |:RustFmtRange| for docs
  109. command! -range -buffer RustFmtRange call rustfmt#FormatRange(<line1>, <line2>)
  110. " Mappings {{{1
  111. " Bind ⌘R in MacVim to :RustRun
  112. nnoremap <silent> <buffer> <D-r> :RustRun<CR>
  113. " Bind ⌘⇧R in MacVim to :RustRun! pre-filled with the last args
  114. nnoremap <buffer> <D-R> :RustRun! <C-r>=join(b:rust_last_rustc_args)<CR><C-\>erust#AppendCmdLine(' -- ' . join(b:rust_last_args))<CR>
  115. if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args")
  116. let b:rust_last_rustc_args = []
  117. let b:rust_last_args = []
  118. endif
  119. " Cleanup {{{1
  120. let b:undo_ftplugin = "
  121. \ setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd<
  122. \|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth<
  123. \|if exists('b:rust_original_delimitMate_excluded_regions')
  124. \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
  125. \|unlet b:rust_original_delimitMate_excluded_regions
  126. \|else
  127. \|unlet! b:delimitMate_excluded_regions
  128. \|endif
  129. \|if exists('b:rust_set_foldmethod')
  130. \|setlocal foldmethod< foldlevel<
  131. \|unlet b:rust_set_foldmethod
  132. \|endif
  133. \|if exists('b:rust_set_conceallevel')
  134. \|setlocal conceallevel<
  135. \|unlet b:rust_set_conceallevel
  136. \|endif
  137. \|unlet! b:rust_last_rustc_args b:rust_last_args
  138. \|delcommand RustRun
  139. \|delcommand RustExpand
  140. \|delcommand RustEmitIr
  141. \|delcommand RustEmitAsm
  142. \|delcommand RustPlay
  143. \|nunmap <buffer> <D-r>
  144. \|nunmap <buffer> <D-R>
  145. \|nunmap <buffer> [[
  146. \|nunmap <buffer> ]]
  147. \|xunmap <buffer> [[
  148. \|xunmap <buffer> ]]
  149. \|ounmap <buffer> [[
  150. \|ounmap <buffer> ]]
  151. \|set matchpairs-=<:>
  152. \"
  153. " }}}1
  154. " Code formatting on save
  155. if get(g:, "rustfmt_autosave", 0)
  156. autocmd BufWritePre *.rs silent! call rustfmt#Format()
  157. endif
  158. augroup END
  159. let &cpo = s:save_cpo
  160. unlet s:save_cpo
  161. " vim: set noet sw=8 ts=8: