mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00:00
Allow searching with a ./ path in a workspace folder that has a slash in its name
Fix #99512
This commit is contained in:
parent
bc04b1c04b
commit
f19a2c969b
|
@ -12,7 +12,7 @@ import { Schemas } from 'vs/base/common/network';
|
|||
import * as path from 'vs/base/common/path';
|
||||
import { isEqual, basename, relativePath, isAbsolutePath } from 'vs/base/common/resources';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { assertIsDefined, isDefined } from 'vs/base/common/types';
|
||||
import { URI, URI as uri } from 'vs/base/common/uri';
|
||||
import { isMultilineRegexSource } from 'vs/editor/common/model/textModelSearch';
|
||||
import * as nls from 'vs/nls';
|
||||
|
@ -415,29 +415,33 @@ export class QueryBuilder {
|
|||
} else if (searchPath === './' || searchPath === '.\\') {
|
||||
return []; // ./ or ./**/foo makes sense for single-folder but not multi-folder workspaces
|
||||
} else {
|
||||
const relativeSearchPathMatch = searchPath.match(/\.[\/\\]([^\/\\]+)(?:[\/\\](.+))?/);
|
||||
if (relativeSearchPathMatch) {
|
||||
const searchPathRoot = relativeSearchPathMatch[1];
|
||||
const matchingRoots = this.workspaceContextService.getWorkspace().folders.filter(folder => folder.name === searchPathRoot);
|
||||
if (matchingRoots.length) {
|
||||
return matchingRoots.map(root => {
|
||||
const patternMatch = relativeSearchPathMatch[2];
|
||||
return {
|
||||
searchPath: root.uri,
|
||||
pattern: patternMatch && normalizeGlobPattern(patternMatch)
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// No root folder with name
|
||||
const searchPathNotFoundError = nls.localize('search.noWorkspaceWithName', "Workspace folder does not exist: {0}", searchPathRoot);
|
||||
throw new Error(searchPathNotFoundError);
|
||||
}
|
||||
const searchPathWithoutDotSlash = searchPath.replace(/^\.[\/\\]/, '');
|
||||
const folders = this.workspaceContextService.getWorkspace().folders;
|
||||
const folderMatches = folders.map(folder => {
|
||||
const match = searchPathWithoutDotSlash.match(new RegExp(`^${folder.name}(?:/(.*))?`));
|
||||
return match ? {
|
||||
match,
|
||||
folder
|
||||
} : null;
|
||||
}).filter(isDefined);
|
||||
|
||||
if (folderMatches.length) {
|
||||
return folderMatches.map(match => {
|
||||
const patternMatch = match.match[1];
|
||||
return {
|
||||
searchPath: match.folder.uri,
|
||||
pattern: patternMatch && normalizeGlobPattern(patternMatch)
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// Malformed ./ search path, ignore
|
||||
const probableWorkspaceFolderNameMatch = searchPath.match(/\.[\/\\](.+)[\/\\]?/);
|
||||
const probableWorkspaceFolderName = probableWorkspaceFolderNameMatch ? probableWorkspaceFolderNameMatch[1] : searchPath;
|
||||
|
||||
// No root folder with name
|
||||
const searchPathNotFoundError = nls.localize('search.noWorkspaceWithName', "Workspace folder does not exist: {0}", probableWorkspaceFolderName);
|
||||
throw new Error(searchPathNotFoundError);
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private resolveOneSearchPathPattern(oneExpandedResult: IOneSearchPathPattern, globPortion?: string): IOneSearchPathPattern[] {
|
||||
|
|
|
@ -573,8 +573,15 @@ suite('QueryBuilder', () => {
|
|||
});
|
||||
|
||||
function testIncludes(includePattern: string, expectedResult: ISearchPathsInfo): void {
|
||||
let actual: ISearchPathsInfo;
|
||||
try {
|
||||
actual = queryBuilder.parseSearchPaths(includePattern);
|
||||
} catch (_) {
|
||||
actual = { searchPaths: [] };
|
||||
}
|
||||
|
||||
assertEqualSearchPathResults(
|
||||
queryBuilder.parseSearchPaths(includePattern),
|
||||
actual,
|
||||
expectedResult,
|
||||
includePattern);
|
||||
}
|
||||
|
@ -799,6 +806,42 @@ suite('QueryBuilder', () => {
|
|||
cases.forEach(testIncludesDataItem);
|
||||
});
|
||||
|
||||
test('folder with slash in the name', () => {
|
||||
const ROOT_2 = '/project/root2';
|
||||
const ROOT_2_URI = getUri(ROOT_2);
|
||||
const ROOT_1_FOLDERNAME = 'folder/one';
|
||||
const ROOT_2_FOLDERNAME = 'folder/two';
|
||||
mockWorkspace.folders = toWorkspaceFolders([{ path: ROOT_1_URI.fsPath, name: ROOT_1_FOLDERNAME }, { path: ROOT_2_URI.fsPath, name: ROOT_2_FOLDERNAME }], WS_CONFIG_PATH, extUriBiasedIgnorePathCase);
|
||||
mockWorkspace.configuration = uri.file(fixPath('config'));
|
||||
|
||||
const cases: [string, ISearchPathsInfo][] = [
|
||||
[
|
||||
'./folder/one',
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: ROOT_1_URI
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
'./folder/two/foo/',
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: ROOT_2_URI,
|
||||
pattern: patternsToIExpression('foo', 'foo/**')
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
'./folder',
|
||||
{
|
||||
searchPaths: []
|
||||
}
|
||||
]
|
||||
];
|
||||
cases.forEach(testIncludesDataItem);
|
||||
});
|
||||
|
||||
test('relative includes w/multiple ambiguous root folders', () => {
|
||||
const ROOT_2 = '/project/rootB';
|
||||
const ROOT_3 = '/otherproject/rootB';
|
||||
|
|
Loading…
Reference in a new issue