diff options
38 files changed, 1372 insertions, 927 deletions
| diff --git a/after/syntax/javascript/graphql.vim b/after/syntax/javascript/graphql.vim index 58c1de08..eb862e05 100644 --- a/after/syntax/javascript/graphql.vim +++ b/after/syntax/javascript/graphql.vim @@ -9,11 +9,17 @@ if exists('s:current_syntax')    let b:current_syntax = s:current_syntax  endif -syntax region graphqlTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=@GraphQLSyntax,jsTemplateExpression,jsSpecial extend -exec 'syntax match graphqlTaggedTemplate +\%(' . join(g:graphql_javascript_tags, '\|') . '\)\%(`\)\@=+ nextgroup=graphqlTemplateString' +let s:tags = '\%(' . join(g:graphql_javascript_tags, '\|') . '\)' + +exec 'syntax region graphqlTemplateString start=+' . s:tags . '\@20<=`+ skip=+\\`+ end=+`+ contains=@GraphQLSyntax,jsTemplateExpression,jsSpecial extend' +exec 'syntax match graphqlTaggedTemplate +' . s:tags . '\ze`+ nextgroup=graphqlTemplateString' + +" Support expression interpolation ((${...})) inside template strings. +syntax region graphqlTemplateExpression start=+${+ end=+}+ contained contains=jsTemplateExpression containedin=graphqlFold keepend  hi def link graphqlTemplateString jsTemplateString  hi def link graphqlTaggedTemplate jsTaggedTemplate +hi def link graphqlTemplateExpression jsTemplateExpression  syn cluster jsExpression add=graphqlTaggedTemplate  syn cluster graphqlTaggedTemplate add=graphqlTemplateString diff --git a/after/syntax/rust.vim b/after/syntax/rust.vim index 9a317956..3e2c2077 100644 --- a/after/syntax/rust.vim +++ b/after/syntax/rust.vim @@ -1,12 +1,14 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 -if !exists('g:rust_conceal') || g:rust_conceal == 0 || !has('conceal') || &enc != 'utf-8' -	finish +scriptencoding utf-8 + +if !get(g:, 'rust_conceal', 0) || !has('conceal') || &encoding !=# 'utf-8' +    finish  endif  " For those who don't want to see `::`... -if exists('g:rust_conceal_mod_path') && g:rust_conceal_mod_path != 0 -	syn match rustNiceOperator "::" conceal cchar=ㆍ +if get(g:, 'rust_conceal_mod_path', 0) +    syn match rustNiceOperator "::" conceal cchar=ㆍ  endif  syn match rustRightArrowHead contained ">" conceal cchar=  @@ -20,7 +22,7 @@ syn match rustNiceOperator "=>" contains=rustFatRightArrowHead,rustFatRightArrow  syn match rustNiceOperator /\<\@!_\(_*\>\)\@=/ conceal cchar=′  " For those who don't want to see `pub`... -if exists('g:rust_conceal_pub') && g:rust_conceal_pub != 0 +if get(g:, 'rust_conceal_pub', 0)      syn match rustPublicSigil contained "pu" conceal cchar=*      syn match rustPublicRest contained "b" conceal cchar=       syn match rustNiceOperator "pub " contains=rustPublicSigil,rustPublicRest @@ -28,11 +30,16 @@ endif  hi link rustNiceOperator Operator -if !(exists('g:rust_conceal_mod_path') && g:rust_conceal_mod_path != 0) +if !get(g:, 'rust_conceal_mod_path', 0)      hi! link Conceal Operator -    " And keep it after a colorscheme change -    au ColorScheme <buffer> hi! link Conceal Operator +    augroup rust.vim.after +        autocmd! +        " And keep it after a colorscheme change +        autocmd ColorScheme <buffer> hi! link Conceal Operator +    augroup END  endif +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/after/syntax/typescript/graphql.vim b/after/syntax/typescript/graphql.vim index 53999699..5fc9ab41 100644 --- a/after/syntax/typescript/graphql.vim +++ b/after/syntax/typescript/graphql.vim @@ -9,10 +9,16 @@ if exists('s:current_syntax')    let b:current_syntax = s:current_syntax  endif -syntax region graphqlTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=@GraphQLSyntax,typescriptTemplateTag extend -exec 'syntax match graphqlTaggedTemplate +\%(' . join(g:graphql_javascript_tags, '\|') . '\)\%(`\)\@=+ nextgroup=graphqlTemplateString' +let s:tags = '\%(' . join(g:graphql_javascript_tags, '\|') . '\)' + +exec 'syntax region graphqlTemplateString start=+' . s:tags . '\@20<=`+ skip=+\\`+ end=+`+ contains=@GraphQLSyntax,typescriptTemplateSubstitution extend' +exec 'syntax match graphqlTaggedTemplate +' . s:tags . '\ze`+ nextgroup=graphqlTemplateString' + +" Support expression interpolation ((${...})) inside template strings. +syntax region graphqlTemplateExpression start=+${+ end=+}+ contained contains=typescriptTemplateSubstitution containedin=graphqlFold keepend  hi def link graphqlTemplateString typescriptTemplate +hi def link graphqlTemplateExpression typescriptTemplateSubstitution  syn cluster typescriptExpression add=graphqlTaggedTemplate  syn cluster graphqlTaggedTemplate add=graphqlTemplateString diff --git a/autoload/cargo.vim b/autoload/cargo.vim index e92da22b..d1547fc9 100644 --- a/autoload/cargo.vim +++ b/autoload/cargo.vim @@ -1,89 +1,91 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 +function! cargo#Load()  +    " Utility call to get this script loaded, for debugging +endfunction +  function! cargo#cmd(args) -    silent! clear -    if !a:args -        execute "!" . "cargo ". a:args +    execute "! cargo" a:args +endfunction + +function! s:nearest_cargo(...) abort +    " If the second argument is not specified, the first argument determines +    " whether we will start from the current directory or the directory of the +    " current buffer, otherwise, we start with the provided path on the  +    " second argument. + +    let l:is_getcwd = get(a:, 1, 0) +    if l:is_getcwd  +        let l:starting_path = get(a:, 2, getcwd())      else -        echom "Missing arguments" +        let l:starting_path = get(a:, 2, expand('%:p:h'))      endif + +    return findfile('Cargo.toml', l:starting_path . ';')  endfunction -function! cargo#build(args) -    silent! clear -    if !a:args -        execute "!" . "cargo build " . a:args -    else -        execute "!" . "cargo build" +function! cargo#nearestCargo(is_getcwd) abort +    return s:nearest_cargo(a:is_getcwd) +endfunction + +function! cargo#nearestWorkspaceCargo(is_getcwd) abort +    let l:nearest = s:nearest_cargo(a:is_getcwd) +    while l:nearest !=# '' +        for l:line in readfile(l:nearest, '', 0x100) +            if l:line =~# '\V[workspace]' +                return l:nearest +            endif +        endfor +        let l:next = fnamemodify(l:nearest, ':p:h:h') +        let l:nearest = s:nearest_cargo(0, l:next) +    endwhile +    return '' +endfunction + +function! cargo#nearestRootCargo(is_getcwd) abort +    " Try to find a workspace Cargo.toml, and if not found, take the nearest +    " regular Cargo.toml +    let l:workspace_cargo = cargo#nearestWorkspaceCargo(a:is_getcwd) +    if l:workspace_cargo !=# '' +        return l:workspace_cargo      endif -    silent! clear -    execute "!" . "cargo build" +    return s:nearest_cargo(a:is_getcwd) +endfunction + + +function! cargo#build(args) +    call cargo#cmd("build " . a:args)  endfunction  function! cargo#clean(args) -    silent! clear -    if !a:args -        execute "!" . "cargo clean " . a:args -    else -        execute "!" . "cargo clean" -    endif -    silent! clear -    execute "!" . "cargo clean" +    call cargo#cmd("clean " . a:args)  endfunction  function! cargo#doc(args) -    silent! clear -    if !a:args -        execute "!" . "cargo doc " . a:args -    else -        execute "!" . "cargo doc" -    endif +    call cargo#cmd("doc " . a:args)  endfunction  function! cargo#new(args) -    silent! clear -    if !a:args -        execute "!cargo new " . a:args -        :cd `=a:args` -    else -        echom "Missing arguments" -    endif +    call cargo#cmd("new " . a:args) +    cd `=a:args`  endfunction  function! cargo#init(args) -    silent! clear -    if !a:args -        execute "!" . "cargo init " . a:args -    else -        execute "!" . "cargo init" -    endif +    call cargo#cmd("init " . a:args)  endfunction  function! cargo#run(args) -    silent! clear -    if !a:args -        execute "!" . "cargo run " . a:args -    else -        execute "!" . "cargo run" -    endif +    call cargo#cmd("run " . a:args)  endfunction  function! cargo#test(args) -    silent! clear -    if !a:args -        execute "!" . "cargo test " . a:args -    else -        execute "!" . "cargo test" -    endif +    call cargo#cmd("test " . a:args)  endfunction  function! cargo#bench(args) -    silent! clear -    if !a:args -        execute "!" . "cargo bench " . a:args -    else -        execute "!" . "cargo bench" -    endif +    call cargo#cmd("bench " . a:args)  endfunction +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/autoload/cargo/quickfix.vim b/autoload/cargo/quickfix.vim new file mode 100644 index 00000000..13c3b465 --- /dev/null +++ b/autoload/cargo/quickfix.vim @@ -0,0 +1,30 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 +   +function! cargo#quickfix#CmdPre() abort +    if &filetype ==# 'rust' && get(b:, 'current_compiler', '') ==# 'cargo' +        " Preserve the current directory, and 'lcd' to the nearest Cargo file. +        let b:rust_compiler_cargo_qf_has_lcd = haslocaldir() +        let b:rust_compiler_cargo_qf_prev_cd = getcwd() +        let b:rust_compiler_cargo_qf_prev_cd_saved = 1 +        let l:nearest = fnamemodify(cargo#nearestRootCargo(0), ':h') +        execute 'lchdir! '.l:nearest +    else +        let b:rust_compiler_cargo_qf_prev_cd_saved = 0 +    endif +endfunction + +function! cargo#quickfix#CmdPost() abort +    if b:rust_compiler_cargo_qf_prev_cd_saved +        " Restore the current directory. +        if b:rust_compiler_cargo_qf_has_lcd +            execute 'lchdir! '.b:rust_compiler_cargo_qf_prev_cd +        else +            execute 'chdir! '.b:rust_compiler_cargo_qf_prev_cd +        endif +        let b:rust_compiler_cargo_qf_prev_cd_saved = 0 +    endif +endfunction + +" vim: set et sw=4 sts=4 ts=8: + +endif diff --git a/autoload/rubycomplete.vim b/autoload/rubycomplete.vim index 8cb73fd5..1184c427 100644 --- a/autoload/rubycomplete.vim +++ b/autoload/rubycomplete.vim @@ -261,7 +261,7 @@ class VimRubyCompletion      nums.each do |x|        ln = buf[x]        begin -        eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln ) +        eval( "require %s" % $1 ) if /.*require\s*(["'].*?["'])/.match( ln )        rescue Exception          #ignore?        end diff --git a/autoload/rust.vim b/autoload/rust.vim index 6edc48f7..7e766da1 100644 --- a/autoload/rust.vim +++ b/autoload/rust.vim @@ -7,203 +7,219 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " Jump {{{1 +function! rust#Load()  +    " Utility call to get this script loaded, for debugging +endfunction + +function! rust#GetConfigVar(name, default) +    " Local buffer variable with same name takes predeence over global +    if has_key(b:, a:name)  +        return get(b:, a:name) +    endif +    if has_key(g:, a:name)  +        return get(g:, a:name) +    endif +    return a:default +endfunction + +  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 +    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[{ +    call search('{', 'b') +    keepjumps normal! w99[{  endfunction  function! s:Jump_Forward() -	normal! j0 -	call search('{', 'b') -	keepjumps normal! w99[{% -	call search('{') +    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) +    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 +    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) +    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 +    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) +    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) +    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 +    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 @@ -221,145 +237,145 @@ endfunction  " 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 +    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 +    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 +    " 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)) +    " 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) +    let cmd = a:cmd +    if !empty(a:pwd) +        let cmd = 'cd ' . shellescape(a:pwd) . ' && ' . cmd +    endif +    return system(cmd)  endfunction  " Playpen Support {{{1 @@ -368,10 +384,10 @@ endfunction  " http://github.com/mattn/gist-vim  function! s:has_webapi()      if !exists("*webapi#http#post") -	try -	    call webapi#http#post() -	catch -	endtry +        try +            call webapi#http#post() +        catch +        endtry      endif      return exists("*webapi#http#post")  endfunction @@ -383,26 +399,26 @@ function! rust#Play(count, line1, line2, ...) abort      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 +        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") +        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) +        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 +        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) @@ -410,7 +426,7 @@ function! rust#Play(count, line1, line2, ...) abort      let url = res.content      if exists('g:rust_clip_command') -	call system(g:rust_clip_command, url) +        call system(g:rust_clip_command, url)      endif      redraw | echomsg 'Done: '.url @@ -418,6 +434,6 @@ endfunction  " }}}1 -" vim: set noet sw=8 ts=8: +" vim: set et sw=4 sts=4 ts=8:  endif diff --git a/autoload/rust/debugging.vim b/autoload/rust/debugging.vim new file mode 100644 index 00000000..352556d7 --- /dev/null +++ b/autoload/rust/debugging.vim @@ -0,0 +1,98 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 +   +" For debugging, inspired by https://github.com/w0rp/rust/blob/master/autoload/rust/debugging.vim + +let s:global_variable_list = [ +            \ 'ftplugin_rust_source_path', +            \ 'loaded_syntastic_rust_cargo_checker', +            \ 'loaded_syntastic_rust_filetype', +            \ 'loaded_syntastic_rust_rustc_checker', +            \ 'rust_bang_comment_leader', +            \ 'rust_cargo_avoid_whole_workspace', +            \ 'rust_clip_command', +            \ 'rust_conceal', +            \ 'rust_conceal_mod_path', +            \ 'rust_conceal_pub', +            \ 'rust_fold', +            \ 'rust_last_args', +            \ 'rust_last_rustc_args', +            \ 'rust_original_delimitMate_excluded_regions', +            \ 'rust_playpen_url', +            \ 'rust_recent_nearest_cargo_tol', +            \ 'rust_recent_root_cargo_toml', +            \ 'rust_recommended_style', +            \ 'rust_set_conceallevel', +            \ 'rust_set_conceallevel=1', +            \ 'rust_set_foldmethod', +            \ 'rust_set_foldmethod=1', +            \ 'rust_shortener_url', +            \ 'rustc_makeprg_no_percent', +            \ 'rustc_path', +            \ 'rustfmt_autosave', +            \ 'rustfmt_autosave_because_of_config', +            \ 'rustfmt_autosave_if_config_present', +            \ 'rustfmt_command', +            \ 'rustfmt_emit_files', +            \ 'rustfmt_fail_silently', +            \ 'rustfmt_options', +            \ 'syntastic_extra_filetypes', +            \ 'syntastic_rust_cargo_fname', +            \] + +function! s:Echo(message) abort +    execute 'echo a:message' +endfunction + +function! s:EchoGlobalVariables() abort +    for l:key in s:global_variable_list +        call s:Echo('let g:' . l:key . ' = ' . string(get(g:, l:key, v:null))) + +        if has_key(b:, l:key) +            call s:Echo('let b:' . l:key . ' = ' . string(b:[l:key])) +        endif +    endfor +endfunction + +function! rust#debugging#Info() abort +    call cargo#Load() +    call rust#Load() +    call rustfmt#Load() +    call s:Echo('rust.vim Global Variables:') +    call s:Echo('') +    call s:EchoGlobalVariables() + +    silent let l:output = system(g:rustfmt_command . ' --version') +    echo l:output + +    let l:rustc = exists("g:rustc_path") ? g:rustc_path : "rustc" +    silent let l:output = system(l:rustc . ' --version') +    echo l:output + +    silent let l:output = system('cargo --version') +    echo l:output + +    version +endfunction + +function! rust#debugging#InfoToClipboard() abort +    redir @" +    silent call rust#debugging#Info() +    redir END + +    call s:Echo('RustInfo copied to your clipboard') +endfunction + +function! rust#debugging#InfoToFile(filename) abort +    let l:expanded_filename = expand(a:filename) + +    redir => l:output +    silent call rust#debugging#Info() +    redir END + +    call writefile(split(l:output, "\n"), l:expanded_filename) +    call s:Echo('RustInfo written to ' . l:expanded_filename) +endfunction + +" vim: set et sw=4 sts=4 ts=8: + +endif diff --git a/autoload/rustfmt.vim b/autoload/rustfmt.vim index 307fead7..c0335173 100644 --- a/autoload/rustfmt.vim +++ b/autoload/rustfmt.vim @@ -6,106 +6,187 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " For bugs, patches and license go to https://github.com/rust-lang/rust.vim  if !exists("g:rustfmt_autosave") -	let g:rustfmt_autosave = 0 +    let g:rustfmt_autosave = 0  endif  if !exists("g:rustfmt_command") -	let g:rustfmt_command = "rustfmt" +    let g:rustfmt_command = "rustfmt"  endif  if !exists("g:rustfmt_options") -	let g:rustfmt_options = "" +    let g:rustfmt_options = ""  endif  if !exists("g:rustfmt_fail_silently") -	let g:rustfmt_fail_silently = 0 +    let g:rustfmt_fail_silently = 0 +endif + +function! rustfmt#DetectVersion() +    " Save rustfmt '--help' for feature inspection +    silent let s:rustfmt_help = system(g:rustfmt_command . " --help") +    let s:rustfmt_unstable_features = 1 - (s:rustfmt_help !~# "--unstable-features") + +    " Build a comparable rustfmt version varible out of its `--version` output: +    silent let s:rustfmt_version = system(g:rustfmt_command . " --version") +    let s:rustfmt_version = matchlist(s:rustfmt_version, '\vrustfmt ([0-9]+[.][0-9]+[.][0-9]+)') + +    if len(s:rustfmt_version) < 3  +        let s:rustfmt_version = "0" +    else +        let s:rustfmt_version = s:rustfmt_version[1] +    endif + +    return s:rustfmt_version +endfunction + +call rustfmt#DetectVersion() + +if !exists("g:rustfmt_emit_files") +    let g:rustfmt_emit_files = s:rustfmt_version >= "0.8.2" +endif + +if !exists("g:rustfmt_file_lines") +    let g:rustfmt_file_lines = 1 - (s:rustfmt_help !~# "--file-lines JSON")  endif  let s:got_fmt_error = 0 +function! rustfmt#Load() +    " Utility call to get this script loaded, for debugging +endfunction + +function! s:RustfmtWriteMode() +    if g:rustfmt_emit_files +        return "--emit=files" +    else +        return "--write-mode=overwrite" +    endif +endfunction +  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)) +    if g:rustfmt_file_lines == 0 +        echo "--file-lines is not supported in the installed `rustfmt` executable" +        return +    endif + +    let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]} +    let l:write_mode = s:RustfmtWriteMode() + +    " FIXME: When --file-lines gets to be stable, enhance this version range checking +    " accordingly. +    let l:unstable_features =  +                \ (s:rustfmt_unstable_features && (s:rustfmt_version < '1.')) +                \ ? '--unstable-features' : '' + +    let l:cmd = printf("%s %s %s %s --file-lines '[%s]' %s", g:rustfmt_command,  +                \ l:write_mode, g:rustfmt_options,  +                \ l:unstable_features, json_encode(l:arg), shellescape(a:filename)) +    return l:cmd  endfunction  function! s:RustfmtCommand(filename) -	return g:rustfmt_command . " --write-mode=overwrite " . g:rustfmt_options . " " . shellescape(a:filename) +    let l:write_mode = s:RustfmtWriteMode() +    return g:rustfmt_command . " ". l:write_mode . " " . 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) +function! s:RunRustfmt(command, tmpname, fail_silently) +    mkview! + +    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 + +        " take the tmpfile's content, this is better than rename +        " because it preserves file modes. +        let l:content = readfile(a:tmpname) +        1,$d _ +        call setline(1, l:content) + +        " 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 && a:fail_silently == 0 +        " otherwise get the errors and put them in the location list +        let errors = [] + +        let prev_line = "" +        for line in out +            " error: expected one of `;` or `as`, found `extern` +            "  --> src/main.rs:2:1 +            let tokens = matchlist(line, '^\s-->\s\(.\{-}\):\(\d\+\):\(\d\+\)$') +            if !empty(tokens) +                call add(errors, {"filename": @%, +                            \"lnum":	tokens[2], +                            \"col":	tokens[3], +                            \"text":	prev_line}) +            endif +            let prev_line = line +        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 +    endif + +    call delete(a:tmpname) + +    silent! loadview  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) +function! s:rustfmtSaveToTmp() +    let l:tmpname = tempname() +    call writefile(getline(1, '$'), l:tmpname) +    return l:tmpname +endfunction -	call s:RunRustfmt(command, l:curw, l:tmpname) +function! rustfmt#FormatRange(line1, line2) +    let l:tmpname = s:rustfmtSaveToTmp() +    let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2) +    call s:RunRustfmt(command, l:tmpname, 0)  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) +    let l:tmpname = s:rustfmtSaveToTmp() +    let command = s:RustfmtCommand(l:tmpname) +    call s:RunRustfmt(command, l:tmpname, 0) +endfunction -	call s:RunRustfmt(command, l:curw, l:tmpname) +function! rustfmt#PreWrite() +    if rust#GetConfigVar('rustfmt_autosave_if_config_present', 0) +        if findfile('rustfmt.toml', '.;') !=# ''  +            let b:rustfmt_autosave = 1 +            let b:rustfmt_autosave_because_of_config = 1 +        endif +    endif + +    if !rust#GetConfigVar("rustfmt_autosave", 0) +        return +    endif + +    let l:tmpname = s:rustfmtSaveToTmp() +    let command = s:RustfmtCommand(l:tmpname) +    call s:RunRustfmt(command, l:tmpname, 1)  endfunction + +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/compiler/cargo.vim b/compiler/cargo.vim index 8e3c6212..10147e00 100644 --- a/compiler/cargo.vim +++ b/compiler/cargo.vim @@ -7,7 +7,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " For bugs, patches and license go to https://github.com/rust-lang/rust.vim  if exists('current_compiler') -	finish +    finish  endif  runtime compiler/rustc.vim  let current_compiler = "cargo" @@ -16,26 +16,34 @@ let s:save_cpo = &cpo  set cpo&vim  if exists(':CompilerSet') != 2 -	command -nargs=* CompilerSet setlocal <args> +    command -nargs=* CompilerSet setlocal <args>  endif  if exists('g:cargo_makeprg_params') -	execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*' +    execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*'  else -	CompilerSet makeprg=cargo\ $* +    CompilerSet makeprg=cargo\ $*  endif +augroup RustCargoQuickFixHooks +    autocmd! +    autocmd QuickFixCmdPre make call cargo#quickfix#CmdPre() +    autocmd QuickFixCmdPost make call cargo#quickfix#CmdPost() +augroup END +  " 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\\,%.%#, -			\%-Gnote:\ Run\ with\ \`RUST_BACKTRACE=%.%#, -			\%.%#panicked\ at\ \\'%m\\'\\,\ %f:%l +            \%-G%\\s%#Downloading%.%#, +            \%-G%\\s%#Compiling%.%#, +            \%-G%\\s%#Finished%.%#, +            \%-G%\\s%#error:\ Could\ not\ compile\ %.%#, +            \%-G%\\s%#To\ learn\ more\\,%.%#, +            \%-Gnote:\ Run\ with\ \`RUST_BACKTRACE=%.%#, +            \%.%#panicked\ at\ \\'%m\\'\\,\ %f:%l:%c  let &cpo = s:save_cpo  unlet s:save_cpo +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/compiler/rustc.vim b/compiler/rustc.vim index 7b691b31..23390fd9 100644 --- a/compiler/rustc.vim +++ b/compiler/rustc.vim @@ -7,7 +7,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " For bugs, patches and license go to https://github.com/rust-lang/rust.vim  if exists("current_compiler") -	finish +    finish  endif  let current_compiler = "rustc" @@ -15,36 +15,39 @@ let s:cpo_save = &cpo  set cpo&vim  if exists(":CompilerSet") != 2 -	command -nargs=* CompilerSet setlocal <args> +    command -nargs=* CompilerSet setlocal <args>  endif -if exists("g:rustc_makeprg_no_percent") && g:rustc_makeprg_no_percent != 0 -	CompilerSet makeprg=rustc +if get(g:, 'rustc_makeprg_no_percent', 0) +    CompilerSet makeprg=rustc  else -	CompilerSet makeprg=rustc\ \% +    CompilerSet makeprg=rustc\ \%  endif -" Old errorformat (before nightly 2016/08/10) +" New errorformat (after 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%*[\ ]... +            \%-G, +            \%-Gerror:\ aborting\ %.%#, +            \%-Gerror:\ Could\ not\ compile\ %.%#, +            \%Eerror:\ %m, +            \%Eerror[E%n]:\ %m, +            \%Wwarning:\ %m, +            \%Inote:\ %m, +            \%C\ %#-->\ %f:%l:%c, +            \%E\ \ left:%m,%C\ right:%m\ %f:%l:%c,%Z -" New errorformat (after nightly 2016/08/10) +" Old errorformat (before 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 +            \%f:%l:%c:\ %t%*[^:]:\ %m, +            \%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m, +            \%-G%f:%l\ %s, +            \%-G%*[\ ]^, +            \%-G%*[\ ]^%*[~], +            \%-G%*[\ ]...  let &cpo = s:cpo_save  unlet s:cpo_save +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/extras/flow.vim b/extras/flow.vim index b3f899da..6a0aa94e 100644 --- a/extras/flow.vim +++ b/extras/flow.vim @@ -15,7 +15,7 @@ syntax region  jsFlowArrowArguments contained matchgroup=jsFlowNoise start=/(/  syntax match   jsFlowArrow          contained /=>/ skipwhite skipempty nextgroup=jsFlowType,jsFlowTypeCustom,jsFlowParens  syntax match   jsFlowObjectKey      contained /[0-9a-zA-Z_$?]*\(\s*:\)\@=/ contains=jsFunctionKey,jsFlowMaybe skipwhite skipempty nextgroup=jsObjectValue containedin=jsObject  syntax match   jsFlowOrOperator     contained /|/ skipwhite skipempty nextgroup=@jsFlowCluster -syntax keyword jsFlowImportType     contained type skipwhite skipempty nextgroup=jsModuleAsterisk,jsModuleKeyword,jsModuleGroup +syntax keyword jsFlowImportType     contained type typeof skipwhite skipempty nextgroup=jsModuleAsterisk,jsModuleKeyword,jsModuleGroup  syntax match   jsFlowWildcard       contained /*/  syntax match   jsFlowReturn         contained /:\s*/ contains=jsFlowNoise skipwhite skipempty nextgroup=@jsFlowReturnCluster,jsFlowArrow,jsFlowReturnParens @@ -23,7 +23,7 @@ syntax region  jsFlowReturnObject   contained matchgroup=jsFlowNoise start=/{/  syntax region  jsFlowReturnArray    contained matchgroup=jsFlowNoise start=/\[/   end=/\]/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp fold  syntax region  jsFlowReturnParens   contained matchgroup=jsFlowNoise start=/(/    end=/)/  contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp,jsFlowReturnArrow fold  syntax match   jsFlowReturnArrow    contained /=>/ skipwhite skipempty nextgroup=@jsFlowReturnCluster -syntax match   jsFlowReturnKeyword  contained /\k\+/ contains=jsFlowType,jsFlowTypeCustom skipwhite skipempty nextgroup=jsFlowReturnGroup,jsFuncBlock,jsFlowReturnOrOp +syntax match   jsFlowReturnKeyword  contained /\k\+/ contains=jsFlowType,jsFlowTypeCustom skipwhite skipempty nextgroup=jsFlowReturnGroup,jsFuncBlock,jsFlowReturnOrOp,jsFlowReturnArray  syntax match   jsFlowReturnMaybe    contained /?/ skipwhite skipempty nextgroup=jsFlowReturnKeyword,jsFlowReturnObject  syntax region  jsFlowReturnGroup    contained matchgroup=jsFlowNoise start=/</ end=/>/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp  syntax match   jsFlowReturnOrOp     contained /\s*|\s*/ skipwhite skipempty nextgroup=@jsFlowReturnCluster diff --git a/extras/jsdoc.vim b/extras/jsdoc.vim index ca4069cb..65546139 100644 --- a/extras/jsdoc.vim +++ b/extras/jsdoc.vim @@ -12,7 +12,7 @@ syntax match  jsDocTags         contained "@\(callback\|define\|enum\|external\|  " tags containing references  syntax match  jsDocTags         contained "@\(lends\|see\|tutorial\)\>" skipwhite nextgroup=jsDocSeeTag  " other tags (no extra syntax) -syntax match  jsDocTags         contained "@\(abstract\|access\|accessor\|async\|author\|classdesc\|constant\|const\|constructor\|copyright\|deprecated\|desc\|description\|dict\|event\|example\|file\|file[oO]verview\|final\|function\|global\|ignore\|inheritDoc\|inner\|instance\|interface\|license\|localdoc\|method\|mixin\|nosideeffects\|override\|overview\|preserve\|private\|protected\|public\|readonly\|since\|static\|struct\|todo\|summary\|undocumented\|virtual\)\>" +syntax match  jsDocTags         contained "@\(abstract\|access\|accessor\|async\|author\|classdesc\|constant\|const\|constructor\|copyright\|deprecated\|desc\|description\|dict\|event\|example\|file\|file[oO]verview\|final\|function\|global\|ignore\|inherit[dD]oc\|inner\|instance\|interface\|license\|localdoc\|method\|mixin\|nosideeffects\|override\|overview\|preserve\|private\|protected\|public\|readonly\|since\|static\|struct\|todo\|summary\|undocumented\|virtual\)\>"  syntax region jsDocType         contained matchgroup=jsDocTypeBrackets start="{" end="}" contains=jsDocTypeRecord oneline skipwhite nextgroup=jsDocParam  syntax match  jsDocType         contained "\%(#\|\"\|\w\|\.\|:\|\/\)\+" skipwhite nextgroup=jsDocParam diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index 0a4d36d3..580946ff 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -442,23 +442,17 @@ endif  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1    augroup filetypedetect    " javascript, from javascript.vim in pangloss/vim-javascript:_JAVASCRIPT -au BufNewFile,BufRead *.{js,mjs,jsm,es,es6},Jakefile setf javascript - -fun! s:SourceFlowSyntax() -  if !exists('javascript_plugin_flow') && !exists('b:flow_active') && -        \ search('\v\C%^\_s*%(//\s*|/\*[ \t\n*]*)\@flow>','nw') -    runtime extras/flow.vim -    let b:flow_active = 1 -  endif -endfun -au FileType javascript au BufRead,BufWritePost <buffer> call s:SourceFlowSyntax() -  fun! s:SelectJavascript()    if getline(1) =~# '^#!.*/bin/\%(env\s\+\)\?node\>'      set ft=javascript    endif  endfun -au BufNewFile,BufRead * call s:SelectJavascript() + +augroup javascript_syntax_detection +  autocmd! +  autocmd BufNewFile,BufRead *.{js,mjs,jsm,es,es6},Jakefile setfiletype javascript +  autocmd BufNewFile,BufRead * call s:SelectJavascript() +augroup END    augroup end  endif @@ -951,6 +945,9 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1    augroup filetypedetect    " rust, from rust.vim in rust-lang/rust.vim  au BufRead,BufNewFile *.rs set filetype=rust +au BufRead,BufNewFile Cargo.toml if &filetype == "" | set filetype=cfg | endif + +" vim: set et sw=4 sts=4 ts=8:    augroup end  endif diff --git a/ftplugin/elm.vim b/ftplugin/elm.vim index c989d922..b2423c29 100644 --- a/ftplugin/elm.vim +++ b/ftplugin/elm.vim @@ -43,14 +43,26 @@ setlocal comments=:--  setlocal commentstring=--\ %s  " Commands -command! -buffer -nargs=? -complete=file ElmMake call elm#Make(<f-args>) -command! -buffer ElmMakeMain call elm#Make("Main.elm") -command! -buffer -nargs=? -complete=file ElmTest call elm#Test(<f-args>) -command! -buffer ElmRepl call elm#Repl() -command! -buffer ElmErrorDetail call elm#ErrorDetail() -command! -buffer ElmShowDocs call elm#ShowDocs() -command! -buffer ElmBrowseDocs call elm#BrowseDocs() -command! -buffer ElmFormat call elm#Format() +command -buffer -nargs=? -complete=file ElmMake call elm#Make(<f-args>) +command -buffer ElmMakeMain call elm#Make("Main.elm") +command -buffer -nargs=? -complete=file ElmTest call elm#Test(<f-args>) +command -buffer ElmRepl call elm#Repl() +command -buffer ElmErrorDetail call elm#ErrorDetail() +command -buffer ElmShowDocs call elm#ShowDocs() +command -buffer ElmBrowseDocs call elm#BrowseDocs() +command -buffer ElmFormat call elm#Format() + +" Commands cleanup +let b:undo_ftplugin = " +      \ delcommand ElmMake +      \|delcommand ElmMakeMain +      \|delcommand ElmTest +      \|delcommand ElmRepl +      \|delcommand ElmErrorDetail +      \|delcommand ElmShowDocs +      \|delcommand ElmBrowseDocs +      \|delcommand ElmFormat +      \"  if get(g:, 'elm_setup_keybindings', 1)    nmap <buffer> <LocalLeader>m <Plug>(elm-make) diff --git a/ftplugin/eruby.vim b/ftplugin/eruby.vim index bf380e8a..12d3245f 100644 --- a/ftplugin/eruby.vim +++ b/ftplugin/eruby.vim @@ -7,7 +7,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ruby') == -1  " Release Coordinator:	Doug Kearns <dougkearns@gmail.com>  " Only do this when not done yet for this buffer -if exists("b:did_ftplugin") +if get(b:, 'did_ftplugin') =~# '\<eruby\>'    finish  endif @@ -25,6 +25,8 @@ endif  if &filetype =~ '^eruby\.'    let b:eruby_subtype = matchstr(&filetype,'^eruby\.\zs\w\+') +elseif &filetype =~ '^.*\.eruby\>' +  let b:eruby_subtype = matchstr(&filetype,'^.\{-\}\ze\.eruby\>')  elseif !exists("b:eruby_subtype")    let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")    let b:eruby_subtype = matchstr(s:lines,'eruby_subtype=\zs\w\+') @@ -47,11 +49,14 @@ elseif !exists("b:eruby_subtype")    endif  endif -if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=? 'eruby' -  exe "runtime! ftplugin/".b:eruby_subtype.".vim ftplugin/".b:eruby_subtype."_*.vim ftplugin/".b:eruby_subtype."/*.vim" -else -  runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim +if &filetype =~# '^eruby\>' +  if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=? 'eruby' +    exe "runtime! ftplugin/".b:eruby_subtype.".vim ftplugin/".b:eruby_subtype."_*.vim ftplugin/".b:eruby_subtype."/*.vim" +  else +    runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim +  endif  endif +let s:did_ftplugin = get(b:, 'did_ftplugin', 1)  unlet! b:did_ftplugin  " Override our defaults if these were set by an included ftplugin. @@ -68,8 +73,23 @@ if exists("b:match_words")    unlet b:match_words  endif +let s:cfilemap = v:version >= 704 ? maparg('<Plug><cfile>', 'c', 0, 1) : {} +if !get(s:cfilemap, 'buffer') || !s:cfilemap.expr || s:cfilemap.rhs =~# 'ErubyAtCursor()' +  let s:cfilemap = {} +endif +if !has_key(s:cfilemap, 'rhs') +  let s:cfilemap.rhs = "substitute(&l:inex =~# '\\<v:fname\\>' && len(expand('<cfile>')) ? eval(substitute(&l:inex, '\\<v:fname\\>', '\\=string(expand(\"<cfile>\"))', 'g')) : '', '^$', \"\\022\\006\",'')" +endif +let s:ctagmap = v:version >= 704 ? maparg('<Plug><ctag>', 'c', 0, 1) : {} +if !get(s:ctagmap, 'buffer') || !s:ctagmap.expr || s:ctagmap.rhs =~# 'ErubyAtCursor()' +  let s:ctagmap = {} +endif +let s:include = &l:include +let s:path = &l:path +let s:suffixesadd = &l:suffixesadd +  runtime! ftplugin/ruby.vim ftplugin/ruby_*.vim ftplugin/ruby/*.vim -let b:did_ftplugin = 1 +let b:did_ftplugin = s:did_ftplugin . '.eruby'  " Combine the new set of values with those previously included.  if exists("b:undo_ftplugin") @@ -82,6 +102,15 @@ if exists("b:match_words")    let s:match_words = b:match_words . ',' . s:match_words  endif +if len(s:include) +  let &l:include = s:include +endif +let &l:path = s:path . (s:path =~# ',$\|^$' ? '' : ',') . &l:path +let &l:suffixesadd = s:suffixesadd . (s:suffixesadd =~# ',$\|^$' ? '' : ',') . &l:suffixesadd +exe 'cmap <buffer><script><expr> <Plug><cfile> ErubyAtCursor() ? ' . maparg('<Plug><cfile>', 'c') . ' : ' . s:cfilemap.rhs +exe 'cmap <buffer><script><expr> <Plug><ctag> ErubyAtCursor() ? ' . maparg('<Plug><ctag>', 'c') . ' : ' . get(s:ctagmap, 'rhs', '"\022\027"') +unlet s:cfilemap s:ctagmap s:include s:path s:suffixesadd +  " Change the browse dialog on Win32 to show mainly eRuby-related files  if has("gui_win32")    let b:browsefilter="eRuby Files (*.erb, *.rhtml)\t*.erb;*.rhtml\n" . s:browsefilter @@ -101,6 +130,11 @@ let b:undo_ftplugin = "setl cms< "  let &cpo = s:save_cpo  unlet s:save_cpo +function! ErubyAtCursor() abort +  let groups = map(['erubyBlock', 'erubyComment', 'erubyExpression', 'erubyOneLiner'], 'hlID(v:val)') +  return !empty(filter(synstack(line('.'), col('.')), 'index(groups, v:val) >= 0')) +endfunction +  " vim: nowrap sw=2 sts=2 ts=8:  endif diff --git a/ftplugin/ruby.vim b/ftplugin/ruby.vim index b844bfdf..5b763e16 100644 --- a/ftplugin/ruby.vim +++ b/ftplugin/ruby.vim @@ -46,19 +46,12 @@ endif  setlocal formatoptions-=t formatoptions+=croql  setlocal include=^\\s*\\<\\(load\\>\\\|require\\>\\\|autoload\\s*:\\=[\"']\\=\\h\\w*[\"']\\=,\\) -setlocal includeexpr=substitute(substitute(v:fname,'::','/','g'),'\\%(\\.rb\\)\\=$','.rb','')  setlocal suffixesadd=.rb  if exists("&ofu") && has("ruby")    setlocal omnifunc=rubycomplete#Complete  endif -" To activate, :set ballooneval -if has('balloon_eval') && exists('+balloonexpr') -  setlocal balloonexpr=RubyBalloonexpr() -endif - -  " TODO:  "setlocal define=^\\s*def @@ -143,10 +136,20 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")                       \ "All Files (*.*)\t*.*\n"  endif -let b:undo_ftplugin = "setl fo< inc< inex< sua< def< com< cms< path< tags< kp<" +let b:undo_ftplugin = "setl inc= sua= path= tags= fo< com< cms< kp="        \."| unlet! b:browsefilter b:match_ignorecase b:match_words b:match_skip"        \."| if exists('&ofu') && has('ruby') | setl ofu< | endif" -      \."| if has('balloon_eval') && exists('+bexpr') | setl bexpr< | endif" + +if get(g:, 'ruby_recommended_style', 1) +  setlocal shiftwidth=2 softtabstop=2 expandtab +  let b:undo_ftplugin .= ' | setl sw< sts< et<' +endif + +" To activate, :set ballooneval +if exists('+balloonexpr') && get(g:, 'ruby_balloonexpr') +  setlocal balloonexpr=RubyBalloonexpr() +  let b:undo_ftplugin .= "| setl bexpr=" +endif  function! s:map(mode, flags, map) abort    let from = matchstr(a:map, '\S\+') @@ -156,9 +159,9 @@ function! s:map(mode, flags, map) abort    endif  endfunction -cmap <buffer><script><expr> <Plug><cword> substitute(RubyCursorIdentifier(),'^$',"\022\027",'') +cmap <buffer><script><expr> <Plug><ctag> substitute(RubyCursorTag(),'^$',"\022\027",'')  cmap <buffer><script><expr> <Plug><cfile> substitute(RubyCursorFile(),'^$',"\022\006",'') -let b:undo_ftplugin .= "| sil! cunmap <buffer> <Plug><cword>| sil! cunmap <buffer> <Plug><cfile>" +let b:undo_ftplugin .= "| sil! cunmap <buffer> <Plug><ctag>| sil! cunmap <buffer> <Plug><cfile>"  if !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps")    nmap <buffer><script> <SID>:  :<C-U> @@ -206,19 +209,18 @@ if !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps")            \."| sil! exe 'xunmap <buffer> iM' | sil! exe 'xunmap <buffer> aM'"    endif -  call s:map('c', '', '<C-R><C-W> <Plug><cword>')    call s:map('c', '', '<C-R><C-F> <Plug><cfile>')    cmap <buffer><script><expr> <SID>tagzv &foldopen =~# 'tag' ? '<Bar>norm! zv' : '' -  call s:map('n', '<silent>', '<C-]>       <SID>:exe  v:count1."tag <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', 'g<C-]>      <SID>:exe         "tjump <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', 'g]          <SID>:exe       "tselect <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', '<C-W>]      <SID>:exe v:count1."stag <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', '<C-W><C-]>  <SID>:exe v:count1."stag <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', '<C-W>g<C-]> <SID>:exe        "stjump <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', '<C-W>g]     <SID>:exe      "stselect <Plug><cword>"<SID>tagzv<CR>') -  call s:map('n', '<silent>', '<C-W>}      <SID>:exe v:count1."ptag <Plug><cword>"<CR>') -  call s:map('n', '<silent>', '<C-W>g}     <SID>:exe        "ptjump <Plug><cword>"<CR>') +  call s:map('n', '<silent>', '<C-]>       <SID>:exe  v:count1."tag <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', 'g<C-]>      <SID>:exe         "tjump <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', 'g]          <SID>:exe       "tselect <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', '<C-W>]      <SID>:exe v:count1."stag <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', '<C-W><C-]>  <SID>:exe v:count1."stag <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', '<C-W>g<C-]> <SID>:exe        "stjump <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', '<C-W>g]     <SID>:exe      "stselect <Plug><ctag>"<SID>tagzv<CR>') +  call s:map('n', '<silent>', '<C-W>}      <SID>:exe v:count1."ptag <Plug><ctag>"<CR>') +  call s:map('n', '<silent>', '<C-W>g}     <SID>:exe        "ptjump <Plug><ctag>"<CR>')    call s:map('n', '<silent>', 'gf           <SID>c:find <Plug><cfile><CR>')    call s:map('n', '<silent>', '<C-W>f      <SID>c:sfind <Plug><cfile><CR>') @@ -352,6 +354,10 @@ function! RubyCursorIdentifier() abort    return stripped == '' ? expand("<cword>") : stripped  endfunction +function! RubyCursorTag() abort +  return substitute(RubyCursorIdentifier(), '^[$@]*', '', '') +endfunction +  function! RubyCursorFile() abort    let isfname = &isfname    try diff --git a/ftplugin/rust.vim b/ftplugin/rust.vim index d1765d07..acf4d71d 100644 --- a/ftplugin/rust.vim +++ b/ftplugin/rust.vim @@ -8,7 +8,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " For bugs, patches and license go to https://github.com/rust-lang/rust.vim   if exists("b:did_ftplugin") -	finish +    finish  endif  let b:did_ftplugin = 1 @@ -16,181 +16,190 @@ 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-=<:> -		\|unlet b:match_skip -		\" - -" }}}1 - -" Code formatting on save -if get(g:, "rustfmt_autosave", 0) -	autocmd BufWritePre *.rs silent! call rustfmt#Format() -endif +    autocmd! + +    if get(b:, 'current_compiler', '') ==# '' +        if strlen(findfile('Cargo.toml', '.;')) > 0 +            compiler cargo +        else +            compiler rustc +        endif +    endif + +    " 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 get(g:, 'rust_bang_comment_leader', 0) +        " Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why, +        " but without it, */ gets indented one space even if there were no +        " leaders. I'm fairly sure that's a Vim bug. +        setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,:// +    else +        setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,:// +    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 get(g:, 'rust_recommended_style', 1) +        let b:rust_set_style = 1 +        setlocal tabstop=8 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") && get(g:, 'rust_fold', 0) +        let b:rust_set_foldmethod=1 +        setlocal foldmethod=syntax +        if g:rust_fold == 2 +            setlocal foldlevel< +        else +            setlocal foldlevel=99 +        endif +    endif + +    if has('conceal') && get(g:, 'rust_conceal', 0) +        let b:rust_set_conceallevel=1 +        setlocal conceallevel=2 +    endif + +    " Motion Commands {{{1 + +    " 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>) + +    " See |:RustInfo| for docs +    command! -bar RustInfo call rust#debugging#Info() + +    " See |:RustInfoToClipboard| for docs +    command! -bar RustInfoToClipboard call rust#debugging#InfoToClipboard() + +    " See |:RustInfoToFile| for docs +    command! -bar -nargs=1 RustInfoToFile call rust#debugging#InfoToFile(<f-args>) + +    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< +                \|if exists('b:rust_set_style') +                    \|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth< +                    \|endif +                    \|if exists('b:rust_original_delimitMate_excluded_regions') +                        \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions +                        \|unlet b:rust_original_delimitMate_excluded_regions +                        \|else +                            \|unlet! b:delimitMate_excluded_regions +                            \|endif +                            \|if exists('b:rust_set_foldmethod') +                                \|setlocal foldmethod< foldlevel< +                                \|unlet b:rust_set_foldmethod +                                \|endif +                                \|if exists('b:rust_set_conceallevel') +                                    \|setlocal conceallevel< +                                    \|unlet b:rust_set_conceallevel +                                    \|endif +                                    \|unlet! b:rust_last_rustc_args b:rust_last_args +                                    \|delcommand RustRun +                                    \|delcommand RustExpand +                                    \|delcommand RustEmitIr +                                    \|delcommand RustEmitAsm +                                    \|delcommand RustPlay +                                    \|nunmap <buffer> [[ +                                    \|nunmap <buffer> ]] +                                    \|xunmap <buffer> [[ +                                    \|xunmap <buffer> ]] +                                    \|ounmap <buffer> [[ +                                    \|ounmap <buffer> ]] +                                    \|set matchpairs-=<:> +                                    \|unlet b:match_skip +                                    \" + +    " }}}1 + +    " Code formatting on save +    autocmd BufWritePre *.rs silent! call rustfmt#PreWrite()  augroup END @@ -201,6 +210,6 @@ let b:match_skip = 's:comment\|string\|rustArrow'  let &cpo = s:save_cpo  unlet s:save_cpo -" vim: set noet sw=8 ts=8: +" vim: set et sw=4 sts=4 ts=8:  endif diff --git a/ftplugin/rust/tagbar.vim b/ftplugin/rust/tagbar.vim new file mode 100644 index 00000000..5c95f357 --- /dev/null +++ b/ftplugin/rust/tagbar.vim @@ -0,0 +1,38 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 +   +" +" Support for Tagbar -- https://github.com/majutsushi/tagbar +" +if !exists(':Tagbar') +    finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +let g:tagbar_type_rust = { +            \ 'ctagstype' : 'rust', +            \ 'kinds' : [ +            \'T:types', +            \'f:functions', +            \'g:enumerations', +            \'s:structures', +            \'m:modules', +            \'c:constants', +            \'t:traits', +            \'i:trait implementations', +            \ ] +            \ } + +" In case you've updated/customized your ~/.ctags and prefer to use it. +if !get(g:, 'rust_use_custom_ctags_defs', 0) +    let g:tagbar_type_rust.deffile = expand('<sfile>:p:h:h:h') . '/ctags/rust.ctags' +endif + +let &cpo = s:save_cpo +unlet s:save_cpo + + +" vim: set et sw=4 sts=4 ts=8: + +endif diff --git a/ftplugin/vue.vim b/ftplugin/vue.vim index cc10c561..959dca4e 100644 --- a/ftplugin/vue.vim +++ b/ftplugin/vue.vim @@ -5,7 +5,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vue') == -1  " Maintainer: Eduardo San Martin Morote  " Author: Adriaan Zonnenberg -if exists("b:did_ftplugin") +if exists('b:did_ftplugin')    finish  endif @@ -20,11 +20,9 @@ if !exists('g:no_plugin_maps') && !exists('g:no_vue_maps')    nnoremap <silent> <buffer> ][ :call search('^</\(template\<Bar>script\<Bar>style\)', 'W')<CR>  endif -if exists('g:loaded_ale') -  let g:ale_linters = get(g:, 'ale_linters', {}) -  let g:ale_linters.vue = get(g:ale_linters, 'vue', ['eslint']) -  let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {}) -  let g:ale_linter_aliases.vue = get(g:ale_linter_aliases, 'vue', 'javascript') -endif +" Run only ESLint for Vue files by default. +" linters specifically for Vue can still be loaded. +let b:ale_linter_aliases = ['vue', 'javascript'] +let b:ale_linters = ['eslint']  endif diff --git a/indent/eruby.vim b/indent/eruby.vim index 6fd76600..cdc5fedf 100644 --- a/indent/eruby.vim +++ b/indent/eruby.vim @@ -6,7 +6,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ruby') == -1  " URL:			https://github.com/vim-ruby/vim-ruby  " Release Coordinator:	Doug Kearns <dougkearns@gmail.com> -if exists("b:did_indent") +if get(b:, 'did_indent') =~# '\<eruby\>'    finish  endif @@ -14,12 +14,14 @@ runtime! indent/ruby.vim  unlet! b:did_indent  setlocal indentexpr= -if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=# 'eruby' -  exe "runtime! indent/".b:eruby_subtype.".vim" -else -  runtime! indent/html.vim +if &filetype =~# '^eruby\>' +  if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=# 'eruby' +    exe "runtime! indent/".b:eruby_subtype.".vim" +  else +    runtime! indent/html.vim +  endif  endif -unlet! b:did_indent +let b:did_indent = get(b:, 'did_indent', 1) . '.eruby'  " Force HTML indent to not keep state.  let b:html_indent_usestate = 0 @@ -33,8 +35,6 @@ if &l:indentexpr == ''  endif  let b:eruby_subtype_indentexpr = &l:indentexpr -let b:did_indent = 1 -  setlocal indentexpr=GetErubyIndent()  setlocal indentkeys=o,O,*<Return>,<>>,{,},0),0],o,O,!^F,=end,=else,=elsif,=rescue,=ensure,=when diff --git a/indent/nix.vim b/indent/nix.vim index fd277dcc..2910cbd6 100644 --- a/indent/nix.vim +++ b/indent/nix.vim @@ -21,6 +21,8 @@ let s:cpo_save = &cpo  set cpo&vim  let s:skip_syntax = '\%(Comment\|String\)$' +let s:binding_open = '\%(\<let\>\|{\)' +let s:binding_close = '\%(\<in\>\|}\)'  let s:block_open  = '\%({\|[\)'  let s:block_close = '\%(}\|]\)' @@ -43,6 +45,23 @@ function! GetNixIndent()      let current_line = getline(v:lnum)      let last_line = getline(lnum) +    if current_line =~ '^\s*in\>' +      let save_cursor = getcurpos() +      normal ^ +      let bslnum = searchpair(s:binding_open, '', s:binding_close, 'bnW', +            \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "StringSpecial$"') +      call setpos('.', save_cursor) +      return indent(bslnum) +    endif + +    if last_line =~ ';$' +      let bslnum = searchpair(s:binding_open, '', s:binding_close, 'bnW', +            \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "StringSpecial$"') +      if bslnum != 0 +        let ind = indent(bslnum) + &sw +      endif +    endif +      if last_line =~ s:block_open . '\s*$'        let ind += &sw      endif @@ -51,6 +70,10 @@ function! GetNixIndent()        let ind -= &sw      endif +    if last_line =~ '[(=]$' +      let ind += &sw +    endif +      if last_line =~ '\<let\s*$'        let ind += &sw      endif diff --git a/indent/purescript.vim b/indent/purescript.vim index c22da095..515f88e2 100644 --- a/indent/purescript.vim +++ b/indent/purescript.vim @@ -103,7 +103,7 @@ function! GetPurescriptIndent()      return s    endif -  if prevline =~ '^\S.*::' && line !~ '^\s*\(\.\|->\|→\|=>\|⇒\)' && !~ '^instance' +  if prevline =~ '^\S.*::' && line !~ '^\s*\(\.\|->\|→\|=>\|⇒\)' && prevline !~ '^instance'      " f :: String      "	-> String      return 0 diff --git a/indent/rust.vim b/indent/rust.vim index 042e2ab5..fa4dfb54 100644 --- a/indent/rust.vim +++ b/indent/rust.vim @@ -3,17 +3,17 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " Vim indent file  " Language:         Rust  " Author:           Chris Morgan <me@chrismorgan.info> -" Last Change:      2017 Mar 21 +" Last Change:      2018 Jan 10  " 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 +    finish  endif  let b:did_indent = 1  setlocal cindent -setlocal cinoptions=L0,(0,Ws,J1,j1 +setlocal cinoptions=L0,(0,Ws,J1,j1,m1  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,macro @@ -28,7 +28,7 @@ setlocal indentexpr=GetRustIndent(v:lnum)  " Only define the function once.  if exists("*GetRustIndent") -	finish +    finish  endif  let s:save_cpo = &cpo @@ -37,181 +37,183 @@ 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 +    " 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 +    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) +    " 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 +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/syntax/ansible.vim b/syntax/ansible.vim index 0b732101..2f2d3b83 100644 --- a/syntax/ansible.vim +++ b/syntax/ansible.vim @@ -26,7 +26,7 @@ endif  syn cluster jinjaSLSBlocks add=jinjaTagBlock,jinjaVarBlock,jinjaComment  " https://github.com/mitsuhiko/jinja2/blob/6b7c0c23/ext/Vim/jinja.vim  syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment,@jinjaSLSBlocks -syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment,@jinjaSLSBlocks +syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,yamlComment,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment,@jinjaSLSBlocks  syn region jinjaComment matchgroup=jinjaCommentDelim start="{#" end="#}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,@jinjaSLSBlocks  highlight link jinjaVariable Constant  highlight link jinjaVarDelim Delimiter diff --git a/syntax/crystal.vim b/syntax/crystal.vim index 32629781..88395596 100644 --- a/syntax/crystal.vim +++ b/syntax/crystal.vim @@ -274,7 +274,8 @@ syn match crystalLinkAttr "]" contained containedin=crystalLinkAttrRegion displa  if !exists('g:crystal_no_special_methods')    syn keyword crystalAccess    protected private    " attr is a common variable name -  syn keyword crystalAttribute getter setter property abstract +  syn keyword crystalAttribute abstract +  syn match   crystalAttribute "\<\%(class_\)\=\%(getter\|setter\|property\)[!?]\=\s" display    syn match   crystalControl   "\<\%(abort\|at_exit\|exit\|fork\|loop\)\>[?!]\@!" display    syn keyword crystalException raise    " false positive with 'include?' diff --git a/syntax/elm.vim b/syntax/elm.vim index a26fb0f6..67d737a8 100644 --- a/syntax/elm.vim +++ b/syntax/elm.vim @@ -43,7 +43,7 @@ syn match elmInt "-\?\<\d\+\>\|0[xX][0-9a-fA-F]\+\>"  syn match elmFloat "\(\<\d\+\.\d\+\>\)"  " Identifiers -syn match elmTopLevelDecl "^\s*[a-zA-Z][a-zA-z0-9_]*\('\)*\s\+:\s\+" contains=elmOperator +syn match elmTopLevelDecl "^\s*[a-zA-Z][a-zA-z0-9_]*\('\)*\s\+:\(\r\n\|\r\|\n\|\s\)\+" contains=elmOperator  " Folding  syn region elmTopLevelTypedef start="type" end="\n\(\n\n\)\@=" contains=ALL fold diff --git a/syntax/eruby.vim b/syntax/eruby.vim index 75354042..1e760988 100644 --- a/syntax/eruby.vim +++ b/syntax/eruby.vim @@ -6,7 +6,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ruby') == -1  " URL:			https://github.com/vim-ruby/vim-ruby  " Release Coordinator:	Doug Kearns <dougkearns@gmail.com> -if exists("b:current_syntax") +if &syntax !~# '\<eruby\>' || get(b:, 'current_syntax') =~# '\<eruby\>'    finish  endif @@ -20,6 +20,8 @@ endif  if &filetype =~ '^eruby\.'    let b:eruby_subtype = matchstr(&filetype,'^eruby\.\zs\w\+') +elseif &filetype =~ '^.*\.eruby\>' +  let b:eruby_subtype = matchstr(&filetype,'^.\{-\}\ze\.eruby\>')  elseif !exists("b:eruby_subtype") && main_syntax == 'eruby'    let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")    let b:eruby_subtype = matchstr(s:lines,'eruby_subtype=\zs\w\+') @@ -43,16 +45,20 @@ elseif !exists("b:eruby_subtype") && main_syntax == 'eruby'  endif  if !exists("b:eruby_nest_level") -  let b:eruby_nest_level = strlen(substitute(substitute(substitute(expand("%:t"),'@','','g'),'\c\.\%(erb\|rhtml\)\>','@','g'),'[^@]','','g')) +  if &syntax =~# '\<eruby\.eruby\>' +    let b:eruby_nest_level = strlen(substitute(substitute(&filetype,'\C\<eruby\>','@','g'),'[^@]','','g')) +  else +    let b:eruby_nest_level = strlen(substitute(substitute(substitute(expand("%:t"),'@','','g'),'\c\.\%(erb\|rhtml\)\>','@','g'),'[^@]','','g')) +  endif  endif  if !b:eruby_nest_level    let b:eruby_nest_level = 1  endif -if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=? 'eruby' +if get(b:, 'eruby_subtype', '') !~# '^\%(eruby\)\=$' && &syntax =~# '^eruby\>'    exe "runtime! syntax/".b:eruby_subtype.".vim" -  unlet! b:current_syntax  endif +unlet! b:current_syntax  syn include @rubyTop syntax/ruby.vim  syn cluster erubyRegions contains=erubyOneLiner,erubyBlock,erubyExpression,erubyComment @@ -67,7 +73,7 @@ exe 'syn region  erubyComment    matchgroup=erubyDelimiter start="<%\{1,'.b:erub  hi def link erubyDelimiter		PreProc  hi def link erubyComment		Comment -let b:current_syntax = 'eruby' +let b:current_syntax = matchstr(&syntax, '^.*\<eruby\>')  if main_syntax == 'eruby'    unlet main_syntax diff --git a/syntax/go.vim b/syntax/go.vim index ab5ac8af..c3c26ed6 100644 --- a/syntax/go.vim +++ b/syntax/go.vim @@ -373,6 +373,10 @@ function! s:hi()    " :GoCoverage commands    hi def      goCoverageCovered    ctermfg=green guifg=#A6E22E    hi def      goCoverageUncover    ctermfg=red guifg=#F92672 + +  " :GoDebug commands +  hi GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5  guifg=Black +  hi GoDebugCurrent    term=reverse  ctermbg=12  ctermfg=7 guibg=DarkBlue guifg=White  endfunction  augroup vim-go-hi diff --git a/syntax/graphql.vim b/syntax/graphql.vim index c498afa4..b59151af 100644 --- a/syntax/graphql.vim +++ b/syntax/graphql.vim @@ -39,8 +39,8 @@ syn match graphqlConstant   "\<[A-Z_]\+\>" display  syn keyword graphqlMetaFields __schema __type __typename -syn region  graphqlFold matchgroup=graphqlBraces start="{" end=/}\(\_s\+\ze\("\|{\)\)\@!/ transparent fold contains=ALLBUT,graphqlStructure -syn region  graphqlList matchgroup=graphqlBraces start="\[" end=/]\(\_s\+\ze"\)\@!/ transparent contains=ALLBUT,graphqlDirective,graphqlStructure +syn region  graphqlFold matchgroup=graphqlBraces start="{" end="}" transparent fold contains=ALLBUT,graphqlStructure +syn region  graphqlList matchgroup=graphqlBraces start="\[" end="]" transparent contains=ALLBUT,graphqlDirective,graphqlStructure  hi def link graphqlComment          Comment  hi def link graphqlOperator         Operator diff --git a/syntax/i3.vim b/syntax/i3.vim index cbac6a53..45bf846e 100644 --- a/syntax/i3.vim +++ b/syntax/i3.vim @@ -58,7 +58,7 @@ syn keyword i3SeparatorSymbol separator_symbol nextgroup=@i3String skipwhite  " Set statement  syn match   i3SetVar "\$\w\+" contained nextgroup=@i3String skipwhite -syn keyword i3SetKeyword set nextgroup=i3SetVar skipwhite +syn keyword i3SetKeyword set set_from_resource nextgroup=i3SetVar skipwhite  " Workspaces  syn keyword i3WsKeyword workspace nextgroup=i3WsSpecialParam,@i3String skipwhite diff --git a/syntax/javascript.vim b/syntax/javascript.vim index a4ffaa39..d1480e7c 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -15,7 +15,7 @@ if !exists("main_syntax")  endif  " Dollar sign is permitted anywhere in an identifier -if v:version > 704 || v:version == 704 && has('patch1142') +if (v:version > 704 || v:version == 704 && has('patch1142')) && main_syntax == 'javascript'    syntax iskeyword @,48-57,_,192-255,$  else    setlocal iskeyword+=$ @@ -27,7 +27,7 @@ syntax sync fromstart  syntax case match  syntax match   jsNoise          /[:,;]/ -syntax match   jsNoise          /\./ skipwhite skipempty nextgroup=jsObjectProp,jsFuncCall,jsPrototype,jsTaggedTemplate +syntax match   jsDot            /\./ skipwhite skipempty nextgroup=jsObjectProp,jsFuncCall,jsPrototype,jsTaggedTemplate  syntax match   jsObjectProp     contained /\<\K\k*/  syntax match   jsFuncCall       /\<\K\k*\ze\s*(/  syntax match   jsParensError    /[)}\]]/ @@ -74,12 +74,12 @@ syntax region  jsRegexpString   start=+\%(\%(\<return\|\<typeof\|\_[^)\]'"[:blan  syntax cluster jsRegexpSpecial    contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod  " Objects +syntax match   jsObjectShorthandProp contained /\<\k*\ze\s*/ skipwhite skipempty nextgroup=jsObjectSeparator  syntax match   jsObjectKey         contained /\<\k*\ze\s*:/ contains=jsFunctionKey skipwhite skipempty nextgroup=jsObjectValue -syntax match   jsObjectColon       contained /:/ skipwhite skipempty  syntax region  jsObjectKeyString   contained start=+\z(["']\)+  skip=+\\\%(\z1\|$\)+  end=+\z1\|$+  contains=jsSpecial,@Spell skipwhite skipempty nextgroup=jsObjectValue  syntax region  jsObjectKeyComputed contained matchgroup=jsBrackets start=/\[/ end=/]/ contains=@jsExpression skipwhite skipempty nextgroup=jsObjectValue,jsFuncArgs extend  syntax match   jsObjectSeparator   contained /,/ -syntax region  jsObjectValue       contained matchgroup=jsNoise start=/:/ end=/[,}]\@=/ contains=@jsExpression extend +syntax region  jsObjectValue       contained matchgroup=jsObjectColon start=/:/ end=/[,}]\@=/ contains=@jsExpression extend  syntax match   jsObjectFuncName    contained /\<\K\k*\ze\_s*(/ skipwhite skipempty nextgroup=jsFuncArgs  syntax match   jsFunctionKey       contained /\<\K\k*\ze\s*:\s*function\>/  syntax match   jsObjectMethodType  contained /\<[gs]et\ze\s\+\K\k*/ skipwhite skipempty nextgroup=jsObjectFuncName @@ -151,8 +151,8 @@ syntax region  jsFinallyBlock       contained matchgroup=jsFinallyBraces       s  syntax region  jsSwitchBlock        contained matchgroup=jsSwitchBraces        start=/{/  end=/}/  contains=@jsAll,jsBlock,jsSwitchCase extend fold  syntax region  jsRepeatBlock        contained matchgroup=jsRepeatBraces        start=/{/  end=/}/  contains=@jsAll,jsBlock extend fold  syntax region  jsDestructuringBlock contained matchgroup=jsDestructuringBraces start=/{/  end=/}/  contains=jsDestructuringProperty,jsDestructuringAssignment,jsDestructuringNoise,jsDestructuringPropertyComputed,jsSpreadExpression,jsComment extend fold -syntax region  jsDestructuringArray contained matchgroup=jsDestructuringBraces start=/\[/ end=/\]/ contains=jsDestructuringPropertyValue,jsNoise,jsDestructuringProperty,jsSpreadExpression,jsDestructuringBlock,jsComment extend fold -syntax region  jsObject             contained matchgroup=jsObjectBraces        start=/{/  end=/}/  contains=jsObjectKey,jsObjectKeyString,jsObjectKeyComputed,jsObjectSeparator,jsObjectFuncName,jsObjectMethodType,jsGenerator,jsComment,jsObjectStringKey,jsSpreadExpression,jsDecorator,jsAsyncKeyword extend fold +syntax region  jsDestructuringArray contained matchgroup=jsDestructuringBraces start=/\[/ end=/\]/ contains=jsDestructuringPropertyValue,jsNoise,jsDestructuringProperty,jsSpreadExpression,jsDestructuringBlock,jsDestructuringArray,jsComment extend fold +syntax region  jsObject             contained matchgroup=jsObjectBraces        start=/{/  end=/}/  contains=jsObjectKey,jsObjectKeyString,jsObjectKeyComputed,jsObjectShorthandProp,jsObjectSeparator,jsObjectFuncName,jsObjectMethodType,jsGenerator,jsComment,jsObjectStringKey,jsSpreadExpression,jsDecorator,jsAsyncKeyword extend fold  syntax region  jsBlock                        matchgroup=jsBraces              start=/{/  end=/}/  contains=@jsAll,jsSpreadExpression extend fold  syntax region  jsModuleGroup        contained matchgroup=jsModuleBraces        start=/{/ end=/}/   contains=jsModuleKeyword,jsModuleComma,jsModuleAs,jsComment,jsFlowTypeKeyword skipwhite skipempty nextgroup=jsFrom fold  syntax region  jsSpreadExpression   contained matchgroup=jsSpreadOperator      start=/\.\.\./ end=/[,}\]]\@=/ contains=@jsExpression @@ -232,7 +232,7 @@ if exists("javascript_plugin_flow")    runtime extras/flow.vim  endif -syntax cluster jsExpression  contains=jsBracket,jsParen,jsObject,jsTernaryIf,jsTaggedTemplate,jsTemplateString,jsString,jsRegexpString,jsNumber,jsFloat,jsOperator,jsOperatorKeyword,jsBooleanTrue,jsBooleanFalse,jsNull,jsFunction,jsArrowFunction,jsGlobalObjects,jsExceptions,jsFutureKeys,jsDomErrNo,jsDomNodeConsts,jsHtmlEvents,jsFuncCall,jsUndefined,jsNan,jsPrototype,jsBuiltins,jsNoise,jsClassDefinition,jsArrowFunction,jsArrowFuncArgs,jsParensError,jsComment,jsArguments,jsThis,jsSuper,jsDo,jsForAwait,jsAsyncKeyword,jsStatement +syntax cluster jsExpression  contains=jsBracket,jsParen,jsObject,jsTernaryIf,jsTaggedTemplate,jsTemplateString,jsString,jsRegexpString,jsNumber,jsFloat,jsOperator,jsOperatorKeyword,jsBooleanTrue,jsBooleanFalse,jsNull,jsFunction,jsArrowFunction,jsGlobalObjects,jsExceptions,jsFutureKeys,jsDomErrNo,jsDomNodeConsts,jsHtmlEvents,jsFuncCall,jsUndefined,jsNan,jsPrototype,jsBuiltins,jsNoise,jsClassDefinition,jsArrowFunction,jsArrowFuncArgs,jsParensError,jsComment,jsArguments,jsThis,jsSuper,jsDo,jsForAwait,jsAsyncKeyword,jsStatement,jsDot  syntax cluster jsAll         contains=@jsExpression,jsStorageClass,jsConditional,jsRepeat,jsReturn,jsException,jsTry,jsNoise,jsBlockLabel  " Define the default highlighting. @@ -287,6 +287,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")    HiLink jsGenerator            jsFunction    HiLink jsArrowFuncArgs        jsFuncArgs    HiLink jsFuncName             Function +  HiLink jsFuncCall             Function    HiLink jsClassFuncName        jsFuncName    HiLink jsObjectFuncName       Function    HiLink jsArguments            Special @@ -309,6 +310,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")    HiLink jsBooleanFalse         Boolean    HiLink jsObjectColon          jsNoise    HiLink jsNoise                Noise +  HiLink jsDot                  Noise    HiLink jsBrackets             Noise    HiLink jsParens               Noise    HiLink jsBraces               Noise @@ -343,6 +345,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")    HiLink jsParensDecorator      jsParens    HiLink jsFuncArgOperator      jsFuncArgs    HiLink jsClassProperty        jsObjectKey +  HiLink jsObjectShorthandProp  jsObjectKey    HiLink jsSpreadOperator       Operator    HiLink jsRestOperator         Operator    HiLink jsRestExpression       jsFuncArgs diff --git a/syntax/jinja2.vim b/syntax/jinja2.vim index 55d9fbfd..402bad56 100644 --- a/syntax/jinja2.vim +++ b/syntax/jinja2.vim @@ -50,7 +50,7 @@ syn region jinjaNested matchgroup=jinjaOperator start="\[" end="\]" transparent  syn region jinjaNested matchgroup=jinjaOperator start="{" end="}" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained  syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment -syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment +syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,yamlComment,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment  " Jinja template 'raw' tag  syn region jinjaRaw matchgroup=jinjaRawDelim start="{%\s*raw\s*%}" end="{%\s*endraw\s*%}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,jinjaComment diff --git a/syntax/julia.vim b/syntax/julia.vim index 3e5c1433..8d7d7b4d 100644 --- a/syntax/julia.vim +++ b/syntax/julia.vim @@ -84,7 +84,7 @@ let s:binop_chars_extra = "\\U214B\\U2190-\\U2194\\U219A\\U219B\\U21A0\\U21A3\\U  let s:idregex = '\%([^' . s:nonidS_chars . '0-9!?' . s:uniop_chars . s:binop_chars . '][^' . s:nonidS_chars . s:uniop_chars . s:binop_chars . s:binop_chars_extra . ']*\|\<?\>\)'  let s:operators = '\%(' . '\.\%([-+*/^÷%|&!]\|//\|\\\|<<\|>>>\?\)\?=' . -      \           '\|'  . '[:$<>]=\|||\|&&\||>\|<|\|<:\|:>\|::\|<<\|>>>\?\|//\|[-=]>\|\.\{3\}' . +      \           '\|'  . '[:$<>]=\|||\|&&\||>\|<|\|<:\|>:\|::\|<<\|>>>\?\|//\|[-=]>\|\.\{3\}' .        \           '\|'  . '[' . s:uniop_chars . '!$]' .        \           '\|'  . '\.\?[' . s:binop_chars . s:binop_chars_extra . ']' .        \           '\)' diff --git a/syntax/nginx.vim b/syntax/nginx.vim index 944b36ab..10d69b26 100644 --- a/syntax/nginx.vim +++ b/syntax/nginx.vim @@ -558,6 +558,7 @@ syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol,ngxSSLProtocolDe  syn match ngxSSLProtocol 'TLSv1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite  syn match ngxSSLProtocol 'TLSv1\.1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite  syn match ngxSSLProtocol 'TLSv1\.2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +syn match ngxSSLProtocol 'TLSv1\.3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite  " Do not enable highlighting of insecure protocols if sslecure is loaded  if !exists('g:loaded_sslsecure') diff --git a/syntax/rust.vim b/syntax/rust.vim index 81abf942..90e5b6b6 100644 --- a/syntax/rust.vim +++ b/syntax/rust.vim @@ -9,9 +9,9 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1  " For bugs, patches and license go to https://github.com/rust-lang/rust.vim  if version < 600 -	syntax clear +    syntax clear  elseif exists("b:current_syntax") -	finish +    finish  endif  " Syntax definitions {{{1 @@ -29,6 +29,7 @@ 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     crate  syn keyword   rustKeyword     extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty  syn keyword   rustKeyword     fn nextgroup=rustFuncName skipwhite skipempty  syn keyword   rustKeyword     in impl let @@ -45,8 +46,6 @@ syn keyword   rustKeyword     mod trait nextgroup=rustIdentifier skipwhite skipe  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 @@ -155,6 +154,16 @@ syn region    rustDerive      start="derive(" end=")" contained contains=rustDer  " 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 +" dyn keyword: It's only a keyword when used inside a type expression, so +" we make effort here to highlight it only when Rust identifiers follow it +" (not minding the case of pre-2018 Rust where a path starting with :: can +" follow). +" +" This is so that uses of dyn variable names such as in 'let &dyn = &2' +" and 'let dyn = 2' will not get highlighted as a keyword. +syn match     rustKeyword "\<dyn\ze\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)" contains=rustDynKeyword +syn keyword   rustDynKeyword  dyn contained +  " 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\)\)\=" @@ -174,7 +183,7 @@ syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE  " 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 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 @@ -191,11 +200,17 @@ syn region rustCommentLine                                                  star  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 rustCommentBlockDoc          matchgroup=rustCommentBlockDoc      start="/\*\%(!\|\*[*/]\@!\)"    end="\*/" contains=rustTodo,rustCommentBlockDocNest,rustCommentBlockDocRustCode,@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 + +if exists("b:current_syntax_embed") +syn match rustCommentLine                                                  "^//" +syn match rustCommentLineDoc                                               "^//\%(//\@!\|!\)" +endif +  " 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 @@ -215,6 +230,32 @@ syn keyword rustTodo contained TODO FIXME XXX NB NOTE  " FIXME: use the AST to make really good folding  syn region rustFoldBraces start="{" end="}" transparent fold +if !exists("b:current_syntax_embed") +    let b:current_syntax_embed = 1 +    syntax include @RustCodeInComment <sfile>:p:h/rust.vim +    unlet b:current_syntax_embed + +    " We borrow the rules from rust’s src/librustdoc/html/markdown.rs, so that +    " we only highlight as Rust what it would perceive as Rust (almost; it’s +    " possible to trick it if you try hard, and indented code blocks aren’t +    " supported because Markdown is a menace to parse and only mad dogs and +    " Englishmen would try to handle that case correctly in this syntax file). +    syn region rustCommentLinesDocRustCode matchgroup=rustCommentDocCodeFence start='^\z(\s*//[!/]\s*```\)[^A-Za-z0-9_-]*\%(\%(should_panic\|no_run\|ignore\|allow_fail\|rust\|test_harness\|compile_fail\|E\d\{4}\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment +    syn region rustCommentBlockDocRustCode matchgroup=rustCommentDocCodeFence start='^\z(\%(\s*\*\)\?\s*```\)[^A-Za-z0-9_-]*\%(\%(should_panic\|no_run\|ignore\|allow_fail\|rust\|test_harness\|compile_fail\|E\d\{4}\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment,rustCommentBlockDocStar +    " Strictly, this may or may not be correct; this code, for example, would +    " mishighlight: +    " +    "     /** +    "     ```rust +    "     println!("{}", 1 +    "     * 1); +    "     ``` +    "     */ +    " +    " … but I don’t care. Balance of probability, and all that. +    syn match rustCommentBlockDocStar /^\s*\*\s\?/ contained +endif +  " Default highlighting {{{1  hi def link rustDecNumber       rustNumber  hi def link rustHexNumber       rustNumber @@ -246,6 +287,7 @@ hi def link rustFloat         Float  hi def link rustArrowCharacter rustOperator  hi def link rustOperator      Operator  hi def link rustKeyword       Keyword +hi def link rustDynKeyword    rustKeyword  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 @@ -269,7 +311,9 @@ hi def link rustCommentLineDoc SpecialComment  hi def link rustCommentLineDocError Error  hi def link rustCommentBlock  rustCommentLine  hi def link rustCommentBlockDoc rustCommentLineDoc +hi def link rustCommentBlockDocStar rustCommentBlockDoc  hi def link rustCommentBlockDocError Error +hi def link rustCommentDocCodeFence rustCommentLineDoc  hi def link rustAssert        PreCondit  hi def link rustPanic         PreCondit  hi def link rustMacro         Macro @@ -282,7 +326,6 @@ 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 @@ -300,4 +343,6 @@ syn sync maxlines=500  let b:current_syntax = "rust" +" vim: set et sw=4 sts=4 ts=8: +  endif diff --git a/syntax/toml.vim b/syntax/toml.vim index 7a5b44f2..1decc5fb 100644 --- a/syntax/toml.vim +++ b/syntax/toml.vim @@ -28,6 +28,7 @@ syn region tomlString start=/'''/ end=/'''/  hi def link tomlString String  syn match tomlInteger /\<[+-]\=[0-9]\(_\=\d\)*\>/ display +syn match tomlInteger /\<[+-]\=\(inf\|nan\)\>/ display  hi def link tomlInteger Number  syn match tomlFloat /\<[+-]\=[0-9]\(_\=\d\)*\.\d\+\>/ display @@ -43,16 +44,19 @@ syn match tomlDate /\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?/ display  syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}[T ]\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?\%(Z\|[+-]\d\{2\}:\d\{2\}\)\?/ display  hi def link tomlDate Constant -syn region tomlKeyDq oneline start=/"/ end=/"/ contains=tomlEscape contained +syn match tomlKey /\v(^|[{,])\s*\zs[[:alnum:]_-]+\ze\s*\=/ display +hi def link tomlKey Identifier + +syn region tomlKeyDq oneline start=/\v(^|[{,])\s*\zs"/ end=/"\ze\s*=/ contains=tomlEscape  hi def link tomlKeyDq Identifier -syn region tomlKeySq oneline start=/'/ end=/'/ contained +syn region tomlKeySq oneline start=/\v(^|[{,])\s*\zs'/ end=/'\ze\s*=/  hi def link tomlKeySq Identifier -syn region tomlTable oneline start=/^\s*\[[^\[]/ end=/\]/ contains=tomlKeyDq,tomlKeySq +syn region tomlTable oneline start=/^\s*\[[^\[]/ end=/\]/ contains=tomlKey,tomlKeyDq,tomlKeySq  hi def link tomlTable Identifier -syn region tomlTableArray oneline start=/^\s*\[\[/ end=/\]\]/ contains=tomlKeyDq,tomlKeySq +syn region tomlTableArray oneline start=/^\s*\[\[/ end=/\]\]/ contains=tomlKey,tomlKeyDq,tomlKeySq  hi def link tomlTableArray Identifier  syn keyword tomlTodo TODO FIXME XXX BUG contained diff --git a/syntax/vifm.vim b/syntax/vifm.vim index 8843d1ac..1ae9da14 100644 --- a/syntax/vifm.vim +++ b/syntax/vifm.vim @@ -2,7 +2,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vifm') == -1  " vifm syntax file  " Maintainer:  xaizek <xaizek@posteo.net> -" Last Change: April 30, 2018 +" Last Change: July 4, 2018  " Inspired By: Vim syntax file by Dr. Charles E. Campbell, Jr.  if exists('b:current_syntax') @@ -76,8 +76,9 @@ syntax keyword vifmHiGroups contained WildMenu Border Win CmdLine CurrLine  		\ OtherLine Directory Link Socket Device Executable Selected BrokenLink  		\ TopLine TopLineSel StatusLine JobLine SuggestBox Fifo ErrorMsg CmpMismatch  		\ AuxWin TabLine TabLineSel -syntax keyword vifmHiStyles contained bold underline reverse inverse standout -		\ none +		\ User1 User2 User3 User4 User5 User6 User7 User8 User9 +syntax keyword vifmHiStyles contained +		\ bold underline reverse inverse standout italic none  syntax keyword vifmHiColors contained black red green yellow blue magenta cyan  		\ white default lightblack lightred lightgreen lightyellow lightblue  		\ lightmagenta lightcyan lightwhite Grey0 NavyBlue DarkBlue Blue3 Blue3_2 @@ -233,7 +234,7 @@ syntax region vifmExecute start='!' skip='\(\n\s*\\\)\|\(\n\s*".*$\)' end='$'  syntax region vifmMapArgs start='\ze\S\+'  		\ end='\ze.' skip='\(\n\s*\\\)\|\(\n\s*".*$\)'  		\ contained -		\ nextgroup=vifmMapLhs +		\ nextgroup=vifmMapArgList  syntax region vifmCMapArgs start='\S\+'  		\ end='\n\s*\\' skip='\(\n\s*\\\)\|\(\n\s*".*$\)'  		\ contained @@ -381,6 +382,9 @@ syntax region vifmArgument contained start=+'+ skip=+\\\\\|\\'\|''+  end=+'+  syntax match vifmEnvVar contained /\$[0-9a-zA-Z_]\+/  syntax match vifmNumber contained /\d\+/ +" Optional map arguments right after command name +syntax match vifmMapArgList '\(<silent>\s*\)*' contained nextgroup=vifmMapLhs +  " Ange-bracket notation  syntax case ignore  syntax match vifmNotation '<\(esc\|cr\|space\|del\|nop\|\(s-\)\?tab\|home\|end\|left\|right\|up\|down\|bs\|delete\|insert\|pageup\|pagedown\|\([acms]-\)\?f\d\{1,2\}\|c-s-[a-z[\]^_]\|s-c-[a-z[\]^_]\|c-[a-z[\]^_]\|[am]-c-[a-z]\|c-[am]-[a-z]\|[am]-[a-z]\)>' @@ -391,7 +395,7 @@ syntax region vifmComment contained contains=@Spell start='^\(\s\|:\)*"' end='$'  " Comment at the end of a line  syntax match vifmInlineComment contained contains=@Spell '\s"[^"]*$'  " This prevents highlighting non-first line of multi-line command -syntax match vifmNotComment contained '\s"[^"]*\(\(\n\s*\(\\\|"\)\)\@!\|$\)' +syntax match vifmNotComment contained '\s"[^"]*\(\n\s*\(\\\|"\)\)\@='  " Empty line  syntax match vifmEmpty /^\s*$/ @@ -435,6 +439,7 @@ highlight link vifmHiStyles PreProc  highlight link vifmHiColors Special  highlight link vifmOption PreProc  highlight link vifmNotation Special +highlight link vifmMapArgList Special  highlight link vifmString String  highlight link vifmStringInExpr String  highlight link vifmEnvVar PreProc | 
