GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — HighlightedYank feature · Issue #14848 · vim/vim

HighlightedYank feature #14848

New issue
Copy link
New issue
Copy link
Closed
Closed
HighlightedYank feature#14848
Copy link
Labels
enhancement

Description

@girishji
girishji
opened on May 25, 2024
Issue body actions

Now 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

Activity

  1. girishji
    added
    enhancement
    on May 25, 2024
  2. bfrg commented on May 25, 2024

    @bfrg
    bfrg
    on May 25, 2024
    Contributor
    More actions

    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.

    Reacted by girish
  3. bfrg commented on May 25, 2024

    @bfrg
    bfrg
    on May 25, 2024
    Contributor
    More actions

    And I don't quite understand how getregionpos() makes this simpler. It works perfectly fine with line() and col() using the '[ and '] marks.

  4. chrisbra commented on May 25, 2024

    @chrisbra
    chrisbra
    on May 25, 2024
    Member
    More actions

    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.

  5. zeertzjq commented on May 25, 2024

    @zeertzjq
    zeertzjq
    on May 25, 2024
    Member
    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.

    Reacted by girish
  6. zeertzjq commented on May 26, 2024

    @zeertzjq
    zeertzjq
    on May 26, 2024
    Member
    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.

  7. girishji commented on May 26, 2024

    @girishji
    girishji
    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().

  8. zeertzjq commented on May 26, 2024

    @zeertzjq
    zeertzjq
    on May 26, 2024
    Member
    More actions

    Does your Vim version contain patch 9.1.0443?

  9. girishji commented on May 26, 2024

    @girishji
    girishji
    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.

  10. zeertzjq commented on May 26, 2024

    @zeertzjq
    zeertzjq
    on May 26, 2024
    Member
    More actions

    Oops, sorry, I confused two different flags.

  11. girishji commented on May 26, 2024

    @girishji
    girishji
    on May 26, 2024
    ContributorAuthor
    More actions

    Does your Vim version contain patch 9.1.0443?

    My bad, removed [0].

  12. lkintact commented on May 29, 2024

    @lkintact
    lkintact
    on May 29, 2024
    More actions

    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.

  13. bfrg commented on May 29, 2024

    @bfrg
    bfrg
    on May 29, 2024
    Contributor
    More actions

    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
  14. lkintact commented on May 30, 2024

    @lkintact
    lkintact
    on May 30, 2024
    More actions

    @bfrg: I see, thank you!

  15. nickspoons commented on May 30, 2024

    @nickspoons
    nickspoons
    on May 30, 2024
    Contributor
    More actions

    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
  16. chrisbra
    closed this as completedin bad9577on May 31, 2024
  17. yegappan
    added a commit that references this issue on May 31, 2024

    runtime(doc): include some vim9 script examples in the help

    This issue will close once commit bad9577 is merged into the 'master' branch.
    bad9577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.