mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 03:29:00 +01:00
Split text and file search interfaces
This commit is contained in:
@@ -24,7 +24,7 @@ import { LabelRules } from 'vs/platform/label/common/label';
|
||||
import { LogLevel } from 'vs/platform/log/common/log';
|
||||
import { IMarkerData } from 'vs/platform/markers/common/markers';
|
||||
import { IPickOptions, IQuickInputButton, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IPatternInfo, IQueryOptions, IRawFileMatch2, IRawSearchQuery, ISearchCompleteStats } from 'vs/platform/search/common/search';
|
||||
import { IPatternInfo, IRawFileMatch2, IRawQuery, ISearchCompleteStats, IRawTextQuery } from 'vs/platform/search/common/search';
|
||||
import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
@@ -41,6 +41,7 @@ import { IProgressOptions, IProgressStep } from 'vs/workbench/services/progress/
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import * as vscode from 'vscode';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ITextQueryBuilderOptions } from 'vs/workbench/parts/search/common/queryBuilder';
|
||||
|
||||
export interface IEnvironment {
|
||||
isExtensionDevelopmentDebug: boolean;
|
||||
@@ -482,7 +483,7 @@ export interface ExtHostUrlsShape {
|
||||
|
||||
export interface MainThreadWorkspaceShape extends IDisposable {
|
||||
$startFileSearch(includePattern: string, includeFolder: URI, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Thenable<UriComponents[]>;
|
||||
$startTextSearch(query: IPatternInfo, options: IQueryOptions, requestId: number, token: CancellationToken): Thenable<vscode.TextSearchComplete>;
|
||||
$startTextSearch(query: IPatternInfo, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Thenable<vscode.TextSearchComplete>;
|
||||
$checkExists(includes: string[], token: CancellationToken): Thenable<boolean>;
|
||||
$saveAll(includeUntitled?: boolean): Thenable<boolean>;
|
||||
$updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string }[]): Thenable<void>;
|
||||
@@ -707,9 +708,9 @@ export interface ExtHostFileSystemShape {
|
||||
}
|
||||
|
||||
export interface ExtHostSearchShape {
|
||||
$provideFileSearchResults(handle: number, session: number, query: IRawSearchQuery, token: CancellationToken): Thenable<ISearchCompleteStats>;
|
||||
$provideFileSearchResults(handle: number, session: number, query: IRawQuery, token: CancellationToken): Thenable<ISearchCompleteStats>;
|
||||
$provideTextSearchResults(handle: number, session: number, query: IRawTextQuery, token: CancellationToken): Thenable<ISearchCompleteStats>;
|
||||
$clearCache(cacheKey: string): Thenable<void>;
|
||||
$provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, query: IRawSearchQuery, token: CancellationToken): Thenable<ISearchCompleteStats>;
|
||||
}
|
||||
|
||||
export interface ExtHostExtensionServiceShape {
|
||||
|
||||
@@ -15,7 +15,7 @@ import * as strings from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer';
|
||||
import { ICachedSearchStats, IFileIndexProviderStats, IFileMatch, IFileSearchStats, IFolderQuery, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search';
|
||||
import { ICachedSearchStats, IFileIndexProviderStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchCompleteStats } from 'vs/platform/search/common/search';
|
||||
import { IDirectoryEntry, IDirectoryTree, IInternalFileMatch } from 'vs/workbench/services/search/node/fileSearchManager';
|
||||
import { QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/node/search';
|
||||
import * as vscode from 'vscode';
|
||||
@@ -43,7 +43,7 @@ export class FileIndexSearchEngine {
|
||||
|
||||
private globalExcludePattern: glob.ParsedExpression;
|
||||
|
||||
constructor(private config: ISearchQuery, private provider: vscode.FileIndexProvider) {
|
||||
constructor(private config: IFileQuery, private provider: vscode.FileIndexProvider) {
|
||||
this.filePattern = config.filePattern;
|
||||
this.includePattern = config.includePattern && glob.parse(config.includePattern);
|
||||
this.maxResults = config.maxResults || null;
|
||||
@@ -190,9 +190,9 @@ export class FileIndexSearchEngine {
|
||||
folder: fq.folder,
|
||||
excludes,
|
||||
includes,
|
||||
useIgnoreFiles: !this.config.disregardIgnoreFiles,
|
||||
useGlobalIgnoreFiles: !this.config.disregardGlobalIgnoreFiles,
|
||||
followSymlinks: !this.config.ignoreSymlinks
|
||||
useIgnoreFiles: !fq.disregardIgnoreFiles,
|
||||
useGlobalIgnoreFiles: !fq.disregardGlobalIgnoreFiles,
|
||||
followSymlinks: !fq.ignoreSymlinks
|
||||
};
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ export class FileIndexSearchManager {
|
||||
|
||||
private readonly folderCacheKeys = new Map<string, Set<string>>();
|
||||
|
||||
public fileSearch(config: ISearchQuery, provider: vscode.FileIndexProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): TPromise<ISearchCompleteStats> {
|
||||
public fileSearch(config: IFileQuery, provider: vscode.FileIndexProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): TPromise<ISearchCompleteStats> {
|
||||
if (config.sortByScore) {
|
||||
let sortedSearch = this.trySortedSearchFromCache(config, token);
|
||||
if (!sortedSearch) {
|
||||
@@ -341,7 +341,7 @@ export class FileIndexSearchManager {
|
||||
});
|
||||
}
|
||||
|
||||
private getFolderCacheKey(config: ISearchQuery): string {
|
||||
private getFolderCacheKey(config: IFileQuery): string {
|
||||
const uri = config.folderQueries[0].folder.toString();
|
||||
const folderCacheKey = config.cacheKey && `${uri}_${config.cacheKey}`;
|
||||
if (!this.folderCacheKeys.get(config.cacheKey)) {
|
||||
@@ -359,7 +359,7 @@ export class FileIndexSearchManager {
|
||||
};
|
||||
}
|
||||
|
||||
private doSortedSearch(engine: FileIndexSearchEngine, config: ISearchQuery, token: CancellationToken): TPromise<IInternalSearchComplete> {
|
||||
private doSortedSearch(engine: FileIndexSearchEngine, config: IFileQuery, token: CancellationToken): TPromise<IInternalSearchComplete> {
|
||||
let allResultsPromise = createCancelablePromise<IInternalSearchComplete<IFileIndexProviderStats>>(token => {
|
||||
return this.doSearch(engine, token);
|
||||
});
|
||||
@@ -413,7 +413,7 @@ export class FileIndexSearchManager {
|
||||
return this.caches[cacheKey] = new Cache();
|
||||
}
|
||||
|
||||
private trySortedSearchFromCache(config: ISearchQuery, token: CancellationToken): TPromise<IInternalSearchComplete> {
|
||||
private trySortedSearchFromCache(config: IFileQuery, token: CancellationToken): TPromise<IInternalSearchComplete> {
|
||||
const folderCacheKey = this.getFolderCacheKey(config);
|
||||
const cache = folderCacheKey && this.caches[folderCacheKey];
|
||||
if (!cache) {
|
||||
@@ -447,7 +447,7 @@ export class FileIndexSearchManager {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private sortResults(config: IRawSearchQuery, results: IInternalFileMatch[], scorerCache: ScorerCache, token: CancellationToken): TPromise<IInternalFileMatch[]> {
|
||||
private sortResults(config: IFileQuery, results: IInternalFileMatch[], scorerCache: ScorerCache, token: CancellationToken): TPromise<IInternalFileMatch[]> {
|
||||
// we use the same compare function that is used later when showing the results using fuzzy scoring
|
||||
// this is very important because we are also limiting the number of results by config.maxResults
|
||||
// and as such we want the top items to be included in this result set if the number of items
|
||||
|
||||
@@ -9,10 +9,11 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IFolderQuery, IPatternInfo, IRawSearchQuery, ISearchCompleteStats, ISearchQuery } from 'vs/platform/search/common/search';
|
||||
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery } from 'vs/platform/search/common/search';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { FileIndexSearchManager } from 'vs/workbench/api/node/extHostSearch.fileIndex';
|
||||
import { FileSearchManager } from 'vs/workbench/services/search/node/fileSearchManager';
|
||||
import { IFolderSearch, IRawSearch } from 'vs/workbench/services/search/node/legacy/search';
|
||||
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
|
||||
import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrepSearchProvider';
|
||||
import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils';
|
||||
@@ -20,7 +21,6 @@ import { isSerializedFileMatch, isSerializedSearchComplete, isSerializedSearchSu
|
||||
import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from './extHost.protocol';
|
||||
import { IRawSearch, IFolderSearch } from 'vs/workbench/services/search/node/legacy/search';
|
||||
|
||||
export interface ISchemeTransformer {
|
||||
transformOutgoing(scheme: string): string;
|
||||
@@ -96,7 +96,7 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
});
|
||||
}
|
||||
|
||||
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawSearchQuery, token: CancellationToken): Thenable<ISearchCompleteStats> {
|
||||
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: CancellationToken): Thenable<ISearchCompleteStats> {
|
||||
const query = reviveQuery(rawQuery);
|
||||
if (handle === this._internalFileSearchHandle) {
|
||||
return this.doInternalFileSearch(handle, session, query, token);
|
||||
@@ -115,24 +115,21 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
}
|
||||
}
|
||||
|
||||
private doInternalFileSearch(handle: number, session: number, rawQuery: ISearchQuery, token: CancellationToken): Thenable<ISearchCompleteStats> {
|
||||
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: CancellationToken): Thenable<ISearchCompleteStats> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query: IRawSearch = {
|
||||
folderQueries: [],
|
||||
ignoreSymlinks: rawQuery.ignoreSymlinks,
|
||||
ignoreSymlinks: rawQuery.folderQueries.some(fq => fq.ignoreSymlinks),
|
||||
filePattern: rawQuery.filePattern,
|
||||
excludePattern: rawQuery.excludePattern,
|
||||
includePattern: rawQuery.includePattern,
|
||||
contentPattern: rawQuery.contentPattern,
|
||||
maxResults: rawQuery.maxResults,
|
||||
exists: rawQuery.exists,
|
||||
sortByScore: rawQuery.sortByScore,
|
||||
cacheKey: rawQuery.cacheKey,
|
||||
maxFilesize: rawQuery.maxFileSize,
|
||||
useRipgrep: rawQuery.useRipgrep,
|
||||
disregardIgnoreFiles: rawQuery.disregardIgnoreFiles,
|
||||
previewOptions: rawQuery.previewOptions,
|
||||
disregardGlobalIgnoreFiles: rawQuery.disregardGlobalIgnoreFiles
|
||||
disregardIgnoreFiles: rawQuery.folderQueries.some(fq => fq.disregardIgnoreFiles),
|
||||
disregardGlobalIgnoreFiles: rawQuery.folderQueries.some(fq => fq.disregardGlobalIgnoreFiles),
|
||||
};
|
||||
query.folderQueries = rawQuery.folderQueries.map(fq => (<IFolderSearch>{
|
||||
disregardGlobalIgnoreFiles: fq.disregardGlobalIgnoreFiles,
|
||||
@@ -181,14 +178,14 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
return this._fileIndexSearchManager.clearCache(cacheKey);
|
||||
}
|
||||
|
||||
$provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, rawQuery: IRawSearchQuery, token: CancellationToken): Thenable<ISearchCompleteStats> {
|
||||
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: CancellationToken): Thenable<ISearchCompleteStats> {
|
||||
const provider = this._textSearchProvider.get(handle);
|
||||
if (!provider.provideTextSearchResults) {
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
|
||||
const query = reviveQuery(rawQuery);
|
||||
const engine = new TextSearchManager(pattern, query, provider, this._extfs);
|
||||
const engine = new TextSearchManager(query, provider, this._extfs);
|
||||
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
|
||||
}
|
||||
}
|
||||
@@ -202,9 +199,9 @@ function registerEHProviders(extHostSearch: ExtHostSearch, logService: ILogServi
|
||||
}
|
||||
}
|
||||
|
||||
function reviveQuery(rawQuery: IRawSearchQuery): ISearchQuery {
|
||||
function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
|
||||
return {
|
||||
...rawQuery,
|
||||
...<any>rawQuery, // TODO
|
||||
...{
|
||||
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
|
||||
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
|
||||
|
||||
@@ -16,13 +16,14 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IQueryOptions, IRawFileMatch2 } from 'vs/platform/search/common/search';
|
||||
import { IRawFileMatch2 } from 'vs/platform/search/common/search';
|
||||
import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { Range, RelativePattern } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostWorkspaceShape, IMainContext, IWorkspaceData, MainContext, MainThreadMessageServiceShape, MainThreadWorkspaceShape } from './extHost.protocol';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ITextQueryBuilderOptions } from 'vs/workbench/parts/search/common/queryBuilder';
|
||||
|
||||
function isFolderEqual(folderA: URI, folderB: URI): boolean {
|
||||
return isEqual(folderA, folderB, !isLinux);
|
||||
@@ -399,7 +400,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
} :
|
||||
options.previewOptions;
|
||||
|
||||
const queryOptions: IQueryOptions = {
|
||||
const queryOptions: ITextQueryBuilderOptions = {
|
||||
ignoreSymlinks: typeof options.followSymlinks === 'boolean' ? !options.followSymlinks : undefined,
|
||||
disregardIgnoreFiles: typeof options.useIgnoreFiles === 'boolean' ? !options.useIgnoreFiles : undefined,
|
||||
disregardGlobalIgnoreFiles: typeof options.useGlobalIgnoreFiles === 'boolean' ? !options.useGlobalIgnoreFiles : undefined,
|
||||
|
||||
Reference in New Issue
Block a user