mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
vim-patch:3c2881dc1195
Update runtime files. Add Rust support.
3c2881dc11
This commit is contained in:
parent
dc92901094
commit
0312fc2ddb
415
runtime/autoload/rust.vim
Normal file
415
runtime/autoload/rust.vim
Normal file
@ -0,0 +1,415 @@
|
||||
" Author: Kevin Ballard
|
||||
" Description: Helper functions for Rust commands/mappings
|
||||
" Last Modified: May 27, 2014
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
" Jump {{{1
|
||||
|
||||
function! rust#Jump(mode, function) range
|
||||
let cnt = v:count1
|
||||
normal! m'
|
||||
if a:mode ==# 'v'
|
||||
norm! gv
|
||||
endif
|
||||
let foldenable = &foldenable
|
||||
set nofoldenable
|
||||
while cnt > 0
|
||||
execute "call <SID>Jump_" . a:function . "()"
|
||||
let cnt = cnt - 1
|
||||
endwhile
|
||||
let &foldenable = foldenable
|
||||
endfunction
|
||||
|
||||
function! s:Jump_Back()
|
||||
call search('{', 'b')
|
||||
keepjumps normal! w99[{
|
||||
endfunction
|
||||
|
||||
function! s:Jump_Forward()
|
||||
normal! j0
|
||||
call search('{', 'b')
|
||||
keepjumps normal! w99[{%
|
||||
call search('{')
|
||||
endfunction
|
||||
|
||||
" Run {{{1
|
||||
|
||||
function! rust#Run(bang, args)
|
||||
let args = s:ShellTokenize(a:args)
|
||||
if a:bang
|
||||
let idx = index(l:args, '--')
|
||||
if idx != -1
|
||||
let rustc_args = idx == 0 ? [] : l:args[:idx-1]
|
||||
let args = l:args[idx+1:]
|
||||
else
|
||||
let rustc_args = l:args
|
||||
let args = []
|
||||
endif
|
||||
else
|
||||
let rustc_args = []
|
||||
endif
|
||||
|
||||
let b:rust_last_rustc_args = l:rustc_args
|
||||
let b:rust_last_args = l:args
|
||||
|
||||
call s:WithPath(function("s:Run"), rustc_args, args)
|
||||
endfunction
|
||||
|
||||
function! s:Run(dict, rustc_args, args)
|
||||
let exepath = a:dict.tmpdir.'/'.fnamemodify(a:dict.path, ':t:r')
|
||||
if has('win32')
|
||||
let exepath .= '.exe'
|
||||
endif
|
||||
|
||||
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
|
||||
let rustc_args = [relpath, '-o', exepath] + a:rustc_args
|
||||
|
||||
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
|
||||
|
||||
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
|
||||
let output = s:system(pwd, shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
|
||||
if output != ''
|
||||
echohl WarningMsg
|
||||
echo output
|
||||
echohl None
|
||||
endif
|
||||
if !v:shell_error
|
||||
exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Expand {{{1
|
||||
|
||||
function! rust#Expand(bang, args)
|
||||
let args = s:ShellTokenize(a:args)
|
||||
if a:bang && !empty(l:args)
|
||||
let pretty = remove(l:args, 0)
|
||||
else
|
||||
let pretty = "expanded"
|
||||
endif
|
||||
call s:WithPath(function("s:Expand"), pretty, args)
|
||||
endfunction
|
||||
|
||||
function! s:Expand(dict, pretty, args)
|
||||
try
|
||||
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
|
||||
|
||||
if a:pretty =~? '^\%(everybody_loops$\|flowgraph=\)'
|
||||
let flag = '--xpretty'
|
||||
else
|
||||
let flag = '--pretty'
|
||||
endif
|
||||
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
|
||||
let args = [relpath, '-Z', 'unstable-options', l:flag, a:pretty] + a:args
|
||||
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
|
||||
let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
|
||||
if v:shell_error
|
||||
echohl WarningMsg
|
||||
echo output
|
||||
echohl None
|
||||
else
|
||||
new
|
||||
silent put =output
|
||||
1
|
||||
d
|
||||
setl filetype=rust
|
||||
setl buftype=nofile
|
||||
setl bufhidden=hide
|
||||
setl noswapfile
|
||||
" give the buffer a nice name
|
||||
let suffix = 1
|
||||
let basename = fnamemodify(a:dict.path, ':t:r')
|
||||
while 1
|
||||
let bufname = basename
|
||||
if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
|
||||
let bufname .= '.pretty.rs'
|
||||
if bufexists(bufname)
|
||||
let suffix += 1
|
||||
continue
|
||||
endif
|
||||
exe 'silent noautocmd keepalt file' fnameescape(bufname)
|
||||
break
|
||||
endwhile
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! rust#CompleteExpand(lead, line, pos)
|
||||
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)
|
||||
call filter(list, "v:val[:len(a:lead)-1] == a:lead")
|
||||
endif
|
||||
return list
|
||||
endif
|
||||
|
||||
return glob(escape(a:lead, "*?[") . '*', 0, 1)
|
||||
endfunction
|
||||
|
||||
" Emit {{{1
|
||||
|
||||
function! rust#Emit(type, args)
|
||||
let args = s:ShellTokenize(a:args)
|
||||
call s:WithPath(function("s:Emit"), a:type, args)
|
||||
endfunction
|
||||
|
||||
function! s:Emit(dict, type, args)
|
||||
try
|
||||
let output_path = a:dict.tmpdir.'/output'
|
||||
|
||||
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
|
||||
|
||||
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
|
||||
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 != ''
|
||||
echohl WarningMsg
|
||||
echo output
|
||||
echohl None
|
||||
endif
|
||||
if !v:shell_error
|
||||
new
|
||||
exe 'silent keepalt read' fnameescape(output_path)
|
||||
1
|
||||
d
|
||||
if a:type == "llvm-ir"
|
||||
setl filetype=llvm
|
||||
let extension = 'll'
|
||||
elseif a:type == "asm"
|
||||
setl filetype=asm
|
||||
let extension = 's'
|
||||
endif
|
||||
setl buftype=nofile
|
||||
setl bufhidden=hide
|
||||
setl noswapfile
|
||||
if exists('l:extension')
|
||||
" give the buffer a nice name
|
||||
let suffix = 1
|
||||
let basename = fnamemodify(a:dict.path, ':t:r')
|
||||
while 1
|
||||
let bufname = basename
|
||||
if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
|
||||
let bufname .= '.'.extension
|
||||
if bufexists(bufname)
|
||||
let suffix += 1
|
||||
continue
|
||||
endif
|
||||
exe 'silent noautocmd keepalt file' fnameescape(bufname)
|
||||
break
|
||||
endwhile
|
||||
endif
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Utility functions {{{1
|
||||
|
||||
" Invokes func(dict, ...)
|
||||
" Where {dict} is a dictionary with the following keys:
|
||||
" 'path' - The path to the file
|
||||
" 'tmpdir' - The path to a temporary directory that will be deleted when the
|
||||
" function returns.
|
||||
" 'istemp' - 1 if the path is a file inside of {dict.tmpdir} or 0 otherwise.
|
||||
" If {istemp} is 1 then an additional key is provided:
|
||||
" 'tmpdir_relpath' - The {path} relative to the {tmpdir}.
|
||||
"
|
||||
" {dict.path} may be a path to a file inside of {dict.tmpdir} or it may be the
|
||||
" existing path of the current buffer. If the path is inside of {dict.tmpdir}
|
||||
" then it is guaranteed to have a '.rs' extension.
|
||||
function! s:WithPath(func, ...)
|
||||
let buf = bufnr('')
|
||||
let saved = {}
|
||||
let dict = {}
|
||||
try
|
||||
let saved.write = &write
|
||||
set write
|
||||
let dict.path = expand('%')
|
||||
let pathisempty = empty(dict.path)
|
||||
|
||||
" Always create a tmpdir in case the wrapped command wants it
|
||||
let dict.tmpdir = tempname()
|
||||
call mkdir(dict.tmpdir)
|
||||
|
||||
if pathisempty || !saved.write
|
||||
let dict.istemp = 1
|
||||
" if we're doing this because of nowrite, preserve the filename
|
||||
if !pathisempty
|
||||
let filename = expand('%:t:r').".rs"
|
||||
else
|
||||
let filename = 'unnamed.rs'
|
||||
endif
|
||||
let dict.tmpdir_relpath = filename
|
||||
let dict.path = dict.tmpdir.'/'.filename
|
||||
|
||||
let saved.mod = &mod
|
||||
set nomod
|
||||
|
||||
silent exe 'keepalt write! ' . fnameescape(dict.path)
|
||||
if pathisempty
|
||||
silent keepalt 0file
|
||||
endif
|
||||
else
|
||||
let dict.istemp = 0
|
||||
update
|
||||
endif
|
||||
|
||||
call call(a:func, [dict] + a:000)
|
||||
finally
|
||||
if bufexists(buf)
|
||||
for [opt, value] in items(saved)
|
||||
silent call setbufvar(buf, '&'.opt, value)
|
||||
unlet value " avoid variable type mismatches
|
||||
endfor
|
||||
endif
|
||||
if has_key(dict, 'tmpdir') | silent call s:RmDir(dict.tmpdir) | endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! rust#AppendCmdLine(text)
|
||||
call setcmdpos(getcmdpos())
|
||||
let cmd = getcmdline() . a:text
|
||||
return cmd
|
||||
endfunction
|
||||
|
||||
" Tokenize the string according to sh parsing rules
|
||||
function! s:ShellTokenize(text)
|
||||
" states:
|
||||
" 0: start of word
|
||||
" 1: unquoted
|
||||
" 2: unquoted backslash
|
||||
" 3: double-quote
|
||||
" 4: double-quoted backslash
|
||||
" 5: single-quote
|
||||
let l:state = 0
|
||||
let l:current = ''
|
||||
let l:args = []
|
||||
for c in split(a:text, '\zs')
|
||||
if l:state == 0 || l:state == 1 " unquoted
|
||||
if l:c ==# ' '
|
||||
if l:state == 0 | continue | endif
|
||||
call add(l:args, l:current)
|
||||
let l:current = ''
|
||||
let l:state = 0
|
||||
elseif l:c ==# '\'
|
||||
let l:state = 2
|
||||
elseif l:c ==# '"'
|
||||
let l:state = 3
|
||||
elseif l:c ==# "'"
|
||||
let l:state = 5
|
||||
else
|
||||
let l:current .= l:c
|
||||
let l:state = 1
|
||||
endif
|
||||
elseif l:state == 2 " unquoted backslash
|
||||
if l:c !=# "\n" " can it even be \n?
|
||||
let l:current .= l:c
|
||||
endif
|
||||
let l:state = 1
|
||||
elseif l:state == 3 " double-quote
|
||||
if l:c ==# '\'
|
||||
let l:state = 4
|
||||
elseif l:c ==# '"'
|
||||
let l:state = 1
|
||||
else
|
||||
let l:current .= l:c
|
||||
endif
|
||||
elseif l:state == 4 " double-quoted backslash
|
||||
if stridx('$`"\', l:c) >= 0
|
||||
let l:current .= l:c
|
||||
elseif l:c ==# "\n" " is this even possible?
|
||||
" skip it
|
||||
else
|
||||
let l:current .= '\'.l:c
|
||||
endif
|
||||
let l:state = 3
|
||||
elseif l:state == 5 " single-quoted
|
||||
if l:c == "'"
|
||||
let l:state = 1
|
||||
else
|
||||
let l:current .= l:c
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if l:state != 0
|
||||
call add(l:args, l:current)
|
||||
endif
|
||||
return l:args
|
||||
endfunction
|
||||
|
||||
function! s:RmDir(path)
|
||||
" sanity check; make sure it's not empty, /, or $HOME
|
||||
if empty(a:path)
|
||||
echoerr 'Attempted to delete empty path'
|
||||
return 0
|
||||
elseif a:path == '/' || a:path == $HOME
|
||||
echoerr 'Attempted to delete protected path: ' . a:path
|
||||
return 0
|
||||
endif
|
||||
return system("rm -rf " . shellescape(a:path))
|
||||
endfunction
|
||||
|
||||
" Executes {cmd} with the cwd set to {pwd}, without changing Vim's cwd.
|
||||
" If {pwd} is the empty string then it doesn't change the cwd.
|
||||
function! s:system(pwd, cmd)
|
||||
let cmd = a:cmd
|
||||
if !empty(a:pwd)
|
||||
let cmd = 'cd ' . shellescape(a:pwd) . ' && ' . cmd
|
||||
endif
|
||||
return system(cmd)
|
||||
endfunction
|
||||
|
||||
" Playpen Support {{{1
|
||||
" Parts of gist.vim by Yasuhiro Matsumoto <mattn.jp@gmail.com> reused
|
||||
" gist.vim available under the BSD license, available at
|
||||
" http://github.com/mattn/gist-vim
|
||||
function! s:has_webapi()
|
||||
if !exists("*webapi#http#post")
|
||||
try
|
||||
call webapi#http#post()
|
||||
catch
|
||||
endtry
|
||||
endif
|
||||
return exists("*webapi#http#post")
|
||||
endfunction
|
||||
|
||||
function! rust#Play(count, line1, line2, ...) abort
|
||||
redraw
|
||||
|
||||
let l:rust_playpen_url = get(g:, 'rust_playpen_url', 'https://play.rust-lang.org/')
|
||||
let l:rust_shortener_url = get(g:, 'rust_shortener_url', 'https://is.gd/')
|
||||
|
||||
if !s:has_webapi()
|
||||
echohl ErrorMsg | echomsg ':RustPlay depends on webapi.vim (https://github.com/mattn/webapi-vim)' | echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
let bufname = bufname('%')
|
||||
if a:count < 1
|
||||
let content = join(getline(a:line1, a:line2), "\n")
|
||||
else
|
||||
let save_regcont = @"
|
||||
let save_regtype = getregtype('"')
|
||||
silent! normal! gvy
|
||||
let content = @"
|
||||
call setreg('"', save_regcont, save_regtype)
|
||||
endif
|
||||
|
||||
let body = 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
|
||||
return
|
||||
endif
|
||||
|
||||
let payload = "format=simple&url=".webapi#http#encodeURI(body)
|
||||
let res = webapi#http#post(l:rust_shortener_url.'create.php', payload, {})
|
||||
let url = res.content
|
||||
|
||||
redraw | echomsg 'Done: '.url
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" vim: set noet sw=8 ts=8:
|
107
runtime/autoload/rustfmt.vim
Normal file
107
runtime/autoload/rustfmt.vim
Normal file
@ -0,0 +1,107 @@
|
||||
" Author: Stephen Sugden <stephen@stephensugden.com>
|
||||
"
|
||||
" Adapted from https://github.com/fatih/vim-go
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
if !exists("g:rustfmt_autosave")
|
||||
let g:rustfmt_autosave = 0
|
||||
endif
|
||||
|
||||
if !exists("g:rustfmt_command")
|
||||
let g:rustfmt_command = "rustfmt"
|
||||
endif
|
||||
|
||||
if !exists("g:rustfmt_options")
|
||||
let g:rustfmt_options = ""
|
||||
endif
|
||||
|
||||
if !exists("g:rustfmt_fail_silently")
|
||||
let g:rustfmt_fail_silently = 0
|
||||
endif
|
||||
|
||||
let s:got_fmt_error = 0
|
||||
|
||||
function! s:RustfmtCommandRange(filename, line1, line2)
|
||||
let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
|
||||
return printf("%s %s --write-mode=overwrite --file-lines '[%s]'", g:rustfmt_command, g:rustfmt_options, json_encode(l:arg))
|
||||
endfunction
|
||||
|
||||
function! s:RustfmtCommand(filename)
|
||||
return g:rustfmt_command . " --write-mode=overwrite " . g:rustfmt_options . " " . shellescape(a:filename)
|
||||
endfunction
|
||||
|
||||
function! s:RunRustfmt(command, curw, tmpname)
|
||||
if exists("*systemlist")
|
||||
let out = systemlist(a:command)
|
||||
else
|
||||
let out = split(system(a:command), '\r\?\n')
|
||||
endif
|
||||
|
||||
if v:shell_error == 0 || v:shell_error == 3
|
||||
" remove undo point caused via BufWritePre
|
||||
try | silent undojoin | catch | endtry
|
||||
|
||||
" Replace current file with temp file, then reload buffer
|
||||
call rename(a:tmpname, expand('%'))
|
||||
silent edit!
|
||||
let &syntax = &syntax
|
||||
|
||||
" only clear location list if it was previously filled to prevent
|
||||
" clobbering other additions
|
||||
if s:got_fmt_error
|
||||
let s:got_fmt_error = 0
|
||||
call setloclist(0, [])
|
||||
lwindow
|
||||
endif
|
||||
elseif g:rustfmt_fail_silently == 0
|
||||
" otherwise get the errors and put them in the location list
|
||||
let errors = []
|
||||
|
||||
for line in out
|
||||
" src/lib.rs:13:5: 13:10 error: expected `,`, or `}`, found `value`
|
||||
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\):\s*\(\d\+:\d\+\s*\)\?\s*error: \(.*\)')
|
||||
if !empty(tokens)
|
||||
call add(errors, {"filename": @%,
|
||||
\"lnum": tokens[2],
|
||||
\"col": tokens[3],
|
||||
\"text": tokens[5]})
|
||||
endif
|
||||
endfor
|
||||
|
||||
if empty(errors)
|
||||
% | " Couldn't detect rustfmt error format, output errors
|
||||
endif
|
||||
|
||||
if !empty(errors)
|
||||
call setloclist(0, errors, 'r')
|
||||
echohl Error | echomsg "rustfmt returned error" | echohl None
|
||||
endif
|
||||
|
||||
let s:got_fmt_error = 1
|
||||
lwindow
|
||||
" We didn't use the temp file, so clean up
|
||||
call delete(a:tmpname)
|
||||
endif
|
||||
|
||||
call winrestview(a:curw)
|
||||
endfunction
|
||||
|
||||
function! rustfmt#FormatRange(line1, line2)
|
||||
let l:curw = winsaveview()
|
||||
let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt"
|
||||
call writefile(getline(1, '$'), l:tmpname)
|
||||
|
||||
let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2)
|
||||
|
||||
call s:RunRustfmt(command, l:curw, l:tmpname)
|
||||
endfunction
|
||||
|
||||
function! rustfmt#Format()
|
||||
let l:curw = winsaveview()
|
||||
let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt"
|
||||
call writefile(getline(1, '$'), l:tmpname)
|
||||
|
||||
let command = s:RustfmtCommand(l:tmpname)
|
||||
|
||||
call s:RunRustfmt(command, l:curw, l:tmpname)
|
||||
endfunction
|
35
runtime/compiler/cargo.vim
Normal file
35
runtime/compiler/cargo.vim
Normal file
@ -0,0 +1,35 @@
|
||||
" Vim compiler file
|
||||
" Compiler: Cargo Compiler
|
||||
" Maintainer: Damien Radtke <damienradtke@gmail.com>
|
||||
" Latest Revision: 2014 Sep 24
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
if exists('current_compiler')
|
||||
finish
|
||||
endif
|
||||
runtime compiler/rustc.vim
|
||||
let current_compiler = "cargo"
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if exists(':CompilerSet') != 2
|
||||
command -nargs=* CompilerSet setlocal <args>
|
||||
endif
|
||||
|
||||
if exists('g:cargo_makeprg_params')
|
||||
execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*'
|
||||
else
|
||||
CompilerSet makeprg=cargo\ $*
|
||||
endif
|
||||
|
||||
" Ignore general cargo progress messages
|
||||
CompilerSet errorformat+=
|
||||
\%-G%\\s%#Downloading%.%#,
|
||||
\%-G%\\s%#Compiling%.%#,
|
||||
\%-G%\\s%#Finished%.%#,
|
||||
\%-G%\\s%#error:\ Could\ not\ compile\ %.%#,
|
||||
\%-G%\\s%#To\ learn\ more\\,%.%#
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
46
runtime/compiler/rustc.vim
Normal file
46
runtime/compiler/rustc.vim
Normal file
@ -0,0 +1,46 @@
|
||||
" Vim compiler file
|
||||
" Compiler: Rust Compiler
|
||||
" Maintainer: Chris Morgan <me@chrismorgan.info>
|
||||
" Latest Revision: 2013 Jul 12
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
if exists("current_compiler")
|
||||
finish
|
||||
endif
|
||||
let current_compiler = "rustc"
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if exists(":CompilerSet") != 2
|
||||
command -nargs=* CompilerSet setlocal <args>
|
||||
endif
|
||||
|
||||
if exists("g:rustc_makeprg_no_percent") && g:rustc_makeprg_no_percent != 0
|
||||
CompilerSet makeprg=rustc
|
||||
else
|
||||
CompilerSet makeprg=rustc\ \%
|
||||
endif
|
||||
|
||||
" Old errorformat (before nightly 2016/08/10)
|
||||
CompilerSet errorformat=
|
||||
\%f:%l:%c:\ %t%*[^:]:\ %m,
|
||||
\%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m,
|
||||
\%-G%f:%l\ %s,
|
||||
\%-G%*[\ ]^,
|
||||
\%-G%*[\ ]^%*[~],
|
||||
\%-G%*[\ ]...
|
||||
|
||||
" New errorformat (after nightly 2016/08/10)
|
||||
CompilerSet errorformat+=
|
||||
\%-G,
|
||||
\%-Gerror:\ aborting\ %.%#,
|
||||
\%-Gerror:\ Could\ not\ compile\ %.%#,
|
||||
\%Eerror:\ %m,
|
||||
\%Eerror[E%n]:\ %m,
|
||||
\%Wwarning:\ %m,
|
||||
\%Inote:\ %m,
|
||||
\%C\ %#-->\ %f:%l:%c
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
@ -2201,12 +2201,13 @@ readfile({fname} [, {binary} [, {max}]])
|
||||
reltime([{start} [, {end}]]) List get time value
|
||||
reltimefloat({time}) Float turn the time value into a Float
|
||||
reltimestr({time}) String turn time value into a String
|
||||
remote_expr({server}, {string} [, {idvar}])
|
||||
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
|
||||
String send expression
|
||||
remote_foreground({server}) Number bring Vim server to the foreground
|
||||
remote_peek({serverid} [, {retvar}])
|
||||
Number check for reply string
|
||||
remote_read({serverid}) String read reply string
|
||||
remote_read({serverid} [, {timeout}])
|
||||
String read reply string
|
||||
remote_send({server}, {string} [, {idvar}])
|
||||
String send key sequence
|
||||
remove({list}, {idx} [, {end}]) any remove items {idx}-{end} from {list}
|
||||
|
@ -724,6 +724,12 @@ Format description:
|
||||
not recognized here as well.
|
||||
|
||||
|
||||
RUST *ft-rust*
|
||||
|
||||
Since the text for this plugin is rather long it has been put in a separate
|
||||
file: |ft_rust.txt|.
|
||||
|
||||
|
||||
SQL *ft-sql*
|
||||
|
||||
Since the text for this plugin is rather long it has been put in a separate
|
||||
|
@ -73,7 +73,7 @@ This will call a function to compute the fold level: >
|
||||
:set foldexpr=MyFoldLevel(v:lnum)
|
||||
This will make a fold out of paragraphs separated by blank lines: >
|
||||
:set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
|
||||
this does the same: >
|
||||
This does the same: >
|
||||
:set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1
|
||||
|
||||
Note that backslashes must be used to escape characters that ":set" handles
|
||||
@ -197,7 +197,7 @@ and the level given by the marker:
|
||||
1. If a marker with the same fold level is encountered, the previous fold
|
||||
ends and another fold with the same level starts.
|
||||
2. If a marker with a higher fold level is found, a nested fold is started.
|
||||
3. if a marker with a lower fold level is found, all folds up to and including
|
||||
3. If a marker with a lower fold level is found, all folds up to and including
|
||||
this level end and a fold with the specified level starts.
|
||||
|
||||
The number indicates the fold level. A zero cannot be used (a marker with
|
||||
|
237
runtime/doc/ft_rust.txt
Normal file
237
runtime/doc/ft_rust.txt
Normal file
@ -0,0 +1,237 @@
|
||||
*ft_rust.txt* Filetype plugin for Rust
|
||||
|
||||
==============================================================================
|
||||
CONTENTS *rust* *ft-rust*
|
||||
|
||||
1. Introduction |rust-intro|
|
||||
2. Settings |rust-settings|
|
||||
3. Commands |rust-commands|
|
||||
4. Mappings |rust-mappings|
|
||||
|
||||
==============================================================================
|
||||
INTRODUCTION *rust-intro*
|
||||
|
||||
This plugin provides syntax and supporting functionality for the Rust
|
||||
filetype.
|
||||
|
||||
==============================================================================
|
||||
SETTINGS *rust-settings*
|
||||
|
||||
This plugin has a few variables you can define in your vimrc that change the
|
||||
behavior of the plugin.
|
||||
|
||||
*g:rustc_path*
|
||||
g:rustc_path~
|
||||
Set this option to the path to rustc for use in the |:RustRun| and
|
||||
|:RustExpand| commands. If unset, "rustc" will be located in $PATH: >
|
||||
let g:rustc_path = $HOME."/bin/rustc"
|
||||
<
|
||||
|
||||
*g:rustc_makeprg_no_percent*
|
||||
g:rustc_makeprg_no_percent~
|
||||
Set this option to 1 to have 'makeprg' default to "rustc" instead of
|
||||
"rustc %": >
|
||||
let g:rustc_makeprg_no_percent = 1
|
||||
<
|
||||
|
||||
*g:rust_conceal*
|
||||
g:rust_conceal~
|
||||
Set this option to turn on the basic |conceal| support: >
|
||||
let g:rust_conceal = 1
|
||||
<
|
||||
|
||||
*g:rust_conceal_mod_path*
|
||||
g:rust_conceal_mod_path~
|
||||
Set this option to turn on |conceal| for the path connecting token
|
||||
"::": >
|
||||
let g:rust_conceal_mod_path = 1
|
||||
<
|
||||
|
||||
*g:rust_conceal_pub*
|
||||
g:rust_conceal_pub~
|
||||
Set this option to turn on |conceal| for the "pub" token: >
|
||||
let g:rust_conceal_pub = 1
|
||||
<
|
||||
|
||||
*g:rust_recommended_style*
|
||||
g:rust_recommended_style~
|
||||
Set this option to enable vim indentation and textwidth settings to
|
||||
conform to style conventions of the rust standard library (i.e. use 4
|
||||
spaces for indents and sets 'textwidth' to 99). This option is enabled
|
||||
by default. To disable it: >
|
||||
let g:rust_recommended_style = 0
|
||||
<
|
||||
|
||||
*g:rust_fold*
|
||||
g:rust_fold~
|
||||
Set this option to turn on |folding|: >
|
||||
let g:rust_fold = 1
|
||||
<
|
||||
Value Effect ~
|
||||
0 No folding
|
||||
1 Braced blocks are folded. All folds are open by
|
||||
default.
|
||||
2 Braced blocks are folded. 'foldlevel' is left at the
|
||||
global value (all folds are closed by default).
|
||||
|
||||
*g:rust_bang_comment_leader*
|
||||
g:rust_bang_comment_leader~
|
||||
Set this option to 1 to preserve the leader on multi-line doc comments
|
||||
using the /*! syntax: >
|
||||
let g:rust_bang_comment_leader = 1
|
||||
<
|
||||
|
||||
*g:ftplugin_rust_source_path*
|
||||
g:ftplugin_rust_source_path~
|
||||
Set this option to a path that should be prepended to 'path' for Rust
|
||||
source files: >
|
||||
let g:ftplugin_rust_source_path = $HOME.'/dev/rust'
|
||||
<
|
||||
|
||||
*g:rustfmt_command*
|
||||
g:rustfmt_command~
|
||||
Set this option to the name of the 'rustfmt' executable in your $PATH. If
|
||||
not specified it defaults to 'rustfmt' : >
|
||||
let g:rustfmt_command = 'rustfmt'
|
||||
<
|
||||
*g:rustfmt_autosave*
|
||||
g:rustfmt_autosave~
|
||||
Set this option to 1 to run |:RustFmt| automatically when saving a
|
||||
buffer. If not specified it defaults to 0 : >
|
||||
let g:rustfmt_autosave = 0
|
||||
<
|
||||
*g:rustfmt_fail_silently*
|
||||
g:rustfmt_fail_silently~
|
||||
Set this option to 1 to prevent 'rustfmt' from populating the
|
||||
|location-list| with errors. If not specified it defaults to 0: >
|
||||
let g:rustfmt_fail_silently = 0
|
||||
<
|
||||
*g:rustfmt_options*
|
||||
g:rustfmt_options~
|
||||
Set this option to a string of options to pass to 'rustfmt'. The
|
||||
write-mode is already set to 'overwrite'. If not specified it
|
||||
defaults to '' : >
|
||||
let g:rustfmt_options = ''
|
||||
<
|
||||
|
||||
*g:rust_playpen_url*
|
||||
g:rust_playpen_url~
|
||||
Set this option to override the url for the playpen to use: >
|
||||
let g:rust_playpen_url = 'https://play.rust-lang.org/'
|
||||
<
|
||||
|
||||
*g:rust_shortener_url*
|
||||
g:rust_shortener_url~
|
||||
Set this option to override the url for the url shortener: >
|
||||
let g:rust_shortener_url = 'https://is.gd/'
|
||||
<
|
||||
|
||||
|
||||
==============================================================================
|
||||
COMMANDS *rust-commands*
|
||||
|
||||
:RustRun [args] *:RustRun*
|
||||
:RustRun! [rustc-args] [--] [args]
|
||||
Compiles and runs the current file. If it has unsaved changes,
|
||||
it will be saved first using |:update|. If the current file is
|
||||
an unnamed buffer, it will be written to a temporary file
|
||||
first. The compiled binary is always placed in a temporary
|
||||
directory, but is run from the current directory.
|
||||
|
||||
The arguments given to |:RustRun| will be passed to the
|
||||
compiled binary.
|
||||
|
||||
If ! is specified, the arguments are passed to rustc instead.
|
||||
A "--" argument will separate the rustc arguments from the
|
||||
arguments passed to the binary.
|
||||
|
||||
If |g:rustc_path| is defined, it is used as the path to rustc.
|
||||
Otherwise it is assumed rustc can be found in $PATH.
|
||||
|
||||
:RustExpand [args] *:RustExpand*
|
||||
:RustExpand! [TYPE] [args]
|
||||
Expands the current file using --pretty and displays the
|
||||
results in a new split. If the current file has unsaved
|
||||
changes, it will be saved first using |:update|. If the
|
||||
current file is an unnamed buffer, it will be written to a
|
||||
temporary file first.
|
||||
|
||||
The arguments given to |:RustExpand| will be passed to rustc.
|
||||
This is largely intended for specifying various --cfg
|
||||
configurations.
|
||||
|
||||
If ! is specified, the first argument is the expansion type to
|
||||
pass to rustc --pretty. Otherwise it will default to
|
||||
"expanded".
|
||||
|
||||
If |g:rustc_path| is defined, it is used as the path to rustc.
|
||||
Otherwise it is assumed rustc can be found in $PATH.
|
||||
|
||||
:RustEmitIr [args] *:RustEmitIr*
|
||||
Compiles the current file to LLVM IR and displays the results
|
||||
in a new split. If the current file has unsaved changes, it
|
||||
will be saved first using |:update|. If the current file is an
|
||||
unnamed buffer, it will be written to a temporary file first.
|
||||
|
||||
The arguments given to |:RustEmitIr| will be passed to rustc.
|
||||
|
||||
If |g:rustc_path| is defined, it is used as the path to rustc.
|
||||
Otherwise it is assumed rustc can be found in $PATH.
|
||||
|
||||
:RustEmitAsm [args] *:RustEmitAsm*
|
||||
Compiles the current file to assembly and displays the results
|
||||
in a new split. If the current file has unsaved changes, it
|
||||
will be saved first using |:update|. If the current file is an
|
||||
unnamed buffer, it will be written to a temporary file first.
|
||||
|
||||
The arguments given to |:RustEmitAsm| will be passed to rustc.
|
||||
|
||||
If |g:rustc_path| is defined, it is used as the path to rustc.
|
||||
Otherwise it is assumed rustc can be found in $PATH.
|
||||
|
||||
:RustPlay *:RustPlay*
|
||||
This command will only work if you have web-api.vim installed
|
||||
(available at https://github.com/mattn/webapi-vim). It sends the
|
||||
current selection, or if nothing is selected, the entirety of the
|
||||
current buffer to the Rust playpen, and emits a message with the
|
||||
shortened URL to the playpen.
|
||||
|
||||
|g:rust_playpen_url| is the base URL to the playpen, by default
|
||||
"https://play.rust-lang.org/".
|
||||
|
||||
|g:rust_shortener_url| is the base url for the shorterner, by
|
||||
default "https://is.gd/"
|
||||
|
||||
:RustFmt *:RustFmt*
|
||||
Runs |g:rustfmt_command| on the current buffer. If
|
||||
|g:rustfmt_options| is set then those will be passed to the
|
||||
executable.
|
||||
|
||||
If |g:rustfmt_fail_silently| is 0 (the default) then it
|
||||
will populate the |location-list| with the errors from
|
||||
|g:rustfmt_command|. If |g:rustfmt_fail_silently| is set to 1
|
||||
then it will not populate the |location-list|.
|
||||
|
||||
:RustFmtRange *:RustFmtRange*
|
||||
Runs |g:rustfmt_command| with selected range. See
|
||||
|:RustFmt| for any other information.
|
||||
|
||||
==============================================================================
|
||||
MAPPINGS *rust-mappings*
|
||||
|
||||
This plugin defines mappings for |[[| and |]]| to support hanging indents.
|
||||
|
||||
It also has a few other mappings:
|
||||
|
||||
*rust_<D-r>*
|
||||
<D-r> Executes |:RustRun| with no arguments.
|
||||
Note: This binding is only available in MacVim.
|
||||
|
||||
*rust_<D-R>*
|
||||
<D-R> Populates the command line with |:RustRun|! using the
|
||||
arguments given to the last invocation, but does not
|
||||
execute it.
|
||||
Note: This binding is only available in MacVim.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
|
@ -140,7 +140,8 @@ Help on help files *helphelp*
|
||||
already opened, then the location list for that window
|
||||
is used. Otherwise, a new help window is opened and
|
||||
the location list for that window is set. The
|
||||
location list for the current window is not changed.
|
||||
location list for the current window is not changed
|
||||
then.
|
||||
|
||||
*:exu* *:exusage*
|
||||
:exu[sage] Show help on Ex commands. Added to simulate the Nvi
|
||||
|
@ -137,6 +137,7 @@ the description in |eval.txt| or use CTRL-] on the function name to jump to
|
||||
the full explanation.
|
||||
|
||||
synopsis explanation ~
|
||||
remote_startserver( name) run a server
|
||||
remote_expr( server, string, idvar) send expression
|
||||
remote_send( server, string, idvar) send key sequence
|
||||
serverlist() get a list of available servers
|
||||
|
@ -888,6 +888,7 @@ GUI: *gui-functions*
|
||||
|
||||
Vim server: *server-functions*
|
||||
serverlist() return the list of server names
|
||||
remote_startserve() run a server
|
||||
remote_send() send command characters to a Vim server
|
||||
remote_expr() evaluate an expression in a Vim server
|
||||
server2client() send a reply to a client of a Vim server
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Language: Hamster Script
|
||||
" Version: 2.0.6.0
|
||||
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
|
||||
" Last Change: 2017 Mar 07
|
||||
" Last Change: 2017 Mar 18
|
||||
|
||||
" Only do this when not done yet for this buffer
|
||||
if exists("b:did_ftplugin")
|
||||
@ -14,7 +14,6 @@ let b:did_ftplugin = 1
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
set cpo-=C
|
||||
|
||||
let b:undo_ftplugin = "setl fo< com< tw< commentstring<"
|
||||
\ . "| unlet! b:match_ignorecase b:match_words b:match_skip"
|
||||
|
197
runtime/ftplugin/rust.vim
Normal file
197
runtime/ftplugin/rust.vim
Normal file
@ -0,0 +1,197 @@
|
||||
" Language: Rust
|
||||
" Description: Vim ftplugin for Rust
|
||||
" Maintainer: Chris Morgan <me@chrismorgan.info>
|
||||
" Maintainer: Kevin Ballard <kevin@sb.org>
|
||||
" Last Change: June 08, 2016
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
if exists("b:did_ftplugin")
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
augroup rust.vim
|
||||
autocmd!
|
||||
|
||||
" Variables {{{1
|
||||
|
||||
" The rust source code at present seems to typically omit a leader on /*!
|
||||
" 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:*/,:///,://!,://
|
||||
else
|
||||
setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
|
||||
endif
|
||||
setlocal commentstring=//%s
|
||||
setlocal formatoptions-=t formatoptions+=croqnl
|
||||
" j was only added in 7.3.541, so stop complaints about its nonexistence
|
||||
silent! setlocal formatoptions+=j
|
||||
|
||||
" smartindent will be overridden by indentexpr if filetype indent is on, but
|
||||
" 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
|
||||
endif
|
||||
|
||||
" This includeexpr isn't perfect, but it's a good start
|
||||
setlocal includeexpr=substitute(v:fname,'::','/','g')
|
||||
|
||||
setlocal suffixesadd=.rs
|
||||
|
||||
if exists("g:ftplugin_rust_source_path")
|
||||
let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
|
||||
endif
|
||||
|
||||
if exists("g:loaded_delimitMate")
|
||||
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'
|
||||
|
||||
" 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
|
||||
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
|
||||
endif
|
||||
|
||||
if has('conceal') && exists('g:rust_conceal') && g:rust_conceal != 0
|
||||
let b:rust_set_conceallevel=1
|
||||
setlocal conceallevel=2
|
||||
endif
|
||||
|
||||
" Motion Commands {{{1
|
||||
|
||||
" Bind motion commands to support hanging indents
|
||||
nnoremap <silent> <buffer> [[ :call rust#Jump('n', 'Back')<CR>
|
||||
nnoremap <silent> <buffer> ]] :call rust#Jump('n', 'Forward')<CR>
|
||||
xnoremap <silent> <buffer> [[ :call rust#Jump('v', 'Back')<CR>
|
||||
xnoremap <silent> <buffer> ]] :call rust#Jump('v', 'Forward')<CR>
|
||||
onoremap <silent> <buffer> [[ :call rust#Jump('o', 'Back')<CR>
|
||||
onoremap <silent> <buffer> ]] :call rust#Jump('o', 'Forward')<CR>
|
||||
|
||||
" Commands {{{1
|
||||
|
||||
" See |:RustRun| for docs
|
||||
command! -nargs=* -complete=file -bang -buffer RustRun call rust#Run(<bang>0, <q-args>)
|
||||
|
||||
" See |:RustExpand| for docs
|
||||
command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -buffer RustExpand call rust#Expand(<bang>0, <q-args>)
|
||||
|
||||
" See |:RustEmitIr| for docs
|
||||
command! -nargs=* -buffer RustEmitIr call rust#Emit("llvm-ir", <q-args>)
|
||||
|
||||
" See |:RustEmitAsm| for docs
|
||||
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>)
|
||||
|
||||
" See |:RustFmt| for docs
|
||||
command! -buffer RustFmt call rustfmt#Format()
|
||||
|
||||
" See |:RustFmtRange| for docs
|
||||
command! -range -buffer RustFmtRange call rustfmt#FormatRange(<line1>, <line2>)
|
||||
|
||||
" Mappings {{{1
|
||||
|
||||
" 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>
|
||||
|
||||
if !exists("b:rust_last_rustc_args") || !exists("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-=<:>
|
||||
\"
|
||||
|
||||
" }}}1
|
||||
|
||||
" Code formatting on save
|
||||
if get(g:, "rustfmt_autosave", 0)
|
||||
autocmd BufWritePre *.rs silent! call rustfmt#Format()
|
||||
endif
|
||||
|
||||
augroup END
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim: set noet sw=8 ts=8:
|
@ -2,7 +2,7 @@
|
||||
" Language: Javascript
|
||||
" Maintainer: Chris Paul ( https://github.com/bounceme )
|
||||
" URL: https://github.com/pangloss/vim-javascript
|
||||
" Last Change: December 31, 2016
|
||||
" Last Change: March 21, 2017
|
||||
|
||||
" Only load this indent file when no other was loaded.
|
||||
if exists('b:did_indent')
|
||||
@ -14,6 +14,10 @@ let b:did_indent = 1
|
||||
setlocal indentexpr=GetJavascriptIndent()
|
||||
setlocal autoindent nolisp nosmartindent
|
||||
setlocal indentkeys+=0],0)
|
||||
" Testable with something like:
|
||||
" vim -eNs "+filetype plugin indent on" "+syntax on" "+set ft=javascript" \
|
||||
" "+norm! gg=G" '+%print' '+:q!' testfile.js \
|
||||
" | diff -uBZ testfile.js -
|
||||
|
||||
let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys<'
|
||||
|
||||
@ -32,10 +36,14 @@ if exists('*shiftwidth')
|
||||
endfunction
|
||||
else
|
||||
function s:sw()
|
||||
return &sw
|
||||
return &l:shiftwidth == 0 ? &l:tabstop : &l:shiftwidth
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" Performance for forwards search(): start search at pos rather than masking
|
||||
" matches before pos.
|
||||
let s:z = has('patch-7.4.984') ? 'z' : ''
|
||||
|
||||
" searchpair() wrapper
|
||||
if has('reltime')
|
||||
function s:GetPair(start,end,flags,skip,time,...)
|
||||
@ -48,34 +56,41 @@ else
|
||||
endif
|
||||
|
||||
" Regex of syntax group names that are or delimit string or are comments.
|
||||
let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template'
|
||||
let s:syng_str = 'string\|template'
|
||||
let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template\%(braces\)\@!'
|
||||
let s:syng_str = 'string\|template\|special'
|
||||
let s:syng_com = 'comment\|doc'
|
||||
" Expression used to check whether we should skip a match with searchpair().
|
||||
let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'"
|
||||
|
||||
function s:parse_cino(f) abort
|
||||
return float2nr(eval(substitute(substitute(join(split(
|
||||
\ matchstr(&cino,'.*'.a:f.'\zs[^,]*'), 's',1), '*'.s:W)
|
||||
\ , '^-\=\zs\*','',''), '^-\=\zs\.','0.','')))
|
||||
endfunction
|
||||
|
||||
function s:skip_func()
|
||||
if !s:free || search('\m`\|\*\/','nW',s:looksyn)
|
||||
let s:free = !eval(s:skip_expr)
|
||||
let s:looksyn = s:free ? line('.') : s:looksyn
|
||||
return !s:free
|
||||
if getline('.') =~ '\%<'.col('.').'c\/.\{-}\/\|\%>'.col('.').'c[''"]\|\\$'
|
||||
return eval(s:skip_expr)
|
||||
elseif s:checkIn || search('\m`\|\${\|\*\/','nW'.s:z,s:looksyn)
|
||||
let s:checkIn = eval(s:skip_expr)
|
||||
endif
|
||||
let s:looksyn = line('.')
|
||||
return (search('\m\/','nbW',s:looksyn) || search('\m[''"]\|\\$','nW',s:looksyn)) && eval(s:skip_expr)
|
||||
return s:checkIn
|
||||
endfunction
|
||||
|
||||
function s:alternatePair(stop)
|
||||
let pos = getpos('.')[1:2]
|
||||
while search('\m[][(){}]','bW',a:stop)
|
||||
if !s:skip_func()
|
||||
let idx = stridx('])}',s:looking_at())
|
||||
if idx + 1
|
||||
if !s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop)
|
||||
break
|
||||
endif
|
||||
else
|
||||
return
|
||||
let pat = '[][(){};]'
|
||||
while search('\m'.pat,'bW',a:stop)
|
||||
if s:skip_func() | continue | endif
|
||||
let idx = stridx('])};',s:looking_at())
|
||||
if idx is 3 | let pat = '[{}()]' | continue | endif
|
||||
if idx + 1
|
||||
if s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop) <= 0
|
||||
break
|
||||
endif
|
||||
else
|
||||
return
|
||||
endif
|
||||
endwhile
|
||||
call call('cursor',pos)
|
||||
@ -100,93 +115,91 @@ function s:token()
|
||||
return s:looking_at() =~ '\k' ? expand('<cword>') : s:looking_at()
|
||||
endfunction
|
||||
|
||||
function s:b_token()
|
||||
if s:looking_at() =~ '\k'
|
||||
call search('\m\<','cbW')
|
||||
endif
|
||||
return search('\m\S','bW')
|
||||
endfunction
|
||||
|
||||
function s:previous_token()
|
||||
let l:n = line('.')
|
||||
while s:b_token()
|
||||
if (s:looking_at() == '/' || line('.') != l:n && search('\m\/\/','nbW',
|
||||
\ line('.'))) && s:syn_at(line('.'),col('.')) =~? s:syng_com
|
||||
call search('\m\_[^/]\zs\/[/*]','bW')
|
||||
let l:pos = getpos('.')[1:2]
|
||||
if search('\m\k\{1,}\zs\k\|\S','bW')
|
||||
if (getline('.')[col('.')-2:col('.')-1] == '*/' || line('.') != l:pos[0] &&
|
||||
\ getline('.') =~ '\%<'.col('.').'c\/\/') && s:syn_at(line('.'),col('.')) =~? s:syng_com
|
||||
while search('\m\S\ze\_s*\/[/*]','bW')
|
||||
if s:syn_at(line('.'),col('.')) !~? s:syng_com
|
||||
return s:token()
|
||||
endif
|
||||
endwhile
|
||||
else
|
||||
return s:token()
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
call call('cursor',l:pos)
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function s:others(p)
|
||||
return "((line2byte(line('.')) + col('.')) <= ".(line2byte(a:p[0]) + a:p[1]).") || ".s:skip_expr
|
||||
endfunction
|
||||
|
||||
function s:tern_skip(p)
|
||||
return s:GetPair('{','}','nbW',s:others(a:p),200,a:p[0]) > 0
|
||||
endfunction
|
||||
|
||||
function s:tern_col(p)
|
||||
return s:GetPair('?',':\@<!::\@!','nbW',s:others(a:p)
|
||||
\ .' || s:tern_skip('.string(a:p).')',200,a:p[0]) > 0
|
||||
endfunction
|
||||
|
||||
function s:label_col()
|
||||
let pos = getpos('.')[1:2]
|
||||
let [s:looksyn,s:free] = pos
|
||||
call s:alternatePair(0)
|
||||
if s:save_pos('s:IsBlock')
|
||||
let poss = getpos('.')[1:2]
|
||||
return call('cursor',pos) || !s:tern_col(poss)
|
||||
elseif s:looking_at() == ':'
|
||||
return !s:tern_col([0,0])
|
||||
function s:expr_col()
|
||||
if getline('.')[col('.')-2] == ':'
|
||||
return 1
|
||||
endif
|
||||
let bal = 0
|
||||
while search('\m[{}?:;]','bW')
|
||||
if eval(s:skip_expr) | continue | endif
|
||||
" switch (looking_at())
|
||||
exe { '}': "if s:GetPair('{','}','bW',s:skip_expr,200) <= 0 | return | endif",
|
||||
\ ';': "return",
|
||||
\ '{': "return getpos('.')[1:2] != b:js_cache[1:] && !s:IsBlock()",
|
||||
\ ':': "let bal -= getline('.')[max([col('.')-2,0]):col('.')] !~ '::'",
|
||||
\ '?': "let bal += 1 | if bal > 0 | return 1 | endif" }[s:looking_at()]
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
" configurable regexes that define continuation lines, not including (, {, or [.
|
||||
let s:opfirst = '^' . get(g:,'javascript_opfirst',
|
||||
\ '\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)')
|
||||
\ '\C\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)')
|
||||
let s:continuation = get(g:,'javascript_continuation',
|
||||
\ '\%([<=,.~!?/*^%|&:]\|+\@<!+\|-\@<!-\|=\@<!>\|\<\%(typeof\|delete\|void\|in\|instanceof\)\)') . '$'
|
||||
\ '\C\%([-+<>=,.~!?/*^%|&:]\|\<\%(typeof\|new\|delete\|void\|in\|instanceof\|await\)\)') . '$'
|
||||
|
||||
function s:continues(ln,con)
|
||||
return !cursor(a:ln, match(' '.a:con,s:continuation)) &&
|
||||
\ eval((['s:syn_at(line("."),col(".")) !~? "regex"'] +
|
||||
\ repeat(['s:previous_token() != "."'],5) + [1])[
|
||||
\ index(split('/ typeof in instanceof void delete'),s:token())])
|
||||
if !cursor(a:ln, match(' '.a:con,s:continuation))
|
||||
let teol = s:looking_at()
|
||||
if teol == '/'
|
||||
return s:syn_at(line('.'),col('.')) !~? 'regex'
|
||||
elseif teol =~ '[-+>]'
|
||||
return getline('.')[col('.')-2] != tr(teol,'>','=')
|
||||
elseif teol =~ '\l'
|
||||
return s:previous_token() != '.'
|
||||
elseif teol == ':'
|
||||
return s:expr_col()
|
||||
endif
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" get the line of code stripped of comments and move cursor to the last
|
||||
" non-comment char.
|
||||
function s:Trim(ln)
|
||||
let pline = substitute(getline(a:ln),'\s*$','','')
|
||||
let l:max = max([match(pline,'.*[^/]\zs\/[/*]'),0])
|
||||
while l:max && s:syn_at(a:ln, strlen(pline)) =~? s:syng_com
|
||||
let pline = substitute(strpart(pline, 0, l:max),'\s*$','','')
|
||||
let l:max = max([match(pline,'.*[^/]\zs\/[/*]'),0])
|
||||
let l:max = max([strridx(pline,'//'), strridx(pline,'/*')])
|
||||
while l:max != -1 && s:syn_at(a:ln, strlen(pline)) =~? s:syng_com
|
||||
let pline = pline[: l:max]
|
||||
let l:max = max([strridx(pline,'//'), strridx(pline,'/*')])
|
||||
let pline = substitute(pline[:-2],'\s*$','','')
|
||||
endwhile
|
||||
return cursor(a:ln,strlen(pline)) ? pline : pline
|
||||
return pline is '' || cursor(a:ln,strlen(pline)) ? pline : pline
|
||||
endfunction
|
||||
|
||||
" Find line above 'lnum' that isn't empty or in a comment
|
||||
function s:PrevCodeLine(lnum)
|
||||
let l:n = prevnonblank(a:lnum)
|
||||
let [l:pos, l:n] = [getpos('.')[1:2], prevnonblank(a:lnum)]
|
||||
while l:n
|
||||
if getline(l:n) =~ '^\s*\/[/*]'
|
||||
if (stridx(getline(l:n),'`') > 0 || getline(l:n-1)[-1:] == '\') &&
|
||||
\ s:syn_at(l:n,1) =~? s:syng_str
|
||||
return l:n
|
||||
endif
|
||||
let l:n = prevnonblank(l:n-1)
|
||||
elseif s:syn_at(l:n,1) =~? s:syng_com
|
||||
let l:n = s:save_pos('eval',
|
||||
\ 'cursor('.l:n.',1) + search(''\m\/\*'',"bW")')
|
||||
elseif stridx(getline(l:n), '*/') + 1 && s:syn_at(l:n,1) =~? s:syng_com
|
||||
call cursor(l:n,1)
|
||||
keepjumps norm! [*
|
||||
let l:n = search('\m\S','nbW')
|
||||
else
|
||||
return l:n
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
call call('cursor',l:pos)
|
||||
return l:n
|
||||
endfunction
|
||||
|
||||
" Check if line 'lnum' has a balanced amount of parentheses.
|
||||
@ -201,7 +214,9 @@ function s:Balanced(lnum)
|
||||
return
|
||||
endif
|
||||
endif
|
||||
let pos = match(l:line, '[][(){}]', pos + 1)
|
||||
let pos = match(l:line, (l:open ?
|
||||
\ '['.escape(tr(l:line[pos],'({[]})',')}][{(').l:line[pos],']').']' :
|
||||
\ '[][(){}]'), pos + 1)
|
||||
endwhile
|
||||
return !l:open
|
||||
endfunction
|
||||
@ -210,11 +225,11 @@ function s:OneScope(lnum)
|
||||
let pline = s:Trim(a:lnum)
|
||||
let kw = 'else do'
|
||||
if pline[-1:] == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
|
||||
call s:previous_token()
|
||||
let kw = 'for if let while with'
|
||||
if index(split('await each'),s:token()) + 1
|
||||
if s:previous_token() =~# '^\%(await\|each\)$'
|
||||
call s:previous_token()
|
||||
let kw = 'for'
|
||||
else
|
||||
let kw = 'for if let while with'
|
||||
endif
|
||||
endif
|
||||
return pline[-2:] == '=>' || index(split(kw),s:token()) + 1 &&
|
||||
@ -246,18 +261,23 @@ function s:IsBlock()
|
||||
if s:looking_at() == '{'
|
||||
let l:n = line('.')
|
||||
let char = s:previous_token()
|
||||
let syn = char =~ '[{>/]' ? s:syn_at(line('.'),col('.')-(char == '{')) : ''
|
||||
if syn =~? 'xml\|jsx'
|
||||
if match(s:stack,'\cxml\|jsx') + 1 && s:syn_at(line('.'),col('.')-1) =~? 'xml\|jsx'
|
||||
return char != '{'
|
||||
elseif char =~ '\k'
|
||||
return index(split('return const let import export yield default delete var await void typeof throw case new in instanceof')
|
||||
\ ,char) < (line('.') != l:n) || s:previous_token() == '.'
|
||||
if char ==# 'type'
|
||||
return s:previous_token() !~# '^\%(im\|ex\)port$'
|
||||
endif
|
||||
return index(split('return const let import export extends yield default delete var await void typeof throw case new of in instanceof')
|
||||
\ ,char) < (line('.') != l:n) || s:save_pos('s:previous_token') == '.'
|
||||
elseif char == '>'
|
||||
return getline('.')[col('.')-2] == '=' || syn =~? '^jsflow'
|
||||
return getline('.')[col('.')-2] == '=' || s:syn_at(line('.'),col('.')) =~? '^jsflow'
|
||||
elseif char == ':'
|
||||
return getline('.')[col('.')-2] != ':' && s:label_col()
|
||||
return !s:save_pos('s:expr_col')
|
||||
elseif char == '/'
|
||||
return s:syn_at(line('.'),col('.')) =~? 'regex'
|
||||
endif
|
||||
return syn =~? 'regex' || char !~ '[-=~!<*+,/?^%|&([]'
|
||||
return char !~ '[=~!<*,?^%|&([]' &&
|
||||
\ (char !~ '[-+]' || l:n != line('.') && getline('.')[col('.')-2] == char)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -266,7 +286,9 @@ function GetJavascriptIndent()
|
||||
" Get the current line.
|
||||
call cursor(v:lnum,1)
|
||||
let l:line = getline('.')
|
||||
let syns = s:syn_at(v:lnum, 1)
|
||||
" use synstack as it validates syn state and works in an empty line
|
||||
let s:stack = map(synstack(v:lnum,1),"synIDattr(v:val,'name')")
|
||||
let syns = get(s:stack,-1,'')
|
||||
|
||||
" start with strings,comments,etc.
|
||||
if syns =~? s:syng_com
|
||||
@ -275,7 +297,7 @@ function GetJavascriptIndent()
|
||||
elseif l:line !~ '^\s*\/[/*]'
|
||||
return -1
|
||||
endif
|
||||
elseif syns =~? s:syng_str && l:line !~ '^[''"]'
|
||||
elseif syns =~? s:syng_str
|
||||
if b:js_cache[0] == v:lnum - 1 && s:Balanced(v:lnum-1)
|
||||
let b:js_cache[0] = v:lnum
|
||||
endif
|
||||
@ -295,69 +317,60 @@ function GetJavascriptIndent()
|
||||
endif
|
||||
|
||||
" the containing paren, bracket, or curly. Many hacks for performance
|
||||
let idx = strlen(l:line) ? stridx('])}',l:line[0]) : -1
|
||||
let idx = index([']',')','}'],l:line[0])
|
||||
if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum &&
|
||||
\ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum))
|
||||
call call('cursor',b:js_cache[1:])
|
||||
else
|
||||
let [s:looksyn, s:free, top] = [v:lnum - 1, 1, (!indent(l:lnum) &&
|
||||
let [s:looksyn, s:checkIn, top] = [v:lnum - 1, 0, (!indent(l:lnum) &&
|
||||
\ s:syn_at(l:lnum,1) !~? s:syng_str) * l:lnum]
|
||||
if idx + 1
|
||||
call s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,top)
|
||||
elseif indent(v:lnum) && syns =~? 'block'
|
||||
call s:GetPair(['\[','(','{'][idx],'])}'[idx],'bW','s:skip_func()',2000,top)
|
||||
elseif getline(v:lnum) !~ '^\S' && syns =~? 'block'
|
||||
call s:GetPair('{','}','bW','s:skip_func()',2000,top)
|
||||
else
|
||||
call s:alternatePair(top)
|
||||
endif
|
||||
endif
|
||||
|
||||
if idx + 1 || l:line[:1] == '|}'
|
||||
if idx == 2 && search('\m\S','bW',line('.')) && s:looking_at() == ')'
|
||||
call s:GetPair('(',')','bW',s:skip_expr,200)
|
||||
endif
|
||||
return indent('.')
|
||||
endif
|
||||
|
||||
let b:js_cache = [v:lnum] + (line('.') == v:lnum ? [0,0] : getpos('.')[1:2])
|
||||
let num = b:js_cache[1]
|
||||
|
||||
let [s:W, isOp, bL, switch_offset] = [s:sw(),0,0,0]
|
||||
if !num || s:IsBlock()
|
||||
let ilnum = line('.')
|
||||
let pline = s:save_pos('s:Trim',l:lnum)
|
||||
if num && s:looking_at() == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
|
||||
let num = line('.')
|
||||
if s:previous_token() ==# 'switch' && s:previous_token() != '.'
|
||||
if &cino !~ ':' || !has('float')
|
||||
let num = ilnum == num ? line('.') : num
|
||||
if idx < 0 && s:previous_token() ==# 'switch' && s:previous_token() != '.'
|
||||
if &cino !~ ':'
|
||||
let switch_offset = s:W
|
||||
else
|
||||
let cinc = matchlist(&cino,'.*:\(-\)\=\([0-9.]*\)\(s\)\=\C')
|
||||
let switch_offset = float2nr(str2float(cinc[1].(strlen(cinc[2]) ? cinc[2] : strlen(cinc[3])))
|
||||
\ * (strlen(cinc[3]) ? s:W : 1))
|
||||
let switch_offset = max([-indent(num),s:parse_cino(':')])
|
||||
endif
|
||||
if pline[-1:] != '.' && l:line =~# '^\%(default\|case\)\>'
|
||||
return indent(num) + switch_offset
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if pline[-1:] !~ '[{;]'
|
||||
if pline =~# ':\@<!:$'
|
||||
call cursor(l:lnum,strlen(pline))
|
||||
let isOp = s:tern_col(b:js_cache[1:2])
|
||||
else
|
||||
let isOp = l:line =~# s:opfirst || s:continues(l:lnum,pline)
|
||||
endif
|
||||
let bL = s:iscontOne(l:lnum,num,isOp)
|
||||
if idx < 0 && pline[-1:] !~ '[{;]'
|
||||
let isOp = (l:line =~# s:opfirst || s:continues(l:lnum,pline)) * s:W
|
||||
let bL = s:iscontOne(l:lnum,b:js_cache[1],isOp)
|
||||
let bL -= (bL && l:line[0] == '{') * s:W
|
||||
endif
|
||||
elseif idx < 0 && getline(b:js_cache[1])[b:js_cache[2]-1] == '(' && &cino =~ '('
|
||||
let pval = s:parse_cino('(')
|
||||
return !pval ? (s:parse_cino('w') ? 0 : -(!!search('\m\S','W'.s:z,num))) + virtcol('.') :
|
||||
\ max([indent('.') + pval + (s:GetPair('(',')','nbrmW',s:skip_expr,100,num) * s:W),0])
|
||||
endif
|
||||
|
||||
" main return
|
||||
if isOp
|
||||
return (num ? indent(num) : -s:W) + (s:W * 2) + switch_offset + bL
|
||||
if l:line =~ '^\%([])}]\||}\)'
|
||||
return max([indent(num),0])
|
||||
elseif num
|
||||
return indent(num) + s:W + switch_offset + bL
|
||||
return indent(num) + s:W + switch_offset + bL + isOp
|
||||
endif
|
||||
return bL
|
||||
return bL + isOp
|
||||
endfunction
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
|
213
runtime/indent/rust.vim
Normal file
213
runtime/indent/rust.vim
Normal file
@ -0,0 +1,213 @@
|
||||
" Vim indent file
|
||||
" Language: Rust
|
||||
" Author: Chris Morgan <me@chrismorgan.info>
|
||||
" Last Change: 2017 Mar 21
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
" Only load this indent file when no other was loaded.
|
||||
if exists("b:did_indent")
|
||||
finish
|
||||
endif
|
||||
let b:did_indent = 1
|
||||
|
||||
setlocal cindent
|
||||
setlocal cinoptions=L0,(0,Ws,J1,j1
|
||||
setlocal cinkeys=0{,0},!^F,o,O,0[,0]
|
||||
" Don't think cinwords will actually do anything at all... never mind
|
||||
setlocal cinwords=for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern
|
||||
|
||||
" Some preliminary settings
|
||||
setlocal nolisp " Make sure lisp indenting doesn't supersede us
|
||||
setlocal autoindent " indentexpr isn't much help otherwise
|
||||
" Also do indentkeys, otherwise # gets shoved to column 0 :-/
|
||||
setlocal indentkeys=0{,0},!^F,o,O,0[,0]
|
||||
|
||||
setlocal indentexpr=GetRustIndent(v:lnum)
|
||||
|
||||
" Only define the function once.
|
||||
if exists("*GetRustIndent")
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Come here when loading the script the first time.
|
||||
|
||||
function! s:get_line_trimmed(lnum)
|
||||
" Get the line and remove a trailing comment.
|
||||
" Use syntax highlighting attributes when possible.
|
||||
" NOTE: this is not accurate; /* */ or a line continuation could trick it
|
||||
let line = getline(a:lnum)
|
||||
let line_len = strlen(line)
|
||||
if has('syntax_items')
|
||||
" If the last character in the line is a comment, do a binary search for
|
||||
" the start of the comment. synID() is slow, a linear search would take
|
||||
" too long on a long line.
|
||||
if synIDattr(synID(a:lnum, line_len, 1), "name") =~ 'Comment\|Todo'
|
||||
let min = 1
|
||||
let max = line_len
|
||||
while min < max
|
||||
let col = (min + max) / 2
|
||||
if synIDattr(synID(a:lnum, col, 1), "name") =~ 'Comment\|Todo'
|
||||
let max = col
|
||||
else
|
||||
let min = col + 1
|
||||
endif
|
||||
endwhile
|
||||
let line = strpart(line, 0, min - 1)
|
||||
endif
|
||||
return substitute(line, "\s*$", "", "")
|
||||
else
|
||||
" Sorry, this is not complete, nor fully correct (e.g. string "//").
|
||||
" Such is life.
|
||||
return substitute(line, "\s*//.*$", "", "")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:is_string_comment(lnum, col)
|
||||
if has('syntax_items')
|
||||
for id in synstack(a:lnum, a:col)
|
||||
let synname = synIDattr(id, "name")
|
||||
if synname == "rustString" || synname =~ "^rustComment"
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
else
|
||||
" without syntax, let's not even try
|
||||
return 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function GetRustIndent(lnum)
|
||||
|
||||
" Starting assumption: cindent (called at the end) will do it right
|
||||
" normally. We just want to fix up a few cases.
|
||||
|
||||
let line = getline(a:lnum)
|
||||
|
||||
if has('syntax_items')
|
||||
let synname = synIDattr(synID(a:lnum, 1, 1), "name")
|
||||
if synname == "rustString"
|
||||
" If the start of the line is in a string, don't change the indent
|
||||
return -1
|
||||
elseif synname =~ '\(Comment\|Todo\)'
|
||||
\ && line !~ '^\s*/\*' " not /* opening line
|
||||
if synname =~ "CommentML" " multi-line
|
||||
if line !~ '^\s*\*' && getline(a:lnum - 1) =~ '^\s*/\*'
|
||||
" This is (hopefully) the line after a /*, and it has no
|
||||
" leader, so the correct indentation is that of the
|
||||
" previous line.
|
||||
return GetRustIndent(a:lnum - 1)
|
||||
endif
|
||||
endif
|
||||
" If it's in a comment, let cindent take care of it now. This is
|
||||
" for cases like "/*" where the next line should start " * ", not
|
||||
" "* " as the code below would otherwise cause for module scope
|
||||
" Fun fact: " /*\n*\n*/" takes two calls to get right!
|
||||
return cindent(a:lnum)
|
||||
endif
|
||||
endif
|
||||
|
||||
" cindent gets second and subsequent match patterns/struct members wrong,
|
||||
" as it treats the comma as indicating an unfinished statement::
|
||||
"
|
||||
" match a {
|
||||
" b => c,
|
||||
" d => e,
|
||||
" f => g,
|
||||
" };
|
||||
|
||||
" Search backwards for the previous non-empty line.
|
||||
let prevlinenum = prevnonblank(a:lnum - 1)
|
||||
let prevline = s:get_line_trimmed(prevlinenum)
|
||||
while prevlinenum > 1 && prevline !~ '[^[:blank:]]'
|
||||
let prevlinenum = prevnonblank(prevlinenum - 1)
|
||||
let prevline = s:get_line_trimmed(prevlinenum)
|
||||
endwhile
|
||||
|
||||
" Handle where clauses nicely: subsequent values should line up nicely.
|
||||
if prevline[len(prevline) - 1] == ","
|
||||
\ && prevline =~# '^\s*where\s'
|
||||
return indent(prevlinenum) + 6
|
||||
endif
|
||||
|
||||
if prevline[len(prevline) - 1] == ","
|
||||
\ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]'
|
||||
\ && prevline !~ '^\s*fn\s'
|
||||
\ && prevline !~ '([^()]\+,$'
|
||||
\ && s:get_line_trimmed(a:lnum) !~ '^\s*\S\+\s*=>'
|
||||
" Oh ho! The previous line ended in a comma! I bet cindent will try to
|
||||
" take this too far... For now, let's normally use the previous line's
|
||||
" indent.
|
||||
|
||||
" One case where this doesn't work out is where *this* line contains
|
||||
" square or curly brackets; then we normally *do* want to be indenting
|
||||
" further.
|
||||
"
|
||||
" Another case where we don't want to is one like a function
|
||||
" definition with arguments spread over multiple lines:
|
||||
"
|
||||
" fn foo(baz: Baz,
|
||||
" baz: Baz) // <-- cindent gets this right by itself
|
||||
"
|
||||
" Another case is similar to the previous, except calling a function
|
||||
" instead of defining it, or any conditional expression that leaves
|
||||
" an open paren:
|
||||
"
|
||||
" foo(baz,
|
||||
" baz);
|
||||
"
|
||||
" if baz && (foo ||
|
||||
" bar) {
|
||||
"
|
||||
" Another case is when the current line is a new match arm.
|
||||
"
|
||||
" There are probably other cases where we don't want to do this as
|
||||
" well. Add them as needed.
|
||||
return indent(prevlinenum)
|
||||
endif
|
||||
|
||||
if !has("patch-7.4.355")
|
||||
" cindent before 7.4.355 doesn't do the module scope well at all; e.g.::
|
||||
"
|
||||
" static FOO : &'static [bool] = [
|
||||
" true,
|
||||
" false,
|
||||
" false,
|
||||
" true,
|
||||
" ];
|
||||
"
|
||||
" uh oh, next statement is indented further!
|
||||
|
||||
" Note that this does *not* apply the line continuation pattern properly;
|
||||
" that's too hard to do correctly for my liking at present, so I'll just
|
||||
" start with these two main cases (square brackets and not returning to
|
||||
" column zero)
|
||||
|
||||
call cursor(a:lnum, 1)
|
||||
if searchpair('{\|(', '', '}\|)', 'nbW',
|
||||
\ 's:is_string_comment(line("."), col("."))') == 0
|
||||
if searchpair('\[', '', '\]', 'nbW',
|
||||
\ 's:is_string_comment(line("."), col("."))') == 0
|
||||
" Global scope, should be zero
|
||||
return 0
|
||||
else
|
||||
" At the module scope, inside square brackets only
|
||||
"if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum
|
||||
if line =~ "^\\s*]"
|
||||
" It's the closing line, dedent it
|
||||
return 0
|
||||
else
|
||||
return &shiftwidth
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
" Fall back on cindent, which does it mostly right
|
||||
return cindent(a:lnum)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
295
runtime/syntax/rust.vim
Normal file
295
runtime/syntax/rust.vim
Normal file
@ -0,0 +1,295 @@
|
||||
" Vim syntax file
|
||||
" Language: Rust
|
||||
" Maintainer: Patrick Walton <pcwalton@mozilla.com>
|
||||
" Maintainer: Ben Blum <bblum@cs.cmu.edu>
|
||||
" Maintainer: Chris Morgan <me@chrismorgan.info>
|
||||
" Last Change: Feb 24, 2016
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
elseif exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
" Syntax definitions {{{1
|
||||
" Basic keywords {{{2
|
||||
syn keyword rustConditional match if else
|
||||
syn keyword rustRepeat for loop while
|
||||
syn keyword rustTypedef type nextgroup=rustIdentifier skipwhite skipempty
|
||||
syn keyword rustStructure struct enum nextgroup=rustIdentifier skipwhite skipempty
|
||||
syn keyword rustUnion union nextgroup=rustIdentifier skipwhite skipempty contained
|
||||
syn match rustUnionContextual /\<union\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*/ transparent contains=rustUnion
|
||||
syn keyword rustOperator as
|
||||
|
||||
syn match rustAssert "\<assert\(\w\)*!" contained
|
||||
syn match rustPanic "\<panic\(\w\)*!" contained
|
||||
syn keyword rustKeyword break
|
||||
syn keyword rustKeyword box nextgroup=rustBoxPlacement skipwhite skipempty
|
||||
syn keyword rustKeyword continue
|
||||
syn keyword rustKeyword extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty
|
||||
syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite skipempty
|
||||
syn keyword rustKeyword in impl let
|
||||
syn keyword rustKeyword pub nextgroup=rustPubScope skipwhite skipempty
|
||||
syn keyword rustKeyword return
|
||||
syn keyword rustSuper super
|
||||
syn keyword rustKeyword unsafe where
|
||||
syn keyword rustKeyword use nextgroup=rustModPath skipwhite skipempty
|
||||
" FIXME: Scoped impl's name is also fallen in this category
|
||||
syn keyword rustKeyword mod trait nextgroup=rustIdentifier skipwhite skipempty
|
||||
syn keyword rustStorage move mut ref static const
|
||||
syn match rustDefault /\<default\ze\_s\+\(impl\|fn\|type\|const\)\>/
|
||||
|
||||
syn keyword rustInvalidBareKeyword crate
|
||||
|
||||
syn keyword rustPubScopeCrate crate contained
|
||||
syn match rustPubScopeDelim /[()]/ contained
|
||||
syn match rustPubScope /([^()]*)/ contained contains=rustPubScopeDelim,rustPubScopeCrate,rustSuper,rustModPath,rustModPathSep,rustSelf transparent
|
||||
|
||||
syn keyword rustExternCrate crate contained nextgroup=rustIdentifier,rustExternCrateString skipwhite skipempty
|
||||
" This is to get the `bar` part of `extern crate "foo" as bar;` highlighting.
|
||||
syn match rustExternCrateString /".*"\_s*as/ contained nextgroup=rustIdentifier skipwhite transparent skipempty contains=rustString,rustOperator
|
||||
syn keyword rustObsoleteExternMod mod contained nextgroup=rustIdentifier skipwhite skipempty
|
||||
|
||||
syn match rustIdentifier contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
|
||||
syn match rustFuncName "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
|
||||
|
||||
syn region rustBoxPlacement matchgroup=rustBoxPlacementParens start="(" end=")" contains=TOP contained
|
||||
" Ideally we'd have syntax rules set up to match arbitrary expressions. Since
|
||||
" we don't, we'll just define temporary contained rules to handle balancing
|
||||
" delimiters.
|
||||
syn region rustBoxPlacementBalance start="(" end=")" containedin=rustBoxPlacement transparent
|
||||
syn region rustBoxPlacementBalance start="\[" end="\]" containedin=rustBoxPlacement transparent
|
||||
" {} are handled by rustFoldBraces
|
||||
|
||||
syn region rustMacroRepeat matchgroup=rustMacroRepeatDelimiters start="$(" end=")" contains=TOP nextgroup=rustMacroRepeatCount
|
||||
syn match rustMacroRepeatCount ".\?[*+]" contained
|
||||
syn match rustMacroVariable "$\w\+"
|
||||
|
||||
" Reserved (but not yet used) keywords {{{2
|
||||
syn keyword rustReservedKeyword alignof become do offsetof priv pure sizeof typeof unsized yield abstract virtual final override macro
|
||||
|
||||
" Built-in types {{{2
|
||||
syn keyword rustType isize usize char bool u8 u16 u32 u64 u128 f32
|
||||
syn keyword rustType f64 i8 i16 i32 i64 i128 str Self
|
||||
|
||||
" Things from the libstd v1 prelude (src/libstd/prelude/v1.rs) {{{2
|
||||
" This section is just straight transformation of the contents of the prelude,
|
||||
" to make it easy to update.
|
||||
|
||||
" Reexported core operators {{{3
|
||||
syn keyword rustTrait Copy Send Sized Sync
|
||||
syn keyword rustTrait Drop Fn FnMut FnOnce
|
||||
|
||||
" Reexported functions {{{3
|
||||
" There’s no point in highlighting these; when one writes drop( or drop::< it
|
||||
" gets the same highlighting anyway, and if someone writes `let drop = …;` we
|
||||
" don’t really want *that* drop to be highlighted.
|
||||
"syn keyword rustFunction drop
|
||||
|
||||
" Reexported types and traits {{{3
|
||||
syn keyword rustTrait Box
|
||||
syn keyword rustTrait ToOwned
|
||||
syn keyword rustTrait Clone
|
||||
syn keyword rustTrait PartialEq PartialOrd Eq Ord
|
||||
syn keyword rustTrait AsRef AsMut Into From
|
||||
syn keyword rustTrait Default
|
||||
syn keyword rustTrait Iterator Extend IntoIterator
|
||||
syn keyword rustTrait DoubleEndedIterator ExactSizeIterator
|
||||
syn keyword rustEnum Option
|
||||
syn keyword rustEnumVariant Some None
|
||||
syn keyword rustEnum Result
|
||||
syn keyword rustEnumVariant Ok Err
|
||||
syn keyword rustTrait SliceConcatExt
|
||||
syn keyword rustTrait String ToString
|
||||
syn keyword rustTrait Vec
|
||||
|
||||
" Other syntax {{{2
|
||||
syn keyword rustSelf self
|
||||
syn keyword rustBoolean true false
|
||||
|
||||
" If foo::bar changes to foo.bar, change this ("::" to "\.").
|
||||
" If foo::bar changes to Foo::bar, change this (first "\w" to "\u").
|
||||
syn match rustModPath "\w\(\w\)*::[^<]"he=e-3,me=e-3
|
||||
syn match rustModPathSep "::"
|
||||
|
||||
syn match rustFuncCall "\w\(\w\)*("he=e-1,me=e-1
|
||||
syn match rustFuncCall "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>();
|
||||
|
||||
" This is merely a convention; note also the use of [A-Z], restricting it to
|
||||
" latin identifiers rather than the full Unicode uppercase. I have not used
|
||||
" [:upper:] as it depends upon 'noignorecase'
|
||||
"syn match rustCapsIdent display "[A-Z]\w\(\w\)*"
|
||||
|
||||
syn match rustOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?"
|
||||
" This one isn't *quite* right, as we could have binary-& with a reference
|
||||
syn match rustSigil display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1
|
||||
syn match rustSigil display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1
|
||||
" This isn't actually correct; a closure with no arguments can be `|| { }`.
|
||||
" Last, because the & in && isn't a sigil
|
||||
syn match rustOperator display "&&\|||"
|
||||
" This is rustArrowCharacter rather than rustArrow for the sake of matchparen,
|
||||
" so it skips the ->; see http://stackoverflow.com/a/30309949 for details.
|
||||
syn match rustArrowCharacter display "->"
|
||||
syn match rustQuestionMark display "?\([a-zA-Z]\+\)\@!"
|
||||
|
||||
syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustPanic
|
||||
syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustPanic
|
||||
|
||||
syn match rustEscapeError display contained /\\./
|
||||
syn match rustEscape display contained /\\\([nrt0\\'"]\|x\x\{2}\)/
|
||||
syn match rustEscapeUnicode display contained /\\u{\x\{1,6}}/
|
||||
syn match rustStringContinuation display contained /\\\n\s*/
|
||||
syn region rustString start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation
|
||||
syn region rustString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell
|
||||
syn region rustString start='b\?r\z(#*\)"' end='"\z1' contains=@Spell
|
||||
|
||||
syn region rustAttribute start="#!\?\[" end="\]" contains=rustString,rustDerive,rustCommentLine,rustCommentBlock,rustCommentLineDocError,rustCommentBlockDocError
|
||||
syn region rustDerive start="derive(" end=")" contained contains=rustDeriveTrait
|
||||
" This list comes from src/libsyntax/ext/deriving/mod.rs
|
||||
" Some are deprecated (Encodable, Decodable) or to be removed after a new snapshot (Show).
|
||||
syn keyword rustDeriveTrait contained Clone Hash RustcEncodable RustcDecodable Encodable Decodable PartialEq Eq PartialOrd Ord Rand Show Debug Default FromPrimitive Send Sync Copy
|
||||
|
||||
" Number literals
|
||||
syn match rustDecNumber display "\<[0-9][0-9_]*\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
|
||||
syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
|
||||
syn match rustOctNumber display "\<0o[0-7_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
|
||||
syn match rustBinNumber display "\<0b[01_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
|
||||
|
||||
" Special case for numbers of the form "1." which are float literals, unless followed by
|
||||
" an identifier, which makes them integer literals with a method call or field access,
|
||||
" or by another ".", which makes them integer literals followed by the ".." token.
|
||||
" (This must go first so the others take precedence.)
|
||||
syn match rustFloat display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!"
|
||||
" To mark a number as a normal float, it must have at least one of the three things integral values don't have:
|
||||
" a decimal point and more numbers; an exponent; and a type suffix.
|
||||
syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\="
|
||||
syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\="
|
||||
syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)"
|
||||
|
||||
" For the benefit of delimitMate
|
||||
syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u{\x\{1,6}}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
|
||||
syn region rustGenericRegion display start=/<\%('\|[^[cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate
|
||||
syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
|
||||
|
||||
"rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting
|
||||
syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
|
||||
syn match rustLabel display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*:"
|
||||
syn match rustCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/
|
||||
" The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII).
|
||||
syn match rustCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/
|
||||
syn match rustCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode
|
||||
syn match rustCharacter /'\([^\\]\|\\\(.\|x\x\{2}\|u{\x\{1,6}}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid
|
||||
|
||||
syn match rustShebang /\%^#![^[].*/
|
||||
syn region rustCommentLine start="//" end="$" contains=rustTodo,@Spell
|
||||
syn region rustCommentLineDoc start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell
|
||||
syn region rustCommentLineDocError start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell contained
|
||||
syn region rustCommentBlock matchgroup=rustCommentBlock start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell
|
||||
syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell
|
||||
syn region rustCommentBlockDocError matchgroup=rustCommentBlockDocError start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained
|
||||
syn region rustCommentBlockNest matchgroup=rustCommentBlock start="/\*" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent
|
||||
syn region rustCommentBlockDocNest matchgroup=rustCommentBlockDoc start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent
|
||||
syn region rustCommentBlockDocNestError matchgroup=rustCommentBlockDocError start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained transparent
|
||||
" FIXME: this is a really ugly and not fully correct implementation. Most
|
||||
" importantly, a case like ``/* */*`` should have the final ``*`` not being in
|
||||
" a comment, but in practice at present it leaves comments open two levels
|
||||
" deep. But as long as you stay away from that particular case, I *believe*
|
||||
" the highlighting is correct. Due to the way Vim's syntax engine works
|
||||
" (greedy for start matches, unlike Rust's tokeniser which is searching for
|
||||
" the earliest-starting match, start or end), I believe this cannot be solved.
|
||||
" Oh you who would fix it, don't bother with things like duplicating the Block
|
||||
" rules and putting ``\*\@<!`` at the start of them; it makes it worse, as
|
||||
" then you must deal with cases like ``/*/**/*/``. And don't try making it
|
||||
" worse with ``\%(/\@<!\*\)\@<!``, either...
|
||||
|
||||
syn keyword rustTodo contained TODO FIXME XXX NB NOTE
|
||||
|
||||
" Folding rules {{{2
|
||||
" Trivial folding rules to begin with.
|
||||
" FIXME: use the AST to make really good folding
|
||||
syn region rustFoldBraces start="{" end="}" transparent fold
|
||||
|
||||
" Default highlighting {{{1
|
||||
hi def link rustDecNumber rustNumber
|
||||
hi def link rustHexNumber rustNumber
|
||||
hi def link rustOctNumber rustNumber
|
||||
hi def link rustBinNumber rustNumber
|
||||
hi def link rustIdentifierPrime rustIdentifier
|
||||
hi def link rustTrait rustType
|
||||
hi def link rustDeriveTrait rustTrait
|
||||
|
||||
hi def link rustMacroRepeatCount rustMacroRepeatDelimiters
|
||||
hi def link rustMacroRepeatDelimiters Macro
|
||||
hi def link rustMacroVariable Define
|
||||
hi def link rustSigil StorageClass
|
||||
hi def link rustEscape Special
|
||||
hi def link rustEscapeUnicode rustEscape
|
||||
hi def link rustEscapeError Error
|
||||
hi def link rustStringContinuation Special
|
||||
hi def link rustString String
|
||||
hi def link rustCharacterInvalid Error
|
||||
hi def link rustCharacterInvalidUnicode rustCharacterInvalid
|
||||
hi def link rustCharacter Character
|
||||
hi def link rustNumber Number
|
||||
hi def link rustBoolean Boolean
|
||||
hi def link rustEnum rustType
|
||||
hi def link rustEnumVariant rustConstant
|
||||
hi def link rustConstant Constant
|
||||
hi def link rustSelf Constant
|
||||
hi def link rustFloat Float
|
||||
hi def link rustArrowCharacter rustOperator
|
||||
hi def link rustOperator Operator
|
||||
hi def link rustKeyword Keyword
|
||||
hi def link rustTypedef Keyword " More precise is Typedef, but it doesn't feel right for Rust
|
||||
hi def link rustStructure Keyword " More precise is Structure
|
||||
hi def link rustUnion rustStructure
|
||||
hi def link rustPubScopeDelim Delimiter
|
||||
hi def link rustPubScopeCrate rustKeyword
|
||||
hi def link rustSuper rustKeyword
|
||||
hi def link rustReservedKeyword Error
|
||||
hi def link rustRepeat Conditional
|
||||
hi def link rustConditional Conditional
|
||||
hi def link rustIdentifier Identifier
|
||||
hi def link rustCapsIdent rustIdentifier
|
||||
hi def link rustModPath Include
|
||||
hi def link rustModPathSep Delimiter
|
||||
hi def link rustFunction Function
|
||||
hi def link rustFuncName Function
|
||||
hi def link rustFuncCall Function
|
||||
hi def link rustShebang Comment
|
||||
hi def link rustCommentLine Comment
|
||||
hi def link rustCommentLineDoc SpecialComment
|
||||
hi def link rustCommentLineDocError Error
|
||||
hi def link rustCommentBlock rustCommentLine
|
||||
hi def link rustCommentBlockDoc rustCommentLineDoc
|
||||
hi def link rustCommentBlockDocError Error
|
||||
hi def link rustAssert PreCondit
|
||||
hi def link rustPanic PreCondit
|
||||
hi def link rustMacro Macro
|
||||
hi def link rustType Type
|
||||
hi def link rustTodo Todo
|
||||
hi def link rustAttribute PreProc
|
||||
hi def link rustDerive PreProc
|
||||
hi def link rustDefault StorageClass
|
||||
hi def link rustStorage StorageClass
|
||||
hi def link rustObsoleteStorage Error
|
||||
hi def link rustLifetime Special
|
||||
hi def link rustLabel Label
|
||||
hi def link rustInvalidBareKeyword Error
|
||||
hi def link rustExternCrate rustKeyword
|
||||
hi def link rustObsoleteExternMod Error
|
||||
hi def link rustBoxPlacementParens Delimiter
|
||||
hi def link rustQuestionMark Special
|
||||
|
||||
" Other Suggestions:
|
||||
" hi rustAttribute ctermfg=cyan
|
||||
" hi rustDerive ctermfg=cyan
|
||||
" hi rustAssert ctermfg=yellow
|
||||
" hi rustPanic ctermfg=red
|
||||
" hi rustMacro ctermfg=magenta
|
||||
|
||||
syn sync minlines=200
|
||||
syn sync maxlines=500
|
||||
|
||||
let b:current_syntax = "rust"
|
Loading…
Reference in New Issue
Block a user