Skip to content

Commit 84bdd34

Browse files
authored
Notebook Search eagerly activates extensions (microsoft#203748)
* initial attempt for 'hasResult' in remote code * Notebook Search eagerly activates extensions Fixes microsoft#203389
1 parent ed35abb commit 84bdd34

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

src/vs/workbench/contrib/search/browser/notebookSearch/notebookSearchService.ts

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55
import { CancellationToken } from 'vs/base/common/cancellation';
6+
import * as glob from 'vs/base/common/glob';
67
import { ResourceSet, ResourceMap } from 'vs/base/common/map';
78
import { URI } from 'vs/base/common/uri';
89
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -12,13 +13,16 @@ import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/note
1213
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
1314
import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch';
1415
import { INotebookCellMatchWithModel, INotebookFileMatchWithModel, contentMatchesToTextSearchMatches, webviewMatchesToTextSearchMatches } from 'vs/workbench/contrib/search/browser/notebookSearch/searchNotebookHelpers';
15-
import { ITextQuery, QueryType, ISearchProgressItem, ISearchComplete, ISearchConfigurationProperties, pathIncludedInQuery } from 'vs/workbench/services/search/common/search';
16+
import { ITextQuery, QueryType, ISearchProgressItem, ISearchComplete, ISearchConfigurationProperties, pathIncludedInQuery, ISearchService, IFolderQuery } from 'vs/workbench/services/search/common/search';
1617
import * as arrays from 'vs/base/common/arrays';
1718
import { isNumber } from 'vs/base/common/types';
1819
import { IEditorResolverService } from 'vs/workbench/services/editor/common/editorResolverService';
1920
import { INotebookFileMatchNoModel } from 'vs/workbench/contrib/search/common/searchNotebookHelpers';
2021
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService';
2122
import { NotebookPriorityInfo } from 'vs/workbench/contrib/search/common/search';
23+
import { INotebookExclusiveDocumentFilter } from 'vs/workbench/contrib/notebook/common/notebookCommon';
24+
import { QueryBuilder } from 'vs/workbench/services/search/common/queryBuilder';
25+
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2226

2327
interface IOpenNotebookSearchResults {
2428
results: ResourceMap<INotebookFileMatchWithModel | null>;
@@ -30,17 +34,20 @@ interface IClosedNotebookSearchResults {
3034
}
3135
export class NotebookSearchService implements INotebookSearchService {
3236
declare readonly _serviceBrand: undefined;
37+
private queryBuilder: QueryBuilder;
3338
constructor(
3439
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
3540
@INotebookEditorService private readonly notebookEditorService: INotebookEditorService,
3641
@ILogService private readonly logService: ILogService,
3742
@INotebookService private readonly notebookService: INotebookService,
3843
@IConfigurationService private readonly configurationService: IConfigurationService,
39-
@IEditorResolverService private readonly editorResolverService: IEditorResolverService
44+
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
45+
@ISearchService private readonly searchService: ISearchService,
46+
@IInstantiationService instantiationService: IInstantiationService
4047
) {
48+
this.queryBuilder = instantiationService.createInstance(QueryBuilder);
4149
}
4250

43-
4451
notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): {
4552
openFilesToScan: ResourceSet;
4653
completeData: Promise<ISearchComplete>;
@@ -109,14 +116,38 @@ export class NotebookSearchService implements INotebookSearchService {
109116
};
110117
}
111118

119+
private async doesFileExist(includes: string[], folderQueries: IFolderQuery<URI>[], token: CancellationToken): Promise<boolean> {
120+
const promises: Promise<void>[] = includes.map(async includePattern => {
121+
const query = this.queryBuilder.file(folderQueries.map(e => e.folder), {
122+
includePattern: includePattern.startsWith('/') ? includePattern : '**/' + includePattern, // todo: find cleaner way to ensure that globs match all appropriate filetypes
123+
exists: true
124+
});
125+
return this.searchService.fileSearch(
126+
query,
127+
token
128+
).then((ret) => {
129+
if (!ret.limitHit) {
130+
throw Error('File not found');
131+
}
132+
});
133+
});
134+
135+
return Promise.any(promises).then(() => true).catch(() => false);
136+
}
137+
112138
private async getClosedNotebookResults(textQuery: ITextQuery, scannedFiles: ResourceSet, token: CancellationToken): Promise<IClosedNotebookSearchResults> {
113139

114140
const userAssociations = this.editorResolverService.getAllUserAssociations();
115141
const allPriorityInfo: Map<string, NotebookPriorityInfo[]> = new Map();
116142
const contributedNotebookTypes = this.notebookService.getContributedNotebookTypes();
117143

144+
118145
userAssociations.forEach(association => {
119146

147+
// we gather the editor associations here, but cannot check them until we actually have the files that the glob matches
148+
// this is because longer patterns take precedence over shorter ones, and even if there is a user association that
149+
// specifies the exact same glob as a contributed notebook type, there might be another user association that is longer/more specific
150+
// that still matches the path and should therefore take more precedence.
120151
if (!association.filenamePattern) {
121152
return;
122153
}
@@ -140,14 +171,26 @@ export class NotebookSearchService implements INotebookSearchService {
140171
} | undefined>[] = [];
141172

142173
contributedNotebookTypes.forEach((notebook) => {
143-
promises.push((async () => {
144-
const canResolve = await this.notebookService.canResolve(notebook.id);
145-
if (!canResolve) {
146-
return undefined;
147-
}
148-
const serializer = (await this.notebookService.withNotebookDataProvider(notebook.id)).serializer;
149-
return await serializer.searchInNotebooks(textQuery, token, allPriorityInfo);
150-
})());
174+
if (notebook.selectors.length > 0) {
175+
promises.push((async () => {
176+
const includes = notebook.selectors.map((selector) => {
177+
const globPattern = (selector as INotebookExclusiveDocumentFilter).include || selector as glob.IRelativePattern | string;
178+
return globPattern.toString();
179+
});
180+
181+
const isInWorkspace = await this.doesFileExist(includes, textQuery.folderQueries, token);
182+
if (isInWorkspace) {
183+
const canResolve = await this.notebookService.canResolve(notebook.id);
184+
if (!canResolve) {
185+
return undefined;
186+
}
187+
const serializer = (await this.notebookService.withNotebookDataProvider(notebook.id)).serializer;
188+
return await serializer.searchInNotebooks(textQuery, token, allPriorityInfo);
189+
} else {
190+
return undefined;
191+
}
192+
})());
193+
}
151194
});
152195

153196
const start = Date.now();

0 commit comments

Comments
 (0)