@theia/notebook 1.53.0-next.4 → 1.53.0-next.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +30 -30
  2. package/lib/browser/contributions/cell-operations.d.ts.map +1 -1
  3. package/lib/browser/contributions/cell-operations.js +8 -1
  4. package/lib/browser/contributions/cell-operations.js.map +1 -1
  5. package/lib/browser/contributions/notebook-actions-contribution.d.ts +1 -0
  6. package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -1
  7. package/lib/browser/contributions/notebook-actions-contribution.js +31 -6
  8. package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -1
  9. package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts +4 -0
  10. package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts.map +1 -1
  11. package/lib/browser/contributions/notebook-cell-actions-contribution.js +49 -12
  12. package/lib/browser/contributions/notebook-cell-actions-contribution.js.map +1 -1
  13. package/lib/browser/contributions/notebook-status-bar-contribution.d.ts +14 -0
  14. package/lib/browser/contributions/notebook-status-bar-contribution.d.ts.map +1 -0
  15. package/lib/browser/contributions/notebook-status-bar-contribution.js +75 -0
  16. package/lib/browser/contributions/notebook-status-bar-contribution.js.map +1 -0
  17. package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
  18. package/lib/browser/notebook-editor-widget.js +3 -5
  19. package/lib/browser/notebook-editor-widget.js.map +1 -1
  20. package/lib/browser/notebook-frontend-module.d.ts.map +1 -1
  21. package/lib/browser/notebook-frontend-module.js +3 -0
  22. package/lib/browser/notebook-frontend-module.js.map +1 -1
  23. package/lib/browser/notebook-open-handler.d.ts +3 -2
  24. package/lib/browser/notebook-open-handler.d.ts.map +1 -1
  25. package/lib/browser/notebook-open-handler.js +12 -5
  26. package/lib/browser/notebook-open-handler.js.map +1 -1
  27. package/lib/browser/service/notebook-options.d.ts +1 -0
  28. package/lib/browser/service/notebook-options.d.ts.map +1 -1
  29. package/lib/browser/service/notebook-options.js +1 -0
  30. package/lib/browser/service/notebook-options.js.map +1 -1
  31. package/lib/browser/service/notebook-service.d.ts +1 -0
  32. package/lib/browser/service/notebook-service.d.ts.map +1 -1
  33. package/lib/browser/service/notebook-service.js +7 -0
  34. package/lib/browser/service/notebook-service.js.map +1 -1
  35. package/lib/browser/view/notebook-cell-editor.d.ts +1 -0
  36. package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -1
  37. package/lib/browser/view/notebook-cell-editor.js +30 -16
  38. package/lib/browser/view/notebook-cell-editor.js.map +1 -1
  39. package/lib/browser/view/notebook-cell-list-view.d.ts +7 -4
  40. package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
  41. package/lib/browser/view/notebook-cell-list-view.js +39 -29
  42. package/lib/browser/view/notebook-cell-list-view.js.map +1 -1
  43. package/lib/browser/view-model/notebook-cell-model.d.ts +3 -0
  44. package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -1
  45. package/lib/browser/view-model/notebook-cell-model.js +5 -0
  46. package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
  47. package/package.json +8 -8
  48. package/src/browser/contributions/cell-operations.ts +44 -39
  49. package/src/browser/contributions/notebook-actions-contribution.ts +379 -351
  50. package/src/browser/contributions/notebook-cell-actions-contribution.ts +525 -485
  51. package/src/browser/contributions/notebook-color-contribution.ts +268 -268
  52. package/src/browser/contributions/notebook-context-keys.ts +113 -113
  53. package/src/browser/contributions/notebook-label-provider-contribution.ts +85 -85
  54. package/src/browser/contributions/notebook-outline-contribution.ts +114 -114
  55. package/src/browser/contributions/notebook-output-action-contribution.ts +82 -82
  56. package/src/browser/contributions/notebook-preferences.ts +92 -92
  57. package/src/browser/contributions/notebook-status-bar-contribution.ts +77 -0
  58. package/src/browser/contributions/notebook-undo-redo-handler.ts +41 -41
  59. package/src/browser/index.ts +27 -27
  60. package/src/browser/notebook-cell-resource-resolver.ts +130 -130
  61. package/src/browser/notebook-editor-widget-factory.ts +82 -82
  62. package/src/browser/notebook-editor-widget.tsx +330 -331
  63. package/src/browser/notebook-frontend-module.ts +119 -115
  64. package/src/browser/notebook-open-handler.ts +120 -114
  65. package/src/browser/notebook-output-utils.ts +119 -119
  66. package/src/browser/notebook-renderer-registry.ts +85 -85
  67. package/src/browser/notebook-type-registry.ts +54 -54
  68. package/src/browser/notebook-types.ts +186 -186
  69. package/src/browser/renderers/cell-output-webview.ts +33 -33
  70. package/src/browser/service/notebook-clipboard-service.ts +43 -43
  71. package/src/browser/service/notebook-context-manager.ts +162 -162
  72. package/src/browser/service/notebook-editor-widget-service.ts +101 -101
  73. package/src/browser/service/notebook-execution-service.ts +139 -139
  74. package/src/browser/service/notebook-execution-state-service.ts +311 -311
  75. package/src/browser/service/notebook-kernel-history-service.ts +124 -124
  76. package/src/browser/service/notebook-kernel-quick-pick-service.ts +479 -479
  77. package/src/browser/service/notebook-kernel-service.ts +357 -357
  78. package/src/browser/service/notebook-model-resolver-service.ts +160 -160
  79. package/src/browser/service/notebook-monaco-text-model-service.ts +48 -48
  80. package/src/browser/service/notebook-options.ts +155 -154
  81. package/src/browser/service/notebook-renderer-messaging-service.ts +121 -121
  82. package/src/browser/service/notebook-service.ts +215 -209
  83. package/src/browser/style/index.css +483 -467
  84. package/src/browser/view/notebook-cell-editor.tsx +263 -247
  85. package/src/browser/view/notebook-cell-list-view.tsx +279 -259
  86. package/src/browser/view/notebook-cell-toolbar-factory.tsx +102 -102
  87. package/src/browser/view/notebook-cell-toolbar.tsx +74 -74
  88. package/src/browser/view/notebook-code-cell-view.tsx +350 -350
  89. package/src/browser/view/notebook-find-widget.tsx +335 -335
  90. package/src/browser/view/notebook-main-toolbar.tsx +235 -235
  91. package/src/browser/view/notebook-markdown-cell-view.tsx +208 -208
  92. package/src/browser/view/notebook-viewport-service.ts +61 -61
  93. package/src/browser/view-model/notebook-cell-model.ts +473 -466
  94. package/src/browser/view-model/notebook-cell-output-model.ts +100 -100
  95. package/src/browser/view-model/notebook-model.ts +550 -550
  96. package/src/common/index.ts +18 -18
  97. package/src/common/notebook-common.ts +337 -337
  98. package/src/common/notebook-protocol.ts +35 -35
  99. package/src/common/notebook-range.ts +30 -30
