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.12k stars 163 forks source link

bug: which-key triggers not working with some keys. #751

Closed hoofcushion closed 1 month ago

hoofcushion commented 1 month ago

Did you check docs and existing issues?

Neovim version (nvim -v)

NVIM v0.10.0 Build type: Release LuaJIT 2.1.1713484068

Operating system/version

Arch Linux x86_64 Linux 6.9.7-zen1-1-zen

Describe the bug

Which key does not automatically set up triggers for all keymap that starts with a-z (except z or g).

Steps To Reproduce

local lazypath=vim.fn.stdpath("data").."/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
 local lazyrepo="https://github.com/folke/lazy.nvim.git"
 local out=vim.fn.system({"git","clone","--filter=blob:none","--branch=stable",lazyrepo,lazypath})
 if vim.v.shell_error~=0 then
  vim.api.nvim_echo(
   {
    {"Failed to clone lazy.nvim:\n","ErrorMsg"},
    {out,                           "WarningMsg"},
    {"\nPress any key to exit..."},
   },
   true,
   {}
  )
  vim.fn.getchar()
  os.exit(1)
 end
end
vim.opt.rtp:prepend(lazypath)
--- Create all keys like aa bb cc... and also <space>aa <space>bb <space>cc
for i=("a"):byte(),("z"):byte() do
 local lhs=string.char(i):rep(2)
 vim.keymap.set("n",lhs,"rhs",{desc="desc"})
 vim.keymap.set("n"," "..lhs,"rhs",{desc="desc"})
end
require("lazy").setup({
 {
  "folke/which-key.nvim",
  lazy=false,
 },
})

Use this configuration file, and try press a-z, only g and z can trigger which key.

Expected Behavior

For all key maps, setup triggers for them automatically, just like the old version. (version 1.0)

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
- WARNING |nvim-web-devicons| is not installed
- WARNING Keymap icon support will be limited.

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

No response

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
  },
})
hoofcushion commented 1 month ago

the log file:

