Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ripgrep search provider to work for files backed by file scheme, but not file scheme themselves (vscode-userdata) #118069

Merged
merged 3 commits into from Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/vs/workbench/api/node/extHostSearch.ts
Expand Up @@ -35,13 +35,15 @@ export class NativeExtHostSearch extends ExtHostSearch {
) {
super(extHostRpc, _uriTransformer, _logService);

const outputChannel = new OutputChannel('RipgrepSearchUD', this._logService);
this.registerTextSearchProvider(Schemas.userData, new RipgrepSearchProvider(outputChannel));
if (initData.remote.isRemote && initData.remote.authority) {
this._registerEHSearchProviders();
}
}

private _registerEHSearchProviders(): void {
const outputChannel = new OutputChannel(this._logService);
const outputChannel = new OutputChannel('RipgrepSearchEH', this._logService);
this.registerTextSearchProvider(Schemas.file, new RipgrepSearchProvider(outputChannel));
this.registerInternalFileSearchProvider(Schemas.file, new SearchService());
}
Expand Down Expand Up @@ -101,4 +103,3 @@ export class NativeExtHostSearch extends ExtHostSearch {
return new NativeTextSearchManager(query, provider);
}
}

3 changes: 1 addition & 2 deletions src/vs/workbench/contrib/search/common/queryBuilder.ts
Expand Up @@ -211,8 +211,7 @@ export class QueryBuilder {

const providerExists = isAbsolutePath(file);
// Special case userdata as we don't have a search provider for it, but it can be searched.
const isUserdata = file.scheme === Schemas.userData;
if (providerExists && !isUserdata) {
if (providerExists) {
const searchRoot = this.workspaceContextService.getWorkspaceFolder(file)?.uri ?? file.with({ path: path.dirname(file.fsPath) });

let folderQuery = foldersToSearch.get(searchRoot);
Expand Down
13 changes: 11 additions & 2 deletions src/vs/workbench/services/search/node/ripgrepSearchProvider.ts
Expand Up @@ -8,6 +8,7 @@ import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUt
import { RipgrepTextSearchEngine } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine';
import { TextSearchProvider, TextSearchComplete, TextSearchResult, TextSearchQuery, TextSearchOptions } from 'vs/workbench/services/search/common/searchExtTypes';
import { Progress } from 'vs/platform/progress/common/progress';
import { Schemas } from 'vs/base/common/network';

export class RipgrepSearchProvider implements TextSearchProvider {
private inProgress: Set<CancellationTokenSource> = new Set();
Expand All @@ -18,7 +19,15 @@ export class RipgrepSearchProvider implements TextSearchProvider {

provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): Promise<TextSearchComplete> {
const engine = new RipgrepTextSearchEngine(this.outputChannel);
return this.withToken(token, token => engine.provideTextSearchResults(query, options, progress, token));
if (options.folder.scheme === Schemas.userData) {
// Ripgrep search engine can only provide file-scheme results, but we want to use it to search some schemes that are backed by the filesystem, but with some other provider as the frontend,
// case in point vscode-userdata. In these cases we translate the query to a file, and translate the results back to the frontend scheme.
const translatedOptions = { ...options, folder: options.folder.with({ scheme: Schemas.file }) };
const progressTranslator = new Progress<TextSearchResult>(data => progress.report({ ...data, uri: data.uri.with({ scheme: options.folder.scheme }) }));
return this.withToken(token, token => engine.provideTextSearchResults(query, translatedOptions, progressTranslator, token));
} else {
return this.withToken(token, token => engine.provideTextSearchResults(query, options, progress, token));
}
}

private async withToken<T>(token: CancellationToken, fn: (token: CancellationToken) => Promise<T>): Promise<T> {
Expand All @@ -40,4 +49,4 @@ function mergedTokenSource(token: CancellationToken): CancellationTokenSource {
token.onCancellationRequested(() => tokenSource.cancel());

return tokenSource;
}
}
4 changes: 2 additions & 2 deletions src/vs/workbench/services/search/node/ripgrepSearchUtils.ts
Expand Up @@ -46,9 +46,9 @@ export interface IOutputChannel {
}

export class OutputChannel implements IOutputChannel {
constructor(@ILogService private readonly logService: ILogService) { }
constructor(private prefix: string, @ILogService private readonly logService: ILogService) { }

appendLine(msg: string): void {
this.logService.debug('RipgrepSearchEH#search', msg);
this.logService.debug(`${this.prefix}#search`, msg);
}
}