On Thursday, October 18, 2018 at 1:11:58 AM UTC+2, Chris P wrote: > I don't have patch-approval. It would be useful to get a sense of how large > the change is. I think any patch approver will likely want that information. > How hard is it for you to specify what the diff is?
Hello Chris, Included is the patch. I would also be glad if any MATLAB users would mind testing it on their projects. A priori it should handle all the cases I can think of, but still, there exists no standardized test suite. /Axel Forsman -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
--- a/runtime/indent/matlab.vim +++ b/runtime/indent/matlab.vim @@ -1,74 +1,83 @@ -" Matlab indent file -" Language: Matlab +" Vim indent file +" Language: MATLAB " Maintainer: Christophe Poucet <christophe.pou...@pandora.be> " Last Change: 6 January, 2001 -" Only load this indent file when no other was loaded. -if exists("b:did_indent") - finish -endif +" Only load this indent file when no other was 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() +setlocal indentkeys=!,o,O,0=end,e,0=elsei,0=elseif,0=case,0=otherwise,0=catch,0=function +" 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) -setlocal indentexpr=GetMatlabIndent(v:lnum) +let s:open_pat = 'for\|if\|parfor\|spmd\|switch\|try\|while\|classdef\|properties\|methods\|events\|enumeration' +let s:middle_pat = 'else\|elseif\|case\|otherwise\|catch' +let b:pair_pat = '\C\(\<\%(' + \ . (b:MATLAB_function_indent == 1 ? '\s\@<=' : '') + \ . (b:MATLAB_function_indent >= 1 ? 'function\|' : '') + \ . s:open_pat . '\|\%(^\s*\)\@<=\%(' . s:middle_pat . '\)\)\>\|\[\|{\)' + \ . '\|\(\%(\S.*\)\@<=\<end\>\|\]\|}\)' -" Only define the function once. -if exists("*GetMatlabIndent") - finish -endif +" 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 +let s:dedent_pat = '\C^\s*\<\%(end\|else\|elseif\|catch\|otherwise\|\(case\|function\)\)\>' +let s:start_pat = '\C\<\%(function\|' . s:open_pat . '\)\>' +let s:search_flags = 'cp' . (has('patch-7.4.984') ? 'z' : '') - " 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 +" 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 - let curind = indent(plnum) +" 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 - " 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 +function! s:GetOpenCloseCount(lnum, ...) + let endcol = a:0 >= 1 ? a:1 : 0 + let i = 0 | let line = getline(a:lnum) + call cursor(a:lnum, 1) + while 1 + let [lnum, c, submatch] = searchpos(b:pair_pat, s:search_flags, a:lnum) + if !submatch || endcol && c >= endcol | break | endif + if !s:IsCommentOrString(lnum, c) + \ && line[c - 3:] !~# 'end[^(]*)' " Array indexing heuristic + let i += submatch == 2 ? 1 : -1 + endif + if c == col('$') - 1 | break | endif + call cursor(0, c + 1) + endwhile + return i +endfunction - " 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 +function! GetMatlabIndent() + " Align end, etc. with start of block + call cursor(v:lnum, 1) + let submatch = search(s:dedent_pat, s:search_flags, v:lnum) + if submatch && !s:IsCommentOrString(v:lnum, col('.')) + let [lnum, col] = searchpairpos(s:start_pat, '', '\C\<end\>', 'bW', 's:IsCommentOrString(line("."), col("."))') + return lnum ? indent(lnum) + shiftwidth() * (s:GetOpenCloseCount(lnum, col) + submatch == 2) : 0 + endif + let prev_lnum = prevnonblank(v:lnum - 1) + " Count how many blocks the previous line opens/closes + let i = prev_lnum ? s:GetOpenCloseCount(prev_lnum) : 0 + " Line continuations indent once per statement + let i += s:IsLineContinuation(v:lnum - 1) - s:IsLineContinuation(v:lnum - 2) - " If we got to here, it means that the user takes the standardversion, so we return it - return curind + return indent(prev_lnum) + shiftwidth() * i endfunction - -" vim:sw=2