Extension 0.6.0: next-edit, token healing, TS errors context, cursor-move, prewarm
ci / build (push) Canceled after 0s
ci / build (push) Canceled after 0s
- shared/nextedit.ts: next-edit prompt format (region rewrite or NO_EDIT, Qwen spare special tokens) - shared/diagnostics.ts: TS errors near the cursor as context; symbols format 2 adds namespace imports - shared/prompt.ts: token healing (cut the half-typed word, force it via grammar), errors header section - daemon: model profiles carry contextFormat/errors/members/nextEdit; /v1/next-edit with edit-burst tracking; /v1/prewarm; /v1/debug/last; token healing on by default - extension: next-edit decorations (Tab apply / Esc dismiss), suggest on cursor move, prewarm on focus, Show Last Prompt, update check against releases, diagnostics in the edit recorder - models/README: training-data attribution; release script profiles for stage-d/stage-e - .gitea/workflows/ci.yml: build + test, publish release on vscode-v* tags (needs a runner + RELEASE_TOKEN) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J39imRDT8L7xYbWzsVWd8A
This commit is contained in:
@@ -63,3 +63,39 @@ export function statusText(cfg: { enabled: boolean; mode: ContextMode; effective
|
||||
const mode = cfg.effectiveMode && cfg.effectiveMode !== cfg.mode ? `${cfg.mode}→${cfg.effectiveMode}` : cfg.mode
|
||||
return `$(sparkle) AC: ${mode}${lastMs !== null ? ` · ${Math.round(lastMs)} ms` : ''}`
|
||||
}
|
||||
|
||||
/** Line-block diff of a region: the first/last changed lines (old and new) after trimming common lines. */
|
||||
export function lineBlockDiff(oldText: string, newText: string): { oldStart: number; oldEnd: number; newLines: string[]; oldLines: string[] } | null {
|
||||
const a = oldText.split('\n'), b = newText.split('\n')
|
||||
let p = 0
|
||||
while (p < a.length && p < b.length && a[p] === b[p]) p++
|
||||
if (p === a.length && p === b.length) return null
|
||||
let s = 0
|
||||
while (s < a.length - p && s < b.length - p && a[a.length - 1 - s] === b[b.length - 1 - s]) s++
|
||||
return { oldStart: p, oldEnd: a.length - s, oldLines: a.slice(p, a.length - s), newLines: b.slice(p, b.length - s) }
|
||||
}
|
||||
|
||||
/** Character diff of one line: deleted [start, end) in the old line and the text inserted there. */
|
||||
export function charDiff(oldLine: string, newLine: string): { start: number; deleteEnd: number; insert: string } {
|
||||
let p = 0
|
||||
while (p < oldLine.length && p < newLine.length && oldLine[p] === newLine[p]) p++
|
||||
let s = 0
|
||||
while (s < oldLine.length - p && s < newLine.length - p && oldLine[oldLine.length - 1 - s] === newLine[newLine.length - 1 - s]) s++
|
||||
return { start: p, deleteEnd: oldLine.length - s, insert: newLine.slice(p, newLine.length - s) }
|
||||
}
|
||||
|
||||
/** Where cursor-move triggers make sense for plain FIM: empty line, end of line, or on a line with an error. */
|
||||
export function insertionMakesSense(lineText: string, column: number, lineHasError: boolean): boolean {
|
||||
if (!lineText.trim()) return true
|
||||
if (!lineText.slice(column).trim()) return true
|
||||
return lineHasError
|
||||
}
|
||||
|
||||
/** Semver-ish comparison of "a.b.c" strings. */
|
||||
export function newerVersion(candidate: string, current: string): boolean {
|
||||
const pa = candidate.split('.').map(Number), pb = current.split('.').map(Number)
|
||||
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
||||
if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pa[i] ?? 0) > (pb[i] ?? 0)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user