@theia/editor 1.53.0-next.55 → 1.53.0-next.64

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 (42) hide show
  1. package/README.md +30 -30
  2. package/lib/browser/editor-manager.d.ts.map +1 -1
  3. package/lib/browser/editor-manager.js +2 -4
  4. package/lib/browser/editor-manager.js.map +1 -1
  5. package/lib/browser/navigation/navigation-location-service.js +3 -3
  6. package/package.json +4 -4
  7. package/src/browser/decorations/editor-decoration-style.ts +41 -41
  8. package/src/browser/decorations/editor-decoration.ts +127 -127
  9. package/src/browser/decorations/editor-decorator.ts +36 -36
  10. package/src/browser/decorations/index.ts +19 -19
  11. package/src/browser/diff-navigator.ts +27 -27
  12. package/src/browser/editor-command.ts +393 -393
  13. package/src/browser/editor-contribution.ts +185 -185
  14. package/src/browser/editor-frontend-module.ts +90 -90
  15. package/src/browser/editor-generated-preference-schema.ts +2956 -2956
  16. package/src/browser/editor-keybinding.ts +55 -55
  17. package/src/browser/editor-language-quick-pick-service.ts +68 -68
  18. package/src/browser/editor-linenumber-contribution.ts +88 -88
  19. package/src/browser/editor-manager.ts +460 -462
  20. package/src/browser/editor-menu.ts +224 -224
  21. package/src/browser/editor-navigation-contribution.ts +343 -343
  22. package/src/browser/editor-preferences.ts +226 -226
  23. package/src/browser/editor-variable-contribution.ts +62 -62
  24. package/src/browser/editor-widget-factory.ts +82 -82
  25. package/src/browser/editor-widget.ts +139 -139
  26. package/src/browser/editor.ts +366 -366
  27. package/src/browser/index.ts +26 -26
  28. package/src/browser/language-status/editor-language-status-service.ts +271 -271
  29. package/src/browser/language-status/editor-language-status.css +101 -101
  30. package/src/browser/navigation/navigation-location-service.spec.ts +245 -245
  31. package/src/browser/navigation/navigation-location-service.ts +284 -284
  32. package/src/browser/navigation/navigation-location-similarity.spec.ts +46 -46
  33. package/src/browser/navigation/navigation-location-similarity.ts +58 -58
  34. package/src/browser/navigation/navigation-location-updater.spec.ts +197 -197
  35. package/src/browser/navigation/navigation-location-updater.ts +220 -220
  36. package/src/browser/navigation/navigation-location.ts +418 -418
  37. package/src/browser/navigation/test/mock-navigation-location-updater.ts +41 -41
  38. package/src/browser/quick-editor-service.ts +94 -94
  39. package/src/browser/style/index.css +19 -19
  40. package/src/browser/undo-redo-service.ts +120 -120
  41. package/src/common/language-selector.ts +104 -104
  42. package/src/package.spec.ts +28 -28
