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

cmdline: `enter` keymap preset issues

Open b0o opened this issue 11 months ago • 9 comments

Make sure you have done the following

  • [X] I have updated to the latest version of blink.cmp
  • [X] I have read the README

Bug Description

When keymap is set to the enter preset, there are a few issues:

  • command abbreviations (cabbrev) are not expanded before the command is executed (E492: Not an editor command)
    • note: the first completion may be the expanded completion - to repro, don't accept that, dismiss the cmp popup and then try to accept the abbreviated command alone
  • if auto_insert is enabled, when picking a completion item, you need to press enter twice to run the command

Relevant configuration

{
  keymap = { preset = 'enter' },
  completion = {
    list = {
      selection = 'auto_insert',
    },
  },
}

neovim version

NVIM v0.11.0-dev-1273+g7a367c6967

blink.cmp version: branch, tag, or commit

fb03ca7dd41fc5c234bf5ec089568f4eae584efb

b0o avatar Dec 13 '24 19:12 b0o

The default preset for cmdline completions is now super-tab as mentioned in the README. You may want to add cmdline = { preset = 'enter' }} to your keymap table.

Edit: this is irrelavant pls ignore

voidstar-null avatar Dec 13 '24 20:12 voidstar-null

That's actually just an example, it'll use your keymap.preset by default

saghen avatar Dec 13 '24 20:12 saghen

if auto_insert is enabled, when picking a completion item, you need to press enter twice to run the command

It's a bit unintuitive but I think this behavior makes sense since it matches the behavior in default mode. Maybe you could unmap enter in cmdline mode to get the behavior you're looking for

keymap = {
  cmdline = {
    preset = 'enter',
    ['<CR>'] = {}
  }
}

saghen avatar Dec 13 '24 20:12 saghen

Thanks, that does work.

Perhaps there can be separate presets for cmdline with intuitive defaults. Then, doing keymap = { preset = 'enter' } would use the cmdline-specific preset for command mode. Though, in this case, I suppose "enter" isn't a great name, because it would exclude that particular keymap from the preset. Hmm..

On second thought, I think the most intuitive solution would be for the cmdline keymap configuration to not be nested inside of the standard keymaps, but to be in e.g. cmdline_keymap or cmdline.keymap. Then, I would expect changing the standard keymaps to not change the cmdline keymaps. This would make it more clear what mappings will be applied where.

b0o avatar Dec 13 '24 21:12 b0o

I think typically if you wanted to run the first option, you would press enter twice (first to accept, second to run). ~~You could make a keymap that selects, accepts and runs~~

keymap = {
  cmdline = {
    preset = 'enter',
    -- We don't return so that the fallback runs
    ['<CR>'] = { function(cmp) cmp.select_and_accept() end, 'fallback' }
  }
}

On second thought, I think the most intuitive solution would be for the cmdline keymap configuration to not be nested inside of the standard keymaps, but to be in e.g. cmdline_keymap or cmdline.keymap. Then, I would expect changing the standard keymaps to not change the cmdline keymaps. This would make it more clear what mappings will be applied where.

Totally agree! I'm thinking it would make sense to have a cmdline section that includes some of the settings from the main config (i.e. completion.list.selection, keymap, among others) for overriding settings in cmdline mode.

saghen avatar Dec 13 '24 21:12 saghen

command abbreviations (cabbrev) are not expanded before the command is executed (E492: Not an editor command)

This should be fixed on main after https://github.com/Saghen/blink.cmp/commit/89479f3f4c9096330a321a6cc438f5bc3f1e596b

saghen avatar Dec 13 '24 21:12 saghen

On the latest commit, you can do something like

['<CR>'] = {
  function(cmp)
    return cmp.select_and_accept({
      callback = function()
        vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<CR>', true, true, true), 'n', true)
      end,
    })
  end,
  'fallback',
}

saghen avatar Dec 13 '24 21:12 saghen

On the latest commit, you can do something like

Thanks, this works exactly how I want, as long as I set selection = 'manual'

I'm thinking it would make sense to have a cmdline section that includes some of the settings from the main config (i.e. completion.list.selection, keymap, among others) for overriding settings in cmdline mode.

This would be perfect!

b0o avatar Dec 13 '24 21:12 b0o

I'm thinking it would make sense to have a cmdline section that includes some of the settings from the main config (i.e. completion.list.selection, keymap, among others) for overriding settings in cmdline mode.

As a temporary workaround until this is implemented, in order to use completion.list.selection = "auto_insert" in insert mode and "manual" in command mode, I'm using CmdlineEnter/Leave autocommands to manipulate the list selection configuration setting:

local orig_list_selection
vim.api.nvim_create_autocmd('CmdlineEnter', {
  callback = function()
    local list = require 'blink.cmp.completion.list'
    orig_list_selection = list.config.selection
    list.config.selection = 'manual'
  end,
})
vim.api.nvim_create_autocmd('CmdlineLeave', {
  callback = function()
    if orig_list_selection then
      local list = require 'blink.cmp.completion.list'
      list.config.selection = orig_list_selection
    end
  end,
})

b0o avatar Dec 13 '24 22:12 b0o

In the spirit of sharing, following is my current workaround to have diff CR behavior in diff modes while setting completion.list = auto_insert. Didn't know that we can set cmdline separately within keymap (worthy putting into documentation?)

["<CR>"] = {
  function(cmp)
    if vim.api.nvim_get_mode().mode == "c" then
      return cmp.accept()
    else
      return cmp.select_and_accept()
    end
  end,
  "fallback",
},

echaya avatar Dec 24 '24 05:12 echaya

i believe this is already fixed by c1017f0a? https://cmp.saghen.dev/recipes.html#change-selection-type-per-mode

joshuali925 avatar Dec 24 '24 23:12 joshuali925

Not sure if this is relevant, but i have noticed that even with preset = "default" and

completion.list.selection = {
    preselect = true,
    auto_insert = true,

}

cmd enter doesn't select the completion item before accepting it if the plugin is not loaded. Example using lazy:

-- This will only load the plugin once the command TSPlaygroundToggle runs
return {
	{ "nvim-treesitter/playground", cmd = "TSPlaygroundToggle" },
}

Image

Image

FotiadisM avatar Jan 20 '25 19:01 FotiadisM

I believe this issue is resolved. I've tweaked my config and it's been working as desired for me now for several weeks.

b0o avatar Jan 22 '25 16:01 b0o