Since a comment under the question mentions that OP is using the plugin vim-matchup, I'll give the match-up specific solution. The plugin provides matchup#custom#define_motion
to facilitate such customization. This motion boils down to checking if there is a delimiter at the cursor and fetching the count-th next match. It will work in normal, visual, and operator pending mode, and g%
(the opposite of %
) is also provided.
function! s:percent(info, opts) abort
let l:delim = matchup#delim#get_current('all', 'both_all')
if !empty(l:delim)
let l:matches = matchup#delim#get_matching(l:delim, 1)
if len(l:matches)
for _ in range(a:info.count1)
let l:delim = l:delim.links[a:opts.down ? 'next': 'prev']
endfor
return matchup#custom#suggest_pos(l:delim, a:opts)
endif
endif
endfunction
call matchup#custom#define_motion('nox', '%', funcref('s:percent'), { 'down': 1 })
call matchup#custom#define_motion('nox', 'g%', funcref('s:percent'), { 'down': 0 })
As a bonus, here is a second, perhaps more straightforward method. Here we just check if there is a delimiter under the cursor, and if so use match-up's %
map. Otherwise, do nothing. Unlike the first solution, this doesn't work for modes other than normal.
function! s:test_cur()
call matchup#perf#timeout_start(1000)
return !empty(matchup#delim#get_current('all', 'both_all'))
endfunction
nmap <expr> % <sid>test_cur() ? '<plug>(matchup-%)' : '<Ignore>'
%
operator works even on an empty file type.%