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