4

Are there any events similar to InsertEnter and InsertLeave that I could use for visual mode?

Looking through the helpfiles, I did not fine any.

If not, how would I be able to detect if Vim enters or leaves Visual mode?

2
  • 1
    Maybe duplicate of stackoverflow.com/q/15561132/11135136.
    – 3N4N
    Commented Sep 18, 2022 at 11:07
  • I think your suggested question is not a duplicate. The question is related but the implementations are not what I am looking for.
    – unrealapex
    Commented Sep 19, 2022 at 0:00

2 Answers 2

10

September of last year, a new event was added:

commit f1e8876fa2359b572d262772747405d3616db670 (tag: v8.2.3430)
Author: =?UTF-8?q?Magnus=20Gro=C3=9F?= <[email protected]>
Date:   2021-09-12

    patch 8.2.3430: no generic way to trigger an autocommand on mode change

    Problem:    No generic way to trigger an autocommand on mode change.
    Solution:   Add the ModeChanged autocommand event. (Magnus Gross, closes #8856)

From :h ModeChanged:

ModeChanged         After changing the mode. The pattern is
                    matched against `'old_mode:new_mode'`, for
                    example match against `*:c*` to simulate
                    |CmdlineEnter|.
                    The following values of |v:event| are set:
                            old_mode    The mode before it changed.
                            new_mode    The new mode as also returned
                                        by |mode()| called with a
                                        non-zero argument.

So you can use the following event pattern:

augroup VisualEvent
  autocmd!
  autocmd ModeChanged *:[vV\x16]* :echom 'VisualEnter'
  autocmd Modechanged [vV\x16]*:* :echom 'VisualLeave'
augroup END

[vV\x16] is a regex pattern matching either of v (visual mode), V (line-wise), or ctrl-v (block-wise).


Answer found courtesy of clason.

11
  • 1
    @UnrealApex detects with <ESC> for me. Maybe not using bang is causing problem. I edited the answer to incorporate augroup. Try that. After entering and leaving visual mode, you should invoke :messages to see the messages left with echom.
    – 3N4N
    Commented Sep 19, 2022 at 8:40
  • 1
    @UnrealApex interesting! <C-c> doesn't trigger ModeChanged event. (It wasn't silly. I didn't know about <C-c> not triggering InsertLeave. Your objection made me aware of it.)
    – 3N4N
    Commented Sep 19, 2022 at 17:14
  • 1
    If you find a reason why <C-c> doesn't trigger these events, share here. Or edit my answer with a note.
    – 3N4N
    Commented Sep 19, 2022 at 17:15
  • 2
    @UnrealApex, kadekai: <C-c> not triggering ModeChanged was a bug. I finally got around to reporting it weeks after reading your discussion, and Bram fixed it within hours!
    – Rich
    Commented Oct 18, 2022 at 15:11
  • 1
    @UnrealApex zeertzjq is on it. He is a core nvim dev, so patch should be ported quickly.
    – 3N4N
    Commented Oct 18, 2022 at 18:24
0

I went ahead and rewrote 3N4N's answer in Lua in case some Neovim users would like to take advantage of this:

local visual_event_group =
  vim.api.nvim_create_augroup("visual_event", { clear = true })

vim.api.nvim_create_autocmd("ModeChanged", {
  group = visual_event_group,
  pattern = { "*:[vV\x16]*" },
  callback = function()
    print("VisualEnter")
  end,
})

vim.api.nvim_create_autocmd("ModeChanged", {
  group = visual_event_group,
  pattern = { "[vV\x16]*:*" },
  callback = function()
    print("VisualLeave")
  end,
})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.