mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-20 02:08:47 +00:00
Merge remote-tracking branch 'origin/main' into dev/dmitriv/finalize-button-location-api
This commit is contained in:
@@ -322,7 +322,7 @@ function doScoreFuzzy2Multiple(target: string, query: IPreparedQueryPiece[], pat
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doScoreFuzzy2Single(target: string, query: IPreparedQueryPiece, patternStart: number, wordStart: number): FuzzyScore2 {
|
function doScoreFuzzy2Single(target: string, query: IPreparedQueryPiece, patternStart: number, wordStart: number): FuzzyScore2 {
|
||||||
const score = fuzzyScore(query.original, query.originalLowercase, patternStart, target, target.toLowerCase(), wordStart, { firstMatchCanBeWeak: true, boostFullMatch: true });
|
const score = fuzzyScore(query.normalized, query.normalizedLowercase, patternStart, target, target.toLowerCase(), wordStart, { firstMatchCanBeWeak: true, boostFullMatch: true });
|
||||||
if (!score) {
|
if (!score) {
|
||||||
return NO_SCORE2;
|
return NO_SCORE2;
|
||||||
}
|
}
|
||||||
@@ -811,7 +811,7 @@ export interface IPreparedQueryPiece {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* In addition to the normalized path, will have
|
* In addition to the normalized path, will have
|
||||||
* whitespace and wildcards removed.
|
* whitespace, wildcards, quotes, ellipsis, and trailing hash characters removed.
|
||||||
*/
|
*/
|
||||||
normalized: string;
|
normalized: string;
|
||||||
normalizedLowercase: string;
|
normalizedLowercase: string;
|
||||||
@@ -905,7 +905,8 @@ function normalizeQuery(original: string): { pathNormalized: string; normalized:
|
|||||||
// - wildcards: are used for fuzzy matching
|
// - wildcards: are used for fuzzy matching
|
||||||
// - whitespace: are used to separate queries
|
// - whitespace: are used to separate queries
|
||||||
// - ellipsis: sometimes used to indicate any path segments
|
// - ellipsis: sometimes used to indicate any path segments
|
||||||
const normalized = pathNormalized.replace(/[\*\u2026\s"]/g, '');
|
// - trailing hash: used by some language servers (e.g. rust-analyzer) as query modifiers
|
||||||
|
const normalized = pathNormalized.replace(/[\*\u2026\s"]/g, '').replace(/(?<=.)#$/, '');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pathNormalized,
|
pathNormalized,
|
||||||
|
|||||||
@@ -1141,6 +1141,10 @@ suite('Fuzzy Scorer', () => {
|
|||||||
test('prepareQuery', () => {
|
test('prepareQuery', () => {
|
||||||
assert.strictEqual(prepareQuery(' f*a ').normalized, 'fa');
|
assert.strictEqual(prepareQuery(' f*a ').normalized, 'fa');
|
||||||
assert.strictEqual(prepareQuery(' f…a ').normalized, 'fa');
|
assert.strictEqual(prepareQuery(' f…a ').normalized, 'fa');
|
||||||
|
assert.strictEqual(prepareQuery('main#').normalized, 'main');
|
||||||
|
assert.strictEqual(prepareQuery('main#').original, 'main#');
|
||||||
|
assert.strictEqual(prepareQuery('foo*').normalized, 'foo');
|
||||||
|
assert.strictEqual(prepareQuery('foo*').original, 'foo*');
|
||||||
assert.strictEqual(prepareQuery('model Tester.ts').original, 'model Tester.ts');
|
assert.strictEqual(prepareQuery('model Tester.ts').original, 'model Tester.ts');
|
||||||
assert.strictEqual(prepareQuery('model Tester.ts').originalLowercase, 'model Tester.ts'.toLowerCase());
|
assert.strictEqual(prepareQuery('model Tester.ts').originalLowercase, 'model Tester.ts'.toLowerCase());
|
||||||
assert.strictEqual(prepareQuery('model Tester.ts').normalized, 'modelTester.ts');
|
assert.strictEqual(prepareQuery('model Tester.ts').normalized, 'modelTester.ts');
|
||||||
@@ -1295,5 +1299,59 @@ suite('Fuzzy Scorer', () => {
|
|||||||
assert.strictEqual(score[1][1], 8);
|
assert.strictEqual(score[1][1], 8);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Workspace symbol search with special characters (#, *)', function () {
|
||||||
|
// Simulates the scenario from the issue where rust-analyzer uses # and * as query modifiers
|
||||||
|
// The original query (with special chars) should reach the language server
|
||||||
|
// but normalized query (without special chars) should be used for fuzzy matching
|
||||||
|
|
||||||
|
// Test #: User types "main#", language server returns "main" symbol
|
||||||
|
let query = prepareQuery('main#');
|
||||||
|
assert.strictEqual(query.original, 'main#'); // Sent to language server
|
||||||
|
assert.strictEqual(query.normalized, 'main'); // Used for fuzzy matching
|
||||||
|
let [score, matches] = _doScore2('main', 'main#');
|
||||||
|
assert.ok(typeof score === 'number' && score > 0, 'Should match "main" symbol when query is "main#"');
|
||||||
|
assert.ok(matches.length > 0);
|
||||||
|
|
||||||
|
// Test *: User types "foo*", language server returns "foo" symbol
|
||||||
|
query = prepareQuery('foo*');
|
||||||
|
assert.strictEqual(query.original, 'foo*'); // Sent to language server
|
||||||
|
assert.strictEqual(query.normalized, 'foo'); // Used for fuzzy matching
|
||||||
|
[score, matches] = _doScore2('foo', 'foo*');
|
||||||
|
assert.ok(typeof score === 'number' && score > 0, 'Should match "foo" symbol when query is "foo*"');
|
||||||
|
assert.ok(matches.length > 0);
|
||||||
|
|
||||||
|
// Test both: User types "MyClass#*", should match "MyClass"
|
||||||
|
query = prepareQuery('MyClass#*');
|
||||||
|
assert.strictEqual(query.original, 'MyClass#*');
|
||||||
|
assert.strictEqual(query.normalized, 'MyClass');
|
||||||
|
[score, matches] = _doScore2('MyClass', 'MyClass#*');
|
||||||
|
assert.ok(typeof score === 'number' && score > 0, 'Should match "MyClass" symbol when query is "MyClass#*"');
|
||||||
|
assert.ok(matches.length > 0);
|
||||||
|
|
||||||
|
// Test fuzzy matching still works: User types "MC#", should match "MyClass"
|
||||||
|
query = prepareQuery('MC#');
|
||||||
|
assert.strictEqual(query.original, 'MC#');
|
||||||
|
assert.strictEqual(query.normalized, 'MC');
|
||||||
|
[score, matches] = _doScore2('MyClass', 'MC#');
|
||||||
|
assert.ok(typeof score === 'number' && score > 0, 'Should fuzzy match "MyClass" symbol when query is "MC#"');
|
||||||
|
assert.ok(matches.length > 0);
|
||||||
|
|
||||||
|
// Make sure leading # or # in the middle are not removed.
|
||||||
|
query = prepareQuery('#SpecialFunction');
|
||||||
|
assert.strictEqual(query.original, '#SpecialFunction');
|
||||||
|
assert.strictEqual(query.normalized, '#SpecialFunction');
|
||||||
|
[score, matches] = _doScore2('#SpecialFunction', '#SpecialFunction');
|
||||||
|
assert.ok(typeof score === 'number' && score > 0, 'Should match "#SpecialFunction" symbol when query is "#SpecialFunction"');
|
||||||
|
assert.ok(matches.length > 0);
|
||||||
|
|
||||||
|
// Make sure standalone # is not removed
|
||||||
|
query = prepareQuery('#');
|
||||||
|
assert.strictEqual(query.original, '#');
|
||||||
|
assert.strictEqual(query.normalized, '#', 'Standalone # should not be removed');
|
||||||
|
[score, matches] = _doScore2('#', '#');
|
||||||
|
assert.ok(typeof score === 'number' && score > 0, 'Should match "#" symbol when query is "#"');
|
||||||
|
assert.ok(matches.length > 0);
|
||||||
|
});
|
||||||
|
|
||||||
ensureNoDisposablesAreLeakedInTestSuite();
|
ensureNoDisposablesAreLeakedInTestSuite();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -175,8 +175,6 @@ export class DetachedTerminalCommandMirror extends DetachedTerminalMirror implem
|
|||||||
return { lineCount: 0 };
|
return { lineCount: 0 };
|
||||||
}
|
}
|
||||||
const detached = await this._getTerminal();
|
const detached = await this._getTerminal();
|
||||||
detached.xterm.clearBuffer();
|
|
||||||
detached.xterm.clearSearchDecorations?.();
|
|
||||||
await new Promise<void>(resolve => {
|
await new Promise<void>(resolve => {
|
||||||
detached.xterm.write(vt.text, () => resolve());
|
detached.xterm.write(vt.text, () => resolve());
|
||||||
});
|
});
|
||||||
@@ -238,8 +236,6 @@ export class DetachedTerminalSnapshotMirror extends DetachedTerminalMirror {
|
|||||||
return { lineCount: this._lastRenderedLineCount ?? output.lineCount };
|
return { lineCount: this._lastRenderedLineCount ?? output.lineCount };
|
||||||
}
|
}
|
||||||
const terminal = await this._getTerminal();
|
const terminal = await this._getTerminal();
|
||||||
terminal.xterm.clearBuffer();
|
|
||||||
terminal.xterm.clearSearchDecorations?.();
|
|
||||||
if (this._container) {
|
if (this._container) {
|
||||||
this._applyTheme(this._container);
|
this._applyTheme(this._container);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user