fix: ensure there is no overlap between code snippets (#396)

This commit is contained in:
yetone 2024-08-30 20:43:26 +08:00 committed by GitHub
parent fc1bcda822
commit 5cf85d59bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 7 deletions

View File

@ -16,7 +16,7 @@ M.CANCEL_PATTERN = "AvanteLLMEscape"
-- Copy from: https://github.com/Doriandarko/claude-engineer/blob/15c94963cbf9d01b8ae7bbb5d42d7025aa0555d5/main.py#L276
---@alias AvanteBasePrompt string
local planning_mode_system_prompt_tpl = [[
You are an AI coding agent that generates code according to the instructions. Follow these steps:
You are an excellent programming expert and your primary task is to generate code according to the instructions. Follow these steps:
1. Review the entire file content to understand the context:
${file_content}
@ -40,12 +40,12 @@ ${full_file_contents_context}
- Include enough context to uniquely identify the code to be changed
- Provide the exact replacement code, maintaining correct INDENTATION and FORMATTING
- Focus on specific, targeted changes rather than large, sweeping modifications
- The content in the SEARCH tag MUST NOT contain any of your generated content
- The content in the SEARCH tag MUST NOT contain any of your generated content. Do not be lazy!
- The content in the SEARCH tag MUST be based on the original content of the source file
- The content in the SEARCH tag needs to ensure a certain context to guarantee its UNIQUENESS
- The content in the REPLACE tag should also correspond to the context of the SEARCH tag
- There should be NO OVERLAP between the code of each SEARCH tag.
- DO NOT use ``` to wrap code blocks
- There should be NO OVERLAP between the code of each SEARCH tag. Do not be lazy!
- Be sure to ensure that there are NO SYNTAX ERRORS OR FORMATTING ERRORS after the SEARCH part in the source code is replaced by the REPLACE part! Do not be lazy!
- DO NOT use ``` to wrap code blocks, Do not be lazy!
8. Ensure that your SEARCH/REPLACE blocks:
- Address all relevant aspects of the instructions
@ -69,7 +69,7 @@ If no changes are needed, return an empty list.
]]
local editing_mode_system_prompt_tpl = [[
You are an AI coding agent that generates code according to the instructions. Follow these steps:
You are an excellent programming expert and your primary task is to generate code according to the instructions. Follow these steps:
1. Review the entire file content to understand the context:
${file_content}

View File

@ -243,11 +243,18 @@ local function transform_result_content(original_content, result_content, code_l
}
end
local searching_hint = "\n 🔍 Searching..."
local searching_hints = { "\n 🔍 Searching...", "\n 🔍 Searching...", "\n 🔍 Searching..." }
local searching_hint_idx = 1
---@param replacement AvanteReplacementResult
---@return string
local function generate_display_content(replacement)
local searching_hint = searching_hints[searching_hint_idx]
if searching_hint_idx >= #searching_hints then
searching_hint_idx = 1
else
searching_hint_idx = searching_hint_idx + 1
end
if replacement.is_searching then
return table.concat(
vim.list_slice(vim.split(replacement.content, "\n"), 1, replacement.last_search_tag_start_line - 1),
@ -318,6 +325,49 @@ local function extract_code_snippets(response_content)
return snippets
end
---@param snippets AvanteCodeSnippet[]
---@return AvanteCodeSnippet[]
local function ensure_snippets_no_overlap(original_content, snippets)
table.sort(snippets, function(a, b)
return a.range[1] < b.range[1]
end)
local original_lines = vim.split(original_content, "\n")
local result = {}
local last_end_line = 0
for _, snippet in ipairs(snippets) do
if snippet.range[1] > last_end_line then
table.insert(result, snippet)
last_end_line = snippet.range[2]
else
local snippet_lines = vim.split(snippet.content, "\n")
-- Trim the overlapping part
local new_start_line = nil
for i = snippet.range[1], math.min(snippet.range[2], last_end_line) do
if
Utils.remove_indentation(original_lines[i])
== Utils.remove_indentation(snippet_lines[i - snippet.range[1] + 1])
then
new_start_line = i + 1
else
break
end
end
if new_start_line ~= nil then
snippet.content = table.concat(vim.list_slice(snippet_lines, new_start_line - snippet.range[1] + 1), "\n")
snippet.range[1] = new_start_line
table.insert(result, snippet)
last_end_line = snippet.range[2]
else
Utils.error("Failed to ensure snippets no overlap", { once = true, title = "Avante" })
end
end
end
return result
end
local function get_conflict_content(content, snippets)
-- sort snippets by start_line
table.sort(snippets, function(a, b)
@ -421,6 +471,7 @@ function Sidebar:apply(current_cursor)
local content = table.concat(Utils.get_buf_lines(0, -1, self.code.bufnr), "\n")
local response, response_start_line = self:get_content_between_separators()
local snippets = extract_code_snippets(response)
snippets = ensure_snippets_no_overlap(content, snippets)
if current_cursor then
if self.result and self.result.winid then
local cursor_line = Utils.get_cursor_pos(self.result.winid)