Update 2020-07-17: Now I would recommend using the vim-matchup plugin. When matching pair highlighting is turned on, vim-matchup also highlights matching keywords like if/else/endif
or while/continue/break
.
Update 2017-12-04: I've updated the answer by @Tommy A below to account for poorly specified matchit.vim
groups, and other situations where the %
operator does not return the cursor to the original position, ever. Check out the differences in the "while" loop. Anyone reading this thread is advised to use this version, to avoid infinite loops:
" Loop until `%` returns the original line number. Abort if:
" (1) the % operator keeps us on the same line, or
" (2) the % operator doesn't return us to the same line after some nubmer of jumps
function! s:get_match_lines(line) abort
let a:tolerance = 25
let a:badbrea = 1
let a:linebefore = -1
let lines = []
while a:tolerance && a:linebefore != line('.')
let a:linebefore = line('.')
let a:tolerance -= 1
normal! %
if line('.') == a:line
let a:badbreak = 0
break
endif
call add(lines, line('.'))
endwhile
exe 'normal! ' . a:line . 'gg'
if a:badbreak == 1
return []
else
return lines
endif
endfunction
" Trigger matching line highlights.
" Here `b:hl_last_line` prevents running the script again while the
" cursor is moved to matching pair on the same line.
function! s:hl_matching_lines() abort
if exists('b:hl_last_line') && b:hl_last_line == line('.')
return
endif
let b:hl_last_line = line('.')
let view = winsaveview()
silent! call matchdelete(12345) " arbitrary match ID
let lines = s:get_match_lines(view.lnum)
if empty(lines) " try detecting at column 1
call cursor(view.lnum, 1)
let lines = s:get_match_lines(view.lnum)
endif
if len(lines)
" call add(lines, view.lnum) " highlight current line as well as other lines
if exists('*matchaddpos') " faster than using 'matchadd' patterns (if available)
call matchaddpos('MatchLine', lines, 0, 12345)
else " highlight matching lines using the \%l atom and add highlight group
call matchadd('MatchLine', join(map(lines, '''\%''.v:val.''l'''), '\|'), 0, 12345)
endif
endif
call winrestview(view)
endfunction
function! s:hl_matching_lines_clear() abort
silent! call matchdelete(12345)
unlet! b:hl_last_line
endfunction
" Define highlight groups used for matching lines.
" Use the `MatchParen` group by default.
highlight default link MatchLine MatchParen
augroup matching_lines
autocmd!
autocmd CursorMoved * call s:hl_matching_lines()
autocmd InsertEnter * call s:hl_matching_lines_clear()
autocmd TextChanged,TextChangedI * call s:hl_matching_lines_clear()
augroup END
Original question:
Currently vim highlights matching parentheses, brackets, quotes, etc. with cyan background and white foreground -- the cursor can be moved between these with %
. Thanks to my matchit.vim, I can also switch with %
between if/end, for/end, etc., however these are not highlighted on selection.
How can I automatically highlight these matching pairs upon selection, like is automatically done with parentheses?
Furthermore, how can I modify the background color used for these pairs using :highlight
?
Thanks in advance.
autoload
, how should I call it?