liuchengxu/vim-which-key

define seperate which_key_map dictionaries for different modes

divramod opened this issue · 7 comments

Hey, thx for the awesome plugin!

i ask myself, if it is possible to define different seperate dictionaries for visual or insert mode.

Or will the mappings i do with for example:

let g:which_key_map.g = {
  \ 'name' : '+git',
  \ 'b' : [ ':Gblame'     ,'[git] blame' ],
  \ 'c' : [ ':Gcommit'    ,'[git] commit' ],
  \ 'd' : [ ':Gdiff'      ,'[git] diff' ],
  \ 'o' : [ ':Gbrowse'    ,'[git] browse' ],
  \ 'r' : [ ':Greview'    ,'[git] review'],
  \ 's' : [ ':Gstatus'    ,'[git] status' ],
  \ 'w' : [ ':Gwrite'     ,'[git] write' ],
  \ }

be the same in visual and normal mode?

so basically my question is, what could i do, when i have different mappings for the same leader key in different modes?

This is also an issue for me, I can think of defining the visual keys using vmap, and the plugin will recognize them, but then, how can I assign "friendly names" to them? 🤔

I was able to achieve it like so:

vnoremap <silent> <leader> :silent <C-u>WhichKeyVisual '<VisualBindings>'<CR>

let g:which_key_visual_map = { ...your mode special dict here... }

call which_key#register('<VisualBindings>', "g:which_key_visual_map ")

This creates separate dictionary "g:which_key_visual_map" register it in which_key_register and using vnoremap bind it to show up only in visual mode.

@BrotifyPacha This is really nice and I made use of this in nvim-whichkey-setup.lua. However I'm having some issues with the descriptive text. For example if do the following as a test:

:call which_key#register('<VisualBindings>', {"t": {"t": "test"}})

only the second letter of "test" is used, see below screenshot:

gscreenshot_2021-04-17-124406

Any idea what might be going wrong?

bew commented

Hello!
I'm using the same mapping as @BrotifyPacha I have the same issue as @AckslD, and in addition to that, my visual mappings do not work at all when triggered by the plugin (and I'm not sure how to debug that).

I'm wondering how it can even work, because the mapping <VisualBindings> does not actually exist, so when which_key tries to run the mapping it doesn't know that it has to type my leader key first, does it?
But then I tried to map <VisualBindings> to <leader> but it didn't work either. Any idea what I might be missing? or how is it supposed to work?
Thank you

@bew At least in nvim-whichkey-setup.lua the actual keybinding uses <Leader> and are not mapped using which-key but directly through the nvim-api. So in this case the mappings do work, it's just that the hint is wrong.

bew commented

My mappings are also defined using vim's mapping system, I'm using vim-which-key only for descriptions.
So for example:

let g:which_key_vmap = {}
call which_key#register('<VisualBindings>', "g:which_key_vmap ")
vnoremap <silent> <leader> <cmd>WhichKeyVisual '<VisualBindings>'<cr>

" and later...
vnoremap <leader>vx <cmd>echo "do something useful"<cr>
let g:which_key_vmap.v = {"name": "+some-group-name"}
let g:which_key_vmap.v.x = "some description"

In visual mode, typing <leader>v and wating for the which-key popup to show I see the same vision as you @AckslD, and then trying to type x: nothing happens.

I know the keybinding works though, because if I type in visual mode <leader>vx rapidly (so my timeoutlen does not trigger which-key), I see the echo "do something useful" working.

On reading the code, putting some thoughts here.

<VisualBindings> indeed doesn't appear to exist.

which_key.vim's s:cache will contain either 'n' or 'vx' mode native mappings depending on if WhichKey or WhichKeyVisual were called. Probably best to cache both modes.

I think the best way to change the code to support two dictionaries would be to index s:cache[key] and s:desc[key] with s:cache[mode][key] and s:desc[mode][key] instead.

And change the external API to which_key#register(prefix, dict, ...), where the third parameter "mode" is optional for backwards compatibility (or to intentionally maintain prior behaviour):

call which_key#register('<Space>', 'g:descN', 'n')
call which_key#register('<Space>', 'g:descV', 'v')
nnoremap <silent> <leader> :<c-u>WhichKey '<Space>'<CR>
vnoremap <silent> <leader> :<c-u>WhichKeyVisual '<Space>'<CR>