Skip to content

Commit af4687c

Browse files
ulugbeknaCopilot
andcommitted
nes: fix: do not insert spurious trailing newline after suggestion
Co-authored-by: Copilot <copilot@github.com>
1 parent f729383 commit af4687c

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

extensions/copilot/src/extension/inlineEdits/test/vscode-node/isInlineSuggestion.spec.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ suite('toInlineSuggestion', () => {
101101
assert.isDefined(result);
102102
// Range is an empty range at the cursor for a pure insertion
103103
assert.deepStrictEqual(result!.range, new Range(1, 15, 1, 15));
104-
// Text is prepended with the newline between cursor and original range
105-
assert.strictEqual(result!.newText, '\n' + replaceText);
104+
// Text is prepended with the newline between cursor and original range,
105+
// and the trailing newline is dropped so we don't introduce a blank line.
106+
assert.strictEqual(result!.newText, '\n' + replaceText.replace(/\n$/, ''));
106107
});
107108

108109
test('should not use ghost text when inserting on next line when none empty', () => {
@@ -149,7 +150,8 @@ suite('toInlineSuggestion', () => {
149150
const result = toInlineSuggestion(cursorPosition, document, replaceRange, replaceText);
150151
assert.isDefined(result);
151152
assert.deepStrictEqual(result!.range, new Range(0, 13, 0, 13));
152-
assert.strictEqual(result!.newText, '\n' + replaceText);
153+
// Trailing '\n' is dropped to avoid a spurious blank line.
154+
assert.strictEqual(result!.newText, '\n' + replaceText.replace(/\n$/, ''));
153155
});
154156

155157
test('multi-line insertion without trailing newline rejected when target line has content', () => {
@@ -318,7 +320,8 @@ function createDocumentSymbol(
318320
const result = toInlineSuggestion(cursorPosition, document, replaceRange, replaceText);
319321
assert.isDefined(result);
320322
assert.deepStrictEqual(result!.range, new Range(0, 6, 0, 6));
321-
assert.strictEqual(result!.newText, '\n\n');
323+
// Trailing '\n' is dropped — only the prepended newline remains.
324+
assert.strictEqual(result!.newText, '\n');
322325
});
323326

324327
test('next-line: cursor at end of an empty line', () => {
@@ -330,7 +333,8 @@ function createDocumentSymbol(
330333
const result = toInlineSuggestion(cursorPosition, document, replaceRange, replaceText);
331334
assert.isDefined(result);
332335
assert.deepStrictEqual(result!.range, new Range(0, 0, 0, 0));
333-
assert.strictEqual(result!.newText, '\nnew line\n');
336+
// Trailing '\n' is dropped to avoid a spurious blank line.
337+
assert.strictEqual(result!.newText, '\nnew line');
334338
});
335339

336340
test('next-line: range on line before cursor is rejected', () => {
@@ -585,6 +589,8 @@ const fieldLabels: Record<keyof FormData, string> = {
585589
const result = toInlineSuggestion(cursorPosition, document, replaceRange, replaceText, true);
586590
assert.isDefined(result);
587591
assert.deepStrictEqual(result!.range, new Range(22, 26, 22, 26));
588-
assert.strictEqual(result!.newText, '\n' + replaceText);
592+
// Trailing '\n' is dropped because the original line terminator after
593+
// the cursor is preserved.
594+
assert.strictEqual(result!.newText, '\n password: "Password",');
589595
});
590596
});

extensions/copilot/src/extension/inlineEdits/vscode-node/isInlineSuggestion.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ export function toInlineSuggestion(cursorPos: Position, doc: TextDocument, range
2626
// Use an empty range at the cursor so the suggestion is a pure insertion
2727
const adjustedRange = new Range(cursorPos, cursorPos);
2828
const textBetweenCursorAndRange = doc.getText(new Range(cursorPos, range.start));
29-
return { range: adjustedRange, newText: textBetweenCursorAndRange + newText };
29+
// The original range is on the next line, so the line terminator that
30+
// already separates the cursor's line from range.start is preserved.
31+
// Drop a single trailing '\n' from newText (if present) to avoid
32+
// inserting an extra blank line after the suggestion.
33+
const adjustedNewText = newText.endsWith('\n') ? newText.slice(0, -1) : newText;
34+
return { range: adjustedRange, newText: textBetweenCursorAndRange + adjustedNewText };
3035
}
3136

3237
if (advanced) {

0 commit comments

Comments
 (0)