Path: blob/main/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.ts
5240 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Codicon } from '../../../../../base/common/codicons.js';6import { KeyCode, KeyMod } from '../../../../../base/common/keyCodes.js';7import { ILanguageService } from '../../../../../editor/common/languages/language.js';8import { localize } from '../../../../../nls.js';9import { IAction2Options, MenuId, MenuRegistry, registerAction2 } from '../../../../../platform/actions/common/actions.js';10import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';11import { InputFocusedContext } from '../../../../../platform/contextkey/common/contextkeys.js';12import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';13import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';14import { insertCell } from './cellOperations.js';15import { INotebookActionContext, NotebookAction } from './coreActions.js';16import { NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_EDITOR_EDITABLE } from '../../common/notebookContextKeys.js';17import { CellViewModel } from '../viewModel/notebookViewModelImpl.js';18import { CellKind, NotebookSetting } from '../../common/notebookCommon.js';19import { INotebookKernelHistoryService } from '../../common/notebookKernelService.js';2021const INSERT_CODE_CELL_ABOVE_COMMAND_ID = 'notebook.cell.insertCodeCellAbove';22const INSERT_CODE_CELL_BELOW_COMMAND_ID = 'notebook.cell.insertCodeCellBelow';23const INSERT_CODE_CELL_ABOVE_AND_FOCUS_CONTAINER_COMMAND_ID = 'notebook.cell.insertCodeCellAboveAndFocusContainer';24const INSERT_CODE_CELL_BELOW_AND_FOCUS_CONTAINER_COMMAND_ID = 'notebook.cell.insertCodeCellBelowAndFocusContainer';25const INSERT_CODE_CELL_AT_TOP_COMMAND_ID = 'notebook.cell.insertCodeCellAtTop';26const INSERT_MARKDOWN_CELL_ABOVE_COMMAND_ID = 'notebook.cell.insertMarkdownCellAbove';27const INSERT_MARKDOWN_CELL_BELOW_COMMAND_ID = 'notebook.cell.insertMarkdownCellBelow';28const INSERT_MARKDOWN_CELL_AT_TOP_COMMAND_ID = 'notebook.cell.insertMarkdownCellAtTop';2930export function insertNewCell(accessor: ServicesAccessor, context: INotebookActionContext, kind: CellKind, direction: 'above' | 'below', focusEditor: boolean) {31let newCell: CellViewModel | null = null;32if (context.ui) {33context.notebookEditor.focus();34}3536const languageService = accessor.get(ILanguageService);37const kernelHistoryService = accessor.get(INotebookKernelHistoryService);3839if (context.cell) {40const idx = context.notebookEditor.getCellIndex(context.cell);41newCell = insertCell(languageService, context.notebookEditor, idx, kind, direction, undefined, true, kernelHistoryService);42} else {43const focusRange = context.notebookEditor.getFocus();44const next = Math.max(focusRange.end - 1, 0);45newCell = insertCell(languageService, context.notebookEditor, next, kind, direction, undefined, true, kernelHistoryService);46}4748return newCell;49}5051export abstract class InsertCellCommand extends NotebookAction {52constructor(53desc: Readonly<IAction2Options>,54private kind: CellKind,55private direction: 'above' | 'below',56private focusEditor: boolean57) {58super(desc);59}6061async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext): Promise<void> {62const newCell = await insertNewCell(accessor, context, this.kind, this.direction, this.focusEditor);6364if (newCell) {65await context.notebookEditor.focusNotebookCell(newCell, this.focusEditor ? 'editor' : 'container');66}67}68}6970registerAction2(class InsertCodeCellAboveAction extends InsertCellCommand {71constructor() {72super(73{74id: INSERT_CODE_CELL_ABOVE_COMMAND_ID,75title: localize('notebookActions.insertCodeCellAbove', "Insert Code Cell Above"),76keybinding: {77primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter,78when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, InputFocusedContext.toNegated()),79weight: KeybindingWeight.WorkbenchContrib80},81menu: {82id: MenuId.NotebookCellInsert,83order: 084}85},86CellKind.Code,87'above',88true);89}90});91929394registerAction2(class InsertCodeCellAboveAndFocusContainerAction extends InsertCellCommand {95constructor() {96super(97{98id: INSERT_CODE_CELL_ABOVE_AND_FOCUS_CONTAINER_COMMAND_ID,99title: localize('notebookActions.insertCodeCellAboveAndFocusContainer', "Insert Code Cell Above and Focus Container")100},101CellKind.Code,102'above',103false);104}105});106107registerAction2(class InsertCodeCellBelowAction extends InsertCellCommand {108constructor() {109super(110{111id: INSERT_CODE_CELL_BELOW_COMMAND_ID,112title: localize('notebookActions.insertCodeCellBelow', "Insert Code Cell Below"),113keybinding: {114primary: KeyMod.CtrlCmd | KeyCode.Enter,115when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, InputFocusedContext.toNegated()),116weight: KeybindingWeight.WorkbenchContrib117},118menu: {119id: MenuId.NotebookCellInsert,120order: 1121}122},123CellKind.Code,124'below',125true);126}127});128129registerAction2(class InsertCodeCellBelowAndFocusContainerAction extends InsertCellCommand {130constructor() {131super(132{133id: INSERT_CODE_CELL_BELOW_AND_FOCUS_CONTAINER_COMMAND_ID,134title: localize('notebookActions.insertCodeCellBelowAndFocusContainer', "Insert Code Cell Below and Focus Container"),135},136CellKind.Code,137'below',138false);139}140});141142143registerAction2(class InsertMarkdownCellAboveAction extends InsertCellCommand {144constructor() {145super(146{147id: INSERT_MARKDOWN_CELL_ABOVE_COMMAND_ID,148title: localize('notebookActions.insertMarkdownCellAbove', "Insert Markdown Cell Above"),149menu: {150id: MenuId.NotebookCellInsert,151order: 2152}153},154CellKind.Markup,155'above',156true);157}158});159160registerAction2(class InsertMarkdownCellBelowAction extends InsertCellCommand {161constructor() {162super(163{164id: INSERT_MARKDOWN_CELL_BELOW_COMMAND_ID,165title: localize('notebookActions.insertMarkdownCellBelow', "Insert Markdown Cell Below"),166menu: {167id: MenuId.NotebookCellInsert,168order: 3169}170},171CellKind.Markup,172'below',173true);174}175});176177178registerAction2(class InsertCodeCellAtTopAction extends NotebookAction {179constructor() {180super(181{182id: INSERT_CODE_CELL_AT_TOP_COMMAND_ID,183title: localize('notebookActions.insertCodeCellAtTop', "Add Code Cell At Top"),184f1: false185});186}187188override async run(accessor: ServicesAccessor, context?: INotebookActionContext): Promise<void> {189context = context ?? this.getEditorContextFromArgsOrActive(accessor);190if (context) {191this.runWithContext(accessor, context);192}193}194195async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext): Promise<void> {196const languageService = accessor.get(ILanguageService);197const kernelHistoryService = accessor.get(INotebookKernelHistoryService);198const newCell = insertCell(languageService, context.notebookEditor, 0, CellKind.Code, 'above', undefined, true, kernelHistoryService);199200if (newCell) {201await context.notebookEditor.focusNotebookCell(newCell, 'editor');202}203}204});205206registerAction2(class InsertMarkdownCellAtTopAction extends NotebookAction {207constructor() {208super(209{210id: INSERT_MARKDOWN_CELL_AT_TOP_COMMAND_ID,211title: localize('notebookActions.insertMarkdownCellAtTop', "Add Markdown Cell At Top"),212f1: false213});214}215216override async run(accessor: ServicesAccessor, context?: INotebookActionContext): Promise<void> {217context = context ?? this.getEditorContextFromArgsOrActive(accessor);218if (context) {219this.runWithContext(accessor, context);220}221}222223async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext): Promise<void> {224const languageService = accessor.get(ILanguageService);225const kernelHistoryService = accessor.get(INotebookKernelHistoryService);226227const newCell = insertCell(languageService, context.notebookEditor, 0, CellKind.Markup, 'above', undefined, true, kernelHistoryService);228229if (newCell) {230await context.notebookEditor.focusNotebookCell(newCell, 'editor');231}232}233});234235MenuRegistry.appendMenuItem(MenuId.NotebookCellBetween, {236command: {237id: INSERT_CODE_CELL_BELOW_COMMAND_ID,238title: '$(add) ' + localize('notebookActions.menu.insertCode', "Code"),239tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell")240},241order: 0,242group: 'inline',243when: ContextKeyExpr.and(244NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),245ContextKeyExpr.notEquals('config.notebook.experimental.insertToolbarAlignment', 'left')246)247});248249MenuRegistry.appendMenuItem(MenuId.NotebookCellBetween, {250command: {251id: INSERT_CODE_CELL_BELOW_COMMAND_ID,252title: localize('notebookActions.menu.insertCode.minimalToolbar', "Add Code"),253icon: Codicon.add,254tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell")255},256order: 0,257group: 'inline',258when: ContextKeyExpr.and(259NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),260ContextKeyExpr.equals('config.notebook.experimental.insertToolbarAlignment', 'left')261)262});263264MenuRegistry.appendMenuItem(MenuId.NotebookToolbar, {265command: {266id: INSERT_CODE_CELL_BELOW_COMMAND_ID,267icon: Codicon.add,268title: localize('notebookActions.menu.insertCode.ontoolbar', "Code"),269tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell")270},271order: -5,272group: 'navigation/add',273when: ContextKeyExpr.and(274NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),275ContextKeyExpr.notEquals('config.notebook.insertToolbarLocation', 'betweenCells'),276ContextKeyExpr.notEquals('config.notebook.insertToolbarLocation', 'hidden')277)278});279280MenuRegistry.appendMenuItem(MenuId.NotebookCellListTop, {281command: {282id: INSERT_CODE_CELL_AT_TOP_COMMAND_ID,283title: '$(add) ' + localize('notebookActions.menu.insertCode', "Code"),284tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell")285},286order: 0,287group: 'inline',288when: ContextKeyExpr.and(289NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),290ContextKeyExpr.notEquals('config.notebook.experimental.insertToolbarAlignment', 'left')291)292});293294MenuRegistry.appendMenuItem(MenuId.NotebookCellListTop, {295command: {296id: INSERT_CODE_CELL_AT_TOP_COMMAND_ID,297title: localize('notebookActions.menu.insertCode.minimaltoolbar', "Add Code"),298icon: Codicon.add,299tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell")300},301order: 0,302group: 'inline',303when: ContextKeyExpr.and(304NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),305ContextKeyExpr.equals('config.notebook.experimental.insertToolbarAlignment', 'left')306)307});308309310MenuRegistry.appendMenuItem(MenuId.NotebookCellBetween, {311command: {312id: INSERT_MARKDOWN_CELL_BELOW_COMMAND_ID,313title: '$(add) ' + localize('notebookActions.menu.insertMarkdown', "Markdown"),314tooltip: localize('notebookActions.menu.insertMarkdown.tooltip', "Add Markdown Cell")315},316order: 1,317group: 'inline',318when: ContextKeyExpr.and(319NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),320ContextKeyExpr.notEquals('config.notebook.experimental.insertToolbarAlignment', 'left')321)322});323324MenuRegistry.appendMenuItem(MenuId.NotebookToolbar, {325command: {326id: INSERT_MARKDOWN_CELL_BELOW_COMMAND_ID,327icon: Codicon.add,328title: localize('notebookActions.menu.insertMarkdown.ontoolbar', "Markdown"),329tooltip: localize('notebookActions.menu.insertMarkdown.tooltip', "Add Markdown Cell")330},331order: -5,332group: 'navigation/add',333when: ContextKeyExpr.and(334NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),335ContextKeyExpr.notEquals('config.notebook.insertToolbarLocation', 'betweenCells'),336ContextKeyExpr.notEquals('config.notebook.insertToolbarLocation', 'hidden'),337ContextKeyExpr.notEquals(`config.${NotebookSetting.globalToolbarShowLabel}`, false),338ContextKeyExpr.notEquals(`config.${NotebookSetting.globalToolbarShowLabel}`, 'never')339)340});341342MenuRegistry.appendMenuItem(MenuId.NotebookCellListTop, {343command: {344id: INSERT_MARKDOWN_CELL_AT_TOP_COMMAND_ID,345title: '$(add) ' + localize('notebookActions.menu.insertMarkdown', "Markdown"),346tooltip: localize('notebookActions.menu.insertMarkdown.tooltip', "Add Markdown Cell")347},348order: 1,349group: 'inline',350when: ContextKeyExpr.and(351NOTEBOOK_EDITOR_EDITABLE.isEqualTo(true),352ContextKeyExpr.notEquals('config.notebook.experimental.insertToolbarAlignment', 'left')353)354});355356357