From 26b00a394e9a7725ac5cd033e91a945d96fbbaaa Mon Sep 17 00:00:00 2001 From: rebornix Date: Fri, 18 Sep 2020 11:36:24 -0700 Subject: [PATCH] support cell range in notebook.cell.execute command --- .../notebook/browser/contrib/coreActions.ts | 114 ++++++++++++++++-- 1 file changed, 102 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts b/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts index f156a51c5ef..455575b41af 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts @@ -20,7 +20,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, NotebookCellMetadata, NotebookCellRunState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, ICellRange, NotebookCellMetadata, NotebookCellRunState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } 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'; @@ -167,28 +167,36 @@ abstract class NotebookAction extends Action2 { } } -abstract class NotebookCellAction extends NotebookAction { +abstract class NotebookCellAction extends NotebookAction { protected isCellActionContext(context?: unknown): context is INotebookCellActionContext { return !!context && !!(context as INotebookCellActionContext).notebookEditor && !!(context as INotebookCellActionContext).cell; } + protected getCellContextFromArgs(accessor: ServicesAccessor, context?: T): INotebookCellActionContext | undefined { + return undefined; + } + async run(accessor: ServicesAccessor, context?: INotebookCellActionContext): Promise { - if (!this.isCellActionContext(context)) { - const activeEditorContext = this.getActiveEditorContext(accessor); - if (this.isCellActionContext(activeEditorContext)) { - context = activeEditorContext; - } else { - return; - } + if (this.isCellActionContext(context)) { + return this.runWithContext(accessor, context); } - this.runWithContext(accessor, context); + const contextFromArgs = this.getCellContextFromArgs(accessor, context); + + if (contextFromArgs) { + return this.runWithContext(accessor, contextFromArgs); + } + + const activeEditorContext = this.getActiveEditorContext(accessor); + if (this.isCellActionContext(activeEditorContext)) { + return this.runWithContext(accessor, activeEditorContext); + } } abstract runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise; } -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookCellAction { constructor() { super({ id: EXECUTE_CELL_COMMAND_ID, @@ -201,24 +209,106 @@ registerAction2(class extends NotebookCellAction { }, weight: EDITOR_WIDGET_ACTION_WEIGHT }, + description: { + description: localize('notebookActions.execute', "Execute Cell"), + args: [ + { + name: 'range', + description: 'The cell range', + schema: { + 'type': 'object', + 'required': ['start', 'end'], + 'properties': { + 'start': { + 'type': 'number' + }, + 'end': { + 'type': 'number' + } + } + } + } + ] + }, icon: { id: 'codicon/play' }, }); } + getCellContextFromArgs(accessor: ServicesAccessor, context?: ICellRange): INotebookCellActionContext | undefined { + if (!context || typeof context.start !== 'number' || typeof context.end !== 'number' || context.start >= context.end) { + return; + } + + const activeEditorContext = this.getActiveEditorContext(accessor); + + if (!activeEditorContext || !activeEditorContext.notebookEditor.viewModel || context.start >= activeEditorContext.notebookEditor.viewModel.viewCells.length) { + return; + } + + const cells = activeEditorContext.notebookEditor.viewModel.viewCells; + + // TODO@rebornix, support multiple cells + return { + notebookEditor: activeEditorContext.notebookEditor, + cell: cells[context.start] + }; + } + async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise { return runCell(accessor, context); } }); -registerAction2(class extends NotebookCellAction { +registerAction2(class extends NotebookCellAction { constructor() { super({ id: CANCEL_CELL_COMMAND_ID, title: localize('notebookActions.cancel', "Stop Cell Execution"), icon: { id: 'codicon/primitive-square' }, + description: { + description: localize('notebookActions.execute', "Execute Cell"), + args: [ + { + name: 'range', + description: 'The cell range', + schema: { + 'type': 'object', + 'required': ['start', 'end'], + 'properties': { + 'start': { + 'type': 'number' + }, + 'end': { + 'type': 'number' + } + } + } + } + ] + }, }); } + getCellContextFromArgs(accessor: ServicesAccessor, context?: ICellRange): INotebookCellActionContext | undefined { + if (!context || typeof context.start !== 'number' || typeof context.end !== 'number' || context.start >= context.end) { + return; + } + + const activeEditorContext = this.getActiveEditorContext(accessor); + + if (!activeEditorContext || !activeEditorContext.notebookEditor.viewModel || context.start >= activeEditorContext.notebookEditor.viewModel.viewCells.length) { + return; + } + + const cells = activeEditorContext.notebookEditor.viewModel.viewCells; + + // TODO@rebornix, support multiple cells + return { + notebookEditor: activeEditorContext.notebookEditor, + cell: cells[context.start] + }; + } + async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise { return context.notebookEditor.cancelNotebookCellExecution(context.cell); }