@jupyterlab/notebook-extension 3.4.1 → 4.0.0-alpha.10

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.
package/lib/index.js CHANGED
@@ -5,23 +5,26 @@
5
5
  * @module notebook-extension
6
6
  */
7
7
  import { ILabShell, ILayoutRestorer } from '@jupyterlab/application';
8
- import { createToolbarFactory, Dialog, ICommandPalette, InputDialog, ISessionContextDialogs, IToolbarWidgetRegistry, MainAreaWidget, sessionContextDialogs, showDialog, Toolbar, WidgetTracker } from '@jupyterlab/apputils';
8
+ import { createToolbarFactory, Dialog, ICommandPalette, IKernelStatusModel, InputDialog, ISanitizer, ISessionContextDialogs, IToolbarWidgetRegistry, MainAreaWidget, sessionContextDialogs, showDialog, Toolbar, WidgetTracker } from '@jupyterlab/apputils';
9
9
  import { MarkdownCell } from '@jupyterlab/cells';
10
- import { IEditorServices } from '@jupyterlab/codeeditor';
10
+ import { IEditorServices, IPositionModel } from '@jupyterlab/codeeditor';
11
11
  import { PageConfig } from '@jupyterlab/coreutils';
12
12
  import { IDocumentManager } from '@jupyterlab/docmanager';
13
13
  import { ToolbarItems as DocToolbarItems } from '@jupyterlab/docmanager-extension';
14
+ import { ISearchProviderRegistry } from '@jupyterlab/documentsearch';
14
15
  import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
15
16
  import { ILauncher } from '@jupyterlab/launcher';
16
17
  import { IMainMenu } from '@jupyterlab/mainmenu';
17
- import { CommandEditStatus, ExecutionIndicator, INotebookTools, INotebookTracker, INotebookWidgetFactory, NotebookActions, NotebookModelFactory, NotebookPanel, NotebookTools, NotebookTracker, NotebookTrustStatus, NotebookWidgetFactory, StaticNotebook, ToolbarItems } from '@jupyterlab/notebook';
18
+ import { CommandEditStatus, ExecutionIndicator, INotebookTools, INotebookTracker, INotebookWidgetFactory, NotebookActions, NotebookModelFactory, NotebookPanel, NotebookSearchProvider, NotebookToCFactory, NotebookTools, NotebookTracker, NotebookTrustStatus, NotebookWidgetFactory, StaticNotebook, ToolbarItems } from '@jupyterlab/notebook';
18
19
  import { IPropertyInspectorProvider } from '@jupyterlab/property-inspector';
19
- import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
20
+ import { IMarkdownParser, IRenderMimeRegistry } from '@jupyterlab/rendermime';
20
21
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
21
22
  import { IStateDB } from '@jupyterlab/statedb';
22
23
  import { IStatusBar } from '@jupyterlab/statusbar';
24
+ import { ITableOfContentsRegistry } from '@jupyterlab/toc';
23
25
  import { ITranslator, nullTranslator } from '@jupyterlab/translation';
24
26
  import { addAboveIcon, addBelowIcon, buildIcon, copyIcon, cutIcon, duplicateIcon, moveDownIcon, moveUpIcon, notebookIcon, pasteIcon } from '@jupyterlab/ui-components';
27
+ import { ICompletionProviderManager } from '@jupyterlab/completer';
25
28
  import { ArrayExt } from '@lumino/algorithm';
26
29
  import { JSONExt, UUID } from '@lumino/coreutils';
27
30
  import { DisposableSet } from '@lumino/disposable';
@@ -41,9 +44,11 @@ var CommandIDs;
41
44
  CommandIDs.restartRunAll = 'notebook:restart-run-all';
42
45
  CommandIDs.reconnectToKernel = 'notebook:reconnect-to-kernel';
43
46
  CommandIDs.changeKernel = 'notebook:change-kernel';
47
+ CommandIDs.getKernel = 'notebook:get-kernel';
44
48
  CommandIDs.createConsole = 'notebook:create-console';
45
49
  CommandIDs.createOutputView = 'notebook:create-output-view';
46
50
  CommandIDs.clearAllOutputs = 'notebook:clear-all-cell-outputs';
51
+ CommandIDs.shutdown = 'notebook:shutdown-kernel';
47
52
  CommandIDs.closeAndShutdown = 'notebook:close-and-shutdown';
48
53
  CommandIDs.trust = 'notebook:trust';
49
54
  CommandIDs.exportToFormat = 'notebook:export-to-format';
@@ -72,6 +77,10 @@ var CommandIDs;
72
77
  CommandIDs.insertBelow = 'notebook:insert-cell-below';
73
78
  CommandIDs.selectAbove = 'notebook:move-cursor-up';
74
79
  CommandIDs.selectBelow = 'notebook:move-cursor-down';
80
+ CommandIDs.selectHeadingAboveOrCollapse = 'notebook:move-cursor-heading-above-or-collapse';
81
+ CommandIDs.selectHeadingBelowOrExpand = 'notebook:move-cursor-heading-below-or-expand';
82
+ CommandIDs.insertHeadingAbove = 'notebook:insert-heading-above';
83
+ CommandIDs.insertHeadingBelow = 'notebook:insert-heading-below';
75
84
  CommandIDs.extendAbove = 'notebook:extend-marked-cells-above';
76
85
  CommandIDs.extendTop = 'notebook:extend-marked-cells-top';
77
86
  CommandIDs.extendBelow = 'notebook:extend-marked-cells-below';
@@ -87,6 +96,8 @@ var CommandIDs;
87
96
  CommandIDs.toggleAllLines = 'notebook:toggle-all-cell-line-numbers';
88
97
  CommandIDs.undoCellAction = 'notebook:undo-cell-action';
89
98
  CommandIDs.redoCellAction = 'notebook:redo-cell-action';
99
+ CommandIDs.redo = 'notebook:redo';
100
+ CommandIDs.undo = 'notebook:undo';
90
101
  CommandIDs.markdown1 = 'notebook:change-cell-to-heading-1';
