提交 c185f7ab 编写于 作者: R rebornix

command for fetching all notebook content providers.

上级 4a45c746
......@@ -19,6 +19,7 @@ import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGro
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { IRange } from 'vs/editor/common/core/range';
import { IPosition } from 'vs/editor/common/core/position';
import { TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
//#region --- NEW world
......@@ -312,6 +313,12 @@ export class ExtHostApiCommands {
returns: 'A promise that resolves to an array of ColorPresentation objects.'
});
this._register('vscode.resolveNotebookContentProviders', this._resolveNotebookContentProviders, {
description: 'Resolve Notebook Content Providers',
args: [],
returns: 'A promise that resolves to an array of NotebookContentProvider static info objects.'
});
// -----------------------------------------------------------------
// The following commands are registered on both sides separately.
//
......@@ -480,6 +487,28 @@ export class ExtHostApiCommands {
item.command ? this._commands.converter.fromInternal(item.command) : undefined);
}));
}
private _resolveNotebookContentProviders(): Promise<{
viewType: string;
displayName: string;
filenamePattern: vscode.NotebookFilenamePattern[];
options: vscode.NotebookDocumentContentOptions;
}[] | undefined> {
return this._commands.executeCommand<{
viewType: string;
displayName: string;
options: { transientOutputs: boolean; transientMetadata: TransientMetadata };
filenamePattern: (string | types.RelativePattern | { include: string | types.RelativePattern, exclude: string | types.RelativePattern })[]
}[]>('_resolveNotebookContentProvider')
.then(tryMapWith(item => {
return {
viewType: item.viewType,
displayName: item.displayName,
options: { transientOutputs: item.options.transientOutputs, transientMetadata: item.options.transientMetadata },
filenamePattern: item.filenamePattern.map(pattern => typeConverters.NotebookExclusiveDocumentPattern.to(pattern))
};
}));
}
}
function tryMapWith<T, R>(f: (x: T) => R) {
......
......@@ -1329,6 +1329,24 @@ export namespace NotebookExclusiveDocumentPattern {
}
export function to(pattern: string | types.RelativePattern | { include: string | types.RelativePattern, exclude: string | types.RelativePattern }): { include: vscode.GlobPattern, exclude: vscode.GlobPattern } | vscode.GlobPattern {
if (typeof pattern === 'string') {
return pattern;
}
if (isRelativePattern(pattern)) {
return {
base: pattern.base,
pattern: pattern.pattern
};
}
return {
include: pattern.include,
exclude: pattern.exclude
};
}
function isExclusivePattern(obj: any): obj is { include: types.RelativePattern | undefined | null, exclude: types.RelativePattern | undefined | null } {
const ep = obj as { include: vscode.GlobPattern, exclude: vscode.GlobPattern };
const include = GlobPattern.from(ep.include);
......
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import * as glob from 'vs/base/common/glob';
import { URI } from 'vs/base/common/uri';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
......@@ -12,7 +13,7 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import { localize } from 'vs/nls';
import { Action2, IAction2Options, MenuId, MenuItemAction, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
......@@ -20,7 +21,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
import { BaseCellRenderTemplate, CellEditState, CellFocusMode, ICellViewModel, INotebookEditor, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_OUTPUT_FOCUSED, EXPAND_CELL_CONTENT_COMMAND_ID, NOTEBOOK_CELL_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellEditType, CellKind, ICellRange, NotebookCellMetadata, NotebookCellRunState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellEditType, CellKind, ICellRange, isDocumentExcludePattern, NotebookCellMetadata, NotebookCellRunState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY, TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
......@@ -1816,3 +1817,40 @@ registerAction2(class extends Action2 {
}
}
});
CommandsRegistry.registerCommand('_resolveNotebookContentProvider', (accessor, args): {
viewType: string;
displayName: string;
options: { transientOutputs: boolean; transientMetadata: TransientMetadata };
filenamePattern: (string | glob.IRelativePattern | { include: string | glob.IRelativePattern, exclude: string | glob.IRelativePattern })[]
}[] => {
const notebookService = accessor.get<INotebookService>(INotebookService);
const contentProviders = notebookService.getContributedNotebookProviders();
return contentProviders.map(provider => {
const filenamePatterns = provider.selectors.map(selector => {
if (typeof selector === 'string') {
return selector;
}
if (glob.isRelativePattern(selector)) {
return selector;
}
if (isDocumentExcludePattern(selector)) {
return {
include: selector.include,
exclude: selector.exclude
};
}
return null;
}).filter(pattern => pattern !== null) as (string | glob.IRelativePattern | { include: string | glob.IRelativePattern, exclude: string | glob.IRelativePattern })[];
return {
viewType: provider.id,
displayName: provider.displayName,
filenamePattern: filenamePatterns,
options: { transientMetadata: provider.options.transientMetadata, transientOutputs: provider.options.transientOutputs }
};
});
});
......@@ -6,7 +6,6 @@
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import * as nls from 'vs/nls';
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { NotebookSelector } from 'vs/workbench/contrib/notebook/common/notebookProvider';
import { NotebookEditorPriority } from 'vs/workbench/contrib/notebook/common/notebookCommon';
namespace NotebookEditorContribution {
......@@ -19,7 +18,7 @@ namespace NotebookEditorContribution {
export interface INotebookEditorContribution {
readonly [NotebookEditorContribution.viewType]: string;
readonly [NotebookEditorContribution.displayName]: string;
readonly [NotebookEditorContribution.selector]?: readonly NotebookSelector[];
readonly [NotebookEditorContribution.selector]?: readonly { filenamePattern?: string; excludeFileNamePattern?: string; }[];
readonly [NotebookEditorContribution.priority]?: string;
}
......
......@@ -569,20 +569,26 @@ export class NotebookService extends Disposable implements INotebookService, ICu
if (controller.viewOptions && !this.notebookProviderInfoStore.get(viewType)) {
// register this content provider to the static contribution, if it does not exist
this.notebookProviderInfoStore.add(new NotebookProviderInfo({
const info = new NotebookProviderInfo({
displayName: controller.viewOptions.displayName,
id: viewType,
priority: NotebookEditorPriority.default,
selectors: controller.viewOptions.filenamePattern.map(pattern => ({ filenamePattern: pattern })),
selectors: [],
providerExtensionId: extensionData.id.value,
providerDescription: extensionData.description,
providerDisplayName: extensionData.id.value,
providerExtensionLocation: URI.revive(extensionData.location),
dynamicContribution: true,
exclusive: controller.viewOptions.exclusive
}));
});
info.update({ selectors: controller.viewOptions.filenamePattern });
info.update({ options: controller.options });
this.notebookProviderInfoStore.add(info);
}
this.notebookProviderInfoStore.get(viewType)?.update({ options: controller.options });
this._onDidChangeViewTypes.fire();
return toDisposable(() => {
this._notebookProviders.delete(viewType);
......@@ -806,8 +812,12 @@ export class NotebookService extends Disposable implements INotebookService, ICu
return this.notebookRenderersInfoStore.getContributedRenderer(mimeType);
}
getContributedNotebookProviders(resource: URI): readonly NotebookProviderInfo[] {
return this.notebookProviderInfoStore.getContributedNotebook(resource);
getContributedNotebookProviders(resource?: URI): readonly NotebookProviderInfo[] {
if (resource) {
return this.notebookProviderInfoStore.getContributedNotebook(resource);
}
return [...this.notebookProviderInfoStore];
}
getContributedNotebookProvider(viewType: string): NotebookProviderInfo | undefined {
......
......@@ -6,17 +6,14 @@
import * as glob from 'vs/base/common/glob';
import { URI } from 'vs/base/common/uri';
import { basename } from 'vs/base/common/path';
import { INotebookExclusiveDocumentFilter, isDocumentExcludePattern, NotebookEditorPriority } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookExclusiveDocumentFilter, isDocumentExcludePattern, NotebookEditorPriority, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
export interface NotebookSelector {
readonly filenamePattern?: string | glob.IRelativePattern | INotebookExclusiveDocumentFilter;
readonly excludeFileNamePattern?: string;
}
export type NotebookSelector = string | glob.IRelativePattern | INotebookExclusiveDocumentFilter;
export interface NotebookEditorDescriptor {
readonly id: string;
readonly displayName: string;
readonly selectors: readonly NotebookSelector[];
readonly selectors: readonly { filenamePattern?: string; excludeFileNamePattern?: string; }[];
readonly priority: NotebookEditorPriority;
readonly providerExtensionId?: string;
readonly providerDescription?: string;
......@@ -26,11 +23,11 @@ export interface NotebookEditorDescriptor {
readonly exclusive: boolean;
}
export class NotebookProviderInfo implements NotebookEditorDescriptor {
export class NotebookProviderInfo {
readonly id: string;
readonly displayName: string;
readonly selectors: readonly NotebookSelector[];
readonly priority: NotebookEditorPriority;
// it's optional as the memento might not have it
readonly providerExtensionId?: string;
......@@ -39,11 +36,22 @@ export class NotebookProviderInfo implements NotebookEditorDescriptor {
readonly providerExtensionLocation: URI;
readonly dynamicContribution: boolean;
readonly exclusive: boolean;
private _selectors: NotebookSelector[];
get selectors() {
return this._selectors;
}
private _options: TransientOptions;
get options() {
return this._options;
}
constructor(descriptor: NotebookEditorDescriptor) {
this.id = descriptor.id;
this.displayName = descriptor.displayName;
this.selectors = descriptor.selectors;
this._selectors = descriptor.selectors?.map(selector => ({
include: selector.filenamePattern,
exclude: selector.excludeFileNamePattern || ''
})) || [];
this.priority = descriptor.priority;
this.providerExtensionId = descriptor.providerExtensionId;
this.providerDescription = descriptor.providerDescription;
......@@ -51,6 +59,20 @@ export class NotebookProviderInfo implements NotebookEditorDescriptor {
this.providerExtensionLocation = descriptor.providerExtensionLocation;
this.dynamicContribution = descriptor.dynamicContribution;
this.exclusive = descriptor.exclusive;
this._options = {
transientMetadata: {},
transientOutputs: false
};
}
update(args: { selectors?: NotebookSelector[]; options?: TransientOptions }) {
if (args.selectors) {
this._selectors = args.selectors;
}
if (args.options) {
this._options = args.options;
}
}
matches(resource: URI): boolean {
......@@ -58,25 +80,25 @@ export class NotebookProviderInfo implements NotebookEditorDescriptor {
}
static selectorMatches(selector: NotebookSelector, resource: URI): boolean {
if (!selector.filenamePattern) {
return false;
if (typeof selector === 'string') {
// filenamePattern
if (glob.match(selector.toLowerCase(), basename(resource.fsPath).toLowerCase())) {
return true;
}
}
if (typeof selector.filenamePattern === 'string') {
if (glob.match(selector.filenamePattern.toLowerCase(), basename(resource.fsPath).toLowerCase())) {
if (selector.excludeFileNamePattern) {
if (glob.match(selector.excludeFileNamePattern.toLowerCase(), basename(resource.fsPath).toLowerCase())) {
// should exclude
return false;
}
}
if (glob.isRelativePattern(selector)) {
if (glob.match(selector, basename(resource.fsPath).toLowerCase())) {
return true;
}
}
let filenamePattern = isDocumentExcludePattern(selector.filenamePattern) ? selector.filenamePattern.include : (selector.filenamePattern as string | glob.IRelativePattern);
let excludeFilenamePattern = isDocumentExcludePattern(selector.filenamePattern) ? selector.filenamePattern.exclude : undefined;
if (!isDocumentExcludePattern(selector)) {
return false;
}
let filenamePattern = selector.include;
let excludeFilenamePattern = selector.exclude;
if (glob.match(filenamePattern, basename(resource.fsPath).toLowerCase())) {
if (excludeFilenamePattern) {
......
......@@ -59,7 +59,7 @@ export interface INotebookService {
resolveNotebook(viewType: string, uri: URI, forceReload: boolean, backupId?: string): Promise<NotebookTextModel>;
getNotebookTextModel(uri: URI): NotebookTextModel | undefined;
getNotebookTextModels(): Iterable<NotebookTextModel>;
getContributedNotebookProviders(resource: URI): readonly NotebookProviderInfo[];
getContributedNotebookProviders(resource?: URI): readonly NotebookProviderInfo[];
getContributedNotebookProvider(viewType: string): NotebookProviderInfo | undefined;
getNotebookProviderResourceRoots(): URI[];
destoryNotebookDocument(viewType: string, notebook: INotebookTextModel): void;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册