Skip to content

accept = "<Tab>" does not reliably pass through when trigger_on_accept = false #670

@A-mess

Description

@A-mess

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

  1. Start Neovim with the minimal config
  2. Open a normal buffer
  3. Wait for Copilot suggestion to appear at least once
  4. Move to a place where no suggestion is visible
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions