From: Doug Kearns Date: Fri, 23 Jan 2026 19:07:21 +0000 (+0000) Subject: runtime(csh): Update ftplugin, improve matchit behaviour X-Git-Tag: v9.1.2105~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09a48056c775074e0c29aaaf252ccea918f42bbc;p=thirdparty%2Fvim.git runtime(csh): Update ftplugin, improve matchit behaviour - Allow for an unparenthesised expression argument to the 'if', 'if-then', and 'while' commands. This is undocumented, and probably unintended, behaviour but is frequently seen in the wild. - Allow for a continued-line expression argument to the 'if-then' command. related: #19172 (csh: Support negated if in matchit) closes: #19190 Signed-off-by: Doug Kearns Signed-off-by: Christian Brabandt --- diff --git a/runtime/ftplugin/csh.vim b/runtime/ftplugin/csh.vim index 6f8201b99d..7603d0556f 100644 --- a/runtime/ftplugin/csh.vim +++ b/runtime/ftplugin/csh.vim @@ -3,9 +3,8 @@ " Maintainer: Doug Kearns " Previous Maintainer: Dan Sharp " Contributor: Johannes Zellner -" Last Change: 2024 Jan 14 -" 2024 May 23 by Riley Bruins ('commentstring') -" 2026 Jan 15 improved matchit support +" Riley Bruins +" Last Change: 2026 Jan 16 if exists("b:did_ftplugin") finish @@ -22,29 +21,52 @@ setlocal formatoptions+=crql let b:undo_ftplugin = "setlocal com< cms< fo<" -" Csh: thanks to Johannes Zellner -" - Both foreach and end must appear alone on separate lines. -" - The words else and endif must appear at the beginning of input lines; -" the if must appear alone on its input line or after an else. -" - Each case label and the default label must appear at the start of a -" line. -" - while and end must appear alone on their input lines. if exists("loaded_matchit") && !exists("b:match_words") - let s:line_start = '\%(^\s*\)\@<=' - let b:match_words = - \ s:line_start .. 'if\s*!\?\s*(.*)\s*then\>:' .. - \ s:line_start .. 'else\s\+if\s*(.*)\s*then\>:' .. s:line_start .. 'else\>:' .. - \ s:line_start .. 'endif\>,' .. - \ s:line_start .. '\%(\:\:' .. - \ s:line_start .. 'end\>,' .. - \ s:line_start .. 'switch\s*(:' .. - \ s:line_start .. 'case\s\+:' .. s:line_start .. 'default\>:\:' .. - \ s:line_start .. 'endsw\>' - unlet s:line_start - let b:undo_ftplugin ..= " | unlet! b:match_words" + let b:match_ignorecase = 0 + let b:match_words = "CshMatchWords()" + let b:match_skip = "CshMatchSkip()" + let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_skip b:match_words" endif +" skip single line 'if' commands +function CshMatchSkip() + return getline(".") =~# '^\s*if\>' && !s:CshIsIfThenCommand() +endfunction + +function CshMatchWords() + let line_start = '\%(^\s*\)\@<=' + let match_words = + \ line_start .. '\%(foreach\s\+\h\w*\s*(\|while\>\):' .. + \ '\:\:' .. + \ line_start .. 'end\>,' .. + \ line_start .. 'switch\s*(:' .. + \ line_start .. 'case\s\+:' .. line_start .. 'default\>:\:' .. + \ line_start .. 'endsw\>' + + if expand("") =~# '\' && !s:CshIsIfThenCommand() + return match_words + else + return match_words .. "," .. + \ line_start .. 'if\>:' .. + \ line_start .. 'else\s\+if\>:' .. line_start .. 'else\>:' .. + \ line_start .. 'endif\>' + endif +endfunction + +function s:CshIsIfThenCommand() + let lnum = line(".") + let line = getline(lnum) + + " join continued lines + while lnum < line("$") && line =~ '^\%([^\\]\|\\\\\)*\\$' + let lnum += 1 + let line = substitute(line, '\\$', '', '') .. getline(lnum) + endwhile + + " TODO: confirm with syntax checks when the highlighting is more accurate + return line =~# '^\s*if\>.*\