@opensumi/ide-editor 2.21.13 → 2.22.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.
Files changed (238) hide show
  1. package/lib/browser/breadcrumb/default.js.map +1 -1
  2. package/lib/browser/breadcrumb/document-symbol.js.map +1 -1
  3. package/lib/browser/breadcrumb/index.js.map +1 -1
  4. package/lib/browser/component.js.map +1 -1
  5. package/lib/browser/decoration-applier.js.map +1 -1
  6. package/lib/browser/diff/compare.js.map +1 -1
  7. package/lib/browser/diff/index.d.ts.map +1 -1
  8. package/lib/browser/diff/index.js +1 -1
  9. package/lib/browser/diff/index.js.map +1 -1
  10. package/lib/browser/doc-cache/empty-doc-cache.js.map +1 -1
  11. package/lib/browser/doc-cache/local-storage-cache.js.map +1 -1
  12. package/lib/browser/doc-model/editor-document-model-service.js +3 -3
  13. package/lib/browser/doc-model/editor-document-model-service.js.map +1 -1
  14. package/lib/browser/doc-model/editor-document-model.d.ts +8 -0
  15. package/lib/browser/doc-model/editor-document-model.d.ts.map +1 -1
  16. package/lib/browser/doc-model/editor-document-model.js +61 -11
  17. package/lib/browser/doc-model/editor-document-model.js.map +1 -1
  18. package/lib/browser/doc-model/editor-document-registry.js.map +1 -1
  19. package/lib/browser/doc-model/override.js.map +1 -1
  20. package/lib/browser/doc-model/save-task.js +1 -1
  21. package/lib/browser/doc-model/save-task.js.map +1 -1
  22. package/lib/browser/doc-model/saveParticipants.d.ts +7 -7
  23. package/lib/browser/doc-model/saveParticipants.d.ts.map +1 -1
  24. package/lib/browser/doc-model/saveParticipants.js +69 -38
  25. package/lib/browser/doc-model/saveParticipants.js.map +1 -1
  26. package/lib/browser/doc-model/types.d.ts +1 -1
  27. package/lib/browser/doc-model/types.d.ts.map +1 -1
  28. package/lib/browser/editor-collection.service.d.ts +8 -3
  29. package/lib/browser/editor-collection.service.d.ts.map +1 -1
  30. package/lib/browser/editor-collection.service.js +75 -66
  31. package/lib/browser/editor-collection.service.js.map +1 -1
  32. package/lib/browser/editor-opener.js.map +1 -1
  33. package/lib/browser/editor.contribution.d.ts.map +1 -1
  34. package/lib/browser/editor.contribution.js +31 -3
  35. package/lib/browser/editor.contribution.js.map +1 -1
  36. package/lib/browser/editor.decoration.service.d.ts +5 -6
  37. package/lib/browser/editor.decoration.service.d.ts.map +1 -1
  38. package/lib/browser/editor.decoration.service.js +9 -1
  39. package/lib/browser/editor.decoration.service.js.map +1 -1
  40. package/lib/browser/editor.override.js +2 -2
  41. package/lib/browser/editor.override.js.map +1 -1
  42. package/lib/browser/editor.status-bar.service.js.map +1 -1
  43. package/lib/browser/editor.view.d.ts.map +1 -1
  44. package/lib/browser/editor.view.js +20 -23
  45. package/lib/browser/editor.view.js.map +1 -1
  46. package/lib/browser/error.d.ts +1 -1
  47. package/lib/browser/error.d.ts.map +1 -1
  48. package/lib/browser/feature.js.map +1 -1
  49. package/lib/browser/format/format.service.js.map +1 -1
  50. package/lib/browser/format/formatterSelect.js.map +1 -1
  51. package/lib/browser/fs-resource/file-tree-set.js +6 -6
  52. package/lib/browser/fs-resource/file-tree-set.js.map +1 -1
  53. package/lib/browser/fs-resource/fs-editor-doc.js +1 -1
  54. package/lib/browser/fs-resource/fs-editor-doc.js.map +1 -1
  55. package/lib/browser/fs-resource/fs-resource.js.map +1 -1
  56. package/lib/browser/fs-resource/index.js.map +1 -1
  57. package/lib/browser/history/index.d.ts.map +1 -1
  58. package/lib/browser/history/index.js +2 -1
  59. package/lib/browser/history/index.js.map +1 -1
  60. package/lib/browser/index.d.ts.map +1 -1
  61. package/lib/browser/index.js +2 -0
  62. package/lib/browser/index.js.map +1 -1
  63. package/lib/browser/language/diagnostic-collection.d.ts +5 -5
  64. package/lib/browser/language/diagnostic-collection.d.ts.map +1 -1
  65. package/lib/browser/language/diagnostic-collection.js +1 -1
  66. package/lib/browser/language/diagnostic-collection.js.map +1 -1
  67. package/lib/browser/language/language-status.contribution.js.map +1 -1
  68. package/lib/browser/language/language-status.service.js.map +1 -1
  69. package/lib/browser/language/language.service.d.ts +4 -3
  70. package/lib/browser/language/language.service.d.ts.map +1 -1
  71. package/lib/browser/language/language.service.js +8 -2
  72. package/lib/browser/language/language.service.js.map +1 -1
  73. package/lib/browser/menu/editor.context.js +3 -3
  74. package/lib/browser/menu/editor.context.js.map +1 -1
  75. package/lib/browser/menu/editor.menu.d.ts +2 -2
  76. package/lib/browser/menu/editor.menu.d.ts.map +1 -1
  77. package/lib/browser/menu/editor.menu.js +6 -8
  78. package/lib/browser/menu/editor.menu.js.map +1 -1
  79. package/lib/browser/menu/open-type-menu.contribution.js +9 -9
  80. package/lib/browser/menu/open-type-menu.contribution.js.map +1 -1
  81. package/lib/browser/menu/title-context.menu.js.map +1 -1
  82. package/lib/browser/merge-editor/merge-editor.contribution.d.ts +8 -0
  83. package/lib/browser/merge-editor/merge-editor.contribution.d.ts.map +1 -0
  84. package/lib/browser/merge-editor/merge-editor.contribution.js +29 -0
  85. package/lib/browser/merge-editor/merge-editor.contribution.js.map +1 -0
  86. package/lib/browser/merge-editor/merge-editor.provider.d.ts +8 -0
  87. package/lib/browser/merge-editor/merge-editor.provider.d.ts.map +1 -0
  88. package/lib/browser/merge-editor/merge-editor.provider.js +44 -0
  89. package/lib/browser/merge-editor/merge-editor.provider.js.map +1 -0
  90. package/lib/browser/monaco-contrib/callHierarchy/callHierarchy.contribution.js.map +1 -1
  91. package/lib/browser/monaco-contrib/callHierarchy/callHierarchy.service.js +7 -7
  92. package/lib/browser/monaco-contrib/callHierarchy/callHierarchy.service.js.map +1 -1
  93. package/lib/browser/monaco-contrib/command/command.service.d.ts +1 -1
  94. package/lib/browser/monaco-contrib/command/command.service.d.ts.map +1 -1
  95. package/lib/browser/monaco-contrib/command/command.service.js.map +1 -1
  96. package/lib/browser/monaco-contrib/tokenizer/textmate-registry.js.map +1 -1
  97. package/lib/browser/monaco-contrib/tokenizer/textmate.service.d.ts +2 -1
  98. package/lib/browser/monaco-contrib/tokenizer/textmate.service.d.ts.map +1 -1
  99. package/lib/browser/monaco-contrib/tokenizer/textmate.service.js +5 -2
  100. package/lib/browser/monaco-contrib/tokenizer/textmate.service.js.map +1 -1
  101. package/lib/browser/monaco-contrib/typeHierarchy/typeHierarchy.contribution.js.map +1 -1
  102. package/lib/browser/monaco-contrib/typeHierarchy/typeHierarchy.service.js +7 -7
  103. package/lib/browser/monaco-contrib/typeHierarchy/typeHierarchy.service.js.map +1 -1
  104. package/lib/browser/navigation.module.less +1 -1
  105. package/lib/browser/navigation.view.d.ts.map +1 -1
  106. package/lib/browser/navigation.view.js +26 -15
  107. package/lib/browser/navigation.view.js.map +1 -1
  108. package/lib/browser/preference/contribution.js.map +1 -1
  109. package/lib/browser/preference/converter.d.ts +3 -3
  110. package/lib/browser/preference/converter.d.ts.map +1 -1
  111. package/lib/browser/preference/schema.d.ts +1 -1
  112. package/lib/browser/preference/schema.d.ts.map +1 -1
  113. package/lib/browser/preference/schema.js +8 -8
  114. package/lib/browser/preference/schema.js.map +1 -1
  115. package/lib/browser/quick-open/go-to-line.js.map +1 -1
  116. package/lib/browser/quick-open/workspace-symbol-quickopen.d.ts.map +1 -1
  117. package/lib/browser/quick-open/workspace-symbol-quickopen.js +2 -2
  118. package/lib/browser/quick-open/workspace-symbol-quickopen.js.map +1 -1
  119. package/lib/browser/resource.service.js.map +1 -1
  120. package/lib/browser/tab.view.d.ts +1 -1
  121. package/lib/browser/tab.view.d.ts.map +1 -1
  122. package/lib/browser/tab.view.js +2 -2
  123. package/lib/browser/tab.view.js.map +1 -1
  124. package/lib/browser/types.d.ts +5 -5
  125. package/lib/browser/types.d.ts.map +1 -1
  126. package/lib/browser/untitled-resource.js +1 -1
  127. package/lib/browser/untitled-resource.js.map +1 -1
  128. package/lib/browser/view/suggest-widget.js.map +1 -1
  129. package/lib/browser/workbench-editor.service.d.ts +17 -0
  130. package/lib/browser/workbench-editor.service.d.ts.map +1 -1
  131. package/lib/browser/workbench-editor.service.js +259 -176
  132. package/lib/browser/workbench-editor.service.js.map +1 -1
  133. package/lib/common/doc-cache.d.ts +2 -2
  134. package/lib/common/doc-cache.d.ts.map +1 -1
  135. package/lib/common/editor.d.ts +20 -6
  136. package/lib/common/editor.d.ts.map +1 -1
  137. package/lib/common/editor.js +12 -1
  138. package/lib/common/editor.js.map +1 -1
  139. package/lib/common/language.d.ts +18 -7
  140. package/lib/common/language.d.ts.map +1 -1
  141. package/lib/common/language.js +15 -7
  142. package/lib/common/language.js.map +1 -1
  143. package/lib/common/mocks/workbench-editor.service.js.map +1 -1
  144. package/lib/common/resource.d.ts +8 -2
  145. package/lib/common/resource.d.ts.map +1 -1
  146. package/lib/common/resource.js +1 -0
  147. package/lib/common/resource.js.map +1 -1
  148. package/package.json +17 -16
  149. package/src/browser/breadcrumb/default.ts +299 -0
  150. package/src/browser/breadcrumb/document-symbol.ts +187 -0
  151. package/src/browser/breadcrumb/index.ts +96 -0
  152. package/src/browser/component.ts +204 -0
  153. package/src/browser/decoration-applier.ts +256 -0
  154. package/src/browser/diff/compare.ts +99 -0
  155. package/src/browser/diff/index.ts +81 -0
  156. package/src/browser/doc-cache/empty-doc-cache.ts +26 -0
  157. package/src/browser/doc-cache/index.ts +2 -0
  158. package/src/browser/doc-cache/local-storage-cache.ts +67 -0
  159. package/src/browser/doc-model/editor-document-error.ts +10 -0
  160. package/src/browser/doc-model/editor-document-model-service.ts +346 -0
  161. package/src/browser/doc-model/editor-document-model.ts +690 -0
  162. package/src/browser/doc-model/editor-document-registry.ts +119 -0
  163. package/src/browser/doc-model/editor-is-fn.ts +9 -0
  164. package/src/browser/doc-model/main.ts +4 -0
  165. package/src/browser/doc-model/override.ts +49 -0
  166. package/src/browser/doc-model/save-task.ts +88 -0
  167. package/src/browser/doc-model/saveParticipants.ts +227 -0
  168. package/src/browser/doc-model/types.ts +350 -0
  169. package/src/browser/editor-collection.service.ts +790 -0
  170. package/src/browser/editor-opener.ts +44 -0
  171. package/src/browser/editor.contribution.ts +1438 -0
  172. package/src/browser/editor.decoration.service.ts +247 -0
  173. package/src/browser/editor.less +4 -0
  174. package/src/browser/editor.module.less +548 -0
  175. package/src/browser/editor.override.ts +133 -0
  176. package/src/browser/editor.status-bar.service.ts +116 -0
  177. package/src/browser/editor.view.tsx +623 -0
  178. package/src/browser/error.ts +21 -0
  179. package/src/browser/feature.ts +63 -0
  180. package/src/browser/format/format.service.ts +95 -0
  181. package/src/browser/format/formatterSelect.ts +82 -0
  182. package/src/browser/fs-resource/file-tree-set.ts +126 -0
  183. package/src/browser/fs-resource/fs-editor-doc.ts +213 -0
  184. package/src/browser/fs-resource/fs-resource.ts +247 -0
  185. package/src/browser/fs-resource/index.ts +27 -0
  186. package/src/browser/grid/grid.service.ts +288 -0
  187. package/src/browser/history/index.ts +228 -0
  188. package/src/browser/index.ts +236 -0
  189. package/src/browser/language/diagnostic-collection.ts +83 -0
  190. package/src/browser/language/language-status.contribution.ts +81 -0
  191. package/src/browser/language/language-status.service.ts +32 -0
  192. package/src/browser/language/language.service.ts +185 -0
  193. package/src/browser/menu/editor.context.ts +186 -0
  194. package/src/browser/menu/editor.menu.ts +45 -0
  195. package/src/browser/menu/open-type-menu.contribution.ts +90 -0
  196. package/src/browser/menu/title-context.menu.ts +54 -0
  197. package/src/browser/merge-editor/merge-editor.contribution.ts +25 -0
  198. package/src/browser/merge-editor/merge-editor.provider.ts +36 -0
  199. package/src/browser/monaco-contrib/callHierarchy/callHierarchy.contribution.ts +78 -0
  200. package/src/browser/monaco-contrib/callHierarchy/callHierarchy.service.ts +160 -0
  201. package/src/browser/monaco-contrib/command/command.service.ts +438 -0
  202. package/src/browser/monaco-contrib/index.ts +4 -0
  203. package/src/browser/monaco-contrib/tokenizer/textmate-registry.ts +107 -0
  204. package/src/browser/monaco-contrib/tokenizer/textmate-tokenizer.ts +104 -0
  205. package/src/browser/monaco-contrib/tokenizer/textmate.service.ts +925 -0
  206. package/src/browser/monaco-contrib/typeHierarchy/typeHierarchy.contribution.ts +78 -0
  207. package/src/browser/monaco-contrib/typeHierarchy/typeHierarchy.service.ts +154 -0
  208. package/src/browser/navigation.module.less +96 -0
  209. package/src/browser/navigation.view.tsx +254 -0
  210. package/src/browser/preference/contribution.ts +8 -0
  211. package/src/browser/preference/converter.ts +793 -0
  212. package/src/browser/preference/schema.ts +1896 -0
  213. package/src/browser/preference/util.ts +14 -0
  214. package/src/browser/quick-open/go-to-line.ts +164 -0
  215. package/src/browser/quick-open/workspace-symbol-quickopen.ts +276 -0
  216. package/src/browser/resource.service.ts +263 -0
  217. package/src/browser/tab.view.tsx +514 -0
  218. package/src/browser/types.ts +467 -0
  219. package/src/browser/untitled-resource.ts +223 -0
  220. package/src/browser/view/editor.react.tsx +82 -0
  221. package/src/browser/view/react-hook.tsx +7 -0
  222. package/src/browser/view/suggest-widget.ts +77 -0
  223. package/src/browser/view/topPadding.ts +18 -0
  224. package/src/browser/workbench-editor.service.ts +2291 -0
  225. package/src/common/doc-cache.ts +117 -0
  226. package/src/common/editor.ts +799 -0
  227. package/src/common/index.ts +6 -0
  228. package/src/common/language-status.ts +33 -0
  229. package/src/common/language.ts +206 -0
  230. package/src/common/mocks/workbench-editor.service.ts +52 -0
  231. package/src/common/resource.ts +147 -0
  232. package/src/common/utils.ts +10 -0
  233. package/src/index.ts +1 -0
  234. package/lib/browser/component/scroll/scroll.d.ts +0 -2
  235. package/lib/browser/component/scroll/scroll.d.ts.map +0 -1
  236. package/lib/browser/component/scroll/scroll.js +0 -5
  237. package/lib/browser/component/scroll/scroll.js.map +0 -1
  238. package/lib/browser/component/scroll/scroll.module.less +0 -86
