Skip to content

fix: prevent extra bracket with import statement completion #2713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
} from '../utils';
import { getJsDocTemplateCompletion } from './getJsDocTemplateCompletion';
import {
checkRangeMappingWithGeneratedSemi,
getComponentAtPosition,
getFormatCodeBasis,
getNewScriptStartTag,
Expand Down Expand Up @@ -334,7 +335,9 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionRe
this.fixTextEditRange(
wordInfo.range,
mapCompletionItemToOriginal(tsDoc, completion),
isHandlerCompletion
isHandlerCompletion,
completion.textEdit,
tsDoc
)
);
}
Expand Down Expand Up @@ -876,7 +879,9 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionRe
private fixTextEditRange(
wordRange: Range,
completionItem: CompletionItem,
isHandlerCompletion: boolean
isHandlerCompletion: boolean,
generatedTextEdit: CompletionItem['textEdit'] | undefined,
tsDoc: SvelteDocumentSnapshot
) {
if (isHandlerCompletion && completionItem.label.startsWith('on:')) {
completionItem.textEdit = TextEdit.replace(
Expand All @@ -892,6 +897,10 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionRe
return completionItem;
}

if (TextEdit.is(generatedTextEdit)) {
checkRangeMappingWithGeneratedSemi(textEdit.range, generatedTextEdit.range, tsDoc);
}

const {
newText,
range: { start }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { SelectionRangeProvider } from '../../interfaces';
import { SvelteDocumentSnapshot } from '../DocumentSnapshot';
import { LSAndTSDocResolver } from '../LSAndTSDocResolver';
import { convertRange } from '../utils';
import { checkRangeMappingWithGeneratedSemi } from './utils';

export class SelectionRangeProviderImpl implements SelectionRangeProvider {
constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) {}
Expand Down Expand Up @@ -43,16 +44,7 @@ export class SelectionRangeProviderImpl implements SelectionRangeProvider {
const { range, parent } = selectionRange;
const originalRange = mapRangeToOriginal(tsDoc, range);

const originalLength = originalRange.end.character - originalRange.start.character;
const generatedLength = range.end.character - range.start.character;

// sourcemap off by one character issue + a generated semicolon
if (
originalLength === generatedLength - 2 &&
tsDoc.getFullText()[tsDoc.offsetAt(range.end) - 1] === ';'
) {
originalRange.end.character += 1;
}
checkRangeMappingWithGeneratedSemi(originalRange, range, tsDoc);

if (!parent) {
return SelectionRange.create(originalRange);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ts from 'typescript';
import { Position } from 'vscode-languageserver';
import { Position, Range } from 'vscode-languageserver';
import {
Document,
getLineAtPosition,
Expand Down Expand Up @@ -434,3 +434,20 @@ export function getNewScriptStartTag(lsConfig: Readonly<LSConfig>) {
const scriptLang = lang === 'none' ? '' : ` lang="${lang}"`;
return `<script${scriptLang}>${ts.sys.newLine}`;
}

export function checkRangeMappingWithGeneratedSemi(
originalRange: Range,
generatedRange: Range,
tsDoc: SvelteDocumentSnapshot
) {
const originalLength = originalRange.end.character - originalRange.start.character;
const generatedLength = generatedRange.end.character - generatedRange.start.character;

// sourcemap off by one character issue + a generated semicolon
if (
originalLength === generatedLength - 2 &&
tsDoc.getFullText()[tsDoc.offsetAt(generatedRange.end) - 1] === ';'
) {
originalRange.end.character += 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,66 @@ describe('CompletionProviderImpl', function () {
});
});

it('provides import statement completion with brackets', async () => {
const { completionProvider, document } = setup('importstatementcompletions2.svelte');

const completions = await completionProvider.getCompletions(
document,
{
line: 1,
character: 15
},
{
triggerKind: CompletionTriggerKind.Invoked
}
);

const item = completions?.items.find((item) => item.label === 'blubb');

delete item?.data;

assert.deepStrictEqual(item, {
additionalTextEdits: [
{
newText: 'import ',
range: {
end: {
character: 11,
line: 1
},
start: {
character: 4,
line: 1
}
}
}
],
label: 'blubb',
insertText: 'import { blubb$1 } from "../definitions";',
insertTextFormat: 2,
kind: CompletionItemKind.Function,
sortText: '11',
commitCharacters: undefined,
preselect: undefined,
labelDetails: {
description: '../definitions'
},
textEdit: {
newText: '{ blubb$1 } from "../definitions";',
range: {
end: {
character: 16,
line: 1
},
start: {
character: 11,
line: 1
}
}
}
});
});

it('provides optional chaining completion', async () => {
const { completionProvider, document } = setup('completions-auto-optional-chain.svelte');

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script lang="ts">
import {blu}
</script>
Loading