Skip to content

Commit 9d9fd7b

Browse files
authored
(fix) better import completion locations (#1011)
Add import to module script if trigger in there, same for instance script #927
1 parent a8d19a8 commit 9d9fd7b

File tree

6 files changed

+77
-19
lines changed

6 files changed

+77
-19
lines changed

packages/language-server/src/plugins/typescript/features/CodeActionsProvider.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ts from 'typescript';
12
import {
23
CodeAction,
34
CodeActionContext,
@@ -10,18 +11,15 @@ import {
1011
} from 'vscode-languageserver';
1112
import {
1213
Document,
13-
mapRangeToOriginal,
14+
getLineAtPosition,
1415
isRangeInTag,
15-
isInTag,
16-
getLineAtPosition
16+
mapRangeToOriginal
1717
} from '../../../lib/documents';
18-
import { pathToUrl, flatten, isNotNullOrUndefined, modifyLines, getIndent } from '../../../utils';
18+
import { flatten, getIndent, isNotNullOrUndefined, modifyLines, pathToUrl } from '../../../utils';
1919
import { CodeActionsProvider } from '../../interfaces';
2020
import { SnapshotFragment, SvelteSnapshotFragment } from '../DocumentSnapshot';
2121
import { LSAndTSDocResolver } from '../LSAndTSDocResolver';
2222
import { convertRange } from '../utils';
23-
24-
import ts from 'typescript';
2523
import { CompletionsProviderImpl } from './CompletionProvider';
2624
import { isNoTextSpanInGeneratedCode, SnapshotFragmentMap } from './utils';
2725

@@ -189,8 +187,7 @@ export class CodeActionsProviderImpl implements CodeActionsProvider {
189187
fragment,
190188
edit,
191189
true,
192-
isInTag(range.start, document.scriptInfo) ||
193-
isInTag(range.start, document.moduleScriptInfo)
190+
range.start
194191
);
195192
}
196193

packages/language-server/src/plugins/typescript/features/CompletionProvider.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,7 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
317317
fragment,
318318
change,
319319
isImport,
320-
isInTag(comp.position, document.scriptInfo) ||
321-
isInTag(comp.position, document.moduleScriptInfo)
320+
comp.position
322321
)
323322
);
324323
}
@@ -355,15 +354,15 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
355354
fragment: SvelteSnapshotFragment,
356355
changes: ts.FileTextChanges,
357356
isImport: boolean,
358-
actionTriggeredInScript: boolean
357+
originalTriggerPosition: Position
359358
): TextEdit[] {
360359
return changes.textChanges.map((change) =>
361360
this.codeActionChangeToTextEdit(
362361
doc,
363362
fragment,
364363
change,
365364
isImport,
366-
actionTriggeredInScript
365+
originalTriggerPosition
367366
)
368367
);
369368
}
@@ -373,9 +372,12 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
373372
fragment: SvelteSnapshotFragment,
374373
change: ts.TextChange,
375374
isImport: boolean,
376-
actionTriggeredInScript: boolean
375+
originalTriggerPosition: Position
377376
): TextEdit {
378-
change.newText = this.changeComponentImport(change.newText, actionTriggeredInScript);
377+
change.newText = this.changeComponentImport(
378+
change.newText,
379+
isInScript(originalTriggerPosition, doc)
380+
);
379381

380382
const scriptTagInfo = fragment.scriptInfo || fragment.moduleScriptInfo;
381383
if (!scriptTagInfo) {
@@ -410,7 +412,11 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
410412
!isInScript(range.start, fragment)
411413
) {
412414
range = convertRange(doc, {
413-
start: scriptTagInfo.start,
415+
start: isInTag(originalTriggerPosition, doc.scriptInfo)
416+
? fragment.scriptInfo?.start || scriptTagInfo.start
417+
: isInTag(originalTriggerPosition, doc.moduleScriptInfo)
418+
? fragment.moduleScriptInfo?.start || scriptTagInfo.start
419+
: scriptTagInfo.start,
414420
length: span.length
415421
});
416422
}

packages/language-server/src/plugins/typescript/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
Range,
88
SymbolKind
99
} from 'vscode-languageserver';
10-
import { isInTag, mapRangeToOriginal } from '../../lib/documents';
10+
import { Document, isInTag, mapRangeToOriginal } from '../../lib/documents';
1111
import { pathToUrl } from '../../utils';
1212
import { SnapshotFragment, SvelteSnapshotFragment } from './DocumentSnapshot';
1313