@@ -0,0 +1,623 @@
1
+ import classnames from 'classnames';
2
+ import { observer } from 'mobx-react-lite';
3
+ import React from 'react';
4
+ import ReactDOM from 'react-dom';
5
+ import ReactIs from 'react-is';
6
+
7
+ import { Scrollbars } from '@opensumi/ide-components';
8
+ import {
9
+ AppConfig,
10
+ ComponentRegistry,
11
+ ConfigContext,
12
+ ConfigProvider,
13
+ ErrorBoundary,
14
+ IEventBus,
15
+ MaybeNull,
16
+ PreferenceService,
17
+ URI,
18
+ useDisposable,
19
+ View,
20
+ } from '@opensumi/ide-core-browser';
21
+ import {
22
+ IResizeHandleDelegate,
23
+ ResizeFlexMode,
24
+ ResizeHandleHorizontal,
25
+ ResizeHandleVertical,
26
+ } from '@opensumi/ide-core-browser/lib/components';
27
+ import { VIEW_CONTAINERS } from '@opensumi/ide-core-browser/lib/layout/view-id';
28
+ import { useInjectable } from '@opensumi/ide-core-browser/lib/react-hooks';
29
+
30
+ import { IResource, WorkbenchEditorService } from '../common';
31
+
32
+ import { EditorComponentRegistryImpl } from './component';
33
+ import styles from './editor.module.less';
34
+ import { EditorGrid, SplitDirection } from './grid/grid.service';
35
+ import { NavigationBar } from './navigation.view';
36
+ import { Tabs } from './tab.view';
37
+ import {
38
+ DragOverPosition,
39
+ EditorComponentRegistry,
40
+ EditorComponentRenderMode,
41
+ EditorGroupFileDropEvent,
42
+ EditorGroupsResetSizeEvent,
43
+ RegisterEditorSideComponentEvent,
44
+ EditorSide,
45
+ IEditorComponent,
46
+ CodeEditorDidVisibleEvent,
47
+ EditorOpenType,
48
+ } from './types';
49
+ import { EditorGroup, WorkbenchEditorServiceImpl } from './workbench-editor.service';
50
+
51
+ export const EditorView = () => {
52
+ const ref = React.useRef<HTMLElement | null>();
53
+
54
+ const workbenchEditorService = useInjectable(WorkbenchEditorService) as WorkbenchEditorServiceImpl;
55
+ const componentRegistry = useInjectable<ComponentRegistry>(ComponentRegistry);
56
+ const rightWidgetInfo = componentRegistry.getComponentRegistryInfo('editor-widget-right');
57
+ const RightWidget: React.ComponentType<any> | undefined = rightWidgetInfo && rightWidgetInfo.views[0].component;
58
+ const [ready, setReady] = React.useState<boolean>(workbenchEditorService.gridReady);
59
+
60
+ React.useEffect(() => {
61
+ if (!ready) {
62
+ if (workbenchEditorService.gridReady) {
63
+ setReady(true);
64
+ } else {
65
+ const disposer = workbenchEditorService.onDidGridReady(() => {
66
+ setReady(true);
67
+ });
68
+ return () => disposer.dispose();
69
+ }
70
+ }
71
+ }, []);
72
+
73
+ if (!ready) {
74
+ return null;
75
+ }
76
+
77
+ return (
78
+ <div
79
+ className={styles.kt_workbench_editor}
80
+ id='workbench-editor'
81
+ ref={(ele) => {
82
+ ref.current = ele;
83
+ if (ele) {
84
+ workbenchEditorService.onDomCreated(ele);
85
+ }
86
+ }}
87
+ >
88
+ <div className={styles.kt_editor_main_wrapper}>
89
+ <EditorGridView grid={workbenchEditorService.topGrid}></EditorGridView>
90
+ </div>
91
+ {RightWidget ? (
92
+ <div className={styles.kt_editor_right_widget}>
93
+ <ErrorBoundary>
94
+ <RightWidget></RightWidget>
95
+ </ErrorBoundary>
96
+ </div>
97
+ ) : null}
98
+ </div>
99
+ );
100
+ };
101
+
102
+ const cachedGroupView = {};
103
+
104
+ export const EditorGridView = ({ grid }: { grid: EditorGrid }) => {
105
+ let editorGroupContainer: HTMLDivElement;
106
+ const context = React.useContext(ConfigContext);
107
+
108
+ const eventBus = useInjectable(IEventBus) as IEventBus;
109
+ const resizeDelegates: IResizeHandleDelegate[] = [];
110
+ const [, updateState] = React.useState<any>();
111
+ const forceUpdate = React.useCallback(() => updateState({}), []);
112
+
113
+ React.useEffect(() => {
114
+ if (editorGroupContainer) {
115
+ if (cachedGroupView[grid.editorGroup!.name]) {
116
+ editorGroupContainer.appendChild(cachedGroupView[grid.editorGroup!.name]);
117
+ (grid.editorGroup! as EditorGroup).layoutEditors();
118
+ } else {
119
+ const div = document.createElement('div');
120
+ cachedGroupView[grid.editorGroup!.name] = div;
121
+ div.style.height = '100%';
122
+ editorGroupContainer.appendChild(div);
123
+ ReactDOM.render(
124
+ <ConfigProvider value={context}>
125
+ <EditorGroupView group={grid.editorGroup! as EditorGroup} />
126
+ </ConfigProvider>,
127
+ div,
128
+ );
129
+ }
130
+ }
131
+ });
132
+
133
+ useDisposable(
134
+ () => [
135
+ eventBus.on(EditorGroupsResetSizeEvent, () => {
136
+ if (grid.splitDirection && resizeDelegates.length > 0) {
137
+ resizeDelegates.forEach((delegate) => {
138
+ delegate.setSize(1 / grid.children.length, 1 / grid.children.length);
139
+ });
140
+ }
141
+ }),
142
+ grid.onDidGridStateChange(() => {
143
+ forceUpdate();
144
+ }),
145
+ ],
146
+ [],
147
+ );
148
+
149
+ if (grid.children.length === 0 && grid.editorGroup) {
150
+ return <div style={{ height: '100%' }} ref={(el) => el && (editorGroupContainer = el)} />;
151
+ }
152
+
153
+ const defaultChildStyle =
154
+ grid.splitDirection === SplitDirection.Horizontal
155
+ ? { width: 100 / grid.children.length + '%' }
156
+ : { height: 100 / grid.children.length + '%' };
157
+ const children: any[] = [];
158
+ grid.children.forEach((g, index) => {
159
+ if (index !== 0) {
160
+ if (grid.splitDirection === SplitDirection.Vertical) {
161
+ children.push(
162
+ <ResizeHandleVertical
163
+ key={'resize-' + grid.children[index - 1].uid + '-' + g.uid}
164
+ onResize={() => {
165
+ grid.children[index - 1].emitResizeWithEventBus(eventBus);
166
+ g.emitResizeWithEventBus(eventBus);
167
+ }}
168
+ delegate={(delegate) => {
169
+ resizeDelegates.push(delegate);
170
+ }}
171
+ flexMode={ResizeFlexMode.Percentage}
172
+ />,
173
+ );
174
+ } else {
175
+ children.push(
176
+ <ResizeHandleHorizontal
177
+ key={'resize-' + grid.children[index - 1].uid + '-' + g.uid}
178
+ onResize={() => {
179
+ grid.children[index - 1].emitResizeWithEventBus(eventBus);
180
+ g.emitResizeWithEventBus(eventBus);
181
+ }}
182
+ delegate={(delegate) => {
183
+ resizeDelegates.push(delegate);
184
+ }}
185
+ />,
186
+ );
187
+ }
188
+ }
189
+ children.push(
190
+ <div
191
+ className={classnames({
192
+ [styles.kt_grid_vertical_child]: grid.splitDirection === SplitDirection.Vertical,
193
+ [styles.kt_grid_horizontal_child]: grid.splitDirection === SplitDirection.Horizontal,
194
+ })}
195
+ style={defaultChildStyle}
196
+ key={g.uid}
197
+ data-min-resize={grid.splitDirection === SplitDirection.Horizontal ? 150 : 60}
198
+ >
199
+ <EditorGridView grid={g} />
200
+ </div>,
201
+ );
202
+ });
203
+
204
+ return (
205
+ <div
206
+ className={classnames({
207
+ [styles.kt_grid_vertical]: grid.splitDirection === SplitDirection.Vertical,
208
+ [styles.kt_grid_horizontal]: grid.splitDirection === SplitDirection.Horizontal,
209
+ })}
210
+ >
211
+ {children}
212
+ </div>
213
+ );
214
+ };
215
+
216
+ const cachedEditor: { [key: string]: HTMLDivElement } = {};
217
+
218
+ /**
219
+ * 默认的 editor empty component
220
+ * 接受外部的 editorBackgroundImage 作为图片展示
221
+ */
222
+ const EditorEmptyComponent: React.FC<{
223
+ editorBackgroundImage: string;
224
+ }> = ({ editorBackgroundImage }) => {
225
+ if (!editorBackgroundImage) {
226
+ return null;
227
+ }
228
+
229
+ return (
230
+ <div className={styles.editorEmpty}>
231
+ <img className={styles.editorEmptyImg} src={editorBackgroundImage} />
232
+ </div>
233
+ );
234
+ };
235
+
236
+ export const EditorGroupView = observer(({ group }: { group: EditorGroup }) => {
237
+ const groupWrapperRef = React.useRef<HTMLElement | null>();
238
+
239
+ const preferenceService = useInjectable(PreferenceService) as PreferenceService;
240
+ const [isEmpty, setIsEmpty] = React.useState(group.resources.length === 0);
241
+
242
+ const appConfig = useInjectable(AppConfig);
243
+ const { editorBackgroundImage } = appConfig;
244
+
245
+ React.useEffect(() => {
246
+ group.attachToDom(groupWrapperRef.current);
247
+ });
248
+
249
+ React.useEffect(() => {
250
+ // 由于当前可能已经发生改变,因此需要再检查一次
251
+ setIsEmpty(group.resources.length === 0);
252
+ const disposer = group.onDidEditorGroupTabChanged(() => {
253
+ setIsEmpty(group.resources.length === 0);
254
+ });
255
+ return () => {
256
+ disposer.dispose();
257
+ };
258
+ }, []);
259
+
260
+ const [showActionWhenGroupEmpty, setShowActionWhenGroupEmpty] = React.useState(
261
+ () => !!preferenceService.get<boolean>('editor.showActionWhenGroupEmpty'),
262
+ );
263
+
264
+ useDisposable(
265
+ () => [
266
+ preferenceService.onPreferenceChanged((change) => {
267
+ if (change.preferenceName === 'editor.showActionWhenGroupEmpty') {
268
+ setShowActionWhenGroupEmpty(!!change.newValue);
269
+ }
270
+ }),
271
+ ],
272
+ [],
273
+ );
274
+
275
+ const componentRegistry = useInjectable<ComponentRegistry>(ComponentRegistry);
276
+
277
+ // TODO: 将图片转换成默认的 editor component
278
+ const EmptyEditorViewConfig = React.useMemo(() => {
279
+ const emptyComponentInfo = componentRegistry.getComponentRegistryInfo('editor-empty');
280
+ return (
281
+ (emptyComponentInfo && emptyComponentInfo.views[0]) ||
282
+ ({
283
+ component: EditorEmptyComponent,
284
+ initialProps: { editorBackgroundImage },
285
+ } as View)
286
+ );
287
+ }, []);
288
+
289
+ return (
290
+ <div
291
+ ref={groupWrapperRef as any}
292
+ className={styles.kt_editor_group}
293
+ tabIndex={1}
294
+ onFocus={(e) => {
295
+ group.gainFocus();
296
+ }}
297
+ >
298
+ {(!isEmpty || showActionWhenGroupEmpty) && (
299
+ <div className={styles.editorGroupHeader}>
300
+ <Tabs group={group} />
301
+ </div>
302
+ )}
303
+ <EditorGroupBody group={group} />
304
+ {isEmpty && (
305
+ <div
306
+ className={styles.kt_editor_background}
307
+ style={{
308
+ backgroundImage: !EmptyEditorViewConfig && editorBackgroundImage ? `url(${editorBackgroundImage})` : 'none',
309
+ }}
310
+ >
311
+ {EmptyEditorViewConfig && ReactIs.isValidElementType(EmptyEditorViewConfig.component) ? (
312
+ <ErrorBoundary>
313
+ {React.createElement(EmptyEditorViewConfig.component, EmptyEditorViewConfig.initialProps)}
314
+ </ErrorBoundary>
315
+ ) : null}
316
+ </div>
317
+ )}
318
+ </div>
319
+ );
320
+ });
321
+
322
+ export const EditorGroupBody = observer(({ group }: { group: EditorGroup }) => {
323
+ const editorBodyRef = React.useRef<HTMLDivElement>(null);
324
+ const editorService = useInjectable(WorkbenchEditorService) as WorkbenchEditorServiceImpl;
325
+ const eventBus = useInjectable(IEventBus) as IEventBus;
326
+ const components: React.ReactNode[] = [];
327
+ const codeEditorRef = React.useRef<HTMLDivElement>(null);
328
+ const diffEditorRef = React.useRef<HTMLDivElement>(null);
329
+ const mergeEditorRef = React.useRef<HTMLDivElement>(null);
330
+ const [, updateState] = React.useState<any>();
331
+ const forceUpdate = React.useCallback(() => updateState({}), []);
332
+
333
+ React.useEffect(() => {
334
+ if (codeEditorRef.current) {
335
+ if (cachedEditor[group.name]) {
336
+ cachedEditor[group.name].remove();
337
+ codeEditorRef.current.appendChild(cachedEditor[group.name]);
338
+ } else {
339
+ const container = document.createElement('div');
340
+ codeEditorRef.current.appendChild(container);
341
+ cachedEditor[group.name] = container;
342
+ group.createEditor(container);
343
+ }
344
+ }
345
+
346
+ if (diffEditorRef.current) {
347
+ group.attachDiffEditorDom(diffEditorRef.current);
348
+ }
349
+ if (mergeEditorRef.current) {
350
+ group.attachMergeEditorDom(mergeEditorRef.current);
351
+ }
352
+ }, [codeEditorRef.current, diffEditorRef.current, mergeEditorRef.current]);
353
+
354
+ useDisposable(
355
+ () =>
356
+ group.onDidEditorGroupBodyChanged(() => {
357
+ forceUpdate();
358
+ }),
359
+ [],
360
+ );
361
+
362
+ group.activeComponents.forEach((resources, component) => {
363
+ const initialProps = group.activateComponentsProps.get(component);
364
+ components.push(
365
+ <div
366
+ key={component.uid}
367
+ className={classnames({
368
+ [styles.kt_hidden]: !(group.currentOpenType && group.currentOpenType.componentId === component.uid),
369
+ })}
370
+ >
371
+ <ComponentsWrapper
372
+ key={component.uid}
373
+ component={component}
374
+ {...initialProps}
375
+ resources={resources}
376
+ current={group.currentResource}
377
+ ></ComponentsWrapper>
378
+ </div>,
379
+ );
380
+ });
381
+
382
+ const editorHasNoTab = React.useMemo(
383
+ () => group.resources.length === 0 || !group.currentResource,
384
+ [group.resources.length, group.currentResource],
385
+ );
386
+
387
+ React.useEffect(() => {
388
+ if (group.currentOpenType?.type === EditorOpenType.code) {
389
+ eventBus.fire(
390
+ new CodeEditorDidVisibleEvent({
391
+ groupName: group.name,
392
+ type: EditorOpenType.code,
393
+ editorId: group.codeEditor.getId(),
394
+ }),
395
+ );
396
+ } else if (group.currentOpenType?.type === EditorOpenType.diff) {
397
+ eventBus.fire(
398
+ new CodeEditorDidVisibleEvent({
399
+ groupName: group.name,
400
+ type: EditorOpenType.diff,
401
+ editorId: group.diffEditor.modifiedEditor.getId(),
402
+ }),
403
+ );
404
+ }
405
+ });
406
+
407
+ return (
408
+ <div
409
+ id={VIEW_CONTAINERS.EDITOR}
410
+ ref={editorBodyRef}
411
+ className={styles.kt_editor_body}
412
+ onDragOver={(e) => {
413
+ e.preventDefault();
414
+ if (editorBodyRef.current) {
415
+ const position = getDragOverPosition(e.nativeEvent, editorBodyRef.current);
416
+ decorateDragOverElement(editorBodyRef.current, position);
417
+ }
418
+ }}
419
+ onDragLeave={(e) => {
420
+ if (editorBodyRef.current) {
421
+ removeDecorationDragOverElement(editorBodyRef.current);
422
+ }
423
+ }}
424
+ onDrop={(e) => {
425
+ if (editorBodyRef.current) {
426
+ removeDecorationDragOverElement(editorBodyRef.current);
427
+ if (e.dataTransfer.getData('uri')) {
428
+ const uri = new URI(e.dataTransfer.getData('uri'));
429
+ let sourceGroup: EditorGroup | undefined;
430
+ if (e.dataTransfer.getData('uri-source-group')) {
431
+ sourceGroup = editorService.getEditorGroup(e.dataTransfer.getData('uri-source-group'));
432
+ }
433
+ group.dropUri(uri, getDragOverPosition(e.nativeEvent, editorBodyRef.current), sourceGroup);
434
+ }
435
+ if (e.dataTransfer.files.length > 0) {
436
+ eventBus.fire(
437
+ new EditorGroupFileDropEvent({
438
+ group,
439
+ files: e.dataTransfer.files,
440
+ position: getDragOverPosition(e.nativeEvent, editorBodyRef.current),
441
+ }),
442
+ );
443
+ }
444
+ }
445
+ }}
446
+ >
447
+ {!editorHasNoTab && <NavigationBar editorGroup={group} />}
448
+ <div className={styles.kt_editor_components}>
449
+ <div
450
+ className={classnames({
451
+ [styles.kt_editor_component]: true,
452
+ [styles.kt_hidden]: !group.currentOpenType || group.currentOpenType.type !== EditorOpenType.component,
453
+ })}
454
+ >
455
+ {components}
456
+ </div>
457
+ <div
458
+ className={classnames({
459
+ [styles.kt_editor_code_editor]: true,
460
+ [styles.kt_editor_component]: true,
461
+ [styles.kt_hidden]: !group.currentOpenType || group.currentOpenType.type !== EditorOpenType.code,
462
+ })}
463
+ ref={codeEditorRef}
464
+ />
465
+ <div
466
+ className={classnames(styles.kt_editor_diff_editor, styles.kt_editor_component, {
467
+ [styles.kt_hidden]: !group.currentOpenType || group.currentOpenType.type !== EditorOpenType.diff,
468
+ })}
469
+ ref={diffEditorRef}
470
+ />
471
+ <div
472
+ className={classnames(styles.kt_editor_diff_3_editor, styles.kt_editor_component, {
473
+ [styles.kt_hidden]: !group.currentOpenType || group.currentOpenType.type !== EditorOpenType.mergeEditor,
474
+ })}
475
+ ref={mergeEditorRef}
476
+ />
477
+ </div>
478
+ {group.currentResource && <EditorSideView side={'bottom'} resource={group.currentResource}></EditorSideView>}
479
+ </div>
480
+ );
481
+ });
482
+
483
+ export const ComponentsWrapper = ({
484
+ component,
485
+ resources,
486
+ current,
487
+ ...other
488
+ }: {
489
+ component: IEditorComponent;
490
+ resources: IResource[];
491
+ current: MaybeNull<IResource>;
492
+ }) => (
493
+ <div className={styles.kt_editor_component_wrapper}>
494
+ {resources.map((resource) => (
495
+ <ComponentWrapper
496
+ {...other}
497
+ key={resource.toString()}
498
+ component={component}
499
+ resource={resource}
500
+ hidden={!(current && current.uri.toString() === resource.uri.toString())}
501
+ />
502
+ ))}
503
+ </div>
504
+ );
505
+
506
+ export const ComponentWrapper = ({ component, resource, hidden, ...other }) => {
507
+ const componentService: EditorComponentRegistryImpl = useInjectable(EditorComponentRegistry);
508
+ let containerRef: HTMLDivElement | null = null;
509
+ let componentNode;
510
+ if (component.renderMode !== EditorComponentRenderMode.ONE_PER_WORKBENCH) {
511
+ componentNode = <component.component resource={resource} {...other} />;
512
+ }
513
+ const context = React.useContext(ConfigContext);
514
+
515
+ React.useEffect(() => {
516
+ if (component.renderMode === EditorComponentRenderMode.ONE_PER_WORKBENCH) {
517
+ if (!componentService.perWorkbenchComponents[component.uid]) {
518
+ const div = document.createElement('div');
519
+ div.style.height = '100%';
520
+ componentService.perWorkbenchComponents[component.uid] = div;
521
+ // 对于per_workbench的,resource默认为不会改变
522
+ ReactDOM.render(
523
+ <ConfigProvider value={context}>
524
+ <component.component resource={resource} />
525
+ </ConfigProvider>,
526
+ div,
527
+ );
528
+ }
529
+ containerRef!.appendChild(componentService.perWorkbenchComponents[component.uid]);
530
+ }
531
+ });
532
+
533
+ return (
534
+ <div
535
+ key={resource.uri.toString()}
536
+ className={classnames({
537
+ [styles.kt_hidden]: hidden,
538
+ })}
539
+ >
540
+ <Scrollbars>
541
+ <ErrorBoundary>
542
+ <div
543
+ ref={(el) => {
544
+ containerRef = el;
545
+ }}
546
+ style={{ height: '100%' }}
547
+ >
548
+ {componentNode}
549
+ </div>
550
+ </ErrorBoundary>
551
+ </Scrollbars>
552
+ </div>
553
+ );
554
+ };
555
+
556
+ function getDragOverPosition(e: DragEvent, element: HTMLElement): DragOverPosition {
557
+ const rect = element.getBoundingClientRect();
558
+ const x = e.clientX - rect.left;
559
+ const y = e.clientY - rect.top;
560
+ const width = element.offsetWidth;
561
+ const height = element.offsetHeight;
562
+ if (x < width * 0.15) {
563
+ return DragOverPosition.LEFT;
564
+ }
565
+ if (x > width * 0.85) {
566
+ return DragOverPosition.RIGHT;
567
+ }
568
+ if (y < height * 0.15) {
569
+ return DragOverPosition.TOP;
570
+ }
571
+ if (y > height * 0.85) {
572
+ return DragOverPosition.BOTTOM;
573
+ }
574
+ return DragOverPosition.CENTER;
575
+ }
576
+
577
+ function addClass(element: HTMLElement, className: string) {
578
+ if (!element.classList.contains(className)) {
579
+ element.classList.add(className);
580
+ }
581
+ }
582
+
583
+ function removeClass(element: HTMLElement, className: string) {
584
+ if (element.classList.contains(className)) {
585
+ element.classList.remove(className);
586
+ }
587
+ }
588
+
589
+ function decorateDragOverElement(element: HTMLElement, position: DragOverPosition) {
590
+ addClass(element, styles.kt_on_drag_over);
591
+ [DragOverPosition.LEFT, DragOverPosition.RIGHT, DragOverPosition.TOP, DragOverPosition.BOTTOM]
592
+ .filter((pos) => pos !== position)
593
+ .forEach((pos) => {
594
+ removeClass(element, styles['kt_on_drag_over_' + pos]);
595
+ });
596
+ addClass(element, styles['kt_on_drag_over_' + position]);
597
+ }
598
+
599
+ function removeDecorationDragOverElement(element: HTMLElement) {
600
+ removeClass(element, styles.kt_on_drag_over);
601
+ [DragOverPosition.LEFT, DragOverPosition.RIGHT, DragOverPosition.TOP, DragOverPosition.BOTTOM].forEach((pos) => {
602
+ removeClass(element, styles['kt_on_drag_over_' + pos]);
603
+ });
604
+ }
605
+
606
+ const EditorSideView = ({ side, resource }: { side: EditorSide; resource: IResource }) => {
607
+ const componentRegistry: EditorComponentRegistry = useInjectable(EditorComponentRegistry);
608
+ const eventBus = useInjectable(IEventBus) as IEventBus;
609
+ const widgets = componentRegistry.getSideWidgets(side, resource);
610
+ const [, updateState] = React.useState<any>();
611
+ const forceUpdate = React.useCallback(() => updateState({}), []);
612
+
613
+ useDisposable(() => eventBus.on(RegisterEditorSideComponentEvent, forceUpdate), []);
614
+
615
+ return (
616
+ <div className={classnames(styles['kt_editor_side_widgets'], styles['kt_editor_side_widgets_' + side])}>
617
+ {widgets.map((widget) => {
618
+ const C = widget.component;
619
+ return <C resource={resource} key={widget.id} {...(widget.initialProps || {})}></C>;
620
+ })}
621
+ </div>
622
+ );
623
+ };
@@ -0,0 +1,21 @@
1
+ import { ConstructorOf } from '@opensumi/ide-core-common';
2
+
3
+ export class EditorError extends Error {
4
+ type: number;
5
+ }
6
+
7
+ export class EditorTabChangedError extends EditorError {
8
+ static errorCode = 1001;
9
+
10
+ type: number = EditorTabChangedError.errorCode;
11
+
12
+ constructor() {
13
+ super('editor current tab changed when opening resource');
14
+ }
15
+ }
16
+
17
+ export type EditorErrorType = ConstructorOf<EditorError> & { errorCode: number };
18
+
19
+ export function isEditorError(e: any, type: EditorErrorType) {
20
+ return e && (e as EditorError).type === type.errorCode;
21
+ }
@@ -0,0 +1,63 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import { IDisposable, arrays, ILogger, Emitter, Event, URI } from '@opensumi/ide-core-browser';
3
+
4
+ import { IEditor } from '../common';
5
+
6
+ import { IEditorFeatureRegistry, IEditorFeatureContribution } from './types';
7
+
8
+ const { addElement } = arrays;
9
+
10
+ @Injectable()
11
+ export class EditorFeatureRegistryImpl implements IEditorFeatureRegistry {
12
+ private contributions: IEditorFeatureContribution[] = [];
13
+
14
+ private _onDidRegisterFeature = new Emitter<IEditorFeatureContribution>();
15
+
16
+ public readonly onDidRegisterFeature: Event<IEditorFeatureContribution> = this._onDidRegisterFeature.event;
17
+
18
+ @Autowired(ILogger)
19
+ logger: ILogger;
20
+
21
+ registerEditorFeatureContribution(contribution: IEditorFeatureContribution): IDisposable {
22
+ const disposer = addElement(this.contributions, contribution);
23
+ this._onDidRegisterFeature.fire(contribution);
24
+ return disposer;
25
+ }
26
+
27
+ runContributions(editor: IEditor) {
28
+ this.contributions.forEach((contribution) => {
29
+ this.runOneContribution(editor, contribution);
30
+ });
31
+ }
32
+
33
+ async runProvideEditorOptionsForUri(uri: URI) {
34
+ const result = await Promise.all(
35
+ this.contributions.map((contribution) => {
36
+ if (contribution.provideEditorOptionsForUri) {
37
+ return contribution.provideEditorOptionsForUri(uri);
38
+ } else {
39
+ return {};
40
+ }
41
+ }),
42
+ );
43
+
44
+ return result.reduce(
45
+ (pre, current) => ({
46
+ ...pre,
47
+ ...current,
48
+ }),
49
+ {},
50
+ );
51
+ }
52
+
53
+ runOneContribution(editor: IEditor, contribution: IEditorFeatureContribution) {
54
+ try {
55
+ const disposer = contribution.contribute(editor);
56
+ editor.onDispose(() => {
57
+ disposer.dispose();
58
+ });
59
+ } catch (e) {
60
+ this.logger.error(e);
61
+ }
62
+ }
63
+ }