edit API names and remove findFiles2New and aiTextSearchProviderNew (#232431)

* remove references to findfiles2New and aiTextSearchProviderNew
This commit is contained in:
Andrea Mah
2024-10-29 18:41:23 -07:00
committed by GitHub
parent 63e5a64a61
commit 3551cb01fa
14 changed files with 117 additions and 542 deletions
@@ -598,19 +598,19 @@ suite('vscode API - workspace', () => {
});
test('`findFiles2`', () => {
return vscode.workspace.findFiles2('**/image.png').then((res) => {
return vscode.workspace.findFiles2(['**/image.png']).then((res) => {
assert.strictEqual(res.length, 2);
});
});
test('findFiles2 - null exclude', async () => {
await vscode.workspace.findFiles2('**/file.txt', { useDefaultExcludes: true, useDefaultSearchExcludes: false }).then((res) => {
await vscode.workspace.findFiles2(['**/file.txt'], { useExcludeSettings: vscode.ExcludeSettingOptions.FilesExclude }).then((res) => {
// file.exclude folder is still searched, search.exclude folder is not
assert.strictEqual(res.length, 1);
assert.strictEqual(basename(vscode.workspace.asRelativePath(res[0])), 'file.txt');
});
await vscode.workspace.findFiles2('**/file.txt', { useDefaultExcludes: false, useDefaultSearchExcludes: false }).then((res) => {
await vscode.workspace.findFiles2(['**/file.txt'], { useExcludeSettings: vscode.ExcludeSettingOptions.None }).then((res) => {
// search.exclude and files.exclude folders are both searched
assert.strictEqual(res.length, 2);
assert.strictEqual(basename(vscode.workspace.asRelativePath(res[0])), 'file.txt');
@@ -618,7 +618,7 @@ suite('vscode API - workspace', () => {
});
test('findFiles2, exclude', () => {
return vscode.workspace.findFiles2('**/image.png', { exclude: '**/sub/**' }).then((res) => {
return vscode.workspace.findFiles2(['**/image.png'], { exclude: ['**/sub/**'] }).then((res) => {
res.forEach(r => console.log(r.toString()));
assert.strictEqual(res.length, 1);
});
@@ -630,7 +630,7 @@ suite('vscode API - workspace', () => {
const token = source.token; // just to get an instance first
source.cancel();
return vscode.workspace.findFiles2('*.js', {}, token).then((res) => {
return vscode.workspace.findFiles2(['*.js'], {}, token).then((res) => {
assert.deepStrictEqual(res, []);
});
});
@@ -14,9 +14,7 @@ const _allApiProposals = {
},
aiTextSearchProvider: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.aiTextSearchProvider.d.ts',
},
aiTextSearchProvider2: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.aiTextSearchProvider2.d.ts',
version: 2
},
attributableCoverage: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.attributableCoverage.d.ts',
@@ -205,9 +203,7 @@ const _allApiProposals = {
},
findFiles2: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.findFiles2.d.ts',
},
findFiles2New: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.findFiles2New.d.ts',
version: 2
},
findTextInFiles: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.findTextInFiles.d.ts',
@@ -961,14 +961,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// Note, undefined/null have different meanings on "exclude"
return extHostWorkspace.findFiles(include, exclude, maxResults, extension.identifier, token);
},
findFiles2: (filePattern: vscode.GlobPattern, options?: vscode.FindFiles2Options, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> => {
findFiles2: (filePattern: vscode.GlobPattern[], options?: vscode.FindFiles2Options, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> => {
checkProposedApiEnabled(extension, 'findFiles2');
return extHostWorkspace.findFiles2(filePattern, options, extension.identifier, token);
},
findFiles2New: (filePattern: vscode.GlobPattern[], options?: vscode.FindFiles2OptionsNew, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> => {
checkProposedApiEnabled(extension, 'findFiles2New');
return extHostWorkspace.findFiles2New(filePattern, options, extension.identifier, token);
},
findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => {
checkProposedApiEnabled(extension, 'findTextInFiles');
let options: vscode.FindTextInFilesOptions;
@@ -1136,8 +1132,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
registerAITextSearchProvider: (scheme: string, provider: vscode.AITextSearchProvider) => {
// there are some dependencies on textSearchProvider, so we need to check for both
checkProposedApiEnabled(extension, 'aiTextSearchProvider');
checkProposedApiEnabled(extension, 'textSearchProvider');
return extHostSearch.registerAITextSearchProviderOld(scheme, provider);
checkProposedApiEnabled(extension, 'textSearchProvider2');
return extHostSearch.registerAITextSearchProvider(scheme, provider);
},
registerFileSearchProvider2: (scheme: string, provider: vscode.FileSearchProvider2) => {
checkProposedApiEnabled(extension, 'fileSearchProvider2');
@@ -1147,12 +1143,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension, 'textSearchProvider2');
return extHostSearch.registerTextSearchProvider(scheme, provider);
},
registerAITextSearchProvider2: (scheme: string, provider: vscode.AITextSearchProvider2) => {
// there are some dependencies on textSearchProvider, so we need to check for both
checkProposedApiEnabled(extension, 'aiTextSearchProvider2');
checkProposedApiEnabled(extension, 'textSearchProvider2');
return extHostSearch.registerAITextSearchProvider(scheme, provider);
},
registerRemoteAuthorityResolver: (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => {
checkProposedApiEnabled(extension, 'resolvers');
return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver);
+5 -22
View File
@@ -16,14 +16,13 @@ import { URI, UriComponents } from '../../../base/common/uri.js';
import { TextSearchManager } from '../../services/search/common/textSearchManager.js';
import { CancellationToken } from '../../../base/common/cancellation.js';
import { revive } from '../../../base/common/marshalling.js';
import { OldAITextSearchProviderConverter, OldFileSearchProviderConverter, OldTextSearchProviderConverter } from '../../services/search/common/searchExtConversionTypes.js';
import { OldFileSearchProviderConverter, OldTextSearchProviderConverter } from '../../services/search/common/searchExtConversionTypes.js';
export interface IExtHostSearch extends ExtHostSearchShape {
registerTextSearchProviderOld(scheme: string, provider: vscode.TextSearchProvider): IDisposable;
registerAITextSearchProviderOld(scheme: string, provider: vscode.AITextSearchProvider): IDisposable;
registerFileSearchProviderOld(scheme: string, provider: vscode.FileSearchProvider): IDisposable;
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider2): IDisposable;
registerAITextSearchProvider(scheme: string, provider: vscode.AITextSearchProvider2): IDisposable;
registerAITextSearchProvider(scheme: string, provider: vscode.AITextSearchProvider): IDisposable;
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider2): IDisposable;
doInternalFileSearchWithCustomCallback(query: IFileQuery, token: CancellationToken, handleFileMatch: (data: URI[]) => void): Promise<ISearchCompleteStats>;
}
@@ -38,7 +37,7 @@ export class ExtHostSearch implements IExtHostSearch {
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider2>();
private readonly _textSearchUsedSchemes = new Set<string>();
private readonly _aiTextSearchProvider = new Map<number, vscode.AITextSearchProvider2>();
private readonly _aiTextSearchProvider = new Map<number, vscode.AITextSearchProvider>();
private readonly _aiTextSearchUsedSchemes = new Set<string>();
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider2>();
@@ -88,23 +87,7 @@ export class ExtHostSearch implements IExtHostSearch {
});
}
registerAITextSearchProviderOld(scheme: string, provider: vscode.AITextSearchProvider): IDisposable {
if (this._aiTextSearchUsedSchemes.has(scheme)) {
throw new Error(`an AI text search provider for the scheme '${scheme}'is already registered`);
}
this._aiTextSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._aiTextSearchProvider.set(handle, new OldAITextSearchProviderConverter(provider));
this._proxy.$registerAITextSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._aiTextSearchUsedSchemes.delete(scheme);
this._aiTextSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
registerAITextSearchProvider(scheme: string, provider: vscode.AITextSearchProvider2): IDisposable {
registerAITextSearchProvider(scheme: string, provider: vscode.AITextSearchProvider): IDisposable {
if (this._aiTextSearchUsedSchemes.has(scheme)) {
throw new Error(`an AI text search provider for the scheme '${scheme}'is already registered`);
}
@@ -215,7 +198,7 @@ export class ExtHostSearch implements IExtHostSearch {
}, 'textSearchProvider');
}
protected createAITextSearchManager(query: IAITextQuery, provider: vscode.AITextSearchProvider2): TextSearchManager {
protected createAITextSearchManager(query: IAITextQuery, provider: vscode.AITextSearchProvider): TextSearchManager {
return new TextSearchManager({ query, provider }, {
readdir: resource => Promise.resolve([]),
toCanonicalName: encoding => encoding
@@ -478,36 +478,11 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
}, token);
}
findFiles2(filePattern: vscode.GlobPattern | undefined,
findFiles2(filePatterns: vscode.GlobPattern[],
options: vscode.FindFiles2Options = {},
extensionId: ExtensionIdentifier,
token: vscode.CancellationToken = CancellationToken.None): Promise<vscode.Uri[]> {
this._logService.trace(`extHostWorkspace#findFiles2: fileSearch, extension: ${extensionId.value}, entryPoint: findFiles2`);
const useDefaultExcludes = options.useDefaultExcludes ?? true;
const useDefaultSearchExcludes = options.useDefaultSearchExcludes ?? true;
const excludeSetting = useDefaultExcludes ?
(useDefaultSearchExcludes ? ExcludeSettingOptions.SearchAndFilesExclude : ExcludeSettingOptions.FilesExclude) :
ExcludeSettingOptions.None;
const newOptions: vscode.FindFiles2OptionsNew = {
exclude: options.exclude ? [options.exclude] : undefined,
useIgnoreFiles: {
local: options.useIgnoreFiles,
global: options.useGlobalIgnoreFiles,
parent: options.useParentIgnoreFiles
},
useExcludeSettings: excludeSetting,
followSymlinks: options.followSymlinks,
maxResults: options.maxResults,
};
return this._findFilesImpl(undefined, filePattern !== undefined ? [filePattern] : [], newOptions, token);
}
findFiles2New(filePatterns: vscode.GlobPattern[],
options: vscode.FindFiles2OptionsNew = {},
extensionId: ExtensionIdentifier,
token: vscode.CancellationToken = CancellationToken.None): Promise<vscode.Uri[]> {
this._logService.trace(`extHostWorkspace#findFiles2New: fileSearch, extension: ${extensionId.value}, entryPoint: findFiles2New`);
return this._findFilesImpl(undefined, filePatterns, options, token);
}
@@ -517,7 +492,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
// `filePattern` is the proper way to handle this, since it takes less precedence than the ignore files.
include: vscode.GlobPattern | undefined,
filePatterns: vscode.GlobPattern[] | undefined,
options: vscode.FindFiles2OptionsNew,
options: vscode.FindFiles2Options,
token: vscode.CancellationToken = CancellationToken.None): Promise<vscode.Uri[]> {
if (token && token.isCancellationRequested) {
return Promise.resolve([]);
@@ -716,12 +716,12 @@ suite('ExtHostWorkspace', function () {
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2('foo', { maxResults: 10, useDefaultExcludes: true }, new ExtensionIdentifier('test')).then(() => {
return ws.findFiles2(['foo'], { maxResults: 10, useExcludeSettings: ExcludeSettingOptions.FilesExclude }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
function testFindFiles2Include(pattern: RelativePattern) {
function testFindFiles2Include(pattern: RelativePattern[]) {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
@@ -745,11 +745,11 @@ suite('ExtHostWorkspace', function () {
}
test('RelativePattern include (string)', () => {
return testFindFiles2Include(new RelativePattern('/other/folder', 'glob/**'));
return testFindFiles2Include([new RelativePattern('/other/folder', 'glob/**')]);
});
test('RelativePattern include (URI)', () => {
return testFindFiles2Include(new RelativePattern(URI.file('/other/folder'), 'glob/**'));
return testFindFiles2Include([new RelativePattern(URI.file('/other/folder'), 'glob/**')]);
});
test('no excludes', () => {
@@ -770,7 +770,7 @@ suite('ExtHostWorkspace', function () {
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2(new RelativePattern('/other/folder', 'glob/**'), {}, new ExtensionIdentifier('test')).then(() => {
return ws.findFiles2([new RelativePattern('/other/folder', 'glob/**')], {}, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
@@ -790,7 +790,7 @@ suite('ExtHostWorkspace', function () {
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
const token = CancellationToken.Cancelled;
return ws.findFiles2(new RelativePattern('/other/folder', 'glob/**'), {}, new ExtensionIdentifier('test'), token).then(() => {
return ws.findFiles2([new RelativePattern('/other/folder', 'glob/**')], {}, new ExtensionIdentifier('test'), token).then(() => {
assert(!mainThreadCalled, '!mainThreadCalled');
});
});
@@ -811,7 +811,7 @@ suite('ExtHostWorkspace', function () {
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2('', { exclude: new RelativePattern(root, 'glob/**') }, new ExtensionIdentifier('test')).then(() => {
return ws.findFiles2([''], { exclude: [new RelativePattern(root, 'glob/**')] }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
@@ -832,7 +832,7 @@ suite('ExtHostWorkspace', function () {
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2('', { useIgnoreFiles: true, useParentIgnoreFiles: true, useGlobalIgnoreFiles: true }, new ExtensionIdentifier('test')).then(() => {
return ws.findFiles2([''], { useIgnoreFiles: { local: true, parent: true, global: true } }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
@@ -851,168 +851,7 @@ suite('ExtHostWorkspace', function () {
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2('', { followSymlinks: true }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
});
suite('findFiles2New -', function () {
test('string include', () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.strictEqual(options.filePattern, 'foo');
assert.strictEqual(options.includePattern, undefined);
assert.strictEqual(_includeFolder, null);
assert.strictEqual(options.excludePattern, undefined);
assert.strictEqual(options.disregardExcludeSettings, false);
assert.strictEqual(options.maxResults, 10);
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2New(['foo'], { maxResults: 10, useExcludeSettings: ExcludeSettingOptions.FilesExclude }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
function testFindFiles2NewInclude(pattern: RelativePattern[]) {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.strictEqual(options.filePattern, 'glob/**');
assert.strictEqual(options.includePattern, undefined);
assert.deepStrictEqual(_includeFolder ? URI.from(_includeFolder).toJSON() : null, URI.file('/other/folder').toJSON());
assert.strictEqual(options.excludePattern, undefined);
assert.strictEqual(options.disregardExcludeSettings, false);
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2New(pattern, { maxResults: 10 }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
}
test('RelativePattern include (string)', () => {
return testFindFiles2NewInclude([new RelativePattern('/other/folder', 'glob/**')]);
});
test('RelativePattern include (URI)', () => {
return testFindFiles2NewInclude([new RelativePattern(URI.file('/other/folder'), 'glob/**')]);
});
test('no excludes', () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.strictEqual(options.filePattern, 'glob/**');
assert.strictEqual(options.includePattern, undefined);
assert.deepStrictEqual(URI.revive(_includeFolder!).toString(), URI.file('/other/folder').toString());
assert.strictEqual(options.excludePattern, undefined);
assert.strictEqual(options.disregardExcludeSettings, false);
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2New([new RelativePattern('/other/folder', 'glob/**')], {}, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
test('with cancelled token', () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
const token = CancellationToken.Cancelled;
return ws.findFiles2New([new RelativePattern('/other/folder', 'glob/**')], {}, new ExtensionIdentifier('test'), token).then(() => {
assert(!mainThreadCalled, '!mainThreadCalled');
});
});
test('RelativePattern exclude', () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.strictEqual(options.disregardExcludeSettings, false);
assert.strictEqual(options.excludePattern?.length, 1);
assert.strictEqual(options.excludePattern[0].pattern, 'glob/**'); // Note that the base portion is ignored, see #52651
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2New([''], { exclude: [new RelativePattern(root, 'glob/**')] }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
test('useIgnoreFiles', () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.strictEqual(options.disregardExcludeSettings, false);
assert.strictEqual(options.disregardIgnoreFiles, false);
assert.strictEqual(options.disregardGlobalIgnoreFiles, false);
assert.strictEqual(options.disregardParentIgnoreFiles, false);
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2New([''], { useIgnoreFiles: { local: true, parent: true, global: true } }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
test('use symlinks', () => {
const root = '/project/foo';
const rpcProtocol = new TestRPCProtocol();
let mainThreadCalled = false;
rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock<MainThreadWorkspace>() {
override $startFileSearch(_includeFolder: UriComponents | null, options: IFileQueryBuilderOptions, token: CancellationToken): Promise<URI[] | null> {
mainThreadCalled = true;
assert.strictEqual(options.ignoreSymlinks, false);
return Promise.resolve(null);
}
});
const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
return ws.findFiles2New([''], { followSymlinks: true }, new ExtensionIdentifier('test')).then(() => {
return ws.findFiles2([''], { followSymlinks: true }, new ExtensionIdentifier('test')).then(() => {
assert(mainThreadCalled, 'mainThreadCalled');
});
});
@@ -13,7 +13,7 @@ import { CancellationToken } from '../../../../base/common/cancellation.js';
import { URI } from '../../../../base/common/uri.js';
import { IProgress } from '../../../../platform/progress/common/progress.js';
import { DEFAULT_TEXT_SEARCH_PREVIEW_OPTIONS } from './search.js';
import { Range, FileSearchProvider2, FileSearchProviderOptions, ProviderResult, TextSearchComplete2, TextSearchContext2, TextSearchMatch2, TextSearchProvider2, TextSearchProviderOptions, TextSearchQuery2, TextSearchResult2, AITextSearchProvider2, TextSearchCompleteMessage } from './searchExtTypes.js';
import { Range, FileSearchProvider2, FileSearchProviderOptions, ProviderResult, TextSearchComplete2, TextSearchContext2, TextSearchMatch2, TextSearchProvider2, TextSearchProviderOptions, TextSearchQuery2, TextSearchResult2, TextSearchCompleteMessage } from './searchExtTypes.js';
// old types that are retained for backward compatibility
// TODO: delete this when search apis are adopted by all first-party extensions
@@ -372,23 +372,6 @@ export interface TextSearchProvider {
*/
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: IProgress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
}
export interface AITextSearchProvider {
/**
* The name of the AI searcher. Will be displayed as `{name} Results` in the Search View.
*/
readonly name?: string;
/**
* Provide results that match the given text pattern.
* @param query The parameter for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
*/
provideAITextSearchResults(query: string, options: AITextSearchOptions, progress: IProgress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
}
/**
* Options that can be set on a findTextInFiles search.
*/
@@ -561,40 +544,6 @@ export class OldTextSearchProviderConverter implements TextSearchProvider2 {
}
}
export class OldAITextSearchProviderConverter implements AITextSearchProvider2 {
public readonly name?: string;
constructor(private provider: AITextSearchProvider) {
this.name = this.provider.name;
}
provideAITextSearchResults(query: string, options: TextSearchProviderOptions, progress: IProgress<TextSearchResult2>, token: CancellationToken): ProviderResult<TextSearchComplete2> {
const progressShim = (oldResult: TextSearchResult) => {
if (!validateProviderResult(oldResult)) {
return;
}
progress.report(oldToNewTextSearchResult(oldResult));
};
const getResult = async () => {
return coalesce(await Promise.all(
newToOldTextProviderOptions(options).map(
o => this.provider.provideAITextSearchResults(query, o, { report: (e) => progressShim(e) }, token))))
.reduce(
(prev, cur) => ({ limitHit: prev.limitHit || cur.limitHit }),
{ limitHit: false }
);
};
const oldResult = getResult();
return oldResult.then((e) => {
return {
limitHit: e.limitHit,
message: coalesce(asArray(e.message))
} satisfies TextSearchComplete2;
});
}
}
function validateProviderResult(result: TextSearchResult): boolean {
if (extensionResultIsMatch(result)) {
if (Array.isArray(result.ranges)) {
@@ -527,7 +527,7 @@ export interface TextSearchCompleteMessage {
/**
* An AITextSearchProvider provides additional AI text search results in the workspace.
*/
export interface AITextSearchProvider2 {
export interface AITextSearchProvider {
/**
* The name of the AI searcher. Will be displayed as `{name} Results` in the Search View.
@@ -12,14 +12,14 @@ import * as resources from '../../../../base/common/resources.js';
import { URI } from '../../../../base/common/uri.js';
import { FolderQuerySearchTree } from './folderQuerySearchTree.js';
import { DEFAULT_MAX_SEARCH_RESULTS, hasSiblingPromiseFn, IAITextQuery, IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, excludeToGlobPattern, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, ITextSearchStats, QueryGlobTester, QueryType, resolvePatternsForProvider, ISearchRange, DEFAULT_TEXT_SEARCH_PREVIEW_OPTIONS } from './search.js';
import { AITextSearchProvider2, TextSearchComplete2, TextSearchMatch2, TextSearchProviderFolderOptions, TextSearchProvider2, TextSearchProviderOptions, TextSearchQuery2, TextSearchResult2 } from './searchExtTypes.js';
import { TextSearchComplete2, TextSearchMatch2, TextSearchProviderFolderOptions, TextSearchProvider2, TextSearchProviderOptions, TextSearchQuery2, TextSearchResult2, AITextSearchProvider } from './searchExtTypes.js';
export interface IFileUtils {
readdir: (resource: URI) => Promise<string[]>;
toCanonicalName: (encoding: string) => string;
}
interface IAITextQueryProviderPair {
query: IAITextQuery; provider: AITextSearchProvider2;
query: IAITextQuery; provider: AITextSearchProvider;
}
interface ITextQueryProviderPair {
+4 -34
View File
@@ -3,39 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 2
declare module 'vscode' {
/**
* Options that apply to AI text search.
*/
export interface AITextSearchOptions extends SearchOptions {
/**
* The maximum number of results to be returned.
*/
maxResults: number;
/**
* Options to specify the size of the result text preview.
*/
previewOptions?: TextSearchPreviewOptions;
/**
* Exclude files larger than `maxFileSize` in bytes.
*/
maxFileSize?: number;
/**
* Number of lines of context to include before each match.
*/
beforeContext?: number;
/**
* Number of lines of context to include after each match.
*/
afterContext?: number;
}
/**
* An AITextSearchProvider provides additional AI text search results in the workspace.
*/
@@ -46,14 +16,14 @@ declare module 'vscode' {
readonly name?: string;
/**
*
* Provide results that match the given text pattern.
* @param query The parameter for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
*/
provideAITextSearchResults(query: string, options: AITextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
provideAITextSearchResults(query: string, options: TextSearchProviderOptions, progress: Progress<TextSearchResult2>, token: CancellationToken): ProviderResult<TextSearchComplete2>;
}
export namespace workspace {
@@ -1,40 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
/**
* An AITextSearchProvider provides additional AI text search results in the workspace.
*/
export interface AITextSearchProvider2 {
/**
* The name of the AI searcher. Will be displayed as `{name} Results` in the Search View.
*/
readonly name?: string;
/**
* WARNING: VERY EXPERIMENTAL.
*
* Provide results that match the given text pattern.
* @param query The parameter for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
*/
provideAITextSearchResults(query: string, options: TextSearchProviderOptions, progress: Progress<TextSearchResult2>, token: CancellationToken): ProviderResult<TextSearchComplete2>;
}
export namespace workspace {
/**
* Register an AI text search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A {@link Disposable} that unregisters this provider when being disposed.
*/
export function registerAITextSearchProvider2(scheme: string, provider: AITextSearchProvider2): Disposable;
}
}
+82 -46
View File
@@ -3,87 +3,123 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 2
declare module 'vscode' {
export interface FindFiles2Options {
// note: this is just FindTextInFilesOptions without select properties (include, previewOptions, beforeContext, afterContext)
/**
* A {@link GlobPattern glob pattern} that defines files and folders to exclude. The glob pattern
* will be matched against the file paths of resulting matches relative to their workspace.
* An array of {@link GlobPattern GlobPattern} that defines files to exclude.
* The glob patterns will be matched against the file paths of files relative to their workspace or {@link RelativePattern.baseUri} if applicable.
*
* If more than one value is used, the values are combined with a logical AND.
* For example, consider the following code:
*
* ```ts
* const ab = findFiles(['**​/*.js'], {exclude: ['*.ts', '*.js']});
* const a = findFiles(['**​/*.js'], {exclude: ['*.ts']});
* const b = findFiles(['**​/*.js'], {exclude: ['*.js']});
* ```
*
* In this, `ab` will be the intersection of results from `a` and `b`.
*/
exclude?: GlobPattern;
exclude?: GlobPattern[];
/**
* Whether to use the values for files.exclude. Defaults to true.
* Which settings to follow when searching for files. Defaults to {@link ExcludeSettingOptions.searchAndFilesExclude}.
*/
useDefaultExcludes?: boolean;
useExcludeSettings?: ExcludeSettingOptions;
/**
* Whether to use the values for search.exclude. Defaults to true. Will not be followed if `useDefaultExcludes` is set to `false`.
*/
useDefaultSearchExcludes?: boolean;
/**
* The maximum number of results to search for
* The maximum number of results to search for. Defaults to 20000 results.
*/
maxResults?: number;
/**
* Whether external files that exclude files, like .gitignore, should be respected.
* Defaults to the value for `search.useIgnoreFiles` in settings.
* For more info, see the setting listed above.
* Which file locations have ignore (`.gitignore` or `.ignore`) files to follow.
*
* When any of these fields are `undefined`, the value will either be assumed (e.g. if only one is valid),
* or it will follow settings based on the corresponding `search.use*IgnoreFiles` setting.
*
* Will log an error if an invalid combination is set.
*
* Although `.ignore` files are uncommon, they can be leveraged if there are patterns
* that should not be known to git, but should be known to the search providers.
* They should be in the same locations where `.gitignore` files are found, and they follow the same format.
*/
useIgnoreFiles?: boolean;
/**
* Whether global files that exclude files, like .gitignore, should be respected.
* Must set `useIgnoreFiles` to `true` to use this.
* Defaults to the value for `search.useGlobalIgnoreFiles` in settings.
* For more info, see the setting listed above.
*/
useGlobalIgnoreFiles?: boolean;
/**
* Whether files in parent directories that exclude files, like .gitignore, should be respected.
* Must set `useIgnoreFiles` to `true` to use this.
* Defaults to the value for `search.useParentIgnoreFiles` in settings.
* For more info, see the setting listed above.
*/
useParentIgnoreFiles?: boolean;
useIgnoreFiles?: {
/**
* Use ignore files at the current workspace root.
* May default to `search.useIgnoreFiles` setting if not set.
*/
local?: boolean;
/**
* Use ignore files at the parent directory. When set to `true`, {@link FindFiles2Options.useIgnoreFiles.local} must also be `true`.
* May default to `search.useParentIgnoreFiles` setting if not set.
*/
parent?: boolean;
/**
* Use global ignore files. When set to `true`, {@link FindFiles2Options.useIgnoreFiles.local} must also be `true`.
* May default to `search.useGlobalIgnoreFiles` setting if not set.
*/
global?: boolean;
};
/**
* Whether symlinks should be followed while searching.
* Defaults to the value for `search.followSymlinks` in settings.
* For more info, see the setting listed above.
* For more info, see the setting description for `search.followSymlinks`.
*/
followSymlinks?: boolean;
/**
* If set to true, the `filePattern` arg will be fuzzy-searched instead of glob-searched.
* If `filePattern` is a {@link RelativePattern relative pattern}, then the fuzzy search will act on the `pattern` of the {@link RelativePattern RelativePattern}
*/
fuzzy?: boolean;
}
/**
* Represents a session of a currently logged in user.
* Options for following search.exclude and files.exclude settings.
*/
export enum ExcludeSettingOptions {
/**
* Don't use any exclude settings.
*/
None = 1,
/**
* Use the `files.exclude` setting
*/
FilesExclude = 2,
/**
* Use the `files.exclude` and `search.exclude` settings
*/
SearchAndFilesExclude = 3
}
export namespace workspace {
/**
* WARNING: VERY EXPERIMENTAL.
*
* Find files across all {@link workspace.workspaceFolders workspace folders} in the workspace.
*
* @example
* findFiles('**​/*.js', {exclude: '**​/out/**', useIgnoreFiles: true, maxResults: 10})
* findFiles(['**​/*.js'], {exclude: ['**​/out/**'], useIgnoreFiles: true, maxResults: 10})
*
* @param filePattern A {@link GlobPattern glob pattern} that defines the files to search for. The glob pattern
* will be matched against the file paths of resulting matches relative to their workspace. Use a {@link RelativePattern relative pattern}
* to restrict the search results to a {@link WorkspaceFolder workspace folder}.
* @param filePattern An array of {@link GlobPattern GlobPattern} that defines the files to search for.
* The glob patterns will be matched against the file paths of files relative to their workspace or {@link baseUri GlobPattern.baseUri} if applicable.
* Use a {@link RelativePattern RelativePatten} to restrict the search results to a {@link WorkspaceFolder workspace folder}.
*
* If more than one value is used, the values are combined with a logical OR.
*
* For example, consider the following code:
*
* ```ts
* const ab = findFiles(['*.ts', '*.js']);
* const a = findFiles(['**​/*.ts']);
* const b = findFiles(['**​/*.js']);
* ```
*
* In this, `ab` will be the union of results from `a` and `b`.
* @param options A set of {@link FindFiles2Options FindFiles2Options} that defines where and how to search (e.g. exclude settings).
* @param token A token that can be used to signal cancellation to the underlying search engine.
* @returns A thenable that resolves to an array of resource identifiers. Will return no results if no
* {@link workspace.workspaceFolders workspace folders} are opened.
*/
export function findFiles2(filePattern: GlobPattern, options?: FindFiles2Options, token?: CancellationToken): Thenable<Uri[]>;
export function findFiles2(filePattern: GlobPattern[], options?: FindFiles2Options, token?: CancellationToken): Thenable<Uri[]>;
}
}
-105
View File
@@ -1,105 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
export interface FindFiles2OptionsNew {
/**
* An array of {@link GlobPattern GlobPattern} that defines files to exclude.
* The glob patterns will be matched against the file paths of files relative to their workspace or {@link RelativePattern.baseUri} if applicable.
*
* If more than one value is used, the values are combined with a logical AND.
* For example, consider the following code:
*
* ```ts
* const ab = findFiles(['**​/*.js'], {exclude: ['*.ts', '*.js']});
* const a = findFiles(['**​/*.js'], {exclude: ['*.ts']});
* const b = findFiles(['**​/*.js'], {exclude: ['*.js']});
* ```
*
* In this, `ab` will be the intersection of results from `a` and `b`.
*/
exclude?: GlobPattern[];
/**
* Which settings to follow when searching for files. Defaults to {@link ExcludeSettingOptions.searchAndFilesExclude}.
*/
useExcludeSettings?: ExcludeSettingOptions;
/**
* The maximum number of results to search for. Defaults to 20000 results.
*/
maxResults?: number;
/**
* Which file locations have ignore (`.gitignore` or `.ignore`) files to follow.
*
* When any of these fields are `undefined`, the value will either be assumed (e.g. if only one is valid),
* or it will follow settings based on the corresponding `search.use*IgnoreFiles` setting.
*
* Will log an error if an invalid combination is set.
*
* Although `.ignore` files are uncommon, they can be leveraged if there are patterns
* that should not be known to git, but should be known to the search providers.
* They should be in the same locations where `.gitignore` files are found, and they follow the same format.
*/
useIgnoreFiles?: {
/**
* Use ignore files at the current workspace root.
* May default to `search.useIgnoreFiles` setting if not set.
*/
local?: boolean;
/**
* Use ignore files at the parent directory. When set to `true`, {@link FindFiles2OptionsNew.useIgnoreFiles.local} must also be `true`.
* May default to `search.useParentIgnoreFiles` setting if not set.
*/
parent?: boolean;
/**
* Use global ignore files. When set to `true`, {@link FindFiles2OptionsNew.useIgnoreFiles.local} must also be `true`.
* May default to `search.useGlobalIgnoreFiles` setting if not set.
*/
global?: boolean;
};
/**
* Whether symlinks should be followed while searching.
* Defaults to the value for `search.followSymlinks` in settings.
* For more info, see the setting description for `search.followSymlinks`.
*/
followSymlinks?: boolean;
}
export namespace workspace {
/**
* WARNING: VERY EXPERIMENTAL.
*
* Find files across all {@link workspace.workspaceFolders workspace folders} in the workspace.
*
* @example
* findFiles(['**​/*.js'], {exclude: ['**​/out/**'], useIgnoreFiles: true, maxResults: 10})
*
* @param filePattern An array of {@link GlobPattern GlobPattern} that defines the files to search for.
* The glob patterns will be matched against the file paths of files relative to their workspace or {@link baseUri GlobPattern.baseUri} if applicable.
* Use a {@link RelativePattern RelativePatten} to restrict the search results to a {@link WorkspaceFolder workspace folder}.
*
* If more than one value is used, the values are combined with a logical OR.
*
* For example, consider the following code:
*
* ```ts
* const ab = findFiles(['*.ts', '*.js']);
* const a = findFiles(['**​/*.ts']);
* const b = findFiles(['**​/*.js']);
* ```
*
* In this, `ab` will be the union of results from `a` and `b`.
* @param options A set of {@link FindFiles2Options FindFiles2Options} that defines where and how to search (e.g. exclude settings).
* @param token A token that can be used to signal cancellation to the underlying search engine.
* @returns A thenable that resolves to an array of resource identifiers. Will return no results if no
* {@link workspace.workspaceFolders workspace folders} are opened.
*/
export function findFiles2New(filePattern: GlobPattern[], options?: FindFiles2OptionsNew, token?: CancellationToken): Thenable<Uri[]>;
}
}
-18
View File
@@ -130,24 +130,6 @@ declare module 'vscode' {
complete: Thenable<TextSearchComplete2>;
}
/**
* Options for following search.exclude and files.exclude settings.
*/
export enum ExcludeSettingOptions {
/**
* Don't use any exclude settings.
*/
None = 1,
/**
* Use the `files.exclude` setting
*/
FilesExclude = 2,
/**
* Use the `files.exclude` and `search.exclude` settings
*/
SearchAndFilesExclude = 3
}
export namespace workspace {
/**
* WARNING: VERY EXPERIMENTAL.