@theia/core 1.70.0-next.7 → 1.70.0-next.81
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 +3 -3
- package/lib/browser/about-dialog.d.ts.map +1 -1
- package/lib/browser/about-dialog.js +3 -1
- package/lib/browser/about-dialog.js.map +1 -1
- package/lib/browser/catalog.json +83 -7
- package/lib/browser/common-frontend-contribution.d.ts +0 -2
- package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/common-frontend-contribution.js +39 -15
- package/lib/browser/common-frontend-contribution.js.map +1 -1
- package/lib/browser/frontend-application-module.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.js +1 -0
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/hover-service.d.ts.map +1 -1
- package/lib/browser/hover-service.js +5 -3
- package/lib/browser/hover-service.js.map +1 -1
- package/lib/browser/markdown-rendering/markdown-renderer.d.ts +1 -1
- package/lib/browser/markdown-rendering/markdown-renderer.d.ts.map +1 -1
- package/lib/browser/menu/action-menu-node.d.ts +1 -0
- package/lib/browser/menu/action-menu-node.d.ts.map +1 -1
- package/lib/browser/menu/action-menu-node.js +1 -0
- package/lib/browser/menu/action-menu-node.js.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.js +9 -1
- package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
- package/lib/browser/menu/composite-menu-node.d.ts +2 -1
- package/lib/browser/menu/composite-menu-node.d.ts.map +1 -1
- package/lib/browser/menu/composite-menu-node.js +3 -1
- package/lib/browser/menu/composite-menu-node.js.map +1 -1
- package/lib/browser/menu/menu.spec.js +15 -0
- package/lib/browser/menu/menu.spec.js.map +1 -1
- package/lib/browser/menu/utils.d.ts +2 -0
- package/lib/browser/menu/utils.d.ts.map +1 -0
- package/lib/browser/menu/utils.js +29 -0
- package/lib/browser/menu/utils.js.map +1 -0
- package/lib/browser/quick-input/quick-input-service.spec.js +53 -9
- package/lib/browser/quick-input/quick-input-service.spec.js.map +1 -1
- package/lib/browser/saveable-service.d.ts +24 -1
- package/lib/browser/saveable-service.d.ts.map +1 -1
- package/lib/browser/saveable-service.js +34 -3
- package/lib/browser/saveable-service.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts +3 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js +10 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts +7 -0
- 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 +35 -0
- 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.d.ts +2 -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 +9 -3
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts +2 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.js +3 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.js.map +1 -1
- package/lib/browser/tree/fuzzy-search.d.ts +1 -60
- package/lib/browser/tree/fuzzy-search.d.ts.map +1 -1
- package/lib/browser/tree/fuzzy-search.js +3 -58
- package/lib/browser/tree/fuzzy-search.js.map +1 -1
- package/lib/browser/tree/tree-view-welcome-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-view-welcome-widget.js +1 -2
- package/lib/browser/tree/tree-view-welcome-widget.js.map +1 -1
- package/lib/browser/widgets/select-component.d.ts +1 -0
- package/lib/browser/widgets/select-component.d.ts.map +1 -1
- package/lib/browser/widgets/select-component.js +30 -0
- package/lib/browser/widgets/select-component.js.map +1 -1
- package/lib/browser/window/default-window-service.d.ts +2 -1
- package/lib/browser/window/default-window-service.d.ts.map +1 -1
- package/lib/browser/window/default-window-service.js +5 -1
- package/lib/browser/window/default-window-service.js.map +1 -1
- package/lib/browser/window/test/mock-window-service.d.ts +2 -1
- package/lib/browser/window/test/mock-window-service.d.ts.map +1 -1
- package/lib/browser/window/test/mock-window-service.js +2 -1
- package/lib/browser/window/test/mock-window-service.js.map +1 -1
- package/lib/browser/window/window-service.d.ts +8 -1
- package/lib/browser/window/window-service.d.ts.map +1 -1
- package/lib/common/fuzzy-match-utils.d.ts +27 -0
- package/lib/common/fuzzy-match-utils.d.ts.map +1 -0
- package/lib/common/fuzzy-match-utils.js +96 -0
- package/lib/common/fuzzy-match-utils.js.map +1 -0
- package/lib/common/fuzzy-match-utils.spec.d.ts +2 -0
- package/lib/common/fuzzy-match-utils.spec.d.ts.map +1 -0
- package/lib/common/fuzzy-match-utils.spec.js +109 -0
- package/lib/common/fuzzy-match-utils.spec.js.map +1 -0
- package/lib/common/fuzzy-search.d.ts +63 -0
- package/lib/common/fuzzy-search.d.ts.map +1 -0
- package/lib/common/fuzzy-search.js +101 -0
- package/lib/common/fuzzy-search.js.map +1 -0
- package/lib/common/fuzzy-search.spec.d.ts.map +1 -0
- package/lib/{browser/tree → common}/fuzzy-search.spec.js +20 -1
- package/lib/common/fuzzy-search.spec.js.map +1 -0
- package/lib/common/logger-sanitizer.d.ts +9 -0
- package/lib/common/logger-sanitizer.d.ts.map +1 -1
- package/lib/common/logger-sanitizer.js +26 -3
- package/lib/common/logger-sanitizer.js.map +1 -1
- package/lib/common/logger-sanitizer.spec.js +41 -0
- package/lib/common/logger-sanitizer.spec.js.map +1 -1
- package/lib/common/menu/menu-types.d.ts +4 -0
- package/lib/common/menu/menu-types.d.ts.map +1 -1
- package/lib/common/menu/menu-types.js.map +1 -1
- package/lib/common/preferences/injectable-preference-proxy.d.ts +5 -3
- package/lib/common/preferences/injectable-preference-proxy.d.ts.map +1 -1
- package/lib/common/preferences/injectable-preference-proxy.js +9 -6
- package/lib/common/preferences/injectable-preference-proxy.js.map +1 -1
- package/lib/common/preferences/preference-configurations.d.ts +2 -2
- package/lib/common/preferences/preference-configurations.d.ts.map +1 -1
- package/lib/common/preferences/preference-configurations.js +1 -1
- package/lib/common/preferences/preference-configurations.js.map +1 -1
- package/lib/common/preferences/preference-provider-impl.d.ts +4 -3
- package/lib/common/preferences/preference-provider-impl.d.ts.map +1 -1
- package/lib/common/preferences/preference-provider-impl.js +9 -6
- package/lib/common/preferences/preference-provider-impl.js.map +1 -1
- package/lib/common/preferences/preference-proxy.d.ts +4 -2
- package/lib/common/preferences/preference-proxy.d.ts.map +1 -1
- package/lib/common/preferences/preference-proxy.js +4 -5
- package/lib/common/preferences/preference-proxy.js.map +1 -1
- package/lib/common/preferences/preference-service.d.ts +4 -3
- package/lib/common/preferences/preference-service.d.ts.map +1 -1
- package/lib/common/preferences/preference-service.js +13 -10
- package/lib/common/preferences/preference-service.js.map +1 -1
- package/lib/common/quick-pick-service.d.ts +18 -2
- package/lib/common/quick-pick-service.d.ts.map +1 -1
- package/lib/common/quick-pick-service.js +53 -8
- package/lib/common/quick-pick-service.js.map +1 -1
- package/lib/common/uri.js +1 -1
- package/lib/common/uri.js.map +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 +4 -6
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.js +3 -3
- package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.d.ts +2 -0
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.d.ts.map +1 -1
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.js +5 -3
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.js.map +1 -1
- package/lib/electron-browser/preload.js +2 -2
- package/lib/electron-browser/preload.js.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts +4 -0
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.js +32 -0
- package/lib/electron-browser/window/electron-secondary-window-service.js.map +1 -1
- package/lib/electron-browser/window/electron-window-module.d.ts +1 -0
- package/lib/electron-browser/window/electron-window-module.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-module.js +4 -0
- package/lib/electron-browser/window/electron-window-module.js.map +1 -1
- package/lib/electron-browser/window/electron-window-service.d.ts +3 -2
- package/lib/electron-browser/window/electron-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-service.js +7 -4
- package/lib/electron-browser/window/electron-window-service.js.map +1 -1
- package/lib/electron-browser/window/window-zoom-action-bar.d.ts +21 -0
- package/lib/electron-browser/window/window-zoom-action-bar.d.ts.map +1 -0
- package/lib/electron-browser/window/window-zoom-action-bar.js +71 -0
- package/lib/electron-browser/window/window-zoom-action-bar.js.map +1 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.d.ts +14 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.d.ts.map +1 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.js +87 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.js.map +1 -0
- package/lib/electron-common/electron-api.d.ts +1 -1
- package/lib/electron-common/electron-api.d.ts.map +1 -1
- package/lib/electron-common/electron-main-window-service.d.ts +2 -1
- package/lib/electron-common/electron-main-window-service.d.ts.map +1 -1
- package/lib/electron-common/electron-window-preferences.d.ts +5 -2
- package/lib/electron-common/electron-window-preferences.d.ts.map +1 -1
- package/lib/electron-common/electron-window-preferences.js +16 -10
- package/lib/electron-common/electron-window-preferences.js.map +1 -1
- package/lib/electron-main/electron-api-main.d.ts.map +1 -1
- package/lib/electron-main/electron-api-main.js +14 -2
- package/lib/electron-main/electron-api-main.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +1 -0
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +6 -0
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/electron-main/electron-main-window-service-impl.d.ts +2 -1
- package/lib/electron-main/electron-main-window-service-impl.d.ts.map +1 -1
- package/lib/electron-main/electron-main-window-service-impl.js +6 -2
- package/lib/electron-main/electron-main-window-service-impl.js.map +1 -1
- package/package.json +7 -7
- package/src/browser/about-dialog.tsx +3 -1
- package/src/browser/common-frontend-contribution.ts +36 -17
- package/src/browser/frontend-application-module.ts +2 -1
- package/src/browser/hover-service.ts +5 -3
- package/src/browser/markdown-rendering/markdown-renderer.ts +1 -1
- package/src/browser/menu/action-menu-node.ts +1 -0
- package/src/browser/menu/browser-menu-plugin.ts +9 -1
- package/src/browser/menu/composite-menu-node.ts +4 -2
- package/src/browser/menu/menu.spec.ts +17 -0
- package/src/browser/menu/utils.ts +26 -0
- package/src/browser/quick-input/quick-input-service.spec.ts +58 -9
- package/src/browser/saveable-service.ts +56 -4
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.tsx +12 -0
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +40 -1
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +8 -4
- package/src/browser/shell/tab-bar-toolbar/tab-toolbar-item.tsx +4 -0
- package/src/browser/style/hover-service.css +1 -0
- package/src/browser/style/index.css +1 -1
- package/src/browser/tree/fuzzy-search.ts +2 -120
- package/src/browser/tree/tree-view-welcome-widget.tsx +1 -2
- package/src/browser/widgets/select-component.tsx +39 -2
- package/src/browser/window/default-window-service.ts +6 -1
- package/src/browser/window/test/mock-window-service.ts +2 -1
- package/src/browser/window/window-service.ts +9 -1
- package/src/common/fuzzy-match-utils.spec.ts +141 -0
- package/src/common/fuzzy-match-utils.ts +78 -0
- package/src/{browser/tree → common}/fuzzy-search.spec.ts +23 -1
- package/src/common/fuzzy-search.ts +158 -0
- package/src/common/i18n/nls.metadata.json +25379 -24577
- package/src/common/logger-sanitizer.spec.ts +54 -1
- package/src/common/logger-sanitizer.ts +38 -3
- package/src/common/menu/menu-types.ts +4 -0
- package/src/common/preferences/injectable-preference-proxy.ts +6 -3
- package/src/common/preferences/preference-configurations.ts +2 -2
- package/src/common/preferences/preference-provider-impl.ts +6 -3
- package/src/common/preferences/preference-proxy.ts +6 -4
- package/src/common/preferences/preference-service.ts +6 -3
- package/src/common/quick-pick-service.ts +65 -11
- package/src/common/uri.ts +1 -1
- package/src/electron-browser/menu/electron-main-menu-factory.ts +4 -6
- package/src/electron-browser/menu/electron-menu-contribution.ts +4 -4
- package/src/electron-browser/messaging/electron-local-ws-connection-source.ts +4 -2
- package/src/electron-browser/preload.ts +2 -2
- package/src/electron-browser/style/window-zoom-action-bar.css +57 -0
- package/src/electron-browser/window/electron-secondary-window-service.ts +32 -1
- package/src/electron-browser/window/electron-window-module.ts +4 -0
- package/src/electron-browser/window/electron-window-service.ts +10 -7
- package/src/electron-browser/window/window-zoom-action-bar.tsx +115 -0
- package/src/electron-browser/window/window-zoom-status-bar-item.ts +81 -0
- package/src/electron-common/electron-api.ts +1 -1
- package/src/electron-common/electron-main-window-service.ts +2 -1
- package/src/electron-common/electron-window-preferences.ts +19 -11
- package/src/electron-main/electron-api-main.ts +12 -2
- package/src/electron-main/electron-main-application.ts +7 -0
- package/src/electron-main/electron-main-window-service-impl.ts +7 -2
- package/lib/browser/tree/fuzzy-search.spec.d.ts.map +0 -1
- package/lib/browser/tree/fuzzy-search.spec.js.map +0 -1
- /package/lib/{browser/tree → common}/fuzzy-search.spec.d.ts +0 -0
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
17
|
import type { ApplicationShell } from './shell';
|
|
18
|
-
import { injectable } from 'inversify';
|
|
19
|
-
import { UNTITLED_SCHEME, URI, Disposable, DisposableCollection, Emitter, Event } from '../common';
|
|
18
|
+
import { inject, injectable, named } from 'inversify';
|
|
19
|
+
import { ContributionProvider, UNTITLED_SCHEME, URI, Disposable, DisposableCollection, Emitter, Event } from '../common';
|
|
20
20
|
import { Navigatable, NavigatableWidget } from './navigatable-types';
|
|
21
21
|
import { AutoSaveMode, Saveable, SaveableSource, SaveableWidget, SaveOptions, SaveReason, setDirty, close, PostCreationSaveableWidget, ShouldSaveDialog } from './saveable';
|
|
22
22
|
import { waitForClosed, Widget } from './widgets';
|
|
@@ -24,16 +24,40 @@ import { FrontendApplicationContribution } from './frontend-application-contribu
|
|
|
24
24
|
import { FrontendApplication } from './frontend-application';
|
|
25
25
|
import throttle = require('lodash.throttle');
|
|
26
26
|
|
|
27
|
+
export const SaveErrorChecker = Symbol('SaveErrorChecker');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Contribution point for checking whether a given URI has errors.
|
|
31
|
+
* When `files.autoSaveWhenNoErrors` is enabled, auto-save will be suppressed
|
|
32
|
+
* for files where any registered checker reports errors.
|
|
33
|
+
*/
|
|
34
|
+
export interface SaveErrorChecker {
|
|
35
|
+
/**
|
|
36
|
+
* Returns `true` if the given URI has errors that should prevent auto-save.
|
|
37
|
+
*/
|
|
38
|
+
hasErrors(uri: URI): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Event fired when the error state may have changed (e.g. diagnostics updated).
|
|
41
|
+
* The SaveableService listens to this to re-evaluate auto-save for dirty widgets.
|
|
42
|
+
*/
|
|
43
|
+
onDidErrorStateChange: Event<void>;
|
|
44
|
+
}
|
|
45
|
+
|
|
27
46
|
@injectable()
|
|
28
47
|
export class SaveableService implements FrontendApplicationContribution {
|
|
29
48
|
|
|
49
|
+
@inject(ContributionProvider) @named(SaveErrorChecker)
|
|
50
|
+
protected readonly errorCheckers: ContributionProvider<SaveErrorChecker>;
|
|
51
|
+
|
|
30
52
|
protected saveThrottles = new Map<Widget, AutoSaveThrottle>();
|
|
31
53
|
protected saveMode: AutoSaveMode = 'off';
|
|
32
54
|
protected saveDelay = 1000;
|
|
55
|
+
protected saveWhenNoErrors = false;
|
|
33
56
|
protected shell: ApplicationShell;
|
|
34
57
|
|
|
35
58
|
protected readonly onDidAutoSaveChangeEmitter = new Emitter<AutoSaveMode>();
|
|
36
59
|
protected readonly onDidAutoSaveDelayChangeEmitter = new Emitter<number>();
|
|
60
|
+
protected readonly onDidAutoSaveConditionsChangeEmitter = new Emitter<void>();
|
|
37
61
|
|
|
38
62
|
get onDidAutoSaveChange(): Event<AutoSaveMode> {
|
|
39
63
|
return this.onDidAutoSaveChangeEmitter.event;
|
|
@@ -43,6 +67,10 @@ export class SaveableService implements FrontendApplicationContribution {
|
|
|
43
67
|
return this.onDidAutoSaveDelayChangeEmitter.event;
|
|
44
68
|
}
|
|
45
69
|
|
|
70
|
+
get onDidAutoSaveConditionsChange(): Event<void> {
|
|
71
|
+
return this.onDidAutoSaveConditionsChangeEmitter.event;
|
|
72
|
+
}
|
|
73
|
+
|
|
46
74
|
get autoSave(): AutoSaveMode {
|
|
47
75
|
return this.saveMode;
|
|
48
76
|
}
|
|
@@ -59,8 +87,22 @@ export class SaveableService implements FrontendApplicationContribution {
|
|
|
59
87
|
this.updateAutoSaveDelay(value);
|
|
60
88
|
}
|
|
61
89
|
|
|
90
|
+
get autoSaveWhenNoErrors(): boolean {
|
|
91
|
+
return this.saveWhenNoErrors;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
set autoSaveWhenNoErrors(value: boolean) {
|
|
95
|
+
this.saveWhenNoErrors = value;
|
|
96
|
+
}
|
|
97
|
+
|
|
62
98
|
onDidInitializeLayout(app: FrontendApplication): void {
|
|
63
99
|
this.shell = app.shell;
|
|
100
|
+
// Listen to error state changes from all registered error checkers
|
|
101
|
+
for (const checker of this.errorCheckers.getContributions()) {
|
|
102
|
+
checker.onDidErrorStateChange(() => {
|
|
103
|
+
this.onDidAutoSaveConditionsChangeEmitter.fire();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
64
106
|
// Register restored editors first
|
|
65
107
|
for (const widget of this.shell.widgets) {
|
|
66
108
|
const saveable = Saveable.get(widget);
|
|
@@ -165,9 +207,16 @@ export class SaveableService implements FrontendApplicationContribution {
|
|
|
165
207
|
if (uri?.scheme === UNTITLED_SCHEME) {
|
|
166
208
|
// Never auto-save untitled documents
|
|
167
209
|
return false;
|
|
168
|
-
} else {
|
|
169
|
-
return saveable.autosaveable !== false && saveable.dirty;
|
|
170
210
|
}
|
|
211
|
+
if (saveable.autosaveable === false || !saveable.dirty) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if (this.saveWhenNoErrors && uri) {
|
|
215
|
+
if (this.errorCheckers.getContributions().some(checker => checker.hasErrors(uri))) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return true;
|
|
171
220
|
}
|
|
172
221
|
|
|
173
222
|
protected applySaveableWidget(widget: Widget, saveable: Saveable): void {
|
|
@@ -314,6 +363,9 @@ export class AutoSaveThrottle implements Disposable {
|
|
|
314
363
|
}),
|
|
315
364
|
saveService.onDidAutoSaveDelayChange(() => {
|
|
316
365
|
this.throttledSave(true);
|
|
366
|
+
}),
|
|
367
|
+
saveService.onDidAutoSaveConditionsChange(() => {
|
|
368
|
+
this.throttledSave();
|
|
317
369
|
})
|
|
318
370
|
);
|
|
319
371
|
}
|
|
@@ -24,6 +24,7 @@ import { ContextMenuRenderer } from '../../context-menu-renderer';
|
|
|
24
24
|
import { TabBarToolbarItem } from './tab-toolbar-item';
|
|
25
25
|
import { ContextKeyService, ContextMatcher } from '../../context-key-service';
|
|
26
26
|
import { CommandMenu, CompoundMenuNode, ContextExpressionMatcher, Group, MenuModelRegistry, MenuNode, MenuPath, RenderedMenuNode, Submenu } from '../../../common/menu';
|
|
27
|
+
import { combineWhenExpressions } from '../../menu/utils';
|
|
27
28
|
|
|
28
29
|
export const TOOLBAR_WRAPPER_ID_SUFFIX = '-as-tabbar-toolbar-item';
|
|
29
30
|
|
|
@@ -128,6 +129,9 @@ export class SubmenuAsToolbarItemWrapper extends AbstractToolbarMenuWrapper impl
|
|
|
128
129
|
super(effectiveMenuPath, commandRegistry, menuRegistry, contextKeyService, contextMenuRenderer);
|
|
129
130
|
}
|
|
130
131
|
priority?: number | undefined;
|
|
132
|
+
get when(): string | undefined {
|
|
133
|
+
return this.menuNode.when;
|
|
134
|
+
}
|
|
131
135
|
|
|
132
136
|
executeCommand(widget: Widget, e: React.MouseEvent<HTMLDivElement, MouseEvent>): void {
|
|
133
137
|
}
|
|
@@ -164,6 +168,10 @@ export class CommandMenuAsToolbarItemWrapper extends AbstractToolbarMenuWrapper
|
|
|
164
168
|
super(effectiveMenuPath, commandRegistry, menuRegistry, contextKeyService, contextMenuRenderer);
|
|
165
169
|
}
|
|
166
170
|
|
|
171
|
+
get when(): string | undefined {
|
|
172
|
+
return this.menuNode.when;
|
|
173
|
+
}
|
|
174
|
+
|
|
167
175
|
isVisible(widget: Widget): boolean {
|
|
168
176
|
return this.menuNode.isVisible(this.effectiveMenuPath, this.contextKeyService, widget.node, widget);
|
|
169
177
|
}
|
|
@@ -199,6 +207,10 @@ export class ToolbarActionWrapper extends AbstractToolbarMenuWrapper implements
|
|
|
199
207
|
super(effectiveMenuPath, commandRegistry, menuRegistry, contextKeyService, contextMenuRenderer);
|
|
200
208
|
}
|
|
201
209
|
|
|
210
|
+
get when(): string | undefined {
|
|
211
|
+
return combineWhenExpressions(this.toolbarItem.when, this.menuNode?.when);
|
|
212
|
+
}
|
|
213
|
+
|
|
202
214
|
override isEnabled(widget?: Widget): boolean {
|
|
203
215
|
return this.toolbarItem.command ? this.commandRegistry.isEnabled(this.toolbarItem.command, widget) : !!this.toolbarItem.menuPath;
|
|
204
216
|
}
|
|
@@ -26,7 +26,7 @@ import { CommandMenuAsToolbarItemWrapper, SubmenuAsToolbarItemWrapper, ToolbarAc
|
|
|
26
26
|
import { KeybindingRegistry } from '../../keybinding';
|
|
27
27
|
import { LabelParser } from '../../label-parser';
|
|
28
28
|
import { ContextMenuRenderer } from '../../context-menu-renderer';
|
|
29
|
-
import { CommandMenu, CompoundMenuNode, RenderedMenuNode } from '../../../common/menu';
|
|
29
|
+
import { CommandMenu, CompoundMenuNode, MenuNode, RenderedMenuNode } from '../../../common/menu';
|
|
30
30
|
import { ReactToolbarItemImpl, RenderedToolbarItemImpl, TabBarToolbarItem } from './tab-toolbar-item';
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -168,6 +168,45 @@ export class TabBarToolbarRegistry implements FrontendApplicationContribution {
|
|
|
168
168
|
return result;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Collects all context keys referenced by toolbar items and delegated menu nodes
|
|
173
|
+
* that may participate in rendering for the given widget.
|
|
174
|
+
*/
|
|
175
|
+
collectContextKeys(widget: Widget): Set<string> {
|
|
176
|
+
const contextKeys = new Set<string>();
|
|
177
|
+
if (widget.isDisposed) {
|
|
178
|
+
return contextKeys;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (const item of this.items.values()) {
|
|
182
|
+
if (item.when) {
|
|
183
|
+
this.contextKeyService.parseKeys(item.when)?.forEach(key => contextKeys.add(key));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
for (const delegate of this.menuDelegates.values()) {
|
|
188
|
+
if (!delegate.isVisible(widget)) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const menu = this.menuRegistry.getMenu(delegate.menuPath);
|
|
192
|
+
if (menu) {
|
|
193
|
+
this.collectMenuContextKeys(menu, contextKeys);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return contextKeys;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
protected collectMenuContextKeys(menuNode: MenuNode, contextKeys: Set<string>): void {
|
|
200
|
+
if (menuNode.when) {
|
|
201
|
+
this.contextKeyService.parseKeys(menuNode.when)?.forEach(key => contextKeys.add(key));
|
|
202
|
+
}
|
|
203
|
+
if (CompoundMenuNode.is(menuNode)) {
|
|
204
|
+
for (const child of menuNode.children) {
|
|
205
|
+
this.collectMenuContextKeys(child, contextKeys);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
171
210
|
unregisterItem(id: string): void {
|
|
172
211
|
if (this.items.delete(id)) {
|
|
173
212
|
this.fireOnDidChange();
|
|
@@ -53,6 +53,7 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
53
53
|
protected contextKeyListener: Disposable | undefined;
|
|
54
54
|
protected toDisposeOnUpdateItems: DisposableCollection = new DisposableCollection();
|
|
55
55
|
|
|
56
|
+
protected toolbarContextKeys = new Set<string>();
|
|
56
57
|
protected keybindingContextKeys = new Set<string>();
|
|
57
58
|
|
|
58
59
|
@inject(CommandRegistry) protected readonly commands: CommandRegistry;
|
|
@@ -74,7 +75,9 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
74
75
|
this.toDispose.pushAll([
|
|
75
76
|
this.keybindings.onKeybindingsChanged(() => this.maybeUpdate()),
|
|
76
77
|
this.contextKeyService.onDidChange(e => {
|
|
77
|
-
if (e.affects(this.
|
|
78
|
+
if (this.current && e.affects(this.toolbarContextKeys)) {
|
|
79
|
+
this.updateTarget(this.current);
|
|
80
|
+
} else if (e.affects(this.keybindingContextKeys)) {
|
|
78
81
|
this.maybeUpdate();
|
|
79
82
|
}
|
|
80
83
|
}),
|
|
@@ -85,11 +88,12 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
85
88
|
]);
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
updateItems(items: Array<TabBarToolbarItem>, current: Widget | undefined): void {
|
|
91
|
+
updateItems(items: Array<TabBarToolbarItem>, current: Widget | undefined, contextKeys: Set<string> = new Set()): void {
|
|
89
92
|
this.toDisposeOnUpdateItems.dispose();
|
|
90
93
|
this.toDisposeOnUpdateItems = new DisposableCollection();
|
|
91
94
|
this.inline.clear();
|
|
92
95
|
this.more.clear();
|
|
96
|
+
this.toolbarContextKeys = contextKeys;
|
|
93
97
|
|
|
94
98
|
for (const item of items.sort(TabBarToolbarAction.PRIORITY_COMPARATOR).reverse()) {
|
|
95
99
|
|
|
@@ -98,7 +102,6 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
98
102
|
} else {
|
|
99
103
|
this.more.set(item.id, item);
|
|
100
104
|
}
|
|
101
|
-
|
|
102
105
|
if (item.onDidChange) {
|
|
103
106
|
this.toDisposeOnUpdateItems.push(item.onDidChange(() => this.maybeUpdate()));
|
|
104
107
|
}
|
|
@@ -116,7 +119,8 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
116
119
|
updateTarget(current?: Widget): void {
|
|
117
120
|
const operativeWidget = TabBarDelegator.is(current) ? current.getTabBarDelegate() : current;
|
|
118
121
|
const items = operativeWidget ? this.toolbarRegistry.visibleItems(operativeWidget) : [];
|
|
119
|
-
this.
|
|
122
|
+
const contextKeys = operativeWidget ? this.toolbarRegistry.collectContextKeys(operativeWidget) : new Set<string>();
|
|
123
|
+
this.updateItems(items, operativeWidget, contextKeys);
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
protected readonly toDisposeOnSetCurrent = new DisposableCollection();
|
|
@@ -27,6 +27,7 @@ import { ActionMenuNode, GroupImpl, MenuNode } from '../../../common/menu';
|
|
|
27
27
|
|
|
28
28
|
export interface TabBarToolbarItem {
|
|
29
29
|
id: string;
|
|
30
|
+
when?: string;
|
|
30
31
|
isVisible(widget: Widget): boolean;
|
|
31
32
|
isEnabled(widget: Widget): boolean;
|
|
32
33
|
isToggled(widget: Widget): boolean;
|
|
@@ -52,6 +53,9 @@ class AbstractToolbarItemImpl<T extends TabBarToolbarActionBase> {
|
|
|
52
53
|
get id(): string {
|
|
53
54
|
return this.action.id;
|
|
54
55
|
}
|
|
56
|
+
get when(): string | undefined {
|
|
57
|
+
return this.action.when;
|
|
58
|
+
}
|
|
55
59
|
get group(): string | undefined {
|
|
56
60
|
return this.action.group;
|
|
57
61
|
}
|
|
@@ -78,13 +78,13 @@
|
|
|
78
78
|
|
|
79
79
|
html,
|
|
80
80
|
body {
|
|
81
|
+
overflow: hidden;
|
|
81
82
|
height: 100vh;
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
body {
|
|
85
86
|
margin: 0;
|
|
86
87
|
padding: 0;
|
|
87
|
-
overflow: hidden;
|
|
88
88
|
font-family: var(--theia-ui-font-family);
|
|
89
89
|
background: var(--theia-editor-background);
|
|
90
90
|
color: var(--theia-foreground);
|
|
@@ -14,123 +14,5 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@injectable()
|
|
21
|
-
export class FuzzySearch {
|
|
22
|
-
|
|
23
|
-
private static readonly PRE = '\x01';
|
|
24
|
-
private static readonly POST = '\x02';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Filters the input and returns with an array that contains all items that match the pattern.
|
|
28
|
-
*/
|
|
29
|
-
async filter<T>(input: FuzzySearch.Input<T>): Promise<FuzzySearch.Match<T>[]> {
|
|
30
|
-
return fuzzy.filter(input.pattern, input.items.slice(), {
|
|
31
|
-
pre: FuzzySearch.PRE,
|
|
32
|
-
post: FuzzySearch.POST,
|
|
33
|
-
extract: input.transform
|
|
34
|
-
}).sort(this.sortResults.bind(this)).map(this.mapResult.bind(this));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
protected sortResults<T>(left: fuzzy.FilterResult<T>, right: fuzzy.FilterResult<T>): number {
|
|
38
|
-
return left.index - right.index;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
protected mapResult<T>(result: fuzzy.FilterResult<T>): FuzzySearch.Match<T> {
|
|
42
|
-
return {
|
|
43
|
-
item: result.original,
|
|
44
|
-
ranges: this.mapRanges(result.string)
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
protected mapRanges(input: string): ReadonlyArray<FuzzySearch.Range> {
|
|
49
|
-
const copy = input.split('').filter(s => s !== '');
|
|
50
|
-
const ranges: FuzzySearch.Range[] = [];
|
|
51
|
-
const validate = (pre: number, post: number) => {
|
|
52
|
-
if (preIndex > postIndex || (preIndex === -1) !== (postIndex === -1)) {
|
|
53
|
-
throw new Error(`Error when trying to map ranges. Escaped string was: '${input}. [${[...input].join('|')}]'`);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
let preIndex = copy.indexOf(FuzzySearch.PRE);
|
|
57
|
-
let postIndex = copy.indexOf(FuzzySearch.POST);
|
|
58
|
-
validate(preIndex, postIndex);
|
|
59
|
-
while (preIndex !== -1 && postIndex !== -1) {
|
|
60
|
-
ranges.push({
|
|
61
|
-
offset: preIndex,
|
|
62
|
-
length: postIndex - preIndex - 1
|
|
63
|
-
});
|
|
64
|
-
copy.splice(postIndex, 1);
|
|
65
|
-
copy.splice(preIndex, 1);
|
|
66
|
-
preIndex = copy.indexOf(FuzzySearch.PRE);
|
|
67
|
-
postIndex = copy.indexOf(FuzzySearch.POST);
|
|
68
|
-
}
|
|
69
|
-
if (ranges.length === 0) {
|
|
70
|
-
throw new Error(`Unexpected zero ranges for match-string: ${input}.`);
|
|
71
|
-
}
|
|
72
|
-
return ranges;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Fuzzy searcher.
|
|
79
|
-
*/
|
|
80
|
-
export namespace FuzzySearch {
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* A range representing the match region.
|
|
84
|
-
*/
|
|
85
|
-
export interface Range {
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The zero based offset of the match region.
|
|
89
|
-
*/
|
|
90
|
-
readonly offset: number;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* The length of the match region.
|
|
94
|
-
*/
|
|
95
|
-
readonly length: number;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* A fuzzy search match.
|
|
100
|
-
*/
|
|
101
|
-
export interface Match<T> {
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* The original item.
|
|
105
|
-
*/
|
|
106
|
-
readonly item: T;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* An array of ranges representing the match regions.
|
|
110
|
-
*/
|
|
111
|
-
readonly ranges: ReadonlyArray<Range>;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* The fuzzy search input.
|
|
116
|
-
*/
|
|
117
|
-
export interface Input<T> {
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* The pattern to match.
|
|
121
|
-
*/
|
|
122
|
-
readonly pattern: string;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* The items to filter based on the `pattern`.
|
|
126
|
-
*/
|
|
127
|
-
readonly items: ReadonlyArray<T>;
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Function that extracts the string from the inputs which will be used to evaluate the fuzzy matching filter.
|
|
131
|
-
*/
|
|
132
|
-
readonly transform: (item: T) => string;
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
}
|
|
17
|
+
// Re-export from common location for backward compatibility.
|
|
18
|
+
export { FuzzySearch } from '../../common/fuzzy-search';
|
|
@@ -257,8 +257,7 @@ export class TreeViewWelcomeWidget extends TreeWidget {
|
|
|
257
257
|
event.stopPropagation();
|
|
258
258
|
|
|
259
259
|
if (value.startsWith('command:')) {
|
|
260
|
-
|
|
261
|
-
this.commands.executeCommand(command);
|
|
260
|
+
open(this.openerService, new URI(value));
|
|
262
261
|
} else if (value.startsWith('file:')) {
|
|
263
262
|
const uri = value.replace('file:', '');
|
|
264
263
|
open(this.openerService, new URI(CodeUri.file(uri).toString()));
|
|
@@ -60,6 +60,7 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
|
|
|
60
60
|
protected mountedListeners: Map<string, EventListenerOrEventListenerObject> = new Map();
|
|
61
61
|
protected optimalWidth = 0;
|
|
62
62
|
protected optimalHeight = 0;
|
|
63
|
+
protected resizeObserver: ResizeObserver | undefined;
|
|
63
64
|
|
|
64
65
|
constructor(props: SelectComponentProps) {
|
|
65
66
|
super(props);
|
|
@@ -148,14 +149,16 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
|
|
|
148
149
|
return optimal + 20; // Just to be safe, add another 20 pixels here
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
const hide = (event:
|
|
152
|
+
protected attachListeners(): void {
|
|
153
|
+
const hide = (event: Event) => {
|
|
153
154
|
if (!this.dropdownRef.current?.contains(event.target as Node)) {
|
|
154
155
|
this.hide();
|
|
155
156
|
}
|
|
156
157
|
};
|
|
158
|
+
const hideOnResize = () => this.hide();
|
|
157
159
|
this.mountedListeners.set('scroll', hide);
|
|
158
160
|
this.mountedListeners.set('wheel', hide);
|
|
161
|
+
this.mountedListeners.set('resize', hideOnResize);
|
|
159
162
|
|
|
160
163
|
let parent = this.fieldRef.current?.parentElement;
|
|
161
164
|
while (parent) {
|
|
@@ -170,9 +173,43 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
|
|
|
170
173
|
for (const [key, listener] of this.mountedListeners.entries()) {
|
|
171
174
|
window.addEventListener(key, listener);
|
|
172
175
|
}
|
|
176
|
+
|
|
177
|
+
// Catch Lumino sash drags globally - observe the closest lm-Widget panel
|
|
178
|
+
const fieldEl = this.fieldRef.current;
|
|
179
|
+
const resizablePanel = fieldEl?.closest('.lm-Widget') ?? fieldEl?.parentElement;
|
|
180
|
+
|
|
181
|
+
if (resizablePanel && typeof ResizeObserver !== 'undefined') {
|
|
182
|
+
let lastWidth = 0;
|
|
183
|
+
let lastHeight = 0;
|
|
184
|
+
let isFirstFire = true;
|
|
185
|
+
|
|
186
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
187
|
+
for (const entry of entries) {
|
|
188
|
+
const { width, height } = entry.contentRect;
|
|
189
|
+
|
|
190
|
+
// Ignore the initial automatic fire when the observer attaches
|
|
191
|
+
if (isFirstFire) {
|
|
192
|
+
lastWidth = width;
|
|
193
|
+
lastHeight = height;
|
|
194
|
+
isFirstFire = false;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Only hide if the panel dimensions actually changed by more than 2 pixels
|
|
199
|
+
if (this.state.dimensions && (Math.abs(width - lastWidth) > 2 || Math.abs(height - lastHeight) > 2)) {
|
|
200
|
+
this.hide();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
lastWidth = width;
|
|
204
|
+
lastHeight = height;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
this.resizeObserver.observe(resizablePanel);
|
|
208
|
+
}
|
|
173
209
|
}
|
|
174
210
|
|
|
175
211
|
override componentWillUnmount(): void {
|
|
212
|
+
this.resizeObserver?.disconnect();
|
|
176
213
|
if (this.mountedListeners.size > 0) {
|
|
177
214
|
const eventListener = this.mountedListeners.get('scroll')!;
|
|
178
215
|
let parent = this.fieldRef.current?.parentElement;
|
|
@@ -53,8 +53,13 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
53
53
|
return undefined;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
openNewDefaultWindow():
|
|
56
|
+
async openNewDefaultWindow(): Promise<number> {
|
|
57
57
|
this.openNewWindow(`#${DEFAULT_WINDOW_HASH}`);
|
|
58
|
+
return -1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
closeWindow(windowId: number): void {
|
|
62
|
+
// No-op in browser-only mode
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
focus(): void {
|
|
@@ -20,7 +20,8 @@ import { WindowService } from '../window-service';
|
|
|
20
20
|
@injectable()
|
|
21
21
|
export class MockWindowService implements WindowService {
|
|
22
22
|
openNewWindow(): undefined { return undefined; }
|
|
23
|
-
openNewDefaultWindow():
|
|
23
|
+
async openNewDefaultWindow(): Promise<number> { return -1; }
|
|
24
|
+
closeWindow(): void { }
|
|
24
25
|
focus(): void { }
|
|
25
26
|
reload(): void { }
|
|
26
27
|
isSafeToShutDown(): Promise<boolean> { return Promise.resolve(true); }
|
|
@@ -39,8 +39,16 @@ export interface WindowService {
|
|
|
39
39
|
/**
|
|
40
40
|
* Opens a new default window.
|
|
41
41
|
* - In electron and in the browser it will open the default window without a pre-defined content.
|
|
42
|
+
* @returns a window identifier that can be passed to {@link closeWindow}, or -1 if not supported.
|
|
42
43
|
*/
|
|
43
|
-
openNewDefaultWindow(params?: WindowReloadOptions):
|
|
44
|
+
openNewDefaultWindow(params?: WindowReloadOptions): Promise<number>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Closes a window previously opened by {@link openNewDefaultWindow}.
|
|
48
|
+
* @param windowId the identifier returned by {@link openNewDefaultWindow}.
|
|
49
|
+
* No-op if the window does not exist or the platform does not support it.
|
|
50
|
+
*/
|
|
51
|
+
closeWindow(windowId: number): void;
|
|
44
52
|
|
|
45
53
|
/**
|
|
46
54
|
* Reveal and focuses the current window
|