mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-30 17:14:40 +08:00
fix(vscode): apply next edit insertions safely at eof
This commit is contained in:
+9
-4
@@ -1,5 +1,6 @@
|
||||
import * as vscode from "vscode"
|
||||
import { nesLog } from "./log"
|
||||
import { planInsertion } from "./pendingEdit"
|
||||
|
||||
const PENDING_CONTEXT_KEY = "kilo-code.nextEdit.hasPendingSuggestion"
|
||||
const CHAIN_DELAY_MS = 60
|
||||
@@ -20,7 +21,7 @@ export type PendingNextEdit =
|
||||
| {
|
||||
kind: "insert"
|
||||
document: vscode.TextDocument
|
||||
/** Existing line BEFORE which the new content will be inserted. */
|
||||
/** Existing line before insertion, or `lineCount` when appending at EOF. */
|
||||
diffStartLine: number
|
||||
/** Same as diffStartLine for hint/jump-target purposes. */
|
||||
diffEndLine: number
|
||||
@@ -192,9 +193,13 @@ export class NextEditSuggestionManager implements vscode.Disposable {
|
||||
nesLog(`document drifted since suggestion was made — dropping insert at line ${p.diffStartLine}`)
|
||||
return
|
||||
}
|
||||
const pos = new vscode.Position(p.diffStartLine, 0)
|
||||
ok = await editor.edit((b) => b.insert(pos, p.replacement))
|
||||
nesLog(`applied insert at line ${pos.line} (${p.replacement.length} chars, ok=${ok})`)
|
||||
const edit = planInsertion(p, {
|
||||
lineCount: editor.document.lineCount,
|
||||
end: (line) => editor.document.lineAt(line).range.end.character,
|
||||
})
|
||||
const pos = new vscode.Position(edit.line, edit.character)
|
||||
ok = await editor.edit((b) => b.insert(pos, edit.text))
|
||||
nesLog(`applied insert at line ${pos.line} (${edit.text.length} chars, ok=${ok})`)
|
||||
} else {
|
||||
const range = new vscode.Range(
|
||||
new vscode.Position(p.diffStartLine, 0),
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
type Input = {
|
||||
diffStartLine: number
|
||||
replacement: string
|
||||
}
|
||||
|
||||
type Document = {
|
||||
lineCount: number
|
||||
end(line: number): number
|
||||
}
|
||||
|
||||
export function planInsertion(input: Input, document: Document) {
|
||||
if (input.diffStartLine < document.lineCount) {
|
||||
return { line: input.diffStartLine, character: 0, text: input.replacement }
|
||||
}
|
||||
const line = Math.max(0, document.lineCount - 1)
|
||||
const text = input.replacement.endsWith("\n") ? input.replacement.slice(0, -1) : input.replacement
|
||||
return { line, character: document.end(line), text: `\n${text}` }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { planInsertion } from "../../src/services/autocomplete/next-edit/pendingEdit"
|
||||
|
||||
describe("planInsertion", () => {
|
||||
it("appends after the final unterminated line at EOF", () => {
|
||||
const edit = planInsertion(
|
||||
{ diffStartLine: 2, replacement: "third\n" },
|
||||
{ lineCount: 2, end: (line) => [5, 6][line] },
|
||||
)
|
||||
|
||||
expect(edit).toEqual({ line: 1, character: 6, text: "\nthird" })
|
||||
})
|
||||
|
||||
it("keeps insertion-before-line semantics for a trailing empty line", () => {
|
||||
const edit = planInsertion(
|
||||
{ diffStartLine: 1, replacement: "second\n" },
|
||||
{ lineCount: 2, end: (line) => [5, 0][line] },
|
||||
)
|
||||
|
||||
expect(edit).toEqual({ line: 1, character: 0, text: "second\n" })
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user