@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,96 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import { IDisposable, URI, arrays, MaybeNull, Emitter } from '@opensumi/ide-core-browser';
3
+
4
+ import { IEditor } from '../../common';
5
+ import { IBreadCrumbService, IBreadCrumbPart, IBreadCrumbProvider } from '../types';
6
+
7
+ import { DefaultBreadCrumbProvider } from './default';
8
+
9
+ const { addElement } = arrays;
10
+
11
+ @Injectable()
12
+ export class BreadCrumbServiceImpl implements IBreadCrumbService {
13
+ private providers: IBreadCrumbProvider[] = [];
14
+
15
+ private _onDidUpdateBreadCrumbResults = new Emitter<{ uri: URI; editor: MaybeNull<IEditor> }>();
16
+ public readonly onDidUpdateBreadCrumbResults = this._onDidUpdateBreadCrumbResults.event;
17
+
18
+ // editor-id / uriString
19
+ private crumbResults: Map<MaybeNull<IEditor>, Map<string, IBreadCrumbPart[]>> = new Map();
20
+
21
+ @Autowired()
22
+ defaultBreadCrumbProvider: DefaultBreadCrumbProvider;
23
+
24
+ constructor() {
25
+ this.registerBreadCrumbProvider(this.defaultBreadCrumbProvider);
26
+ }
27
+
28
+ registerBreadCrumbProvider(provider: IBreadCrumbProvider): IDisposable {
29
+ const disposer = addElement(this.providers, provider);
30
+
31
+ provider.onDidUpdateBreadCrumb((uri: URI) => {
32
+ this.crumbResults.forEach((crumbResults, editor) => {
33
+ if (crumbResults.has(uri.toString())) {
34
+ this.getBreadCrumbs(uri, editor);
35
+ }
36
+ });
37
+ });
38
+
39
+ return disposer;
40
+ }
41
+
42
+ getBreadCrumbs(uri: URI, editor: MaybeNull<IEditor>): IBreadCrumbPart[] | undefined {
43
+ const editorCrumbResults = this.getEditorCrumbResults(editor);
44
+ for (const provider of this.providers) {
45
+ if (provider.handlesUri(uri)) {
46
+ const lastCrumb = editorCrumbResults.get(uri.toString());
47
+ const newCrumb = provider.provideBreadCrumbForUri(uri, editor);
48
+ if (!isBreadCrumbArrayEqual(lastCrumb, newCrumb)) {
49
+ editorCrumbResults.set(uri.toString(), newCrumb);
50
+ this._onDidUpdateBreadCrumbResults.fire({ editor, uri });
51
+ }
52
+ break;
53
+ }
54
+ }
55
+ return editorCrumbResults.get(uri.toString());
56
+ }
57
+
58
+ getEditorCrumbResults(editor: MaybeNull<IEditor>): Map<string, IBreadCrumbPart[]> {
59
+ if (!this.crumbResults.has(editor)) {
60
+ this.crumbResults.set(editor, new Map());
61
+ if (editor) {
62
+ // todo IEditor 应该也暴露 onDispose
63
+ editor.monacoEditor.onDidDispose(() => {
64
+ this.crumbResults.delete(editor);
65
+ });
66
+ }
67
+ }
68
+ return this.crumbResults.get(editor)!;
69
+ }
70
+
71
+ disposeCrumb(uri: URI) {
72
+ // this.crumbResults.delete(uri.toString());
73
+ }
74
+ }
75
+
76
+ function isBreadCrumbArrayEqual(p1: IBreadCrumbPart[] | undefined, p2: IBreadCrumbPart[] | undefined): boolean {
77
+ if (!p1 && !p2) {
78
+ return true;
79
+ } else if (!p1 || !p2) {
80
+ return false;
81
+ } else {
82
+ if (p1.length !== p2.length) {
83
+ return false;
84
+ }
85
+ for (let i = 0; i < p1.length; i++) {
86
+ if (!isBreadCrumbEqual(p1[i], p2[i])) {
87
+ return false;
88
+ }
89
+ }
90
+ return true;
91
+ }
92
+ }
93
+
94
+ function isBreadCrumbEqual(p1: IBreadCrumbPart, p2: IBreadCrumbPart): boolean {
95
+ return p1.name === p2.name;
96
+ }
@@ -0,0 +1,204 @@
1
+ import isEqual from 'lodash/isEqual';
2
+ import uniqWith from 'lodash/uniqWith';
3
+ import ReactDOM from 'react-dom';
4
+
5
+ import { Injectable, Autowired } from '@opensumi/di';
6
+ import { ExtensionActivateEvent, IDisposable, IEventBus } from '@opensumi/ide-core-common';
7
+
8
+ import { IResource, IEditorOpenType } from '../common';
9
+
10
+ import {
11
+ EditorComponentRegistry,
12
+ IEditorComponent,
13
+ IEditorComponentResolver,
14
+ EditorComponentRenderMode,
15
+ IEditorSideWidget,
16
+ EditorSide,
17
+ EditorComponentDisposeEvent,
18
+ RegisterEditorComponentEvent,
19
+ RegisterEditorSideComponentEvent,
20
+ } from './types';
21
+
22
+ type SchemeKey = string;
23
+
24
+ interface INormalizedEditorComponentResolver {
25
+ handleScheme: (scheme: string) => number;
26
+ resolver: IEditorComponentResolver;
27
+ }
28
+
29
+ @Injectable()
30
+ export class EditorComponentRegistryImpl implements EditorComponentRegistry {
31
+ @Autowired(IEventBus)
32
+ eventBus: IEventBus;
33
+
34
+ private components: Map<string, IEditorComponent> = new Map();
35
+
36
+ private sideWidgets = {
37
+ bottom: new Set<IEditorSideWidget>(),
38
+ };
39
+
40
+ private initialPropsMap: Map<string, any> = new Map();
41
+
42
+ private resolvers: Map<SchemeKey, IEditorComponentResolver[]> = new Map();
43
+
44
+ private normalizedResolvers: INormalizedEditorComponentResolver[] = [];
45
+
46
+ public readonly perWorkbenchComponents = {};
47
+
48
+ public registerEditorComponent<T>(component: IEditorComponent<T>, initialProps?: any): IDisposable {
49
+ const uid = component.uid;
50
+ if (!component.renderMode) {
51
+ component.renderMode = EditorComponentRenderMode.ONE_PER_GROUP;
52
+ }
53
+ this.components.set(uid, component);
54
+ this.initialPropsMap.set(uid, initialProps);
55
+ // 使用 activationEvent 通知插件
56
+ this.eventBus.fire(new ExtensionActivateEvent({ topic: 'onRegisterEditorComponent', data: uid }));
57
+ this.eventBus.fire(new RegisterEditorComponentEvent(uid));
58
+ return {
59
+ dispose: () => {
60
+ if (this.components.get(uid) === component) {
61
+ this.components.delete(uid);
62
+ this.eventBus.fire(new EditorComponentDisposeEvent(component));
63
+ }
64
+ },
65
+ };
66
+ }
67
+
68
+ public registerEditorComponentResolver<T>(
69
+ scheme: string | ((scheme: string) => number),
70
+ resolver: IEditorComponentResolver<any>,
71
+ ): IDisposable {
72
+ let normalizedResolver: INormalizedEditorComponentResolver;
73
+ if (typeof scheme === 'function') {
74
+ normalizedResolver = {
75
+ handleScheme: scheme,
76
+ resolver,
77
+ };
78
+ } else {
79
+ normalizedResolver = {
80
+ handleScheme: (s: string) => (s === scheme ? 10 : -1),
81
+ resolver,
82
+ };
83
+ }
84
+ this.normalizedResolvers.push(normalizedResolver);
85
+
86
+ // 注册了新的,清除缓存
87
+ this.resolvers.clear();
88
+ return {
89
+ dispose: () => {
90
+ // 去除已被 cache 的resolver
91
+ for (const resolvers of this.resolvers.values()) {
92
+ const index = resolvers.indexOf(resolver);
93
+ if (index !== -1) {
94
+ resolvers.splice(index, 1);
95
+ }
96
+ }
97
+
98
+ const i = this.normalizedResolvers.indexOf(normalizedResolver);
99
+ if (i !== -1) {
100
+ this.normalizedResolvers.splice(i, 1);
101
+ }
102
+ },
103
+ };
104
+ }
105
+
106
+ public async resolveEditorComponent(resource: IResource): Promise<IEditorOpenType[]> {
107
+ let results: IEditorOpenType[] = [];
108
+ const resolvers = this.getResolvers(resource.uri.scheme).slice(); // 防止异步操作时数组被改变
109
+ let shouldBreak = false;
110
+ const resolve = (res) => {
111
+ results = res;
112
+ shouldBreak = true;
113
+ };
114
+ for (const resolver of resolvers) {
115
+ await resolver(resource, results, resolve);
116
+ if (shouldBreak) {
117
+ break;
118
+ }
119
+ }
120
+ results.sort((a, b) => {
121
+ const wa = a.weight || 0;
122
+ const wb = b.weight || 0;
123
+ return wb - wa;
124
+ });
125
+ return uniqWith(results, isEqual);
126
+ }
127
+
128
+ private calculateSchemeResolver(scheme: string): IEditorComponentResolver[] {
129
+ const resolvers = this.normalizedResolvers.slice();
130
+ const calculated: {
131
+ weight: number; // handleScheme 的权重
132
+ index: number; // resolver 在resolver中的位置(后来的先处理)
133
+ resolver: IEditorComponentResolver;
134
+ }[] = [];
135
+
136
+ resolvers.forEach((r, index) => {
137
+ const weight = r.handleScheme(scheme);
138
+ if (weight >= 0) {
139
+ calculated.push({
140
+ weight,
141
+ index,
142
+ resolver: r.resolver,
143
+ });
144
+ }
145
+ });
146
+
147
+ return calculated
148
+ .sort((a, b) => {
149
+ if (a.weight > b.weight) {
150
+ return -1;
151
+ } else if (a.weight < b.weight) {
152
+ return 1;
153
+ } else {
154
+ return b.index - a.index;
155
+ }
156
+ })
157
+ .map((c) => c.resolver);
158
+ }
159
+
160
+ private getResolvers(scheme: string): IEditorComponentResolver[] {
161
+ if (!this.resolvers.has(scheme)) {
162
+ this.resolvers.set(scheme, this.calculateSchemeResolver(scheme));
163
+ }
164
+ return this.resolvers.get(scheme) as IEditorComponentResolver[];
165
+ }
166
+
167
+ public getEditorComponent(id: string): IEditorComponent | null {
168
+ return this.components.get(id) || null;
169
+ }
170
+
171
+ public getEditorInitialProps(id: string): any {
172
+ return this.initialPropsMap.get(id) || null;
173
+ }
174
+
175
+ public clearPerWorkbenchComponentCache(componentId: string) {
176
+ ReactDOM.unmountComponentAtNode(this.perWorkbenchComponents[componentId]);
177
+ delete this.perWorkbenchComponents[componentId];
178
+ }
179
+
180
+ public getSideWidgets(side: EditorSide, resource: IResource): IEditorSideWidget<any>[] {
181
+ const res: IEditorSideWidget<any>[] = [];
182
+ this.sideWidgets[side].forEach((widget) => {
183
+ if (widget.displaysOnResource(resource)) {
184
+ res.push(widget);
185
+ }
186
+ });
187
+ return res.sort((w1, w2) => {
188
+ const weight1 = w1.weight === undefined ? 10 : w1.weight;
189
+ const weight2 = w2.weight === undefined ? 10 : w2.weight;
190
+ return weight2 - weight1;
191
+ });
192
+ }
193
+
194
+ public registerEditorSideWidget(widget: IEditorSideWidget<any>): IDisposable {
195
+ const side = widget.side || 'bottom';
196
+ this.sideWidgets[side].add(widget);
197
+ this.eventBus.fire(new RegisterEditorSideComponentEvent());
198
+ return {
199
+ dispose: () => {
200
+ this.sideWidgets[side].delete(widget);
201
+ },
202
+ };
203
+ }
204
+ }
@@ -0,0 +1,256 @@
1
+ import clsx from 'classnames';
2
+
3
+ import { Autowired, Injectable } from '@opensumi/di';
4
+ import { Disposable, URI, IEventBus, IMarkdownString } from '@opensumi/ide-core-common';
5
+ import type { ICodeEditor as IMonacoCodeEditor } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
6
+ import { IThemeService } from '@opensumi/ide-theme';
7
+ import * as monaco from '@opensumi/monaco-editor-core/esm/vs/editor/editor.api';
8
+
9
+ import { IDecorationRenderOptions, IDecorationApplyOptions } from '../common';
10
+
11
+ import {
12
+ IEditorDecorationCollectionService,
13
+ IDynamicModelDecorationProperty,
14
+ IThemedCssStyle,
15
+ EditorDecorationChangeEvent,
16
+ EditorDecorationTypeRemovedEvent,
17
+ DidApplyEditorDecorationFromProvider,
18
+ } from './types';
19
+
20
+ @Injectable({ multiple: true })
21
+ export class MonacoEditorDecorationApplier extends Disposable {
22
+ @Autowired(IEditorDecorationCollectionService)
23
+ decorationService: IEditorDecorationCollectionService;
24
+
25
+ @Autowired(IThemeService)
26
+ themeService: IThemeService;
27
+
28
+ @Autowired(IEventBus)
29
+ eventBus: IEventBus;
30
+
31
+ private decorations: Map<string, { decorations: string[]; dispose: () => void }> = new Map();
32
+
33
+ constructor(private editor: IMonacoCodeEditor) {
34
+ super();
35
+ this.applyDecorationFromProvider();
36
+ this.editor.onDidChangeModel(() => {
37
+ this.clearDecorations();
38
+ this.applyDecorationFromProvider();
39
+ });
40
+ this.editor.onDidDispose(() => {
41
+ this.dispose();
42
+ });
43
+ this.addDispose(
44
+ this.eventBus.on(EditorDecorationChangeEvent, (e) => {
45
+ const currentUri = this.getEditorUri();
46
+ if (currentUri && e.payload.uri.isEqual(currentUri)) {
47
+ this.applyDecorationFromProvider(e.payload.key);
48
+ }
49
+ }),
50
+ );
51
+ this.addDispose(
52
+ this.eventBus.on(EditorDecorationTypeRemovedEvent, (e) => {
53
+ this.deltaDecoration(e.payload, []);
54
+ }),
55
+ );
56
+ }
57
+
58
+ private getEditorUri(): URI | null {
59
+ if (this.editor.getModel()) {
60
+ const uri = new URI(this.editor.getModel()!.uri.toString());
61
+ return uri;
62
+ } else {
63
+ return null;
64
+ }
65
+ }
66
+
67
+ private async applyDecorationFromProvider(key?: string) {
68
+ if (this.editor.getModel()) {
69
+ const uri = new URI(this.editor.getModel()!.uri.toString());
70
+ const decs = await this.decorationService.getDecorationFromProvider(uri, key);
71
+ // 由于是异步获取decoration,此时uri可能已经变了
72
+ if (!this.editor.getModel() || this.editor.getModel()!.uri.toString() !== uri.toString()) {
73
+ return;
74
+ }
75
+
76
+ for (const key of Object.keys(decs)) {
77
+ this.deltaDecoration(key, decs[key]);
78
+ }
79
+ this.eventBus.fire(
80
+ new DidApplyEditorDecorationFromProvider({
81
+ key,
82
+ uri,
83
+ }),
84
+ );
85
+ }
86
+ }
87
+
88
+ dispose() {
89
+ super.dispose();
90
+ this.clearDecorations();
91
+ }
92
+
93
+ clearDecorations() {
94
+ this.decorations.forEach((v) => {
95
+ v.dispose();
96
+ this.editor.deltaDecorations(v.decorations, []);
97
+ });
98
+ this.decorations.clear();
99
+ }
100
+
101
+ deltaDecoration(key: string, decorations: monaco.editor.IModelDeltaDecoration[]) {
102
+ let oldDecorations: string[] = [];
103
+ if (this.decorations.has(key)) {
104
+ oldDecorations = this.decorations.get(key)!.decorations;
105
+ this.decorations.get(key)!.dispose();
106
+ this.decorations.delete(key);
107
+ }
108
+ if (oldDecorations.length === 0 && decorations.length === 0) {
109
+ return;
110
+ }
111
+ const newDecoration = this.editor.deltaDecorations(oldDecorations, decorations);
112
+ this.decorations.set(key, {
113
+ decorations: newDecoration,
114
+ dispose: () => null,
115
+ });
116
+ }
117
+
118
+ applyDecoration(key: string, options: IDecorationApplyOptions[]) {
119
+ const oldDecorations = this.decorations.get(key);
120
+ if (oldDecorations) {
121
+ oldDecorations.dispose();
122
+ }
123
+ const oldResult = oldDecorations ? oldDecorations.decorations : [];
124
+ const newDecorations: monaco.editor.IModelDeltaDecoration[] = [];
125
+ const disposer = new Disposable();
126
+ if (oldResult.length === 0 && options.length === 0) {
127
+ return;
128
+ }
129
+ options.forEach((option) => {
130
+ const resolved = this.resolveDecorationRenderer(key, option.renderOptions);
131
+ newDecorations.push({
132
+ range: option.range,
133
+ options: {
134
+ ...resolved.options,
135
+ hoverMessage: resolveHoverMessage(option.hoverMessage),
136
+ },
137
+ });
138
+ disposer.addDispose(resolved);
139
+ });
140
+ const result = this.editor.deltaDecorations(oldResult, newDecorations);
141
+ this.decorations.set(key, {
142
+ decorations: result,
143
+ dispose: () => disposer.dispose(),
144
+ });
145
+ }
146
+
147
+ resolveDecorationRenderer(
148
+ key: string,
149
+ options?: IDecorationRenderOptions,
150
+ ): { options: monaco.editor.IModelDecorationOptions; dispose: () => void } {
151
+ const type = this.decorationService.getTextEditorDecorationType(key);
152
+ const result: monaco.editor.IModelDecorationOptions = {
153
+ description: key,
154
+ };
155
+ const currentTheme = this.themeService.getCurrentThemeSync().type;
156
+ const disposer = new Disposable();
157
+ if (type) {
158
+ const property = type.property;
159
+ assignModelDecorationOptions(result, property, currentTheme);
160
+ }
161
+ if (options) {
162
+ const tempType = this.decorationService.createTextEditorDecorationType(options);
163
+ assignModelDecorationOptions(result, tempType.property, currentTheme);
164
+ disposer.addDispose(tempType);
165
+ }
166
+ return {
167
+ options: result,
168
+ dispose: () => disposer.dispose(),
169
+ };
170
+ }
171
+ }
172
+
173
+ function assignModelDecorationOptions(
174
+ target: monaco.editor.IModelDecorationOptions,
175
+ property: IDynamicModelDecorationProperty,
176
+ currentTheme: undefined | 'dark' | 'light' | 'hcDark' | 'hcLight',
177
+ ) {
178
+ if (property.overviewRulerLane) {
179
+ if (!target.overviewRuler) {
180
+ target.overviewRuler = {
181
+ color: null as any,
182
+ range: null as any,
183
+ position: property.overviewRulerLane,
184
+ };
185
+ } else {
186
+ target.overviewRuler.position = property.overviewRulerLane;
187
+ }
188
+ }
189
+
190
+ if (property.default) {
191
+ assignModelDecorationStyle(target, property.default);
192
+ }
193
+ if (currentTheme === 'dark' && property.dark) {
194
+ assignModelDecorationStyle(target, property.dark);
195
+ }
196
+ if (currentTheme === 'light' && property.light) {
197
+ assignModelDecorationStyle(target, property.light);
198
+ }
199
+
200
+ if (property.isWholeLine !== undefined) {
201
+ target.isWholeLine = property.isWholeLine;
202
+ }
203
+
204
+ if (property.rangeBehavior) {
205
+ target.stickiness = property.rangeBehavior as number;
206
+ }
207
+
208
+ target.inlineClassNameAffectsLetterSpacing = true;
209
+ }
210
+
211
+ function assignModelDecorationStyle(target: monaco.editor.IModelDecorationOptions, style: IThemedCssStyle) {
212
+ if (style.className) {
213
+ target.className = clsx(target.className, style.className);
214
+ }
215
+ if (style.inlineClassName) {
216
+ target.inlineClassName = clsx(target.inlineClassName, style.inlineClassName);
217
+ }
218
+ if (style.afterContentClassName) {
219
+ target.afterContentClassName = clsx(target.afterContentClassName, style.afterContentClassName);
220
+ }
221
+ if (style.beforeContentClassName) {
222
+ target.beforeContentClassName = clsx(target.beforeContentClassName, style.beforeContentClassName);
223
+ }
224
+ if (style.glyphMarginClassName) {
225
+ target.glyphMarginClassName = clsx(target.glyphMarginClassName, style.glyphMarginClassName);
226
+ }
227
+ if (style.overviewRulerColor) {
228
+ if (target.overviewRuler) {
229
+ target.overviewRuler.color = style.overviewRulerColor;
230
+ }
231
+ }
232
+ }
233
+
234
+ function resolveHoverMessage(
235
+ str: IMarkdownString | IMarkdownString[] | string | undefined,
236
+ ): IMarkdownString | IMarkdownString[] | undefined {
237
+ if (!str) {
238
+ return undefined;
239
+ }
240
+ if (str instanceof Array) {
241
+ return str.map(toMarkdownString);
242
+ } else {
243
+ return toMarkdownString(str);
244
+ }
245
+ }
246
+
247
+ function toMarkdownString(str: IMarkdownString | string): IMarkdownString {
248
+ if (typeof str === 'string') {
249
+ return {
250
+ value: str,
251
+ isTrusted: true,
252
+ };
253
+ } else {
254
+ return str;
255
+ }
256
+ }
@@ -0,0 +1,99 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import {
3
+ URI,
4
+ Domain,
5
+ localize,
6
+ Deferred,
7
+ CommandService,
8
+ EDITOR_COMMANDS,
9
+ CommandContribution,
10
+ CommandRegistry,
11
+ } from '@opensumi/ide-core-browser';
12
+ import { getIcon } from '@opensumi/ide-core-browser';
13
+ import { MenuContribution, IMenuRegistry, MenuId } from '@opensumi/ide-core-browser/lib/menu/next';
14
+
15
+ import { ICompareService, CompareResult } from '../types';
16
+
17
+ @Injectable()
18
+ export class CompareService implements ICompareService {
19
+ public readonly comparing = new Map<string, Deferred<CompareResult>>();
20
+
21
+ @Autowired(CommandService)
22
+ private commandService: CommandService;
23
+
24
+ compare(original: URI, modified: URI, name: string): Promise<CompareResult> {
25
+ const compareUri = URI.from({
26
+ scheme: 'diff',
27
+ query: URI.stringifyQuery({
28
+ name,
29
+ original,
30
+ modified,
31
+ comparing: true,
32
+ }),
33
+ });
34
+ if (!this.comparing.has(compareUri.toString())) {
35
+ const deferred = new Deferred<CompareResult>();
36
+ this.comparing.set(compareUri.toString(), deferred);
37
+ deferred.promise.then(() => {
38
+ this.comparing.delete(compareUri.toString());
39
+ this.commandService.executeCommand(EDITOR_COMMANDS.CLOSE_ALL.id, compareUri);
40
+ });
41
+ }
42
+ this.commandService.executeCommand(EDITOR_COMMANDS.OPEN_RESOURCE.id, compareUri);
43
+ return this.comparing.get(compareUri.toString())!.promise;
44
+ }
45
+ }
46
+
47
+ @Domain(MenuContribution, CommandContribution)
48
+ export class CompareEditorContribution implements MenuContribution, CommandContribution {
49
+ @Autowired(ICompareService)
50
+ compareService: CompareService;
51
+
52
+ registerMenus(menu: IMenuRegistry) {
53
+ menu.registerMenuItems(MenuId.EditorTitle, [
54
+ {
55
+ command: {
56
+ id: 'editor.diff.accept',
57
+ label: localize('editor.action.accept'),
58
+ },
59
+ iconClass: getIcon('check'),
60
+ group: 'navigation',
61
+ when: 'isInDiffEditor && diffResource =~ /%26comparing%3Dtrue$/',
62
+ },
63
+ ]);
64
+ menu.registerMenuItems(MenuId.EditorTitle, [
65
+ {
66
+ command: {
67
+ id: 'editor.diff.revert',
68
+ label: localize('editor.action.revert'),
69
+ },
70
+ iconClass: getIcon('rollback'),
71
+ group: 'navigation',
72
+ when: 'isInDiffEditor && diffResource =~ /%26comparing%3Dtrue$/',
73
+ },
74
+ ]);
75
+ }
76
+
77
+ registerCommands(commands: CommandRegistry) {
78
+ commands.registerCommand(
79
+ { id: 'editor.diff.accept' },
80
+ {
81
+ execute: (uri: URI) => {
82
+ if (uri && this.compareService.comparing.has(uri.toString())) {
83
+ this.compareService.comparing.get(uri.toString())!.resolve(CompareResult.accept);
84
+ }
85
+ },
86
+ },
87
+ );
88
+ commands.registerCommand(
89
+ { id: 'editor.diff.revert' },
90
+ {
91
+ execute: (uri: URI) => {
92
+ if (uri && this.compareService.comparing.has(uri.toString())) {
93
+ this.compareService.comparing.get(uri.toString())!.resolve(CompareResult.revert);
94
+ }
95
+ },
96
+ },
97
+ );
98
+ }
99
+ }