which-key.nvim
which-key.nvim copied to clipboard
bug: which-key does not show up in visual mode and prevents key mappings from working
Did you check docs and existing issues?
- [X] I have read all the which-key.nvim docs
- [X] I have searched the existing issues of which-key.nvim
- [X] I have searched the existing issues of plugins related to this issue
Neovim version (nvim -v)
v0.10.0-dev-273+gc8ebb04e9
Operating system/version
redhat
Describe the bug
I have a buffer mapping (for gitsigns), that is set like this:
vim.keymap.set( {'n', 'v'}, '<leader>hs', ':Gitsigns stage_hunk<CR>', { buffer = 123 } )
My leader key is the default \
. I can see the mapping as registered if I type :vmap
or map
, both for normal and visual modes. The mapping works as expected in normal mode.
However, if I try executing this mapping in visual mode, it does not work as expected. Upon closer inspection, it seems that when I type the leader key, neovim waits for futher input. I guess that after 'timeout' which-key is supposed to take over and display the hint window. It tries to take over, but nothing is displayed. However, neovim also stops waiting for furhter key presses, meaning that I am back to visual mode, unable to execute my keymaps.
So, unless I am really really fast, pressing <leader>hs
keymap results in:
<leader>
- very quickly gets discarded
h
- move left
s
- whatever s does by itself ...
Steps To Reproduce
- Enter visual mode
- Press the leader key
Expected Behavior
A which-key pop-up appears at the bottom with descriptions of which keys can be pressed now, etc...
Repro
-- Minimal config:
vim.o.timeoutlen = 300
require("which-key").setup {
-- your configuration comes here
-- or leave it empty to use the default settings
}
This is happening also to me with all visual commands
Same here
A weird work-around: running the command:
:WhichKey <leader> v
makes the visual mode leader-key sequences working, including showing of the which-key menu, although only for the current buffer.
Ok, I got the visual<leader>hs
to work, here's the bit of which-key config that enables the visual mode <leader>
keys to work properly:
require('which-key').register({
['<leader>'] = { name = 'VISUAL <leader>' },
['<leader>h'] = { 'Git [H]unk' },
}, { mode = "v", })
@SergioQuijanoRey , @j-xella can you check if the above snippet fixes your issue? This should probably be added to the README or integrated in the default config. This is the minimal required config to get visual leader work with which-key:
require('which-key').register({
['<leader>'] = { name = 'VISUAL <leader>' },
}, { mode = "v" })
The last example you provided does not fix my issue. So I will provide my workaround in case someone finds it useful. I have a lua/myconf/aux.lua
module where I define the following util functions:
-- Methods we are going to export
local M = {}
-- Libraries that we are going to use
local wk = require("which-key")
--- Function to set maps. This is handy because the api for this might change
--- (nvim is not quite stable yet), and thus we can have single change affect
--- all maps
---
--- NOTE: also useful because we are using third party libraries (whichkey) for
--- setting the keymaps, and this might change in the future
---
--- Example: `setmap("n", "<Tab>", ":echo hello", {noremap = True}, 'Just print hello world')`
function M.setmap(mode, keymap, command, opts, description)
-- NOTE -- whichkey does not work well in visual mode
-- -- see https://github.com/folke/which-key.nvim/issues/458
-- -- So in this case register this command also with stdlib map
if mode == "v" then
M.stdlib_map(mode, keymap, command, opts, description)
return
end
-- Sanitize input
description = description or ""
if opts == nil then
opts = {}
end
-- WhichKey puts the mode inside the opts table
local myopts = opts
myopts.mode = mode
-- Construct the whichkey mapping
local mapping = {
[keymap] = { command, description }
}
wk.register({ mapping, myopts })
end
--- Define a group name for a set of mappings using whichkey
function M.setmap_group_name(keymap, groupname)
wk.register({
[keymap] = { name = groupname }
})
end
--- VIM way of setting maps. This is used for cases where whichkey cannot set
--- properly some maps in `M.setmap`
--- NOTE: `description` is not used, so don't hesitate to put proper values there
function M.stdlib_map(mode, keymap, command, opts, description)
vim.api.nvim_set_keymap(mode, keymap, command, opts)
end
return M
With this, I can set keybindings and groups of keybindings like:
--- Avoid long lines for the set command
local setmap = require("myconf/aux").setmap
local setmap_group_name = require("myconf/aux").setmap_group_name
-- Whole block identation
setmap("v", "<", "<gv", { noremap = true }, "Ident block left")
setmap("v", ">", ">gv", { noremap = true }, "Ident block right")
-- File tree manipulation
setmap_group_name("<leader>o", "File tree management")
setmap("n", "<leader>oo", ":NvimTreeToggle<CR>", {}, "Nvim tree")
setmap("n", "<leader>oO", ":Oil<CR>", {}, "Nvim tree")
setmap("n", "<leader>-", ":Oil .<CR>", {}, "Nvim tree")
I did this in the first place because I didn't want to be dependent on whichkey
. For example, I wanted to be able to roll back to normal nvim maps anytime, or be able to make a quick change to another / newer plugin. But having this setup, I can easily "correct" the buggy behaviour. Hope it helps.
kinda fixed this by adding a visual mode mapping and a normal mode mappings: should probably add this info to the README
wk.register({
h = {
name = "Gitsigns",
j = { "<cmd>lua require('gitsigns').next_hunk()<cr>", "next Line", mode = { 'n' } },
k = { "<cmd>lua require('gitsigns').prev_hunk()<cr>", "prev Line", mode = { 'n' } },
s = { "<cmd>lua require('gitsigns').stage_hunk()<cr>", "Stage Hunk", mode = { 'n' } },
u = { "<cmd>lua require('gitsigns').undo_stage_hunk()<cr>", "Undo Stage Hunk", mode = { 'n' } },
},
}, { prefix = "<leader>" })
wk.register({
h = {
s = {function() gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end, "Stage Hunk visual mode", mode = { 'v' }},
u = {function() gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end, "reset hunk visual mode", mode = { 'v' }},
},
}, { prefix = "<leader>", mode = "v" })