zbirenbaum / zbirenbaum/copilot.lua

Accepting suggestion with `<M-l>` ruins expanded snippet (LuaSnip)

Open
#315 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Lua
Stars
4.1k
Forks
161
Avg merge
11h 54m
Merged PRs (30d)
13

Description

Probably by disturbing/clobbering extmarks in the current line.

How I stumbled upon the bug

  1. Expand a LuSnip snippet that includes choices (i.e. includes a single choice node within, somewhere in the middle among a couple other nodes). For simplicity, just use a single-line snippet.
  2. <Esc> to normal mode, and then manually position the cursor at EOL (if it isn't already there).
  3. Accept copilot suggestion with <M-l> "accept" which extends the current line.
  4. Now, cycle snippet choices (e.g. via keymap). Instead of the choices cycling at the proper position within the line (as they would otherwise), the position will be all screwed up (e.g. always at the very begging of the current line).

I know that LuSnip uses extmarks to track the position of the expanded snippet, so I believe that the issue has something to do with this plugin (copilot.lua) disturbing those extmarks when inserting the suggestion text. I mean it could also be a LuaSnip issue (extmark config/gravity settings), but I think that this is less likely. Might need further investigation.

Idk how this plugin handles inserting the suggestion text, but if it always just replaces the entire line, then that would explain why the extmarks are getting ruined.

Example/Reproduction

-- You will need to have both luasnip and copilot.lua installed/setup, and the
-- latter should be active for this buffer (or on Lua buffers).
--
-- 1. Paste this into a new buffer.
-- 2. Run `:%lua` at the cmdline.
-- 3. Press `<Esc>` to exit select mode.
-- 4. Press `A` to enter insert mode at the EOL.
-- 5. Type a space and wait for copilot suggestion.
-- 6. Accept the suggestion (e.g. `<M-l>`).
-- 7. Cycle snippet choices with `<S-Tab>` and observe the bug.
--
-- To observe the correct behavior, repeat these steps but skip step 6.

local ls = require 'luasnip'
vim.bo.ft = 'lua'
vim.keymap.set(
  { 'n', 'i', 'v' },
  '<S-Tab>',
  function() ls.change_choice(1) end,
  { buffer = 0 }
)
vim.cmd [[normal! G2o]]

ls.snip_expand(ls.s({}, {
  ls.t '-- What does ',
  ls.c(1, { ls.i(1, '1 + 2'), ls.i(1, '2 + 3') }), -- Choice node
  ls.t ' equal? The answer is',
}))

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue using the supplied Lua snippet with copilot.lua and LuaSnip, then inspect copilot.lua's suggestion-insertion path and how it changes the current line. Compare extmark positions before and after accepting the suggestion, and verify that cycling the choice node remains at the correct position without breaking the reported reproduction.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua, neovim
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.