@@ -1,485 +1,525 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2023 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import { Command, CommandContribution, CommandHandler, CommandRegistry, CompoundMenuNodeRole, MenuContribution, MenuModelRegistry, nls } from '@theia/core';
18
- import { codicon, Key, KeybindingContribution, KeybindingRegistry, KeyCode, KeyModifier } from '@theia/core/lib/browser';
19
- import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
20
- import { NotebookModel } from '../view-model/notebook-model';
21
- import { NotebookCellModel } from '../view-model/notebook-cell-model';
22
- import {
23
- NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_TYPE,
24
- NotebookContextKeys, NOTEBOOK_CELL_EXECUTING, NOTEBOOK_EDITOR_FOCUSED,
25
- NOTEBOOK_CELL_FOCUSED,
26
- NOTEBOOK_CELL_LIST_FOCUSED
27
- } from './notebook-context-keys';
28
- import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
29
- import { NotebookExecutionService } from '../service/notebook-execution-service';
30
- import { NotebookCellOutputModel } from '../view-model/notebook-cell-output-model';
31
- import { CellEditType, CellKind } from '../../common';
32
- import { NotebookEditorWidgetService } from '../service/notebook-editor-widget-service';
33
- import { NotebookCommands } from './notebook-actions-contribution';
34
- import { changeCellType } from './cell-operations';
35
- import { EditorLanguageQuickPickService } from '@theia/editor/lib/browser/editor-language-quick-pick-service';
36
-
37
- export namespace NotebookCellCommands {
38
- /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
39
- export const EDIT_COMMAND = Command.toDefaultLocalizedCommand({
40
- id: 'notebook.cell.edit',
41
- iconClass: codicon('edit')
42
- });
43
- /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
44
- export const STOP_EDIT_COMMAND = Command.toDefaultLocalizedCommand({
45
- id: 'notebook.cell.stop-edit',
46
- iconClass: codicon('check')
47
- });
48
- /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
49
- export const DELETE_COMMAND = Command.toDefaultLocalizedCommand({
50
- id: 'notebook.cell.delete',
51
- iconClass: codicon('trash')
52
- });
53
- /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
54
- export const SPLIT_CELL_COMMAND = Command.toDefaultLocalizedCommand({
55
- id: 'notebook.cell.split-cell',
56
- iconClass: codicon('split-vertical'),
57
- });
58
- /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
59
- export const EXECUTE_SINGLE_CELL_COMMAND = Command.toDefaultLocalizedCommand({
60
- id: 'notebook.cell.execute-cell',
61
- iconClass: codicon('play'),
62
- });
63
- /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
64
- export const EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND = Command.toDefaultLocalizedCommand({
65
- id: 'notebook.cell.execute-cell-and-focus-next',
66
- });
67
-
68
- export const EXECUTE_ABOVE_CELLS_COMMAND = Command.toDefaultLocalizedCommand({
69
- id: 'notebookActions.executeAbove',
70
- label: 'Execute Above Cells',
71
- iconClass: codicon('run-above')
72
- });
73
-
74
- export const EXECUTE_CELL_AND_BELOW_COMMAND = Command.toDefaultLocalizedCommand({
75
- id: 'notebookActions.executeBelow',
76
- label: 'Execute Cell and Below',
77
- iconClass: codicon('run-below')
78
- });
79
- /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
80
- export const STOP_CELL_EXECUTION_COMMAND = Command.toDefaultLocalizedCommand({
81
- id: 'notebook.cell.stop-cell-execution',
82
- iconClass: codicon('stop'),
83
- });
84
- /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
85
- export const CLEAR_OUTPUTS_COMMAND = Command.toDefaultLocalizedCommand({
86
- id: 'notebook.cell.clear-outputs',
87
- label: 'Clear Cell Outputs',
88
- });
89
- /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel | undefined, output: NotebookCellOutputModel */
90
- export const CHANGE_OUTPUT_PRESENTATION_COMMAND = Command.toDefaultLocalizedCommand({
91
- id: 'notebook.cell.change-presentation',
92
- label: 'Change Presentation',
93
- });
94
-
95
- export const INSERT_NEW_CELL_ABOVE_COMMAND = Command.toDefaultLocalizedCommand({
96
- id: 'notebook.cell.insertCodeCellAboveAndFocusContainer',
97
- label: 'Insert Code Cell Above and Focus Container'
98
- });
99
-
100
- export const INSERT_NEW_CELL_BELOW_COMMAND = Command.toDefaultLocalizedCommand({
101
- id: 'notebook.cell.insertCodeCellBelowAndFocusContainer',
102
- label: 'Insert Code Cell Below and Focus Container'
103
- });
104
-
105
- export const INSERT_MARKDOWN_CELL_ABOVE_COMMAND = Command.toLocalizedCommand({
106
- id: 'notebook.cell.insertMarkdownCellAbove',
107
- label: 'Insert Markdown Cell Above'
108
- });
109
- export const INSERT_MARKDOWN_CELL_BELOW_COMMAND = Command.toLocalizedCommand({
110
- id: 'notebook.cell.insertMarkdownCellBelow',
111
- label: 'Insert Markdown Cell Below'
112
- });
113
-
114
- export const TO_CODE_CELL_COMMAND = Command.toLocalizedCommand({
115
- id: 'notebook.cell.changeToCode',
116
- label: 'Change Cell to Code'
117
- });
118
-
119
- export const TO_MARKDOWN_CELL_COMMAND = Command.toLocalizedCommand({
120
- id: 'notebook.cell.changeToMarkdown',
121
- label: 'Change Cell to Mardown'
122
- });
123
-
124
- export const TOGGLE_CELL_OUTPUT = Command.toDefaultLocalizedCommand({
125
- id: 'notebook.cell.toggleOutputs',
126
- category: 'Notebook',
127
- label: 'Collapse Cell Output',
128
- });
129
-
130
- export const CHANGE_CELL_LANGUAGE = Command.toDefaultLocalizedCommand({
131
- id: 'notebook.cell.changeLanguage',
132
- category: 'Notebook',
133
- label: 'Change Cell Language',
134
- });
135
-
136
- export const TOGGLE_LINE_NUMBERS = Command.toDefaultLocalizedCommand({
137
- id: 'notebook.cell.toggleLineNumbers',
138
- category: 'Notebook',
139
- label: 'Show Cell Line Numbers',
140
- });
141
-
142
- }
143
-
144
- @injectable()
145
- export class NotebookCellActionContribution implements MenuContribution, CommandContribution, KeybindingContribution {
146
-
147
- @inject(ContextKeyService)
148
- protected contextKeyService: ContextKeyService;
149
-
150
- @inject(NotebookExecutionService)
151
- protected notebookExecutionService: NotebookExecutionService;
152
-
153
- @inject(NotebookEditorWidgetService)
154
- protected notebookEditorWidgetService: NotebookEditorWidgetService;
155
-
156
- @inject(EditorLanguageQuickPickService)
157
- protected languageQuickPickService: EditorLanguageQuickPickService;
158
-
159
- @postConstruct()
160
- protected init(): void {
161
- NotebookContextKeys.initNotebookContextKeys(this.contextKeyService);
162
- }
163
-
164
- registerMenus(menus: MenuModelRegistry): void {
165
- menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
166
- commandId: NotebookCellCommands.EDIT_COMMAND.id,
167
- icon: NotebookCellCommands.EDIT_COMMAND.iconClass,
168
- when: `${NOTEBOOK_CELL_TYPE} == 'markdown' && !${NOTEBOOK_CELL_MARKDOWN_EDIT_MODE}`,
169
- label: nls.localizeByDefault('Edit Cell'),
170
- order: '10'
171
- });
172
- menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
173
- commandId: NotebookCellCommands.STOP_EDIT_COMMAND.id,
174
- icon: NotebookCellCommands.STOP_EDIT_COMMAND.iconClass,
175
- when: `${NOTEBOOK_CELL_TYPE} == 'markdown' && ${NOTEBOOK_CELL_MARKDOWN_EDIT_MODE}`,
176
- label: nls.localizeByDefault('Stop Editing Cell'),
177
- order: '10'
178
- });
179
-
180
- menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
181
- commandId: NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND.id,
182
- icon: NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND.iconClass,
183
- when: `${NOTEBOOK_CELL_TYPE} == 'code'`,
184
- label: nls.localizeByDefault('Execute Above Cells'),
185
- order: '10'
186
- });
187
-
188
- menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
189
- commandId: NotebookCellCommands.EXECUTE_CELL_AND_BELOW_COMMAND.id,
190
- icon: NotebookCellCommands.EXECUTE_CELL_AND_BELOW_COMMAND.iconClass,
191
- when: `${NOTEBOOK_CELL_TYPE} == 'code'`,
192
- label: nls.localizeByDefault('Execute Cell and Below'),
193
- order: '20'
194
- });
195
-
196
- // menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
197
- // commandId: NotebookCellCommands.SPLIT_CELL_COMMAND.id,
198
- // icon: NotebookCellCommands.SPLIT_CELL_COMMAND.iconClass,
199
- // label: nls.localizeByDefault('Split Cell'),
200
- // order: '20'
201
- // });
202
-
203
- menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
204
- commandId: NotebookCellCommands.DELETE_COMMAND.id,
205
- icon: NotebookCellCommands.DELETE_COMMAND.iconClass,
206
- label: nls.localizeByDefault('Delete Cell'),
207
- order: '999'
208
- });
209
-
210
- menus.registerSubmenu(
211
- NotebookCellActionContribution.ADDITIONAL_ACTION_MENU,
212
- nls.localizeByDefault('More'),
213
- {
214
- icon: codicon('ellipsis'),
215
- role: CompoundMenuNodeRole.Submenu,
216
- order: '30'
217
- }
218
- );
219
-
220
- menus.registerIndependentSubmenu(NotebookCellActionContribution.CONTRIBUTED_CELL_ACTION_MENU, '', { role: CompoundMenuNodeRole.Flat });
221
- // since contributions are adding to an independent submenu we have to manually add it to the more submenu
222
- menus.getMenu(NotebookCellActionContribution.ADDITIONAL_ACTION_MENU).addNode(menus.getMenuNode(NotebookCellActionContribution.CONTRIBUTED_CELL_ACTION_MENU));
223
-
224
- // code cell sidebar menu
225
- menus.registerMenuAction(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, {
226
- commandId: NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id,
227
- icon: NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.iconClass,
228
- label: nls.localizeByDefault('Execute Cell'),
229
- when: `!${NOTEBOOK_CELL_EXECUTING}`
230
- });
231
- menus.registerMenuAction(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, {
232
- commandId: NotebookCellCommands.STOP_CELL_EXECUTION_COMMAND.id,
233
- icon: NotebookCellCommands.STOP_CELL_EXECUTION_COMMAND.iconClass,
234
- label: nls.localizeByDefault('Stop Cell Execution'),
235
- when: NOTEBOOK_CELL_EXECUTING
236
- });
237
-
238
- // Notebook Cell extra execution options
239
- menus.registerIndependentSubmenu(NotebookCellActionContribution.CONTRIBUTED_CELL_EXECUTION_MENU,
240
- nls.localizeByDefault('More...'),
241
- { role: CompoundMenuNodeRole.Flat, icon: codicon('chevron-down') });
242
- // menus.getMenu(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU).addNode(menus.getMenuNode(NotebookCellActionContribution.CONTRIBUTED_CELL_EXECUTION_MENU));
243
-
244
- // code cell output sidebar menu
245
- menus.registerSubmenu(
246
- NotebookCellActionContribution.ADDITIONAL_OUTPUT_SIDEBAR_MENU,
247
- nls.localizeByDefault('More'),
248
- {
249
- icon: codicon('ellipsis'),
250
- role: CompoundMenuNodeRole.Submenu
251
- });
252
- menus.registerMenuAction(NotebookCellActionContribution.ADDITIONAL_OUTPUT_SIDEBAR_MENU, {
253
- commandId: NotebookCellCommands.CLEAR_OUTPUTS_COMMAND.id,
254
- label: nls.localizeByDefault('Clear Cell Outputs'),
255
- });
256
- menus.registerMenuAction(NotebookCellActionContribution.ADDITIONAL_OUTPUT_SIDEBAR_MENU, {
257
- commandId: NotebookCellCommands.CHANGE_OUTPUT_PRESENTATION_COMMAND.id,
258
- label: nls.localizeByDefault('Change Presentation'),
259
- });
260
-
261
- }
262
-
263
- registerCommands(commands: CommandRegistry): void {
264
- commands.registerCommand(NotebookCellCommands.EDIT_COMMAND, this.editableCellCommandHandler((_, cell) => cell.requestFocusEditor()));
265
- commands.registerCommand(NotebookCellCommands.STOP_EDIT_COMMAND, { execute: (_, cell: NotebookCellModel) => (cell ?? this.getSelectedCell()).requestBlurEditor() });
266
- commands.registerCommand(NotebookCellCommands.DELETE_COMMAND,
267
- this.editableCellCommandHandler((notebookModel, cell) => {
268
- notebookModel.applyEdits([{
269
- editType: CellEditType.Replace,
270
- index: notebookModel.cells.indexOf(cell),
271
- count: 1,
272
- cells: []
273
- }]
274
- , true);
275
- }));
276
- commands.registerCommand(NotebookCellCommands.SPLIT_CELL_COMMAND);
277
-
278
- commands.registerCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND, this.editableCellCommandHandler(
279
- (notebookModel, cell) => {
280
- this.notebookExecutionService.executeNotebookCells(notebookModel, [cell]);
281
- })
282
- );
283
-
284
- commands.registerCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND, this.editableCellCommandHandler(
285
- (notebookModel, cell) => {
286
- if (cell.cellKind === CellKind.Code) {
287
- commands.executeCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id, notebookModel, cell);
288
- } else {
289
- commands.executeCommand(NotebookCellCommands.STOP_EDIT_COMMAND.id, notebookModel, cell);
290
- }
291
- const index = notebookModel.cells.indexOf(cell);
292
- if (index < notebookModel.cells.length - 1) {
293
- notebookModel.setSelectedCell(notebookModel.cells[index + 1]);
294
- } else if (cell.cellKind === CellKind.Code) {
295
- commands.executeCommand(NotebookCellCommands.INSERT_NEW_CELL_BELOW_COMMAND.id);
296
- } else {
297
- commands.executeCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_BELOW_COMMAND.id);
298
- }
299
- })
300
- );
301
-
302
- commands.registerCommand(NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND, this.editableCellCommandHandler(
303
- (notebookModel, cell) => {
304
- const index = notebookModel.cells.indexOf(cell);
305
- if (index > 0) {
306
- this.notebookExecutionService.executeNotebookCells(notebookModel, notebookModel.cells.slice(0, index).filter(c => c.cellKind === CellKind.Code));
307
- }
308
- })
309
- );
310
-
311
- commands.registerCommand(NotebookCellCommands.EXECUTE_CELL_AND_BELOW_COMMAND, this.editableCellCommandHandler(
312
- (notebookModel, cell) => {
313
- const index = notebookModel.cells.indexOf(cell);
314
- if (index < notebookModel.cells.length - 1) {
315
- this.notebookExecutionService.executeNotebookCells(notebookModel, notebookModel.cells.slice(index).filter(c => c.cellKind === CellKind.Code));
316
- }
317
- })
318
- );
319
-
320
- commands.registerCommand(NotebookCellCommands.STOP_CELL_EXECUTION_COMMAND, {
321
- execute: (notebookModel: NotebookModel, cell: NotebookCellModel) => {
322
- notebookModel = notebookModel ?? this.notebookEditorWidgetService.focusedEditor?.model;
323
- cell = cell ?? this.getSelectedCell();
324
- this.notebookExecutionService.cancelNotebookCells(notebookModel, [cell]);
325
- }
326
- });
327
- commands.registerCommand(NotebookCellCommands.CLEAR_OUTPUTS_COMMAND, this.editableCellCommandHandler(
328
- (notebook, cell) => (notebook ?? this.notebookEditorWidgetService.focusedEditor?.model)?.applyEdits([{
329
- editType: CellEditType.Output,
330
- handle: cell.handle,
331
- outputs: [],
332
- deleteCount: cell.outputs.length,
333
- append: false
334
- }], true)
335
- ));
336
- commands.registerCommand(NotebookCellCommands.CHANGE_OUTPUT_PRESENTATION_COMMAND, this.editableCellCommandHandler(
337
- (_, __, output) => output?.requestOutputPresentationUpdate()
338
- ));
339
-
340
- const insertCommand = (type: CellKind, index: number | 'above' | 'below'): CommandHandler => this.editableCellCommandHandler(() =>
341
- commands.executeCommand(NotebookCommands.ADD_NEW_CELL_COMMAND.id, undefined, type, index)
342
- );
343
- commands.registerCommand(NotebookCellCommands.INSERT_NEW_CELL_ABOVE_COMMAND, insertCommand(CellKind.Code, 'above'));
344
- commands.registerCommand(NotebookCellCommands.INSERT_NEW_CELL_BELOW_COMMAND, insertCommand(CellKind.Code, 'below'));
345
- commands.registerCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_ABOVE_COMMAND, insertCommand(CellKind.Markup, 'above'));
346
- commands.registerCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_BELOW_COMMAND, insertCommand(CellKind.Markup, 'below'));
347
-
348
- commands.registerCommand(NotebookCellCommands.TO_CODE_CELL_COMMAND, this.editableCellCommandHandler((notebookModel, cell) => {
349
- changeCellType(notebookModel, cell, CellKind.Code);
350
- }));
351
- commands.registerCommand(NotebookCellCommands.TO_MARKDOWN_CELL_COMMAND, this.editableCellCommandHandler((notebookModel, cell) => {
352
- changeCellType(notebookModel, cell, CellKind.Markup);
353
- }));
354
-
355
- commands.registerCommand(NotebookCellCommands.TOGGLE_CELL_OUTPUT, {
356
- execute: () => {
357
- const selectedCell = this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
358
- if (selectedCell) {
359
- selectedCell.outputVisible = !selectedCell.outputVisible;
360
- }
361
- }
362
- });
363
-
364
- commands.registerCommand(NotebookCellCommands.CHANGE_CELL_LANGUAGE, {
365
- isVisible: () => !!this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell,
366
- execute: async (notebook?: NotebookModel, cell?: NotebookCellModel) => {
367
- const selectedCell = cell ?? this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
368
- const activeNotebook = notebook ?? this.notebookEditorWidgetService.focusedEditor?.model;
369
- if (!selectedCell || !activeNotebook) {
370
- return;
371
- }
372
- const language = await this.languageQuickPickService.pickEditorLanguage(selectedCell.language);
373
- if (!language?.value || language.value === 'autoDetect' || language.value.id === selectedCell.language) {
374
- return;
375
- }
376
- const isMarkdownCell = selectedCell.cellKind === CellKind.Markup;
377
- const isMarkdownLanguage = language.value.id === 'markdown';
378
- if (isMarkdownLanguage) {
379
- if (!isMarkdownCell) {
380
- changeCellType(activeNotebook, selectedCell, CellKind.Markup, language.value.id);
381
- }
382
- } else {
383
- if (isMarkdownCell) {
384
- changeCellType(activeNotebook, selectedCell, CellKind.Code, language.value.id);
385
- } else {
386
- this.notebookEditorWidgetService.focusedEditor?.model?.applyEdits([{
387
- editType: CellEditType.CellLanguage,
388
- index: activeNotebook.cells.indexOf(selectedCell),
389
- language: language.value.id
390
- }], true);
391
- }
392
- }
393
- }
394
- });
395
-
396
- commands.registerCommand(NotebookCellCommands.TOGGLE_LINE_NUMBERS, {
397
- execute: () => {
398
- const selectedCell = this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
399
- if (selectedCell) {
400
- const currentLineNumber = selectedCell.editorOptions?.lineNumbers;
401
- selectedCell.editorOptions = { ...selectedCell.editorOptions, lineNumbers: !currentLineNumber || currentLineNumber === 'off' ? 'on' : 'off' };
402
- }
403
- }
404
- });
405
-
406
- }
407
-
408
- protected editableCellCommandHandler(execute: (notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel) => void): CommandHandler {
409
- return {
410
- isEnabled: (notebookModel: NotebookModel) => !Boolean(notebookModel?.readOnly),
411
- isVisible: (notebookModel: NotebookModel) => !Boolean(notebookModel?.readOnly),
412
- execute: (notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel) => {
413
- notebookModel = notebookModel ?? this.notebookEditorWidgetService.focusedEditor?.model;
414
- cell = cell ?? this.getSelectedCell();
415
- execute(notebookModel, cell, output);
416
- }
417
- };
418
- }
419
-
420
- protected getSelectedCell(): NotebookCellModel | undefined {
421
- return this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
422
- }
423
-
424
- registerKeybindings(keybindings: KeybindingRegistry): void {
425
- keybindings.registerKeybindings(
426
- {
427
- command: NotebookCellCommands.EDIT_COMMAND.id,
428
- keybinding: 'Enter',
429
- when: `!editorTextFocus && !inputFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
430
- },
431
- {
432
- command: NotebookCellCommands.STOP_EDIT_COMMAND.id,
433
- keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Alt] }).toString(),
434
- when: `editorTextFocus && !inputFocus && ${NOTEBOOK_EDITOR_FOCUSED}`,
435
- },
436
- {
437
- command: NotebookCellCommands.STOP_EDIT_COMMAND.id,
438
- keybinding: 'esc',
439
- when: `editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED}`,
440
- },
441
- {
442
- command: NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id,
443
- keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.CtrlCmd] }).toString(),
444
- when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
445
- },
446
- {
447
- command: NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND.id,
448
- keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Shift] }).toString(),
449
- when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
450
- },
451
- {
452
- command: NotebookCellCommands.CLEAR_OUTPUTS_COMMAND.id,
453
- keybinding: KeyCode.createKeyCode({ first: Key.KEY_O, modifiers: [KeyModifier.Alt] }).toString(),
454
- when: `${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
455
- },
456
- {
457
- command: NotebookCellCommands.CHANGE_OUTPUT_PRESENTATION_COMMAND.id,
458
- keybinding: KeyCode.createKeyCode({ first: Key.KEY_P, modifiers: [KeyModifier.Alt] }).toString(),
459
- when: `${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
460
- },
461
- {
462
- command: NotebookCellCommands.TO_CODE_CELL_COMMAND.id,
463
- keybinding: 'Y',
464
- when: `!editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'markdown'`,
465
- },
466
- {
467
- command: NotebookCellCommands.TO_MARKDOWN_CELL_COMMAND.id,
468
- keybinding: 'M',
469
- when: `!editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
470
- },
471
- );
472
- }
473
- }
474
-
475
- export namespace NotebookCellActionContribution {
476
- export const ACTION_MENU = ['notebook-cell-actions-menu'];
477
- export const ADDITIONAL_ACTION_MENU = [...ACTION_MENU, 'more'];
478
- export const CONTRIBUTED_CELL_ACTION_MENU = 'notebook/cell/title';
479
- export const CONTRIBUTED_CELL_EXECUTION_MENU = 'notebook/cell/execute';
480
- export const CODE_CELL_SIDEBAR_MENU = ['code-cell-sidebar-menu'];
481
- export const OUTPUT_SIDEBAR_MENU = ['code-cell-output-sidebar-menu'];
482
- export const ADDITIONAL_OUTPUT_SIDEBAR_MENU = [...OUTPUT_SIDEBAR_MENU, 'more'];
483
-
484
- }
485
-
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { Command, CommandContribution, CommandHandler, CommandRegistry, CompoundMenuNodeRole, MenuContribution, MenuModelRegistry, nls } from '@theia/core';
18
+ import { codicon, Key, KeybindingContribution, KeybindingRegistry, KeyCode, KeyModifier } from '@theia/core/lib/browser';
19
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
20
+ import { NotebookModel } from '../view-model/notebook-model';
21
+ import { NotebookCellModel } from '../view-model/notebook-cell-model';
22
+ import {
23
+ NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_TYPE,
24
+ NotebookContextKeys, NOTEBOOK_CELL_EXECUTING, NOTEBOOK_EDITOR_FOCUSED,
25
+ NOTEBOOK_CELL_FOCUSED,
26
+ NOTEBOOK_CELL_LIST_FOCUSED
27
+ } from './notebook-context-keys';
28
+ import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
29
+ import { NotebookExecutionService } from '../service/notebook-execution-service';
30
+ import { NotebookCellOutputModel } from '../view-model/notebook-cell-output-model';
31
+ import { CellEditType, CellKind } from '../../common';
32
+ import { NotebookEditorWidgetService } from '../service/notebook-editor-widget-service';
33
+ import { NotebookCommands } from './notebook-actions-contribution';
34
+ import { changeCellType } from './cell-operations';
35
+ import { EditorLanguageQuickPickService } from '@theia/editor/lib/browser/editor-language-quick-pick-service';
36
+ import { NotebookService } from '../service/notebook-service';
37
+
38
+ export namespace NotebookCellCommands {
39
+ /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
40
+ export const EDIT_COMMAND = Command.toDefaultLocalizedCommand({
41
+ id: 'notebook.cell.edit',
42
+ category: 'Notebook',
43
+ iconClass: codicon('edit')
44
+ });
45
+ /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
46
+ export const STOP_EDIT_COMMAND = Command.toDefaultLocalizedCommand({
47
+ id: 'notebook.cell.stop-edit',
48
+ category: 'Notebook',
49
+ iconClass: codicon('check')
50
+ });
51
+ /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
52
+ export const DELETE_COMMAND = Command.toDefaultLocalizedCommand({
53
+ id: 'notebook.cell.delete',
54
+ iconClass: codicon('trash')
55
+ });
56
+ /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
57
+ export const SPLIT_CELL_COMMAND = Command.toDefaultLocalizedCommand({
58
+ id: 'notebook.cell.split-cell',
59
+ iconClass: codicon('split-vertical'),
60
+ });
61
+ /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
62
+ export const EXECUTE_SINGLE_CELL_COMMAND = Command.toDefaultLocalizedCommand({
63
+ id: 'notebook.cell.execute-cell',
64
+ category: 'Notebook',
65
+ label: nls.localizeByDefault('Execute Cell'),
66
+ iconClass: codicon('play'),
67
+ });
68
+ /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
69
+ export const EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND = Command.toDefaultLocalizedCommand({
70
+ id: 'notebook.cell.execute-cell-and-focus-next',
71
+ label: nls.localizeByDefault('Execute Notebook Cell and Select Below'),
72
+ category: 'Notebook',
73
+ });
74
+ /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
75
+ export const EXECUTE_SINGLE_CELL_AND_INSERT_BELOW_COMMAND = Command.toDefaultLocalizedCommand({
76
+ id: 'notebook.cell.execute-cell-and-insert-below',
77
+ label: nls.localizeByDefault('Execute Notebook Cell and Insert Below'),
78
+ category: 'Notebook',
79
+ });
80
+
81
+ export const EXECUTE_ABOVE_CELLS_COMMAND = Command.toDefaultLocalizedCommand({
82
+ id: 'notebookActions.executeAbove',
83
+ label: 'Execute Above Cells',
84
+ iconClass: codicon('run-above')
85
+ });
86
+
87
+ export const EXECUTE_CELL_AND_BELOW_COMMAND = Command.toDefaultLocalizedCommand({
88
+ id: 'notebookActions.executeBelow',
89
+ label: 'Execute Cell and Below',
90
+ iconClass: codicon('run-below')
91
+ });
92
+ /** Parameters: notebookModel: NotebookModel, cell: NotebookCellModel */
93
+ export const STOP_CELL_EXECUTION_COMMAND = Command.toDefaultLocalizedCommand({
94
+ id: 'notebook.cell.stop-cell-execution',
95
+ iconClass: codicon('stop'),
96
+ });
97
+ /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel */
98
+ export const CLEAR_OUTPUTS_COMMAND = Command.toDefaultLocalizedCommand({
99
+ id: 'notebook.cell.clear-outputs',
100
+ category: 'Notebook',
101
+ label: 'Clear Cell Outputs',
102
+ });
103
+ /** Parameters: notebookModel: NotebookModel | undefined, cell: NotebookCellModel | undefined, output: NotebookCellOutputModel */
104
+ export const CHANGE_OUTPUT_PRESENTATION_COMMAND = Command.toDefaultLocalizedCommand({
105
+ id: 'notebook.cell.change-presentation',
106
+ category: 'Notebook',
107
+ label: 'Change Presentation',
108
+ });
109
+
110
+ export const INSERT_NEW_CELL_ABOVE_COMMAND = Command.toDefaultLocalizedCommand({
111
+ id: 'notebook.cell.insertCodeCellAboveAndFocusContainer',
112
+ label: 'Insert Code Cell Above and Focus Container'
113
+ });
114
+
115
+ export const INSERT_NEW_CELL_BELOW_COMMAND = Command.toDefaultLocalizedCommand({
116
+ id: 'notebook.cell.insertCodeCellBelowAndFocusContainer',
117
+ label: 'Insert Code Cell Below and Focus Container'
118
+ });
119
+
120
+ export const INSERT_MARKDOWN_CELL_ABOVE_COMMAND = Command.toLocalizedCommand({
121
+ id: 'notebook.cell.insertMarkdownCellAbove',
122
+ label: 'Insert Markdown Cell Above'
123
+ });
124
+ export const INSERT_MARKDOWN_CELL_BELOW_COMMAND = Command.toLocalizedCommand({
125
+ id: 'notebook.cell.insertMarkdownCellBelow',
126
+ label: 'Insert Markdown Cell Below'
127
+ });
128
+
129
+ export const TO_CODE_CELL_COMMAND = Command.toLocalizedCommand({
130
+ id: 'notebook.cell.changeToCode',
131
+ category: 'Notebook',
132
+ label: 'Change Cell to Code'
133
+ });
134
+
135
+ export const TO_MARKDOWN_CELL_COMMAND = Command.toLocalizedCommand({
136
+ id: 'notebook.cell.changeToMarkdown',
137
+ category: 'Notebook',
138
+ label: 'Change Cell to Markdown'
139
+ });
140
+
141
+ export const TOGGLE_CELL_OUTPUT = Command.toDefaultLocalizedCommand({
142
+ id: 'notebook.cell.toggleOutputs',
143
+ category: 'Notebook',
144
+ label: 'Collapse Cell Output',
145
+ });
146
+
147
+ export const CHANGE_CELL_LANGUAGE = Command.toDefaultLocalizedCommand({
148
+ id: 'notebook.cell.changeLanguage',
149
+ category: 'Notebook',
150
+ label: 'Change Cell Language',
151
+ });
152
+
153
+ export const TOGGLE_LINE_NUMBERS = Command.toDefaultLocalizedCommand({
154
+ id: 'notebook.cell.toggleLineNumbers',
155
+ category: 'Notebook',
156
+ label: 'Show Cell Line Numbers',
157
+ });
158
+
159
+ }
160
+
161
+ @injectable()
162
+ export class NotebookCellActionContribution implements MenuContribution, CommandContribution, KeybindingContribution {
163
+
164
+ @inject(ContextKeyService)
165
+ protected contextKeyService: ContextKeyService;
166
+
167
+ @inject(NotebookService)
168
+ protected notebookService: NotebookService;
169
+
170
+ @inject(NotebookExecutionService)
171
+ protected notebookExecutionService: NotebookExecutionService;
172
+
173
+ @inject(NotebookEditorWidgetService)
174
+ protected notebookEditorWidgetService: NotebookEditorWidgetService;
175
+
176
+ @inject(EditorLanguageQuickPickService)
177
+ protected languageQuickPickService: EditorLanguageQuickPickService;
178
+
179
+ @postConstruct()
180
+ protected init(): void {
181
+ NotebookContextKeys.initNotebookContextKeys(this.contextKeyService);
182
+ }
183
+
184
+ registerMenus(menus: MenuModelRegistry): void {
185
+ menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
186
+ commandId: NotebookCellCommands.EDIT_COMMAND.id,
187
+ icon: NotebookCellCommands.EDIT_COMMAND.iconClass,
188
+ when: `${NOTEBOOK_CELL_TYPE} == 'markdown' && !${NOTEBOOK_CELL_MARKDOWN_EDIT_MODE}`,
189
+ label: nls.localizeByDefault('Edit Cell'),
190
+ order: '10'
191
+ });
192
+ menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
193
+ commandId: NotebookCellCommands.STOP_EDIT_COMMAND.id,
194
+ icon: NotebookCellCommands.STOP_EDIT_COMMAND.iconClass,
195
+ when: `${NOTEBOOK_CELL_TYPE} == 'markdown' && ${NOTEBOOK_CELL_MARKDOWN_EDIT_MODE}`,
196
+ label: nls.localizeByDefault('Stop Editing Cell'),
197
+ order: '10'
198
+ });
199
+
200
+ menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
201
+ commandId: NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND.id,
202
+ icon: NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND.iconClass,
203
+ when: `${NOTEBOOK_CELL_TYPE} == 'code'`,
204
+ label: nls.localizeByDefault('Execute Above Cells'),
205
+ order: '10'
206
+ });
207
+
208
+ menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
209
+ commandId: NotebookCellCommands.EXECUTE_CELL_AND_BELOW_COMMAND.id,
210
+ icon: NotebookCellCommands.EXECUTE_CELL_AND_BELOW_COMMAND.iconClass,
211
+ when: `${NOTEBOOK_CELL_TYPE} == 'code'`,
212
+ label: nls.localizeByDefault('Execute Cell and Below'),
213
+ order: '20'
214
+ });
215
+
216
+ // menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
217
+ // commandId: NotebookCellCommands.SPLIT_CELL_COMMAND.id,
218
+ // icon: NotebookCellCommands.SPLIT_CELL_COMMAND.iconClass,
219
+ // label: nls.localizeByDefault('Split Cell'),
220
+ // order: '20'
221
+ // });
222
+
223
+ menus.registerMenuAction(NotebookCellActionContribution.ACTION_MENU, {
224
+ commandId: NotebookCellCommands.DELETE_COMMAND.id,
225
+ icon: NotebookCellCommands.DELETE_COMMAND.iconClass,
226
+ label: nls.localizeByDefault('Delete Cell'),
227
+ order: '999'
228
+ });
229
+
230
+ menus.registerSubmenu(
231
+ NotebookCellActionContribution.ADDITIONAL_ACTION_MENU,
232
+ nls.localizeByDefault('More'),
233
+ {
234
+ icon: codicon('ellipsis'),
235
+ role: CompoundMenuNodeRole.Submenu,
236
+ order: '30'
237
+ }
238
+ );
239
+
240
+ menus.registerIndependentSubmenu(NotebookCellActionContribution.CONTRIBUTED_CELL_ACTION_MENU, '', { role: CompoundMenuNodeRole.Flat });
241
+ // since contributions are adding to an independent submenu we have to manually add it to the more submenu
242
+ menus.getMenu(NotebookCellActionContribution.ADDITIONAL_ACTION_MENU).addNode(menus.getMenuNode(NotebookCellActionContribution.CONTRIBUTED_CELL_ACTION_MENU));
243
+
244
+ // code cell sidebar menu
245
+ menus.registerMenuAction(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, {
246
+ commandId: NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id,
247
+ icon: NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.iconClass,
248
+ label: nls.localizeByDefault('Execute Cell'),
249
+ when: `!${NOTEBOOK_CELL_EXECUTING}`
250
+ });
251
+ menus.registerMenuAction(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, {
252
+ commandId: NotebookCellCommands.STOP_CELL_EXECUTION_COMMAND.id,
253
+ icon: NotebookCellCommands.STOP_CELL_EXECUTION_COMMAND.iconClass,
254
+ label: nls.localizeByDefault('Stop Cell Execution'),
255
+ when: NOTEBOOK_CELL_EXECUTING
256
+ });
257
+
258
+ // Notebook Cell extra execution options
259
+ menus.registerIndependentSubmenu(NotebookCellActionContribution.CONTRIBUTED_CELL_EXECUTION_MENU,
260
+ nls.localizeByDefault('More...'),
261
+ { role: CompoundMenuNodeRole.Flat, icon: codicon('chevron-down') });
262
+ // menus.getMenu(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU).addNode(menus.getMenuNode(NotebookCellActionContribution.CONTRIBUTED_CELL_EXECUTION_MENU));
263
+
264
+ // code cell output sidebar menu
265
+ menus.registerSubmenu(
266
+ NotebookCellActionContribution.ADDITIONAL_OUTPUT_SIDEBAR_MENU,
267
+ nls.localizeByDefault('More'),
268
+ {
269
+ icon: codicon('ellipsis'),
270
+ role: CompoundMenuNodeRole.Submenu
271
+ });
272
+ menus.registerMenuAction(NotebookCellActionContribution.ADDITIONAL_OUTPUT_SIDEBAR_MENU, {
273
+ commandId: NotebookCellCommands.CLEAR_OUTPUTS_COMMAND.id,
274
+ label: nls.localizeByDefault('Clear Cell Outputs'),
275
+ });
276
+ menus.registerMenuAction(NotebookCellActionContribution.ADDITIONAL_OUTPUT_SIDEBAR_MENU, {
277
+ commandId: NotebookCellCommands.CHANGE_OUTPUT_PRESENTATION_COMMAND.id,
278
+ label: nls.localizeByDefault('Change Presentation'),
279
+ });
280
+
281
+ }
282
+
283
+ registerCommands(commands: CommandRegistry): void {
284
+ commands.registerCommand(NotebookCellCommands.EDIT_COMMAND, this.editableCellCommandHandler((_, cell) => cell.requestFocusEditor()));
285
+ commands.registerCommand(NotebookCellCommands.STOP_EDIT_COMMAND, { execute: (_, cell: NotebookCellModel) => (cell ?? this.getSelectedCell()).requestBlurEditor() });
286
+ commands.registerCommand(NotebookCellCommands.DELETE_COMMAND,
287
+ this.editableCellCommandHandler((notebookModel, cell) => {
288
+ notebookModel.applyEdits([{
289
+ editType: CellEditType.Replace,
290
+ index: notebookModel.cells.indexOf(cell),
291
+ count: 1,
292
+ cells: []
293
+ }]
294
+ , true);
295
+ }));
296
+ commands.registerCommand(NotebookCellCommands.SPLIT_CELL_COMMAND);
297
+
298
+ commands.registerCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND, this.editableCellCommandHandler(
299
+ (notebookModel, cell) => {
300
+ this.notebookExecutionService.executeNotebookCells(notebookModel, [cell]);
301
+ })
302
+ );
303
+
304
+ commands.registerCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND, this.editableCellCommandHandler(
305
+ (notebookModel, cell) => {
306
+ if (cell.cellKind === CellKind.Code) {
307
+ commands.executeCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id, notebookModel, cell);
308
+ } else {
309
+ commands.executeCommand(NotebookCellCommands.STOP_EDIT_COMMAND.id, notebookModel, cell);
310
+ }
311
+ const index = notebookModel.cells.indexOf(cell);
312
+ if (index < notebookModel.cells.length - 1) {
313
+ notebookModel.setSelectedCell(notebookModel.cells[index + 1]);
314
+ } else if (cell.cellKind === CellKind.Code) {
315
+ commands.executeCommand(NotebookCellCommands.INSERT_NEW_CELL_BELOW_COMMAND.id);
316
+ } else {
317
+ commands.executeCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_BELOW_COMMAND.id);
318
+ }
319
+ })
320
+ );
321
+ commands.registerCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_INSERT_BELOW_COMMAND, this.editableCellCommandHandler(
322
+ async (notebookModel, cell) => {
323
+ if (cell.cellKind === CellKind.Code) {
324
+ await commands.executeCommand(NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id, notebookModel, cell);
325
+ }
326
+ await commands.executeCommand(NotebookCellCommands.STOP_EDIT_COMMAND.id, notebookModel, cell);
327
+
328
+ if (cell.cellKind === CellKind.Code) {
329
+ await commands.executeCommand(NotebookCellCommands.INSERT_NEW_CELL_BELOW_COMMAND.id);
330
+ } else {
331
+ await commands.executeCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_BELOW_COMMAND.id);
332
+ }
333
+
334
+ const index = notebookModel.cells.indexOf(cell);
335
+ notebookModel.setSelectedCell(notebookModel.cells[index + 1]);
336
+ })
337
+ );
338
+
339
+ commands.registerCommand(NotebookCellCommands.EXECUTE_ABOVE_CELLS_COMMAND, this.editableCellCommandHandler(
340
+ (notebookModel, cell) => {
341
+ const index = notebookModel.cells.indexOf(cell);
342
+ if (index > 0) {
343
+ this.notebookExecutionService.executeNotebookCells(notebookModel, notebookModel.cells.slice(0, index).filter(c => c.cellKind === CellKind.Code));
344
+ }
345
+ })
346
+ );
347
+
348
+ commands.registerCommand(NotebookCellCommands.EXECUTE_CELL_AND_BELOW_COMMAND, this.editableCellCommandHandler(
349
+ (notebookModel, cell) => {
350
+ const index = notebookModel.cells.indexOf(cell);
351
+ if (index < notebookModel.cells.length - 1) {
352
+ this.notebookExecutionService.executeNotebookCells(notebookModel, notebookModel.cells.slice(index).filter(c => c.cellKind === CellKind.Code));
353
+ }
354
+ })
355
+ );
356
+
357
+ commands.registerCommand(NotebookCellCommands.STOP_CELL_EXECUTION_COMMAND, {
358
+ execute: (notebookModel: NotebookModel, cell: NotebookCellModel) => {
359
+ notebookModel = notebookModel ?? this.notebookEditorWidgetService.focusedEditor?.model;
360
+ cell = cell ?? this.getSelectedCell();
361
+ this.notebookExecutionService.cancelNotebookCells(notebookModel, [cell]);
362
+ }
363
+ });
364
+ commands.registerCommand(NotebookCellCommands.CLEAR_OUTPUTS_COMMAND, this.editableCellCommandHandler(
365
+ (notebook, cell) => (notebook ?? this.notebookEditorWidgetService.focusedEditor?.model)?.applyEdits([{
366
+ editType: CellEditType.Output,
367
+ handle: cell.handle,
368
+ outputs: [],
369
+ deleteCount: cell.outputs.length,
370
+ append: false
371
+ }], true)
372
+ ));
373
+ commands.registerCommand(NotebookCellCommands.CHANGE_OUTPUT_PRESENTATION_COMMAND, this.editableCellCommandHandler(
374
+ (_, __, output) => output?.requestOutputPresentationUpdate()
375
+ ));
376
+
377
+ const insertCommand = (type: CellKind, index: number | 'above' | 'below', focusContainer: boolean): CommandHandler => this.editableCellCommandHandler(() =>
378
+ commands.executeCommand(NotebookCommands.ADD_NEW_CELL_COMMAND.id, undefined, type, index, focusContainer)
379
+ );
380
+ commands.registerCommand(NotebookCellCommands.INSERT_NEW_CELL_ABOVE_COMMAND, insertCommand(CellKind.Code, 'above', true));
381
+ commands.registerCommand(NotebookCellCommands.INSERT_NEW_CELL_BELOW_COMMAND, insertCommand(CellKind.Code, 'below', true));
382
+ commands.registerCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_ABOVE_COMMAND, insertCommand(CellKind.Markup, 'above', false));
383
+ commands.registerCommand(NotebookCellCommands.INSERT_MARKDOWN_CELL_BELOW_COMMAND, insertCommand(CellKind.Markup, 'below', false));
384
+
385
+ commands.registerCommand(NotebookCellCommands.TO_CODE_CELL_COMMAND, this.editableCellCommandHandler((notebookModel, cell) => {
386
+ changeCellType(notebookModel, cell, CellKind.Code, this.notebookService.getCodeCellLanguage(notebookModel));
387
+ }));
388
+ commands.registerCommand(NotebookCellCommands.TO_MARKDOWN_CELL_COMMAND, this.editableCellCommandHandler((notebookModel, cell) => {
389
+ changeCellType(notebookModel, cell, CellKind.Markup);
390
+ }));
391
+
392
+ commands.registerCommand(NotebookCellCommands.TOGGLE_CELL_OUTPUT, {
393
+ execute: () => {
394
+ const selectedCell = this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
395
+ if (selectedCell) {
396
+ selectedCell.outputVisible = !selectedCell.outputVisible;
397
+ }
398
+ }
399
+ });
400
+
401
+ commands.registerCommand(NotebookCellCommands.CHANGE_CELL_LANGUAGE, {
402
+ isVisible: () => !!this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell,
403
+ execute: async (notebook?: NotebookModel, cell?: NotebookCellModel) => {
404
+ const selectedCell = cell ?? this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
405
+ const activeNotebook = notebook ?? this.notebookEditorWidgetService.focusedEditor?.model;
406
+ if (!selectedCell || !activeNotebook) {
407
+ return;
408
+ }
409
+ const language = await this.languageQuickPickService.pickEditorLanguage(selectedCell.language);
410
+ if (!language?.value || language.value === 'autoDetect' || language.value.id === selectedCell.language) {
411
+ return;
412
+ }
413
+ const isMarkdownCell = selectedCell.cellKind === CellKind.Markup;
414
+ const isMarkdownLanguage = language.value.id === 'markdown';
415
+ if (isMarkdownLanguage) {
416
+ changeCellType(activeNotebook, selectedCell, CellKind.Markup, language.value.id);
417
+ } else {
418
+ if (isMarkdownCell) {
419
+ changeCellType(activeNotebook, selectedCell, CellKind.Code, language.value.id);
420
+ } else {
421
+ this.notebookEditorWidgetService.focusedEditor?.model?.applyEdits([{
422
+ editType: CellEditType.CellLanguage,
423
+ index: activeNotebook.cells.indexOf(selectedCell),
424
+ language: language.value.id
425
+ }], true);
426
+ }
427
+ }
428
+ }
429
+ });
430
+
431
+ commands.registerCommand(NotebookCellCommands.TOGGLE_LINE_NUMBERS, {
432
+ execute: () => {
433
+ const selectedCell = this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
434
+ if (selectedCell) {
435
+ const currentLineNumber = selectedCell.editorOptions?.lineNumbers;
436
+ selectedCell.editorOptions = { ...selectedCell.editorOptions, lineNumbers: !currentLineNumber || currentLineNumber === 'off' ? 'on' : 'off' };
437
+ }
438
+ }
439
+ });
440
+
441
+ }
442
+
443
+ protected editableCellCommandHandler(execute: (notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel) => void): CommandHandler {
444
+ return {
445
+ isEnabled: (notebookModel: NotebookModel) => !Boolean(notebookModel?.readOnly),
446
+ isVisible: (notebookModel: NotebookModel) => !Boolean(notebookModel?.readOnly),
447
+ execute: (notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel) => {
448
+ notebookModel = notebookModel ?? this.notebookEditorWidgetService.focusedEditor?.model;
449
+ cell = cell ?? this.getSelectedCell();
450
+ execute(notebookModel, cell, output);
451
+ }
452
+ };
453
+ }
454
+
455
+ protected getSelectedCell(): NotebookCellModel | undefined {
456
+ return this.notebookEditorWidgetService.focusedEditor?.model?.selectedCell;
457
+ }
458
+
459
+ registerKeybindings(keybindings: KeybindingRegistry): void {
460
+ keybindings.registerKeybindings(
461
+ {
462
+ command: NotebookCellCommands.EDIT_COMMAND.id,
463
+ keybinding: 'Enter',
464
+ when: `!editorTextFocus && !inputFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
465
+ },
466
+ {
467
+ command: NotebookCellCommands.STOP_EDIT_COMMAND.id,
468
+ keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Alt, KeyModifier.CtrlCmd] }).toString(),
469
+ when: `editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'markdown'`,
470
+ },
471
+ {
472
+ command: NotebookCellCommands.STOP_EDIT_COMMAND.id,
473
+ keybinding: 'esc',
474
+ when: `editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED}`,
475
+ },
476
+ {
477
+ command: NotebookCellCommands.EXECUTE_SINGLE_CELL_COMMAND.id,
478
+ keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.CtrlCmd] }).toString(),
479
+ when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
480
+ },
481
+ {
482
+ command: NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_FOCUS_NEXT_COMMAND.id,
483
+ keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Shift] }).toString(),
484
+ when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
485
+ },
486
+ {
487
+ command: NotebookCellCommands.EXECUTE_SINGLE_CELL_AND_INSERT_BELOW_COMMAND.id,
488
+ keybinding: KeyCode.createKeyCode({ first: Key.ENTER, modifiers: [KeyModifier.Alt] }).toString(),
489
+ when: `${NOTEBOOK_CELL_LIST_FOCUSED} && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED}`,
490
+ },
491
+ {
492
+ command: NotebookCellCommands.CLEAR_OUTPUTS_COMMAND.id,
493
+ keybinding: KeyCode.createKeyCode({ first: Key.KEY_O, modifiers: [KeyModifier.Alt] }).toString(),
494
+ when: `${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
495
+ },
496
+ {
497
+ command: NotebookCellCommands.CHANGE_OUTPUT_PRESENTATION_COMMAND.id,
498
+ keybinding: KeyCode.createKeyCode({ first: Key.KEY_P, modifiers: [KeyModifier.Alt] }).toString(),
499
+ when: `${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
500
+ },
501
+ {
502
+ command: NotebookCellCommands.TO_CODE_CELL_COMMAND.id,
503
+ keybinding: 'Y',
504
+ when: `!editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'markdown'`,
505
+ },
506
+ {
507
+ command: NotebookCellCommands.TO_MARKDOWN_CELL_COMMAND.id,
508
+ keybinding: 'M',
509
+ when: `!editorTextFocus && ${NOTEBOOK_EDITOR_FOCUSED} && ${NOTEBOOK_CELL_FOCUSED} && ${NOTEBOOK_CELL_TYPE} == 'code'`,
510
+ },
511
+ );
512
+ }
513
+ }
514
+
515
+ export namespace NotebookCellActionContribution {
516
+ export const ACTION_MENU = ['notebook-cell-actions-menu'];
517
+ export const ADDITIONAL_ACTION_MENU = [...ACTION_MENU, 'more'];
518
+ export const CONTRIBUTED_CELL_ACTION_MENU = 'notebook/cell/title';
519
+ export const CONTRIBUTED_CELL_EXECUTION_MENU = 'notebook/cell/execute';
520
+ export const CODE_CELL_SIDEBAR_MENU = ['code-cell-sidebar-menu'];
521
+ export const OUTPUT_SIDEBAR_MENU = ['code-cell-output-sidebar-menu'];
522
+ export const ADDITIONAL_OUTPUT_SIDEBAR_MENU = [...OUTPUT_SIDEBAR_MENU, 'more'];
523
+
524
+ }
525
+