diff --git a/extensions/vscode/lib/rangeFormatting.ts b/extensions/vscode/lib/rangeFormatting.ts index eb0e9a20fa..34bf41ad0a 100644 --- a/extensions/vscode/lib/rangeFormatting.ts +++ b/extensions/vscode/lib/rangeFormatting.ts @@ -54,8 +54,8 @@ function getTrimmedNewText( }; } const oldText = document.getText(edit.range); - const overlapStart = Math.max(editStart, selectionStart) - editStart; - const overlapEnd = Math.min(editEnd, selectionEnd) - editStart; + let overlapStart = Math.max(editStart, selectionStart) - editStart; + let overlapEnd = Math.min(editEnd, selectionEnd) - editStart; if (overlapStart === overlapEnd) { return; } @@ -64,7 +64,6 @@ function getTrimmedNewText( let newTextIndex = 0; let newStart!: number; let newEnd!: number; - while (true) { if (oldTextIndex === overlapStart) { newStart = newTextIndex; @@ -72,11 +71,16 @@ function getTrimmedNewText( } const oldCharCode = oldText.charCodeAt(oldTextIndex); const newCharCode = edit.newText.charCodeAt(newTextIndex); - if (oldCharCode === newCharCode || (!isWhitespaceChar(oldCharCode) && !isWhitespaceChar(newCharCode))) { + if (oldCharCode === newCharCode) { oldTextIndex++; newTextIndex++; continue; } + if (!isWhitespaceChar(oldCharCode) && !isWhitespaceChar(newCharCode)) { + newStart = newTextIndex; + overlapStart -= overlapStart - oldTextIndex; + break; + } if (isWhitespaceChar(oldCharCode)) { oldTextIndex++; } @@ -94,11 +98,16 @@ function getTrimmedNewText( } const oldCharCode = oldText.charCodeAt(oldTextIndex); const newCharCode = edit.newText.charCodeAt(newTextIndex); - if (oldCharCode === newCharCode || (!isWhitespaceChar(oldCharCode) && !isWhitespaceChar(newCharCode))) { + if (oldCharCode === newCharCode) { oldTextIndex--; newTextIndex--; continue; } + if (!isWhitespaceChar(oldCharCode) && !isWhitespaceChar(newCharCode)) { + newEnd = newTextIndex + 1; + overlapEnd += overlapEnd - oldTextIndex + 1; + break; + } if (isWhitespaceChar(oldCharCode)) { oldTextIndex--; } diff --git a/extensions/vscode/tests/rangeFormatting.spec.ts b/extensions/vscode/tests/rangeFormatting.spec.ts index f45921bc68..db25c2d50c 100644 --- a/extensions/vscode/tests/rangeFormatting.spec.ts +++ b/extensions/vscode/tests/rangeFormatting.spec.ts @@ -8,7 +8,7 @@ describe('provideDocumentRangeFormattingEdits', () => { const selection = createRange(1, 5); const edits = [createTextEdit(0, 5, '_BCDE')]; const result = restrictFormattingEditsToRange(document, selection, edits, createTextEdit); - expect(applyEdits(document, result)).toMatchInlineSnapshot(`"0BCDE5"`); + expect(applyEdits(document, result)).toMatchInlineSnapshot(`"_BCDE5"`); }); test('keeps indent when edits start on previous line', () => { @@ -89,7 +89,7 @@ describe('provideDocumentRangeFormattingEdits', () => { const selection = createRange(1, 5); // select "bcde" const edits = [createTextEdit(0, 6, 'ab')]; // replace all with just "ab" const result = restrictFormattingEditsToRange(document, selection, edits, createTextEdit); - expect(applyEdits(document, result)).toMatchInlineSnapshot(`"af"`); + expect(applyEdits(document, result)).toMatchInlineSnapshot(`"ab"`); }); test('handles insertion where newText is longer than oldText', () => { @@ -164,7 +164,7 @@ describe('provideDocumentRangeFormattingEdits', () => { const selection = createRange(1, 3); // select "好世" const edits = [createTextEdit(0, 4, '你好朋友')]; const result = restrictFormattingEditsToRange(document, selection, edits, createTextEdit); - expect(applyEdits(document, result)).toMatchInlineSnapshot(`"你好朋界"`); + expect(applyEdits(document, result)).toMatchInlineSnapshot(`"你好朋友"`); }); test('handles overlapStart equals overlapEnd', () => {