fix(vscode): guard tag auto-close against replaced selections and stale round-trips
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
// WRN editor extension source hash: 7721e499707f7fb9b0b52fe428de3033cd624fa508322ec795960af7b6d96da5
|
// WRN editor extension source hash: 875fa63e96381e6a0112442a3fce92717fb52e85f4e331e2b3e3487837e00a4d
|
||||||
// WRN editor extension generator hash: 456d1d614e44e5fb1f19b784176c09cf2ade9b64ef73a17934c2698150b62728
|
// WRN editor extension generator hash: 456d1d614e44e5fb1f19b784176c09cf2ade9b64ef73a17934c2698150b62728
|
||||||
"use strict";
|
"use strict";
|
||||||
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
||||||
@@ -22727,16 +22727,29 @@ function registerAutoCloseTags(context, client2) {
|
|||||||
const change = event.contentChanges[0];
|
const change = event.contentChanges[0];
|
||||||
if (!change || change.text !== ">" && change.text !== "/")
|
if (!change || change.text !== ">" && change.text !== "/")
|
||||||
return;
|
return;
|
||||||
|
if (change.rangeLength !== 0)
|
||||||
|
return;
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (!editor || editor.document !== event.document)
|
if (!editor || editor.document !== event.document)
|
||||||
return;
|
return;
|
||||||
|
const documentVersion = event.document.version;
|
||||||
const position = change.range.start.translate(0, change.text.length);
|
const position = change.range.start.translate(0, change.text.length);
|
||||||
|
if (!editor.selection.isEmpty || !editor.selection.active.isEqual(position))
|
||||||
|
return;
|
||||||
const snippet = await client2.sendRequest("wrn/tagComplete", {
|
const snippet = await client2.sendRequest("wrn/tagComplete", {
|
||||||
textDocument: { uri: event.document.uri.toString() },
|
textDocument: { uri: event.document.uri.toString() },
|
||||||
position: { line: position.line, character: position.character }
|
position: { line: position.line, character: position.character }
|
||||||
});
|
});
|
||||||
if (typeof snippet !== "string" || !snippet)
|
if (typeof snippet !== "string" || !snippet)
|
||||||
return;
|
return;
|
||||||
|
if (vscode.window.activeTextEditor !== editor)
|
||||||
|
return;
|
||||||
|
if (editor.document !== event.document)
|
||||||
|
return;
|
||||||
|
if (editor.document.version !== documentVersion)
|
||||||
|
return;
|
||||||
|
if (!editor.selection.isEmpty || !editor.selection.active.isEqual(position))
|
||||||
|
return;
|
||||||
await editor.insertSnippet(new vscode.SnippetString(snippet), position);
|
await editor.insertSnippet(new vscode.SnippetString(snippet), position);
|
||||||
});
|
});
|
||||||
context.subscriptions.push(listener);
|
context.subscriptions.push(listener);
|
||||||
|
|||||||
@@ -37,17 +37,31 @@ function registerAutoCloseTags(context, client) {
|
|||||||
|
|
||||||
const change = event.contentChanges[0];
|
const change = event.contentChanges[0];
|
||||||
if (!change || (change.text !== ">" && change.text !== "/")) return;
|
if (!change || (change.text !== ">" && change.text !== "/")) return;
|
||||||
|
// A replaced selection (overtype/select-and-type) makes `range.start + text.length`
|
||||||
|
// an incorrect offset for both the query and the insertion; decline rather than guess.
|
||||||
|
if (change.rangeLength !== 0) return;
|
||||||
|
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (!editor || editor.document !== event.document) return;
|
if (!editor || editor.document !== event.document) return;
|
||||||
|
|
||||||
|
const documentVersion = event.document.version;
|
||||||
const position = change.range.start.translate(0, change.text.length);
|
const position = change.range.start.translate(0, change.text.length);
|
||||||
|
if (!editor.selection.isEmpty || !editor.selection.active.isEqual(position)) return;
|
||||||
|
|
||||||
const snippet = await client.sendRequest("wrn/tagComplete", {
|
const snippet = await client.sendRequest("wrn/tagComplete", {
|
||||||
textDocument: { uri: event.document.uri.toString() },
|
textDocument: { uri: event.document.uri.toString() },
|
||||||
position: { line: position.line, character: position.character },
|
position: { line: position.line, character: position.character },
|
||||||
});
|
});
|
||||||
if (typeof snippet !== "string" || !snippet) return;
|
if (typeof snippet !== "string" || !snippet) return;
|
||||||
|
|
||||||
|
// The user may have kept typing during the round-trip; re-validate everything the
|
||||||
|
// insertion depends on before touching the document, since a stale offset would
|
||||||
|
// silently corrupt it.
|
||||||
|
if (vscode.window.activeTextEditor !== editor) return;
|
||||||
|
if (editor.document !== event.document) return;
|
||||||
|
if (editor.document.version !== documentVersion) return;
|
||||||
|
if (!editor.selection.isEmpty || !editor.selection.active.isEqual(position)) return;
|
||||||
|
|
||||||
await editor.insertSnippet(new vscode.SnippetString(snippet), position);
|
await editor.insertSnippet(new vscode.SnippetString(snippet), position);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user