Skip to content

Commit 57f8706

Browse files
authored
move punctuation methods down in terminal completion sorting order (microsoft#251922)
fix microsoft#251919
1 parent b8aaad0 commit 57f8706

File tree

5 files changed

+51
-11
lines changed

5 files changed

+51
-11
lines changed

src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionItem.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,15 @@ export class TerminalCompletionItem extends SimpleCompletionItem {
8686
labelLowNormalizedPath: string;
8787

8888
/**
89-
* A penalty that applies to files or folders starting with the underscore character.
89+
* The file extension part from {@link labelLow}.
9090
*/
91-
underscorePenalty: 0 | 1 = 0;
91+
fileExtLow: string = '';
9292

9393
/**
94-
* The file extension part from {@link labelLow}.
94+
* A penalty that applies to completions that are comprised of only punctuation characters or
95+
* that applies to files or folders starting with the underscore character.
9596
*/
96-
fileExtLow: string = '';
97+
punctuationPenalty: 0 | 1 = 0;
9798

9899
constructor(
99100
override readonly completion: ITerminalCompletion
@@ -123,11 +124,16 @@ export class TerminalCompletionItem extends SimpleCompletionItem {
123124
if (completion.kind === TerminalCompletionItemKind.Folder) {
124125
this.labelLowNormalizedPath = this.labelLowNormalizedPath.replace(/\/$/, '');
125126
}
126-
this.underscorePenalty = basename(this.labelLowNormalizedPath).startsWith('_') ? 1 : 0;
127127
}
128+
129+
this.punctuationPenalty = shouldPenalizeForPunctuation(this.labelLowExcludeFileExt) ? 1 : 0;
128130
}
129131
}
130132

131133
function isFile(completion: ITerminalCompletion): boolean {
132134
return !!(completion.kind === TerminalCompletionItemKind.File || completion.isFileOverride);
133135
}
136+
137+
function shouldPenalizeForPunctuation(label: string): boolean {
138+
return basename(label).startsWith('_') || /^[\[\]\{\}\(\)\.,;:!?\/\\\-_@#~*%^=$]+$/.test(label);
139+
}

src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionModel.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ const compareCompletionsFn = (leadingLineContent: string, a: TerminalCompletionI
5252
return 1;
5353
}
5454

55-
// Sort by underscore penalty (eg. `__init__/` should be penalized)
56-
if (a.underscorePenalty !== b.underscorePenalty) {
57-
return a.underscorePenalty - b.underscorePenalty;
55+
if (a.punctuationPenalty !== b.punctuationPenalty) {
56+
// Sort by underscore penalty (eg. `__init__/` should be penalized)
57+
// Sort by punctuation penalty (eg. `;` should be penalized)
58+
return a.punctuationPenalty - b.punctuationPenalty;
5859
}
5960

6061
// Sort files of the same name by extension

src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,13 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
194194
if (completions.resourceRequestConfig) {
195195
const resourceCompletions = await this.resolveResources(completions.resourceRequestConfig, promptValue, cursorPosition, provider.id, capabilities, shellType);
196196
if (resourceCompletions) {
197-
completionItems.push(...resourceCompletions);
197+
for (const item of resourceCompletions) {
198+
const labels = new Set(completionItems.map(c => c.label));
199+
// Ensure no duplicates such as .
200+
if (!labels.has(item.label)) {
201+
completionItems.push(item);
202+
}
203+
}
198204
}
199205
}
200206
return completionItems;
@@ -350,7 +356,6 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
350356
break;
351357
}
352358
}
353-
354359
resourceCompletions.push({
355360
label,
356361
provider,

src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest
584584
this._inlineCompletionItem.fileExtLow = x.fileExtLow;
585585
this._inlineCompletionItem.labelLowExcludeFileExt = x.labelLowExcludeFileExt;
586586
this._inlineCompletionItem.labelLowNormalizedPath = x.labelLowNormalizedPath;
587-
this._inlineCompletionItem.underscorePenalty = x.underscorePenalty;
587+
this._inlineCompletionItem.punctuationPenalty = x.punctuationPenalty;
588588
this._inlineCompletionItem.word = x.word;
589589
this._model?.forceRefilterAll();
590590
}

src/vs/workbench/contrib/terminalContrib/suggest/test/browser/terminalCompletionModel.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,34 @@ suite('TerminalCompletionModel', function () {
218218
});
219219
});
220220

221+
suite('Punctuation', () => {
222+
test('punctuation chars should be below other methods', function () {
223+
const items = [
224+
createItem({ label: 'a' }),
225+
createItem({ label: 'b' }),
226+
createItem({ label: ',' }),
227+
createItem({ label: ';' }),
228+
createItem({ label: ':' }),
229+
createItem({ label: 'c' }),
230+
createItem({ label: '[' }),
231+
createItem({ label: '...' }),
232+
];
233+
model = new TerminalCompletionModel(items, new LineContext('', 0));
234+
assertItems(model, ['a', 'b', 'c', ',', ';', ':', '[', '...']);
235+
});
236+
test('punctuation chars should be below other files', function () {
237+
const items = [
238+
createItem({ label: '..' }),
239+
createItem({ label: '...' }),
240+
createItem({ label: '../' }),
241+
createItem({ label: './a/' }),
242+
createItem({ label: './b/' }),
243+
];
244+
model = new TerminalCompletionModel(items, new LineContext('', 0));
245+
assertItems(model, ['./a/', './b/', '..', '...', '../']);
246+
});
247+
});
248+
221249
suite('inline completions', () => {
222250
function createItems(kind: TerminalCompletionItemKind.InlineSuggestion | TerminalCompletionItemKind.InlineSuggestionAlwaysOnTop) {
223251
return [

0 commit comments

Comments
 (0)