@theia/editor 1.45.1 → 1.46.0-next.72

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