summaryrefslogtreecommitdiffstats
path: root/runtime/indent
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-12-18 21:41:50 +0100
committerBram Moolenaar <Bram@vim.org>2018-12-18 21:41:50 +0100
commit9d87a37ee9d87f5bdbc779bc940d5f1e6f055d0a (patch)
treef569453cf21f8a14b1a90e6e4edeeb41fe624b70 /runtime/indent
parenta86187b9cd529754ad85cd621169876317eb3a69 (diff)
Update runtime files.
Diffstat (limited to 'runtime/indent')
-rw-r--r--runtime/indent/falcon.vim2
-rw-r--r--runtime/indent/matlab.vim187
-rw-r--r--runtime/indent/testdir/matlab.in63
-rw-r--r--runtime/indent/testdir/matlab.ok63
-rw-r--r--runtime/indent/testdir/runtest.vim1
-rw-r--r--runtime/indent/testdir/tcl.in2
-rw-r--r--runtime/indent/testdir/tcl.ok20
-rw-r--r--runtime/indent/testdir/xml.in2
-rw-r--r--runtime/indent/testdir/xml.ok40
-rw-r--r--runtime/indent/xml.vim116
10 files changed, 354 insertions, 142 deletions
diff --git a/runtime/indent/falcon.vim b/runtime/indent/falcon.vim
index b34e7cfd47..664ad61aa5 100644
--- a/runtime/indent/falcon.vim
+++ b/runtime/indent/falcon.vim
@@ -368,7 +368,7 @@ function FalconGetIndent(...)
return indent('.')
endif
else
- call cursor(clnum, vcol)
+ call cursor(clnum, 0) " FIXME: column was vcol
end
endif
diff --git a/runtime/indent/matlab.vim b/runtime/indent/matlab.vim
index 6a31624389..d2818a18ea 100644
--- a/runtime/indent/matlab.vim
+++ b/runtime/indent/matlab.vim
@@ -1,74 +1,121 @@
-" Matlab indent file
-" Language: Matlab
-" Maintainer: Christophe Poucet <christophe.poucet@pandora.be>
-" Last Change: 6 January, 2001
-
-" Only load this indent file when no other was loaded.
-if exists("b:did_indent")
- finish
-endif
+" Vim indent file
+" Language: MATLAB
+" Maintainer: Axel Forsman <axelsfor@gmail.com>
+" Previous maintainer: Christophe Poucet <christophe.poucet@pandora.be>
+
+" Only load if no other indent file is loaded
+if exists('b:did_indent') | finish | endif
let b:did_indent = 1
-" Some preliminary setting
-setlocal indentkeys=!,o,O=end,=case,=else,=elseif,=otherwise,=catch
-
-
-setlocal indentexpr=GetMatlabIndent(v:lnum)
-
-" Only define the function once.
-if exists("*GetMatlabIndent")
- finish
-endif
-
-function GetMatlabIndent(lnum)
- " Give up if this line is explicitly joined.
- if getline(a:lnum - 1) =~ '\\$'
- return -1
- endif
-
- " Search backwards for the first non-empty line.
- let plnum = a:lnum - 1
- while plnum > 0 && getline(plnum) =~ '^\s*$'
- let plnum = plnum - 1
- endwhile
-
- if plnum == 0
- " This is the first non-empty line, use zero indent.
- return 0
- endif
-
- let curind = indent(plnum)
-
- " If the current line is a stop-block statement...
- if getline(v:lnum) =~ '^\s*\(end\|else\|elseif\|case\|otherwise\|catch\)\>'
- " See if this line does not follow the line right after an openblock
- if getline(plnum) =~ '^\s*\(for\|if\|else\|elseif\|case\|while\|switch\|try\|otherwise\|catch\)\>'
- " See if the user has already dedented
- elseif indent(v:lnum) > curind - shiftwidth()
- " If not, recommend one dedent
- let curind = curind - shiftwidth()
- else
- " Otherwise, trust the user
- return -1
- endif
-" endif
-
- " If the previous line opened a block
- elseif getline(plnum) =~ '^\s*\(for\|if\|else\|elseif\|case\|while\|switch\|try\|otherwise\|catch\)\>'
- " See if the user has already indented
- if indent(v:lnum) < curind + shiftwidth()
- "If not, recommend indent
- let curind = curind + shiftwidth()
- else
- " Otherwise, trust the user
- return -1
- endif
- endif
-
-
-
- " If we got to here, it means that the user takes the standardversion, so we return it
- return curind
+setlocal indentexpr=GetMatlabIndent()
+setlocal indentkeys=!,o,O,e,0=end,0=elseif,0=case,0=otherwise,0=catch,0=function,0=elsei
+
+" The value of the Function indenting format in
+" MATLAB Editor/Debugger Language Preferences.
+" The possible values are 0 for Classic, 1 for Indent nested functions
+" and 2 for Indent all functions (default).
+let b:MATLAB_function_indent = get(g:, 'MATLAB_function_indent', 2)
+" The previous value of b:changedtick
+let b:MATLAB_lasttick = -1
+" The previously indented line
+let b:MATLAB_lastline = -1
+" Whether the line above was a line continuation
+let b:MATLAB_waslc = 0
+let b:MATLAB_bracketlevel = 0
+
+" Only define the function once
+if exists("*GetMatlabIndent") | finish | endif
+
+let s:keepcpo = &cpo
+set cpo&vim
+
+let s:end = '\<end\>\%([^(]*)\)\@!' " Array indexing heuristic
+let s:open_pat = 'for\|if\|parfor\|spmd\|switch\|try\|while\|classdef\|properties\|methods\|events\|enumeration'
+let s:dedent_pat = '\C^\s*\zs\<\%(end\|else\|elseif\|catch\|\(case\|otherwise\|function\)\)\>'
+let s:start_pat = '\C\<\%(function\|' . s:open_pat . '\)\>'
+let s:bracket_pair_pat = '\(\[\|{\)\|\(\]\|}\)'
+let s:zflag = has('patch-7.4.984') ? 'z' : ''
+
+" Returns whether a comment or string envelops the specified column.
+function! s:IsCommentOrString(lnum, col)
+ return synIDattr(synID(a:lnum, a:col, 1), "name") =~# 'matlabComment\|matlabMultilineComment\|matlabString'
+endfunction
+
+" Returns whether the specified line continues on the next line.
+function! s:IsLineContinuation(lnum)
+ let l = getline(a:lnum) | let c = -3
+ while 1
+ let c = match(l, '\.\{3}', c + 3)
+ if c == -1 | return 0
+ elseif !s:IsCommentOrString(a:lnum, c) | return 1 | endif
+ endwhile
+endfunction
+
+function! s:SubmatchCount(lnum, pattern, ...)
+ let endcol = a:0 >= 1 ? a:1 : 1 / 0 | let x = [0, 0, 0, 0]
+ call cursor(a:lnum, 1)
+ while 1
+ let [lnum, c, submatch] = searchpos(a:pattern, 'cpe' . s:zflag, a:lnum)
+ if !submatch || c >= endcol | break | endif
+ if !s:IsCommentOrString(lnum, c) | let x[submatch - 2] += 1 | endif
+ if cursor(0, c + 1) == -1 || col('.') == c | break | endif
+ endwhile
+ return x
+endfunction
+
+function! s:GetOpenCloseCount(lnum, pattern, ...)
+ let counts = call('s:SubmatchCount', [a:lnum, a:pattern] + a:000)
+ return counts[0] - counts[1]
+endfunction
+
+function! GetMatlabIndent()
+ let prevlnum = prevnonblank(v:lnum - 1)
+
+ if b:MATLAB_lasttick != b:changedtick || b:MATLAB_lastline != prevlnum
+ " Recalculate bracket count (only have to check same block and line above)
+ let b:MATLAB_bracketlevel = 0
+ let previndent = indent(prevlnum) | let l = prevlnum
+ while 1
+ let l = prevnonblank(l - 1) | let indent = indent(l)
+ if l <= 0 || previndent < indent | break | endif
+ let b:MATLAB_bracketlevel += s:GetOpenCloseCount(l, s:bracket_pair_pat)
+ if previndent != indent | break | endif
+ endwhile
+
+ let b:MATLAB_waslc = s:IsLineContinuation(prevlnum - 1)
+ endif
+ " If line above was blank it can impossibly have been a LC
+ let above_lc = b:MATLAB_lasttick == b:changedtick && prevlnum != v:lnum - 1 && b:MATLAB_lastline == prevlnum ? 0 : s:IsLineContinuation(v:lnum - 1)
+
+ let pair_pat = '\C\<\(' . s:open_pat . '\|'
+ \ . (b:MATLAB_function_indent == 1 ? '^\@<!' : '')
+ \ . (b:MATLAB_function_indent >= 1 ? 'function\|' : '')
+ \ . '\|\%(^\s*\)\@<=\%(else\|elseif\|case\|otherwise\|catch\)\)\>'
+ \ . '\|\S\s*\zs\(' . s:end . '\)'
+ let [open, close, b_open, b_close] = prevlnum ? s:SubmatchCount(prevlnum,
+ \ pair_pat . '\|' . s:bracket_pair_pat) : [0, 0, 0, 0]
+ let curbracketlevel = b:MATLAB_bracketlevel + b_open - b_close
+
+ call cursor(v:lnum, 1)
+ let submatch = search(s:dedent_pat, 'cp' . s:zflag, v:lnum)
+ if submatch && !s:IsCommentOrString(v:lnum, col('.'))
+ " Align end, et cetera with start of block
+ let [lnum, col] = searchpairpos(s:start_pat, '', '\C' . s:end, 'bW', 's:IsCommentOrString(line("."), col("."))')
+ let result = lnum ? indent(lnum) + shiftwidth() * (s:GetOpenCloseCount(lnum, pair_pat, col) + submatch == 2) : 0
+ else
+ " Count how many blocks the previous line opens/closes
+ " Line continuations/brackets indent once per statement
+ let result = indent(prevlnum) + shiftwidth() * (open - close
+ \ + (b:MATLAB_bracketlevel ? -!curbracketlevel : !!curbracketlevel)
+ \ + (curbracketlevel <= 0) * (above_lc - b:MATLAB_waslc))
+ endif
+
+ let b:MATLAB_waslc = above_lc
+ let b:MATLAB_bracketlevel = curbracketlevel
+ let b:MATLAB_lasttick = b:changedtick
+ let b:MATLAB_lastline = v:lnum
+ return result
endfunction
-" vim:sw=2
+let &cpo = s:keepcpo
+unlet s:keepcpo
diff --git a/runtime/indent/testdir/matlab.in b/runtime/indent/testdir/matlab.in
index 1a2bc83d4b..5bba1a56dd 100644
--- a/runtime/indent/testdir/matlab.in
+++ b/runtime/indent/testdir/matlab.in
@@ -15,3 +15,66 @@ catch exception
statements
end
% END_INDENT
+
+% START_INDENT
+if true, ...
+if true
+disp hello
+end
+end
+% END_INDENT
+
+% START_INDENT
+switch a
+case expr
+if true, foo; end
+disp hello
+otherwise
+disp bar
+end
+% END_INDENT
+
+% START_INDENT
+if true
+A(1:end - 1)
+disp foo
+end
+% END_INDENT
+
+% START_INDENT
+A = [{
+}
+] ...
+disp foo
+disp bar
+% END_INDENT
+
+% START_INDENT
+% INDENT_EXE let b:MATLAB_function_indent = 0
+function foo
+disp foo
+function nested
+disp bar
+end
+end
+% END_INDENT
+
+% START_INDENT
+% INDENT_EXE let b:MATLAB_function_indent = 1
+function foo
+disp foo
+function nested
+disp bar
+end
+end
+% END_INDENT
+
+% START_INDENT
+% INDENT_EXE let b:MATLAB_function_indent = 2
+function foo
+disp foo
+function nested
+disp bar
+end
+end
+% END_INDENT
diff --git a/runtime/indent/testdir/matlab.ok b/runtime/indent/testdir/matlab.ok
index 88e1d86b06..b1112263b2 100644
--- a/runtime/indent/testdir/matlab.ok
+++ b/runtime/indent/testdir/matlab.ok
@@ -15,3 +15,66 @@ catch exception
statements
end
% END_INDENT
+
+% START_INDENT
+if true, ...
+ if true
+ disp hello
+ end
+end
+% END_INDENT
+
+% START_INDENT
+switch a
+ case expr
+ if true, foo; end
+ disp hello
+ otherwise
+ disp bar
+end
+% END_INDENT
+
+% START_INDENT
+if true
+ A(1:end - 1)
+ disp foo
+end
+% END_INDENT
+
+% START_INDENT
+A = [{
+ }
+ ] ...
+ disp foo
+disp bar
+% END_INDENT
+
+% START_INDENT
+% INDENT_EXE let b:MATLAB_function_indent = 0
+function foo
+disp foo
+ function nested
+ disp bar
+ end
+end
+% END_INDENT
+
+% START_INDENT
+% INDENT_EXE let b:MATLAB_function_indent = 1
+function foo
+disp foo
+ function nested
+ disp bar
+ end
+end
+% END_INDENT
+
+% START_INDENT
+% INDENT_EXE let b:MATLAB_function_indent = 2
+function foo
+ disp foo
+ function nested
+ disp bar
+ end
+end
+% END_INDENT
diff --git a/runtime/indent/testdir/runtest.vim b/runtime/indent/testdir/runtest.vim
index 96c31453af..2943152d3c 100644
--- a/runtime/indent/testdir/runtest.vim
+++ b/runtime/indent/testdir/runtest.vim
@@ -8,6 +8,7 @@ if 1
set nocp
filetype indent on
set nowrapscan
+set report=9999
au! SwapExists * call HandleSwapExists()
func HandleSwapExists()
diff --git a/runtime/indent/testdir/tcl.in b/runtime/indent/testdir/tcl.in
index 3ef4ebc0a8..c769d5bf5e 100644
--- a/runtime/indent/testdir/tcl.in
+++ b/runtime/indent/testdir/tcl.in
@@ -1,4 +1,4 @@
-# vim: set filetype=tcl shiftwidth=4 tabstop=4:
+# vim: set filetype=tcl shiftwidth=4 tabstop=8 expandtab :
# START_INDENT
proc abc {} {
diff --git a/runtime/indent/testdir/tcl.ok b/runtime/indent/testdir/tcl.ok
index 0fb52e782f..77f24e9044 100644
--- a/runtime/indent/testdir/tcl.ok
+++ b/runtime/indent/testdir/tcl.ok
@@ -1,19 +1,19 @@
-# vim: set filetype=tcl shiftwidth=4 tabstop=4:
+# vim: set filetype=tcl shiftwidth=4 tabstop=8 expandtab :
# START_INDENT
proc abc {} {
- set a 5
- if {[some_cmd]==1} {
- foreach i [list {1 2 3}] {
- # Does this comment affect anything?
- puts $i
- }
- }
+ set a 5
+ if {[some_cmd]==1} {
+ foreach i [list {1 2 3}] {
+ # Does this comment affect anything?
+ puts $i
+ }
+ }
}
command_with_a_long_time -arg1 "First" \
- -arg2 "Second" \
- -arg3 "Third"
+ -arg2 "Second" \
+ -arg3 "Third"
puts "Move indent back after line continuation is complete"
# END_INDENT
diff --git a/runtime/indent/testdir/xml.in b/runtime/indent/testdir/xml.in
index d184681c86..b6333340e2 100644
--- a/runtime/indent/testdir/xml.in
+++ b/runtime/indent/testdir/xml.in
@@ -1,4 +1,4 @@
-<!-- vim: set ft=xml ts=2 sw=0 sts=-1 et : -->
+<!-- vim: set ft=xml ts=8 sw=0 sts=-1 et : -->
<!-- START_INDENT -->
<?xml version="1.0" encoding="utf-8"?>
<tag0>
diff --git a/runtime/indent/testdir/xml.ok b/runtime/indent/testdir/xml.ok
index a8e2c92a16..529198572a 100644
--- a/runtime/indent/testdir/xml.ok
+++ b/runtime/indent/testdir/xml.ok
@@ -1,32 +1,32 @@
-<!-- vim: set ft=xml ts=2 sw=0 sts=-1 et : -->
+<!-- vim: set ft=xml ts=8 sw=0 sts=-1 et : -->
<!-- START_INDENT -->
<?xml version="1.0" encoding="utf-8"?>
<tag0>
- <tag1>
- <!-- comment -->
- <tag2>
- <tag3/>
- </tag2>
- <!-- text comment -->
+ <tag1>
+ <!-- comment -->
+ <tag2>
+ <tag3/>
+ </tag2>
+ <!-- text comment -->
- <!--
- text comment
- -->
- </tag1>
- <!--
- text comment
- end coment -->
+ <!--
+ text comment
+ -->
+ </tag1>
+ <!--
+ text comment
+ end coment -->
</tag0>
<!-- END_INDENT -->
<!-- START_INDENT -->
<?xml version="1.0" encoding="utf-8"?>
<tag0>
- <tag1>
- <!-- comment -->
- <tag2>
- <tag3/>
- </tag2>
- </tag1>
+ <tag1>
+ <!-- comment -->
+ <tag2>
+ <tag3/>
+ </tag2>
+ </tag1>
</tag0>
<!-- END_INDENT -->
diff --git a/runtime/indent/xml.vim b/runtime/indent/xml.vim
index 7afcc89b7f..bc64aacfe1 100644
--- a/runtime/indent/xml.vim
+++ b/runtime/indent/xml.vim
@@ -1,15 +1,21 @@
-" Language: xml
-" Repository: https://github.com/chrisbra/vim-xml-ftplugin
-" Maintainer: Christian Brabandt <cb@256bit.org>
-" Previous Maintainer: Johannes Zellner <johannes@zellner.org>
-" Last Change: 20181022 - Do not overwrite indentkeys setting
-" https://github.com/chrisbra/vim-xml-ftplugin/issues/1
-" 20180724 - Correctly indent xml comments https://github.com/vim/vim/issues/3200
-" Notes: 1) does not indent pure non-xml code (e.g. embedded scripts)
-" 2) will be confused by unbalanced tags in comments
-" or CDATA sections.
-" 2009-05-26 patch by Nikolai Weibull
-" TODO: implement pre-like tags, see xml_indent_open / xml_indent_close
+" Language: xml
+" Repository: https://github.com/chrisbra/vim-xml-ftplugin
+" Last Changed: Dec 07th, 2018
+" Maintainer: Christian Brabandt <cb@256bit.org>
+" Previous Maintainer: Johannes Zellner <johannes@zellner.org>
+" Last Change:
+" 20181116 - Fix indentation when tags start with a colon or an underscore
+" https://github.com/vim/vim/pull/926
+" 20181022 - Do not overwrite indentkeys setting
+" https://github.com/chrisbra/vim-xml-ftplugin/issues/1
+" 20180724 - Correctly indent xml comments https://github.com/vim/vim/issues/3200
+"
+" Notes:
+" 1) does not indent pure non-xml code (e.g. embedded scripts)
+" 2) will be confused by unbalanced tags in comments
+" or CDATA sections.
+" 2009-05-26 patch by Nikolai Weibull
+" TODO: implement pre-like tags, see xml_indent_open / xml_indent_close
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -20,11 +26,12 @@ let s:keepcpo= &cpo
set cpo&vim
" [-- local settings (must come before aborting the script) --]
+" Attention: Parameter use_syntax_check is used by the docbk.vim indent script
setlocal indentexpr=XmlIndentGet(v:lnum,1)
setlocal indentkeys=o,O,*<Return>,<>>,<<>,/,{,},!^F
if !exists('b:xml_indent_open')
- let b:xml_indent_open = '.\{-}<\a'
+ let b:xml_indent_open = '.\{-}<[:A-Z_a-z]'
" pre tag, e.g. <address>
" let b:xml_indent_open = '.\{-}<[/]\@!\(address\)\@!'
endif
@@ -40,7 +47,7 @@ unlet s:keepcpo
" [-- finish, if the function already exists --]
if exists('*XmlIndentGet')
- finish
+ finish
endif
let s:keepcpo= &cpo
@@ -53,13 +60,13 @@ endfun
" [-- check if it's xml --]
fun! <SID>XmlIndentSynCheck(lnum)
- if '' != &syntax
- let syn1 = synIDattr(synID(a:lnum, 1, 1), 'name')
- let syn2 = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
- if '' != syn1 && syn1 !~ 'xml' && '' != syn2 && syn2 !~ 'xml'
- " don't indent pure non-xml code
- return 0
- endif
+ if &syntax != ''
+ let syn1 = synIDattr(synID(a:lnum, 1, 1), 'name')
+ let syn2 = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
+ if syn1 != '' && syn1 !~ 'xml' && syn2 != '' && syn2 !~ 'xml'
+ " don't indent pure non-xml code
+ return 0
+ endif
endif
return 1
endfun
@@ -68,41 +75,72 @@ endfun
fun! <SID>XmlIndentSum(lnum, style, add)
let line = getline(a:lnum)
if a:style == match(line, '^\s*</')
- return (shiftwidth() *
- \ (<SID>XmlIndentWithPattern(line, b:xml_indent_open)
- \ - <SID>XmlIndentWithPattern(line, b:xml_indent_close)
- \ - <SID>XmlIndentWithPattern(line, '.\{-}/>'))) + a:add
+ return (shiftwidth() *
+ \ (<SID>XmlIndentWithPattern(line, b:xml_indent_open)
+ \ - <SID>XmlIndentWithPattern(line, b:xml_indent_close)
+ \ - <SID>XmlIndentWithPattern(line, '.\{-}/>'))) + a:add
else
- return a:add
+ return a:add
endif
endfun
+" Main indent function
fun! XmlIndentGet(lnum, use_syntax_check)
" Find a non-empty line above the current line.
- let lnum = prevnonblank(a:lnum - 1)
+ let plnum = prevnonblank(a:lnum - 1)
+ " Find previous line with a tag (regardless whether open or closed)
+ let ptag = search('.\{-}<[/:A-Z_a-z]', 'bnw')
" Hit the start of the file, use zero indent.
- if lnum == 0
- return 0
+ if plnum == 0
+ return 0
endif
+ let syn_name = ''
if a:use_syntax_check
- let check_lnum = <SID>XmlIndentSynCheck(lnum)
- let check_alnum = <SID>XmlIndentSynCheck(a:lnum)
- if 0 == check_lnum || 0 == check_alnum
- return indent(a:lnum)
- elseif -1 == check_lnum || -1 == check_alnum
- return -1
- endif
+ let check_lnum = <SID>XmlIndentSynCheck(plnum)
+ let check_alnum = <SID>XmlIndentSynCheck(a:lnum)
+ if check_lnum == 0 || check_alnum == 0
+ return indent(a:lnum)
+ endif
+ let syn_name = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
endif
- let ind = <SID>XmlIndentSum(lnum, -1, indent(lnum))
- let ind = <SID>XmlIndentSum(a:lnum, 0, ind)
+ if syn_name =~ 'Comment'
+ return <SID>XmlIndentComment(a:lnum)
+ endif
+ " Get indent from previous tag line
+ let ind = <SID>XmlIndentSum(ptag, -1, indent(ptag))
+ " Determine indent from current line
+ let ind = <SID>XmlIndentSum(a:lnum, 0, ind)
return ind
endfun
+" return indent for a commented line,
+" the middle part might be indented on additional level
+func! <SID>XmlIndentComment(lnum)
+ let ptagopen = search(b:xml_indent_open, 'bnw')
+ let ptagclose = search(b:xml_indent_close, 'bnw')
+ if getline(a:lnum) =~ '<!--'
+ " if previous tag was a closing tag, do not add
+ " one additional level of indent
+ if ptagclose > ptagopen && a:lnum > ptagclose
+ return indent(ptagclose)
+ else
+ " start of comment, add one indentation level
+ return indent(ptagopen) + shiftwidth()
+ endif
+ elseif getline(a:lnum) =~ '-->'
+ " end of comment, same as start of comment
+ return indent(search('<!--', 'bnw'))
+ else
+ " middle part of comment, add one additional level
+ return indent(search('<!--', 'bnw')) + shiftwidth()
+ endif
+endfunc
+
let &cpo = s:keepcpo
unlet s:keepcpo
-" vim:ts=8
+" vim:ts=4 et sts=-1 sw=0