@@ -1644,12 +1644,55 @@ fu! s:highlight(pat, grp)
16441644 if s: matcher != {} | retu | en
16451645 cal clearmatches ()
16461646 if ! empty (a: pat ) && s: ispath
1647- let pat = s: regexp ? substitute (a: pat , ' \\\@<!\^' , ' ^> \\zs' , ' g' ) : a: pat
1648- if s: byfname
1649- let pat = substitute (pat, ' \[\^\(.\{-}\)\]\\{-}' , ' [^\\/\1]\\{-}' , ' g' )
1650- let pat = substitute (pat, ' \$\@<!$' , ' \\ze[^\\/]*$' , ' g' )
1647+ if s: regexp
1648+ let pat = substitute (a: pat , ' \\\@<!\^' , ' ^> \\zs' , ' g' )
1649+ cal matchadd (a: grp , ( s: martcs == ' ' ? ' \c' : ' \C' ).pat)
1650+ el
1651+ let pat = a: pat
1652+
1653+ " get original characters so we can rebuild pat
1654+ let chars = split (pat, ' \[\^\\\?.\]\\{-}' )
1655+
1656+ " Build a pattern like /a.*b.*c/ from abc (but with .\{-} non-greedy
1657+ " matchers instead)
1658+ let pat = join (chars, ' .\{-}' )
1659+ " Ensure we match the last version of our pattern
1660+ let ending = ' \(.*' .pat.' \)\@!'
1661+ " Case sensitive?
1662+ let beginning = ( s: martcs == ' ' ? ' \c' : ' \C' ).' ^.*'
1663+ if s: byfname
1664+ " Make sure there are no slashes in our match
1665+ let beginning = beginning.' \([^\/]*$\)\@='
1666+ end
1667+
1668+ for i in range (len (chars))
1669+ " Surround our current target letter with \zs and \ze so it only
1670+ " actually matches that one letter, but has all preceding and trailing
1671+ " letters as well.
1672+ " \zsa.*b.*c
1673+ " a\(\zsb\|.*\zsb)\ze.*c
1674+ let charcopy = copy (chars)
1675+ if i == 0
1676+ let charcopy[i ] = ' \zs' .charcopy[i ].' \ze'
1677+ let middle = join (charcopy, ' .\{-}' )
1678+ else
1679+ let before = join (charcopy[0 :i - 1 ], ' .\{-}' )
1680+ let after = join (charcopy[i + 1 :-1 ], ' .\{-}' )
1681+ let c = charcopy[i ]
1682+ " for abc, match either ab.\{-}c or a.*b.\{-}c in that order
1683+ let cpat = ' \(\zs' .c .' \|' .' .*\zs' .c .' \)\ze.*'
1684+ let middle = before.cpat.after
1685+ endif
1686+
1687+ " Now we matchadd for each letter, the basic form being:
1688+ " ^.*\zsx\ze.*$, but with our pattern we built above for the letter,
1689+ " and a negative lookahead ensuring that we only highlight the last
1690+ " occurrence of our letters. We also ensure that our matcher is case
1691+ " insensitive or sensitive depending.
1692+ cal matchadd (a: grp , beginning.middle.ending)
1693+ endfor
16511694 en
1652- cal matchadd ( a: grp , ( s: martcs == ' ' ? ' \c ' : ' \C ' ).pat)
1695+
16531696 cal matchadd (' CtrlPLinePre' , ' ^>' )
16541697 en
16551698endf
0 commit comments