@@ -1,393 +1,393 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2017 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import { inject, injectable, optional, postConstruct } from '@theia/core/shared/inversify';
18
- import { CommonCommands, PreferenceService, LabelProvider, ApplicationShell, QuickInputService, QuickPickValue, SaveableService } from '@theia/core/lib/browser';
19
- import { EditorManager } from './editor-manager';
20
- import { CommandContribution, CommandRegistry, Command, ResourceProvider, MessageService, nls } from '@theia/core';
21
- import { LanguageService } from '@theia/core/lib/browser/language-service';
22
- import { SUPPORTED_ENCODINGS } from '@theia/core/lib/browser/supported-encodings';
23
- import { EncodingMode } from './editor';
24
- import { EditorLanguageQuickPickService } from './editor-language-quick-pick-service';
25
-
26
- export namespace EditorCommands {
27
-
28
- const EDITOR_CATEGORY = 'Editor';
29
- const EDITOR_CATEGORY_KEY = nls.getDefaultKey(EDITOR_CATEGORY);
30
-
31
- export const GOTO_LINE_COLUMN = Command.toDefaultLocalizedCommand({
32
- id: 'editor.action.gotoLine',
33
- label: 'Go to Line/Column'
34
- });
35
-
36
- /**
37
- * Show editor references
38
- */
39
- export const SHOW_REFERENCES: Command = {
40
- id: 'textEditor.commands.showReferences'
41
- };
42
- /**
43
- * Change indentation configuration (i.e., indent using tabs / spaces, and how many spaces per tab)
44
- */
45
- export const CONFIG_INDENTATION: Command = {
46
- id: 'textEditor.commands.configIndentation'
47
- };
48
-
49
- export const CONFIG_EOL = Command.toDefaultLocalizedCommand({
50
- id: 'textEditor.commands.configEol',
51
- category: EDITOR_CATEGORY,
52
- label: 'Change End of Line Sequence'
53
- });
54
-
55
- export const INDENT_USING_SPACES = Command.toDefaultLocalizedCommand({
56
- id: 'textEditor.commands.indentUsingSpaces',
57
- category: EDITOR_CATEGORY,
58
- label: 'Indent Using Spaces'
59
- });
60
- export const INDENT_USING_TABS = Command.toDefaultLocalizedCommand({
61
- id: 'textEditor.commands.indentUsingTabs',
62
- category: EDITOR_CATEGORY,
63
- label: 'Indent Using Tabs'
64
- });
65
- export const CHANGE_LANGUAGE = Command.toDefaultLocalizedCommand({
66
- id: 'textEditor.change.language',
67
- category: EDITOR_CATEGORY,
68
- label: 'Change Language Mode'
69
- });
70
- export const CHANGE_ENCODING = Command.toDefaultLocalizedCommand({
71
- id: 'textEditor.change.encoding',
72
- category: EDITOR_CATEGORY,
73
- label: 'Change File Encoding'
74
- });
75
- export const REVERT_EDITOR = Command.toDefaultLocalizedCommand({
76
- id: 'workbench.action.files.revert',
77
- category: CommonCommands.FILE_CATEGORY,
78
- label: 'Revert File',
79
- });
80
- export const REVERT_AND_CLOSE = Command.toDefaultLocalizedCommand({
81
- id: 'workbench.action.revertAndCloseActiveEditor',
82
- category: CommonCommands.VIEW_CATEGORY,
83
- label: 'Revert and Close Editor'
84
- });
85
-
86
- /**
87
- * Command for going back to the last editor navigation location.
88
- */
89
- export const GO_BACK = Command.toDefaultLocalizedCommand({
90
- id: 'textEditor.commands.go.back',
91
- category: EDITOR_CATEGORY,
92
- label: 'Go Back'
93
- });
94
- /**
95
- * Command for going to the forthcoming editor navigation location.
96
- */
97
- export const GO_FORWARD = Command.toDefaultLocalizedCommand({
98
- id: 'textEditor.commands.go.forward',
99
- category: EDITOR_CATEGORY,
100
- label: 'Go Forward'
101
- });
102
- /**
103
- * Command that reveals the last text edit location, if any.
104
- */
105
- export const GO_LAST_EDIT = Command.toDefaultLocalizedCommand({
106
- id: 'textEditor.commands.go.lastEdit',
107
- category: EDITOR_CATEGORY,
108
- label: 'Go to Last Edit Location'
109
- });
110
- /**
111
- * Command that clears the editor navigation history.
112
- */
113
- export const CLEAR_EDITOR_HISTORY = Command.toDefaultLocalizedCommand({
114
- id: 'textEditor.commands.clear.history',
115
- category: EDITOR_CATEGORY,
116
- label: 'Clear Editor History'
117
- });
118
- /**
119
- * Command that displays all editors that are currently opened.
120
- */
121
- export const SHOW_ALL_OPENED_EDITORS = Command.toLocalizedCommand({
122
- id: 'workbench.action.showAllEditors',
123
- category: CommonCommands.VIEW_CATEGORY,
124
- label: 'Show All Opened Editors'
125
- }, 'theia/editor/showAllEditors', EDITOR_CATEGORY_KEY);
126
- /**
127
- * Command that toggles the minimap.
128
- */
129
- export const TOGGLE_MINIMAP = Command.toDefaultLocalizedCommand({
130
- id: 'editor.action.toggleMinimap',
131
- category: CommonCommands.VIEW_CATEGORY,
132
- label: 'Toggle Minimap'
133
- });
134
- /**
135
- * Command that toggles the rendering of whitespace characters in the editor.
136
- */
137
- export const TOGGLE_RENDER_WHITESPACE = Command.toDefaultLocalizedCommand({
138
- id: 'editor.action.toggleRenderWhitespace',
139
- category: CommonCommands.VIEW_CATEGORY,
140
- label: 'Toggle Render Whitespace'
141
- });
142
- /**
143
- * Command that toggles the word wrap.
144
- */
145
- export const TOGGLE_WORD_WRAP = Command.toDefaultLocalizedCommand({
146
- id: 'editor.action.toggleWordWrap',
147
- label: 'View: Toggle Word Wrap'
148
- });
149
- /**
150
- * Command that toggles sticky scroll.
151
- */
152
- export const TOGGLE_STICKY_SCROLL = Command.toLocalizedCommand({
153
- id: 'editor.action.toggleStickyScroll',
154
- category: CommonCommands.VIEW_CATEGORY,
155
- label: 'Toggle Sticky Scroll',
156
- }, 'theia/editor/toggleStickyScroll', EDITOR_CATEGORY_KEY);
157
- /**
158
- * Command that re-opens the last closed editor.
159
- */
160
- export const REOPEN_CLOSED_EDITOR = Command.toDefaultLocalizedCommand({
161
- id: 'workbench.action.reopenClosedEditor',
162
- category: CommonCommands.VIEW_CATEGORY,
163
- label: 'Reopen Closed Editor'
164
- });
165
- /**
166
- * Opens a second instance of the current editor, splitting the view in the direction specified.
167
- */
168
- export const SPLIT_EDITOR_RIGHT = Command.toDefaultLocalizedCommand({
169
- id: 'workbench.action.splitEditorRight',
170
- category: CommonCommands.VIEW_CATEGORY,
171
- label: 'Split Editor Right'
172
- });
173
- export const SPLIT_EDITOR_DOWN = Command.toDefaultLocalizedCommand({
174
- id: 'workbench.action.splitEditorDown',
175
- category: CommonCommands.VIEW_CATEGORY,
176
- label: 'Split Editor Down'
177
- });
178
- export const SPLIT_EDITOR_UP = Command.toDefaultLocalizedCommand({
179
- id: 'workbench.action.splitEditorUp',
180
- category: CommonCommands.VIEW_CATEGORY,
181
- label: 'Split Editor Up'
182
- });
183
- export const SPLIT_EDITOR_LEFT = Command.toDefaultLocalizedCommand({
184
- id: 'workbench.action.splitEditorLeft',
185
- category: CommonCommands.VIEW_CATEGORY,
186
- label: 'Split Editor Left'
187
- });
188
- /**
189
- * Default horizontal split: right.
190
- */
191
- export const SPLIT_EDITOR_HORIZONTAL = Command.toDefaultLocalizedCommand({
192
- id: 'workbench.action.splitEditor',
193
- category: CommonCommands.VIEW_CATEGORY,
194
- label: 'Split Editor'
195
- });
196
- /**
197
- * Default vertical split: down.
198
- */
199
- export const SPLIT_EDITOR_VERTICAL = Command.toDefaultLocalizedCommand({
200
- id: 'workbench.action.splitEditorOrthogonal',
201
- category: CommonCommands.VIEW_CATEGORY,
202
- label: 'Split Editor Orthogonal'
203
- });
204
- }
205
-
206
- @injectable()
207
- export class EditorCommandContribution implements CommandContribution {
208
-
209
- static readonly AUTOSAVE_PREFERENCE: string = 'files.autoSave';
210
- static readonly AUTOSAVE_DELAY_PREFERENCE: string = 'files.autoSaveDelay';
211
-
212
- @inject(ApplicationShell)
213
- protected readonly shell: ApplicationShell;
214
-
215
- @inject(PreferenceService)
216
- protected readonly preferencesService: PreferenceService;
217
-
218
- @inject(SaveableService)
219
- protected readonly saveResourceService: SaveableService;
220
-
221
- @inject(QuickInputService) @optional()
222
- protected readonly quickInputService: QuickInputService;
223
-
224
- @inject(MessageService)
225
- protected readonly messageService: MessageService;
226
-
227
- @inject(LabelProvider)
228
- protected readonly labelProvider: LabelProvider;
229
-
230
- @inject(LanguageService)
231
- protected readonly languages: LanguageService;
232
-
233
- @inject(EditorManager)
234
- protected readonly editorManager: EditorManager;
235
-
236
- @inject(ResourceProvider)
237
- protected readonly resourceProvider: ResourceProvider;
238
-
239
- @inject(EditorLanguageQuickPickService)
240
- protected readonly codeLanguageQuickPickService: EditorLanguageQuickPickService;
241
-
242
- @postConstruct()
243
- protected init(): void {
244
- this.preferencesService.ready.then(() => {
245
- this.saveResourceService.autoSave = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_PREFERENCE) ?? 'off';
246
- this.saveResourceService.autoSaveDelay = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_DELAY_PREFERENCE) ?? 1000;
247
- });
248
- this.preferencesService.onPreferenceChanged(e => {
249
- if (e.preferenceName === EditorCommandContribution.AUTOSAVE_PREFERENCE) {
250
- this.saveResourceService.autoSave = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_PREFERENCE) ?? 'off';
251
- } else if (e.preferenceName === EditorCommandContribution.AUTOSAVE_DELAY_PREFERENCE) {
252
- this.saveResourceService.autoSaveDelay = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_DELAY_PREFERENCE) ?? 1000;
253
- }
254
- });
255
- }
256
-
257
- registerCommands(registry: CommandRegistry): void {
258
- registry.registerCommand(EditorCommands.SHOW_REFERENCES);
259
- registry.registerCommand(EditorCommands.CONFIG_INDENTATION);
260
- registry.registerCommand(EditorCommands.CONFIG_EOL);
261
- registry.registerCommand(EditorCommands.INDENT_USING_SPACES);
262
- registry.registerCommand(EditorCommands.INDENT_USING_TABS);
263
- registry.registerCommand(EditorCommands.REVERT_EDITOR);
264
- registry.registerCommand(EditorCommands.REVERT_AND_CLOSE);
265
- registry.registerCommand(EditorCommands.CHANGE_LANGUAGE, {
266
- isEnabled: () => this.canConfigureLanguage(),
267
- isVisible: () => this.canConfigureLanguage(),
268
- execute: () => this.configureLanguage()
269
- });
270
- registry.registerCommand(EditorCommands.CHANGE_ENCODING, {
271
- isEnabled: () => this.canConfigureEncoding(),
272
- isVisible: () => this.canConfigureEncoding(),
273
- execute: () => this.configureEncoding()
274
- });
275
-
276
- registry.registerCommand(EditorCommands.GO_BACK);
277
- registry.registerCommand(EditorCommands.GO_FORWARD);
278
- registry.registerCommand(EditorCommands.GO_LAST_EDIT);
279
- registry.registerCommand(EditorCommands.CLEAR_EDITOR_HISTORY);
280
- registry.registerCommand(EditorCommands.TOGGLE_MINIMAP);
281
- registry.registerCommand(EditorCommands.TOGGLE_RENDER_WHITESPACE);
282
- registry.registerCommand(EditorCommands.TOGGLE_WORD_WRAP);
283
- registry.registerCommand(EditorCommands.TOGGLE_STICKY_SCROLL);
284
- registry.registerCommand(EditorCommands.REOPEN_CLOSED_EDITOR);
285
-
286
- registry.registerCommand(CommonCommands.AUTO_SAVE, {
287
- isToggled: () => this.isAutoSaveOn(),
288
- execute: () => this.toggleAutoSave()
289
- });
290
- }
291
-
292
- protected canConfigureLanguage(): boolean {
293
- const widget = this.editorManager.currentEditor;
294
- const editor = widget && widget.editor;
295
- return !!editor && !!this.languages.languages;
296
- }
297
- protected async configureLanguage(): Promise<void> {
298
- const widget = this.editorManager.currentEditor;
299
- const editor = widget && widget.editor;
300
- if (!editor || !this.languages.languages) {
301
- return;
302
- }
303
- const current = editor.document.languageId;
304
- const selectedMode = await this.codeLanguageQuickPickService.pickEditorLanguage(current);
305
- if (selectedMode && ('value' in selectedMode)) {
306
- if (selectedMode.value === 'autoDetect') {
307
- editor.detectLanguage();
308
- } else if (selectedMode.value) {
309
- editor.setLanguage(selectedMode.value.id);
310
- }
311
- }
312
- }
313
-
314
- protected canConfigureEncoding(): boolean {
315
- const widget = this.editorManager.currentEditor;
316
- const editor = widget && widget.editor;
317
- return !!editor;
318
- }
319
- protected async configureEncoding(): Promise<void> {
320
- const widget = this.editorManager.currentEditor;
321
- const editor = widget && widget.editor;
322
- if (!editor) {
323
- return;
324
- }
325
- const reopenWithEncodingPick = { label: nls.localizeByDefault('Reopen with Encoding'), value: 'reopen' };
326
- const saveWithEncodingPick = { label: nls.localizeByDefault('Save with Encoding'), value: 'save' };
327
- const actionItems: QuickPickValue<string>[] = [
328
- reopenWithEncodingPick,
329
- saveWithEncodingPick
330
- ];
331
- const selectedEncoding = await this.quickInputService?.showQuickPick(actionItems, { placeholder: nls.localizeByDefault('Select Action') });
332
- if (!selectedEncoding) {
333
- return;
334
- }
335
- const isReopenWithEncoding = (selectedEncoding.value === reopenWithEncodingPick.value);
336
-
337
- const configuredEncoding = this.preferencesService.get<string>('files.encoding', 'utf8', editor.uri.toString());
338
-
339
- const resource = await this.resourceProvider(editor.uri);
340
- const guessedEncoding = resource.guessEncoding ? await resource.guessEncoding() : undefined;
341
- resource.dispose();
342
-
343
- const encodingItems: QuickPickValue<{ id: string, description: string }>[] = Object.keys(SUPPORTED_ENCODINGS)
344
- .sort((k1, k2) => {
345
- if (k1 === configuredEncoding) {
346
- return -1;
347
- } else if (k2 === configuredEncoding) {
348
- return 1;
349
- }
350
- return SUPPORTED_ENCODINGS[k1].order - SUPPORTED_ENCODINGS[k2].order;
351
- })
352
- .filter(k => {
353
- if (k === guessedEncoding && guessedEncoding !== configuredEncoding) {
354
- return false; // do not show encoding if it is the guessed encoding that does not match the configured
355
- }
356
-
357
- return !isReopenWithEncoding || !SUPPORTED_ENCODINGS[k].encodeOnly; // hide those that can only be used for encoding if we are about to decode
358
- })
359
- .map(key => ({ label: SUPPORTED_ENCODINGS[key].labelLong, value: { id: key, description: key } }));
360
-
361
- // Insert guessed encoding
362
- if (guessedEncoding && configuredEncoding !== guessedEncoding && SUPPORTED_ENCODINGS[guessedEncoding]) {
363
- encodingItems.unshift({
364
- label: `${nls.localizeByDefault('Guessed from content')}: ${SUPPORTED_ENCODINGS[guessedEncoding].labelLong}`,
365
- value: { id: guessedEncoding, description: guessedEncoding }
366
- });
367
- }
368
- const selectedFileEncoding = await this.quickInputService?.showQuickPick<QuickPickValue<{ id: string, description: string }>>(encodingItems, {
369
- placeholder: isReopenWithEncoding ?
370
- nls.localizeByDefault('Select File Encoding to Reopen File') :
371
- nls.localizeByDefault('Select File Encoding to Save with')
372
- });
373
-
374
- if (!selectedFileEncoding) {
375
- return;
376
- }
377
- if (editor.document.dirty && isReopenWithEncoding) {
378
- this.messageService.info(nls.localize('theia/editor/dirtyEncoding', 'The file is dirty. Please save it first before reopening it with another encoding.'));
379
- return;
380
- } else if (selectedFileEncoding.value) {
381
- editor.setEncoding(selectedFileEncoding.value.id, isReopenWithEncoding ? EncodingMode.Decode : EncodingMode.Encode);
382
- }
383
- }
384
-
385
- protected isAutoSaveOn(): boolean {
386
- const autoSave = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_PREFERENCE);
387
- return autoSave !== 'off';
388
- }
389
-
390
- protected async toggleAutoSave(): Promise<void> {
391
- this.preferencesService.updateValue(EditorCommandContribution.AUTOSAVE_PREFERENCE, this.isAutoSaveOn() ? 'off' : 'afterDelay');
392
- }
393
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2017 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { inject, injectable, optional, postConstruct } from '@theia/core/shared/inversify';
18
+ import { CommonCommands, PreferenceService, LabelProvider, ApplicationShell, QuickInputService, QuickPickValue, SaveableService } from '@theia/core/lib/browser';
19
+ import { EditorManager } from './editor-manager';
20
+ import { CommandContribution, CommandRegistry, Command, ResourceProvider, MessageService, nls } from '@theia/core';
21
+ import { LanguageService } from '@theia/core/lib/browser/language-service';
22
+ import { SUPPORTED_ENCODINGS } from '@theia/core/lib/browser/supported-encodings';
23
+ import { EncodingMode } from './editor';
24
+ import { EditorLanguageQuickPickService } from './editor-language-quick-pick-service';
25
+
26
+ export namespace EditorCommands {
27
+
28
+ const EDITOR_CATEGORY = 'Editor';
29
+ const EDITOR_CATEGORY_KEY = nls.getDefaultKey(EDITOR_CATEGORY);
30
+
31
+ export const GOTO_LINE_COLUMN = Command.toDefaultLocalizedCommand({
32
+ id: 'editor.action.gotoLine',
33
+ label: 'Go to Line/Column'
34
+ });
35
+
36
+ /**
37
+ * Show editor references
38
+ */
39
+ export const SHOW_REFERENCES: Command = {
40
+ id: 'textEditor.commands.showReferences'
41
+ };
42
+ /**
43
+ * Change indentation configuration (i.e., indent using tabs / spaces, and how many spaces per tab)
44
+ */
45
+ export const CONFIG_INDENTATION: Command = {
46
+ id: 'textEditor.commands.configIndentation'
47
+ };
48
+
49
+ export const CONFIG_EOL = Command.toDefaultLocalizedCommand({
50
+ id: 'textEditor.commands.configEol',
51
+ category: EDITOR_CATEGORY,
52
+ label: 'Change End of Line Sequence'
53
+ });
54
+
55
+ export const INDENT_USING_SPACES = Command.toDefaultLocalizedCommand({
56
+ id: 'textEditor.commands.indentUsingSpaces',
57
+ category: EDITOR_CATEGORY,
58
+ label: 'Indent Using Spaces'
59
+ });
60
+ export const INDENT_USING_TABS = Command.toDefaultLocalizedCommand({
61
+ id: 'textEditor.commands.indentUsingTabs',
62
+ category: EDITOR_CATEGORY,
63
+ label: 'Indent Using Tabs'
64
+ });
65
+ export const CHANGE_LANGUAGE = Command.toDefaultLocalizedCommand({
66
+ id: 'textEditor.change.language',
67
+ category: EDITOR_CATEGORY,
68
+ label: 'Change Language Mode'
69
+ });
70
+ export const CHANGE_ENCODING = Command.toDefaultLocalizedCommand({
71
+ id: 'textEditor.change.encoding',
72
+ category: EDITOR_CATEGORY,
73
+ label: 'Change File Encoding'
74
+ });
75
+ export const REVERT_EDITOR = Command.toDefaultLocalizedCommand({
76
+ id: 'workbench.action.files.revert',
77
+ category: CommonCommands.FILE_CATEGORY,
78
+ label: 'Revert File',
79
+ });
80
+ export const REVERT_AND_CLOSE = Command.toDefaultLocalizedCommand({
81
+ id: 'workbench.action.revertAndCloseActiveEditor',
82
+ category: CommonCommands.VIEW_CATEGORY,
83
+ label: 'Revert and Close Editor'
84
+ });
85
+
86
+ /**
87
+ * Command for going back to the last editor navigation location.
88
+ */
89
+ export const GO_BACK = Command.toDefaultLocalizedCommand({
90
+ id: 'textEditor.commands.go.back',
91
+ category: EDITOR_CATEGORY,
92
+ label: 'Go Back'
93
+ });
94
+ /**
95
+ * Command for going to the forthcoming editor navigation location.
96
+ */
97
+ export const GO_FORWARD = Command.toDefaultLocalizedCommand({
98
+ id: 'textEditor.commands.go.forward',
99
+ category: EDITOR_CATEGORY,
100
+ label: 'Go Forward'
101
+ });
102
+ /**
103
+ * Command that reveals the last text edit location, if any.
104
+ */
105
+ export const GO_LAST_EDIT = Command.toDefaultLocalizedCommand({
106
+ id: 'textEditor.commands.go.lastEdit',
107
+ category: EDITOR_CATEGORY,
108
+ label: 'Go to Last Edit Location'
109
+ });
110
+ /**
111
+ * Command that clears the editor navigation history.
112
+ */
113
+ export const CLEAR_EDITOR_HISTORY = Command.toDefaultLocalizedCommand({
114
+ id: 'textEditor.commands.clear.history',
115
+ category: EDITOR_CATEGORY,
116
+ label: 'Clear Editor History'
117
+ });
118
+ /**
119
+ * Command that displays all editors that are currently opened.
120
+ */
121
+ export const SHOW_ALL_OPENED_EDITORS = Command.toLocalizedCommand({
122
+ id: 'workbench.action.showAllEditors',
123
+ category: CommonCommands.VIEW_CATEGORY,
124
+ label: 'Show All Opened Editors'
125
+ }, 'theia/editor/showAllEditors', EDITOR_CATEGORY_KEY);
126
+ /**
127
+ * Command that toggles the minimap.
128
+ */
129
+ export const TOGGLE_MINIMAP = Command.toDefaultLocalizedCommand({
130
+ id: 'editor.action.toggleMinimap',
131
+ category: CommonCommands.VIEW_CATEGORY,
132
+ label: 'Toggle Minimap'
133
+ });
134
+ /**
135
+ * Command that toggles the rendering of whitespace characters in the editor.
136
+ */
137
+ export const TOGGLE_RENDER_WHITESPACE = Command.toDefaultLocalizedCommand({
138
+ id: 'editor.action.toggleRenderWhitespace',
139
+ category: CommonCommands.VIEW_CATEGORY,
140
+ label: 'Toggle Render Whitespace'
141
+ });
142
+ /**
143
+ * Command that toggles the word wrap.
144
+ */
145
+ export const TOGGLE_WORD_WRAP = Command.toDefaultLocalizedCommand({
146
+ id: 'editor.action.toggleWordWrap',
147
+ label: 'View: Toggle Word Wrap'
148
+ });
149
+ /**
150
+ * Command that toggles sticky scroll.
151
+ */
152
+ export const TOGGLE_STICKY_SCROLL = Command.toLocalizedCommand({
153
+ id: 'editor.action.toggleStickyScroll',
154
+ category: CommonCommands.VIEW_CATEGORY,
155
+ label: 'Toggle Sticky Scroll',
156
+ }, 'theia/editor/toggleStickyScroll', EDITOR_CATEGORY_KEY);
157
+ /**
158
+ * Command that re-opens the last closed editor.
159
+ */
160
+ export const REOPEN_CLOSED_EDITOR = Command.toDefaultLocalizedCommand({
161
+ id: 'workbench.action.reopenClosedEditor',
162
+ category: CommonCommands.VIEW_CATEGORY,
163
+ label: 'Reopen Closed Editor'
164
+ });
165
+ /**
166
+ * Opens a second instance of the current editor, splitting the view in the direction specified.
167
+ */
168
+ export const SPLIT_EDITOR_RIGHT = Command.toDefaultLocalizedCommand({
169
+ id: 'workbench.action.splitEditorRight',
170
+ category: CommonCommands.VIEW_CATEGORY,
171
+ label: 'Split Editor Right'
172
+ });
173
+ export const SPLIT_EDITOR_DOWN = Command.toDefaultLocalizedCommand({
174
+ id: 'workbench.action.splitEditorDown',
175
+ category: CommonCommands.VIEW_CATEGORY,
176
+ label: 'Split Editor Down'
177
+ });
178
+ export const SPLIT_EDITOR_UP = Command.toDefaultLocalizedCommand({
179
+ id: 'workbench.action.splitEditorUp',
180
+ category: CommonCommands.VIEW_CATEGORY,
181
+ label: 'Split Editor Up'
182
+ });
183
+ export const SPLIT_EDITOR_LEFT = Command.toDefaultLocalizedCommand({
184
+ id: 'workbench.action.splitEditorLeft',
185
+ category: CommonCommands.VIEW_CATEGORY,
186
+ label: 'Split Editor Left'
187
+ });
188
+ /**
189
+ * Default horizontal split: right.
190
+ */
191
+ export const SPLIT_EDITOR_HORIZONTAL = Command.toDefaultLocalizedCommand({
192
+ id: 'workbench.action.splitEditor',
193
+ category: CommonCommands.VIEW_CATEGORY,
194
+ label: 'Split Editor'
195
+ });
196
+ /**
197
+ * Default vertical split: down.
198
+ */
199
+ export const SPLIT_EDITOR_VERTICAL = Command.toDefaultLocalizedCommand({
200
+ id: 'workbench.action.splitEditorOrthogonal',
201
+ category: CommonCommands.VIEW_CATEGORY,
202
+ label: 'Split Editor Orthogonal'
203
+ });
204
+ }
205
+
206
+ @injectable()
207
+ export class EditorCommandContribution implements CommandContribution {
208
+
209
+ static readonly AUTOSAVE_PREFERENCE: string = 'files.autoSave';
210
+ static readonly AUTOSAVE_DELAY_PREFERENCE: string = 'files.autoSaveDelay';
211
+
212
+ @inject(ApplicationShell)
213
+ protected readonly shell: ApplicationShell;
214
+
215
+ @inject(PreferenceService)
216
+ protected readonly preferencesService: PreferenceService;
217
+
218
+ @inject(SaveableService)
219
+ protected readonly saveResourceService: SaveableService;
220
+
221
+ @inject(QuickInputService) @optional()
222
+ protected readonly quickInputService: QuickInputService;
223
+
224
+ @inject(MessageService)
225
+ protected readonly messageService: MessageService;
226
+
227
+ @inject(LabelProvider)
228
+ protected readonly labelProvider: LabelProvider;
229
+
230
+ @inject(LanguageService)
231
+ protected readonly languages: LanguageService;
232
+
233
+ @inject(EditorManager)
234
+ protected readonly editorManager: EditorManager;
235
+
236
+ @inject(ResourceProvider)
237
+ protected readonly resourceProvider: ResourceProvider;
238
+
239
+ @inject(EditorLanguageQuickPickService)
240
+ protected readonly codeLanguageQuickPickService: EditorLanguageQuickPickService;
241
+
242
+ @postConstruct()
243
+ protected init(): void {
244
+ this.preferencesService.ready.then(() => {
245
+ this.saveResourceService.autoSave = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_PREFERENCE) ?? 'off';
246
+ this.saveResourceService.autoSaveDelay = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_DELAY_PREFERENCE) ?? 1000;
247
+ });
248
+ this.preferencesService.onPreferenceChanged(e => {
249
+ if (e.preferenceName === EditorCommandContribution.AUTOSAVE_PREFERENCE) {
250
+ this.saveResourceService.autoSave = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_PREFERENCE) ?? 'off';
251
+ } else if (e.preferenceName === EditorCommandContribution.AUTOSAVE_DELAY_PREFERENCE) {
252
+ this.saveResourceService.autoSaveDelay = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_DELAY_PREFERENCE) ?? 1000;
253
+ }
254
+ });
255
+ }
256
+
257
+ registerCommands(registry: CommandRegistry): void {
258
+ registry.registerCommand(EditorCommands.SHOW_REFERENCES);
259
+ registry.registerCommand(EditorCommands.CONFIG_INDENTATION);
260
+ registry.registerCommand(EditorCommands.CONFIG_EOL);
261
+ registry.registerCommand(EditorCommands.INDENT_USING_SPACES);
262
+ registry.registerCommand(EditorCommands.INDENT_USING_TABS);
263
+ registry.registerCommand(EditorCommands.REVERT_EDITOR);
264
+ registry.registerCommand(EditorCommands.REVERT_AND_CLOSE);
265
+ registry.registerCommand(EditorCommands.CHANGE_LANGUAGE, {
266
+ isEnabled: () => this.canConfigureLanguage(),
267
+ isVisible: () => this.canConfigureLanguage(),
268
+ execute: () => this.configureLanguage()
269
+ });
270
+ registry.registerCommand(EditorCommands.CHANGE_ENCODING, {
271
+ isEnabled: () => this.canConfigureEncoding(),
272
+ isVisible: () => this.canConfigureEncoding(),
273
+ execute: () => this.configureEncoding()
274
+ });
275
+
276
+ registry.registerCommand(EditorCommands.GO_BACK);
277
+ registry.registerCommand(EditorCommands.GO_FORWARD);
278
+ registry.registerCommand(EditorCommands.GO_LAST_EDIT);
279
+ registry.registerCommand(EditorCommands.CLEAR_EDITOR_HISTORY);
280
+ registry.registerCommand(EditorCommands.TOGGLE_MINIMAP);
281
+ registry.registerCommand(EditorCommands.TOGGLE_RENDER_WHITESPACE);
282
+ registry.registerCommand(EditorCommands.TOGGLE_WORD_WRAP);
283
+ registry.registerCommand(EditorCommands.TOGGLE_STICKY_SCROLL);
284
+ registry.registerCommand(EditorCommands.REOPEN_CLOSED_EDITOR);
285
+
286
+ registry.registerCommand(CommonCommands.AUTO_SAVE, {
287
+ isToggled: () => this.isAutoSaveOn(),
288
+ execute: () => this.toggleAutoSave()
289
+ });
290
+ }
291
+
292
+ protected canConfigureLanguage(): boolean {
293
+ const widget = this.editorManager.currentEditor;
294
+ const editor = widget && widget.editor;
295
+ return !!editor && !!this.languages.languages;
296
+ }
297
+ protected async configureLanguage(): Promise<void> {
298
+ const widget = this.editorManager.currentEditor;
299
+ const editor = widget && widget.editor;
300
+ if (!editor || !this.languages.languages) {
301
+ return;
302
+ }
303
+ const current = editor.document.languageId;
304
+ const selectedMode = await this.codeLanguageQuickPickService.pickEditorLanguage(current);
305
+ if (selectedMode && ('value' in selectedMode)) {
306
+ if (selectedMode.value === 'autoDetect') {
307
+ editor.detectLanguage();
308
+ } else if (selectedMode.value) {
309
+ editor.setLanguage(selectedMode.value.id);
310
+ }
311
+ }
312
+ }
313
+
314
+ protected canConfigureEncoding(): boolean {
315
+ const widget = this.editorManager.currentEditor;
316
+ const editor = widget && widget.editor;
317
+ return !!editor;
318
+ }
319
+ protected async configureEncoding(): Promise<void> {
320
+ const widget = this.editorManager.currentEditor;
321
+ const editor = widget && widget.editor;
322
+ if (!editor) {
323
+ return;
324
+ }
325
+ const reopenWithEncodingPick = { label: nls.localizeByDefault('Reopen with Encoding'), value: 'reopen' };
326
+ const saveWithEncodingPick = { label: nls.localizeByDefault('Save with Encoding'), value: 'save' };
327
+ const actionItems: QuickPickValue<string>[] = [
328
+ reopenWithEncodingPick,
329
+ saveWithEncodingPick
330
+ ];
331
+ const selectedEncoding = await this.quickInputService?.showQuickPick(actionItems, { placeholder: nls.localizeByDefault('Select Action') });
332
+ if (!selectedEncoding) {
333
+ return;
334
+ }
335
+ const isReopenWithEncoding = (selectedEncoding.value === reopenWithEncodingPick.value);
336
+
337
+ const configuredEncoding = this.preferencesService.get<string>('files.encoding', 'utf8', editor.uri.toString());
338
+
339
+ const resource = await this.resourceProvider(editor.uri);
340
+ const guessedEncoding = resource.guessEncoding ? await resource.guessEncoding() : undefined;
341
+ resource.dispose();
342
+
343
+ const encodingItems: QuickPickValue<{ id: string, description: string }>[] = Object.keys(SUPPORTED_ENCODINGS)
344
+ .sort((k1, k2) => {
345
+ if (k1 === configuredEncoding) {
346
+ return -1;
347
+ } else if (k2 === configuredEncoding) {
348
+ return 1;
349
+ }
350
+ return SUPPORTED_ENCODINGS[k1].order - SUPPORTED_ENCODINGS[k2].order;
351
+ })
352
+ .filter(k => {
353
+ if (k === guessedEncoding && guessedEncoding !== configuredEncoding) {
354
+ return false; // do not show encoding if it is the guessed encoding that does not match the configured
355
+ }
356
+
357
+ return !isReopenWithEncoding || !SUPPORTED_ENCODINGS[k].encodeOnly; // hide those that can only be used for encoding if we are about to decode
358
+ })
359
+ .map(key => ({ label: SUPPORTED_ENCODINGS[key].labelLong, value: { id: key, description: key } }));
360
+
361
+ // Insert guessed encoding
362
+ if (guessedEncoding && configuredEncoding !== guessedEncoding && SUPPORTED_ENCODINGS[guessedEncoding]) {
363
+ encodingItems.unshift({
364
+ label: `${nls.localizeByDefault('Guessed from content')}: ${SUPPORTED_ENCODINGS[guessedEncoding].labelLong}`,
365
+ value: { id: guessedEncoding, description: guessedEncoding }
366
+ });
367
+ }
368
+ const selectedFileEncoding = await this.quickInputService?.showQuickPick<QuickPickValue<{ id: string, description: string }>>(encodingItems, {
369
+ placeholder: isReopenWithEncoding ?
370
+ nls.localizeByDefault('Select File Encoding to Reopen File') :
371
+ nls.localizeByDefault('Select File Encoding to Save with')
372
+ });
373
+
374
+ if (!selectedFileEncoding) {
375
+ return;
376
+ }
377
+ if (editor.document.dirty && isReopenWithEncoding) {
378
+ this.messageService.info(nls.localize('theia/editor/dirtyEncoding', 'The file is dirty. Please save it first before reopening it with another encoding.'));
379
+ return;
380
+ } else if (selectedFileEncoding.value) {
381
+ editor.setEncoding(selectedFileEncoding.value.id, isReopenWithEncoding ? EncodingMode.Decode : EncodingMode.Encode);
382
+ }
383
+ }
384
+
385
+ protected isAutoSaveOn(): boolean {
386
+ const autoSave = this.preferencesService.get(EditorCommandContribution.AUTOSAVE_PREFERENCE);
387
+ return autoSave !== 'off';
388
+ }
389
+
390
+ protected async toggleAutoSave(): Promise<void> {
391
+ this.preferencesService.updateValue(EditorCommandContribution.AUTOSAVE_PREFERENCE, this.isAutoSaveOn() ? 'off' : 'afterDelay');
392
+ }
393
+ }