GeezerVison is showing github.com — HighlightedYank feature · Issue #14848 · vim/vim
HighlightedYank feature #14848DescriptionNow that getregionpos() has been merged, it is quite straightforward to have this feature, which temporarily highlights the yanked region to make it apparent. I use this feature, and it may be of value to others. It is also natively included in Neovim.
If enough people think this is worthwhile, I can submit a PR. Maybe this can be a plugin, or an example added to the help file.
def HighlightedYank(hlgroup = 'IncSearch', duration = 300)
if v:event.operator ==? 'y'
var [beg, end] = [getpos("'["), getpos("']")]
var type = v:event.regtype ?? 'v'
var pos = getregionpos(beg, end, {type: type})
var end_offset = (type == 'V' || v:event.inclusive) ? 1 : 0
var m = matchaddpos(hlgroup, pos->mapnew((_, v) => {
var col_beg = v[0][2] + v[0][3]
var col_end = v[1][2] + v[1][3] + end_offset
return [v[0][1], col_beg, col_end - col_beg]
}))
var winid = win_getid()
timer_start(duration, (_) => m->matchdelete(winid))
endif
enddef
autocmd TextYankPost * HighlightedYank()
Edit: Include window ID in matchdelete(), thanks to @bfrg !
Edit: Removed [0] from regtype, thanks to @zeertzjq
Edit: The highlightedyank plugin has an option to skip highlighting while yanking from visual mode. I've added the parameter in_visual to incorporate this:
def HighlightedYank(hlgroup = 'IncSearch', duration = 300, in_visual = true)
if v:event.operator ==? 'y'
if !in_visual && visualmode() != null_string
visualmode(1)
return
endif
var [beg, end] = [getpos("'["), getpos("']")]
var type = v:event.regtype ?? 'v'
var pos = getregionpos(beg, end, {type: type})
var end_offset = (type == 'V' || v:event.inclusive) ? 1 : 0
var m = matchaddpos(hlgroup, pos->mapnew((_, v) => {
var col_beg = v[0][2] + v[0][3]
var col_end = v[1][2] + v[1][3] + end_offset
return [v[0][1], col_beg, col_end - col_beg]
}))
var winid = win_getid()
timer_start(duration, (_) => m->matchdelete(winid))
endif
enddef
autocmd TextYankPost * HighlightedYank()
Reacted by Nick Jensen and Peter Benjamin Activitybfrg commented on May 25, 2024 You need to pass the window ID of the current window (the currently focused window when timer_start() is called) to matchdelete() since the user might have changed the focus to another window when matchdelete() is invoked. Otherwise matchdelete() will try to delete the highlighting in the wrong window. bfrg commented on May 25, 2024 And I don't quite understand how getregionpos() makes this simpler. It works perfectly fine with line() and col() using the '[ and '] marks. chrisbra commented on May 25, 2024 Thanks. Can some people try this out? I'd like to know how well this works. Perhaps we can add it to the help of vim9 script. Not sure it makes sense to include this as a plugin however. zeertzjq commented on May 25, 2024 type can now contain the width of a blockwise selection, so the [0] in regtype[0] can be removed. Specifying a width for a blockwise selection also seems the only way to indicate one that stops at end of line ($) when a line in the middle is longer than the lines at the start and the end.
zeertzjq commented on May 26, 2024 Also the value of end_offset seems wrong. The column values of end positions returned by getregionpos() is always inclusive, so end_offset should always be 1. girishji commented on May 26, 2024 ContributorAuthor More actions
type can now contain the width of a blockwise selection, so the [0] in regtype[0] can be removed. Specifying a width for a blockwise selection also seems the only way to indicate one that stops at end of line ($) when a line in the middle is longer than the lines at the start and the end.
If I remove [0], I get E475: Invalid value for argument type: ^V3 (3 is just width) when I do visual region select and yank (<c-v> to select region and y). This is on the main branch, coming from getregionpos(). zeertzjq commented on May 26, 2024 Does your Vim version contain patch 9.1.0443? girishji commented on May 26, 2024 ContributorAuthor More actions
Also the value of end_offset seems wrong. The column values of end positions returned by getregionpos() is always inclusive, so end_offset should always be 1.
Word movement w does not work with your suggestion. It includes 1 extra character to the right. You can try yw and verify. zeertzjq commented on May 26, 2024 Oops, sorry, I confused two different flags. girishji commented on May 26, 2024 ContributorAuthor More actions
Does your Vim version contain patch 9.1.0443?
My bad, removed [0]. lkintact commented on May 29, 2024 The line
autocmd TextYankPost * HighlightedYank()
should perhaps be replaced with
autocmd TextYankPost * call HighlightedYank().
Otherwise after sourcing the script and yanking Vim produces an error:
Error detected while processing TextYankPost Autocommands for "*":
E492: Not an editor command: HighlightedYank()
Vim 9.1.443. bfrg commented on May 29, 2024
The line
autocmd TextYankPost * HighlightedYank()
should perhaps be replaced with
autocmd TextYankPost * call HighlightedYank().
The first one is the vim9script version where call can be omitted. You need to add vim9script at the top of the file.
The autocmd should be put inside an augroup:
vim9script
augroup highlightedyank
autocmd!
autocmd TextYankPost * HighlightedYank()
augroup END
Or alternatively using the newer autocmd_add() function:
vim9script
autocmd_add([{
group: 'highlightedyank',
event: 'TextYankPost',
pattern: '*',
cmd: 'HighlightedYank()',
replace: true
}])Reacted by girish and Peter Benjamin lkintact commented on May 30, 2024 nickspoons commented on May 30, 2024
Thanks. Can some people try this out? I'd like to know how well this works.
I've been using this and it works great.
Perhaps we can add it to the help of vim9 script. Not sure it makes sense to include this as a plugin however.
I started using machakann/vim-highlightedyank a few months ago, thinking I'd try it for fun, and have really come to rely on it. It's a simple thing, but the quick visual guide to confirm that the yank you intended was successful is extremely useful. More importantly, I really notice if the yank doesn't highlight (because I fat-fingered the motion, for example), and that saves me time mucking around pasting the wrong thing.
So in my opinion a simple script like this would be a good addition as a built-in plugin. It adds nice usability value with a small amount of code, similar to the comment plugin that was added recently. Reacted by girish, dkearns, Peter Wu and Peter Benjamin added a commit that references this issue on May 31, 2024This issue will close once commit bad9577 is merged into the 'master' branch.bad9577
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|