blink.cmp icon indicating copy to clipboard operation
blink.cmp copied to clipboard

refactor(keymap): improve fallback and key handling

Open soifou opened this issue 1 month ago • 5 comments

Things I want to test/fix:

  • [ ] Handle multi-key sequences Issue: #453
{
    ['jk'] = { 'hide', 'fallback' },
    ['<C-x><C-o>'] = { 'show', 'fallback' },
    ['<Leader>cc'] = { 'show', 'fallback' },
}
  • [ ] Preserve key special notation when fallback Issue: #2119
vim.keymap.set('i', '<C-i>', function() vim.print('fallback to <C-i>') end, { unique = false })
vim.keymap.set('i', '<Tab>', function() vim.print('fallback to <Tab>') end, { unique = false })
vim.keymap.set('i', '<C-m>', function() vim.print('fallback to <C-m>') end, { unique = false })

{       
    ['<C-i>'] = { 'accept', 'snippet_forward', 'fallback' }, -- when fall back prints "fallback to <C-i>"
    ['<C-m>'] = { 'accept', 'fallback' }, -- when fall back prints "fallback to <C-m>"
}
  • [ ] Key composition
{
    ['<C-n>'] = { 'select_next' },
    ['<Tab>'] = {
       function() return '' end, -- would fallback
       function() return '<C-n>' end, -- would call `select_next`
    },
},
  • [ ] Recursive keymap
vim.keymap.set('i', '<F2>', '<Esc>:echo "Hello from F2"<CR>a', { noremap = true, silent = true })
{
   ['<Space><Space>'] = { function() return '<F2>' end }, -- would print "Hello from F2"
}
  • [ ] Handle script mappings correctly: <SNR>, <SID>, <Plug> Issue: #714
vim.cmd([[
  function! s:MyFunction()
    echo "script local function invoked"
  endfunction

  nnoremap <silent> <SNR>42_mykey :call <SID>MyFunction()<CR>
  nnoremap <silent> <Plug>(MyPlug) :echo "Plug mapping triggered"<CR>
]])

{
    ['<Leader>m'] = { function() return '<Esc><Plug>(MyPlug)a' end }, -- prints "Plug mapping triggered"
}
  • [ ] Apply blink.cmp keymaps eagerly when triggering snippets from normal mode Issue: #2164
  • [ ] Reapply blink.cmp keymaps if stolen by others Issue: #406
  • [ ] Refactoring:
    • [ ] Consolidate and keep the keymap module as simply as possible
    • [ ] Don't rely anymore on expr,
    • [ ] Drop the vim.schedule in all commands and return boolean value from the function itself:
-  vim.schedule(function() completion_list.accept(opts) end)
-  return true
+  return completion_list.accept(opts)
  • [ ] Documentation: Revamp the keymap section Issue: #2182

soifou avatar Nov 21 '25 16:11 soifou

Long-standing issue fixed!

I was curious because I couldn't find any neovim issues about it, so I tinker a bit and found that we cannot rely on expr when using multi-key sequences. The fix is actually pretty simple and works reliably :smile:. If I have faith I'll rework a bit the keymap section in the documentation to include this in another PR.

soifou avatar Nov 21 '25 17:11 soifou

Does calling feedkeys have any caveats that we should be aware of? If not, I'd like to adopt it for all the keymaps! Avoiding expr = true would avoid having to vim.schedule anything that edits the buffer, which would be great for scriptability. I don't mind the way you're detecting multi-key mappings but it would be great if there was a less hacky way (maybe replace_keycodes could help?)

saghen avatar Nov 21 '25 19:11 saghen

Thanks for the feedback, you give me some additional thinking! I'd like to explore this approach a bit more. The feedkeys solution does seem cleaner and we could get rid of multi-key detection if we turn off expr.

Edit: Updated PR description

soifou avatar Nov 22 '25 18:11 soifou

Wow this is quite a bit of work, you'd end up fixing all the major issues with keymaps! These changes would be breaking, since theyre no longer vim.schedule so it might make sense to artificially vim.schedule or merge this into a new v2 branch.

Fyi, I got a bit ambitious with v2 so I'm going to reduce its scope. Just planning some light refactoring, these keymap changes, source-per-LSP, adopt blink.lib, and the improved API (for keymaps, enable, vim.g, dynamic config, etc)

saghen avatar Nov 25 '25 21:11 saghen

Yeah, as long as I'm here, I might as well fix these issues once and for all. I've had promising results locally. I don't mind working on this for v2, but last time I switched to this branch, everything was so broken that it was hard to make any convincing commits. Feel free to keep in touch on Matrix to coordinate!

soifou avatar Nov 25 '25 22:11 soifou