@@ -298,6 +298,6 @@ export function convertToTextSpan(range: Range, fragment: SnapshotFragment): ts.
298298
};
299299
}
300300

301-
export function isInScript(position: Position, fragment: SvelteSnapshotFragment) {
301+
export function isInScript(position: Position, fragment: SvelteSnapshotFragment | Document) {
302302
return isInTag(position, fragment.scriptInfo) || isInTag(position, fragment.moduleScriptInfo);
303303
}

packages/language-server/test/plugins/typescript/features/CompletionProvider.test.ts

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const fileNameToAbsoluteUri = (file: string) => {
3030
return pathToUrl(join(testFilesDir, file));
3131
};
3232

33-
describe('CompletionProviderImpl', () => {
33+
describe.only('CompletionProviderImpl', () => {
3434
function setup(filename: string) {
3535
const docManager = new DocumentManager(
3636
(textDocument) => new Document(textDocument.uri, textDocument.text)
@@ -524,6 +524,54 @@ describe('CompletionProviderImpl', () => {
524524
);
525525
});
526526

527+
it('resolve auto import completion in instance script (instance and module script present)', async () => {
528+
const { completionProvider, document } = setup('importcompletions9.svelte');
529+
530+
const completions = await completionProvider.getCompletions(
531+
document,
532+
Position.create(5, 7)
533+
);
534+
document.version++;
535+
536+
const item = completions?.items.find((item) => item.label === 'onMount');
537+
const { additionalTextEdits } = await completionProvider.resolveCompletion(document, item!);
538+
539+
assert.strictEqual(
540+
harmonizeNewLines(additionalTextEdits![0]?.newText),
541+
// " instead of ' because VSCode uses " by default when there are no other imports indicating otherwise
542+
`${newLine}import { onMount } from "svelte";${newLine}${newLine}`
543+
);
544+
545+
assert.deepEqual(
546+
additionalTextEdits![0]?.range,
547+
Range.create(Position.create(4, 8), Position.create(4, 8))
548+
);
549+
});
550+
551+
it('resolve auto import completion in module script (instance and module script present)', async () => {
552+
const { completionProvider, document } = setup('importcompletions9.svelte');
553+
554+
const completions = await completionProvider.getCompletions(
555+
document,
556+
Position.create(1, 7)
557+
);
558+
document.version++;
559+
560+
const item = completions?.items.find((item) => item.label === 'onMount');
561+
const { additionalTextEdits } = await completionProvider.resolveCompletion(document, item!);
562+
563+
assert.strictEqual(
564+
harmonizeNewLines(additionalTextEdits![0]?.newText),
565+
// " instead of ' because VSCode uses " by default when there are no other imports indicating otherwise
566+
`${newLine}import { onMount } from "svelte";${newLine}${newLine}`
567+
);
568+
569+
assert.deepEqual(
570+
additionalTextEdits![0]?.range,
571+
Range.create(Position.create(0, 25), Position.create(0, 25))
572+
);
573+
});
574+
527575
async function openFileToBeImported(
528576
docManager: DocumentManager,
529577
completionProvider: CompletionsProviderImpl,
@@ -656,7 +704,7 @@ describe('CompletionProviderImpl', () => {
656704
});
657705

658706
it('resolve auto completion in correct place when already imported in module script', async () => {
659-
const { completionProvider, document } = setup('importCompletion8.svelte');
707+
const { completionProvider, document } = setup('importcompletions8.svelte');
660708

661709
const completions = await completionProvider.getCompletions(
662710
document,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script context="module">
2+
onMoun
3+
</script>
4+
5+
<script>
6+
onMoun
7+
</script>

0 commit comments

Comments
 (0)