Skip to content

Commit

Permalink
tweak terminal suggest sorting for files/folders (#239145)
Browse files Browse the repository at this point in the history
  • Loading branch information
meganrogge authored Jan 30, 2025
1 parent a0a4332 commit 4e144a1
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 95 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import { events as windows11_pwsh_filename_same_case_change_forward_slash } from
import { events as windows11_pwsh_getcontent_delete_ghost } from './recordings/windows11_pwsh_getcontent_delete_ghost.js';
import { events as windows11_pwsh_input_ls_complete_ls } from './recordings/windows11_pwsh_input_ls_complete_ls.js';
import { events as windows11_pwsh_namespace_same_prefix } from './recordings/windows11_pwsh_namespace_same_prefix.js';
import { events as windows11_pwsh_single_char } from './recordings/windows11_pwsh_single_char.js';
import { events as windows11_pwsh_type_before_prompt } from './recordings/windows11_pwsh_type_before_prompt.js';
import { events as windows11_pwsh_writehost_multiline } from './recordings/windows11_pwsh_writehost_multiline.js';
import { events as windows11_pwsh_writehost_multiline_nav_up } from './recordings/windows11_pwsh_writehost_multiline_nav_up.js';
Expand All @@ -60,7 +59,6 @@ const recordedTestCases: { name: string; events: RecordedSessionEvent[] }[] = [
{ name: 'windows11_pwsh_getcontent_delete_ghost', events: windows11_pwsh_getcontent_delete_ghost as any as RecordedSessionEvent[] },
{ name: 'windows11_pwsh_input_ls_complete_ls', events: windows11_pwsh_input_ls_complete_ls as any as RecordedSessionEvent[] },
{ name: 'windows11_pwsh_namespace_same_prefix', events: windows11_pwsh_namespace_same_prefix as any as RecordedSessionEvent[] },
{ name: 'windows11_pwsh_single_char', events: windows11_pwsh_single_char as any as RecordedSessionEvent[] },
{ name: 'windows11_pwsh_type_before_prompt', events: windows11_pwsh_type_before_prompt as any as RecordedSessionEvent[] },
{ name: 'windows11_pwsh_writehost_multiline_nav_up', events: windows11_pwsh_writehost_multiline_nav_up as any as RecordedSessionEvent[] },
{ name: 'windows11_pwsh_writehost_multiline', events: windows11_pwsh_writehost_multiline as any as RecordedSessionEvent[] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,25 @@ export interface ISimpleCompletion {
}

export class SimpleCompletionItem {
// perf
/**
* The lowercase label, normalized to `\` path separators on Windows.
*/
readonly labelLow: string;

/**
* {@link labelLow} without the file extension.
*/
readonly labelLowExcludeFileExt: string;

/**
* The lowercase label, when the completion is a file or directory this has normalized path
* separators (/) on Windows and no trailing separator for directories.
*/
readonly labelLowNormalizedPath: string;

/**
* The file extension part from {@link labelLow}.
*/
readonly fileExtLow: string = '';

// sorting, filtering
Expand All @@ -73,6 +89,8 @@ export class SimpleCompletionItem {
// ensure lower-variants (perf)
this.labelLow = this.completion.label.toLowerCase();
this.labelLowExcludeFileExt = this.labelLow;
this.labelLowNormalizedPath = this.labelLow;

if (completion.isFile) {
if (isWindows) {
this.labelLow = this.labelLow.replaceAll('/', '\\');
Expand All @@ -83,5 +101,14 @@ export class SimpleCompletionItem {
this.fileExtLow = this.labelLow.substring(extIndex + 1);
}
}

if (completion.isFile || completion.isDirectory) {
if (isWindows) {
this.labelLowNormalizedPath = this.labelLow.replaceAll('\\', '/');
}
if (completion.isDirectory) {
this.labelLowNormalizedPath = this.labelLowNormalizedPath.replace(/\/$/, '');
}
}
}
}
25 changes: 21 additions & 4 deletions src/vs/workbench/services/suggest/browser/simpleCompletionModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { quickSelect } from '../../../../base/common/arrays.js';
import { CharCode } from '../../../../base/common/charCode.js';
import { FuzzyScore, fuzzyScore, fuzzyScoreGracefulAggressive, FuzzyScoreOptions, FuzzyScorer } from '../../../../base/common/filters.js';
import { isWindows } from '../../../../base/common/platform.js';
import { count } from '../../../../base/common/strings.js';

export interface ISimpleCompletionStats {
pLabelLen: number;
Expand Down Expand Up @@ -207,12 +208,28 @@ export class SimpleCompletionModel {
}
// Then by file extension length ascending
score = a.fileExtLow.length - b.fileExtLow.length;
if (score !== 0) {
return score;
}
}
if (score === 0 || fileExtScore(a.fileExtLow) === 0 && fileExtScore(b.fileExtLow) === 0) {
// both files or directories, sort alphabetically
score = a.completion.label.localeCompare(b.completion.label);
if (a.labelLowNormalizedPath && b.labelLowNormalizedPath) {
// Directories
// Count depth of path (number of / or \ occurrences)
score = count(a.labelLowNormalizedPath, '/') - count(b.labelLowNormalizedPath, '/');
if (score !== 0) {
return score;
}

// Ensure shorter prefixes appear first
if (b.labelLowNormalizedPath.startsWith(a.labelLowNormalizedPath)) {
return -1; // `a` is a prefix of `b`, so `a` should come first
}
if (a.labelLowNormalizedPath.startsWith(b.labelLowNormalizedPath)) {
return 1; // `b` is a prefix of `a`, so `b` should come first
}
}
return score;
// Sort alphabetically
return a.labelLow.localeCompare(b.labelLow);
});
this._refilterKind = Refilter.Nothing;

Expand Down

0 comments on commit 4e144a1

Please sign in to comment.