Debug Started for v3.7.0
new Mode(n:1)
Trigger(add) Mode(n:1) ' " ` z= g` g' <Space> ] [ <C-W> z g
on_key: <Space>
State(start): Mode(n:0) Node(<Space>) { keys = "<Space>", waited = 0 }
  update Mode(n:1)
  continue: <Space> Mode(n:1)
  getchar
  on_key: <Esc>
  got: <Esc>
on_key: a
ModeChanged(n:i)
  new Mode(i:1)
  Safe(true)
Trigger(add) Mode(i:1) <C-R>
on_key: <Esc>
ModeChanged(i:n)
  Safe(true)
on_key: b
on_key: <Esc>
on_key: c
ModeChanged(n:no)
  new Mode(o:1)
  Unsafe(pending "^[")
  suspend: Mode(o:1)
on_key: <Esc>
ModeChanged(no:n)
  cooldown
Trigger(add) Mode(o:1) g ] [
on_key: d
ModeChanged(n:no)
  Unsafe(pending "^[")
  suspend: Mode(o:1)
  Trigger(del) Mode(o:1) [ ] g
on_key: <Esc>
ModeChanged(no:n)
  cooldown
Trigger(add) Mode(o:1) g ] [
on_key: e
on_key: <Esc>
on_key: f
on_key: <Esc>
on_key: g
State(start): Mode(n:0) Node(g) { keys = "g", waited = 0 }
  update Mode(n:1)
  continue: g Mode(n:1)
  getchar
  on_key: <Esc>
  got: <Esc>
on_key: h
on_key: <Esc>
on_key: i
ModeChanged(n:i)
  Unsafe(pending "^[")
  suspend: Mode(i:1)
  Trigger(del) Mode(i:1) <C-R>
on_key: <Esc>
ModeChanged(i:n)
  cooldown
Trigger(add) Mode(i:1) <C-R>
on_key: j
on_key: <Esc>
on_key: k
on_key: <Esc>
on_key: l
on_key: <Esc>
on_key: m
on_key: <Esc>
on_key: n
on_key: <Esc>
on_key: o
ModeChanged(n:i)
  Unsafe(pending "^[")
  suspend: Mode(i:1)
  Trigger(del) Mode(i:1) <C-R>
on_key: <Esc>
ModeChanged(i:n)
  cooldown
Trigger(add) Mode(i:1) <C-R>
on_key: p
on_key: <Esc>
on_key: q
on_key: <Esc>
on_key: r
on_key: <Esc>
on_key: s
ModeChanged(n:no)
  Unsafe(pending "l")
  suspend: Mode(o:1)
  Trigger(del) Mode(o:1) [ ] g
ModeChanged(no:i)
  cooldown
on_key: <Esc>
ModeChanged(i:n)
  cooldown
Trigger(add) Mode(o:1) g ] [
on_key: t
on_key: <Esc>
on_key: u
on_key: <Esc>
on_key: v
ModeChanged(n:v)
  new Mode(x:1)
  Unsafe(pending "^[")
  suspend: Mode(x:1)
on_key: <Esc>
ModeChanged(v:n)
  cooldown
Trigger(add) Mode(x:1) " ] [ <C-W> g z
on_key: w
on_key: <Esc>
on_key: x
ModeChanged(n:no)
  Unsafe(pending "l")
  suspend: Mode(o:1)
  Trigger(del) Mode(o:1) g ] [
ModeChanged(no:n)
  cooldown
on_key: <Esc>
Trigger(add) Mode(o:1) g ] [
on_key: y
ModeChanged(n:no)
  Unsafe(pending "^[")
  suspend: Mode(o:1)
  Trigger(del) Mode(o:1) g ] [
on_key: <Esc>
ModeChanged(no:n)
  cooldown
Trigger(add) Mode(o:1) g ] [
on_key: z
State(start): Mode(n:0) Node(z) { keys = "z", waited = 0 }
  update Mode(n:1)
  continue: z Mode(n:1)
  getchar
  on_key: <Esc>
  got: <Esc>
on_key: :
ModeChanged(n:c)
  new Mode(c:1)
  Safe(true)
Trigger(add) Mode(c:1) <C-R>
on_key: q
on_key: a
on_key: <CR>
ModeChanged(c:n)
  Unsafe(command-mode)
  suspend: Mode(n:1)
  Trigger(del) Mode(n:1) g ' " ` z= g` g' <Space> ] [ <C-W> z
on_key: <CR>
Trigger(add) Mode(n:1) ' " ` z= g` g' <Space> ] [ <C-W> z g
on_key: ;
on_key: :
ModeChanged(n:c)
  Safe(true)
on_key: q
on_key: a
on_key: !
on_key: <CR>
ModeChanged(c:n)
  Unsafe(command-mode)
  suspend: Mode(n:1)
  Trigger(del) Mode(n:1) g ' " ` z= g` g' <Space> ] [ <C-W> z
Trigger(add) Mode(n:1) ' " ` z= g` g' <Space> ] [ <C-W> z g
folke commented 1 month ago

That's on purpose, since the only single letter keys that are not a valid Neovim keymap are g and z.

However, I just reworked the whole which-key configuration and you can now trigger on additional keys when needed.

See https://github.com/folke/which-key.nvim?tab=readme-ov-file#-triggers

hoofcushion commented 1 month ago

Thanks for your works.

And I had another question, Can there be an option to use the v1 style auto triggers?

There are plugins that use the a-z as the initial key, and now the Which-Key doesn't work well with them.

Now to do that, I use the whole ASCII table from space to ~, that seems to work like the old version. Does it have to be the way?

local opts={
 triggers=(function()
  local ret={{"<auto>",mode="nixsotc"}}
  for i=32,126 do
   table.insert(ret,{string.char(i),mode="nixsotc"})
  end
  return ret
 end)(),
}
require("which-key").setup(opts)
folke commented 1 month ago

That would prevent builtin mappings from working, so I really wouldn't do that. Just add the letters manually that you need. There's probably only a few.

hoofcushion commented 1 month ago

Okay, thanks.