Skip to content

Commit 5fe3f97

Browse files
committed
Pre-support for backeted property completions in js/ts
Requires a build of TS with microsoft/TypeScript#20547 Fixes #36429 Also relaxes the matching logic for suggestion items with filter texts
1 parent 6195524 commit 5fe3f97

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

extensions/typescript/src/features/completionItemProvider.ts

+20-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ class MyCompletionItem extends CompletionItem {
5353
this.range = tsTextSpanToVsRange(tsEntry.replacementSpan);
5454
}
5555

56+
if (typeof (tsEntry as any).insertText === 'string') {
57+
this.insertText = (tsEntry as any).insertText as string;
58+
59+
if (tsEntry.replacementSpan) {
60+
this.range = tsTextSpanToVsRange(tsEntry.replacementSpan);
61+
if (this.insertText[0] === '[') { // o.x -> o['x']
62+
this.filterText = '.' + this.label;
63+
}
64+
}
65+
}
66+
5667
if (tsEntry.kindModifiers.match(/\boptional\b/)) {
5768
this.insertText = this.label;
5869
this.filterText = this.label;
@@ -275,8 +286,9 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
275286
try {
276287
const args: Proto.CompletionsRequestArgs = {
277288
...vsPositionToTsFileLocation(file, position),
278-
includeExternalModuleExports: config.autoImportSuggestions
279-
};
289+
includeExternalModuleExports: config.autoImportSuggestions,
290+
includeInsertTextCompletions: true
291+
} as Proto.CompletionsRequestArgs;
280292
const msg = await this.client.execute('completions', args, token);
281293
// This info has to come from the tsserver. See https://github.com/Microsoft/TypeScript/issues/2831
282294
// let isMemberCompletion = false;
@@ -402,7 +414,7 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
402414
if (detail && item.useCodeSnippet) {
403415
const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position);
404416
if (shouldCompleteFunction) {
405-
item.insertText = this.snippetForFunctionCall(detail);
417+
item.insertText = this.snippetForFunctionCall(item, detail);
406418
}
407419
return item;
408420
}
@@ -430,12 +442,15 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
430442
}
431443
}
432444

433-
private snippetForFunctionCall(detail: Proto.CompletionEntryDetails): SnippetString {
445+
private snippetForFunctionCall(
446+
item: CompletionItem,
447+
detail: Proto.CompletionEntryDetails
448+
): SnippetString {
434449
let hasOptionalParameters = false;
435450
let hasAddedParameters = false;
436451

437452
const snippet = new SnippetString();
438-
snippet.appendText(detail.name);
453+
snippet.appendText(item.label || item.insertText as string);
439454
snippet.appendText('(');
440455

441456
let parenCount = 0;

src/vs/base/common/filters.ts

+16
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,22 @@ export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSep
341341
return enableSeparateSubstringMatching ? fuzzySeparateFilter(word, wordToMatchAgainst) : fuzzyContiguousFilter(word, wordToMatchAgainst);
342342
}
343343

344+
export function skipScore(pattern: string, word: string, patternMaxWhitespaceIgnore?: number): [number, number[]] {
345+
pattern = pattern.toLowerCase();
346+
word = word.toLowerCase();
347+
348+
const matches: number[] = [];
349+
let idx = 0;
350+
for (let pos = 0; pos < pattern.length; ++pos) {
351+
const thisIdx = word.indexOf(pattern.charAt(pos), idx);
352+
if (thisIdx >= 0) {
353+
matches.push(thisIdx);
354+
idx = thisIdx + 1;
355+
}
356+
}
357+
return [matches.length, matches];
358+
}
359+
344360
//#region --- fuzzyScore ---
345361

346362
export function createMatches(position: number[]): IMatch[] {

src/vs/editor/contrib/suggest/completionModel.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
'use strict';
77

8-
import { fuzzyScore, fuzzyScoreGracefulAggressive } from 'vs/base/common/filters';
8+
import { fuzzyScore, fuzzyScoreGracefulAggressive, skipScore } from 'vs/base/common/filters';
99
import { ISuggestSupport, ISuggestResult } from 'vs/editor/common/modes';
1010
import { ISuggestionItem, SnippetConfig } from './suggest';
1111
import { isDisposable } from 'vs/base/common/lifecycle';
@@ -185,11 +185,8 @@ export class CompletionModel {
185185
continue;
186186
}
187187
item.score = match[0];
188-
item.matches = [];
189-
match = scoreFn(word, suggestion.label, suggestion.overwriteBefore);
190-
if (match) {
191-
item.matches = match[1];
192-
}
188+
item.matches = skipScore(word, suggestion.label)[1];
189+
193190
} else {
194191
// by default match `word` against the `label`
195192
let match = scoreFn(word, suggestion.label, suggestion.overwriteBefore);

0 commit comments

Comments
 (0)