@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,1438 @@
1
+ import { Autowired, INJECTOR_TOKEN, Injector } from '@opensumi/di';
2
+ import {
3
+ IClientApp,
4
+ ClientAppContribution,
5
+ KeybindingContribution,
6
+ KeybindingRegistry,
7
+ EDITOR_COMMANDS,
8
+ CommandContribution,
9
+ CommandRegistry,
10
+ URI,
11
+ Domain,
12
+ localize,
13
+ formatLocalize,
14
+ MonacoService,
15
+ ServiceNames,
16
+ MonacoContribution,
17
+ CommandService,
18
+ QuickPickService,
19
+ IEventBus,
20
+ Schemes,
21
+ PreferenceService,
22
+ Disposable,
23
+ IPreferenceSettingsService,
24
+ OpenerContribution,
25
+ IOpenerService,
26
+ IClipboardService,
27
+ QuickOpenContribution,
28
+ IQuickOpenHandlerRegistry,
29
+ PrefixQuickOpenService,
30
+ MonacoOverrideServiceRegistry,
31
+ IContextKeyService,
32
+ getLanguageIdFromMonaco,
33
+ QuickPickItem,
34
+ AppConfig,
35
+ SUPPORTED_ENCODINGS,
36
+ FILE_COMMANDS,
37
+ electronEnv,
38
+ CorePreferences,
39
+ } from '@opensumi/ide-core-browser';
40
+ import { ComponentContribution, ComponentRegistry } from '@opensumi/ide-core-browser/lib/layout';
41
+ import { MenuContribution, IMenuRegistry, MenuId } from '@opensumi/ide-core-browser/lib/menu/next';
42
+ import { AbstractContextMenuService } from '@opensumi/ide-core-browser/lib/menu/next/menu.interface';
43
+ import { ICtxMenuRenderer } from '@opensumi/ide-core-browser/lib/menu/next/renderer/ctxmenu/base';
44
+ import { IRelaxedOpenMergeEditorArgs } from '@opensumi/ide-core-browser/lib/monaco/merge-editor-widget';
45
+ import { isWindows, isOSX, PreferenceScope, ILogger, OnEvent, WithEventBus } from '@opensumi/ide-core-common';
46
+ import { IElectronMainUIService } from '@opensumi/ide-core-common/lib/electron';
47
+ import { ITextmateTokenizer, ITextmateTokenizerService } from '@opensumi/ide-monaco/lib/browser/contrib/tokenizer';
48
+ import { EOL } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
49
+ import { EditorContextKeys } from '@opensumi/monaco-editor-core/esm/vs/editor/common/editorContextKeys';
50
+ import * as monaco from '@opensumi/monaco-editor-core/esm/vs/editor/editor.api';
51
+ import { ContextKeyExpr } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey';
52
+ import { SyncDescriptor } from '@opensumi/monaco-editor-core/esm/vs/platform/instantiation/common/descriptors';
53
+
54
+ import {
55
+ WorkbenchEditorService,
56
+ IResourceOpenOptions,
57
+ EditorGroupSplitAction,
58
+ ILanguageService,
59
+ Direction,
60
+ IDocPersistentCacheProvider,
61
+ IEditor,
62
+ SaveReason,
63
+ } from '../common';
64
+ import { AUTO_SAVE_MODE } from '../common/editor';
65
+
66
+ import { MonacoTextModelService } from './doc-model/override';
67
+ import { IEditorDocumentModelService } from './doc-model/types';
68
+ import { IEditorDocumentModelContentRegistry } from './doc-model/types';
69
+ import { EditorOpener } from './editor-opener';
70
+ import { MonacoCodeService, MonacoContextViewService } from './editor.override';
71
+ import { EditorStatusBarService } from './editor.status-bar.service';
72
+ import { EditorView } from './editor.view';
73
+ import { DocumentFormatService } from './format/format.service';
74
+ import { FormattingSelector } from './format/formatterSelect';
75
+ import { EditorHistoryService } from './history';
76
+ import { EditorContextMenuController } from './menu/editor.context';
77
+ import { NavigationMenuContainer } from './navigation.view';
78
+ import { GoToLineQuickOpenHandler } from './quick-open/go-to-line';
79
+ import { WorkspaceSymbolQuickOpenHandler } from './quick-open/workspace-symbol-quickopen';
80
+ import {
81
+ EditorGroupsResetSizeEvent,
82
+ BrowserEditorContribution,
83
+ IEditorFeatureRegistry,
84
+ ResourceDecorationChangeEvent,
85
+ } from './types';
86
+ import { EditorSuggestWidgetContribution } from './view/suggest-widget';
87
+ import { EditorTopPaddingContribution } from './view/topPadding';
88
+ import { WorkbenchEditorServiceImpl, EditorGroup } from './workbench-editor.service';
89
+
90
+ interface ResourceArgs {
91
+ group: EditorGroup;
92
+ uri: URI;
93
+ }
94
+
95
+ @Domain(
96
+ CommandContribution,
97
+ ClientAppContribution,
98
+ KeybindingContribution,
99
+ MonacoContribution,
100
+ ComponentContribution,
101
+ MenuContribution,
102
+ OpenerContribution,
103
+ QuickOpenContribution,
104
+ )
105
+ export class EditorContribution
106
+ extends WithEventBus
107
+ implements
108
+ CommandContribution,
109
+ ClientAppContribution,
110
+ KeybindingContribution,
111
+ MonacoContribution,
112
+ ComponentContribution,
113
+ MenuContribution,
114
+ OpenerContribution,
115
+ QuickOpenContribution
116
+ {
117
+ @Autowired(INJECTOR_TOKEN)
118
+ injector: Injector;
119
+
120
+ @Autowired(AppConfig)
121
+ private readonly appConfig: AppConfig;
122
+
123
+ @Autowired(WorkbenchEditorService)
124
+ private workbenchEditorService: WorkbenchEditorServiceImpl;
125
+
126
+ @Autowired()
127
+ private editorStatusBarService: EditorStatusBarService;
128
+
129
+ @Autowired(QuickPickService)
130
+ private quickPickService: QuickPickService;
131
+
132
+ @Autowired(ILanguageService)
133
+ private languagesService: ILanguageService;
134
+
135
+ @Autowired(IEditorDocumentModelService)
136
+ private editorDocumentModelService: IEditorDocumentModelService;
137
+
138
+ @Autowired(IDocPersistentCacheProvider)
139
+ private cacheProvider: IDocPersistentCacheProvider;
140
+
141
+ @Autowired()
142
+ private historyService: EditorHistoryService;
143
+
144
+ @Autowired()
145
+ private monacoService: MonacoService;
146
+
147
+ @Autowired(IOpenerService)
148
+ private readonly openerService: IOpenerService;
149
+
150
+ @Autowired(ILogger)
151
+ private readonly logger: ILogger;
152
+
153
+ @Autowired()
154
+ private editorOpener: EditorOpener;
155
+
156
+ @Autowired(IClipboardService)
157
+ private readonly clipboardService: IClipboardService;
158
+
159
+ @Autowired()
160
+ private readonly workspaceSymbolQuickOpenHandler: WorkspaceSymbolQuickOpenHandler;
161
+
162
+ @Autowired(PrefixQuickOpenService)
163
+ private readonly prefixQuickOpenService: PrefixQuickOpenService;
164
+
165
+ @Autowired()
166
+ private readonly goToLineQuickOpenHandler: GoToLineQuickOpenHandler;
167
+
168
+ @Autowired(PreferenceService)
169
+ private readonly preferenceService: PreferenceService;
170
+
171
+ @Autowired(ITextmateTokenizer)
172
+ private readonly textmateService: ITextmateTokenizerService;
173
+
174
+ @Autowired(CorePreferences)
175
+ private readonly corePreferences: CorePreferences;
176
+
177
+ @Autowired(IEditorDocumentModelContentRegistry)
178
+ contentRegistry: IEditorDocumentModelContentRegistry;
179
+
180
+ registerComponent(registry: ComponentRegistry) {
181
+ registry.register('@opensumi/ide-editor', {
182
+ id: 'ide-editor',
183
+ component: EditorView,
184
+ });
185
+ registry.register('breadcrumb-menu', {
186
+ id: 'breadcrumb-menu',
187
+ component: NavigationMenuContainer,
188
+ });
189
+ }
190
+
191
+ registerOverrideService(registry: MonacoOverrideServiceRegistry): void {
192
+ const codeEditorService = this.injector.get(MonacoCodeService);
193
+
194
+ // Monaco Editor ContextKeyService
195
+ // 经过这个Override, 所有编辑器的 contextKeyService 都是 editorContextKeyService 的孩子
196
+ const globalContextKeyService: IContextKeyService = this.injector.get(IContextKeyService);
197
+ const editorContextKeyService = globalContextKeyService.createScoped();
198
+ this.workbenchEditorService.setEditorContextKeyService(editorContextKeyService);
199
+ registry.registerOverrideService(
200
+ ServiceNames.CONTEXT_KEY_SERVICE,
201
+ (editorContextKeyService as any).contextKeyService,
202
+ );
203
+
204
+ // Monaco CodeEditorService
205
+ registry.registerOverrideService(ServiceNames.CODE_EDITOR_SERVICE, codeEditorService);
206
+
207
+ // Monaco ContextViewService
208
+ registry.registerOverrideService(
209
+ ServiceNames.CONTEXT_VIEW_SERVICE,
210
+ new MonacoContextViewService(codeEditorService),
211
+ );
212
+
213
+ // Monaco TextModelService
214
+ registry.registerOverrideService(ServiceNames.TEXT_MODEL_SERVICE, this.injector.get(MonacoTextModelService));
215
+ }
216
+
217
+ @Autowired(AbstractContextMenuService)
218
+ private readonly contextMenuService: AbstractContextMenuService;
219
+
220
+ @Autowired(IContextKeyService)
221
+ private readonly globalContextKeyService: IContextKeyService;
222
+
223
+ @Autowired(ICtxMenuRenderer)
224
+ private readonly contextMenuRenderer: ICtxMenuRenderer;
225
+
226
+ @Autowired(IElectronMainUIService)
227
+ private readonly electronMainUIService: IElectronMainUIService;
228
+
229
+ registerMonacoDefaultFormattingSelector(register): void {
230
+ const formatSelector = this.injector.get(FormattingSelector);
231
+ register(formatSelector.select.bind(formatSelector));
232
+ }
233
+
234
+ registerEditorExtensionContribution(register): void {
235
+ register(
236
+ EditorContextMenuController.ID,
237
+ /**
238
+ * 如果使用 common-di 的 Injectable 装饰,在内部会无法被 monaco 实例化
239
+ * 这里借用 monaco 内置的 DI 注入方式,将依赖的 Services 通过参数传递进去
240
+ * 在内部重新实例化时会拼接两份参数,对于 EditorContextMenuController
241
+ * monaco 将会自动补充另一个 editor 实例作为参数
242
+ * ref: https://github.com/microsoft/vscode/blob/3820f34dcabb3060715e24abfd05ec2455e71786/src/vs/platform/instantiation/common/instantiationService.ts#L73
243
+ */
244
+ new SyncDescriptor(EditorContextMenuController, [
245
+ this.contextMenuService,
246
+ this.globalContextKeyService,
247
+ this.contextMenuRenderer,
248
+ ]),
249
+ );
250
+ }
251
+
252
+ protected getMimeForMode(langId: string): string | undefined {
253
+ for (const language of this.textmateService.getLanguages()) {
254
+ if (language.id === langId && language.mimetypes) {
255
+ return language.mimetypes[0];
256
+ }
257
+ }
258
+ return undefined;
259
+ }
260
+
261
+ registerPlatformLanguageAssociations(register) {
262
+ const association = this.corePreferences['files.associations'];
263
+ if (!association) {
264
+ return;
265
+ }
266
+
267
+ const mimeAssociation = Object.keys(association).map((filepattern) => ({
268
+ id: association[filepattern],
269
+ filepattern,
270
+ mime: this.getMimeForMode(association[filepattern]) || `text/x-${association.id}`,
271
+ }));
272
+ register(mimeAssociation);
273
+ }
274
+
275
+ protected async interceptOpen(uri: URI) {
276
+ try {
277
+ await this.openerService.open(uri);
278
+ return true;
279
+ } catch (e) {
280
+ this.logger.error(e);
281
+ return false;
282
+ }
283
+ }
284
+
285
+ @OnEvent(ResourceDecorationChangeEvent)
286
+ onResourceDecorationChangeEvent() {
287
+ if (this.appConfig.isElectronRenderer) {
288
+ const hasDirty = this.workbenchEditorService.hasDirty();
289
+ // setup macos native dirty indicator
290
+ this.electronMainUIService.setDocumentEdited(electronEnv.currentWindowId, hasDirty ? true : false);
291
+ }
292
+ }
293
+
294
+ onWillStop(app: IClientApp) {
295
+ if (this.appConfig.isElectronRenderer) {
296
+ return this.onWillStopElectron();
297
+ } else {
298
+ return this.workbenchEditorService.hasDirty() || !this.cacheProvider.isFlushed();
299
+ }
300
+ }
301
+
302
+ // editorTitle出现了参数不统一。。
303
+ private extractGroupAndUriFromArgs(
304
+ resource: ResourceArgs | URI,
305
+ editorGroup?: EditorGroup,
306
+ ): {
307
+ group?: EditorGroup;
308
+ uri?: URI;
309
+ } {
310
+ let group: EditorGroup;
311
+ let uri: URI;
312
+ if (resource instanceof URI) {
313
+ group = editorGroup || this.workbenchEditorService.currentEditorGroup;
314
+ uri = resource || (group && group.currentResource && group.currentResource.uri);
315
+ } else {
316
+ const resourceArgs = resource || {};
317
+ group = resourceArgs.group || this.workbenchEditorService.currentEditorGroup;
318
+ uri = resourceArgs.uri || (group && group.currentResource && group.currentResource.uri);
319
+ }
320
+ return {
321
+ group,
322
+ uri,
323
+ };
324
+ }
325
+
326
+ /**
327
+ * Return true in order to prevent exit.
328
+ */
329
+ async onWillStopElectron() {
330
+ if (await this.workbenchEditorService.closeAllOnlyConfirmOnce()) {
331
+ return true;
332
+ }
333
+
334
+ if (!this.cacheProvider.isFlushed()) {
335
+ return true;
336
+ }
337
+
338
+ return false;
339
+ }
340
+
341
+ private isElectronRenderer(): boolean {
342
+ return this.appConfig.isElectronRenderer;
343
+ }
344
+
345
+ registerKeybindings(keybindings: KeybindingRegistry): void {
346
+ keybindings.registerKeybinding({
347
+ command: EDITOR_COMMANDS.SAVE_CURRENT.id,
348
+ keybinding: 'ctrlcmd+s',
349
+ });
350
+ keybindings.registerKeybinding({
351
+ command: EDITOR_COMMANDS.FOCUS_IF_NOT_ACTIVATE_ELEMENT.id,
352
+ keybinding: 'ctrlcmd+f',
353
+ when: '!editorFocus',
354
+ });
355
+ keybindings.registerKeybinding({
356
+ command: EDITOR_COMMANDS.CLOSE.id,
357
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+w' : 'alt+shift+w',
358
+ });
359
+ keybindings.registerKeybinding({
360
+ command: EDITOR_COMMANDS.PREVIOUS.id,
361
+ keybinding: this.isElectronRenderer() ? 'alt+cmd+left' : 'ctrlcmd+ctrl+left',
362
+ });
363
+ keybindings.registerKeybinding({
364
+ command: EDITOR_COMMANDS.NEXT.id,
365
+ keybinding: this.isElectronRenderer() ? 'alt+cmd+right' : 'ctrlcmd+ctrl+right',
366
+ });
367
+ keybindings.registerKeybinding({
368
+ command: EDITOR_COMMANDS.PREVIOUS.id,
369
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+pageup' : 'alt+pageup',
370
+ });
371
+ keybindings.registerKeybinding({
372
+ command: EDITOR_COMMANDS.NEXT.id,
373
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+pagedown' : 'alt+pagedown',
374
+ });
375
+ keybindings.registerKeybinding({
376
+ command: EDITOR_COMMANDS.GO_FORWARD.id,
377
+ keybinding: isWindows ? 'alt+right' : 'ctrl+shift+-',
378
+ });
379
+ keybindings.registerKeybinding({
380
+ command: EDITOR_COMMANDS.GO_BACK.id,
381
+ keybinding: isWindows ? 'alt+left' : 'ctrl+-',
382
+ });
383
+ keybindings.registerKeybinding({
384
+ command: EDITOR_COMMANDS.CHANGE_LANGUAGE.id,
385
+ keybinding: 'ctrlcmd+k m',
386
+ });
387
+ keybindings.registerKeybinding({
388
+ command: EDITOR_COMMANDS.SPLIT_TO_RIGHT.id,
389
+ keybinding: 'ctrlcmd+\\',
390
+ });
391
+ keybindings.registerKeybinding({
392
+ command: EDITOR_COMMANDS.NAVIGATE_NEXT.id,
393
+ keybinding: 'ctrlcmd+k ctrlcmd+right',
394
+ });
395
+ keybindings.registerKeybinding({
396
+ command: EDITOR_COMMANDS.NAVIGATE_PREVIOUS.id,
397
+ keybinding: 'ctrlcmd+k ctrlcmd+left',
398
+ });
399
+ keybindings.registerKeybinding({
400
+ command: EDITOR_COMMANDS.SAVE_ALL.id,
401
+ keybinding: 'alt+ctrlcmd+s',
402
+ });
403
+ keybindings.registerKeybinding({
404
+ command: EDITOR_COMMANDS.CLOSE_ALL_IN_GROUP.id,
405
+ keybinding: 'ctrlcmd+k w',
406
+ });
407
+ keybindings.registerKeybinding({
408
+ command: EDITOR_COMMANDS.CLOSE_ALL.id,
409
+ keybinding: 'ctrlcmd+k ctrlcmd+w',
410
+ });
411
+ keybindings.registerKeybinding({
412
+ command: EDITOR_COMMANDS.PIN_CURRENT.id,
413
+ keybinding: 'ctrlcmd+k enter',
414
+ });
415
+ keybindings.registerKeybinding({
416
+ command: EDITOR_COMMANDS.COPY_CURRENT_PATH.id,
417
+ keybinding: 'ctrlcmd+k p',
418
+ });
419
+ keybindings.registerKeybinding({
420
+ command: EDITOR_COMMANDS.REOPEN_CLOSED.id,
421
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+shift+t' : 'alt+shift+t',
422
+ });
423
+ keybindings.registerKeybinding({
424
+ command: EDITOR_COMMANDS.NEW_UNTITLED_FILE.id,
425
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+n' : 'alt+n',
426
+ });
427
+ keybindings.registerKeybinding({
428
+ command: EDITOR_COMMANDS.SEARCH_WORKSPACE_SYMBOL.id,
429
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+t' : 'ctrlcmd+o',
430
+ });
431
+ keybindings.registerKeybinding({
432
+ command: EDITOR_COMMANDS.SEARCH_WORKSPACE_SYMBOL_CLASS.id,
433
+ keybinding: this.isElectronRenderer() ? 'ctrlcmd+alt+t' : 'ctrlcmd+alt+o',
434
+ });
435
+ if (this.isElectronRenderer()) {
436
+ keybindings.registerKeybinding({
437
+ command: EDITOR_COMMANDS.NEXT.id,
438
+ keybinding: 'ctrl+tab',
439
+ });
440
+ keybindings.registerKeybinding({
441
+ command: EDITOR_COMMANDS.PREVIOUS.id,
442
+ keybinding: 'ctrl+shift+tab',
443
+ });
444
+ if (isOSX) {
445
+ keybindings.registerKeybinding({
446
+ command: EDITOR_COMMANDS.NEXT.id,
447
+ keybinding: 'ctrlcmd+shift+]',
448
+ });
449
+ keybindings.registerKeybinding({
450
+ command: EDITOR_COMMANDS.PREVIOUS.id,
451
+ keybinding: 'ctrlcmd+shift+[',
452
+ });
453
+ }
454
+ }
455
+ for (let i = 1; i < 10; i++) {
456
+ keybindings.registerKeybinding({
457
+ command: EDITOR_COMMANDS.GO_TO_GROUP.id,
458
+ keybinding: 'ctrlcmd+' + i,
459
+ args: [i],
460
+ });
461
+ }
462
+ ['left', 'up', 'down', 'right'].forEach((direction) => {
463
+ keybindings.registerKeybinding({
464
+ command: EDITOR_COMMANDS.MOVE_GROUP.id,
465
+ keybinding: 'ctrlcmd+k ' + direction,
466
+ args: [direction],
467
+ });
468
+ });
469
+
470
+ keybindings.registerKeybinding({
471
+ command: EDITOR_COMMANDS.COMPONENT_UNDO.id,
472
+ keybinding: 'ctrlcmd+z',
473
+ when: 'inEditorComponent',
474
+ });
475
+
476
+ keybindings.registerKeybinding({
477
+ command: EDITOR_COMMANDS.COMPONENT_REDO.id,
478
+ keybinding: 'shift+ctrlcmd+z',
479
+ when: 'inEditorComponent',
480
+ });
481
+
482
+ keybindings.registerKeybinding({
483
+ command: EDITOR_COMMANDS.TOGGLE_WORD_WRAP.id,
484
+ keybinding: 'alt+z',
485
+ when: 'editorFocus',
486
+ });
487
+ }
488
+
489
+ initialize() {
490
+ this.editorStatusBarService.setListener();
491
+ this.historyService.init();
492
+ }
493
+
494
+ registerCommands(commands: CommandRegistry): void {
495
+ commands.registerCommand(EDITOR_COMMANDS.GO_FORWARD, {
496
+ execute: () => {
497
+ this.historyService.forward();
498
+ },
499
+ });
500
+
501
+ commands.registerCommand(EDITOR_COMMANDS.FOCUS_IF_NOT_ACTIVATE_ELEMENT, {
502
+ execute: () => {
503
+ if (!document.activeElement || document.activeElement === document.body) {
504
+ const group = this.workbenchEditorService.currentEditorGroup;
505
+ group?.focus();
506
+ group?.currentCodeEditor?.monacoEditor?.trigger('api', 'actions.find', null);
507
+ }
508
+ },
509
+ });
510
+
511
+ commands.registerCommand(EDITOR_COMMANDS.GO_BACK, {
512
+ execute: () => {
513
+ this.historyService.back();
514
+ },
515
+ });
516
+
517
+ commands.registerCommand(EDITOR_COMMANDS.OPEN_RESOURCE, {
518
+ execute: async (uri: URI, options?: IResourceOpenOptions) => {
519
+ const openResult = await this.workbenchEditorService.open(uri, options);
520
+ if (openResult) {
521
+ return {
522
+ groupId: openResult?.group.name,
523
+ };
524
+ }
525
+ },
526
+ });
527
+
528
+ commands.registerCommand(EDITOR_COMMANDS.OPEN_RESOURCES, {
529
+ execute: ({ uris }: { uris: URI[] }) => {
530
+ this.workbenchEditorService.openUris(uris);
531
+ },
532
+ });
533
+
534
+ commands.registerCommand(EDITOR_COMMANDS.COMPARE, {
535
+ execute: (
536
+ { original, modified, name }: { original: URI; modified: URI; name?: string },
537
+ options: IResourceOpenOptions = {},
538
+ ) => {
539
+ name = name || `${original.displayName} <=> ${modified.displayName}`;
540
+ return this.workbenchEditorService.open(
541
+ URI.from({
542
+ scheme: 'diff',
543
+ query: URI.stringifyQuery({
544
+ name,
545
+ original,
546
+ modified,
547
+ }),
548
+ }),
549
+ options,
550
+ );
551
+ },
552
+ });
553
+
554
+ commands.registerCommand(EDITOR_COMMANDS.OPEN_MERGEEDITOR, {
555
+ execute: (args: unknown) => {
556
+ const validatedArgs = IRelaxedOpenMergeEditorArgs.validate(args);
557
+ this.workbenchEditorService.open(
558
+ URI.from({
559
+ scheme: 'mergeEditor',
560
+ query: URI.stringifyQuery({
561
+ name: formatLocalize('mergeEditor.workbench.tab.name', validatedArgs.output.displayName),
562
+ openMetadata: IRelaxedOpenMergeEditorArgs.toString(validatedArgs),
563
+ }),
564
+ }),
565
+ );
566
+ },
567
+ });
568
+
569
+ commands.registerCommand(EDITOR_COMMANDS.SAVE_CURRENT, {
570
+ execute: async () => {
571
+ const group = this.workbenchEditorService.currentEditorGroup;
572
+ if (group && group.currentResource) {
573
+ group.pin(group.currentResource!.uri);
574
+ group.saveCurrent();
575
+ }
576
+ },
577
+ });
578
+
579
+ commands.registerCommand(EDITOR_COMMANDS.SAVE_URI, {
580
+ execute: async (uri: URI) => {
581
+ for (const g of this.workbenchEditorService.editorGroups) {
582
+ const r = g.resources.find((r) => r.uri.isEqual(uri));
583
+ if (r) {
584
+ g.saveResource(r);
585
+ }
586
+ }
587
+ },
588
+ });
589
+
590
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE_ALL_IN_GROUP, {
591
+ execute: async (args0: ResourceArgs | URI, args1?: EditorGroup) => {
592
+ const { group } = this.extractGroupAndUriFromArgs(args0, args1);
593
+ if (group) {
594
+ await group.closeAll();
595
+ }
596
+ },
597
+ });
598
+
599
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE_SAVED, {
600
+ execute: async (resource: ResourceArgs) => {
601
+ resource = resource || {};
602
+ const { group = this.workbenchEditorService.currentEditorGroup } = resource;
603
+ if (group) {
604
+ await group.closeSaved();
605
+ }
606
+ },
607
+ });
608
+
609
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE_OTHER_IN_GROUP, {
610
+ execute: async (resource: ResourceArgs) => {
611
+ resource = resource || {};
612
+ const {
613
+ group = this.workbenchEditorService.currentEditorGroup,
614
+ uri = group && group.currentResource && group.currentResource.uri,
615
+ } = resource;
616
+ if (group && uri) {
617
+ await group.closeOthers(uri);
618
+ }
619
+ },
620
+ });
621
+
622
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE, {
623
+ execute: async (resource: ResourceArgs) => {
624
+ resource = resource || {};
625
+ const {
626
+ group = this.workbenchEditorService.currentEditorGroup,
627
+ uri = group && group.currentResource && group.currentResource.uri,
628
+ } = resource;
629
+ if (group && uri) {
630
+ await group.close(uri);
631
+ }
632
+ },
633
+ });
634
+
635
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE_TO_RIGHT, {
636
+ execute: async (resource: ResourceArgs) => {
637
+ resource = resource || {};
638
+ const {
639
+ group = this.workbenchEditorService.currentEditorGroup,
640
+ uri = group && group.currentResource && group.currentResource.uri,
641
+ } = resource;
642
+ if (group && uri) {
643
+ await group.closeToRight(uri);
644
+ }
645
+ },
646
+ });
647
+
648
+ commands.registerCommand(EDITOR_COMMANDS.GET_CURRENT, {
649
+ execute: () => this.workbenchEditorService.currentEditorGroup,
650
+ });
651
+
652
+ commands.registerCommand(EDITOR_COMMANDS.GET_CURRENT_RESOURCE, {
653
+ execute: () => this.workbenchEditorService.currentResource,
654
+ });
655
+
656
+ commands.registerCommand(EDITOR_COMMANDS.PIN_CURRENT, {
657
+ execute: () => {
658
+ const group = this.workbenchEditorService.currentEditorGroup;
659
+ if (group) {
660
+ group.pinPreviewed();
661
+ }
662
+ },
663
+ });
664
+
665
+ commands.registerCommand(EDITOR_COMMANDS.COPY_CURRENT_PATH, {
666
+ execute: () => {
667
+ const resource = this.workbenchEditorService.currentResource;
668
+ if (resource && resource.uri.scheme === Schemes.file) {
669
+ this.clipboardService.writeText(resource.uri.codeUri.fsPath);
670
+ }
671
+ },
672
+ });
673
+
674
+ commands.registerCommand(EDITOR_COMMANDS.SPLIT_TO_LEFT, {
675
+ execute: async (resource: ResourceArgs) => {
676
+ resource = resource || {};
677
+ const {
678
+ group = this.workbenchEditorService.currentEditorGroup,
679
+ uri = group && group.currentResource && group.currentResource.uri,
680
+ } = resource;
681
+ if (group && uri) {
682
+ await group.split(EditorGroupSplitAction.Left, uri, { focus: true });
683
+ }
684
+ },
685
+ });
686
+
687
+ commands.registerCommand(EDITOR_COMMANDS.SPLIT_TO_RIGHT, {
688
+ execute: async (resource: ResourceArgs | URI, editorGroup?: EditorGroup) => {
689
+ const { group, uri } = this.extractGroupAndUriFromArgs(resource, editorGroup);
690
+ if (group && uri) {
691
+ await group.split(EditorGroupSplitAction.Right, uri, { focus: true });
692
+ }
693
+ },
694
+ });
695
+
696
+ commands.registerCommand(EDITOR_COMMANDS.GO_TO_GROUP, {
697
+ execute: async (index = 1) => {
698
+ const group = this.workbenchEditorService.sortedEditorGroups[index - 1];
699
+ if (group) {
700
+ group.focus();
701
+ return;
702
+ }
703
+
704
+ // 如果找的索引比 editorGroups 的数量大1,就向右拆分一个
705
+ const groupLength = this.workbenchEditorService.sortedEditorGroups.length;
706
+ if (groupLength === index - 1) {
707
+ const rightEditorGroup = this.workbenchEditorService.sortedEditorGroups[groupLength - 1];
708
+ const uri = rightEditorGroup?.currentResource?.uri;
709
+
710
+ if (rightEditorGroup && uri) {
711
+ await rightEditorGroup.split(EditorGroupSplitAction.Right, uri, { focus: true });
712
+ }
713
+ }
714
+ },
715
+ });
716
+
717
+ commands.registerCommand(EDITOR_COMMANDS.MOVE_GROUP, {
718
+ execute: async (direction?: Direction) => {
719
+ if (direction) {
720
+ const group = this.workbenchEditorService.currentEditorGroup;
721
+ if (group) {
722
+ group.grid.move(direction);
723
+ }
724
+ }
725
+ },
726
+ });
727
+
728
+ commands.registerCommand(EDITOR_COMMANDS.FOCUS_ACTIVE_EDITOR_GROUP, {
729
+ execute: async () => {
730
+ const group = this.workbenchEditorService.currentEditorGroup;
731
+ if (group) {
732
+ group.focus();
733
+ }
734
+ },
735
+ });
736
+
737
+ commands.registerCommand(EDITOR_COMMANDS.SPLIT_TO_TOP, {
738
+ execute: async (resource: ResourceArgs) => {
739
+ resource = resource || {};
740
+ const {
741
+ group = this.workbenchEditorService.currentEditorGroup,
742
+ uri = group && group.currentResource && group.currentResource.uri,
743
+ } = resource;
744
+ if (group && uri) {
745
+ await group.split(EditorGroupSplitAction.Top, uri, { focus: true });
746
+ }
747
+ },
748
+ });
749
+
750
+ commands.registerCommand(EDITOR_COMMANDS.SPLIT_TO_BOTTOM, {
751
+ execute: async (resource: ResourceArgs) => {
752
+ resource = resource || {};
753
+ const {
754
+ group = this.workbenchEditorService.currentEditorGroup,
755
+ uri = group && group.currentResource && group.currentResource.uri,
756
+ } = resource;
757
+ if (group && uri) {
758
+ await group.split(EditorGroupSplitAction.Bottom, uri, { focus: true });
759
+ }
760
+ },
761
+ });
762
+
763
+ commands.registerCommand(EDITOR_COMMANDS.CHANGE_LANGUAGE, {
764
+ execute: async (currentLanguageId) => {
765
+ const allLanguages = this.languagesService.languages;
766
+ const allLanguageItems = allLanguages.map((language) => ({
767
+ label: language.name,
768
+ value: language.id,
769
+ description: `(${language.id})`,
770
+ }));
771
+ const targetLanguageId = await this.quickPickService.show(allLanguageItems, {
772
+ placeholder: localize('editor.changeLanguageId'),
773
+ selectIndex: () =>
774
+ allLanguageItems.findIndex(
775
+ (item) => item.value === this.workbenchEditorService.currentCodeEditor?.currentDocumentModel?.languageId,
776
+ ),
777
+ });
778
+ if (targetLanguageId && currentLanguageId !== targetLanguageId) {
779
+ if (this.workbenchEditorService.currentEditor) {
780
+ const currentDocModel = this.workbenchEditorService.currentEditor.currentDocumentModel;
781
+ if (currentDocModel) {
782
+ this.editorDocumentModelService.changeModelOptions(currentDocModel.uri, {
783
+ languageId: targetLanguageId,
784
+ });
785
+ }
786
+ }
787
+ }
788
+ },
789
+ });
790
+
791
+ commands.registerCommand(EDITOR_COMMANDS.CHANGE_ENCODING, {
792
+ execute: async () => {
793
+ // TODO: 这里应该和 vscode 一样,可以 通过编码打开 和 通过编码保存
794
+ // 但目前的磁盘文件对比使用的是文件字符串 md5 对比,导致更改编码时必定触发 diff,因此编码保存无法生效
795
+ // 长期看 md5 应该更改为 mtime 和 size 才更可靠
796
+ const resource = this.workbenchEditorService.currentResource;
797
+ const documentModel = this.workbenchEditorService.currentEditor?.currentDocumentModel;
798
+ if (!resource || !documentModel) {
799
+ return;
800
+ }
801
+
802
+ const configuredEncoding = this.preferenceService.get<string>(
803
+ 'files.encoding',
804
+ 'utf8',
805
+ resource.uri.toString(),
806
+ getLanguageIdFromMonaco(resource.uri)!,
807
+ );
808
+
809
+ const provider = await this.contentRegistry.getProvider(resource.uri);
810
+ const guessedEncoding = await provider?.guessEncoding?.(resource.uri);
811
+
812
+ const currentEncoding = documentModel.encoding;
813
+ let matchIndex: number | undefined;
814
+ const encodingItems: QuickPickItem<string>[] = Object.keys(SUPPORTED_ENCODINGS)
815
+ .sort((k1, k2) => {
816
+ if (k1 === configuredEncoding) {
817
+ return -1;
818
+ } else if (k2 === configuredEncoding) {
819
+ return 1;
820
+ }
821
+ return SUPPORTED_ENCODINGS[k1].order - SUPPORTED_ENCODINGS[k2].order;
822
+ })
823
+ .filter((k) => {
824
+ // 猜测的编码和配置的编码不一致不现实,单独在最上方显示
825
+ if (k === guessedEncoding && guessedEncoding !== configuredEncoding) {
826
+ return false;
827
+ }
828
+ return !SUPPORTED_ENCODINGS[k].encodeOnly; // 对于只用于 encode 编码不展示
829
+ })
830
+ .map((key, index) => {
831
+ if (key === currentEncoding || SUPPORTED_ENCODINGS[key].alias === currentEncoding) {
832
+ matchIndex = index;
833
+ }
834
+ return { label: SUPPORTED_ENCODINGS[key].labelLong, value: key, description: key };
835
+ });
836
+
837
+ // Insert guessed encoding
838
+ if (guessedEncoding && configuredEncoding !== guessedEncoding && SUPPORTED_ENCODINGS[guessedEncoding]) {
839
+ if (encodingItems[0]) {
840
+ encodingItems[0].showBorder = true;
841
+ }
842
+ encodingItems.unshift({
843
+ label: SUPPORTED_ENCODINGS[guessedEncoding].labelLong,
844
+ value: guessedEncoding,
845
+ description: localize('editor.guessEncodingFromContent'),
846
+ });
847
+ if (typeof matchIndex === 'number') {
848
+ matchIndex++;
849
+ }
850
+ }
851
+
852
+ const selectedFileEncoding = await this.quickPickService.show(encodingItems, {
853
+ placeholder: localize('editor.chooseEncoding'),
854
+ selectIndex(lookFor) {
855
+ if (!lookFor) {
856
+ return typeof matchIndex === 'number' ? matchIndex : -1;
857
+ }
858
+ return -1;
859
+ },
860
+ });
861
+
862
+ if (!selectedFileEncoding) {
863
+ return;
864
+ }
865
+
866
+ const uris =
867
+ resource.uri.scheme === 'diff' ? [resource.metadata.original, resource.metadata.modified] : [resource.uri];
868
+ uris.forEach((uri) => {
869
+ this.editorDocumentModelService.changeModelOptions(uri, {
870
+ encoding: selectedFileEncoding,
871
+ });
872
+ });
873
+ },
874
+ });
875
+
876
+ commands.registerCommand(EDITOR_COMMANDS.CHANGE_EOL, {
877
+ execute: async () => {
878
+ const resource = this.workbenchEditorService.currentResource;
879
+ const currentCodeEditor = this.workbenchEditorService.currentCodeEditor;
880
+ if (currentCodeEditor && currentCodeEditor.currentDocumentModel && resource) {
881
+ const res: EOL | undefined = await this.quickPickService.show(
882
+ [
883
+ { label: 'LF', value: EOL.LF },
884
+ { label: 'CRLF', value: EOL.CRLF },
885
+ ],
886
+ {
887
+ placeholder: localize('editor.changeEol'),
888
+ selectIndex: () => (currentCodeEditor.currentDocumentModel!.eol === EOL.LF ? 0 : 1),
889
+ },
890
+ );
891
+ if (res) {
892
+ this.editorDocumentModelService.changeModelOptions(resource.uri, {
893
+ eol: res,
894
+ });
895
+ }
896
+ }
897
+ },
898
+ });
899
+
900
+ commands.registerCommand(EDITOR_COMMANDS.FOCUS, {
901
+ execute: async () => {
902
+ if (this.workbenchEditorService.currentEditor) {
903
+ this.workbenchEditorService.currentEditor.monacoEditor.focus();
904
+ }
905
+ },
906
+ });
907
+
908
+ commands.registerCommand(EDITOR_COMMANDS.NAVIGATE_NEXT, {
909
+ execute: async () => {
910
+ let i = this.workbenchEditorService.currentEditorGroup.index + 1;
911
+ if (this.workbenchEditorService.editorGroups.length <= i) {
912
+ i = 0;
913
+ }
914
+ return this.workbenchEditorService.sortedEditorGroups[i].focus();
915
+ },
916
+ });
917
+
918
+ commands.registerCommand(EDITOR_COMMANDS.NAVIGATE_PREVIOUS, {
919
+ execute: async () => {
920
+ let i = this.workbenchEditorService.currentEditorGroup.index - 1;
921
+ if (i < 0) {
922
+ i = this.workbenchEditorService.editorGroups.length - 1;
923
+ }
924
+ return this.workbenchEditorService.sortedEditorGroups[i].focus();
925
+ },
926
+ });
927
+
928
+ commands.registerCommand(EDITOR_COMMANDS.NAVIGATE_UP, {
929
+ execute: async () => {
930
+ const currentGrid = this.workbenchEditorService.currentEditorGroup.grid;
931
+ const targetGrid = currentGrid.findGird(Direction.UP);
932
+ if (targetGrid) {
933
+ return (targetGrid.editorGroup! as EditorGroup).focus();
934
+ }
935
+ },
936
+ });
937
+
938
+ commands.registerCommand(EDITOR_COMMANDS.NAVIGATE_DOWN, {
939
+ execute: async () => {
940
+ const currentGrid = this.workbenchEditorService.currentEditorGroup.grid;
941
+ const targetGrid = currentGrid.findGird(Direction.DOWN);
942
+ if (targetGrid) {
943
+ return (targetGrid.editorGroup! as EditorGroup).focus();
944
+ }
945
+ },
946
+ });
947
+
948
+ commands.registerCommand(EDITOR_COMMANDS.NAVIGATE_LEFT, {
949
+ execute: async () => {
950
+ const currentGrid = this.workbenchEditorService.currentEditorGroup.grid;
951
+ const targetGrid = currentGrid.findGird(Direction.LEFT);
952
+ if (targetGrid) {
953
+ return (targetGrid.editorGroup! as EditorGroup).focus();
954
+ }
955
+ },
956
+ });
957
+
958
+ commands.registerCommand(EDITOR_COMMANDS.NAVIGATE_RIGHT, {
959
+ execute: async () => {
960
+ const currentGrid = this.workbenchEditorService.currentEditorGroup.grid;
961
+ const targetGrid = currentGrid.findGird(Direction.RIGHT);
962
+ if (targetGrid) {
963
+ return (targetGrid.editorGroup! as EditorGroup).focus();
964
+ }
965
+ },
966
+ });
967
+
968
+ commands.registerCommand(EDITOR_COMMANDS.PREVIOUS_IN_GROUP, {
969
+ execute: async () => {
970
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
971
+ if (!editorGroup.currentResource) {
972
+ return;
973
+ }
974
+ const index = editorGroup.resources.findIndex((r) => r.uri.isEqual(editorGroup.currentResource!.uri)) - 1;
975
+ if (editorGroup.resources[index]) {
976
+ return editorGroup.open(editorGroup.resources[index].uri, { focus: true });
977
+ } else {
978
+ return editorGroup.open(editorGroup.resources[0].uri, { focus: true });
979
+ }
980
+ },
981
+ });
982
+
983
+ commands.registerCommand(EDITOR_COMMANDS.NEXT_IN_GROUP, {
984
+ execute: async () => {
985
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
986
+ if (!editorGroup.currentResource) {
987
+ return;
988
+ }
989
+ const index = editorGroup.resources.findIndex((r) => r.uri.isEqual(editorGroup.currentResource!.uri)) + 1;
990
+ if (editorGroup.resources[index]) {
991
+ return editorGroup.open(editorGroup.resources[index].uri, { focus: true });
992
+ } else {
993
+ return editorGroup.open(editorGroup.resources[editorGroup.resources.length - 1].uri, { focus: true });
994
+ }
995
+ },
996
+ });
997
+
998
+ commands.registerCommand(EDITOR_COMMANDS.NEXT, {
999
+ execute: async () => {
1000
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
1001
+ if (!editorGroup.currentResource) {
1002
+ return;
1003
+ }
1004
+ const index = editorGroup.resources.findIndex((r) => r.uri.isEqual(editorGroup.currentResource!.uri)) + 1;
1005
+ if (editorGroup.resources[index]) {
1006
+ return editorGroup.open(editorGroup.resources[index].uri, { focus: true });
1007
+ } else {
1008
+ const nextEditorGroupIndex =
1009
+ editorGroup.index === this.workbenchEditorService.editorGroups.length - 1 ? 0 : editorGroup.index + 1;
1010
+ const nextEditorGroup = this.workbenchEditorService.sortedEditorGroups[nextEditorGroupIndex];
1011
+ nextEditorGroup.focus();
1012
+ return nextEditorGroup.open(nextEditorGroup.resources[0].uri, { focus: true });
1013
+ }
1014
+ },
1015
+ });
1016
+
1017
+ commands.registerCommand(EDITOR_COMMANDS.PREVIOUS, {
1018
+ execute: async () => {
1019
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
1020
+ if (!editorGroup.currentResource) {
1021
+ return;
1022
+ }
1023
+ const index = editorGroup.resources.findIndex((r) => r.uri.isEqual(editorGroup.currentResource!.uri)) - 1;
1024
+ if (editorGroup.resources[index]) {
1025
+ return editorGroup.open(editorGroup.resources[index].uri, { focus: true });
1026
+ } else {
1027
+ const nextEditorGroupIndex =
1028
+ editorGroup.index === 0 ? this.workbenchEditorService.editorGroups.length - 1 : editorGroup.index - 1;
1029
+ const nextEditorGroup = this.workbenchEditorService.sortedEditorGroups[nextEditorGroupIndex];
1030
+ nextEditorGroup.focus();
1031
+ return nextEditorGroup.open(nextEditorGroup.resources[nextEditorGroup.resources.length - 1].uri, {
1032
+ focus: true,
1033
+ });
1034
+ }
1035
+ },
1036
+ });
1037
+
1038
+ commands.registerCommand(EDITOR_COMMANDS.LAST_IN_GROUP, {
1039
+ execute: async () => {
1040
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
1041
+ if (editorGroup.resources.length > 0) {
1042
+ return editorGroup.open(editorGroup.resources[editorGroup.resources.length - 1].uri, { focus: true });
1043
+ }
1044
+ },
1045
+ });
1046
+
1047
+ commands.registerCommand(EDITOR_COMMANDS.EVEN_EDITOR_GROUPS, {
1048
+ execute: async () => {
1049
+ const eventBus: IEventBus = this.injector.get(IEventBus);
1050
+ eventBus.fire(new EditorGroupsResetSizeEvent());
1051
+ },
1052
+ });
1053
+
1054
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE_OTHER_GROUPS, {
1055
+ execute: async () => {
1056
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
1057
+ const groupsToClose = this.workbenchEditorService.editorGroups.filter((e) => e !== editorGroup);
1058
+ groupsToClose.forEach((g) => {
1059
+ g.dispose();
1060
+ });
1061
+ },
1062
+ });
1063
+
1064
+ commands.registerCommand(EDITOR_COMMANDS.OPEN_EDITOR_AT_INDEX, {
1065
+ execute: async (index) => {
1066
+ const editorGroup = this.workbenchEditorService.currentEditorGroup;
1067
+ const target = editorGroup.resources[index];
1068
+ if (target) {
1069
+ await editorGroup.open(target.uri, { focus: true });
1070
+ }
1071
+ },
1072
+ });
1073
+
1074
+ commands.registerCommand(EDITOR_COMMANDS.REVERT_DOCUMENT, {
1075
+ execute: async () => {
1076
+ const group = this.workbenchEditorService.currentEditorGroup;
1077
+ if (group.isCodeEditorMode()) {
1078
+ const documentModel = group.codeEditor.currentDocumentModel;
1079
+ if (documentModel) {
1080
+ await documentModel.revert();
1081
+ }
1082
+ }
1083
+ },
1084
+ });
1085
+
1086
+ commands.registerCommand(EDITOR_COMMANDS.REVERT_AND_CLOSE, {
1087
+ execute: async () => {
1088
+ const group = this.workbenchEditorService.currentEditorGroup;
1089
+ if (group.isCodeEditorMode()) {
1090
+ const documentModel = group.codeEditor.currentDocumentModel;
1091
+ if (documentModel) {
1092
+ await documentModel.revert();
1093
+ }
1094
+ group.close(group.currentResource!.uri);
1095
+ }
1096
+ },
1097
+ });
1098
+
1099
+ commands.registerCommand(EDITOR_COMMANDS.SAVE_ALL, {
1100
+ execute: async (reason?: SaveReason) => {
1101
+ this.workbenchEditorService.saveAll(undefined, reason);
1102
+ },
1103
+ });
1104
+
1105
+ commands.registerCommand(EDITOR_COMMANDS.CLOSE_ALL, {
1106
+ execute: async (uri?: URI) => {
1107
+ this.workbenchEditorService.closeAll(uri);
1108
+ },
1109
+ });
1110
+
1111
+ commands.registerCommand(EDITOR_COMMANDS.REOPEN_CLOSED, {
1112
+ execute: async () => {
1113
+ this.historyService.popClosed();
1114
+ },
1115
+ });
1116
+
1117
+ commands.registerCommand(EDITOR_COMMANDS.NEW_UNTITLED_FILE, {
1118
+ execute: () => {
1119
+ this.workbenchEditorService.createUntitledResource();
1120
+ },
1121
+ });
1122
+
1123
+ commands.registerCommand(EDITOR_COMMANDS.COMPONENT_UNDO, {
1124
+ execute: () => {
1125
+ this.workbenchEditorService.currentEditorGroup.componentUndo();
1126
+ },
1127
+ });
1128
+
1129
+ commands.registerCommand(EDITOR_COMMANDS.COMPONENT_REDO, {
1130
+ execute: () => {
1131
+ this.workbenchEditorService.currentEditorGroup.componentRedo();
1132
+ },
1133
+ });
1134
+
1135
+ commands.registerCommand(EDITOR_COMMANDS.TEST_TOKENIZE, {
1136
+ execute: () => {
1137
+ const currentCodeEditor = this.workbenchEditorService.currentCodeEditor;
1138
+ if (currentCodeEditor) {
1139
+ const selections = currentCodeEditor.getSelections();
1140
+ if (selections && selections.length > 0 && currentCodeEditor.currentDocumentModel) {
1141
+ const { selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn } =
1142
+ selections[0];
1143
+ const selectionText = currentCodeEditor.currentDocumentModel.getText(
1144
+ new monaco.Range(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn),
1145
+ );
1146
+
1147
+ this.monacoService.testTokenize(selectionText, currentCodeEditor.currentDocumentModel.languageId);
1148
+ }
1149
+ }
1150
+ },
1151
+ });
1152
+
1153
+ commands.registerCommand(EDITOR_COMMANDS.SEARCH_WORKSPACE_SYMBOL, {
1154
+ execute: () => this.prefixQuickOpenService.open('#'),
1155
+ });
1156
+ commands.registerCommand(EDITOR_COMMANDS.SEARCH_WORKSPACE_SYMBOL_CLASS, {
1157
+ execute: () => this.prefixQuickOpenService.open('##'),
1158
+ });
1159
+ commands.registerCommand(EDITOR_COMMANDS.GO_TO_LINE, {
1160
+ execute: () => this.prefixQuickOpenService.open(':'),
1161
+ });
1162
+
1163
+ commands.registerCommand(EDITOR_COMMANDS.TOGGLE_WORD_WRAP, {
1164
+ execute: () => {
1165
+ const wordWrap = this.preferenceService.get<string>('editor.wordWrap');
1166
+
1167
+ if (wordWrap) {
1168
+ const values: string[] = ['off', 'on'];
1169
+ const index = values.indexOf(wordWrap) + 1;
1170
+ if (index > -1) {
1171
+ this.preferenceService.set('editor.wordWrap', values[index % values.length], PreferenceScope.User);
1172
+ }
1173
+ }
1174
+ },
1175
+ });
1176
+
1177
+ commands.registerCommand(EDITOR_COMMANDS.FORMAT_DOCUMENT_WITH, {
1178
+ execute: async () => {
1179
+ const formatService = this.injector.get(DocumentFormatService);
1180
+ formatService.formatDocumentWith();
1181
+ },
1182
+ });
1183
+
1184
+ commands.registerCommand(EDITOR_COMMANDS.FORMAT_SELECTION_WITH, {
1185
+ execute: async () => {
1186
+ const formatService = this.injector.get(DocumentFormatService);
1187
+ formatService.formatSelectionWith();
1188
+ },
1189
+ });
1190
+ }
1191
+
1192
+ registerMenus(menus: IMenuRegistry) {
1193
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1194
+ command: EDITOR_COMMANDS.COPY_PATH.id,
1195
+ group: '10_path',
1196
+ order: 1,
1197
+ });
1198
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1199
+ command: EDITOR_COMMANDS.COPY_RELATIVE_PATH.id,
1200
+ group: '10_path',
1201
+ order: 2,
1202
+ });
1203
+
1204
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1205
+ command: EDITOR_COMMANDS.SPLIT_TO_LEFT.id,
1206
+ group: '9_split',
1207
+ });
1208
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1209
+ command: EDITOR_COMMANDS.SPLIT_TO_RIGHT.id,
1210
+ group: '9_split',
1211
+ });
1212
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1213
+ command: EDITOR_COMMANDS.SPLIT_TO_TOP.id,
1214
+ group: '9_split',
1215
+ });
1216
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1217
+ command: EDITOR_COMMANDS.SPLIT_TO_BOTTOM.id,
1218
+ group: '9_split',
1219
+ });
1220
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1221
+ command: {
1222
+ id: EDITOR_COMMANDS.CLOSE.id,
1223
+ label: localize('editor.title.context.close'),
1224
+ },
1225
+ group: '0_tab',
1226
+ order: 1,
1227
+ });
1228
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1229
+ command: EDITOR_COMMANDS.CLOSE_ALL_IN_GROUP.id,
1230
+ group: '0_tab',
1231
+ order: 2,
1232
+ });
1233
+
1234
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1235
+ command: EDITOR_COMMANDS.CLOSE_SAVED.id,
1236
+ group: '0_tab',
1237
+ order: 3,
1238
+ });
1239
+
1240
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1241
+ command: EDITOR_COMMANDS.CLOSE_OTHER_IN_GROUP.id,
1242
+ group: '0_tab',
1243
+ order: 4,
1244
+ });
1245
+
1246
+ menus.registerMenuItem(MenuId.EditorTitleContext, {
1247
+ command: EDITOR_COMMANDS.CLOSE_TO_RIGHT.id,
1248
+ group: '0_tab',
1249
+ order: 5,
1250
+ });
1251
+
1252
+ menus.registerMenuItem(MenuId.EditorTitle, {
1253
+ command: EDITOR_COMMANDS.CLOSE_ALL_IN_GROUP.id,
1254
+ group: '0_internal',
1255
+ });
1256
+
1257
+ menus.registerMenuItem(MenuId.EditorTitle, {
1258
+ command: EDITOR_COMMANDS.SPLIT_TO_RIGHT.id,
1259
+ group: 'navigation',
1260
+ when: 'resource',
1261
+ order: 5,
1262
+ });
1263
+
1264
+ menus.registerMenuItem(MenuId.EditorContext, {
1265
+ command: EDITOR_COMMANDS.FORMAT_DOCUMENT_WITH.id,
1266
+ group: '1_modification',
1267
+ order: 1.3,
1268
+ when: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasMultipleDocumentFormattingProvider),
1269
+ });
1270
+
1271
+ menus.registerMenuItem(MenuId.EditorContext, {
1272
+ command: EDITOR_COMMANDS.FORMAT_SELECTION_WITH.id,
1273
+ when: ContextKeyExpr.and(
1274
+ EditorContextKeys.writable,
1275
+ EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider,
1276
+ EditorContextKeys.hasNonEmptySelection,
1277
+ ),
1278
+ group: '1_modification',
1279
+ order: 1.31,
1280
+ });
1281
+ }
1282
+
1283
+ registerOpener(regisry: IOpenerService) {
1284
+ regisry.registerOpener(this.editorOpener);
1285
+ }
1286
+
1287
+ registerQuickOpenHandlers(handlers: IQuickOpenHandlerRegistry): void {
1288
+ handlers.registerHandler(this.workspaceSymbolQuickOpenHandler, {
1289
+ title: localize('quickopen.tab.symbol'),
1290
+ order: 3,
1291
+ commandId: EDITOR_COMMANDS.SEARCH_WORKSPACE_SYMBOL.id,
1292
+ sub: {
1293
+ // 将类单独作为一个 tab,Java 场景比较常见,其它技术栈可能不一定
1294
+ '#': {
1295
+ title: localize('quickopen.tab.class'),
1296
+ order: 2,
1297
+ commandId: EDITOR_COMMANDS.SEARCH_WORKSPACE_SYMBOL_CLASS.id,
1298
+ },
1299
+ },
1300
+ });
1301
+ handlers.registerHandler(this.goToLineQuickOpenHandler, {
1302
+ title: localize('quickopen.tab.goToLine'),
1303
+ commandId: EDITOR_COMMANDS.GO_TO_LINE.id,
1304
+ order: 5,
1305
+ });
1306
+ }
1307
+ }
1308
+
1309
+ @Domain(BrowserEditorContribution, CommandContribution)
1310
+ export class EditorAutoSaveEditorContribution implements BrowserEditorContribution, CommandContribution {
1311
+ @Autowired(INJECTOR_TOKEN)
1312
+ injector: Injector;
1313
+
1314
+ @Autowired(PreferenceService)
1315
+ preferenceService: PreferenceService;
1316
+
1317
+ @Autowired(WorkbenchEditorService)
1318
+ private workbenchEditorService: WorkbenchEditorServiceImpl;
1319
+
1320
+ @Autowired(CommandService)
1321
+ commandService: CommandService;
1322
+
1323
+ @Autowired(IEditorDocumentModelService)
1324
+ editorDocumentService: IEditorDocumentModelService;
1325
+
1326
+ @Autowired(IPreferenceSettingsService)
1327
+ preferenceSettings: IPreferenceSettingsService;
1328
+
1329
+ registerEditorFeature(registry: IEditorFeatureRegistry) {
1330
+ registry.registerEditorFeatureContribution({
1331
+ contribute: (editor: IEditor) => {
1332
+ const disposable = new Disposable();
1333
+ disposable.addDispose(
1334
+ editor.monacoEditor.onDidBlurEditorWidget(() => {
1335
+ if (this.preferenceService.get('editor.autoSave') === AUTO_SAVE_MODE.EDITOR_FOCUS_CHANGE) {
1336
+ if (
1337
+ editor.currentDocumentModel &&
1338
+ !editor.currentDocumentModel.closeAutoSave &&
1339
+ editor.currentDocumentModel.dirty &&
1340
+ editor.currentDocumentModel.savable
1341
+ ) {
1342
+ editor.currentDocumentModel.save(undefined, SaveReason.FocusOut);
1343
+ }
1344
+ }
1345
+ }),
1346
+ );
1347
+ disposable.addDispose(
1348
+ editor.monacoEditor.onDidChangeModel((e) => {
1349
+ if (this.preferenceService.get('editor.autoSave') === AUTO_SAVE_MODE.EDITOR_FOCUS_CHANGE) {
1350
+ if (e.oldModelUrl) {
1351
+ const oldUri = new URI(e.oldModelUrl.toString());
1352
+ const docRef = this.editorDocumentService.getModelReference(oldUri, 'editor-focus-autosave');
1353
+ if (docRef && !docRef.instance.closeAutoSave && docRef.instance.dirty && docRef.instance.savable) {
1354
+ docRef.instance.save(undefined, SaveReason.FocusOut);
1355
+ }
1356
+ docRef?.dispose();
1357
+ }
1358
+ }
1359
+ }),
1360
+ );
1361
+ return disposable;
1362
+ },
1363
+ });
1364
+ window.addEventListener('blur', () => {
1365
+ if (this.preferenceService.get('editor.autoSave') === AUTO_SAVE_MODE.WINDOWS_LOST_FOCUS) {
1366
+ this.commandService.executeCommand(EDITOR_COMMANDS.SAVE_ALL.id, SaveReason.FocusOut);
1367
+ }
1368
+ });
1369
+ this.preferenceSettings.setEnumLabels('editor.autoSave', {
1370
+ [AUTO_SAVE_MODE.OFF]: localize('editor.autoSave.enum.off'),
1371
+ [AUTO_SAVE_MODE.AFTER_DELAY]: localize('editor.autoSave.enum.afterDelay'),
1372
+ [AUTO_SAVE_MODE.EDITOR_FOCUS_CHANGE]: localize('editor.autoSave.enum.editorFocusChange'),
1373
+ [AUTO_SAVE_MODE.WINDOWS_LOST_FOCUS]: localize('editor.autoSave.enum.windowLostFocus'),
1374
+ });
1375
+ registry.registerEditorFeatureContribution(new EditorTopPaddingContribution());
1376
+ registry.registerEditorFeatureContribution(this.injector.get(EditorSuggestWidgetContribution));
1377
+ this.registerAutoSaveConfigurationChange();
1378
+ }
1379
+
1380
+ registerAutoSaveConfigurationChange() {
1381
+ this.preferenceService.onSpecificPreferenceChange('editor.autoSave', (change) => {
1382
+ const mode = change.newValue;
1383
+ if (mode !== AUTO_SAVE_MODE.OFF) {
1384
+ // 只有两种原因:丢失焦点和延迟保存,非此即彼
1385
+ let reason = SaveReason.FocusOut;
1386
+ if (mode === AUTO_SAVE_MODE.AFTER_DELAY) {
1387
+ reason = SaveReason.AfterDelay;
1388
+ }
1389
+ // 只保存被该设置影响的文档
1390
+ // 比如在当前工作区写代码,然后打开了一个 ~/.xxx 文件
1391
+ // 然后用户修改了设置,这里就只保存当前工作区的文件。
1392
+ for (const group of this.workbenchEditorService.editorGroups) {
1393
+ for (const resource of group.resources) {
1394
+ if (change.affects(resource?.uri.toString())) {
1395
+ group.saveResource(resource, reason);
1396
+ }
1397
+ }
1398
+ }
1399
+ }
1400
+ });
1401
+ }
1402
+
1403
+ registerCommands(commands: CommandRegistry): void {
1404
+ commands.registerCommand(EDITOR_COMMANDS.AUTO_SAVE, {
1405
+ execute: () => {
1406
+ const autoSavePreferenceField = 'editor.autoSave';
1407
+ const value =
1408
+ (this.preferenceSettings.getPreference(autoSavePreferenceField, PreferenceScope.User).value as string) ||
1409
+ AUTO_SAVE_MODE.OFF;
1410
+ const nextValue = [
1411
+ AUTO_SAVE_MODE.AFTER_DELAY,
1412
+ AUTO_SAVE_MODE.EDITOR_FOCUS_CHANGE,
1413
+ AUTO_SAVE_MODE.WINDOWS_LOST_FOCUS,
1414
+ ].includes(value)
1415
+ ? AUTO_SAVE_MODE.OFF
1416
+ : AUTO_SAVE_MODE.AFTER_DELAY;
1417
+
1418
+ return this.preferenceSettings.setPreference(autoSavePreferenceField, nextValue, PreferenceScope.User);
1419
+ },
1420
+ });
1421
+ commands.registerCommand(EDITOR_COMMANDS.COPY_PATH, {
1422
+ execute: (resource: ResourceArgs) => {
1423
+ if (!resource) {
1424
+ return;
1425
+ }
1426
+ this.commandService.executeCommand(FILE_COMMANDS.COPY_PATH.id, resource.uri);
1427
+ },
1428
+ });
1429
+ commands.registerCommand(EDITOR_COMMANDS.COPY_RELATIVE_PATH, {
1430
+ execute: (resource: ResourceArgs) => {
1431
+ if (!resource) {
1432
+ return;
1433
+ }
1434
+ this.commandService.executeCommand(FILE_COMMANDS.COPY_RELATIVE_PATH.id, resource.uri);
1435
+ },
1436
+ });
1437
+ }
1438
+ }