11" matchit.vim: (global plugin) Extended "%" matching
22" autload script of matchit plugin, see ../plugin/matchit.vim
3- " Last Change: May 20, 2024
3+ " Last Change: Jan 06, 2025
44
55" Neovim does not support scriptversion
66if has (" vimscript-4" )
@@ -69,6 +69,26 @@ function matchit#Match_wrapper(word, forward, mode) range
6969 let startpos = [line (" ." ), col (" ." )]
7070 endif
7171
72+ " Check for custom match function hook
73+ if exists (" b:match_function" )
74+ let MatchFunc = b: match_function
75+ try
76+ let result = call (MatchFunc, [a: forward ])
77+ if ! empty (result)
78+ call cursor (result)
79+ return s: CleanUp (restore_options, a: mode , startpos)
80+ endif
81+ catch /.*/
82+ if exists (" b:match_debug" )
83+ echohl WarningMsg
84+ echom ' matchit: b:match_function error: ' .. v: exception
85+ echohl NONE
86+ endif
87+ return s: CleanUp (restore_options, a: mode , startpos)
88+ endtry
89+ " Empty result: fall through to regular matching
90+ endif
91+
7292 " First step: if not already done, set the script variables
7393 " s:do_BR flag for whether there are backrefs
7494 " s:pat parsed version of b:match_words
@@ -91,7 +111,7 @@ function matchit#Match_wrapper(word, forward, mode) range
91111 let default = escape (&mps , ' [$^.*~\\/?]' ) .. (strlen (&mps ) ? " ," : " " ) ..
92112 \ ' \/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\%(n\=def\)\=\>:#\s*endif\>'
93113 " s:all = pattern with all the keywords
94- let match_words = match_words .. ( strlen ( match_words) ? " , " : " " ) .. default
114+ let match_words = s: Append ( match_words, default)
95115 let s: last_words = match_words
96116 if match_words !~ s: notslash .. ' \\\d'
97117 let s: do_BR = 0
@@ -101,8 +121,8 @@ function matchit#Match_wrapper(word, forward, mode) range
101121 let s: pat = s: ParseWords (match_words)
102122 endif
103123 let s: all = substitute (s: pat , s: notslash .. ' \zs[,:]\+' , ' \\|' , ' g' )
104- " un-escape \, to ,
105- let s: all = substitute (s: all , ' \\, ' , ' , ' , ' g' )
124+ " un-escape \, and \: to , and :
125+ let s: all = substitute (s: all , s: notslash .. ' \zs\\\(:\|,\) ' , ' \1 ' , ' g' )
106126 " Just in case there are too many '\(...)' groups inside the pattern, make
107127 " sure to use \%(...) groups, so that error E872 can be avoided
108128 let s: all = substitute (s: all , ' \\(' , ' \\%(' , ' g' )
@@ -341,6 +361,18 @@ fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
341361 return ini .. " :" .. tailBR
342362endfun
343363
364+ " String append item2 to item and add ',' in between items
365+ fun ! s: Append (item, item2)
366+ if a: item == ' '
367+ return a: item2
368+ endif
369+ " there is already a trailing comma, don't add another one
370+ if a: item [-1 :] == ' ,'
371+ return a: item .. a: item2
372+ endif
373+ return a: item .. ' ,' .. a: item2
374+ endfun
375+
344376" Input a comma-separated list of groups with backrefs, such as
345377" a:groups = '\(foo\):end\1,\(bar\):end\1'
346378" and return a comma-separated list of groups with backrefs replaced:
@@ -538,8 +570,8 @@ fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
538570 else
539571 let currpat = substitute (current, s: notslash .. a: branch , ' \\|' , ' g' )
540572 endif
541- " un-escape \, to ,
542- let currpat = substitute (currpat, ' \\, ' , ' , ' , ' g' )
573+ " un-escape \, and \: to , and :
574+ let currpat = substitute (currpat, s: notslash .. ' \zs\\\(:\|,\) ' , ' \1 ' , ' g' )
543575 while a: string !~ a: prefix .. currpat .. a: suffix
544576 let tail = strpart (tail, i )
545577 let i = matchend (tail, s: notslash .. a: comma )
@@ -552,6 +584,8 @@ fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
552584 else
553585 let currpat = substitute (current, s: notslash .. a: branch , ' \\|' , ' g' )
554586 endif
587+ " un-escape \, and \: to , and :
588+ let currpat = substitute (currpat, s: notslash .. ' \zs\\\(:\|,\)' , ' \1' , ' g' )
555589 if a: 0
556590 let alttail = strpart (alttail, j )
557591 let j = matchend (alttail, s: notslash .. a: comma )
@@ -621,7 +655,7 @@ fun! matchit#MultiMatch(spflag, mode)
621655 let default = escape (&mps , ' [$^.*~\\/?]' ) .. (strlen (&mps ) ? " ," : " " ) ..
622656 \ ' \/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
623657 let s: last_mps = &mps
624- let match_words = match_words .. ( strlen ( match_words) ? " , " : " " ) .. default
658+ let match_words = s: Append ( match_words, default)
625659 let s: last_words = match_words
626660 if match_words !~ s: notslash .. ' \\\d'
627661 let s: do_BR = 0
0 commit comments