mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-16 00:43:20 +01:00
Fix exclude settings to be resolved against their root folder, not the searchPath, mainly for './' search scenarios
This commit is contained in:
@@ -15,6 +15,10 @@ export interface IExpression {
|
||||
[pattern: string]: boolean | SiblingClause | any;
|
||||
}
|
||||
|
||||
export function getEmptyExpression(): IExpression {
|
||||
return Object.create(null);
|
||||
}
|
||||
|
||||
export interface SiblingClause {
|
||||
when: string;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { ISearchService, QueryType } from 'vs/platform/search/common/search';
|
||||
import { ISearchService, QueryType, ISearchQuery } from 'vs/platform/search/common/search';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
@@ -56,13 +56,16 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const search = this._searchService.search({
|
||||
const query: ISearchQuery = {
|
||||
folderQueries: workspace.roots.map(root => ({ folder: root })),
|
||||
type: QueryType.File,
|
||||
maxResults,
|
||||
includePattern: { [include]: true },
|
||||
excludePattern: { [exclude]: true },
|
||||
}).then(result => {
|
||||
};
|
||||
this._searchService.extendQuery(query);
|
||||
|
||||
const search = this._searchService.search(query).then(result => {
|
||||
return result.results.map(m => m.resource);
|
||||
}, err => {
|
||||
if (!isPromiseCanceledError(err)) {
|
||||
|
||||
@@ -45,9 +45,6 @@ export class QueryBuilder {
|
||||
let { searchPaths, includePattern } = this.parseSearchPaths(options.includePattern);
|
||||
let excludePattern = patternListToIExpression(splitGlobPattern(options.excludePattern));
|
||||
|
||||
// if we have searchPaths, then turn them into folderQueries, and get all the excludes for the workspaces, and add them to excludePattern.
|
||||
// If we don't, then turn the folderResources into folderQueries, with their excludes on each one
|
||||
|
||||
// Build folderQueries from searchPaths, if given, otherwise folderResources
|
||||
let folderQueries = folderResources && folderResources.map(uri => this.getFolderQueryForRoot(uri, options));
|
||||
if (searchPaths && searchPaths.length) {
|
||||
|
||||
@@ -92,8 +92,6 @@ suite('QueryBuilder', () => {
|
||||
});
|
||||
|
||||
test('simple include', () => {
|
||||
mockConfigService.setUserConfiguration('search', { useRipgrep: true });
|
||||
|
||||
assertEqualQueries(
|
||||
queryBuilder.text(
|
||||
PATTERN_INFO,
|
||||
@@ -142,7 +140,6 @@ suite('QueryBuilder', () => {
|
||||
const ROOT_3_URI = getUri(ROOT_3);
|
||||
mockWorkspace.roots = [ROOT_1_URI, ROOT_2_URI, ROOT_3_URI];
|
||||
|
||||
mockConfigService.setUserConfiguration('search', { useRipgrep: true });
|
||||
mockConfigService.setUserConfiguration('search', {
|
||||
useRipgrep: true,
|
||||
exclude: { 'foo/**/*.js': true }
|
||||
|
||||
@@ -12,6 +12,7 @@ import fs = require('fs');
|
||||
import path = require('path');
|
||||
import { isEqualOrParent } from 'vs/base/common/paths';
|
||||
import { Readable } from 'stream';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
import scorer = require('vs/base/common/scorer');
|
||||
import objects = require('vs/base/common/objects');
|
||||
@@ -103,10 +104,34 @@ export class FileWalker {
|
||||
}
|
||||
});
|
||||
|
||||
this.folderExcludePatterns.set(folderQuery.folder, glob.parse(folderExcludeExpression, { trimForExclusions: true }));
|
||||
this.folderExcludePatterns.set(folderQuery.folder, this.parseAbsoluteAndRelativeGlobs(folderExcludeExpression, folderQuery.folder));
|
||||
});
|
||||
}
|
||||
|
||||
private parseAbsoluteAndRelativeGlobs(expr: glob.IExpression, root: string): glob.ParsedExpression {
|
||||
let absoluteGlobExpr: glob.IExpression;
|
||||
let relativeGlobExpr: glob.IExpression;
|
||||
Object.keys(expr).forEach(key => {
|
||||
if (path.isAbsolute(key)) {
|
||||
absoluteGlobExpr = absoluteGlobExpr || glob.getEmptyExpression();
|
||||
absoluteGlobExpr[key] = true;
|
||||
} else {
|
||||
relativeGlobExpr = relativeGlobExpr || glob.getEmptyExpression();
|
||||
relativeGlobExpr[key] = true;
|
||||
}
|
||||
});
|
||||
|
||||
const absoluteParsedExpr = absoluteGlobExpr && glob.parse(absoluteGlobExpr, { trimForExclusions: true });
|
||||
const relativeParsedExpr = relativeGlobExpr && glob.parse(relativeGlobExpr, { trimForExclusions: true });
|
||||
|
||||
// The absolute and relative expressions don't "have" to be kept separate, but this keeps us from having to path.join every single
|
||||
// file searched, it's only used for a text search with a searchPath
|
||||
return (_path: string, basename?: string, siblingsFn?: () => string[] | TPromise<string[]>): string | TPromise<string> => {
|
||||
return (relativeParsedExpr && relativeParsedExpr(_path, basename, siblingsFn)) ||
|
||||
(absoluteParsedExpr && absoluteParsedExpr(path.join(root, _path), basename, siblingsFn));
|
||||
};
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.isCanceled = true;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,8 @@ function doRipgrepSearchTest(config: IRawSearch, expectedResultCount: number): T
|
||||
}
|
||||
|
||||
function doSearchTest(config: IRawSearch, expectedResultCount: number, done) {
|
||||
return doRipgrepSearchTest(config, expectedResultCount)
|
||||
return doLegacySearchTest(config, expectedResultCount)
|
||||
.then(() => doRipgrepSearchTest(config, expectedResultCount))
|
||||
.then(done, done);
|
||||
}
|
||||
|
||||
@@ -187,6 +188,26 @@ suite('Search-integration', function () {
|
||||
doSearchTest(config, 382, done);
|
||||
});
|
||||
|
||||
test('Text: e (with absolute path excludes)', function (done: () => void) {
|
||||
const config: any = {
|
||||
folderQueries: ROOT_FOLDER_QUERY,
|
||||
contentPattern: { pattern: 'e' },
|
||||
excludePattern: makeExpression(path.join(TEST_FIXTURES, '**/examples'))
|
||||
};
|
||||
|
||||
doSearchTest(config, 394, done);
|
||||
});
|
||||
|
||||
test('Text: e (with mixed absolute/relative path excludes)', function (done: () => void) {
|
||||
const config: any = {
|
||||
folderQueries: ROOT_FOLDER_QUERY,
|
||||
contentPattern: { pattern: 'e' },
|
||||
excludePattern: makeExpression(path.join(TEST_FIXTURES, '**/examples'), '*.css')
|
||||
};
|
||||
|
||||
doSearchTest(config, 310, done);
|
||||
});
|
||||
|
||||
test('Text: sibling exclude', function (done: () => void) {
|
||||
const config: any = {
|
||||
folderQueries: ROOT_FOLDER_QUERY,
|
||||
|
||||
Reference in New Issue
Block a user