@theia/core 1.40.1 → 1.41.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.
- package/README.md +6 -6
- package/i18n/nls.cs.json +5 -1
- package/i18n/nls.de.json +5 -1
- package/i18n/nls.es.json +5 -1
- package/i18n/nls.fr.json +5 -1
- package/i18n/nls.hu.json +5 -1
- package/i18n/nls.it.json +5 -1
- package/i18n/nls.ja.json +5 -1
- package/i18n/nls.json +5 -1
- package/i18n/nls.pl.json +5 -1
- package/i18n/nls.pt-br.json +5 -1
- package/i18n/nls.pt-pt.json +5 -1
- package/i18n/nls.ru.json +5 -1
- package/i18n/nls.zh-cn.json +5 -1
- package/lib/browser/common-frontend-contribution.d.ts +11 -0
- package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/common-frontend-contribution.js +97 -14
- package/lib/browser/common-frontend-contribution.js.map +1 -1
- package/lib/browser/context-menu-renderer.d.ts +5 -0
- package/lib/browser/context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/label-parser.d.ts +8 -0
- package/lib/browser/label-parser.d.ts.map +1 -1
- package/lib/browser/label-parser.js +14 -0
- package/lib/browser/label-parser.js.map +1 -1
- package/lib/browser/label-parser.spec.js +33 -0
- package/lib/browser/label-parser.spec.js.map +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.d.ts +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.js +2 -2
- package/lib/browser/menu/browser-context-menu-renderer.js.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts +1 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.js +2 -2
- package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
- package/lib/browser/performance/frontend-stopwatch.d.ts.map +1 -1
- package/lib/browser/performance/frontend-stopwatch.js +6 -2
- package/lib/browser/performance/frontend-stopwatch.js.map +1 -1
- package/lib/browser/preferences/preference-contribution.d.ts +2 -0
- package/lib/browser/preferences/preference-contribution.d.ts.map +1 -1
- package/lib/browser/preferences/preference-contribution.js +48 -24
- package/lib/browser/preferences/preference-contribution.js.map +1 -1
- package/lib/browser/saveable.d.ts +15 -1
- package/lib/browser/saveable.d.ts.map +1 -1
- package/lib/browser/saveable.js +34 -1
- package/lib/browser/saveable.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts +46 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js +87 -6
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts +20 -2
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js +28 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts +25 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js +79 -7
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js.map +1 -1
- package/lib/browser/shell/tab-bars.d.ts.map +1 -1
- package/lib/browser/shell/tab-bars.js +9 -1
- package/lib/browser/shell/tab-bars.js.map +1 -1
- package/lib/browser/tree/tree-model.d.ts +2 -0
- package/lib/browser/tree/tree-model.d.ts.map +1 -1
- package/lib/browser/tree/tree-model.js +6 -0
- package/lib/browser/tree/tree-model.js.map +1 -1
- package/lib/browser/tree/tree-widget.d.ts +18 -0
- package/lib/browser/tree/tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget.js +57 -0
- package/lib/browser/tree/tree-widget.js.map +1 -1
- package/lib/browser/tree/tree.d.ts +18 -0
- package/lib/browser/tree/tree.d.ts.map +1 -1
- package/lib/browser/tree/tree.js +6 -0
- package/lib/browser/tree/tree.js.map +1 -1
- package/lib/browser/widgets/enhanced-preview-widget.d.ts +7 -0
- package/lib/browser/widgets/enhanced-preview-widget.d.ts.map +1 -0
- package/lib/browser/widgets/enhanced-preview-widget.js +27 -0
- package/lib/browser/widgets/enhanced-preview-widget.js.map +1 -0
- package/lib/browser/window-contribution.js +1 -1
- package/lib/browser/window-contribution.js.map +1 -1
- package/lib/common/array-utils.d.ts +7 -0
- package/lib/common/array-utils.d.ts.map +1 -1
- package/lib/common/array-utils.js +21 -0
- package/lib/common/array-utils.js.map +1 -1
- package/lib/common/event.d.ts +5 -0
- package/lib/common/event.d.ts.map +1 -1
- package/lib/common/event.js +5 -1
- package/lib/common/event.js.map +1 -1
- package/lib/common/menu/menu-model-registry.d.ts +12 -1
- package/lib/common/menu/menu-model-registry.d.ts.map +1 -1
- package/lib/common/menu/menu-model-registry.js +46 -0
- package/lib/common/menu/menu-model-registry.js.map +1 -1
- package/lib/common/performance/measurement.d.ts +21 -0
- package/lib/common/performance/measurement.d.ts.map +1 -1
- package/lib/common/performance/stopwatch.d.ts +10 -2
- package/lib/common/performance/stopwatch.d.ts.map +1 -1
- package/lib/common/performance/stopwatch.js +34 -11
- package/lib/common/performance/stopwatch.js.map +1 -1
- package/lib/common/promise-util.d.ts +4 -0
- package/lib/common/promise-util.d.ts.map +1 -1
- package/lib/common/promise-util.js +11 -1
- package/lib/common/promise-util.js.map +1 -1
- package/lib/common/promise-util.spec.js +26 -12
- package/lib/common/promise-util.spec.js.map +1 -1
- package/lib/common/types.d.ts +4 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js +16 -1
- package/lib/common/types.js.map +1 -1
- package/lib/common/uri.d.ts +1 -0
- package/lib/common/uri.d.ts.map +1 -1
- package/lib/common/uri.js +3 -0
- package/lib/common/uri.js.map +1 -1
- package/lib/electron-browser/menu/electron-context-menu-renderer.js +2 -2
- package/lib/electron-browser/menu/electron-context-menu-renderer.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +2 -2
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +3 -0
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/node/backend-application.d.ts +5 -1
- package/lib/node/backend-application.d.ts.map +1 -1
- package/lib/node/backend-application.js +28 -5
- package/lib/node/backend-application.js.map +1 -1
- package/lib/node/logger-cli-contribution.spec.js +1 -1
- package/lib/node/logger-cli-contribution.spec.js.map +1 -1
- package/lib/node/main.d.ts +2 -5
- package/lib/node/main.d.ts.map +1 -1
- package/lib/node/main.js.map +1 -1
- package/lib/node/performance/node-stopwatch.js +1 -1
- package/lib/node/performance/node-stopwatch.js.map +1 -1
- package/package.json +7 -7
- package/src/browser/common-frontend-contribution.ts +107 -17
- package/src/browser/context-menu-renderer.ts +5 -0
- package/src/browser/label-parser.spec.ts +38 -0
- package/src/browser/label-parser.ts +15 -0
- package/src/browser/menu/browser-context-menu-renderer.ts +2 -2
- package/src/browser/menu/browser-menu-plugin.ts +2 -2
- package/src/browser/performance/frontend-stopwatch.ts +5 -2
- package/src/browser/preferences/preference-contribution.ts +49 -24
- package/src/browser/saveable.ts +41 -2
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +94 -8
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.ts +28 -1
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +87 -8
- package/src/browser/shell/tab-bars.ts +8 -1
- package/src/browser/style/tabs.css +32 -2
- package/src/browser/tree/tree-model.ts +8 -0
- package/src/browser/tree/tree-widget.tsx +66 -0
- package/src/browser/tree/tree.ts +27 -0
- package/src/browser/widgets/enhanced-preview-widget.ts +27 -0
- package/src/browser/window-contribution.ts +1 -1
- package/src/common/array-utils.ts +20 -0
- package/src/common/event.ts +12 -2
- package/src/common/i18n/nls.metadata.json +5616 -5359
- package/src/common/menu/menu-model-registry.ts +50 -0
- package/src/common/performance/measurement.ts +26 -0
- package/src/common/performance/stopwatch.ts +38 -12
- package/src/common/promise-util.spec.ts +43 -12
- package/src/common/promise-util.ts +12 -0
- package/src/common/types.ts +17 -0
- package/src/common/uri.ts +4 -0
- package/src/electron-browser/menu/electron-context-menu-renderer.ts +2 -2
- package/src/electron-browser/menu/electron-main-menu-factory.ts +2 -2
- package/src/electron-main/electron-main-application.ts +3 -0
- package/src/node/backend-application.ts +30 -5
- package/src/node/logger-cli-contribution.spec.ts +1 -1
- package/src/node/main.ts +1 -6
- package/src/node/performance/node-stopwatch.ts +1 -1
|
@@ -36,7 +36,7 @@ import { OS, isOSX, isWindows, EOL } from '../common/os';
|
|
|
36
36
|
import { ResourceContextKey } from './resource-context-key';
|
|
37
37
|
import { UriSelection } from '../common/selection';
|
|
38
38
|
import { StorageService } from './storage-service';
|
|
39
|
-
import { Navigatable } from './navigatable';
|
|
39
|
+
import { Navigatable, NavigatableWidget } from './navigatable';
|
|
40
40
|
import { QuickViewService } from './quick-input/quick-view-service';
|
|
41
41
|
import { environment } from '@theia/application-package/lib/environment';
|
|
42
42
|
import { IconTheme, IconThemeService } from './icon-theme-service';
|
|
@@ -52,7 +52,7 @@ import { UTF8 } from '../common/encodings';
|
|
|
52
52
|
import { EnvVariablesServer } from '../common/env-variables';
|
|
53
53
|
import { AuthenticationService } from './authentication-service';
|
|
54
54
|
import { FormatType, Saveable, SaveOptions } from './saveable';
|
|
55
|
-
import { QuickInputService, QuickPickItem, QuickPickItemOrSeparator } from './quick-input';
|
|
55
|
+
import { QuickInputService, QuickPickItem, QuickPickItemOrSeparator, QuickPickSeparator } from './quick-input';
|
|
56
56
|
import { AsyncLocalizationProvider } from '../common/i18n/localization';
|
|
57
57
|
import { nls } from '../common/nls';
|
|
58
58
|
import { CurrentWidgetCommandAdapter } from './shell/current-widget-command-adapter';
|
|
@@ -63,12 +63,13 @@ import { DecorationStyle } from './decoration-style';
|
|
|
63
63
|
import { isPinned, Title, togglePinned, Widget } from './widgets';
|
|
64
64
|
import { SaveResourceService } from './save-resource-service';
|
|
65
65
|
import { UserWorkingDirectoryProvider } from './user-working-directory-provider';
|
|
66
|
-
import { UntitledResourceResolver } from '../common';
|
|
66
|
+
import { UNTITLED_SCHEME, UntitledResourceResolver } from '../common';
|
|
67
67
|
import { LanguageQuickPickService } from './i18n/language-quick-pick-service';
|
|
68
68
|
|
|
69
69
|
export namespace CommonMenus {
|
|
70
70
|
|
|
71
71
|
export const FILE = [...MAIN_MENU_BAR, '1_file'];
|
|
72
|
+
export const FILE_NEW_TEXT = [...FILE, '1_new_text'];
|
|
72
73
|
export const FILE_NEW = [...FILE, '1_new'];
|
|
73
74
|
export const FILE_OPEN = [...FILE, '2_open'];
|
|
74
75
|
export const FILE_SAVE = [...FILE, '3_save'];
|
|
@@ -79,6 +80,8 @@ export namespace CommonMenus {
|
|
|
79
80
|
export const FILE_SETTINGS_SUBMENU_THEME = [...FILE_SETTINGS_SUBMENU, '2_settings_submenu_theme'];
|
|
80
81
|
export const FILE_CLOSE = [...FILE, '6_close'];
|
|
81
82
|
|
|
83
|
+
export const FILE_NEW_CONTRIBUTIONS = 'file/newFile';
|
|
84
|
+
|
|
82
85
|
export const EDIT = [...MAIN_MENU_BAR, '2_edit'];
|
|
83
86
|
export const EDIT_UNDO = [...EDIT, '1_undo'];
|
|
84
87
|
export const EDIT_CLIPBOARD = [...EDIT, '2_clipboard'];
|
|
@@ -108,6 +111,7 @@ export namespace CommonCommands {
|
|
|
108
111
|
|
|
109
112
|
export const FILE_CATEGORY = 'File';
|
|
110
113
|
export const VIEW_CATEGORY = 'View';
|
|
114
|
+
export const CREATE_CATEGORY = 'Create';
|
|
111
115
|
export const PREFERENCES_CATEGORY = 'Preferences';
|
|
112
116
|
export const FILE_CATEGORY_KEY = nls.getDefaultKey(FILE_CATEGORY);
|
|
113
117
|
export const VIEW_CATEGORY_KEY = nls.getDefaultKey(VIEW_CATEGORY);
|
|
@@ -272,11 +276,16 @@ export namespace CommonCommands {
|
|
|
272
276
|
category: VIEW_CATEGORY,
|
|
273
277
|
label: 'Toggle Menu Bar'
|
|
274
278
|
});
|
|
275
|
-
export const
|
|
276
|
-
id: 'workbench.action.files.
|
|
279
|
+
export const NEW_UNTITLED_TEXT_FILE = Command.toDefaultLocalizedCommand({
|
|
280
|
+
id: 'workbench.action.files.newUntitledTextFile',
|
|
277
281
|
category: FILE_CATEGORY,
|
|
278
282
|
label: 'New Untitled Text File'
|
|
279
283
|
});
|
|
284
|
+
export const NEW_UNTITLED_FILE = Command.toDefaultLocalizedCommand({
|
|
285
|
+
id: 'workbench.action.files.newUntitledFile',
|
|
286
|
+
category: CREATE_CATEGORY,
|
|
287
|
+
label: 'New File...'
|
|
288
|
+
});
|
|
280
289
|
export const SAVE = Command.toDefaultLocalizedCommand({
|
|
281
290
|
id: 'core.save',
|
|
282
291
|
category: FILE_CATEGORY,
|
|
@@ -371,6 +380,9 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
371
380
|
@inject(CommandRegistry)
|
|
372
381
|
protected readonly commandRegistry: CommandRegistry;
|
|
373
382
|
|
|
383
|
+
@inject(MenuModelRegistry)
|
|
384
|
+
protected readonly menuRegistry: MenuModelRegistry;
|
|
385
|
+
|
|
374
386
|
@inject(StorageService)
|
|
375
387
|
protected readonly storageService: StorageService;
|
|
376
388
|
|
|
@@ -545,6 +557,9 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
545
557
|
registry.registerSubmenu(CommonMenus.VIEW, nls.localizeByDefault('View'));
|
|
546
558
|
registry.registerSubmenu(CommonMenus.HELP, nls.localizeByDefault('Help'));
|
|
547
559
|
|
|
560
|
+
// For plugins contributing create new file commands/menu-actions
|
|
561
|
+
registry.registerIndependentSubmenu(CommonMenus.FILE_NEW_CONTRIBUTIONS, nls.localizeByDefault('New File...'));
|
|
562
|
+
|
|
548
563
|
registry.registerMenuAction(CommonMenus.FILE_SAVE, {
|
|
549
564
|
commandId: CommonCommands.SAVE.id
|
|
550
565
|
});
|
|
@@ -693,10 +708,16 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
693
708
|
|
|
694
709
|
registry.registerSubmenu(CommonMenus.VIEW_APPEARANCE_SUBMENU, nls.localizeByDefault('Appearance'));
|
|
695
710
|
|
|
696
|
-
registry.registerMenuAction(CommonMenus.
|
|
711
|
+
registry.registerMenuAction(CommonMenus.FILE_NEW_TEXT, {
|
|
712
|
+
commandId: CommonCommands.NEW_UNTITLED_TEXT_FILE.id,
|
|
713
|
+
label: nls.localizeByDefault('New Text File'),
|
|
714
|
+
order: 'a'
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
registry.registerMenuAction(CommonMenus.FILE_NEW_TEXT, {
|
|
697
718
|
commandId: CommonCommands.NEW_UNTITLED_FILE.id,
|
|
698
719
|
label: nls.localizeByDefault('New File...'),
|
|
699
|
-
order: '
|
|
720
|
+
order: 'a1'
|
|
700
721
|
});
|
|
701
722
|
}
|
|
702
723
|
|
|
@@ -941,13 +962,17 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
941
962
|
execute: () => this.toggleBreadcrumbs(),
|
|
942
963
|
isToggled: () => this.isBreadcrumbsEnabled(),
|
|
943
964
|
});
|
|
944
|
-
commandRegistry.registerCommand(CommonCommands.
|
|
965
|
+
commandRegistry.registerCommand(CommonCommands.NEW_UNTITLED_TEXT_FILE, {
|
|
945
966
|
execute: async () => {
|
|
946
967
|
const untitledUri = this.untitledResourceResolver.createUntitledURI('', await this.workingDirProvider.getUserWorkingDir());
|
|
947
968
|
this.untitledResourceResolver.resolve(untitledUri);
|
|
948
969
|
return open(this.openerService, untitledUri);
|
|
949
970
|
}
|
|
950
971
|
});
|
|
972
|
+
commandRegistry.registerCommand(CommonCommands.NEW_UNTITLED_FILE, {
|
|
973
|
+
execute: async () => this.showNewFilePicker()
|
|
974
|
+
});
|
|
975
|
+
|
|
951
976
|
for (const [index, ordinal] of this.getOrdinalNumbers().entries()) {
|
|
952
977
|
commandRegistry.registerCommand({ id: `workbench.action.focus${ordinal}EditorGroup`, label: index === 0 ? nls.localizeByDefault('Focus First Editor Group') : '', category: nls.localize(CommonCommands.VIEW_CATEGORY_KEY, CommonCommands.VIEW_CATEGORY) }, {
|
|
953
978
|
isEnabled: () => this.shell.mainAreaTabBars.length > index,
|
|
@@ -1097,8 +1122,12 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
1097
1122
|
when: 'activeEditorIsPinned'
|
|
1098
1123
|
},
|
|
1099
1124
|
{
|
|
1100
|
-
command: CommonCommands.
|
|
1125
|
+
command: CommonCommands.NEW_UNTITLED_TEXT_FILE.id,
|
|
1101
1126
|
keybinding: this.isElectron() ? 'ctrlcmd+n' : 'alt+n',
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
command: CommonCommands.NEW_UNTITLED_FILE.id,
|
|
1130
|
+
keybinding: 'ctrlcmd+alt+n'
|
|
1102
1131
|
}
|
|
1103
1132
|
);
|
|
1104
1133
|
for (const [index, ordinal] of this.getOrdinalNumbers().entries()) {
|
|
@@ -1142,14 +1171,26 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
1142
1171
|
}
|
|
1143
1172
|
|
|
1144
1173
|
onWillStop(): OnWillStopAction | undefined {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1174
|
+
if (this.shouldPreventClose || this.shell.canSaveAll()) {
|
|
1175
|
+
return {
|
|
1176
|
+
reason: 'Dirty editors present',
|
|
1177
|
+
action: async () => {
|
|
1178
|
+
const captionsToSave = this.unsavedTabsCaptions();
|
|
1179
|
+
const untitledCaptionsToSave = this.unsavedUntitledTabsCaptions();
|
|
1180
|
+
const result = await confirmExitWithOrWithoutSaving(captionsToSave, async () => {
|
|
1181
|
+
await this.saveDirty(untitledCaptionsToSave);
|
|
1182
|
+
await this.shell.saveAll();
|
|
1183
|
+
});
|
|
1184
|
+
if (this.shell.canSaveAll()) {
|
|
1185
|
+
this.shouldPreventClose = true;
|
|
1186
|
+
return false;
|
|
1187
|
+
} else {
|
|
1188
|
+
this.shouldPreventClose = false;
|
|
1189
|
+
return result;
|
|
1190
|
+
}
|
|
1148
1191
|
|
|
1149
|
-
|
|
1150
|
-
}
|
|
1151
|
-
} finally {
|
|
1152
|
-
this.shouldPreventClose = false;
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1153
1194
|
}
|
|
1154
1195
|
}
|
|
1155
1196
|
protected unsavedTabsCaptions(): string[] {
|
|
@@ -1157,6 +1198,11 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
1157
1198
|
.filter(widget => this.saveResourceService.canSave(widget))
|
|
1158
1199
|
.map(widget => widget.title.label);
|
|
1159
1200
|
}
|
|
1201
|
+
protected unsavedUntitledTabsCaptions(): Widget[] {
|
|
1202
|
+
return this.shell.widgets.filter(widget =>
|
|
1203
|
+
NavigatableWidget.getUri(widget)?.scheme === UNTITLED_SCHEME && this.saveResourceService.canSaveAs(widget)
|
|
1204
|
+
);
|
|
1205
|
+
}
|
|
1160
1206
|
protected async configureDisplayLanguage(): Promise<void> {
|
|
1161
1207
|
const languageInfo = await this.languageQuickPickService.pickDisplayLanguage();
|
|
1162
1208
|
if (languageInfo && !nls.isSelectedLocale(languageInfo.languageId) && await this.confirmRestart(
|
|
@@ -1167,7 +1213,14 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
1167
1213
|
this.windowService.reload();
|
|
1168
1214
|
}
|
|
1169
1215
|
}
|
|
1170
|
-
|
|
1216
|
+
protected async saveDirty(toSave: Widget[]): Promise<void> {
|
|
1217
|
+
for (const widget of toSave) {
|
|
1218
|
+
const saveable = Saveable.get(widget);
|
|
1219
|
+
if (saveable?.dirty) {
|
|
1220
|
+
await this.saveResourceService.save(widget);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1171
1224
|
protected toggleBreadcrumbs(): void {
|
|
1172
1225
|
const value: boolean | undefined = this.preferenceService.get('breadcrumbs.enabled');
|
|
1173
1226
|
this.preferenceService.set('breadcrumbs.enabled', !value, PreferenceScope.User);
|
|
@@ -1294,6 +1347,43 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
1294
1347
|
});
|
|
1295
1348
|
}
|
|
1296
1349
|
|
|
1350
|
+
/**
|
|
1351
|
+
* @todo https://github.com/eclipse-theia/theia/issues/12824
|
|
1352
|
+
*/
|
|
1353
|
+
protected async showNewFilePicker(): Promise<void> {
|
|
1354
|
+
const newFileContributions = this.menuRegistry.getMenuNode(CommonMenus.FILE_NEW_CONTRIBUTIONS); // Add menus
|
|
1355
|
+
const items: QuickPickItemOrSeparator[] = [
|
|
1356
|
+
{
|
|
1357
|
+
label: nls.localizeByDefault('New Text File'),
|
|
1358
|
+
execute: async () => this.commandRegistry.executeCommand(CommonCommands.NEW_UNTITLED_TEXT_FILE.id)
|
|
1359
|
+
},
|
|
1360
|
+
...newFileContributions.children
|
|
1361
|
+
.flatMap(node => {
|
|
1362
|
+
if (node.children && node.children.length > 0) {
|
|
1363
|
+
return node.children;
|
|
1364
|
+
}
|
|
1365
|
+
return node;
|
|
1366
|
+
})
|
|
1367
|
+
.filter(node => node.role || node.command)
|
|
1368
|
+
.map(node => {
|
|
1369
|
+
if (node.role) {
|
|
1370
|
+
return { type: 'separator' } as QuickPickSeparator;
|
|
1371
|
+
}
|
|
1372
|
+
const command = this.commandRegistry.getCommand(node.command!);
|
|
1373
|
+
return {
|
|
1374
|
+
label: command!.label!,
|
|
1375
|
+
execute: async () => this.commandRegistry.executeCommand(command!.id!)
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
})
|
|
1379
|
+
];
|
|
1380
|
+
this.quickInputService.showQuickPick(items, {
|
|
1381
|
+
title: nls.localizeByDefault('New File...'),
|
|
1382
|
+
placeholder: nls.localizeByDefault('Select File Type or Enter File Name...'),
|
|
1383
|
+
canSelectMany: false
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1297
1387
|
registerColors(colors: ColorRegistry): void {
|
|
1298
1388
|
colors.register(
|
|
1299
1389
|
// Base Colors should be aligned with https://code.visualstudio.com/api/references/theme-color#base-colors
|
|
@@ -120,4 +120,9 @@ export interface RenderContextMenuOptions {
|
|
|
120
120
|
context?: HTMLElement;
|
|
121
121
|
contextKeyService?: ContextMatcher;
|
|
122
122
|
onHide?: () => void;
|
|
123
|
+
/**
|
|
124
|
+
* If true a single submenu in the context menu is not rendered but its children are rendered on the top level.
|
|
125
|
+
* Default is `false`.
|
|
126
|
+
*/
|
|
127
|
+
skipSingleRootNode?: boolean;
|
|
123
128
|
}
|
|
@@ -124,4 +124,42 @@ describe('StatusBarEntryUtility', () => {
|
|
|
124
124
|
expect((iconArr[3] as LabelIcon).name).equals('icon3');
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
it('should strip nothing from an empty string', () => {
|
|
128
|
+
text = '';
|
|
129
|
+
const stripped: string = statusBarEntryUtility.stripIcons(text);
|
|
130
|
+
expect(stripped).to.be.equal(text);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should strip nothing from an string containing no icons', () => {
|
|
134
|
+
// Deliberate double space to verify not concatenating these words
|
|
135
|
+
text = 'foo bar';
|
|
136
|
+
const stripped: string = statusBarEntryUtility.stripIcons(text);
|
|
137
|
+
expect(stripped).to.be.equal(text);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("should strip a medial '$(icon)' from a string", () => {
|
|
141
|
+
text = 'foo $(icon) bar';
|
|
142
|
+
const stripped: string = statusBarEntryUtility.stripIcons(text);
|
|
143
|
+
expect(stripped).to.be.equal('foo bar');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("should strip a terminal '$(icon)' from a string", () => {
|
|
147
|
+
// Deliberate double space to verify not concatenating these words
|
|
148
|
+
text = 'foo bar $(icon)';
|
|
149
|
+
const stripped: string = statusBarEntryUtility.stripIcons(text);
|
|
150
|
+
expect(stripped).to.be.equal('foo bar');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("should strip an initial '$(icon)' from a string", () => {
|
|
154
|
+
// Deliberate double space to verify not concatenating these words
|
|
155
|
+
text = '$(icon) foo bar';
|
|
156
|
+
const stripped: string = statusBarEntryUtility.stripIcons(text);
|
|
157
|
+
expect(stripped).to.be.equal('foo bar');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("should strip multiple '$(icon)' specifiers from a string", () => {
|
|
161
|
+
text = '$(icon1) foo $(icon2)$(icon3) bar $(icon4) $(icon5)';
|
|
162
|
+
const stripped: string = statusBarEntryUtility.stripIcons(text);
|
|
163
|
+
expect(stripped).to.be.equal('foo bar');
|
|
164
|
+
});
|
|
127
165
|
});
|
|
@@ -90,4 +90,19 @@ export class LabelParser {
|
|
|
90
90
|
return parserArray;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Strips icon specifiers from the given `text`, leaving only a
|
|
95
|
+
* space-separated concatenation of the non-icon segments.
|
|
96
|
+
*
|
|
97
|
+
* @param text text to be stripped of icon specifiers
|
|
98
|
+
* @returns the `text` with icon specifiers stripped out
|
|
99
|
+
*/
|
|
100
|
+
stripIcons(text: string): string {
|
|
101
|
+
return this.parse(text)
|
|
102
|
+
.filter(item => !LabelIcon.is(item))
|
|
103
|
+
.map(s => (s as string).trim())
|
|
104
|
+
.filter(s => s.length)
|
|
105
|
+
.join(' ');
|
|
106
|
+
}
|
|
107
|
+
|
|
93
108
|
}
|
|
@@ -34,8 +34,8 @@ export class BrowserContextMenuRenderer extends ContextMenuRenderer {
|
|
|
34
34
|
super();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
protected doRender({ menuPath, anchor, args, onHide, context, contextKeyService }: RenderContextMenuOptions): ContextMenuAccess {
|
|
38
|
-
const contextMenu = this.menuFactory.createContextMenu(menuPath, args, context, contextKeyService);
|
|
37
|
+
protected doRender({ menuPath, anchor, args, onHide, context, contextKeyService, skipSingleRootNode }: RenderContextMenuOptions): ContextMenuAccess {
|
|
38
|
+
const contextMenu = this.menuFactory.createContextMenu(menuPath, args, context, contextKeyService, skipSingleRootNode);
|
|
39
39
|
const { x, y } = coordinateFromAnchor(anchor);
|
|
40
40
|
if (onHide) {
|
|
41
41
|
contextMenu.aboutToClose.connect(() => onHide!());
|
|
@@ -108,8 +108,8 @@ export class BrowserMainMenuFactory implements MenuWidgetFactory {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
createContextMenu(path: MenuPath, args?: unknown[], context?: HTMLElement, contextKeyService?: ContextMatcher): MenuWidget {
|
|
112
|
-
const menuModel = this.menuProvider.getMenu(path);
|
|
111
|
+
createContextMenu(path: MenuPath, args?: unknown[], context?: HTMLElement, contextKeyService?: ContextMatcher, skipSingleRootNode?: boolean): MenuWidget {
|
|
112
|
+
const menuModel = skipSingleRootNode ? this.menuProvider.removeSingleRootNode(this.menuProvider.getMenu(path), path) : this.menuProvider.getMenu(path);
|
|
113
113
|
const menuCommandRegistry = this.createMenuCommandRegistry(menuModel, args).snapshot(path);
|
|
114
114
|
const contextMenu = this.createMenuWidget(menuModel, { commands: menuCommandRegistry, context, rootMenuPath: path, contextKeyService });
|
|
115
115
|
return contextMenu;
|
|
@@ -40,6 +40,7 @@ export class FrontendStopwatch extends Stopwatch {
|
|
|
40
40
|
performance.mark(endMarker);
|
|
41
41
|
|
|
42
42
|
let duration: number;
|
|
43
|
+
let startTime: number;
|
|
43
44
|
|
|
44
45
|
try {
|
|
45
46
|
performance.measure(name, startMarker, endMarker);
|
|
@@ -47,16 +48,18 @@ export class FrontendStopwatch extends Stopwatch {
|
|
|
47
48
|
const entries = performance.getEntriesByName(name);
|
|
48
49
|
// If no entries, then performance measurement was disabled or failed, so
|
|
49
50
|
// signal that with a `NaN` result
|
|
50
|
-
duration = entries
|
|
51
|
+
duration = entries[0].duration ?? Number.NaN;
|
|
52
|
+
startTime = entries[0].startTime ?? Number.NaN;
|
|
51
53
|
} catch (e) {
|
|
52
54
|
console.warn(e);
|
|
53
55
|
duration = Number.NaN;
|
|
56
|
+
startTime = Number.NaN;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
performance.clearMeasures(name);
|
|
57
60
|
performance.clearMarks(startMarker);
|
|
58
61
|
performance.clearMarks(endMarker);
|
|
59
|
-
return duration;
|
|
62
|
+
return { startTime, duration };
|
|
60
63
|
}, options);
|
|
61
64
|
}
|
|
62
65
|
};
|
|
@@ -34,6 +34,8 @@ import { JSONValue } from '@phosphor/coreutils';
|
|
|
34
34
|
|
|
35
35
|
export const PreferenceContribution = Symbol('PreferenceContribution');
|
|
36
36
|
|
|
37
|
+
export const DefaultOverridesPreferenceSchemaId = 'defaultOverrides';
|
|
38
|
+
|
|
37
39
|
/**
|
|
38
40
|
* A {@link PreferenceContribution} allows adding additional custom preferences.
|
|
39
41
|
* For this, the {@link PreferenceContribution} has to provide a valid JSON Schema specifying which preferences
|
|
@@ -202,34 +204,44 @@ export class PreferenceSchemaProvider extends PreferenceProvider {
|
|
|
202
204
|
const defaultScope = PreferenceSchema.getDefaultScope(schema);
|
|
203
205
|
const overridable = schema.overridable || false;
|
|
204
206
|
for (const [preferenceName, rawSchemaProps] of Object.entries(schema.properties)) {
|
|
205
|
-
if (this.combinedSchema.properties[preferenceName]) {
|
|
207
|
+
if (this.combinedSchema.properties[preferenceName] && DefaultOverridesPreferenceSchemaId !== schema.id) {
|
|
206
208
|
console.error('Preference name collision detected in the schema for property: ' + preferenceName);
|
|
207
|
-
} else
|
|
208
|
-
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
209
|
+
} else {
|
|
210
|
+
let schemaProps;
|
|
211
|
+
if (this.combinedSchema.properties[preferenceName] && DefaultOverridesPreferenceSchemaId === schema.id) {
|
|
212
|
+
// update existing default value in schema
|
|
213
|
+
schemaProps = PreferenceDataProperty.fromPreferenceSchemaProperty(rawSchemaProps, defaultScope);
|
|
214
|
+
this.updateSchemaPropsDefault(preferenceName, schemaProps);
|
|
215
|
+
} else if (!rawSchemaProps.hasOwnProperty('included') || rawSchemaProps.included) {
|
|
216
|
+
// add overrides for languages
|
|
217
|
+
schemaProps = PreferenceDataProperty.fromPreferenceSchemaProperty(rawSchemaProps, defaultScope);
|
|
218
|
+
if (typeof schemaProps.overridable !== 'boolean' && overridable) {
|
|
219
|
+
schemaProps.overridable = true;
|
|
220
|
+
}
|
|
221
|
+
if (schemaProps.overridable) {
|
|
222
|
+
this.overridePatternProperties.properties[preferenceName] = schemaProps;
|
|
223
|
+
}
|
|
224
|
+
this.updateSchemaProps(preferenceName, schemaProps);
|
|
214
225
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
|
|
227
|
+
if (schemaProps !== undefined) {
|
|
228
|
+
const schemaDefault = this.getDefaultValue(schemaProps);
|
|
229
|
+
const configuredDefault = this.getConfiguredDefault(preferenceName);
|
|
230
|
+
if (this.preferenceOverrideService.testOverrideValue(preferenceName, schemaDefault)) {
|
|
231
|
+
schemaProps.defaultValue = PreferenceSchemaProperties.is(configuredDefault)
|
|
232
|
+
? PreferenceProvider.merge(schemaDefault, configuredDefault)
|
|
233
|
+
: schemaDefault;
|
|
234
|
+
if (schemaProps.defaultValue && PreferenceSchemaProperties.is(schemaProps.defaultValue)) {
|
|
235
|
+
for (const overriddenPreferenceName in schemaProps.defaultValue) {
|
|
236
|
+
const overrideValue = schemaDefault[overriddenPreferenceName];
|
|
237
|
+
const overridePreferenceName = `${preferenceName}.${overriddenPreferenceName}`;
|
|
238
|
+
changes.push(this.doSetPreferenceValue(overridePreferenceName, overrideValue, { scope, domain }));
|
|
239
|
+
}
|
|
228
240
|
}
|
|
241
|
+
} else {
|
|
242
|
+
schemaProps.defaultValue = configuredDefault === undefined ? schemaDefault : configuredDefault;
|
|
243
|
+
changes.push(this.doSetPreferenceValue(preferenceName, schemaProps.defaultValue, { scope, domain }));
|
|
229
244
|
}
|
|
230
|
-
} else {
|
|
231
|
-
schemaProps.defaultValue = configuredDefault === undefined ? schemaDefault : configuredDefault;
|
|
232
|
-
changes.push(this.doSetPreferenceValue(preferenceName, schemaProps.defaultValue, { scope, domain }));
|
|
233
245
|
}
|
|
234
246
|
}
|
|
235
247
|
}
|
|
@@ -383,6 +395,19 @@ export class PreferenceSchemaProvider extends PreferenceProvider {
|
|
|
383
395
|
}
|
|
384
396
|
}
|
|
385
397
|
|
|
398
|
+
protected updateSchemaPropsDefault(key: string, property: PreferenceDataProperty): void {
|
|
399
|
+
this.combinedSchema.properties[key].default = property.default;
|
|
400
|
+
this.combinedSchema.properties[key].defaultValue = property.defaultValue;
|
|
401
|
+
if (this.workspaceSchema.properties[key]) {
|
|
402
|
+
this.workspaceSchema.properties[key].default = property.default;
|
|
403
|
+
this.workspaceSchema.properties[key].defaultValue = property.defaultValue;
|
|
404
|
+
}
|
|
405
|
+
if (this.folderSchema.properties[key]) {
|
|
406
|
+
this.folderSchema.properties[key].default = property.default;
|
|
407
|
+
this.folderSchema.properties[key].defaultValue = property.defaultValue;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
386
411
|
protected removePropFromSchemas(key: string): void {
|
|
387
412
|
// If we remove a key from combined, it should also be removed from all narrower scopes.
|
|
388
413
|
delete this.combinedSchema.properties[key];
|
package/src/browser/saveable.ts
CHANGED
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
|
|
17
17
|
import { Widget } from '@phosphor/widgets';
|
|
18
18
|
import { Message } from '@phosphor/messaging';
|
|
19
|
-
import { Event } from '../common/event';
|
|
19
|
+
import { Emitter, Event } from '../common/event';
|
|
20
20
|
import { MaybePromise } from '../common/types';
|
|
21
21
|
import { Key } from './keyboard/keys';
|
|
22
22
|
import { AbstractDialog } from './dialogs';
|
|
23
23
|
import { waitForClosed } from './widgets';
|
|
24
24
|
import { nls } from '../common/nls';
|
|
25
|
-
import { isObject } from '../common';
|
|
25
|
+
import { Disposable, isObject } from '../common';
|
|
26
26
|
|
|
27
27
|
export interface Saveable {
|
|
28
28
|
readonly dirty: boolean;
|
|
@@ -50,6 +50,45 @@ export interface SaveableSource {
|
|
|
50
50
|
readonly saveable: Saveable;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
export class SaveableDelegate implements Saveable {
|
|
54
|
+
dirty = false;
|
|
55
|
+
protected readonly onDirtyChangedEmitter = new Emitter<void>();
|
|
56
|
+
|
|
57
|
+
get onDirtyChanged(): Event<void> {
|
|
58
|
+
return this.onDirtyChangedEmitter.event;
|
|
59
|
+
}
|
|
60
|
+
autoSave: 'off' | 'afterDelay' | 'onFocusChange' | 'onWindowChange' = 'off';
|
|
61
|
+
|
|
62
|
+
async save(options?: SaveOptions): Promise<void> {
|
|
63
|
+
await this.delegate?.save(options);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
revert?(options?: Saveable.RevertOptions): Promise<void>;
|
|
67
|
+
createSnapshot?(): Saveable.Snapshot;
|
|
68
|
+
applySnapshot?(snapshot: object): void;
|
|
69
|
+
|
|
70
|
+
protected delegate?: Saveable;
|
|
71
|
+
protected toDispose?: Disposable;
|
|
72
|
+
|
|
73
|
+
set(delegate: Saveable): void {
|
|
74
|
+
this.toDispose?.dispose();
|
|
75
|
+
this.delegate = delegate;
|
|
76
|
+
this.toDispose = this.delegate.onDirtyChanged(() => {
|
|
77
|
+
this.dirty = delegate.dirty;
|
|
78
|
+
this.onDirtyChangedEmitter.fire();
|
|
79
|
+
});
|
|
80
|
+
this.autoSave = delegate.autoSave;
|
|
81
|
+
if (this.dirty !== delegate.dirty) {
|
|
82
|
+
this.dirty = delegate.dirty;
|
|
83
|
+
this.onDirtyChangedEmitter.fire();
|
|
84
|
+
}
|
|
85
|
+
this.revert = delegate.revert?.bind(delegate);
|
|
86
|
+
this.createSnapshot = delegate.createSnapshot?.bind(delegate);
|
|
87
|
+
this.applySnapshot = delegate.applySnapshot?.bind(delegate);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
53
92
|
export namespace Saveable {
|
|
54
93
|
export interface RevertOptions {
|
|
55
94
|
/**
|