Description
When using copilot.lua inline suggestions with:
accept = "<Tab>"
trigger_on_accept = false
I expect <Tab> to behave like a normal Tab key when no Copilot suggestion is visible.
However, in practice, when no suggestion is visible, <Tab> still does not reliably behave like native Tab input/indentation.
This does not reproduce with other accept keys such as <C-l>.
Minimal config
vim.o.expandtab = true
vim.pack.add({
{ src = "https://github.com/zbirenbaum/copilot.lua" },
})
require("copilot").setup({
suggestion = {
enabled = true,
auto_trigger = true,
hide_during_completion = true,
debounce = 75,
trigger_on_accept = false,
keymap = {
accept = "<Tab>",
accept_word = false,
accept_line = false,
next = false,
prev = false,
dismiss = "<C-]>",
toggle_auto_trigger = false,
},
},
panel = { enabled = false },
filetypes = {
["*"] = true,
},
})
Steps to reproduce
- Start Neovim with the minimal config
- Open a normal buffer
- Wait for Copilot suggestion to appear at least once
- Move to a place where no suggestion is visible
- Press
<Tab>
Expected behavior
When no suggestion is visible and trigger_on_accept = false, <Tab> should behave exactly like a normal Tab key.
Actual behavior
<Tab> is still intercepted by Copilot's accept mapping and does not reliably behave like native Tab input.
Additional observations
- Reproduces with
accept = "<Tab>"
- Does not reproduce with
accept = "<C-l>"
- Still reproduces after setting
expandtab = false, so it does not seem to be caused by expandtab
- This suggests the issue is specific to the
<Tab> key path, not the general accept/passthrough logic
Mapping info
:lua vim.print(vim.fn.maparg("<Tab>", "i", false, true)) shows:
{
abbr = 0,
buffer = 1,
callback = <function 1>,
desc = "[copilot] accept suggestion",
expr = 1,
lhs = "<Tab>",
lhsraw = "\t",
lnum = 0,
mode = "i",
mode_bits = 16,
noremap = 1,
nowait = 0,
replace_keycodes = 1,
script = 0,
scriptversion = 1,
sid = -8,
silent = 1
}
Notes
From testing, this looks like a <Tab>-specific passthrough issue rather than a general trigger_on_accept = false issue.
Workaround
As a workaround, I disabled Copilot's built-in <Tab> accept mapping and implemented a custom expr mapping instead:
require("copilot").setup({
suggestion = {
keymap = {
accept = false,
},
},
})
vim.keymap.set("i", "<Tab>", function()
if require("copilot.suggestion").is_visible() then
require("copilot.suggestion").accept()
return "<Ignore>"
end
return "<Tab>"
end, { expr = true, desc = "Copilot accept or tab" })
This works correctly:
- If a Copilot suggestion is visible,
<Tab> accepts it
- If no suggestion is visible,
<Tab> behaves like a normal Tab key
nvim version
NVIM v0.12.0-nightly+3a7ade8
Build type: Release
LuaJIT 2.1.1741730670
Description
When using
copilot.luainline suggestions with:accept = "<Tab>"trigger_on_accept = falseI expect
<Tab>to behave like a normal Tab key when no Copilot suggestion is visible.However, in practice, when no suggestion is visible,
<Tab>still does not reliably behave like native Tab input/indentation.This does not reproduce with other accept keys such as
<C-l>.Minimal config
Steps to reproduce
<Tab>Expected behavior
When no suggestion is visible and
trigger_on_accept = false,<Tab>should behave exactly like a normal Tab key.Actual behavior
<Tab>is still intercepted by Copilot's accept mapping and does not reliably behave like native Tab input.Additional observations
accept = "<Tab>"accept = "<C-l>"expandtab = false, so it does not seem to be caused byexpandtab<Tab>key path, not the general accept/passthrough logicMapping info
:lua vim.print(vim.fn.maparg("<Tab>", "i", false, true))shows:{ abbr = 0, buffer = 1, callback = <function 1>, desc = "[copilot] accept suggestion", expr = 1, lhs = "<Tab>", lhsraw = "\t", lnum = 0, mode = "i", mode_bits = 16, noremap = 1, nowait = 0, replace_keycodes = 1, script = 0, scriptversion = 1, sid = -8, silent = 1 }Notes
From testing, this looks like a
<Tab>-specific passthrough issue rather than a generaltrigger_on_accept = falseissue.Workaround
As a workaround, I disabled Copilot's built-in
<Tab>accept mapping and implemented a custom expr mapping instead:This works correctly:
<Tab>accepts it<Tab>behaves like a normal Tab keynvim version