91
102
  CommandIDs.markdown2 = 'notebook:change-cell-to-heading-2';
92
103
  CommandIDs.markdown3 = 'notebook:change-cell-to-heading-3';
@@ -108,10 +119,13 @@ var CommandIDs;
108
119
  CommandIDs.selectLastRunCell = 'notebook:select-last-run-cell';
109
120
  CommandIDs.replaceSelection = 'notebook:replace-selection';
110
121
  CommandIDs.autoClosingBrackets = 'notebook:toggle-autoclosing-brackets';
111
- CommandIDs.toggleCollapseCmd = 'Collapsible_Headings:Toggle_Collapse';
112
- CommandIDs.collapseAllCmd = 'Collapsible_Headings:Collapse_All';
113
- CommandIDs.expandAllCmd = 'Collapsible_Headings:Expand_All';
122
+ CommandIDs.toggleCollapseCmd = 'notebook:toggle-heading-collapse';
123
+ CommandIDs.collapseAllCmd = 'notebook:collapse-all-headings';
124
+ CommandIDs.expandAllCmd = 'notebook:expand-all-headings';
114
125
  CommandIDs.copyToClipboard = 'notebook:copy-to-clipboard';
126
+ CommandIDs.invokeCompleter = 'completer:invoke-notebook';
127
+ CommandIDs.selectCompleter = 'completer:select-notebook';
128
+ CommandIDs.tocRunCells = 'toc:run-cells';
115
129
  })(CommandIDs || (CommandIDs = {}));
116
130
  /**
117
131
  * The name of the factory that creates notebooks.
@@ -300,6 +314,9 @@ export const exportPlugin = {
300
314
  };
301
315
  commands.addCommand(CommandIDs.exportToFormat, {
302
316
  label: args => {
317
+ if (args.label === undefined) {
318
+ return trans.__('Save and Export Notebook to the given `format`.');
319
+ }
303
320
  const formatLabel = args['label'];
304
321
  return args['isPalette']
305
322
  ? trans.__('Save and Export Notebook: %1', formatLabel)
@@ -447,11 +464,85 @@ const codeConsolePlugin = {
447
464
  * A plugin to copy CodeCell outputs.
448
465
  */
449
466
  const copyOutputPlugin = {
450
- id: '@jupyterlab/notebook-extensions:copy-output',
467
+ id: '@jupyterlab/notebook-extension:copy-output',
451
468
  activate: activateCopyOutput,
452
469
  requires: [ITranslator, INotebookTracker],
453
470
  autoStart: true
454
471
  };
