diff --git a/lua/copilot-lsp/nes/init.lua b/lua/copilot-lsp/nes/init.lua index 186941c..f182558 100644 --- a/lua/copilot-lsp/nes/init.lua +++ b/lua/copilot-lsp/nes/init.lua @@ -52,7 +52,24 @@ function M.walk_cursor_start_edit(bufnr) return false end + local total_lines = vim.api.nvim_buf_line_count(bufnr) local cursor_row, _ = unpack(vim.api.nvim_win_get_cursor(0)) + if state.range.start.line >= total_lines then + -- If the start line is beyond the end of the buffer then we can't walk there + -- if we are at the end of the buffer, we've walked as we can + if cursor_row == total_lines then + return false + end + -- if not, walk to the end of the buffer instead + vim.lsp.util.show_document({ + uri = state.textDocument.uri, + range = { + start = { line = total_lines - 1, character = 0 }, + ["end"] = { line = total_lines - 1, character = 0 }, + }, + }, "utf-16", { focus = true }) + return true + end if cursor_row - 1 ~= state.range.start.line then vim.b[bufnr].nes_jump = true -- Since we are async, we check to see if the buffer has changed diff --git a/lua/copilot-lsp/nes/ui.lua b/lua/copilot-lsp/nes/ui.lua index 87b9a21..75da322 100644 --- a/lua/copilot-lsp/nes/ui.lua +++ b/lua/copilot-lsp/nes/ui.lua @@ -82,6 +82,15 @@ function M._calculate_preview(bufnr, edit) end if is_insertion and num_new_lines > 1 then + if num_old_lines == 0 then + return { + lines_insertion = { + text = text, + line = start_line, + }, + } + end + if start_char == #old_lines[1] and new_lines[1] == "" then -- insert lines after the start line return { @@ -133,10 +142,12 @@ end function M._display_preview(bufnr, ns_id, preview) if preview.deletion then local range = preview.deletion.range + local existing_line = vim.api.nvim_buf_get_lines(bufnr, range["end"].line, range["end"].line + 1, false)[1] + or "" vim.api.nvim_buf_set_extmark(bufnr, ns_id, range.start.line, range.start.character, { hl_group = "CopilotLspNesDelete", end_row = range["end"].line, - end_col = range["end"].character, + end_col = math.min(range["end"].character, #existing_line), }) end @@ -154,9 +165,14 @@ function M._display_preview(bufnr, ns_id, preview) if lines_insertion then local virt_lines = require("copilot-lsp.util").hl_text_to_virt_lines(lines_insertion.text, vim.bo[bufnr].filetype) + local total_lines = vim.api.nvim_buf_line_count(bufnr) + if lines_insertion.line >= total_lines then + lines_insertion.line = math.max(total_lines - 1, 0) + end vim.api.nvim_buf_set_extmark(bufnr, ns_id, lines_insertion.line, 0, { virt_lines = virt_lines, virt_lines_above = lines_insertion.above, + strict = false, }) end end diff --git a/tests/nes/test_ui_preview.lua b/tests/nes/test_ui_preview.lua index 7428b16..95f1f82 100644 --- a/tests/nes/test_ui_preview.lua +++ b/tests/nes/test_ui_preview.lua @@ -221,6 +221,29 @@ local cases = { }, final = "hijklmn", }, + ["insertion only passed buffer end"] = { + content = "function greetName(name: string) : string {", + edit = { + range = { + start = { + line = 2, + character = 0, + }, + ["end"] = { + line = 2, + character = 0, + }, + }, + newText = "\treturn `Hello, ${name}!`;\n}\n", + }, + preview = { + lines_insertion = { + line = 2, + text = "\treturn `Hello, ${name}!`;\n}\n", + }, + }, + final = "function greetName(name: string) : string {\n\treturn `Hello, ${name}!`;\n}\n", + }, } local function set_content(content) @@ -354,4 +377,40 @@ T["ui_preview"]["suggestion_preserves_on_movement_towards"] = function() ref(child.get_screenshot()) end +T["ui_preview"]["deletions before response"] = function() + set_content("loooooooooooooooong") + ref(child.get_screenshot()) + + -- Position cursor at end of line 0 + child.cmd("normal! gg$") + + -- Create a suggestion at line 0 + local edit = { + range = { + start = { line = 0, character = 0 }, + ["end"] = { line = 0, character = 19 }, + }, + newText = "long", + } + + child.cmd("normal! xxxxxxxxxxxxx") -- Delete text + + -- Display suggestion + child.g.inline_edit = edit + child.lua_func(function() + local ns_id = vim.api.nvim_create_namespace("nes_test") + local edits = { vim.g.inline_edit } + require("copilot-lsp.nes.ui")._display_next_suggestion(0, ns_id, edits) + end) + ref(child.get_screenshot()) + + child.lua_func(function() + local bufnr = vim.api.nvim_get_current_buf() + vim.lsp.util.apply_text_edits({ vim.g.inline_edit }, bufnr, "utf-16") + end) + + local final = get_content() + eq(final, edit.newText) +end + return T diff --git a/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---deletions-before-response b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---deletions-before-response new file mode 100644 index 0000000..5bd522a --- /dev/null +++ b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---deletions-before-response @@ -0,0 +1,51 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|loooooooooooooooong +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|~ +16|~ +17|~ +18|~ +19|~ +20|~ +21|~ +22|~ +23|[No Name] [+] 1,1 All +24| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +03|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +05|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +06|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +07|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +08|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +09|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +10|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +11|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +12|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +13|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +14|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +15|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +16|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +17|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +18|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +19|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +20|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +21|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +22|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +23|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +24|33333333333333333333333333333333333333333333333333333333333333333333333333333333 diff --git a/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---deletions-before-response-002 b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---deletions-before-response-002 new file mode 100644 index 0000000..42fcd03 --- /dev/null +++ b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---deletions-before-response-002 @@ -0,0 +1,51 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|looooo +02|long +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|~ +16|~ +17|~ +18|~ +19|~ +20|~ +21|~ +22|~ +23|[No Name] [+] 1,6 All +24| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000011111111111111111111111111111111111111111111111111111111111111111111111111 +02|22221111111111111111111111111111111111111111111111111111111111111111111111111111 +03|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +04|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +05|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +06|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +07|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +08|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +09|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +10|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +11|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +12|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +13|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +14|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +15|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +16|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +17|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +18|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +19|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +20|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +21|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +22|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +23|44444444444444444444444444444444444444444444444444444444444444444444444444444444 +24|55555555555555555555555555555555555555555555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---insertion-only-passed-buffer-end b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---insertion-only-passed-buffer-end new file mode 100644 index 0000000..6a83b26 --- /dev/null +++ b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---insertion-only-passed-buffer-end @@ -0,0 +1,51 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|function greetName(name: string) : string { +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|~ +16|~ +17|~ +18|~ +19|~ +20|~ +21|~ +22|~ +23|[No Name] [+] 1,1 All +24| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +03|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +05|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +06|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +07|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +08|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +09|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +10|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +11|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +12|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +13|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +14|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +15|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +16|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +17|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +18|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +19|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +20|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +21|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +22|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +23|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +24|33333333333333333333333333333333333333333333333333333333333333333333333333333333 diff --git a/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---insertion-only-passed-buffer-end-002 b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---insertion-only-passed-buffer-end-002 new file mode 100644 index 0000000..cf9886d --- /dev/null +++ b/tests/screenshots/tests-nes-test_ui_preview.lua---ui_preview---insertion-only-passed-buffer-end-002 @@ -0,0 +1,51 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|function greetName(name: string) : string { +02| return `Hello, ${name}!`; +03|} +04| +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|~ +16|~ +17|~ +18|~ +19|~ +20|~ +21|~ +22|~ +23|[No Name] [+] 1,1 All +24| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|11111111111111111111111111111111100000000000000000000000000000000000000000000000 +03|10000000000000000000000000000000000000000000000000000000000000000000000000000000 +04|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +05|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +06|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +07|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +08|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +09|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +10|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +11|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +12|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +13|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +14|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +15|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +16|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +17|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +18|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +19|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +20|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +21|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +22|22222222222222222222222222222222222222222222222222222222222222222222222222222222 +23|33333333333333333333333333333333333333333333333333333333333333333333333333333333 +24|44444444444444444444444444444444444444444444444444444444444444444444444444444444