Skip to content

Commit

Permalink
Support patterns generated by 'Find in Folder'
Browse files Browse the repository at this point in the history
Additionally add support to search outside workspace folders.

Signed-off-by: Alvaro Sanchez-Leon <[email protected]>
  • Loading branch information
alvsan09 committed Apr 8, 2021
1 parent b98c590 commit d2e3b53
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ export class SearchInWorkspaceResultTreeWidget extends TreeWidget {
}
return workspaceRootUri.toString().concat(pattern.replace('./', '/'));
}
return globalPrefix.concat(pattern);

return pattern.startsWith('/') ? '**'.concat(pattern) : globalPrefix.concat(pattern);
}

/**
Expand Down Expand Up @@ -515,16 +516,16 @@ export class SearchInWorkspaceResultTreeWidget extends TreeWidget {

matches.forEach(m => this.appendToResultTree(m));

// Exclude files already covered by searching open editors.
this.editorManager.all.forEach(e => {
const rootUri = this.workspaceService.getWorkspaceRootUri(e.editor.uri);
if (rootUri) {
// Exclude pattern beginning with './' works after the fix of #8469.
const { name, path } = this.filenameAndPath(e.editor.uri.toString(), rootUri.toString());
const excludePath: string = path === '' ? './' + name : path + '/' + name;
searchOptions.exclude = (searchOptions.exclude) ? searchOptions.exclude.concat(excludePath) : [excludePath];
}
});
// TODO: The following optimization is disabled until issue #9319 is resolved
// // Exclude files already covered by searching open editors.
// this.editorManager.all.forEach(e => {
// const rootUri = this.workspaceService.getWorkspaceRootUri(e.editor.uri);
// if (rootUri) {
// const { name, path } = this.filenameAndPath(rootUri.toString(), e.editor.uri.toString());
// const excludePath: string = path === '' ? './' + name : path + '/' + name;
// searchOptions.exclude = (searchOptions.exclude) ? searchOptions.exclude.concat(excludePath) : [excludePath];
// }
// });

// Reduce `maxResults` due to editor results.
if (searchOptions.maxResults) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ export class RipgrepSearchInWorkspaceServer implements SearchInWorkspaceServer {
@inject(RgPath)
protected readonly rgPath: string;

private static readonly GLOB_SUB_DIRECTORY_PATTERN = '**/';
private static readonly GLOB_COMMAND_ARGUMENT = '--glob=';

constructor(
@inject(ILogger) protected readonly logger: ILogger,
@inject(RawProcessFactory) protected readonly rawProcessFactory: RawProcessFactory,
Expand Down Expand Up @@ -148,11 +145,15 @@ export class RipgrepSearchInWorkspaceServer implements SearchInWorkspaceServer {

protected pathToGlobs(inputPath: string, rootFolder: string, exclude: boolean): string[] {
const prefixPattern = (inputPattern: string): string => {
const globalCommandArgument = '--glob=';
const excludeChar = exclude ? '!' : '';
const updatedPattern = inputPattern.startsWith(RipgrepSearchInWorkspaceServer.GLOB_SUB_DIRECTORY_PATTERN) ?
inputPattern : `${RipgrepSearchInWorkspaceServer.GLOB_SUB_DIRECTORY_PATTERN}${inputPattern}`;
const subDirGlobPattern = '**/';

const subDirGlobPrefix = inputPattern.startsWith('/') ? '**' : subDirGlobPattern;
const updatedPattern = inputPattern.startsWith(subDirGlobPattern) ?
inputPattern : `${subDirGlobPrefix}${inputPattern}`;

return `${RipgrepSearchInWorkspaceServer.GLOB_COMMAND_ARGUMENT}${excludeChar}${updatedPattern}`;
return `${globalCommandArgument}${excludeChar}${updatedPattern}`;
};

const toGlobPattern = pathToGlobPattern({
Expand Down Expand Up @@ -180,8 +181,8 @@ export class RipgrepSearchInWorkspaceServer implements SearchInWorkspaceServer {
// we'll use to parse the lines.
const searchId = this.nextSearchId++;
const rootPaths = rootUris.map(root => FileUri.fsPath(root));
const rgArgs = this.getArgs(rootPaths, opts);
const searchPaths: string[] = this.resolveSearchPaths(rootPaths, opts);
const rgArgs = this.getArgs(searchPaths, opts);
// if we use matchWholeWord we use regExp internally,
// so, we need to escape regexp characters if we actually not set regexp true in UI.
if (opts && opts.matchWholeWord && !opts.useRegExp) {
Expand Down Expand Up @@ -344,18 +345,50 @@ export class RipgrepSearchInWorkspaceServer implements SearchInWorkspaceServer {
}

const searchPaths: string[] = [];
const patternPaths: string[] = [];
opts.include.forEach(pattern => {
rootPaths.forEach(root => {
const searchPath = path.join(root, pattern);
let searchPath = path.join(root, pattern);
let isPatternAValidPath = false;
if (fs.existsSync(searchPath)) {
isPatternAValidPath = true;
} else if (fs.existsSync(pattern)) {
searchPath = pattern;
isPatternAValidPath = true;
} else if (pattern.endsWith('**')) {
const patternPath = this.includeSubDirectoriesToPath(pattern);
if (fs.existsSync(patternPath)) {
searchPath = patternPath;
isPatternAValidPath = true;
}
}

if (isPatternAValidPath) {
searchPaths.push(searchPath);
patternPaths.push(pattern);
}
});
});

// Exclude include file patters that were successfully translated to search paths
opts.include = opts.include.filter(item => !patternPaths.includes(item));
return searchPaths.length > 0 ? searchPaths : rootPaths;
}

protected includeSubDirectoriesToPath(pattern: string): string {
const parsedObj = path.parse(pattern);

let resultingPath = pattern;
if (parsedObj.base === '**') {
parsedObj.base = '';
parsedObj.name = '';
const transformed = resultingPath = path.format(parsedObj);
resultingPath = transformed.endsWith(path.sep) ? transformed.slice(0, -1) : transformed;
}

return resultingPath;
}

/**
* Returns the root folder uri that a file belongs to.
* In case that a file belongs to more than one root folders, returns the root folder that is closest to the file.
Expand Down

0 comments on commit d2e3b53

Please sign in to comment.