472
+ /**
473
+ * Kernel status indicator.
474
+ */
475
+ const kernelStatus = {
476
+ id: '@jupyterlab/notebook-extension:kernel-status',
477
+ activate: (app, tracker, kernelStatus) => {
478
+ const provider = (widget) => {
479
+ let session = null;
480
+ if (widget && tracker.has(widget)) {
481
+ return widget.sessionContext;
482
+ }
483
+ return session;
484
+ };
485
+ kernelStatus.addSessionProvider(provider);
486
+ },
487
+ requires: [INotebookTracker, IKernelStatusModel],
488
+ autoStart: true
489
+ };
490
+ /**
491
+ * Cursor position.
492
+ */
493
+ const lineColStatus = {
494
+ id: '@jupyterlab/notebook-extension:cursor-position',
495
+ activate: (app, tracker, positionModel) => {
496
+ let previousWidget = null;
497
+ const provider = (widget) => {
498
+ var _a, _b, _c, _d;
499
+ let editor = null;
500
+ if (widget !== previousWidget) {
501
+ previousWidget === null || previousWidget === void 0 ? void 0 : previousWidget.content.activeCellChanged.disconnect(positionModel.update);
502
+ previousWidget = null;
503
+ if (widget && tracker.has(widget)) {
504
+ widget.content.activeCellChanged.connect(positionModel.update);
505
+ editor = (_b = (_a = widget.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor) !== null && _b !== void 0 ? _b : null;
506
+ previousWidget = widget;
507
+ }
508
+ }
509
+ else if (widget) {
510
+ editor = (_d = (_c = widget.content.activeCell) === null || _c === void 0 ? void 0 : _c.editor) !== null && _d !== void 0 ? _d : null;
511
+ }
512
+ return editor;
513
+ };
514
+ positionModel.addEditorProvider(provider);
515
+ },
516
+ requires: [INotebookTracker, IPositionModel],
517
+ autoStart: true
518
+ };
519
+ const completerPlugin = {
520
+ id: '@jupyterlab/notebook-extension:completer',
521
+ requires: [INotebookTracker],
522
+ optional: [ICompletionProviderManager, ITranslator],
523
+ activate: activateNotebookCompleterService,
524
+ autoStart: true
525
+ };
526
+ /**
527
+ * A plugin to search notebook documents
528
+ */
529
+ const searchProvider = {
530
+ id: '@jupyterlab/notebook-extension:search',
531
+ requires: [ISearchProviderRegistry],
532
+ autoStart: true,
533
+ activate: (app, registry) => {
534
+ registry.add('jp-notebookSearchProvider', NotebookSearchProvider);
535
+ }
536
+ };
537
+ const tocPlugin = {
538
+ id: '@jupyterlab/notebook-extension:toc',
539
+ requires: [INotebookTracker, ITableOfContentsRegistry, ISanitizer],
540
+ optional: [IMarkdownParser],
541
+ autoStart: true,
542
+ activate: (app, tracker, tocRegistry, sanitizer, mdParser) => {
543
+ tocRegistry.add(new NotebookToCFactory(tracker, mdParser, sanitizer));
544
+ }
545
+ };
455
546
  /**
456
547
  * Export the plugins as default.
457
548
  */
@@ -467,7 +558,12 @@ const plugins = [
467
558
  logNotebookOutput,
468
559
  clonedOutputsPlugin,
469
560
  codeConsolePlugin,
470
- copyOutputPlugin
561
+ copyOutputPlugin,
562
+ kernelStatus,
563
+ lineColStatus,
564
+ completerPlugin,
565
+ searchProvider,
566
+ tocPlugin
471
567
  ];
472
568
  export default plugins;
473
569
  /**
@@ -478,7 +574,9 @@ function activateNotebookTools(app, tracker, editorServices, state, translator,
478
574
  const id = 'notebook-tools';
479
575
  const notebookTools = new NotebookTools({ tracker, translator });
480
576
  const activeCellTool = new NotebookTools.ActiveCellTool();
577
+ const editable = NotebookTools.createEditableToggle(translator);
481
578
  const slideShow = NotebookTools.createSlideShowSelector(translator);
579
+ const tocBaseNumbering = NotebookTools.createToCBaseNumbering(translator);
482
580
  const editorFactory = editorServices.factoryService.newInlineEditor;
483
581
  const cellMetadataEditor = new NotebookTools.CellMetadataEditorTool({
484
582
  editorFactory,
@@ -546,7 +644,9 @@ function activateNotebookTools(app, tracker, editorServices, state, translator,
546
644
  notebookTools.title.caption = trans.__('Notebook Tools');
547
645
  notebookTools.id = id;
548
646
  notebookTools.addItem({ tool: activeCellTool, section: 'common', rank: 1 });
549
- notebookTools.addItem({ tool: slideShow, section: 'common', rank: 2 });
647
+ notebookTools.addItem({ tool: editable, section: 'common', rank: 2 });
648
+ notebookTools.addItem({ tool: slideShow, section: 'common', rank: 3 });
649
+ notebookTools.addItem({ tool: tocBaseNumbering, section: 'common', rank: 4 });
550
650
  notebookTools.addItem({
551
651
  tool: cellMetadataEditor,
552
652
  section: 'advanced',
@@ -576,18 +676,20 @@ function activateWidgetFactory(app, contentFactory, editorServices, rendermime,
576
676
  const { commands } = app;
577
677
  let toolbarFactory;
578
678
  // Register notebook toolbar widgets
579
- toolbarRegistry.registerFactory(FACTORY, 'save', panel => DocToolbarItems.createSaveButton(commands, panel.context.fileChanged));
580
- toolbarRegistry.registerFactory(FACTORY, 'cellType', panel => ToolbarItems.createCellTypeItem(panel, translator));
581
- toolbarRegistry.registerFactory(FACTORY, 'kernelName', panel => Toolbar.createKernelNameItem(panel.sessionContext, sessionContextDialogs, translator));
582
- toolbarRegistry.registerFactory(FACTORY, 'executionProgress', panel => {
679
+ toolbarRegistry.addFactory(FACTORY, 'save', panel => DocToolbarItems.createSaveButton(commands, panel.context.fileChanged));
680
+ toolbarRegistry.addFactory(FACTORY, 'cellType', panel => ToolbarItems.createCellTypeItem(panel, translator));
681
+ toolbarRegistry.addFactory(FACTORY, 'kernelName', panel => Toolbar.createKernelNameItem(panel.sessionContext, sessionContextDialogs, translator));
682
+ toolbarRegistry.addFactory(FACTORY, 'executionProgress', panel => {
583
683
  return ExecutionIndicator.createExecutionIndicatorItem(panel, translator, settingRegistry === null || settingRegistry === void 0 ? void 0 : settingRegistry.load(trackerPlugin.id));
584
684
  });
585
685
  if (settingRegistry) {
586
686
  // Create the factory
587
687
  toolbarFactory = createToolbarFactory(toolbarRegistry, settingRegistry, FACTORY, PANEL_SETTINGS, translator);
588
688
  }
689
+ const trans = translator.load('jupyterlab');
589
690
  const factory = new NotebookWidgetFactory({
590
691
  name: FACTORY,
692
+ label: trans.__('Notebook'),
591
693
  fileTypes: ['notebook'],
592
694
  modelName: 'notebook',
593
695
  defaultFor: ['notebook'],
@@ -629,7 +731,7 @@ function activateClonedOutputs(app, docManager, notebookTracker, translator, res
629
731
  return Private.isEnabledAndSingleSelected(shell, notebookTracker);
630
732
  };
631
733
  commands.addCommand(CommandIDs.createOutputView, {
632
- label: trans.__('Create New View for Output'),
734
+ label: trans.__('Create New View for Cell Output'),
633
735
  execute: async (args) => {
634
736
  var _a;
635
737
  let cell;
@@ -662,7 +764,8 @@ function activateClonedOutputs(app, docManager, notebookTracker, translator, res
662
764
  const widget = new MainAreaWidget({ content });
663
765
  current.context.addSibling(widget, {
664
766
  ref: current.id,
665
- mode: 'split-bottom'
767
+ mode: 'split-bottom',
768
+ type: 'Cloned Output'
666
769
  });
667
770
  const updateCloned = () => {
668
771
  void clonedOutputs.save(widget);
@@ -870,8 +973,11 @@ function activateCopyOutput(app, translator, tracker) {
870
973
  function activateNotebookHandler(app, factory, translator, palette, browserFactory, launcher, restorer, mainMenu, settingRegistry, sessionDialogs) {
871
974
  const trans = translator.load('jupyterlab');
872
975
  const services = app.serviceManager;
873
- const { commands } = app;
976
+ const { commands, shell } = app;
874
977
  const tracker = new NotebookTracker({ namespace: 'notebook' });
978
+ const isEnabled = () => {
979
+ return Private.isEnabled(shell, tracker);
980
+ };
875
981
  // Fetch settings if possible.
876
982
  const fetchSettings = settingRegistry
877
983
  ? settingRegistry.load(trackerPlugin.id)
@@ -930,7 +1036,7 @@ function activateNotebookHandler(app, factory, translator, palette, browserFacto
930
1036
  disableDocumentWideUndoRedo: factory.notebookConfig.disableDocumentWideUndoRedo
931
1037
  });
932
1038
  registry.addModelFactory(modelFactory);
933
- addCommands(app, tracker, translator, sessionDialogs);
1039
+ addCommands(app, tracker, translator, sessionDialogs, isEnabled);
934
1040
  if (palette) {
935
1041
  populatePalette(palette, translator);
936
1042
  }
@@ -968,6 +1074,8 @@ function activateNotebookHandler(app, factory, translator, palette, browserFacto
968
1074
  const raw = Object.assign(Object.assign({}, StaticNotebook.defaultEditorConfig.raw), settings.get('rawCellConfig').composite);
969
1075
  factory.editorConfig = { code, markdown, raw };
970
1076
  factory.notebookConfig = {
1077
+ showHiddenCellsButton: settings.get('showHiddenCellsButton')
1078
+ .composite,
971
1079
  scrollPastEnd: settings.get('scrollPastEnd').composite,
972
1080
  defaultCell: settings.get('defaultCell').composite,
973
1081
  recordTiming: settings.get('recordTiming').composite,
@@ -986,7 +1094,7 @@ function activateNotebookHandler(app, factory, translator, palette, browserFacto
986
1094
  .composite,
987
1095
  sideBySideRightMarginOverride: settings.get('sideBySideRightMarginOverride').composite
988
1096
  };
989
- const sideBySideMarginStyle = `.jp-mod-sideBySide.jp-Notebook .jp-Notebook-cell {
1097
+ const sideBySideMarginStyle = `.jp-mod-sideBySide.jp-Notebook .jp-Notebook-cell {
990
1098
  margin-left: ${factory.notebookConfig.sideBySideLeftMarginOverride} !important;
991
1099
  margin-right: ${factory.notebookConfig.sideBySideRightMarginOverride} !important;`;
992
1100
  const sideBySideMarginTag = document.getElementById(SIDE_BY_SIDE_STYLE_ID);
@@ -1007,7 +1115,7 @@ function activateNotebookHandler(app, factory, translator, palette, browserFacto
1007
1115
  }
1008
1116
  // Add main menu notebook menu.
1009
1117
  if (mainMenu) {
1010
- populateMenus(app, mainMenu, tracker, translator, sessionDialogs);
1118
+ populateMenus(mainMenu, tracker, sessionDialogs, isEnabled);
1011
1119
  }
1012
1120
  // Utility function to create a new notebook.
1013
1121
  const createNew = (cwd, kernelName) => {
@@ -1081,6 +1189,71 @@ function activateNotebookHandler(app, factory, translator, palette, browserFacto
1081
1189
  }
1082
1190
  return tracker;
1083
1191
  }
1192
+ /**
1193
+ * Activate the completer service for notebook.
1194
+ */
1195
+ function activateNotebookCompleterService(app, notebooks, manager, translator) {
1196
+ if (!manager) {
1197
+ return;
1198
+ }
1199
+ const trans = (translator !== null && translator !== void 0 ? translator : nullTranslator).load('jupyterlab');
1200
+ app.commands.addCommand(CommandIDs.invokeCompleter, {
1201
+ label: trans.__('Display the completion helper.'),
1202
+ execute: args => {
1203
+ var _a;
1204
+ const panel = notebooks.currentWidget;
1205
+ if (panel && ((_a = panel.content.activeCell) === null || _a === void 0 ? void 0 : _a.model.type) === 'code') {
1206
+ manager.invoke(panel.id);
1207
+ }
1208
+ }
1209
+ });
1210
+ app.commands.addCommand(CommandIDs.selectCompleter, {
1211
+ label: trans.__('Select the completion suggestion.'),
1212
+ execute: () => {
1213
+ const id = notebooks.currentWidget && notebooks.currentWidget.id;
1214
+ if (id) {
1215
+ return manager.select(id);
1216
+ }
1217
+ }
1218
+ });
1219
+ app.commands.addKeyBinding({
1220
+ command: CommandIDs.selectCompleter,
1221
+ keys: ['Enter'],
1222
+ selector: '.jp-Notebook .jp-mod-completer-active'
1223
+ });
1224
+ const updateCompleter = async (_, notebook) => {
1225
+ var _a, _b;
1226
+ const completerContext = {
1227
+ editor: (_b = (_a = notebook.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor) !== null && _b !== void 0 ? _b : null,
1228
+ session: notebook.sessionContext.session,
1229
+ widget: notebook
1230
+ };
1231
+ await manager.updateCompleter(completerContext);
1232
+ notebook.content.activeCellChanged.connect((_, cell) => {
1233
+ const newCompleterContext = {
1234
+ editor: cell.editor,
1235
+ session: notebook.sessionContext.session,
1236
+ widget: notebook
1237
+ };
1238
+ manager.updateCompleter(newCompleterContext).catch(console.error);
1239
+ });
1240
+ notebook.sessionContext.sessionChanged.connect(() => {
1241
+ var _a, _b;
1242
+ const newCompleterContext = {
1243
+ editor: (_b = (_a = notebook.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor) !== null && _b !== void 0 ? _b : null,
1244
+ session: notebook.sessionContext.session,
1245
+ widget: notebook
1246
+ };
1247
+ manager.updateCompleter(newCompleterContext).catch(console.error);
1248
+ });
1249
+ };
1250
+ notebooks.widgetAdded.connect(updateCompleter);
1251
+ manager.activeProvidersChanged.connect(() => {
1252
+ notebooks.forEach(panel => {
1253
+ updateCompleter(undefined, panel).catch(e => console.error(e));
1254
+ });
1255
+ });
1256
+ }
1084
1257
  // Get the current widget and activate unless the args specify otherwise.
1085
1258
  function getCurrent(tracker, shell, args) {
1086
1259
  const widget = tracker.currentWidget;
@@ -1093,13 +1266,10 @@ function getCurrent(tracker, shell, args) {
1093
1266
  /**
1094
1267
  * Add the notebook commands to the application's command registry.
1095
1268
  */
1096
- function addCommands(app, tracker, translator, sessionDialogs) {
1269
+ function addCommands(app, tracker, translator, sessionDialogs, isEnabled) {
1097
1270
  const trans = translator.load('jupyterlab');
1098
1271
  const { commands, shell } = app;
1099
1272
  sessionDialogs = sessionDialogs !== null && sessionDialogs !== void 0 ? sessionDialogs : sessionContextDialogs;
1100
- const isEnabled = () => {
1101
- return Private.isEnabled(shell, tracker);
1102
- };
1103
1273
  const isEnabledAndSingleSelected = () => {
1104
1274
  return Private.isEnabledAndSingleSelected(shell, tracker);
1105
1275
  };
@@ -1230,8 +1400,19 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1230
1400
  },
1231
1401
  isEnabled
1232
1402
  });
1403
+ commands.addCommand(CommandIDs.shutdown, {
1404
+ label: trans.__('Shut Down Kernel'),
1405
+ execute: args => {
1406
+ const current = getCurrent(tracker, shell, args);
1407
+ if (!current) {
1408
+ return;
1409
+ }
1410
+ return current.context.sessionContext.shutdown();
1411
+ },
1412
+ isEnabled
1413
+ });
1233
1414
  commands.addCommand(CommandIDs.closeAndShutdown, {
1234
- label: trans.__('Close and Shut Down'),
1415
+ label: trans.__('Close and Shut Down Notebook'),
1235
1416
  execute: args => {
1236
1417
  const current = getCurrent(tracker, shell, args);
1237
1418
  if (!current) {
@@ -1244,7 +1425,9 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1244
1425
  buttons: [Dialog.cancelButton(), Dialog.warnButton()]
1245
1426
  }).then(result => {
1246
1427
  if (result.button.accept) {
1247
- return current.context.sessionContext.shutdown().then(() => {
1428
+ return commands
1429
+ .execute(CommandIDs.shutdown, { activate: false })
1430
+ .then(() => {
1248
1431
  current.dispose();
1249
1432
  });
1250
1433
  }
@@ -1264,59 +1447,48 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1264
1447
  isEnabled
1265
1448
  });
1266
1449
  commands.addCommand(CommandIDs.restartClear, {
1267
- label: trans.__('Restart Kernel and Clear All Outputs…'),
1268
- execute: args => {
1269
- const current = getCurrent(tracker, shell, args);
1270
- if (current) {
1271
- const { content, sessionContext } = current;
1272
- return sessionDialogs.restart(sessionContext, translator).then(() => {
1273
- NotebookActions.clearAllOutputs(content);
1274
- });
1450
+ label: trans.__('Restart Kernel and Clear Outputs of All Cells…'),
1451
+ caption: trans.__('Restart the kernel and clear all outputs of all cells'),
1452
+ execute: async () => {
1453
+ const restarted = await commands.execute(CommandIDs.restart, {
1454
+ activate: false
1455
+ });
1456
+ if (restarted) {
1457
+ await commands.execute(CommandIDs.clearAllOutputs);
1275
1458
  }
1276
1459
  },
1277
1460
  isEnabled
1278
1461
  });
1279
1462
  commands.addCommand(CommandIDs.restartAndRunToSelected, {
1280
1463
  label: trans.__('Restart Kernel and Run up to Selected Cell…'),
1281
- execute: args => {
1282
- const current = getCurrent(tracker, shell, args);
1283
- if (current) {
1284
- const { context, content } = current;
1285
- return sessionDialogs
1286
- .restart(current.sessionContext, translator)
1287
- .then(restarted => {
1288
- if (restarted) {
1289
- void NotebookActions.runAllAbove(content, context.sessionContext).then(executed => {
1290
- if (executed || content.activeCellIndex === 0) {
1291
- void NotebookActions.run(content, context.sessionContext);
1292
- }
1293
- });
1294
- }
1295
- });
1464
+ execute: async () => {
1465
+ const restarted = await commands.execute(CommandIDs.restart, {
1466
+ activate: false
1467
+ });
1468
+ if (restarted) {
1469
+ const executed = await commands.execute(CommandIDs.runAllAbove, { activate: false });
1470
+ if (executed) {
1471
+ return commands.execute(CommandIDs.run);
1472
+ }
1296
1473
  }
1297
1474
  },
1298
1475
  isEnabled: isEnabledAndSingleSelected
1299
1476
  });
1300
1477
  commands.addCommand(CommandIDs.restartRunAll, {
1301
1478
  label: trans.__('Restart Kernel and Run All Cells…'),
1302
- execute: args => {
1303
- const current = getCurrent(tracker, shell, args);
1304
- if (current) {
1305
- const { context, content, sessionContext } = current;
1306
- return sessionDialogs
1307
- .restart(sessionContext, translator)
1308
- .then(restarted => {
1309
- if (restarted) {
1310
- void NotebookActions.runAll(content, context.sessionContext);
1311
- }
1312
- return restarted;
1313
- });
1479
+ execute: async () => {
1480
+ const restarted = await commands.execute(CommandIDs.restart, {
1481
+ activate: false
1482
+ });
1483
+ if (restarted) {
1484
+ await commands.execute(CommandIDs.runAll);
1314
1485
  }
1315
1486
  },
1316
1487
  isEnabled
1317
1488
  });
1318
1489
  commands.addCommand(CommandIDs.clearAllOutputs, {
1319
- label: trans.__('Clear All Outputs'),
1490
+ label: trans.__('Clear Outputs of All Cells'),
1491
+ caption: trans.__('Clear all outputs of all cells'),
1320
1492
  execute: args => {
1321
1493
  const current = getCurrent(tracker, shell, args);
1322
1494
  if (current) {
@@ -1326,7 +1498,8 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1326
1498
  isEnabled
1327
1499
  });
1328
1500
  commands.addCommand(CommandIDs.clearOutputs, {
1329
- label: trans.__('Clear Outputs'),
1501
+ label: trans.__('Clear Cell Output'),
1502
+ caption: trans.__('Clear outputs for the selected cells'),
1330
1503
  execute: args => {
1331
1504
  const current = getCurrent(tracker, shell, args);
1332
1505
  if (current) {
@@ -1541,6 +1714,46 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1541
1714
  },
1542
1715
  isEnabled
1543
1716
  });
1717
+ commands.addCommand(CommandIDs.insertHeadingAbove, {
1718
+ label: trans.__('Insert Heading Above Current Heading'),
1719
+ execute: args => {
1720
+ const current = getCurrent(tracker, shell, args);
1721
+ if (current) {
1722
+ return NotebookActions.insertSameLevelHeadingAbove(current.content);
1723
+ }
1724
+ },
1725
+ isEnabled
1726
+ });
1727
+ commands.addCommand(CommandIDs.insertHeadingBelow, {
1728
+ label: trans.__('Insert Heading Below Current Heading'),
1729
+ execute: args => {
1730
+ const current = getCurrent(tracker, shell, args);
1731
+ if (current) {
1732
+ return NotebookActions.insertSameLevelHeadingBelow(current.content);
1733
+ }
1734
+ },
1735
+ isEnabled
1736
+ });
1737
+ commands.addCommand(CommandIDs.selectHeadingAboveOrCollapse, {
1738
+ label: trans.__('Select Heading Above or Collapse Heading'),
1739
+ execute: args => {
1740
+ const current = getCurrent(tracker, shell, args);
1741
+ if (current) {
1742
+ return NotebookActions.selectHeadingAboveOrCollapseHeading(current.content);
1743
+ }
1744
+ },
1745
+ isEnabled
1746
+ });
1747
+ commands.addCommand(CommandIDs.selectHeadingBelowOrExpand, {
1748
+ label: trans.__('Select Heading Below or Expand Heading'),
1749
+ execute: args => {
1750
+ const current = getCurrent(tracker, shell, args);
1751
+ if (current) {
1752
+ return NotebookActions.selectHeadingBelowOrExpandHeading(current.content);
1753
+ }
1754
+ },
1755
+ isEnabled
1756
+ });
1544
1757
  commands.addCommand(CommandIDs.extendAbove, {
1545
1758
  label: trans.__('Extend Selection Above'),
1546
1759
  execute: args => {
@@ -1624,14 +1837,26 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1624
1837
  icon: args => (args.toolbar ? moveDownIcon : undefined)
1625
1838
  });
1626
1839
  commands.addCommand(CommandIDs.toggleAllLines, {
1627
- label: trans.__('Toggle All Line Numbers'),
1840
+ label: trans.__('Show Line Numbers'),
1628
1841
  execute: args => {
1629
1842
  const current = getCurrent(tracker, shell, args);
1630
1843
  if (current) {
1631
1844
  return NotebookActions.toggleAllLineNumbers(current.content);
1632
1845
  }
1633
1846
  },
1634
- isEnabled
1847
+ isEnabled,
1848
+ isToggled: args => {
1849
+ const current = getCurrent(tracker, shell, Object.assign(Object.assign({}, args), { activate: false }));
1850
+ if (current) {
1851
+ const config = current.content.editorConfig;
1852
+ return !!(config.code.lineNumbers &&
1853
+ config.markdown.lineNumbers &&
1854
+ config.raw.lineNumbers);
1855
+ }
1856
+ else {
1857
+ return false;
1858
+ }
1859
+ }
1635
1860
  });
1636
1861
  commands.addCommand(CommandIDs.commandMode, {
1637
1862
  label: trans.__('Enter Command Mode'),
@@ -1673,6 +1898,26 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1673
1898
  },
1674
1899
  isEnabled
1675
1900
  });
1901
+ commands.addCommand(CommandIDs.redo, {
1902
+ label: trans.__('Redo'),
1903
+ execute: args => {
1904
+ var _a;
1905
+ const current = getCurrent(tracker, shell, args);
1906
+ if (current) {
1907
+ return (_a = current.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor.redo();
1908
+ }
1909
+ }
1910
+ });
1911
+ commands.addCommand(CommandIDs.undo, {
1912
+ label: trans.__('Undo'),
1913
+ execute: args => {
1914
+ var _a;
1915
+ const current = getCurrent(tracker, shell, args);
1916
+ if (current) {
1917
+ return (_a = current.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor.undo();
1918
+ }
1919
+ }
1920
+ });
1676
1921
  commands.addCommand(CommandIDs.changeKernel, {
1677
1922
  label: trans.__('Change Kernel…'),
1678
1923
  execute: args => {
@@ -1683,8 +1928,19 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1683
1928
  },
1684
1929
  isEnabled
1685
1930
  });
1931
+ commands.addCommand(CommandIDs.getKernel, {
1932
+ label: trans.__('Get Kernel'),
1933
+ execute: args => {
1934
+ var _a;
1935
+ const current = getCurrent(tracker, shell, Object.assign({ activate: false }, args));
1936
+ if (current) {
1937
+ return (_a = current.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
1938
+ }
1939
+ },
1940
+ isEnabled
1941
+ });
1686
1942
  commands.addCommand(CommandIDs.reconnectToKernel, {
1687
- label: trans.__('Reconnect To Kernel'),
1943
+ label: trans.__('Reconnect to Kernel'),
1688
1944
  execute: args => {
1689
1945
  var _a;
1690
1946
  const current = getCurrent(tracker, shell, args);
@@ -1917,7 +2173,7 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1917
2173
  isEnabled
1918
2174
  });
1919
2175
  commands.addCommand(CommandIDs.toggleCollapseCmd, {
1920
- label: 'Toggle Collapse Notebook Heading',
2176
+ label: trans.__('Toggle Collapse Notebook Heading'),
1921
2177
  execute: args => {
1922
2178
  const current = getCurrent(tracker, shell, args);
1923
2179
  if (current) {
@@ -1927,16 +2183,16 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1927
2183
  isEnabled: isEnabledAndHeadingSelected
1928
2184
  });
1929
2185
  commands.addCommand(CommandIDs.collapseAllCmd, {
1930
- label: 'Collapse All Cells',
2186
+ label: trans.__('Collapse All Headings'),
1931
2187
  execute: args => {
1932
2188
  const current = getCurrent(tracker, shell, args);
1933
2189
  if (current) {
1934
- return NotebookActions.collapseAll(current.content);
2190
+ return NotebookActions.collapseAllHeadings(current.content);
1935
2191
  }
1936
2192
  }
1937
2193
  });
1938
2194
  commands.addCommand(CommandIDs.expandAllCmd, {
1939
- label: 'Expand All Headings',
2195
+ label: trans.__('Expand All Headings'),
1940
2196
  execute: args => {
1941
2197
  const current = getCurrent(tracker, shell, args);
1942
2198
  if (current) {
@@ -1944,6 +2200,33 @@ function addCommands(app, tracker, translator, sessionDialogs) {
1944
2200
  }
1945
2201
  }
1946
2202
  });
2203
+ commands.addCommand(CommandIDs.tocRunCells, {
2204
+ label: trans.__('Select and Run Cell(s) for this Heading'),
2205
+ execute: args => {
2206
+ const current = getCurrent(tracker, shell, Object.assign({ activate: false }, args));
2207
+ if (current === null) {
2208
+ return;
2209
+ }
2210
+ const activeCell = current.content.activeCell;
2211
+ let lastIndex = current.content.activeCellIndex;
2212
+ if (activeCell instanceof MarkdownCell) {
2213
+ const cells = current.content.widgets;
2214
+ const level = activeCell.headingInfo.level;
2215
+ for (let i = current.content.activeCellIndex + 1; i < cells.length; i++) {
2216
+ const cell = cells[i];
2217
+ if (cell instanceof MarkdownCell &&
2218
+ // cell.headingInfo.level === -1 if no heading
2219
+ cell.headingInfo.level >= 0 &&
2220
+ cell.headingInfo.level <= level) {
2221
+ break;
2222
+ }
2223
+ lastIndex = i;
2224
+ }
2225
+ }
2226
+ current.content.extendContiguousSelectionTo(lastIndex);
2227
+ NotebookActions.run(current.content, current.sessionContext);
2228
+ }
2229
+ });
1947
2230
  }
1948
2231
  /**
1949
2232
  * Populate the application's command palette with notebook commands.
@@ -2007,6 +2290,10 @@ function populatePalette(palette, translator) {
2007
2290
  CommandIDs.insertBelow,
2008
2291
  CommandIDs.selectAbove,
2009
2292
  CommandIDs.selectBelow,
2293
+ CommandIDs.selectHeadingAboveOrCollapse,
2294
+ CommandIDs.selectHeadingBelowOrExpand,
2295
+ CommandIDs.insertHeadingAbove,
2296
+ CommandIDs.insertHeadingBelow,
2010
2297
  CommandIDs.extendAbove,
2011
2298
  CommandIDs.extendTop,
2012
2299
  CommandIDs.extendBelow,
@@ -2040,141 +2327,80 @@ function populatePalette(palette, translator) {
2040
2327
  /**
2041
2328
  * Populates the application menus for the notebook.
2042
2329
  */
2043
- function populateMenus(app, mainMenu, tracker, translator, sessionDialogs) {
2044
- const trans = translator.load('jupyterlab');
2045
- const { commands } = app;
2330
+ function populateMenus(mainMenu, tracker, sessionDialogs, isEnabled) {
2046
2331
  sessionDialogs = sessionDialogs || sessionContextDialogs;
2047
2332
  // Add undo/redo hooks to the edit menu.
2048
- mainMenu.editMenu.undoers.add({
2049
- tracker,
2050
- undo: widget => {
2051
- var _a;
2052
- (_a = widget.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor.undo();
2053
- },
2054
- redo: widget => {
2055
- var _a;
2056
- (_a = widget.content.activeCell) === null || _a === void 0 ? void 0 : _a.editor.redo();
2057
- }
2333
+ mainMenu.editMenu.undoers.redo.add({
2334
+ id: CommandIDs.redo,
2335
+ isEnabled
2336
+ });
2337
+ mainMenu.editMenu.undoers.undo.add({
2338
+ id: CommandIDs.undo,
2339
+ isEnabled
2058
2340
  });
2059
2341
  // Add a clearer to the edit menu
2060
- mainMenu.editMenu.clearers.add({
2061
- tracker,
2062
- clearCurrentLabel: (n) => trans.__('Clear Output'),
2063
- clearAllLabel: (n) => {
2064
- return trans.__('Clear All Outputs');
2065
- },
2066
- clearCurrent: (current) => {
2067
- return NotebookActions.clearOutputs(current.content);
2068
- },
2069
- clearAll: (current) => {
2070
- return NotebookActions.clearAllOutputs(current.content);
2071
- }
2342
+ mainMenu.editMenu.clearers.clearAll.add({
2343
+ id: CommandIDs.clearAllOutputs,
2344
+ isEnabled
2345
+ });
2346
+ mainMenu.editMenu.clearers.clearCurrent.add({
2347
+ id: CommandIDs.clearOutputs,
2348
+ isEnabled
2349
+ });
2350
+ // Add a console creator the the Kernel menu
2351
+ mainMenu.fileMenu.consoleCreators.add({
2352
+ id: CommandIDs.createConsole,
2353
+ isEnabled
2072
2354
  });
2073
2355
  // Add a close and shutdown command to the file menu.
2074
2356
  mainMenu.fileMenu.closeAndCleaners.add({
2075
- tracker,
2076
- closeAndCleanupLabel: (n) => trans.__('Close and Shutdown Notebook'),
2077
- closeAndCleanup: (current) => {
2078
- const fileName = current.title.label;
2079
- return showDialog({
2080
- title: trans.__('Shut down the Notebook?'),
2081
- body: trans.__('Are you sure you want to close "%1"?', fileName),
2082
- buttons: [Dialog.cancelButton(), Dialog.warnButton()]
2083
- }).then(result => {
2084
- if (result.button.accept) {
2085
- return current.context.sessionContext.shutdown().then(() => {
2086
- current.dispose();
2087
- });
2088
- }
2089
- });
2090
- }
2357
+ id: CommandIDs.closeAndShutdown,
2358
+ isEnabled
2091
2359
  });
2092
2360
  // Add a kernel user to the Kernel menu
2093
- mainMenu.kernelMenu.kernelUsers.add({
2094
- tracker,
2095
- interruptKernel: current => {
2096
- var _a;
2097
- const kernel = (_a = current.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
2098
- if (kernel) {
2099
- return kernel.interrupt();
2100
- }
2101
- return Promise.resolve(void 0);
2102
- },
2103
- reconnectToKernel: current => {
2104
- var _a;
2105
- const kernel = (_a = current.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
2106
- if (kernel) {
2107
- return kernel.reconnect();
2108
- }
2109
- return Promise.resolve(void 0);
2110
- },
2111
- restartKernelAndClearLabel: (n) => trans.__('Restart Kernel and Clear All Outputs…'),
2112
- restartKernel: current => sessionDialogs.restart(current.sessionContext, translator),
2113
- restartKernelAndClear: current => {
2114
- return sessionDialogs
2115
- .restart(current.sessionContext, translator)
2116
- .then(restarted => {
2117
- if (restarted) {
2118
- NotebookActions.clearAllOutputs(current.content);
2119
- }
2120
- return restarted;
2121
- });
2122
- },
2123
- changeKernel: current => sessionDialogs.selectKernel(current.sessionContext, translator),
2124
- shutdownKernel: current => current.sessionContext.shutdown()
2361
+ mainMenu.kernelMenu.kernelUsers.changeKernel.add({
2362
+ id: CommandIDs.changeKernel,
2363
+ isEnabled
2125
2364
  });
2126
- // Add a console creator the the Kernel menu
2127
- mainMenu.fileMenu.consoleCreators.add({
2128
- tracker,
2129
- createConsoleLabel: (n) => trans.__('New Console for Notebook'),
2130
- createConsole: current => Private.createConsole(commands, current, true)
2365
+ mainMenu.kernelMenu.kernelUsers.clearWidget.add({
2366
+ id: CommandIDs.clearAllOutputs,
2367
+ isEnabled
2368
+ });
2369
+ mainMenu.kernelMenu.kernelUsers.interruptKernel.add({
2370
+ id: CommandIDs.interrupt,
2371
+ isEnabled
2372
+ });
2373
+ mainMenu.kernelMenu.kernelUsers.reconnectToKernel.add({
2374
+ id: CommandIDs.reconnectToKernel,
2375
+ isEnabled
2376
+ });
2377
+ mainMenu.kernelMenu.kernelUsers.restartKernel.add({
2378
+ id: CommandIDs.restart,
2379
+ isEnabled
2380
+ });
2381
+ mainMenu.kernelMenu.kernelUsers.shutdownKernel.add({
2382
+ id: CommandIDs.shutdown,
2383
+ isEnabled
2131
2384
  });
2132
2385
  // Add an IEditorViewer to the application view menu
2133
- mainMenu.viewMenu.editorViewers.add({
2134
- tracker,
2135
- toggleLineNumbers: widget => {
2136
- NotebookActions.toggleAllLineNumbers(widget.content);
2137
- },
2138
- lineNumbersToggled: widget => {
2139
- const config = widget.content.editorConfig;
2140
- return !!(config.code.lineNumbers &&
2141
- config.markdown.lineNumbers &&
2142
- config.raw.lineNumbers);
2143
- }
2386
+ mainMenu.viewMenu.editorViewers.toggleLineNumbers.add({
2387
+ id: CommandIDs.toggleAllLines,
2388
+ isEnabled
2144
2389
  });
2145
2390
  // Add an ICodeRunner to the application run menu
2146
- mainMenu.runMenu.codeRunners.add({
2147
- tracker,
2148
- runLabel: (n) => trans.__('Run Selected Cells'),
2149
- runCaption: (n) => trans.__('Run the selected cells and advance'),
2150
- runAllLabel: (n) => trans.__('Run All Cells'),
2151
- runAllCaption: (n) => trans.__('Run the all notebook cells'),
2152
- restartAndRunAllLabel: (n) => trans.__('Restart Kernel and Run All Cells…'),
2153
- restartAndRunAllCaption: (n) => trans.__('Restart the kernel, then re-run the whole notebook'),
2154
- run: current => {
2155
- const { context, content } = current;
2156
- return NotebookActions.runAndAdvance(content, context.sessionContext).then(() => void 0);
2157
- },
2158
- runAll: current => {
2159
- const { context, content } = current;
2160
- return NotebookActions.runAll(content, context.sessionContext).then(() => void 0);
2161
- },
2162
- restartAndRunAll: current => {
2163
- const { context, content } = current;
2164
- return sessionDialogs
2165
- .restart(context.sessionContext, translator)
2166
- .then(restarted => {
2167
- if (restarted) {
2168
- void NotebookActions.runAll(content, context.sessionContext);
2169
- }
2170
- return restarted;
2171
- });
2172
- }
2391
+ mainMenu.runMenu.codeRunners.restart.add({
2392
+ id: CommandIDs.restart,
2393
+ isEnabled
2173
2394
  });
2395
+ mainMenu.runMenu.codeRunners.run.add({
2396
+ id: CommandIDs.runAndAdvance,
2397
+ isEnabled
2398
+ });
2399
+ mainMenu.runMenu.codeRunners.runAll.add({ id: CommandIDs.runAll, isEnabled });
2174
2400
  // Add kernel information to the application help menu.
2175
- mainMenu.helpMenu.kernelUsers.add({
2176
- tracker,
2177
- getKernel: current => { var _a; return (_a = current.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel; }
2401
+ mainMenu.helpMenu.getKernel.add({
2402
+ id: CommandIDs.getKernel,
2403
+ isEnabled
2178
2404
  });
2179
2405
  }
2180
2406
  /**
@@ -2195,7 +2421,8 @@ var Private;
2195
2421
  preferredLanguage: widget.context.model.defaultKernelLanguage,
2196
2422
  activate: activate,
2197
2423
  ref: widget.id,
2198
- insertMode: 'split-bottom'
2424
+ insertMode: 'split-bottom',
2425
+ type: 'Linked Console'
2199
2426
  };
2200
2427
  return commands.execute('console:create', options);
2201
2428
  }