@difizen/libro-jupyter 0.0.2-alpha.0
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/LICENSE +21 -0
- package/README.md +1 -0
- package/es/add-between-cell/add-between-cell-command-contribution.d.ts +14 -0
- package/es/add-between-cell/add-between-cell-command-contribution.d.ts.map +1 -0
- package/es/add-between-cell/add-between-cell-command-contribution.js +97 -0
- package/es/add-between-cell/add-between-cell.d.ts +5 -0
- package/es/add-between-cell/add-between-cell.d.ts.map +1 -0
- package/es/add-between-cell/add-between-cell.js +243 -0
- package/es/add-between-cell/index.d.ts +3 -0
- package/es/add-between-cell/index.d.ts.map +1 -0
- package/es/add-between-cell/index.js +2 -0
- package/es/add-between-cell/index.less +103 -0
- package/es/add-between-cell/module.d.ts +3 -0
- package/es/add-between-cell/module.d.ts.map +1 -0
- package/es/add-between-cell/module.js +8 -0
- package/es/cell/index.d.ts +3 -0
- package/es/cell/index.d.ts.map +1 -0
- package/es/cell/index.js +2 -0
- package/es/cell/jupyter-code-cell-model.d.ts +12 -0
- package/es/cell/jupyter-code-cell-model.d.ts.map +1 -0
- package/es/cell/jupyter-code-cell-model.js +56 -0
- package/es/cell/jupyter-code-cell-view.d.ts +18 -0
- package/es/cell/jupyter-code-cell-view.d.ts.map +1 -0
- package/es/cell/jupyter-code-cell-view.js +280 -0
- package/es/command/command-contribution.d.ts +10 -0
- package/es/command/command-contribution.d.ts.map +1 -0
- package/es/command/command-contribution.js +161 -0
- package/es/command/index.d.ts +3 -0
- package/es/command/index.d.ts.map +1 -0
- package/es/command/index.js +2 -0
- package/es/command/keybinding-contribution.d.ts +8 -0
- package/es/command/keybinding-contribution.d.ts.map +1 -0
- package/es/command/keybinding-contribution.js +37 -0
- package/es/components/cell-execution-tip.d.ts +6 -0
- package/es/components/cell-execution-tip.d.ts.map +1 -0
- package/es/components/cell-execution-tip.js +69 -0
- package/es/components/cell-input-bottom-blank.d.ts +5 -0
- package/es/components/cell-input-bottom-blank.d.ts.map +1 -0
- package/es/components/cell-input-bottom-blank.js +21 -0
- package/es/components/icons.d.ts +5 -0
- package/es/components/icons.d.ts.map +1 -0
- package/es/components/icons.js +154 -0
- package/es/components/index.d.ts +4 -0
- package/es/components/index.d.ts.map +1 -0
- package/es/components/index.js +3 -0
- package/es/components/index.less +82 -0
- package/es/config/config-contribution.d.ts +10 -0
- package/es/config/config-contribution.d.ts.map +1 -0
- package/es/config/config-contribution.js +50 -0
- package/es/config/config.d.ts +3 -0
- package/es/config/config.d.ts.map +1 -0
- package/es/config/config.js +11 -0
- package/es/config/index.d.ts +2 -0
- package/es/config/index.d.ts.map +1 -0
- package/es/config/index.js +1 -0
- package/es/configuration/index.d.ts +3 -0
- package/es/configuration/index.d.ts.map +1 -0
- package/es/configuration/index.js +2 -0
- package/es/configuration/libro-configuration-contribution.d.ts +5 -0
- package/es/configuration/libro-configuration-contribution.d.ts.map +1 -0
- package/es/configuration/libro-configuration-contribution.js +24 -0
- package/es/configuration/libro-configuration.d.ts +3 -0
- package/es/configuration/libro-configuration.d.ts.map +1 -0
- package/es/configuration/libro-configuration.js +12 -0
- package/es/contents/content-contribution.d.ts +7 -0
- package/es/contents/content-contribution.d.ts.map +1 -0
- package/es/contents/content-contribution.js +63 -0
- package/es/contents/index.d.ts +2 -0
- package/es/contents/index.d.ts.map +1 -0
- package/es/contents/index.js +1 -0
- package/es/file/file-name-alias.d.ts +7 -0
- package/es/file/file-name-alias.d.ts.map +1 -0
- package/es/file/file-name-alias.js +26 -0
- package/es/file/file-protocol.d.ts +8 -0
- package/es/file/file-protocol.d.ts.map +1 -0
- package/es/file/file-protocol.js +7 -0
- package/es/file/file-service.d.ts +31 -0
- package/es/file/file-service.d.ts.map +1 -0
- package/es/file/file-service.js +329 -0
- package/es/file/file-tree-label-provider.d.ts +13 -0
- package/es/file/file-tree-label-provider.d.ts.map +1 -0
- package/es/file/file-tree-label-provider.js +62 -0
- package/es/file/file-view/index.d.ts +14 -0
- package/es/file/file-view/index.d.ts.map +1 -0
- package/es/file/file-view/index.js +101 -0
- package/es/file/file-view/index.less +5 -0
- package/es/file/index.d.ts +7 -0
- package/es/file/index.d.ts.map +1 -0
- package/es/file/index.js +6 -0
- package/es/file/module.d.ts +3 -0
- package/es/file/module.d.ts.map +1 -0
- package/es/file/module.js +8 -0
- package/es/file/navigatable-view.d.ts +24 -0
- package/es/file/navigatable-view.d.ts.map +1 -0
- package/es/file/navigatable-view.js +151 -0
- package/es/file/open-handler-contribution.d.ts +11 -0
- package/es/file/open-handler-contribution.d.ts.map +1 -0
- package/es/file/open-handler-contribution.js +102 -0
- package/es/index.d.ts +32 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +31 -0
- package/es/keybind-instructions/index.d.ts +6 -0
- package/es/keybind-instructions/index.d.ts.map +1 -0
- package/es/keybind-instructions/index.js +5 -0
- package/es/keybind-instructions/index.less +177 -0
- package/es/keybind-instructions/keybind-instructions-contribution.d.ts +11 -0
- package/es/keybind-instructions/keybind-instructions-contribution.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-contribution.js +84 -0
- package/es/keybind-instructions/keybind-instructions-icon.d.ts +3 -0
- package/es/keybind-instructions/keybind-instructions-icon.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-icon.js +23 -0
- package/es/keybind-instructions/keybind-instructions-items.d.ts +14 -0
- package/es/keybind-instructions/keybind-instructions-items.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-items.js +589 -0
- package/es/keybind-instructions/keybind-instructions-view.d.ts +16 -0
- package/es/keybind-instructions/keybind-instructions-view.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-view.js +224 -0
- package/es/keybind-instructions/module.d.ts +3 -0
- package/es/keybind-instructions/module.d.ts.map +1 -0
- package/es/keybind-instructions/module.js +5 -0
- package/es/libro-jupyter-file-service.d.ts +106 -0
- package/es/libro-jupyter-file-service.d.ts.map +1 -0
- package/es/libro-jupyter-file-service.js +127 -0
- package/es/libro-jupyter-model.d.ts +49 -0
- package/es/libro-jupyter-model.d.ts.map +1 -0
- package/es/libro-jupyter-model.js +505 -0
- package/es/libro-jupyter-protocol.d.ts +38 -0
- package/es/libro-jupyter-protocol.d.ts.map +1 -0
- package/es/libro-jupyter-protocol.js +9 -0
- package/es/libro-jupyter-server-launch-manager.d.ts +11 -0
- package/es/libro-jupyter-server-launch-manager.d.ts.map +1 -0
- package/es/libro-jupyter-server-launch-manager.js +59 -0
- package/es/libro-jupyter-view.d.ts +10 -0
- package/es/libro-jupyter-view.d.ts.map +1 -0
- package/es/libro-jupyter-view.js +42 -0
- package/es/module.d.ts +3 -0
- package/es/module.d.ts.map +1 -0
- package/es/module.js +48 -0
- package/es/output/index.d.ts +2 -0
- package/es/output/index.d.ts.map +1 -0
- package/es/output/index.js +1 -0
- package/es/output/libro-jupyter-outputarea.d.ts +8 -0
- package/es/output/libro-jupyter-outputarea.d.ts.map +1 -0
- package/es/output/libro-jupyter-outputarea.js +77 -0
- package/es/rendermime/assets/plotly.svg +31 -0
- package/es/rendermime/index.d.ts +5 -0
- package/es/rendermime/index.d.ts.map +1 -0
- package/es/rendermime/index.js +4 -0
- package/es/rendermime/index.less +22 -0
- package/es/rendermime/module.d.ts +3 -0
- package/es/rendermime/module.d.ts.map +1 -0
- package/es/rendermime/module.js +3 -0
- package/es/rendermime/plotly-render.d.ts +7 -0
- package/es/rendermime/plotly-render.d.ts.map +1 -0
- package/es/rendermime/plotly-render.js +30 -0
- package/es/rendermime/plotly-renderers.d.ts +58 -0
- package/es/rendermime/plotly-renderers.d.ts.map +1 -0
- package/es/rendermime/plotly-renderers.js +211 -0
- package/es/rendermime/plotly-rendermime-contribution.d.ts +12 -0
- package/es/rendermime/plotly-rendermime-contribution.d.ts.map +1 -0
- package/es/rendermime/plotly-rendermime-contribution.js +22 -0
- package/es/theme/color-registry.d.ts +6 -0
- package/es/theme/color-registry.d.ts.map +1 -0
- package/es/theme/color-registry.js +393 -0
- package/es/theme/index.d.ts +2 -0
- package/es/theme/index.d.ts.map +1 -0
- package/es/theme/index.js +1 -0
- package/es/toolbar/index.d.ts +6 -0
- package/es/toolbar/index.d.ts.map +1 -0
- package/es/toolbar/index.js +5 -0
- package/es/toolbar/index.less +194 -0
- package/es/toolbar/kernel-selector-dropdown.d.ts +13 -0
- package/es/toolbar/kernel-selector-dropdown.d.ts.map +1 -0
- package/es/toolbar/kernel-selector-dropdown.js +165 -0
- package/es/toolbar/kernel-status-and-selector.d.ts +18 -0
- package/es/toolbar/kernel-status-and-selector.d.ts.map +1 -0
- package/es/toolbar/kernel-status-and-selector.js +164 -0
- package/es/toolbar/run-selector.d.ts +3 -0
- package/es/toolbar/run-selector.d.ts.map +1 -0
- package/es/toolbar/run-selector.js +98 -0
- package/es/toolbar/save-file-error-contribution.d.ts +5 -0
- package/es/toolbar/save-file-error-contribution.d.ts.map +1 -0
- package/es/toolbar/save-file-error-contribution.js +23 -0
- package/es/toolbar/save-file-error.d.ts +5 -0
- package/es/toolbar/save-file-error.d.ts.map +1 -0
- package/es/toolbar/save-file-error.js +27 -0
- package/es/toolbar/side-toolbar-run-selector.d.ts +3 -0
- package/es/toolbar/side-toolbar-run-selector.d.ts.map +1 -0
- package/es/toolbar/side-toolbar-run-selector.js +67 -0
- package/es/toolbar/toolbar-contribution.d.ts +9 -0
- package/es/toolbar/toolbar-contribution.d.ts.map +1 -0
- package/es/toolbar/toolbar-contribution.js +67 -0
- package/es/typings/index.d.ts +31 -0
- package/es/utils/index.d.ts +11 -0
- package/es/utils/index.d.ts.map +1 -0
- package/es/utils/index.js +47 -0
- package/package.json +75 -0
- package/src/add-between-cell/add-between-cell-command-contribution.ts +63 -0
- package/src/add-between-cell/add-between-cell.tsx +201 -0
- package/src/add-between-cell/index.less +103 -0
- package/src/add-between-cell/index.ts +2 -0
- package/src/add-between-cell/module.ts +13 -0
- package/src/cell/index.ts +2 -0
- package/src/cell/jupyter-code-cell-model.ts +36 -0
- package/src/cell/jupyter-code-cell-view.tsx +221 -0
- package/src/command/command-contribution.ts +163 -0
- package/src/command/index.ts +2 -0
- package/src/command/keybinding-contribution.ts +25 -0
- package/src/components/cell-execution-tip.tsx +107 -0
- package/src/components/cell-input-bottom-blank.tsx +24 -0
- package/src/components/icons.tsx +117 -0
- package/src/components/index.less +82 -0
- package/src/components/index.ts +3 -0
- package/src/config/config-contribution.ts +21 -0
- package/src/config/config.ts +14 -0
- package/src/config/index.ts +1 -0
- package/src/configuration/index.ts +2 -0
- package/src/configuration/libro-configuration-contribution.ts +11 -0
- package/src/configuration/libro-configuration.ts +14 -0
- package/src/contents/content-contribution.ts +32 -0
- package/src/contents/index.ts +1 -0
- package/src/file/file-name-alias.ts +15 -0
- package/src/file/file-protocol.ts +7 -0
- package/src/file/file-service.ts +179 -0
- package/src/file/file-tree-label-provider.ts +42 -0
- package/src/file/file-view/index.less +5 -0
- package/src/file/file-view/index.tsx +90 -0
- package/src/file/index.ts +6 -0
- package/src/file/module.ts +19 -0
- package/src/file/navigatable-view.tsx +93 -0
- package/src/file/open-handler-contribution.ts +44 -0
- package/src/index.ts +32 -0
- package/src/keybind-instructions/index.less +177 -0
- package/src/keybind-instructions/index.ts +5 -0
- package/src/keybind-instructions/keybind-instructions-contribution.ts +47 -0
- package/src/keybind-instructions/keybind-instructions-icon.tsx +28 -0
- package/src/keybind-instructions/keybind-instructions-items.tsx +597 -0
- package/src/keybind-instructions/keybind-instructions-view.tsx +239 -0
- package/src/keybind-instructions/module.ts +11 -0
- package/src/libro-jupyter-file-service.ts +158 -0
- package/src/libro-jupyter-model.ts +289 -0
- package/src/libro-jupyter-protocol.ts +59 -0
- package/src/libro-jupyter-server-launch-manager.ts +36 -0
- package/src/libro-jupyter-view.tsx +24 -0
- package/src/module.ts +105 -0
- package/src/output/index.ts +1 -0
- package/src/output/libro-jupyter-outputarea.tsx +71 -0
- package/src/rendermime/assets/plotly.svg +31 -0
- package/src/rendermime/index.less +13 -0
- package/src/rendermime/index.ts +4 -0
- package/src/rendermime/module.ts +7 -0
- package/src/rendermime/plotly-render.tsx +35 -0
- package/src/rendermime/plotly-renderers.ts +191 -0
- package/src/rendermime/plotly-rendermime-contribution.ts +15 -0
- package/src/theme/color-registry.ts +301 -0
- package/src/theme/index.ts +1 -0
- package/src/toolbar/index.less +194 -0
- package/src/toolbar/index.ts +5 -0
- package/src/toolbar/kernel-selector-dropdown.tsx +204 -0
- package/src/toolbar/kernel-status-and-selector.tsx +195 -0
- package/src/toolbar/run-selector.tsx +110 -0
- package/src/toolbar/save-file-error-contribution.ts +10 -0
- package/src/toolbar/save-file-error.tsx +35 -0
- package/src/toolbar/side-toolbar-run-selector.tsx +77 -0
- package/src/toolbar/toolbar-contribution.tsx +62 -0
- package/src/typings/index.d.ts +31 -0
- package/src/utils/index.ts +65 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { LirboContextKey } from '@difizen/libro-core';
|
|
2
|
+
import { inject, singleton } from '@difizen/mana-app';
|
|
3
|
+
import { getOrigin, prop, useInject } from '@difizen/mana-app';
|
|
4
|
+
import type { ModalItem, ModalItemProps } from '@difizen/mana-app';
|
|
5
|
+
import type { Disposable } from '@difizen/mana-app';
|
|
6
|
+
import { l10n } from '@difizen/mana-l10n';
|
|
7
|
+
import { Input, Drawer, Table, Segmented } from 'antd';
|
|
8
|
+
import { forwardRef, useCallback, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import type { DataType } from './keybind-instructions-items.js';
|
|
11
|
+
import { LibroKeybindItems } from './keybind-instructions-items.js';
|
|
12
|
+
import './index.less';
|
|
13
|
+
|
|
14
|
+
const { Search } = Input;
|
|
15
|
+
|
|
16
|
+
const getSearchResult = (
|
|
17
|
+
value: string,
|
|
18
|
+
sourceData: DataType[],
|
|
19
|
+
targetData: DataType[],
|
|
20
|
+
) => {
|
|
21
|
+
sourceData.forEach((dataItem) => {
|
|
22
|
+
if (
|
|
23
|
+
typeof dataItem.actionDescription === 'string' &&
|
|
24
|
+
dataItem.actionDescription.indexOf(value) !== -1
|
|
25
|
+
) {
|
|
26
|
+
const matchIndex = dataItem.actionDescription.indexOf(value);
|
|
27
|
+
targetData.push({
|
|
28
|
+
key: dataItem.key,
|
|
29
|
+
actionDescription: (
|
|
30
|
+
<>
|
|
31
|
+
<span>{dataItem.actionDescription.substring(0, matchIndex)}</span>
|
|
32
|
+
<span className="libro-keybind-search-match">
|
|
33
|
+
{dataItem.actionDescription.substring(
|
|
34
|
+
matchIndex,
|
|
35
|
+
matchIndex + value.length,
|
|
36
|
+
)}
|
|
37
|
+
</span>
|
|
38
|
+
<span>
|
|
39
|
+
{dataItem.actionDescription.substring(matchIndex + value.length)}
|
|
40
|
+
</span>
|
|
41
|
+
</>
|
|
42
|
+
),
|
|
43
|
+
|
|
44
|
+
keybind: dataItem.keybind,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
@singleton()
|
|
51
|
+
export class KeybindInstrutionsService implements Disposable {
|
|
52
|
+
@inject(LirboContextKey) contextKey: LirboContextKey;
|
|
53
|
+
isKeybindInstructionsMask = false;
|
|
54
|
+
@prop() searchCommandModeData: DataType[] = [];
|
|
55
|
+
@prop() searchEditModeData: DataType[] = [];
|
|
56
|
+
|
|
57
|
+
dispose() {
|
|
58
|
+
this.searchCommandModeData = [];
|
|
59
|
+
this.searchEditModeData = [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type Segment = 'keybind' | 'magic';
|
|
64
|
+
|
|
65
|
+
const magicColumns = [
|
|
66
|
+
{
|
|
67
|
+
title: '关键字',
|
|
68
|
+
dataIndex: 'value',
|
|
69
|
+
key: 'value',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: '含义',
|
|
73
|
+
dataIndex: 'description',
|
|
74
|
+
key: 'description',
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const magics = [
|
|
79
|
+
{
|
|
80
|
+
key: '1',
|
|
81
|
+
value: '%timeit',
|
|
82
|
+
description: '测试单行语句的执行时间',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
key: '2',
|
|
86
|
+
value: '%%timeit',
|
|
87
|
+
description: '测试整个块中代码的执行时间',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
key: '3',
|
|
91
|
+
value: '%run',
|
|
92
|
+
description: '调用外部python脚本',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
key: '4',
|
|
96
|
+
value: '%pwd',
|
|
97
|
+
description: '查看当前工作目录',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: '5',
|
|
101
|
+
value: '%ls',
|
|
102
|
+
description: '查看目录文件列表',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
key: '6',
|
|
106
|
+
value: '%reset',
|
|
107
|
+
description: '清除全部变量',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: '7',
|
|
111
|
+
value: '%who',
|
|
112
|
+
description: '查看所有全局变量的名称,若给定类型参数,只返回该类型的变量列表',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
key: '8',
|
|
116
|
+
value: '%whos',
|
|
117
|
+
description: '显示所有的全局变量名称、类型、值/信息',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
key: '9',
|
|
121
|
+
value: '%env',
|
|
122
|
+
description: '列出全部环境变量',
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
export const KeybindInstrutionsComponent = forwardRef<
|
|
127
|
+
HTMLDivElement,
|
|
128
|
+
ModalItemProps<void>
|
|
129
|
+
>(function KeybindInstrutionsComponent(props, ref) {
|
|
130
|
+
const { visible, close } = props;
|
|
131
|
+
const [segment, setSegment] = useState<Segment>('keybind');
|
|
132
|
+
const keybindInstrutionsService = useInject<KeybindInstrutionsService>(
|
|
133
|
+
KeybindInstrutionsService,
|
|
134
|
+
);
|
|
135
|
+
const libroKeybindItems = useInject(LibroKeybindItems);
|
|
136
|
+
const handleClose = useCallback(() => {
|
|
137
|
+
close();
|
|
138
|
+
keybindInstrutionsService.contextKey.enableCommandMode();
|
|
139
|
+
keybindInstrutionsService.dispose();
|
|
140
|
+
}, [close, keybindInstrutionsService]);
|
|
141
|
+
const handleSearch = (value: string) => {
|
|
142
|
+
keybindInstrutionsService.searchCommandModeData = [];
|
|
143
|
+
keybindInstrutionsService.searchEditModeData = [];
|
|
144
|
+
getSearchResult(
|
|
145
|
+
value,
|
|
146
|
+
libroKeybindItems.commandModeData,
|
|
147
|
+
keybindInstrutionsService.searchCommandModeData,
|
|
148
|
+
);
|
|
149
|
+
getSearchResult(
|
|
150
|
+
value,
|
|
151
|
+
libroKeybindItems.editModeData,
|
|
152
|
+
keybindInstrutionsService.searchEditModeData,
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const commandModeDataSource = getOrigin(
|
|
157
|
+
keybindInstrutionsService.searchCommandModeData.length > 0
|
|
158
|
+
? keybindInstrutionsService.searchCommandModeData
|
|
159
|
+
: libroKeybindItems.commandModeData,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const editModeDataSource = getOrigin(
|
|
163
|
+
keybindInstrutionsService.searchEditModeData.length > 0
|
|
164
|
+
? keybindInstrutionsService.searchEditModeData
|
|
165
|
+
: libroKeybindItems.editModeData,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<div className="libro-keybind-instructions-command" ref={ref}>
|
|
170
|
+
<Drawer
|
|
171
|
+
title={
|
|
172
|
+
<Segmented
|
|
173
|
+
value={segment}
|
|
174
|
+
onChange={(value) => setSegment(value as Segment)}
|
|
175
|
+
options={[
|
|
176
|
+
{ label: l10n.t('快捷键'), value: 'keybind' },
|
|
177
|
+
{ label: 'Magic 命令', value: 'magic' },
|
|
178
|
+
]}
|
|
179
|
+
/>
|
|
180
|
+
}
|
|
181
|
+
placement="right"
|
|
182
|
+
onClose={handleClose}
|
|
183
|
+
width="360px"
|
|
184
|
+
open={visible}
|
|
185
|
+
mask={true}
|
|
186
|
+
className="libro-keybind-instructions-drawer"
|
|
187
|
+
maskClosable={true}
|
|
188
|
+
>
|
|
189
|
+
{segment === 'magic' && (
|
|
190
|
+
<div className="libro-magic-table">
|
|
191
|
+
<Table
|
|
192
|
+
size="small"
|
|
193
|
+
columns={magicColumns}
|
|
194
|
+
dataSource={magics}
|
|
195
|
+
pagination={false}
|
|
196
|
+
rowKey="key"
|
|
197
|
+
/>
|
|
198
|
+
</div>
|
|
199
|
+
)}
|
|
200
|
+
{segment === 'keybind' && (
|
|
201
|
+
<>
|
|
202
|
+
<div className="libro-keybind-instructions-command-search">
|
|
203
|
+
<Search
|
|
204
|
+
placeholder={l10n.t('搜索功能关键字')}
|
|
205
|
+
allowClear
|
|
206
|
+
bordered={false}
|
|
207
|
+
size="middle"
|
|
208
|
+
onSearch={handleSearch}
|
|
209
|
+
/>
|
|
210
|
+
</div>
|
|
211
|
+
<div className="libro-keybind-instructions-table">
|
|
212
|
+
<div className="libro-command-mode-keybind-instructions-table">
|
|
213
|
+
<Table
|
|
214
|
+
rowKey="key"
|
|
215
|
+
columns={libroKeybindItems.commandModeActionColumns}
|
|
216
|
+
dataSource={commandModeDataSource}
|
|
217
|
+
pagination={false}
|
|
218
|
+
/>
|
|
219
|
+
</div>
|
|
220
|
+
<div className="libro-edit-mode-keybind-instructions-table">
|
|
221
|
+
<Table
|
|
222
|
+
rowKey="key"
|
|
223
|
+
columns={libroKeybindItems.editModeActionColumns}
|
|
224
|
+
dataSource={editModeDataSource}
|
|
225
|
+
pagination={false}
|
|
226
|
+
/>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</>
|
|
230
|
+
)}
|
|
231
|
+
</Drawer>
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
export const KeybindInstrutionModal: ModalItem = {
|
|
237
|
+
id: 'libro-keybind-instructions-modal',
|
|
238
|
+
component: KeybindInstrutionsComponent,
|
|
239
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ManaModule } from '@difizen/mana-app';
|
|
2
|
+
|
|
3
|
+
import { KeybindInstructionsContribution } from './keybind-instructions-contribution.js';
|
|
4
|
+
import { LibroKeybindItems } from './keybind-instructions-items.js';
|
|
5
|
+
import { KeybindInstrutionsService } from './keybind-instructions-view.js';
|
|
6
|
+
|
|
7
|
+
export const KeybindInstructionsModule = ManaModule.create().register(
|
|
8
|
+
KeybindInstrutionsService,
|
|
9
|
+
LibroKeybindItems,
|
|
10
|
+
KeybindInstructionsContribution,
|
|
11
|
+
);
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { INotebookContent } from '@difizen/libro-common';
|
|
2
|
+
import type { IContentsModel } from '@difizen/libro-kernel';
|
|
3
|
+
import { ServerManager, ContentsManager } from '@difizen/libro-kernel';
|
|
4
|
+
import { Emitter } from '@difizen/mana-app';
|
|
5
|
+
import { inject, singleton } from '@difizen/mana-app';
|
|
6
|
+
import type { URI } from '@difizen/mana-app';
|
|
7
|
+
import type { Event as ManaEvent } from '@difizen/mana-app';
|
|
8
|
+
|
|
9
|
+
import { LibroFileService } from './libro-jupyter-protocol.js';
|
|
10
|
+
|
|
11
|
+
export interface BaseStat {
|
|
12
|
+
/**
|
|
13
|
+
* The unified resource identifier of this file or folder.
|
|
14
|
+
*/
|
|
15
|
+
resource: URI;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The name which is the last segment
|
|
19
|
+
* of the {{path}}.
|
|
20
|
+
*/
|
|
21
|
+
name: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The size of the file.
|
|
25
|
+
*
|
|
26
|
+
* The value may or may not be resolved as
|
|
27
|
+
* it is optional.
|
|
28
|
+
*/
|
|
29
|
+
size?: number;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The last modification date represented as millis from unix epoch.
|
|
33
|
+
*
|
|
34
|
+
* The value may or may not be resolved as
|
|
35
|
+
* it is optional.
|
|
36
|
+
*/
|
|
37
|
+
mtime?: number;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The creation date represented as millis from unix epoch.
|
|
41
|
+
*
|
|
42
|
+
* The value may or may not be resolved as
|
|
43
|
+
* it is optional.
|
|
44
|
+
*/
|
|
45
|
+
ctime?: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A unique identifier that represents the
|
|
49
|
+
* current state of the file or directory.
|
|
50
|
+
*
|
|
51
|
+
* The value may or may not be resolved as
|
|
52
|
+
* it is optional.
|
|
53
|
+
*/
|
|
54
|
+
etag?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface BaseStatWithMetadata extends BaseStat {
|
|
58
|
+
mtime: number;
|
|
59
|
+
ctime: number;
|
|
60
|
+
etag: string;
|
|
61
|
+
size: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A file resource with meta information.
|
|
66
|
+
*/
|
|
67
|
+
export interface FileStat extends BaseStat {
|
|
68
|
+
/**
|
|
69
|
+
* The resource is a file.
|
|
70
|
+
*/
|
|
71
|
+
isFile: boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The resource is a directory.
|
|
75
|
+
*/
|
|
76
|
+
isDirectory: boolean;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The resource is a symbolic link.
|
|
80
|
+
*/
|
|
81
|
+
isSymbolicLink: boolean;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The children of the file stat or undefined if none.
|
|
85
|
+
*/
|
|
86
|
+
children?: FileStat[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface FileStatWithMetadata extends FileStat, BaseStatWithMetadata {
|
|
90
|
+
mtime: number;
|
|
91
|
+
ctime: number;
|
|
92
|
+
etag: string;
|
|
93
|
+
size: number;
|
|
94
|
+
type?: number;
|
|
95
|
+
children?: FileStatWithMetadata[];
|
|
96
|
+
}
|
|
97
|
+
export interface FileMeta extends Omit<FileStatWithMetadata, 'children' | 'resource'> {
|
|
98
|
+
resource: string;
|
|
99
|
+
children?: FileMeta[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export class LibroFileError extends Error {
|
|
103
|
+
protected errorCause?: string;
|
|
104
|
+
constructor(message: string, errorCause?: string) {
|
|
105
|
+
super(message);
|
|
106
|
+
this.errorCause = errorCause;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@singleton({ contrib: LibroFileService })
|
|
111
|
+
export class LibroJupyterFileService implements LibroFileService {
|
|
112
|
+
protected readonly contentsManager: ContentsManager;
|
|
113
|
+
protected serverManager: ServerManager;
|
|
114
|
+
fileSaveErrorEmitter: Emitter<
|
|
115
|
+
Partial<IContentsModel> & { msg?: string; cause?: string }
|
|
116
|
+
>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* A signal emitted when the file save error.
|
|
120
|
+
*/
|
|
121
|
+
get fileSaveError(): ManaEvent<Partial<IContentsModel>> {
|
|
122
|
+
return this.fileSaveErrorEmitter.event;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
constructor(
|
|
126
|
+
@inject(ContentsManager)
|
|
127
|
+
contentsManager: ContentsManager,
|
|
128
|
+
@inject(ServerManager)
|
|
129
|
+
serverManager: ServerManager,
|
|
130
|
+
) {
|
|
131
|
+
this.contentsManager = contentsManager;
|
|
132
|
+
this.serverManager = serverManager;
|
|
133
|
+
this.fileSaveErrorEmitter = new Emitter<
|
|
134
|
+
Partial<IContentsModel> & { msg?: string; cause?: string }
|
|
135
|
+
>();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async read(path: string): Promise<IContentsModel | undefined> {
|
|
139
|
+
await this.serverManager.ready;
|
|
140
|
+
return await this.contentsManager.get(path);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async write(
|
|
144
|
+
notebookContent: INotebookContent,
|
|
145
|
+
currentFileContents: IContentsModel,
|
|
146
|
+
): Promise<IContentsModel | undefined> {
|
|
147
|
+
await this.serverManager.ready;
|
|
148
|
+
try {
|
|
149
|
+
return await this.contentsManager.save(currentFileContents.path, {
|
|
150
|
+
type: currentFileContents.type,
|
|
151
|
+
content: notebookContent,
|
|
152
|
+
format: currentFileContents.format,
|
|
153
|
+
});
|
|
154
|
+
} catch (e: any) {
|
|
155
|
+
throw new LibroFileError(e.message, 'jupyter service save error');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { LibroModel } from '@difizen/libro-core';
|
|
2
|
+
import type {
|
|
3
|
+
IContentsModel,
|
|
4
|
+
ExecutableNotebookModel,
|
|
5
|
+
IContentsCheckpointModel,
|
|
6
|
+
IKernelConnection,
|
|
7
|
+
} from '@difizen/libro-kernel';
|
|
8
|
+
import {
|
|
9
|
+
LibroKernelConnectionManager,
|
|
10
|
+
ServerManager,
|
|
11
|
+
ContentsManager,
|
|
12
|
+
ServerConnection,
|
|
13
|
+
} from '@difizen/libro-kernel';
|
|
14
|
+
import { prop, ModalService, getOrigin } from '@difizen/mana-app';
|
|
15
|
+
import { inject, transient } from '@difizen/mana-app';
|
|
16
|
+
import { Deferred } from '@difizen/mana-app';
|
|
17
|
+
import { l10n } from '@difizen/mana-l10n';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
LibroFileService,
|
|
21
|
+
ExecutedWithKernelCellModel,
|
|
22
|
+
} from './libro-jupyter-protocol.js';
|
|
23
|
+
import { SaveFileErrorModal } from './toolbar/save-file-error.js';
|
|
24
|
+
import { getDefaultKernel } from './utils/index.js';
|
|
25
|
+
|
|
26
|
+
type IModel = IContentsModel;
|
|
27
|
+
@transient()
|
|
28
|
+
export class LibroJupyterModel extends LibroModel implements ExecutableNotebookModel {
|
|
29
|
+
protected libroFileService: LibroFileService;
|
|
30
|
+
|
|
31
|
+
get fileService() {
|
|
32
|
+
return this.libroFileService;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@prop()
|
|
36
|
+
currentFileContents: IModel;
|
|
37
|
+
@prop()
|
|
38
|
+
protected kernelSelect: string;
|
|
39
|
+
@prop()
|
|
40
|
+
protected kernelStatus: string;
|
|
41
|
+
@prop()
|
|
42
|
+
kernelConnection?: IKernelConnection;
|
|
43
|
+
|
|
44
|
+
@prop()
|
|
45
|
+
lspEnabled = false;
|
|
46
|
+
|
|
47
|
+
protected kernelConnectionManager: LibroKernelConnectionManager;
|
|
48
|
+
protected serverManager: ServerManager;
|
|
49
|
+
protected serverConnection: ServerConnection;
|
|
50
|
+
protected readonly contentsManager: ContentsManager;
|
|
51
|
+
protected readonly modalService: ModalService;
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
@inject(LibroFileService) libroFileService: LibroFileService,
|
|
55
|
+
@inject(LibroKernelConnectionManager)
|
|
56
|
+
kernelConnectionManager: LibroKernelConnectionManager,
|
|
57
|
+
@inject(ServerManager) serverManager: ServerManager,
|
|
58
|
+
@inject(ServerConnection) serverConnection: ServerConnection,
|
|
59
|
+
@inject(ContentsManager) contentsManager: ContentsManager,
|
|
60
|
+
@inject(ModalService) modalService: ModalService,
|
|
61
|
+
) {
|
|
62
|
+
super();
|
|
63
|
+
this.kernelSelection = getDefaultKernel();
|
|
64
|
+
this.libroFileService = libroFileService;
|
|
65
|
+
this.kernelConnectionManager = kernelConnectionManager;
|
|
66
|
+
this.serverManager = serverManager;
|
|
67
|
+
this.serverConnection = serverConnection;
|
|
68
|
+
this.contentsManager = contentsManager;
|
|
69
|
+
this.modalService = modalService;
|
|
70
|
+
this.dndAreaNullEnable = true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get isKernelIdle() {
|
|
74
|
+
return this.kernelConnection && this.kernelConnection.status === 'idle';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get kernelSelection() {
|
|
78
|
+
return this.kernelSelect;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
set kernelSelection(value: string) {
|
|
82
|
+
this.kernelSelect = value;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get currentKernelStatus() {
|
|
86
|
+
return this.kernelStatus;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
set currentKernelStatus(value: string) {
|
|
90
|
+
this.kernelStatus = value;
|
|
91
|
+
}
|
|
92
|
+
protected kcDeferred = new Deferred<IKernelConnection>();
|
|
93
|
+
get kcReady() {
|
|
94
|
+
return this.kcDeferred.promise;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@prop()
|
|
98
|
+
kernelConnecting: boolean | undefined;
|
|
99
|
+
|
|
100
|
+
@prop()
|
|
101
|
+
filePath = '';
|
|
102
|
+
|
|
103
|
+
protected last_modified = '';
|
|
104
|
+
|
|
105
|
+
get lastModified() {
|
|
106
|
+
return this.last_modified;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
set lastModified(value: string) {
|
|
110
|
+
this.last_modified = value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
latestCheckPointModel: IContentsCheckpointModel;
|
|
114
|
+
|
|
115
|
+
async createCheckpoint() {
|
|
116
|
+
this.latestCheckPointModel = await this.contentsManager.createCheckpoint(
|
|
117
|
+
this.filePath,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async listCheckpoints() {
|
|
122
|
+
await this.contentsManager.listCheckpoints(this.filePath);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async restoreCheckpoint(checkpointID: string) {
|
|
126
|
+
await this.contentsManager.restoreCheckpoint(this.filePath, checkpointID);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async deleteCheckpoint(checkpointID: string) {
|
|
130
|
+
await this.contentsManager.deleteCheckpoint(this.filePath, checkpointID);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
startKernelConnection() {
|
|
134
|
+
this.kernelConnecting = true;
|
|
135
|
+
const fileInfo = this.currentFileContents;
|
|
136
|
+
this.serverManager.ready
|
|
137
|
+
.then(async () => {
|
|
138
|
+
const kernelConnection =
|
|
139
|
+
this.kernelConnectionManager.getKernelConnection(fileInfo);
|
|
140
|
+
if (kernelConnection) {
|
|
141
|
+
this.kernelConnection = kernelConnection;
|
|
142
|
+
this.kcDeferred.resolve(this.kernelConnection);
|
|
143
|
+
this.kernelConnecting = false;
|
|
144
|
+
} else {
|
|
145
|
+
const kc = await this.kernelConnectionManager.startNew(
|
|
146
|
+
this.currentFileContents,
|
|
147
|
+
);
|
|
148
|
+
if (!kc) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.kernelConnection = kc;
|
|
152
|
+
this.kcDeferred.resolve(kc);
|
|
153
|
+
this.kernelConnecting = false;
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
})
|
|
157
|
+
.catch(() => {
|
|
158
|
+
//
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
override async saveNotebookContent(): Promise<void> {
|
|
163
|
+
const notebookContent = this.toJSON();
|
|
164
|
+
if (!this.currentFileContents) {
|
|
165
|
+
throw new Error('currentFileContents is undefined');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let res = {} as IModel | undefined;
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
res = await this.libroFileService.write(
|
|
172
|
+
notebookContent,
|
|
173
|
+
this.currentFileContents,
|
|
174
|
+
);
|
|
175
|
+
if (!res) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// 文件保存失败
|
|
179
|
+
if (res.last_modified === this.last_modified || res.size === 0) {
|
|
180
|
+
const errorMsg = `File Save Error: ${res?.message} `;
|
|
181
|
+
this.libroFileService.fileSaveErrorEmitter.fire({
|
|
182
|
+
cause: res.message,
|
|
183
|
+
msg: errorMsg,
|
|
184
|
+
name: res.name,
|
|
185
|
+
path: res.path,
|
|
186
|
+
created: res.created,
|
|
187
|
+
last_modified: res.last_modified,
|
|
188
|
+
size: res.size,
|
|
189
|
+
type: res.type,
|
|
190
|
+
});
|
|
191
|
+
this.modalService.openModal(SaveFileErrorModal);
|
|
192
|
+
|
|
193
|
+
throw new Error(errorMsg);
|
|
194
|
+
}
|
|
195
|
+
} catch (e: any) {
|
|
196
|
+
if (!res) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.libroFileService.fileSaveErrorEmitter.fire({
|
|
200
|
+
cause: e.errorCause,
|
|
201
|
+
msg: e.message,
|
|
202
|
+
name: res.name || this.currentFileContents.name,
|
|
203
|
+
path: res.path || this.currentFileContents.path,
|
|
204
|
+
created: res.created || this.currentFileContents.created,
|
|
205
|
+
last_modified: res.last_modified || this.currentFileContents.last_modified,
|
|
206
|
+
size: res.size || this.currentFileContents.size,
|
|
207
|
+
type: res.type || this.currentFileContents.type,
|
|
208
|
+
});
|
|
209
|
+
this.modalService.openModal(SaveFileErrorModal);
|
|
210
|
+
|
|
211
|
+
throw new Error('File Save Error');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
await this.createCheckpoint();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
override canRun() {
|
|
218
|
+
if (!this.kernelConnection) {
|
|
219
|
+
alert(l10n.t('Kernel Connection 还没有建立'));
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (this.kernelConnection.isDisposed) {
|
|
224
|
+
alert('Kernel Connection disposed');
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async interrupt() {
|
|
232
|
+
if (!this.kernelConnection) {
|
|
233
|
+
alert(l10n.t('Kernel Connection 还没有建立'));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
await this.kernelConnection.interrupt();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async shutdown() {
|
|
240
|
+
if (!this.kernelConnection) {
|
|
241
|
+
alert(l10n.t('Kernel Connection 还没有建立'));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
await this.kernelConnectionManager.shutdownKC(this.currentFileContents);
|
|
246
|
+
this.kernelConnection = undefined;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async restart() {
|
|
250
|
+
if (!this.kernelConnection || this.kernelConnection.isDisposed) {
|
|
251
|
+
this.startKernelConnection();
|
|
252
|
+
getOrigin(this.kcReady)
|
|
253
|
+
.then(() => {
|
|
254
|
+
if (!this.kernelConnection) {
|
|
255
|
+
alert(l10n.t('Kernel Connection 还没有建立'));
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
return;
|
|
259
|
+
})
|
|
260
|
+
.catch(() => {
|
|
261
|
+
//
|
|
262
|
+
});
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.kernelConnection.restart();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async reconnect() {
|
|
270
|
+
if (!this.kernelConnection) {
|
|
271
|
+
alert(l10n.t('Kernel Connection 还没有建立'));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
await this.kernelConnection.reconnect();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
findRunningCell() {
|
|
278
|
+
const runningCellIndex = this.cells.findIndex((item) => {
|
|
279
|
+
if (ExecutedWithKernelCellModel.is(item.model)) {
|
|
280
|
+
return item.model.kernelExecuting === true;
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
283
|
+
});
|
|
284
|
+
if (runningCellIndex > -1) {
|
|
285
|
+
this.selectCell(this.cells[runningCellIndex]);
|
|
286
|
+
this.scrollToView(this.cells[runningCellIndex]);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|