From c9ff80c5d6c95e7d9f29b17dfa2fbd207c42e324 Mon Sep 17 00:00:00 2001 From: 03kev Date: Fri, 10 Apr 2026 11:51:01 +0200 Subject: [PATCH 1/2] fix: suggestion acceptance now follows text wrapping --- lua/copilot/suggestion/init.lua | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/lua/copilot/suggestion/init.lua b/lua/copilot/suggestion/init.lua index a11c824b..4f584c94 100644 --- a/lua/copilot/suggestion/init.lua +++ b/lua/copilot/suggestion/init.lua @@ -595,6 +595,52 @@ function M.prev() end, ctx) end +local function feedkeys(keys, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), mode or "i", true) +end + +local function longest_prefix_suffix_overlap(left_text, new_text) + local max = math.min(#left_text, #new_text) + for k = max, 1, -1 do + if left_text:sub(-k) == new_text:sub(1, k) then + return k + end + end + return 0 +end + +local function accept_in_insert_mode(new_text, range) + local cursor = vim.api.nvim_win_get_cursor(0) + local line = cursor[1] - 1 + local col = cursor[2] + + local current_line = vim.api.nvim_get_current_line() + local left_text = current_line:sub(1, col) + + -- Rimuovi da new_text l'eventuale prefisso già scritto dall'utente + local overlap = longest_prefix_suffix_overlap(left_text, new_text) + if overlap > 0 then + new_text = new_text:sub(overlap + 1) + end + + local right_delete_count = 0 + if range["end"].line == line and range["end"].character > col then + right_delete_count = range["end"].character - col + end + + vim.g.__copilot_accept_text = new_text + + local recall + if new_text:find("\n", 1, true) then + recall = "=g:__copilot_accept_text" + else + recall = "=g:__copilot_accept_text" + end + + local keys = string.rep("", right_delete_count) .. recall .. "" + feedkeys(keys, "i") +end + ---@param modifier? (fun(suggestion: copilot_get_completions_data_completion): copilot_get_completions_data_completion) function M.accept(modifier) local ctx = get_ctx() @@ -677,11 +723,12 @@ function M.accept(modifier) newText = newText .. "\n" end - vim.lsp.util.apply_text_edits({ { range = range, newText = newText } }, bufnr, encoding) + -- vim.lsp.util.apply_text_edits({ { range = range, newText = newText } }, bufnr, encoding) + accept_in_insert_mode(newText, range) -- Position cursor at the end of the last inserted line local new_cursor_line = range["start"].line + #lines - vim.api.nvim_win_set_cursor(0, { new_cursor_line, last_col }) + -- vim.api.nvim_win_set_cursor(0, { new_cursor_line, last_col }) if accepted_partial then suggestion.partial_text = nil From 2dfe556bce406e719a52f4ded219754c7b28e7b1 Mon Sep 17 00:00:00 2001 From: 03kev Date: Sun, 12 Apr 2026 22:46:36 +0200 Subject: [PATCH 2/2] fix: accept suggestion with wrapping now uses get_display_adjustments --- lua/copilot/suggestion/init.lua | 47 ++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/lua/copilot/suggestion/init.lua b/lua/copilot/suggestion/init.lua index 4f584c94..1d3103c1 100644 --- a/lua/copilot/suggestion/init.lua +++ b/lua/copilot/suggestion/init.lua @@ -596,36 +596,36 @@ function M.prev() end local function feedkeys(keys, mode) - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), mode or "i", true) -end - -local function longest_prefix_suffix_overlap(left_text, new_text) - local max = math.min(#left_text, #new_text) - for k = max, 1, -1 do - if left_text:sub(-k) == new_text:sub(1, k) then - return k - end - end - return 0 + vim.api.nvim_feedkeys( + vim.api.nvim_replace_termcodes(keys, true, false, true), + mode or "i", + true + ) end local function accept_in_insert_mode(new_text, range) local cursor = vim.api.nvim_win_get_cursor(0) local line = cursor[1] - 1 - local col = cursor[2] + local col0 = cursor[2] + local col1 = vim.fn.col(".") local current_line = vim.api.nvim_get_current_line() - local left_text = current_line:sub(1, col) + local lines = vim.split(new_text, "\n", { plain = true }) + + local first_line = lines[1] or "" + local adjusted_first_line, outdent = suggestion_util.get_display_adjustments( + first_line, + range.start.character, + col1, + current_line + ) - -- Rimuovi da new_text l'eventuale prefisso già scritto dall'utente - local overlap = longest_prefix_suffix_overlap(left_text, new_text) - if overlap > 0 then - new_text = new_text:sub(overlap + 1) - end + lines[1] = adjusted_first_line + new_text = table.concat(lines, "\n") local right_delete_count = 0 - if range["end"].line == line and range["end"].character > col then - right_delete_count = range["end"].character - col + if range["end"].line == line and range["end"].character > col0 then + right_delete_count = range["end"].character - col0 end vim.g.__copilot_accept_text = new_text @@ -637,7 +637,12 @@ local function accept_in_insert_mode(new_text, range) recall = "=g:__copilot_accept_text" end - local keys = string.rep("", right_delete_count) .. recall .. "" + local keys = + string.rep("", outdent) + .. string.rep("", right_delete_count) + .. recall + .. "" + feedkeys(keys, "i") end