debug completion

This commit is contained in:
Jonas Widen 2025-03-17 07:13:07 +01:00
parent 9456cbd902
commit fa37ffe285

View File

@ -50,37 +50,52 @@ end
local function show_suggestion(suggestion, start_col)
clear_suggestion()
-- Only use first line of suggestion
suggestion = suggestion:match("^[^\n]*")
if suggestion == "" then return end
-- Split suggestion into lines
local suggestion_lines = vim.split(suggestion, "\n")
if #suggestion_lines == 0 then return end
-- Get current line info
local line = vim.api.nvim_win_get_cursor(0)[1] - 1
local line_text = vim.api.nvim_buf_get_lines(0, line, line + 1, true)[1]
-- Get text before cursor on current line
local prefix = string.sub(line_text, 1, start_col)
-- Only show suggestion if it continues the current text
if not suggestion:find("^" .. vim.pesc(prefix), 1, true) then
suggestion = prefix .. suggestion
-- Process first line of suggestion
local first_line = suggestion_lines[1]
if not first_line:find("^" .. vim.pesc(prefix), 1, true) then
first_line = prefix .. first_line
end
first_line = first_line:sub(#prefix + 1)
-- Remove the prefix from the suggestion to avoid duplication
suggestion = suggestion:sub(#prefix + 1)
if suggestion == "" then return end
if first_line == "" and #suggestion_lines == 1 then return end
current_suggestion.text = suggestion
current_suggestion.start_col = start_col
-- Make the text virtual (doesn't affect actual buffer content)
-- Show first line as virtual text
if first_line ~= "" then
vim.api.nvim_buf_set_extmark(0, current_suggestion.namespace_id, line, start_col, {
virt_text = {{suggestion, 'GeminiSuggestion'}},
virt_text = {{first_line, 'GeminiSuggestion'}},
virt_text_pos = 'inline',
virt_text_hide = true,
})
end
debug_print("Showing suggestion: %s", suggestion)
-- Show remaining lines as virtual lines
if #suggestion_lines > 1 then
local virt_lines = {}
for i = 2, #suggestion_lines do
table.insert(virt_lines, {{suggestion_lines[i], 'GeminiSuggestion'}})
end
vim.api.nvim_buf_set_extmark(0, current_suggestion.namespace_id, line, start_col, {
virt_lines = virt_lines,
virt_lines_above = false,
})
end
debug_print("Showing suggestion (%d lines)", #suggestion_lines)
end
function M.accept_suggestion()
@ -96,17 +111,35 @@ function M.accept_suggestion()
return false
end
-- Split suggestion into lines
local suggestion_lines = vim.split(current_suggestion.text, "\n")
if #suggestion_lines == 0 then return false end
-- Insert first line at cursor position
vim.api.nvim_buf_set_text(
0,
line,
col,
line,
col,
{current_suggestion.text}
{suggestion_lines[1]}
)
-- Insert remaining lines below
if #suggestion_lines > 1 then
vim.api.nvim_buf_set_lines(
0,
line + 1,
line + 1,
false,
vim.list_slice(suggestion_lines, 2)
)
end
-- Move cursor to end of inserted text
vim.api.nvim_win_set_cursor(0, {line + 1, col + #current_suggestion.text})
local final_line = line + #suggestion_lines - 1
local final_col = #suggestion_lines[#suggestion_lines]
vim.api.nvim_win_set_cursor(0, {final_line + 1, final_col})
clear_suggestion()
return true
@ -164,27 +197,31 @@ function M.trigger_completion()
debug_print("Getting completion for: %s", prefix)
-- Construct context from buffer
-- Construct context with line numbers and cursor position
local context = {}
local cursor_line = line
local cursor_col = col
-- Add up to 10 previous lines for context
local start_line = math.max(1, line - 10)
for i = start_line, line - 1 do
if lines[i] and #lines[i] > 0 then
table.insert(context, lines[i])
table.insert(context, string.format("L%d: %s", i, lines[i]))
end
end
-- Add current line
-- Add current line with cursor position marker (^)
if current_line and #current_line > 0 then
table.insert(context, current_line)
local cursor_marker = string.rep(" ", cursor_col) .. "^"
table.insert(context, string.format("L%d (current): %s", cursor_line, current_line))
table.insert(context, cursor_marker)
end
-- Add up to 10 lines after current line
local end_line = math.min(#lines, line + 10)
for i = line + 1, end_line do
if lines[i] and #lines[i] > 0 then
table.insert(context, lines[i])
table.insert(context, string.format("L%d: %s", i, lines[i]))
end
end
@ -195,11 +232,19 @@ function M.trigger_completion()
return
end
-- Get file type for better context
local file_type = vim.bo.filetype
-- Construct prompt for Gemini
local prompt = string.format(
"Complete this code. Consider the context (10 lines before and after). Return ONLY the completion that would naturally follow at the cursor position, no explanation:\n%s",
full_context
)
local prompt = string.format([[
I'm editing a %s file. Here's the context around line %d where my cursor (^) is:
%s
Complete the code at the cursor position. Consider the syntax and style of the surrounding code.
Return ONLY the completion that would naturally follow, no explanation.
The completion can be multiple lines if appropriate for the context.
]], file_type, cursor_line, full_context)
-- Validate prompt before sending
if #prompt == 0 then