@jupyterlab/notebook-extension 4.6.0-alpha.5 → 4.6.0-beta.1
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 +238 -9
- package/lib/index.js.map +1 -1
- package/package.json +33 -33
- package/schema/panel.json +4 -1
- package/schema/tracker.json +34 -9
- package/src/index.ts +264 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jupyterlab/notebook-extension",
|
|
3
|
-
"version": "4.6.0-
|
|
3
|
+
"version": "4.6.0-beta.1",
|
|
4
4
|
"description": "JupyterLab - Notebook Extension",
|
|
5
5
|
"homepage": "https://github.com/jupyterlab/jupyterlab",
|
|
6
6
|
"bugs": {
|
|
@@ -36,44 +36,44 @@
|
|
|
36
36
|
"watch": "tsc -b --watch"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@jupyter/ydoc": "^
|
|
40
|
-
"@jupyterlab/application": "^4.6.0-
|
|
41
|
-
"@jupyterlab/apputils": "^4.7.0-
|
|
42
|
-
"@jupyterlab/cell-toolbar": "^4.6.0-
|
|
43
|
-
"@jupyterlab/cells": "^4.6.0-
|
|
44
|
-
"@jupyterlab/codeeditor": "^4.6.0-
|
|
45
|
-
"@jupyterlab/codemirror": "^4.6.0-
|
|
46
|
-
"@jupyterlab/completer": "^4.6.0-
|
|
47
|
-
"@jupyterlab/coreutils": "^6.6.0-
|
|
48
|
-
"@jupyterlab/docmanager": "^4.6.0-
|
|
49
|
-
"@jupyterlab/docmanager-extension": "^4.6.0-
|
|
50
|
-
"@jupyterlab/docregistry": "^4.6.0-
|
|
51
|
-
"@jupyterlab/documentsearch": "^4.6.0-
|
|
52
|
-
"@jupyterlab/filebrowser": "^4.6.0-
|
|
53
|
-
"@jupyterlab/launcher": "^4.6.0-
|
|
54
|
-
"@jupyterlab/logconsole": "^4.6.0-
|
|
55
|
-
"@jupyterlab/lsp": "^4.6.0-
|
|
56
|
-
"@jupyterlab/mainmenu": "^4.6.0-
|
|
57
|
-
"@jupyterlab/metadataform": "^4.6.0-
|
|
58
|
-
"@jupyterlab/nbformat": "^4.6.0-
|
|
59
|
-
"@jupyterlab/notebook": "^4.6.0-
|
|
60
|
-
"@jupyterlab/observables": "^5.6.0-
|
|
61
|
-
"@jupyterlab/property-inspector": "^4.6.0-
|
|
62
|
-
"@jupyterlab/rendermime": "^4.6.0-
|
|
63
|
-
"@jupyterlab/services": "^7.6.0-
|
|
64
|
-
"@jupyterlab/settingregistry": "^4.6.0-
|
|
65
|
-
"@jupyterlab/statedb": "^4.6.0-
|
|
66
|
-
"@jupyterlab/statusbar": "^4.6.0-
|
|
67
|
-
"@jupyterlab/toc": "^6.6.0-
|
|
68
|
-
"@jupyterlab/translation": "^4.6.0-
|
|
69
|
-
"@jupyterlab/ui-components": "^4.6.0-
|
|
39
|
+
"@jupyter/ydoc": "^4.0.0-a3",
|
|
40
|
+
"@jupyterlab/application": "^4.6.0-beta.1",
|
|
41
|
+
"@jupyterlab/apputils": "^4.7.0-beta.1",
|
|
42
|
+
"@jupyterlab/cell-toolbar": "^4.6.0-beta.1",
|
|
43
|
+
"@jupyterlab/cells": "^4.6.0-beta.1",
|
|
44
|
+
"@jupyterlab/codeeditor": "^4.6.0-beta.1",
|
|
45
|
+
"@jupyterlab/codemirror": "^4.6.0-beta.1",
|
|
46
|
+
"@jupyterlab/completer": "^4.6.0-beta.1",
|
|
47
|
+
"@jupyterlab/coreutils": "^6.6.0-beta.1",
|
|
48
|
+
"@jupyterlab/docmanager": "^4.6.0-beta.1",
|
|
49
|
+
"@jupyterlab/docmanager-extension": "^4.6.0-beta.1",
|
|
50
|
+
"@jupyterlab/docregistry": "^4.6.0-beta.1",
|
|
51
|
+
"@jupyterlab/documentsearch": "^4.6.0-beta.1",
|
|
52
|
+
"@jupyterlab/filebrowser": "^4.6.0-beta.1",
|
|
53
|
+
"@jupyterlab/launcher": "^4.6.0-beta.1",
|
|
54
|
+
"@jupyterlab/logconsole": "^4.6.0-beta.1",
|
|
55
|
+
"@jupyterlab/lsp": "^4.6.0-beta.1",
|
|
56
|
+
"@jupyterlab/mainmenu": "^4.6.0-beta.1",
|
|
57
|
+
"@jupyterlab/metadataform": "^4.6.0-beta.1",
|
|
58
|
+
"@jupyterlab/nbformat": "^4.6.0-beta.1",
|
|
59
|
+
"@jupyterlab/notebook": "^4.6.0-beta.1",
|
|
60
|
+
"@jupyterlab/observables": "^5.6.0-beta.1",
|
|
61
|
+
"@jupyterlab/property-inspector": "^4.6.0-beta.1",
|
|
62
|
+
"@jupyterlab/rendermime": "^4.6.0-beta.1",
|
|
63
|
+
"@jupyterlab/services": "^7.6.0-beta.1",
|
|
64
|
+
"@jupyterlab/settingregistry": "^4.6.0-beta.1",
|
|
65
|
+
"@jupyterlab/statedb": "^4.6.0-beta.1",
|
|
66
|
+
"@jupyterlab/statusbar": "^4.6.0-beta.1",
|
|
67
|
+
"@jupyterlab/toc": "^6.6.0-beta.1",
|
|
68
|
+
"@jupyterlab/translation": "^4.6.0-beta.1",
|
|
69
|
+
"@jupyterlab/ui-components": "^4.6.0-beta.1",
|
|
70
70
|
"@lumino/algorithm": "^2.0.4",
|
|
71
71
|
"@lumino/commands": "^2.3.3",
|
|
72
72
|
"@lumino/coreutils": "^2.2.2",
|
|
73
73
|
"@lumino/disposable": "^2.1.5",
|
|
74
74
|
"@lumino/messaging": "^2.0.4",
|
|
75
75
|
"@lumino/polling": "^2.1.5",
|
|
76
|
-
"@lumino/widgets": "^2.
|
|
76
|
+
"@lumino/widgets": "^2.8.0",
|
|
77
77
|
"@rjsf/utils": "^5.13.4",
|
|
78
78
|
"react": "^18.2.0"
|
|
79
79
|
},
|
package/schema/panel.json
CHANGED
package/schema/tracker.json
CHANGED
|
@@ -250,6 +250,21 @@
|
|
|
250
250
|
"selector": ".jp-Notebook .jp-Cell",
|
|
251
251
|
"rank": 3
|
|
252
252
|
},
|
|
253
|
+
{
|
|
254
|
+
"command": "notebook:copy-selected-text",
|
|
255
|
+
"selector": ".jp-Notebook .jp-Cell",
|
|
256
|
+
"rank": 3
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"command": "notebook:cut-selected-text",
|
|
260
|
+
"selector": ".jp-Notebook .jp-InputArea-editor",
|
|
261
|
+
"rank": 3
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"command": "notebook:paste-text",
|
|
265
|
+
"selector": ".jp-Notebook .jp-InputArea-editor",
|
|
266
|
+
"rank": 3
|
|
267
|
+
},
|
|
253
268
|
{
|
|
254
269
|
"type": "separator",
|
|
255
270
|
"selector": ".jp-Notebook .jp-Cell",
|
|
@@ -305,11 +320,6 @@
|
|
|
305
320
|
"selector": ".jp-Notebook .jp-CodeCell",
|
|
306
321
|
"rank": 12
|
|
307
322
|
},
|
|
308
|
-
{
|
|
309
|
-
"command": "notebook:clear-all-cell-outputs",
|
|
310
|
-
"selector": ".jp-Notebook",
|
|
311
|
-
"rank": 13
|
|
312
|
-
},
|
|
313
323
|
{
|
|
314
324
|
"type": "separator",
|
|
315
325
|
"selector": ".jp-Notebook",
|
|
@@ -699,7 +709,11 @@
|
|
|
699
709
|
"title": "Default cell type",
|
|
700
710
|
"description": "The default type (markdown, code, or raw) for new cells",
|
|
701
711
|
"type": "string",
|
|
702
|
-
"
|
|
712
|
+
"oneOf": [
|
|
713
|
+
{ "const": "code", "title": "Code" },
|
|
714
|
+
{ "const": "markdown", "title": "Markdown" },
|
|
715
|
+
{ "const": "raw", "title": "Raw" }
|
|
716
|
+
],
|
|
703
717
|
"default": "code"
|
|
704
718
|
},
|
|
705
719
|
"autoStartDefaultKernel": {
|
|
@@ -717,7 +731,10 @@
|
|
|
717
731
|
"inputHistoryScope": {
|
|
718
732
|
"type": "string",
|
|
719
733
|
"default": "global",
|
|
720
|
-
"
|
|
734
|
+
"oneOf": [
|
|
735
|
+
{ "const": "global", "title": "Global" },
|
|
736
|
+
{ "const": "session", "title": "Session" }
|
|
737
|
+
],
|
|
721
738
|
"title": "Input History Scope",
|
|
722
739
|
"description": "Whether the line history for standard input (e.g. the ipdb prompt) should kept separately for different kernel sessions (`session`) or combined (`global`)."
|
|
723
740
|
},
|
|
@@ -813,7 +830,10 @@
|
|
|
813
830
|
"renderingLayout": {
|
|
814
831
|
"title": "Rendering Layout",
|
|
815
832
|
"description": "Global setting to define the rendering layout in notebooks. 'default' or 'side-by-side' are supported.",
|
|
816
|
-
"
|
|
833
|
+
"oneOf": [
|
|
834
|
+
{ "const": "default", "title": "Default" },
|
|
835
|
+
{ "const": "side-by-side", "title": "Side by side" }
|
|
836
|
+
],
|
|
817
837
|
"default": "default"
|
|
818
838
|
},
|
|
819
839
|
"sideBySideLeftMarginOverride": {
|
|
@@ -838,7 +858,12 @@
|
|
|
838
858
|
"windowingMode": {
|
|
839
859
|
"title": "Windowing mode",
|
|
840
860
|
"description": "- 'defer': Improve loading time - Wait for idle CPU cycles to attach out of viewport cells\n- 'full': Best performance with side effects - Attach to the DOM only cells in viewport\n- 'none': Worst performance without side effects - Attach all cells to the viewport\n- 'contentVisibility': Browser-optimized rendering - Use content-visibility to skip offscreen cells",
|
|
841
|
-
"
|
|
861
|
+
"oneOf": [
|
|
862
|
+
{ "const": "defer", "title": "Defer" },
|
|
863
|
+
{ "const": "full", "title": "Full" },
|
|
864
|
+
{ "const": "none", "title": "None" },
|
|
865
|
+
{ "const": "contentVisibility", "title": "Content visibility" }
|
|
866
|
+
],
|
|
842
867
|
"default": "contentVisibility"
|
|
843
868
|
},
|
|
844
869
|
"accessKernelHistory": {
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Jupyter Development Team.
|
|
2
2
|
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
4
|
/**
|
|
4
5
|
* @packageDocumentation
|
|
5
6
|
* @module notebook-extension
|
|
@@ -14,6 +15,7 @@ import type {
|
|
|
14
15
|
import { ILabShell, ILayoutRestorer, IRouter } from '@jupyterlab/application';
|
|
15
16
|
import type { ISessionContext } from '@jupyterlab/apputils';
|
|
16
17
|
import {
|
|
18
|
+
Clipboard,
|
|
17
19
|
createToolbarFactory,
|
|
18
20
|
Dialog,
|
|
19
21
|
ICommandPalette,
|
|
@@ -35,7 +37,7 @@ import { MarkdownCell } from '@jupyterlab/cells';
|
|
|
35
37
|
import type { CodeEditor } from '@jupyterlab/codeeditor';
|
|
36
38
|
import { IEditorServices, IPositionModel } from '@jupyterlab/codeeditor';
|
|
37
39
|
import type { IChangedArgs } from '@jupyterlab/coreutils';
|
|
38
|
-
import { PageConfig } from '@jupyterlab/coreutils';
|
|
40
|
+
import { compareVersions, PageConfig } from '@jupyterlab/coreutils';
|
|
39
41
|
|
|
40
42
|
import {
|
|
41
43
|
IEditorExtensionRegistry,
|
|
@@ -317,6 +319,10 @@ namespace CommandIDs {
|
|
|
317
319
|
|
|
318
320
|
export const selectLastRunCell = 'notebook:select-last-run-cell';
|
|
319
321
|
|
|
322
|
+
export const selectLastModifiedCell = 'notebook:select-last-modified-cell';
|
|
323
|
+
|
|
324
|
+
export const selectNextModifiedCell = 'notebook:select-next-modified-cell';
|
|
325
|
+
|
|
320
326
|
export const replaceSelection = 'notebook:replace-selection';
|
|
321
327
|
|
|
322
328
|
export const autoClosingBrackets = 'notebook:toggle-autoclosing-brackets';
|
|
@@ -340,6 +346,12 @@ namespace CommandIDs {
|
|
|
340
346
|
export const accessNextHistory = 'notebook:access-next-history-entry';
|
|
341
347
|
|
|
342
348
|
export const virtualScrollbar = 'notebook:toggle-virtual-scrollbar';
|
|
349
|
+
|
|
350
|
+
export const copySelectedtext = 'notebook:copy-selected-text';
|
|
351
|
+
|
|
352
|
+
export const pasteText = 'notebook:paste-text';
|
|
353
|
+
|
|
354
|
+
export const cutSelectedtext = 'notebook:cut-selected-text';
|
|
343
355
|
}
|
|
344
356
|
|
|
345
357
|
/**
|
|
@@ -664,11 +676,32 @@ export const exportPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
664
676
|
|
|
665
677
|
const { context } = current;
|
|
666
678
|
|
|
679
|
+
const serverVersion = PageConfig.getNotebookVersion();
|
|
680
|
+
const supportsHTMLSanitizationOption =
|
|
681
|
+
compareVersions(serverVersion, [4, 0, 0]) <
|
|
682
|
+
0 /* Jupyter Server only */ &&
|
|
683
|
+
compareVersions(serverVersion, [2, 18, 0]) >= 0;
|
|
684
|
+
|
|
685
|
+
let sanitizeHtml = false;
|
|
686
|
+
|
|
687
|
+
if (args['format'] === 'html' && supportsHTMLSanitizationOption) {
|
|
688
|
+
const result = await InputDialog.getBoolean({
|
|
689
|
+
title: trans.__('Export as HTML'),
|
|
690
|
+
label: trans.__('Sanitize HTML output'),
|
|
691
|
+
value: true
|
|
692
|
+
});
|
|
693
|
+
if (!result.button.accept) {
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
sanitizeHtml = result.value ?? false;
|
|
697
|
+
}
|
|
698
|
+
|
|
667
699
|
const exportOptions: NbConvert.IExportOptions = {
|
|
668
700
|
format: args['format'] as string,
|
|
669
701
|
path: current.context.path,
|
|
670
702
|
exporterOptions: {
|
|
671
|
-
download: true
|
|
703
|
+
download: true,
|
|
704
|
+
sanitizeHtml
|
|
672
705
|
}
|
|
673
706
|
};
|
|
674
707
|
|
|
@@ -983,7 +1016,12 @@ const tocPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
983
1016
|
mdParser: IMarkdownParser | null,
|
|
984
1017
|
settingRegistry: ISettingRegistry | null
|
|
985
1018
|
): void => {
|
|
986
|
-
const nbTocFactory = new NotebookToCFactory(
|
|
1019
|
+
const nbTocFactory = new NotebookToCFactory(
|
|
1020
|
+
tracker,
|
|
1021
|
+
mdParser,
|
|
1022
|
+
sanitizer,
|
|
1023
|
+
app.commands
|
|
1024
|
+
);
|
|
987
1025
|
tocRegistry.add(nbTocFactory);
|
|
988
1026
|
if (settingRegistry) {
|
|
989
1027
|
Promise.all([app.restored, settingRegistry.load(trackerPlugin.id)])
|
|
@@ -1230,7 +1268,8 @@ const openWithNoKernelPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
1230
1268
|
label: trans.__('Notebook (no kernel)'),
|
|
1231
1269
|
factory: FACTORY,
|
|
1232
1270
|
kernelPreference: {
|
|
1233
|
-
shouldStart: false
|
|
1271
|
+
shouldStart: false,
|
|
1272
|
+
shouldReuse: false
|
|
1234
1273
|
}
|
|
1235
1274
|
}
|
|
1236
1275
|
})
|
|
@@ -1305,6 +1344,10 @@ function activateNotebookTools(
|
|
|
1305
1344
|
return true;
|
|
1306
1345
|
};
|
|
1307
1346
|
notebookTools.title.icon = buildIcon;
|
|
1347
|
+
notebookTools.title.dataset = {
|
|
1348
|
+
...notebookTools.title.dataset,
|
|
1349
|
+
jpTabLabel: trans.__('Notebook Tools')
|
|
1350
|
+
};
|
|
1308
1351
|
notebookTools.title.caption = trans.__('Notebook Tools');
|
|
1309
1352
|
notebookTools.id = id;
|
|
1310
1353
|
|
|
@@ -2581,6 +2624,9 @@ function addCommands(
|
|
|
2581
2624
|
tracker.selectionChanged.connect(() => {
|
|
2582
2625
|
commands.notifyCommandChanged(CommandIDs.duplicateBelow);
|
|
2583
2626
|
commands.notifyCommandChanged(CommandIDs.deleteCell);
|
|
2627
|
+
commands.notifyCommandChanged(CommandIDs.copySelectedtext);
|
|
2628
|
+
commands.notifyCommandChanged(CommandIDs.pasteText);
|
|
2629
|
+
commands.notifyCommandChanged(CommandIDs.cutSelectedtext);
|
|
2584
2630
|
commands.notifyCommandChanged(CommandIDs.copy);
|
|
2585
2631
|
commands.notifyCommandChanged(CommandIDs.cut);
|
|
2586
2632
|
commands.notifyCommandChanged(CommandIDs.pasteBelow);
|
|
@@ -2597,6 +2643,16 @@ function addCommands(
|
|
|
2597
2643
|
commands.notifyCommandChanged(CommandIDs.deleteCell);
|
|
2598
2644
|
commands.notifyCommandChanged(CommandIDs.moveUp);
|
|
2599
2645
|
commands.notifyCommandChanged(CommandIDs.moveDown);
|
|
2646
|
+
commands.notifyCommandChanged(CommandIDs.selectLastModifiedCell);
|
|
2647
|
+
commands.notifyCommandChanged(CommandIDs.selectNextModifiedCell);
|
|
2648
|
+
});
|
|
2649
|
+
tracker.widgetAdded.connect((_, panel) => {
|
|
2650
|
+
panel.content.stateChanged.connect((_, args) => {
|
|
2651
|
+
if (args.name === 'lastModifiedCellStack') {
|
|
2652
|
+
commands.notifyCommandChanged(CommandIDs.selectLastModifiedCell);
|
|
2653
|
+
commands.notifyCommandChanged(CommandIDs.selectNextModifiedCell);
|
|
2654
|
+
}
|
|
2655
|
+
});
|
|
2600
2656
|
});
|
|
2601
2657
|
|
|
2602
2658
|
commands.addCommand(CommandIDs.runAndAdvance, {
|
|
@@ -3471,6 +3527,156 @@ function addCommands(
|
|
|
3471
3527
|
}
|
|
3472
3528
|
}
|
|
3473
3529
|
});
|
|
3530
|
+
|
|
3531
|
+
commands.addCommand(CommandIDs.copySelectedtext, {
|
|
3532
|
+
label: trans.__('Copy Selected Text'),
|
|
3533
|
+
caption: trans.__('Copy selected text from the active cell or output area'),
|
|
3534
|
+
execute: async args => {
|
|
3535
|
+
const current = getCurrent(tracker, shell, args);
|
|
3536
|
+
if (!current) {
|
|
3537
|
+
return;
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
// copying from the editor (input area)
|
|
3541
|
+
const editor = current.content.activeCell?.editor;
|
|
3542
|
+
if (editor) {
|
|
3543
|
+
const selection = editor.getSelection();
|
|
3544
|
+
const start = editor.getOffsetAt(selection.start);
|
|
3545
|
+
const end = editor.getOffsetAt(selection.end);
|
|
3546
|
+
const text = editor.model.sharedModel.getSource().slice(start, end);
|
|
3547
|
+
if (text) {
|
|
3548
|
+
await navigator.clipboard.writeText(text);
|
|
3549
|
+
return;
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3553
|
+
// fallback to DOM selection (output)
|
|
3554
|
+
const domSelection = window.getSelection();
|
|
3555
|
+
const selectedText = domSelection?.toString();
|
|
3556
|
+
if (selectedText && selectedText.trim().length > 0) {
|
|
3557
|
+
await navigator.clipboard.writeText(selectedText);
|
|
3558
|
+
}
|
|
3559
|
+
},
|
|
3560
|
+
|
|
3561
|
+
isEnabled: args => {
|
|
3562
|
+
const current = getCurrent(tracker, shell, { ...args, activate: false });
|
|
3563
|
+
if (!current) {
|
|
3564
|
+
return false;
|
|
3565
|
+
}
|
|
3566
|
+
|
|
3567
|
+
const editor = current.content.activeCell?.editor;
|
|
3568
|
+
if (editor) {
|
|
3569
|
+
const selection = editor.getSelection();
|
|
3570
|
+
const hasEditorSelection =
|
|
3571
|
+
selection.start.line !== selection.end.line ||
|
|
3572
|
+
selection.start.column !== selection.end.column;
|
|
3573
|
+
if (hasEditorSelection) {
|
|
3574
|
+
return true;
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
// Check for text selection in output area
|
|
3579
|
+
const domSelection = window.getSelection();
|
|
3580
|
+
return !!domSelection && domSelection.toString().trim().length > 0;
|
|
3581
|
+
},
|
|
3582
|
+
describedBy: {
|
|
3583
|
+
args: {
|
|
3584
|
+
type: 'object',
|
|
3585
|
+
properties: {}
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
});
|
|
3589
|
+
|
|
3590
|
+
commands.addCommand(CommandIDs.cutSelectedtext, {
|
|
3591
|
+
label: trans.__('Cut Selected Text'),
|
|
3592
|
+
caption: trans.__('Cut selected text from the active cell or output area'),
|
|
3593
|
+
execute: async args => {
|
|
3594
|
+
const current = getCurrent(tracker, shell, args);
|
|
3595
|
+
if (!current) {
|
|
3596
|
+
return;
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
const editor = current.content.activeCell?.editor;
|
|
3600
|
+
if (editor) {
|
|
3601
|
+
const selection = editor.getSelection();
|
|
3602
|
+
const start = editor.getOffsetAt(selection.start);
|
|
3603
|
+
const end = editor.getOffsetAt(selection.end);
|
|
3604
|
+
const text = editor.model.sharedModel.getSource().slice(start, end);
|
|
3605
|
+
if (text) {
|
|
3606
|
+
await navigator.clipboard.writeText(text);
|
|
3607
|
+
editor.replaceSelection?.('');
|
|
3608
|
+
return;
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
},
|
|
3612
|
+
|
|
3613
|
+
isEnabled: args => {
|
|
3614
|
+
const current = getCurrent(tracker, shell, { ...args, activate: false });
|
|
3615
|
+
if (!current) {
|
|
3616
|
+
return false;
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
const editor = current.content.activeCell?.editor;
|
|
3620
|
+
if (!editor) {
|
|
3621
|
+
return false;
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3624
|
+
const selection = editor.getSelection();
|
|
3625
|
+
const hasEditorSelection =
|
|
3626
|
+
selection.start.line !== selection.end.line ||
|
|
3627
|
+
selection.start.column !== selection.end.column;
|
|
3628
|
+
return hasEditorSelection;
|
|
3629
|
+
},
|
|
3630
|
+
describedBy: {
|
|
3631
|
+
args: {
|
|
3632
|
+
type: 'object',
|
|
3633
|
+
properties: {}
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
});
|
|
3637
|
+
|
|
3638
|
+
commands.addCommand(CommandIDs.pasteText, {
|
|
3639
|
+
label: trans.__('Paste Text'),
|
|
3640
|
+
caption: trans.__(
|
|
3641
|
+
'Paste text from the clipboard into the active cell editor'
|
|
3642
|
+
),
|
|
3643
|
+
execute: async args => {
|
|
3644
|
+
const current = getCurrent(tracker, shell, args);
|
|
3645
|
+
if (!current) {
|
|
3646
|
+
return;
|
|
3647
|
+
}
|
|
3648
|
+
|
|
3649
|
+
const editor = current.content.activeCell?.editor;
|
|
3650
|
+
if (!editor) {
|
|
3651
|
+
return;
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
try {
|
|
3655
|
+
const text = await navigator.clipboard.readText();
|
|
3656
|
+
if (text) {
|
|
3657
|
+
editor.replaceSelection?.(text);
|
|
3658
|
+
}
|
|
3659
|
+
} catch (err) {
|
|
3660
|
+
// browser limitation fallback (e.g Firefox)
|
|
3661
|
+
Clipboard.showPasteUnavailableDialog(trans);
|
|
3662
|
+
}
|
|
3663
|
+
},
|
|
3664
|
+
|
|
3665
|
+
isEnabled: args => {
|
|
3666
|
+
const current = getCurrent(tracker, shell, { ...args, activate: false });
|
|
3667
|
+
if (!current) {
|
|
3668
|
+
return false;
|
|
3669
|
+
}
|
|
3670
|
+
return !!current.content.activeCell?.editor;
|
|
3671
|
+
},
|
|
3672
|
+
describedBy: {
|
|
3673
|
+
args: {
|
|
3674
|
+
type: 'object',
|
|
3675
|
+
properties: {}
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
});
|
|
3679
|
+
|
|
3474
3680
|
commands.addCommand(CommandIDs.split, {
|
|
3475
3681
|
label: trans.__('Split Cell'),
|
|
3476
3682
|
execute: args => {
|
|
@@ -3505,7 +3711,16 @@ function addCommands(
|
|
|
3505
3711
|
);
|
|
3506
3712
|
}
|
|
3507
3713
|
},
|
|
3508
|
-
|
|
3714
|
+
isVisible: args => {
|
|
3715
|
+
const current = getCurrent(tracker, shell, { ...args, activate: false });
|
|
3716
|
+
if (!current) {
|
|
3717
|
+
return false;
|
|
3718
|
+
}
|
|
3719
|
+
|
|
3720
|
+
// Enable only if more than one cell is selected
|
|
3721
|
+
const notebook = current.content;
|
|
3722
|
+
return notebook && notebook.selectedCells.length > 1;
|
|
3723
|
+
},
|
|
3509
3724
|
describedBy: {
|
|
3510
3725
|
args: {
|
|
3511
3726
|
type: 'object',
|
|
@@ -4544,6 +4759,44 @@ function addCommands(
|
|
|
4544
4759
|
}
|
|
4545
4760
|
}
|
|
4546
4761
|
});
|
|
4762
|
+
commands.addCommand(CommandIDs.selectLastModifiedCell, {
|
|
4763
|
+
label: trans.__('Select Last Modified Cell'),
|
|
4764
|
+
execute: async args => {
|
|
4765
|
+
const current = getCurrent(tracker, shell, args);
|
|
4766
|
+
if (current) {
|
|
4767
|
+
await NotebookActions.selectLastModifiedCell(current.content);
|
|
4768
|
+
}
|
|
4769
|
+
},
|
|
4770
|
+
isEnabled: args => {
|
|
4771
|
+
const current = getCurrent(tracker, shell, { ...args, activate: false });
|
|
4772
|
+
return !!current && current.content.hasNavigableModifiedCellBack();
|
|
4773
|
+
},
|
|
4774
|
+
describedBy: {
|
|
4775
|
+
args: {
|
|
4776
|
+
type: 'object',
|
|
4777
|
+
properties: {}
|
|
4778
|
+
}
|
|
4779
|
+
}
|
|
4780
|
+
});
|
|
4781
|
+
commands.addCommand(CommandIDs.selectNextModifiedCell, {
|
|
4782
|
+
label: trans.__('Select Next Modified Cell'),
|
|
4783
|
+
execute: async args => {
|
|
4784
|
+
const current = getCurrent(tracker, shell, args);
|
|
4785
|
+
if (current) {
|
|
4786
|
+
await NotebookActions.selectNextModifiedCell(current.content);
|
|
4787
|
+
}
|
|
4788
|
+
},
|
|
4789
|
+
isEnabled: args => {
|
|
4790
|
+
const current = getCurrent(tracker, shell, { ...args, activate: false });
|
|
4791
|
+
return !!current && current.content.hasNavigableModifiedCellForward();
|
|
4792
|
+
},
|
|
4793
|
+
describedBy: {
|
|
4794
|
+
args: {
|
|
4795
|
+
type: 'object',
|
|
4796
|
+
properties: {}
|
|
4797
|
+
}
|
|
4798
|
+
}
|
|
4799
|
+
});
|
|
4547
4800
|
commands.addCommand(CommandIDs.replaceSelection, {
|
|
4548
4801
|
label: trans.__('Replace Selection in Notebook Cell'),
|
|
4549
4802
|
execute: args => {
|
|
@@ -4800,6 +5053,9 @@ function populatePalette(
|
|
|
4800
5053
|
CommandIDs.pasteAbove,
|
|
4801
5054
|
CommandIDs.pasteAndReplace,
|
|
4802
5055
|
CommandIDs.deleteCell,
|
|
5056
|
+
CommandIDs.copySelectedtext,
|
|
5057
|
+
CommandIDs.pasteText,
|
|
5058
|
+
CommandIDs.cutSelectedtext,
|
|
4803
5059
|
CommandIDs.split,
|
|
4804
5060
|
CommandIDs.merge,
|
|
4805
5061
|
CommandIDs.mergeAbove,
|
|
@@ -4838,7 +5094,9 @@ function populatePalette(
|
|
|
4838
5094
|
CommandIDs.toggleRenderSideBySideCurrentNotebook,
|
|
4839
5095
|
CommandIDs.setSideBySideRatio,
|
|
4840
5096
|
CommandIDs.enableOutputScrolling,
|
|
4841
|
-
CommandIDs.disableOutputScrolling
|
|
5097
|
+
CommandIDs.disableOutputScrolling,
|
|
5098
|
+
CommandIDs.selectLastModifiedCell,
|
|
5099
|
+
CommandIDs.selectNextModifiedCell
|
|
4842
5100
|
].forEach(command => {
|
|
4843
5101
|
palette.addItem({ command, category });
|
|
4844
5102
|
});
|