Review and cleanup

This commit is contained in:
Jonas Widen 2025-03-18 18:25:30 +01:00
parent 2c641faf11
commit 34af659844
2 changed files with 69 additions and 66 deletions

View File

@ -87,11 +87,17 @@ local function show_suggestion(suggestion, start_col)
if #suggestion_lines == 0 then return end if #suggestion_lines == 0 then return end
-- Show ghost text -- Add support for different suggestion styles
local config = require("gemini.config")
local style = config.options.completion_style or "ghost" -- Add this to config
-- Show ghost text with improved styling
vim.api.nvim_buf_set_extmark(0, current_suggestion.namespace_id, line, start_col, { vim.api.nvim_buf_set_extmark(0, current_suggestion.namespace_id, line, start_col, {
virt_text = {{suggestion_lines[1], 'GeminiSuggestion'}}, virt_text = {{suggestion_lines[1], 'GeminiSuggestion'}},
virt_text_pos = 'overlay', virt_text_pos = 'overlay',
hl_mode = 'combine', hl_mode = 'combine',
priority = 100, -- Add higher priority to ensure visibility
right_gravity = false -- Ensure suggestion stays at cursor position
}) })
-- Show remaining lines as virtual lines -- Show remaining lines as virtual lines
@ -198,81 +204,64 @@ local function get_context_around_cursor(lines, current_line, max_lines)
local start_line = math.max(1, current_line - math.floor(max_lines/2)) local start_line = math.max(1, current_line - math.floor(max_lines/2))
local end_line = math.min(#lines, current_line + math.floor(max_lines/2)) local end_line = math.min(#lines, current_line + math.floor(max_lines/2))
-- Add file type and cursor position information
local file_type = vim.bo.filetype
local cursor_pos = vim.api.nvim_win_get_cursor(0)
-- Add metadata to context
table.insert(context, string.format("File type: %s", file_type))
table.insert(context, string.format("Cursor position: line %d, col %d", cursor_pos[1], cursor_pos[2]))
-- Add visible context with line numbers
for i = start_line, end_line do for i = start_line, end_line do
if lines[i] and #lines[i] > 0 then if lines[i] and #lines[i] > 0 then
table.insert(context, string.format("L%d: %s", i, lines[i])) table.insert(context, string.format("L%d: %s", i, lines[i]))
end end
end end
return context return context
end end
local function create_debounced_function(fn, wait)
local timer = nil
return function(...)
local args = {...}
if timer then
vim.fn.timer_stop(timer)
end
timer = vim.fn.timer_start(wait, function()
fn(unpack(args))
timer = nil
end)
end
end
-- Use the improved debouncing
local trigger_completion_debounced = create_debounced_function(function()
M.trigger_completion()
end, current_suggestion.debounce_ms)
function M.trigger_completion() function M.trigger_completion()
if current_suggestion.timer then -- Early exit conditions
vim.fn.timer_stop(current_suggestion.timer) if not vim.b.gemini_completion_enabled then return end
if vim.fn.pumvisible() ~= 0 then return end
local cursor = vim.api.nvim_win_get_cursor(0)
local line = cursor[1] - 1
local col = cursor[2]
-- Check filetype exclusions
local config = require("gemini.config")
if vim.tbl_contains(config.options.completion.exclude_filetypes, vim.bo.filetype) then
return
end end
current_suggestion.timer = vim.fn.timer_start(150, function() -- Get context and trigger completion
local cursor = vim.api.nvim_win_get_cursor(0) local visible_lines, relative_cursor = get_visible_lines()
local line = cursor[1] - 1 local context = get_context_around_cursor(visible_lines, relative_cursor, config.options.completion.max_context_lines)
local col = cursor[2]
-- Get visible context -- Use improved debouncing
local visible_lines, relative_cursor = get_visible_lines() trigger_completion_debounced(context)
local current_line = visible_lines[relative_cursor]
if not current_line or current_line == "" then
clear_suggestion()
return
end
-- Don't trigger in comments or strings
local syntax_group = vim.fn.synIDattr(vim.fn.synID(cursor[1], col, 1), "name")
if syntax_group:match("Comment") or syntax_group:match("String") then
clear_suggestion()
return
end
-- Prepare context for AI
local context = table.concat(visible_lines, "\n")
local file_type = vim.bo.filetype
local prompt = string.format([[
In this %s file, complete the code at line %d, column %d:
%s
Return ONLY the completion text that would naturally continue from the cursor position.
Focus on completing the current statement or block.
Consider the visible context, syntax, and code style.
Do not repeat any text that appears before the cursor.]],
file_type, cursor[1], col + 1, context)
-- Check cache and rate limiting
local cache_key = get_cache_key(prompt)
if current_suggestion.cache[cache_key] then
show_suggestion(current_suggestion.cache[cache_key], col)
return
end
if should_rate_limit() then return end
-- Get completion from Gemini
api.get_response(prompt, nil, function(response, error)
if error then return end
if type(response) == "string" and #response > 0 then
response = vim.trim(response)
current_suggestion.cache[cache_key] = response
vim.schedule(function()
local new_cursor = vim.api.nvim_win_get_cursor(0)
if new_cursor[1] == cursor[1] and math.abs(new_cursor[2] - col) <= 1 then
show_suggestion(response, col)
end
end)
end
end)
end)
end end
-- Setup function to create highlight group and keymaps -- Setup function to create highlight group and keymaps

View File

@ -19,6 +19,20 @@ M.defaults = {
user = "GeminiUser", user = "GeminiUser",
separator = "GeminiSeparator", separator = "GeminiSeparator",
}, },
completion = {
enabled = true,
debounce_ms = 1000,
min_chars = 0,
max_context_lines = 10,
style = "ghost", -- or "inline"
trigger_characters = ".", -- Add trigger characters
exclude_filetypes = { "TelescopePrompt", "neo-tree" },
suggestion_highlight = {
fg = '#666666',
italic = true,
blend = 15
}
}
} }
M.options = {} M.options = {}