folke / which-key.nvim

💥 Create key bindings that stick. WhichKey helps you remember your Neovim keymaps, by showing available keybindings in a popup as you type.
Apache License 2.0
5.36k stars 175 forks source link

bug: user keymaps get double recorded in macros #822

Closed Serega124 closed 1 month ago

Serega124 commented 2 months ago

Did you check docs and existing issues?

Neovim version (nvim -v)

0.10.1

Operating system/version

Windows 10 (10.0.19045.4651)

Describe the bug

When recording a macro using user key mappings the recorded keys are inserted twice in the register, and are also played back twice. This occurs with which-key enabled in the minimal repro.lua. Using the same repro without which-key enabled, or nvim --clean, the issue does not occur.

Similar issue: #702 which-key v3.13.2

Steps To Reproduce

  1. In any buffer enter several lines of text
  2. Position the cursor on the first line
  3. Start recording a macro with qq
  4. Execute user keymap from repro.lua: <Space>t
  5. End recording with q
  6. Check :registers command - "q register will contain t t instead of t
  7. Repeat last recorded register on another line with Q - user keymap will be executed twice

test

Expected Behavior

Not to double record user keystrokes to macros

Health

==============================================================================
which-key: require("which-key.health").check()

- OK Most of these checks are for informational purposes only.
  WARNINGS should be treated as a warning, and don't necessarily indicate a problem with your config.
  Please |DON't| report these warnings as an issue.

Checking your config ~
- WARNING |mini.icons| is not installed
- OK |nvim-web-devicons| is installed

Checking for issues with your mappings ~
- OK No issues reported

checking for overlapping keymaps ~
- WARNING In mode `n`, <gc> overlaps with <gcc>:
  - <gc>: Toggle comment
  - <gcc>: Toggle comment line
- OK Overlapping keymaps are only reported for informational purposes.
  This doesn't necessarily mean there is a problem with your config.

Checking for duplicate mappings ~
- OK No duplicate mappings found

Log

Trigger(add) Mode(n:1) " ' ` g' g` z= g z <C-W> [ <Space> ]
RecordingEnter
Trigger(del) Mode(n:1) ' ` g' g` z= g z <C-W> [ " ] <Space>
Trigger(del) Mode(c:1) <C-R>
Trigger(del) Mode(i:1) <C-R>
new Mode(n:1)
Trigger(add) Mode(n:1) " ' ` g' g` z= g z <C-W> [ <Space> ]
State(start): Mode(n:0) Node(<Space>) { keys = "<Space>" }
  update Mode(n:1)
  continue: <Space> Mode(n:1)
  getchar
  got: t
  suspend: Mode(n:1)
  Trigger(del) Mode(n:1) ' ` g' g` z= g z <C-W> [ " ] <Space>
  feedkeys: Mode(n:1) <Space>t
ModeChanged(n:i)
  new Mode(i:1)
  Unsafe(recording)
  suspend: Mode(i:1)
ModeChanged(i:n)
  cooldown
Trigger(add) Mode(i:1) <C-R>
Trigger(add) Mode(n:1) " ' ` g' g` z= g z <C-W> [ <Space> ]
RecordingLeave
ModeChanged(n:i)
  Unsafe(executing)
  suspend: Mode(i:1)
  Trigger(del) Mode(i:1) <C-R>
ModeChanged(i:n)
  cooldown
ModeChanged(n:i)
  cooldown
ModeChanged(i:n)
  cooldown
Trigger(add) Mode(i:1) <C-R>
ModeChanged(n:c)
  new Mode(c:1)
  Safe(true)
Trigger(add) Mode(c:1) <C-R>
ModeChanged(c:n)
  Unsafe(command-mode)
  suspend: Mode(n:1)
  Trigger(del) Mode(n:1) ' ` g' g` z= g z <C-W> [ " ] <Space>
Trigger(add) Mode(n:1) " ' ` g' g` z= g z <C-W> [ <Space> ]

Repro

vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()

require("lazy.minit").repro({
  spec = {
    { "folke/which-key.nvim", opts = {} },
    -- add any other plugins here
  },
})
vim.cmd.language('en')
vim.g.mapleader = ' '
vim.keymap.set('n', '<Leader>t', '0i1<Esc>')
hesxenon commented 2 months ago

seems to be the source for https://github.com/LazyVim/LazyVim/issues/4286

tmillr commented 2 months ago

This might be the same issue as #807

mihaifm commented 1 month ago

This replicates for some built-in mappings as well, for example ge

MTHLily commented 1 month ago

The bug was introduced on commit 96b2e9397937.

A hack for this would be to modify the following snippet on lua/which-key/buf.lua:69 to fix the double recordings issue, however this will prevent which-key from showing up when recording macros.

-  if Config.triggers.modes[self.mode] then
+  if Config.triggers.modes[self.mode] and vim.fn.reg_recording() == "" then
     -- Auto triggers
     self.tree:walk(function(node)
       if is_safe(node, true) then
         table.insert(self.triggers, node)
         return false
       end
     end)
   end
mehalter commented 1 month ago

I can confirm this using only bindings as well.

repro.lua:

vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()

require("lazy.minit").repro({
    spec = {
        { "folke/which-key.nvim", opts = {} },
        -- add any other plugins here
    },
})

Steps:

  1. nvim -u repro.lua - open Neovim
  2. qqgUlq - record a simple macro to the q register
  3. :reg q - see gUgUl is in the register
skrobul commented 1 month ago

not fixed, still experiencing https://github.com/folke/flash.nvim/issues/366 after upgrading which-key to fb07034/3.13.3, with slightly different output