@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,119 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import { URI, IDisposable, IEventBus, Emitter, LRUMap } from '@opensumi/ide-core-browser';
3
+
4
+ import {
5
+ IEditorDocumentModelContentRegistry,
6
+ IEditorDocumentModelContentProvider,
7
+ EditorDocumentModelOptionExternalUpdatedEvent,
8
+ ORIGINAL_DOC_SCHEME,
9
+ } from './types';
10
+
11
+ @Injectable()
12
+ export class EditorDocumentModelContentRegistryImpl implements IEditorDocumentModelContentRegistry {
13
+ private providers: IEditorDocumentModelContentProvider[] = [];
14
+
15
+ @Autowired(IEventBus)
16
+ eventBus: IEventBus;
17
+
18
+ private _onOriginalDocChanged: Emitter<URI> = new Emitter();
19
+
20
+ private originalProvider: IEditorDocumentModelContentProvider;
21
+
22
+ private cachedProviders = new LRUMap<string, Promise<IEditorDocumentModelContentProvider | undefined>>(1000, 500);
23
+
24
+ constructor() {
25
+ this.originalProvider = {
26
+ handlesScheme: (scheme: string) => scheme === ORIGINAL_DOC_SCHEME,
27
+ provideEditorDocumentModelContent: async (uri: URI) => {
28
+ const { target } = uri.getParsedQuery();
29
+ const targetUri = new URI(target);
30
+ return (await this.getContentForUri(targetUri)) || '';
31
+ },
32
+ isReadonly: () => true,
33
+ onDidChangeContent: this._onOriginalDocChanged.event,
34
+ };
35
+ this.registerEditorDocumentModelContentProvider(this.originalProvider);
36
+ }
37
+
38
+ registerEditorDocumentModelContentProvider(provider: IEditorDocumentModelContentProvider): IDisposable {
39
+ this.providers.push(provider);
40
+ this.cachedProviders.clear();
41
+ const disposer = provider.onDidChangeContent((uri) => {
42
+ this.eventBus.fire(new EditorDocumentModelOptionExternalUpdatedEvent(uri));
43
+ });
44
+ // 每次注册 doc content provider, 都同时注册一个用于取出原始文档内容的doc provider
45
+ // 处理的doc uri为shadowed_前缀的scheme
46
+ if (provider !== this.originalProvider && provider.onDidChangeContent) {
47
+ provider.onDidChangeContent((uri) => {
48
+ this._onOriginalDocChanged.fire(
49
+ URI.from({
50
+ scheme: ORIGINAL_DOC_SCHEME,
51
+ query: URI.stringifyQuery({
52
+ target: uri.toString(),
53
+ }),
54
+ }),
55
+ );
56
+ });
57
+ }
58
+
59
+ return {
60
+ dispose: () => {
61
+ disposer.dispose();
62
+ const index = this.providers.indexOf(provider);
63
+ if (index) {
64
+ this.providers.splice(index, 1);
65
+ this.cachedProviders.clear();
66
+ }
67
+ },
68
+ };
69
+ }
70
+
71
+ getProvider(uri: URI): Promise<IEditorDocumentModelContentProvider | undefined> {
72
+ const uriStr = uri.toString();
73
+ if (!this.cachedProviders.has(uriStr)) {
74
+ this.cachedProviders.set(uriStr, this.calculateProvider(uri));
75
+ }
76
+ return this.cachedProviders.get(uriStr)!;
77
+ }
78
+
79
+ // Ant Codespaces 需要使用该方法复写 getProvider,不使用缓存 provider
80
+ protected async calculateProvider(uri: URI): Promise<IEditorDocumentModelContentProvider | undefined> {
81
+ let calculated: {
82
+ provider: IEditorDocumentModelContentProvider | undefined;
83
+ weight: number;
84
+ index: number;
85
+ } = {
86
+ provider: undefined,
87
+ weight: -1,
88
+ index: 1,
89
+ };
90
+ for (const provider of this.providers) {
91
+ let weight = -1;
92
+ const index = this.providers.indexOf(provider);
93
+ if (provider.handlesUri) {
94
+ weight = await provider.handlesUri(uri);
95
+ } else if (provider.handlesScheme) {
96
+ weight = (await provider.handlesScheme(uri.scheme)) ? 10 : -1;
97
+ }
98
+
99
+ if (weight >= 0) {
100
+ if (weight > calculated.weight || (weight === calculated.weight && index > calculated.index)) {
101
+ calculated = {
102
+ index,
103
+ weight,
104
+ provider,
105
+ };
106
+ }
107
+ }
108
+ }
109
+ return calculated.provider;
110
+ }
111
+
112
+ async getContentForUri(uri: URI, encoding?: string): Promise<string> {
113
+ const p = await this.getProvider(uri);
114
+ if (!p) {
115
+ throw new Error();
116
+ }
117
+ return p.provideEditorDocumentModelContent(uri, encoding);
118
+ }
119
+ }
@@ -0,0 +1,9 @@
1
+ import { IStackElement, IEditStackElement, IEOLStackElement } from './types';
2
+
3
+ export function isEditStack(element: IStackElement): element is IEditStackElement {
4
+ return !!(element as IEditStackElement).editOperations;
5
+ }
6
+
7
+ export function isEOLStack(element: IStackElement): element is IEOLStackElement {
8
+ return !!(element as IEOLStackElement).eol;
9
+ }
@@ -0,0 +1,4 @@
1
+ export * from './editor-document-model-service';
2
+ export * from './editor-document-model';
3
+ export * from './editor-document-registry';
4
+ export * from './save-task';
@@ -0,0 +1,49 @@
1
+ /* istanbul ignore file */
2
+ import { Autowired, Injectable } from '@opensumi/di';
3
+ import { URI } from '@opensumi/ide-core-browser';
4
+ import {
5
+ ITextModelService,
6
+ ITextModelContentProvider,
7
+ } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/resolverService';
8
+ import * as monaco from '@opensumi/monaco-editor-core/esm/vs/editor/editor.api';
9
+
10
+ import { IEditorDocumentModelService } from './types';
11
+
12
+ @Injectable()
13
+ export class MonacoTextModelService implements ITextModelService {
14
+ canHandleResource(resource: any): boolean {
15
+ return true;
16
+ }
17
+
18
+ hasTextModelContentProvider(scheme: string): boolean {
19
+ throw new Error('Method not implemented.');
20
+ }
21
+
22
+ _serviceBrand: undefined;
23
+
24
+ @Autowired(IEditorDocumentModelService)
25
+ documentModelManager: IEditorDocumentModelService;
26
+
27
+ async createModelReference(resource: monaco.Uri) {
28
+ const docModelRef = await this.documentModelManager.createModelReference(new URI(resource.toString()), 'monaco');
29
+ if (docModelRef) {
30
+ const model = docModelRef.instance.getMonacoModel();
31
+ return Promise.resolve({
32
+ object: {
33
+ textEditorModel: model,
34
+ },
35
+ dispose: () => {
36
+ docModelRef.dispose();
37
+ },
38
+ }) as any;
39
+ }
40
+ }
41
+
42
+ registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): monaco.IDisposable {
43
+ return {
44
+ dispose(): void {
45
+ // no-op
46
+ },
47
+ };
48
+ }
49
+ }
@@ -0,0 +1,88 @@
1
+ import {
2
+ URI,
3
+ Deferred,
4
+ IEditorDocumentChange,
5
+ IEditorDocumentModelSaveResult,
6
+ CancellationTokenSource,
7
+ Disposable,
8
+ CancellationToken,
9
+ SaveTaskResponseState,
10
+ SaveTaskErrorCause,
11
+ } from '@opensumi/ide-core-browser';
12
+ import { EOL } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
13
+
14
+ import { IEditorDocumentModelService } from './types';
15
+
16
+ export interface IEditorDocumentModelServiceImpl extends IEditorDocumentModelService {
17
+ saveEditorDocumentModel(
18
+ uri: URI,
19
+ content: string,
20
+ baseContent: string,
21
+ changes: IEditorDocumentChange[],
22
+ encoding?: string,
23
+ ignoreDiff?: boolean,
24
+ eol?: EOL,
25
+ token?: CancellationToken,
26
+ ): Promise<IEditorDocumentModelSaveResult>;
27
+ }
28
+
29
+ export class SaveTask extends Disposable {
30
+ private deferred: Deferred<IEditorDocumentModelSaveResult> = new Deferred();
31
+
32
+ public finished: Promise<IEditorDocumentModelSaveResult> = this.deferred.promise;
33
+
34
+ private cancelToken: CancellationTokenSource;
35
+
36
+ public started = false;
37
+
38
+ constructor(
39
+ private uri: URI,
40
+ public readonly versionId: number,
41
+ public readonly alternativeVersionId: number,
42
+ public content: string,
43
+ private ignoreDiff: boolean,
44
+ ) {
45
+ super();
46
+ this.disposables.push((this.cancelToken = new CancellationTokenSource()));
47
+ }
48
+
49
+ async run(
50
+ service: IEditorDocumentModelServiceImpl,
51
+ baseContent: string,
52
+ changes: IEditorDocumentChange[],
53
+ encoding?: string,
54
+ eol?: EOL,
55
+ ): Promise<IEditorDocumentModelSaveResult> {
56
+ this.started = true;
57
+ try {
58
+ const res = await service.saveEditorDocumentModel(
59
+ this.uri,
60
+ this.content,
61
+ baseContent,
62
+ changes,
63
+ encoding,
64
+ this.ignoreDiff,
65
+ eol,
66
+ this.cancelToken.token,
67
+ );
68
+ this.deferred.resolve(res);
69
+ return res;
70
+ } catch (e) {
71
+ const res: IEditorDocumentModelSaveResult = {
72
+ errorMessage: e.message,
73
+ state: SaveTaskResponseState.ERROR,
74
+ };
75
+ this.deferred.resolve(res);
76
+ return res;
77
+ }
78
+ }
79
+
80
+ cancel() {
81
+ this.cancelToken.cancel();
82
+ const res: IEditorDocumentModelSaveResult = {
83
+ errorMessage: SaveTaskErrorCause.CANCEL,
84
+ state: SaveTaskResponseState.ERROR,
85
+ };
86
+ this.deferred.resolve(res);
87
+ }
88
+ }
@@ -0,0 +1,227 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import {
3
+ ClientAppContribution,
4
+ WithEventBus,
5
+ Domain,
6
+ OnEvent,
7
+ PreferenceService,
8
+ CommandService,
9
+ ServiceNames,
10
+ ILogger,
11
+ MonacoOverrideServiceRegistry,
12
+ IProgress,
13
+ ProgressLocation,
14
+ IProgressStep,
15
+ formatLocalize,
16
+ } from '@opensumi/ide-core-browser';
17
+ import { IProgressService } from '@opensumi/ide-core-browser/lib/progress';
18
+ import { ResourceEdit } from '@opensumi/ide-monaco/lib/browser/monaco-api';
19
+ import { languageFeaturesService } from '@opensumi/ide-monaco/lib/browser/monaco-api/languages';
20
+ import { ITextModel } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
21
+ import * as languages from '@opensumi/monaco-editor-core/esm/vs/editor/common/languages';
22
+ import { CodeActionProvider } from '@opensumi/monaco-editor-core/esm/vs/editor/common/languages';
23
+ import {
24
+ getCodeActions,
25
+ CodeActionItem,
26
+ } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/codeAction/browser/codeAction';
27
+ import {
28
+ CodeActionKind,
29
+ CodeActionTriggerSource,
30
+ } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/codeAction/browser/types';
31
+ import * as monaco from '@opensumi/monaco-editor-core/esm/vs/editor/editor.api';
32
+
33
+ import { SaveReason } from '../types';
34
+
35
+ import { EditorDocumentModelWillSaveEvent, IEditorDocumentModelService } from './types';
36
+
37
+ @Injectable()
38
+ export class CodeActionOnSaveParticipant extends WithEventBus {
39
+ @Autowired(PreferenceService)
40
+ private readonly preferenceService: PreferenceService;
41
+
42
+ @Autowired(MonacoOverrideServiceRegistry)
43
+ private readonly overrideServiceRegistry: MonacoOverrideServiceRegistry;
44
+
45
+ @Autowired(CommandService)
46
+ private readonly commandService: CommandService;
47
+
48
+ @Autowired(IEditorDocumentModelService)
49
+ private readonly docService: IEditorDocumentModelService;
50
+
51
+ @Autowired(ILogger)
52
+ private readonly logger: ILogger;
53
+
54
+ @Autowired(IProgressService)
55
+ private readonly progressService: IProgressService;
56
+
57
+ get bulkEditService(): any {
58
+ return this.overrideServiceRegistry.getRegisteredService(ServiceNames.BULK_EDIT_SERVICE);
59
+ }
60
+
61
+ activate() {
62
+ // noop
63
+ }
64
+
65
+ @OnEvent(EditorDocumentModelWillSaveEvent)
66
+ async onEditorDocumentModelWillSave(e: EditorDocumentModelWillSaveEvent) {
67
+ // 自动保存不运行
68
+ if (e.payload.reason !== SaveReason.Manual) {
69
+ return;
70
+ }
71
+
72
+ const preferenceActions = this.preferenceService.get<
73
+ | {
74
+ [prop: string]: any;
75
+ }
76
+ | string[]
77
+ >('editor.codeActionsOnSave', undefined, e.payload.uri.toString(), e.payload.language);
78
+ if (!preferenceActions) {
79
+ return undefined;
80
+ }
81
+
82
+ return this.progressService.withProgress(
83
+ {
84
+ title: formatLocalize('editor.saveCodeActions.saving', e.payload.uri.displayName),
85
+ location: ProgressLocation.Notification,
86
+ cancellable: true,
87
+ },
88
+ async (progress) => {
89
+ const codeActions = Array.isArray(preferenceActions) ? preferenceActions : Object.keys(preferenceActions);
90
+ const codeActionsOnSave: CodeActionKind[] = codeActions.map((p) => new CodeActionKind(p));
91
+
92
+ if (!Array.isArray(preferenceActions)) {
93
+ codeActionsOnSave.sort((a, b) => {
94
+ if (CodeActionKind.SourceFixAll.contains(a)) {
95
+ if (CodeActionKind.SourceFixAll.contains(b)) {
96
+ return 0;
97
+ }
98
+ return -1;
99
+ }
100
+ if (CodeActionKind.SourceFixAll.contains(b)) {
101
+ return 1;
102
+ }
103
+ return 0;
104
+ });
105
+ }
106
+ if (codeActionsOnSave.length === 0) {
107
+ return;
108
+ }
109
+
110
+ const modelRef = this.docService.getModelReference(e.payload.uri, 'codeActionOnSave');
111
+ if (!modelRef) {
112
+ return;
113
+ }
114
+
115
+ const model = modelRef.instance.getMonacoModel();
116
+
117
+ const tokenSource = new monaco.CancellationTokenSource();
118
+
119
+ const timeout = this.preferenceService.get<number>(
120
+ 'editor.codeActionsOnSaveTimeout',
121
+ undefined,
122
+ e.payload.uri.toString(),
123
+ e.payload.language,
124
+ );
125
+
126
+ const excludedActions = Array.isArray(preferenceActions)
127
+ ? []
128
+ : Object.keys(preferenceActions)
129
+ .filter((x: string) => preferenceActions[x] === false)
130
+ .map((x: string) => new CodeActionKind(x));
131
+
132
+ return Promise.race([
133
+ new Promise<void>((_resolve, reject) =>
134
+ setTimeout(() => {
135
+ tokenSource.cancel();
136
+ reject('codeActionsOnSave timeout');
137
+ }, timeout),
138
+ ),
139
+ this.applyOnSaveActions(model, codeActionsOnSave, excludedActions, progress, tokenSource.token),
140
+ ]).finally(() => {
141
+ tokenSource.cancel();
142
+ modelRef.dispose();
143
+ });
144
+ },
145
+ );
146
+ }
147
+
148
+ private async applyOnSaveActions(
149
+ model: ITextModel,
150
+ actions: CodeActionKind[],
151
+ excludes: readonly CodeActionKind[],
152
+ progress: IProgress<IProgressStep>,
153
+ token: monaco.CancellationToken,
154
+ ) {
155
+ const getActionProgress = new (class implements IProgress<CodeActionProvider> {
156
+ private _names = new Set<string>();
157
+ private _report(): void {
158
+ progress.report({
159
+ message: formatLocalize(
160
+ 'editor.saveCodeActions.getting',
161
+ [...this._names].map((name) => `'${name}'`).join(', '),
162
+ ),
163
+ });
164
+ }
165
+ report(provider: CodeActionProvider) {
166
+ if (provider.displayName && !this._names.has(provider.displayName)) {
167
+ this._names.add(provider.displayName);
168
+ this._report();
169
+ }
170
+ }
171
+ })();
172
+ for (const codeActionKind of actions) {
173
+ try {
174
+ const actionsToRun = await this.getActionsToRun(model, codeActionKind, excludes, getActionProgress, token);
175
+
176
+ await this.applyCodeActions(actionsToRun.validActions);
177
+ } catch (e) {
178
+ this.logger.error(e);
179
+ }
180
+ }
181
+ }
182
+
183
+ private async applyCodeActions(actionsToRun: readonly CodeActionItem[]) {
184
+ for (const actionItem of actionsToRun) {
185
+ if (actionItem.action.edit) {
186
+ await this.bulkEditService?.apply(ResourceEdit.convert(actionItem.action.edit));
187
+ }
188
+ if (actionItem.action.command) {
189
+ await this.commandService.executeCommand(
190
+ actionItem.action.command.id,
191
+ ...(actionItem.action.command.arguments || []),
192
+ );
193
+ }
194
+ }
195
+ }
196
+
197
+ private async getActionsToRun(
198
+ model: ITextModel,
199
+ codeActionKind: CodeActionKind,
200
+ excludes: readonly CodeActionKind[],
201
+ progress: IProgress<CodeActionProvider>,
202
+ token: monaco.CancellationToken,
203
+ ) {
204
+ return getCodeActions(
205
+ languageFeaturesService.codeActionProvider,
206
+ model,
207
+ model.getFullModelRange(),
208
+ {
209
+ type: languages.CodeActionTriggerType.Auto,
210
+ filter: { include: codeActionKind, excludes, includeSourceActions: true },
211
+ triggerAction: CodeActionTriggerSource.OnSave,
212
+ },
213
+ progress,
214
+ token,
215
+ );
216
+ }
217
+ }
218
+
219
+ @Domain(ClientAppContribution)
220
+ export class SaveParticipantsContribution implements ClientAppContribution {
221
+ @Autowired()
222
+ codeActionOnSaveParticipant: CodeActionOnSaveParticipant;
223
+
224
+ onStart() {
225
+ this.codeActionOnSaveParticipant.activate();
226
+ }
227
+ }