Created
September 30, 2024 14:46
-
-
Save AndrewRadev/c3b012e97ddbcd1b65fdce4cfe1f1665 to your computer and use it in GitHub Desktop.
Match other instances of visually selected areas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Install by saving as plugin/match_visual.vim in your Vim (or Neovim) config | |
" directory. | |
" | |
" Reimplementation of https://github.com/aaron-p1/match-visual.nvim | |
" | |
" Requires the function `getregion`, you have it if this expression prints 1: | |
" | |
" echo exists('*getregion') | |
" | |
if !exists('*getregion') | |
finish | |
endif | |
" Change minimum/maximum characters to trigger searches for by setting these | |
" variables: | |
" | |
" let g:match_visual_min_length = 5 | |
" let g:match_visual_max_length = 100 | |
" | |
" For maximum length, this could avoid potential performance issues. Set to -1 | |
" to remove the upper limit | |
" | |
if !exists('g:match_visual_min_length') | |
let g:match_visual_min_length = 2 | |
endif | |
if !exists('g:match_visual_max_length') | |
let g:match_visual_max_length = 1000 | |
endif | |
" Change highlighting by putting a `highlight` line somewhere in your config: | |
" | |
" highlight link VisualMatch Operator | |
" | |
highlight def link VisualMatch Search | |
augroup MatchVisual | |
autocmd! | |
autocmd ModeChanged *:[vV] noautocmd call s:MatchVisual() | |
autocmd ModeChanged [vV]:* noautocmd call s:UnmatchVisual() | |
augroup END | |
let s:matches = [] | |
function! s:MatchVisual() abort | |
augroup MatchVisualCursor | |
autocmd! | |
autocmd CursorMoved * noautocmd call s:UpdateVisual() | |
augroup END | |
noautocmd call s:UpdateVisual() | |
endfunction | |
function! s:UpdateVisual() abort | |
let start_pos = getpos('v') | |
let end_pos = getpos('.') | |
let region = getregion(start_pos, end_pos, {'type': mode()}) | |
call map(region, {_, line -> escape(line, '\')}) | |
let text = join(region, '\n') | |
call s:ClearMatches() | |
if len(text) < g:match_visual_min_length | |
return | |
endif | |
if g:match_visual_max_length > 0 && len(text) > g:match_visual_max_length | |
return | |
endif | |
let tabinfo = gettabinfo(tabpagenr())[0] | |
for window_id in tabinfo.windows | |
let pattern = '\V'..text | |
let match_id = matchadd('VisualMatch', pattern, 10, -1, {'window': window_id}) | |
call add(s:matches, [window_id, match_id]) | |
endfor | |
endfunction | |
function! s:UnmatchVisual() abort | |
call s:ClearMatches() | |
augroup MatchVisualCursor | |
autocmd! | |
augroup END | |
endfunction | |
function! s:ClearMatches() abort | |
for [win_id, match_id] in s:matches | |
call matchdelete(match_id, win_id) | |
endfor | |
let s:matches = [] | |
endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment