@workbench-kit/shell-react 0.0.2-prototype.0.2.10
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 +98 -0
- package/package.json +51 -0
- package/src/chat/ai-mock-proposals.ts +39 -0
- package/src/chat/command-input.ts +52 -0
- package/src/chat/command-policy.ts +54 -0
- package/src/chat/command-surface.tsx +155 -0
- package/src/chat/use-chat-command-proposals.ts +194 -0
- package/src/chat/view-data.ts +20 -0
- package/src/chat/view.tsx +220 -0
- package/src/commands/inspector-surface.tsx +46 -0
- package/src/commands/use-command-descriptors.ts +41 -0
- package/src/commands/use-context-key-revision.ts +18 -0
- package/src/commands/view-data.ts +17 -0
- package/src/commands/view.tsx +43 -0
- package/src/devtools/WorkbenchDevtoolsPanel.tsx +124 -0
- package/src/devtools/WorkbenchDevtoolsShell.tsx +17 -0
- package/src/devtools/index.ts +11 -0
- package/src/devtools/use-workbench-devtools-snapshot.ts +84 -0
- package/src/devtools/workbench-devtools-snapshot.ts +140 -0
- package/src/devtools/workbench-devtools.css +82 -0
- package/src/editor/area-dnd.ts +69 -0
- package/src/editor/area-model.ts +71 -0
- package/src/editor/area.css +454 -0
- package/src/editor/area.tsx +676 -0
- package/src/editor/host-surface.tsx +691 -0
- package/src/editor/markdown-document-view-data.ts +16 -0
- package/src/editor/pane-visibility.ts +130 -0
- package/src/editor/resource.ts +36 -0
- package/src/editor/state-storage.ts +182 -0
- package/src/editor/tab-context-menu.ts +118 -0
- package/src/editor/use-editor.ts +138 -0
- package/src/editor/view-providers.tsx +504 -0
- package/src/editor/workspace-file-availability.ts +15 -0
- package/src/editor/workspace-reconcile.tsx +31 -0
- package/src/explorer/context-menu.ts +114 -0
- package/src/explorer/create-command-workspace-explorer-port.ts +86 -0
- package/src/explorer/reveal.ts +112 -0
- package/src/explorer/search-view-data.ts +15 -0
- package/src/explorer/search-view.tsx +65 -0
- package/src/explorer/use-active-workspace-path.ts +15 -0
- package/src/explorer/view-data.ts +58 -0
- package/src/explorer/view.tsx +227 -0
- package/src/extensions/context-menu.ts +52 -0
- package/src/extensions/management-model.ts +313 -0
- package/src/extensions/use-extension-management.ts +241 -0
- package/src/extensions/view-data.ts +19 -0
- package/src/extensions/view.tsx +63 -0
- package/src/field-remap/chrome-labels.ts +74 -0
- package/src/field-remap/convert-note-editor.tsx +206 -0
- package/src/field-remap/convert-palette.tsx +126 -0
- package/src/field-remap/demo.tsx +105 -0
- package/src/field-remap/detail-panel.tsx +659 -0
- package/src/field-remap/editor-surface.tsx +36 -0
- package/src/field-remap/flow-adapter.ts +838 -0
- package/src/field-remap/flow-ops.ts +442 -0
- package/src/field-remap/flow.tsx +948 -0
- package/src/field-remap/graph.tsx +559 -0
- package/src/field-remap/index.ts +88 -0
- package/src/field-remap/io-class-browse.tsx +145 -0
- package/src/field-remap/jsonata-transform.ts +166 -0
- package/src/field-remap/panel.tsx +466 -0
- package/src/field-remap/samples.ts +507 -0
- package/src/field-remap/shape-io-editor.tsx +170 -0
- package/src/field-remap/table-mapping-adapter.ts +59 -0
- package/src/field-remap/transform-options-editor.tsx +312 -0
- package/src/field-remap/tree.tsx +404 -0
- package/src/field-remap/view-data.ts +16 -0
- package/src/field-remap/view.css +1367 -0
- package/src/field-remap/view.tsx +86 -0
- package/src/index.ts +294 -0
- package/src/jdw/document-view-data.ts +31 -0
- package/src/jdw/json-form-source-patch.ts +323 -0
- package/src/jdw/lab-view-data.ts +25 -0
- package/src/jdw/lab-view.css +21 -0
- package/src/jdw/lab-view.tsx +79 -0
- package/src/jdw/widget-form-view.tsx +68 -0
- package/src/jdw/widget-preview-view.tsx +54 -0
- package/src/management/keybinding-overrides-storage.ts +49 -0
- package/src/management/keybinding-settings.tsx +16 -0
- package/src/management/palette-commands.ts +38 -0
- package/src/management/preference-settings-storage.ts +50 -0
- package/src/management/settings-ids.ts +12 -0
- package/src/management/settings.tsx +96 -0
- package/src/management/use-command-management.ts +191 -0
- package/src/management/use-keybinding-management.ts +130 -0
- package/src/shell/model.tsx +149 -0
- package/src/shell/provider.tsx +606 -0
- package/src/shell/secondary-actions.tsx +59 -0
- package/src/shell/settings-constants.ts +9 -0
- package/src/shell/settings.tsx +599 -0
- package/src/shell/shell.tsx +680 -0
- package/src/shell/titlebar-layout-controls.tsx +4 -0
- package/src/shell/view-host.tsx +212 -0
- package/src/workbench/appearance-storage.ts +107 -0
- package/src/workbench/command-host.tsx +243 -0
- package/src/workbench/command-palette.ts +208 -0
- package/src/workbench/keybinding-bridge.ts +54 -0
- package/src/workbench/layout-storage.ts +134 -0
- package/src/workbench/profile-modal.tsx +118 -0
- package/src/workbench/shell-command-registration.ts +58 -0
- package/src/workbench/startup-gate.tsx +136 -0
- package/src/workbench/status-sections.ts +43 -0
- package/src/workbench/use-persisted-appearance.ts +33 -0
- package/src/workbench/user-commands.ts +46 -0
- package/src/workbench/workspace-view-state.ts +35 -0
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useCallback,
|
|
4
|
+
useContext,
|
|
5
|
+
useEffect,
|
|
6
|
+
useMemo,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
type ReactNode,
|
|
10
|
+
} from 'react';
|
|
11
|
+
import {
|
|
12
|
+
BUILTIN_WORKBENCH_EXTENSIONS,
|
|
13
|
+
collectConfigurationDefaults,
|
|
14
|
+
createEditorService,
|
|
15
|
+
ExtensionRegistry,
|
|
16
|
+
LayoutService,
|
|
17
|
+
loadInstalledExtensions,
|
|
18
|
+
mergeExtensionsConfigWithInstallState,
|
|
19
|
+
PreferenceService,
|
|
20
|
+
registerEditorSaveCommand,
|
|
21
|
+
registerHostWorkbenchThemes,
|
|
22
|
+
resolveInstalledAvailableExtensions,
|
|
23
|
+
resolveWorkbenchExtensions,
|
|
24
|
+
SAMPLE_WORKBENCH_EXTENSIONS,
|
|
25
|
+
DEFAULT_INSTALLED_EXTENSIONS_STORAGE_KEY,
|
|
26
|
+
WORKBENCH_EDITOR_SERVICE_CAPABILITY_ID,
|
|
27
|
+
verifyWorkbenchExtensionsAgainstLock,
|
|
28
|
+
type EditorState,
|
|
29
|
+
type EditorService,
|
|
30
|
+
type ExtensionIntegrityMode,
|
|
31
|
+
type PreferenceService as PreferenceServiceType,
|
|
32
|
+
type WorkbenchHostThemeRegistration,
|
|
33
|
+
type WorkbenchStorageAdapter,
|
|
34
|
+
type WorkbenchEditorSavePort,
|
|
35
|
+
type WorkbenchExtensionDescription,
|
|
36
|
+
type WorkbenchLayoutStateInput,
|
|
37
|
+
} from '@workbench-kit/workbench-core';
|
|
38
|
+
import {
|
|
39
|
+
ContextKeyService,
|
|
40
|
+
createWorkbenchPermissionContextKeys,
|
|
41
|
+
type ContextKeyValue,
|
|
42
|
+
} from '@workbench-kit/platform';
|
|
43
|
+
import type {
|
|
44
|
+
WorkbenchExtensionsConfig,
|
|
45
|
+
WorkbenchExtensionsLock,
|
|
46
|
+
WorkbenchKeybindingDefinition,
|
|
47
|
+
WorkbenchSettingsConfig,
|
|
48
|
+
WorkbenchUserCommandDefinition,
|
|
49
|
+
} from '@workbench-kit/workbench-config';
|
|
50
|
+
import {
|
|
51
|
+
DEFAULT_WORKBENCH_LAYOUT_STORAGE_KEY,
|
|
52
|
+
isWorkbenchLayoutPersistenceAvailable,
|
|
53
|
+
resolvePersistedWorkbenchLayout,
|
|
54
|
+
writePersistedWorkbenchLayout,
|
|
55
|
+
} from '../workbench/layout-storage.js';
|
|
56
|
+
import {
|
|
57
|
+
DEFAULT_WORKBENCH_EDITOR_STATE_STORAGE_KEY,
|
|
58
|
+
isWorkbenchEditorStatePersistenceAvailable,
|
|
59
|
+
readPersistedEditorState,
|
|
60
|
+
writePersistedEditorState,
|
|
61
|
+
} from '../editor/state-storage.js';
|
|
62
|
+
import {
|
|
63
|
+
DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY,
|
|
64
|
+
isWorkbenchKeybindingPersistenceAvailable,
|
|
65
|
+
readPersistedKeybindingOverrides,
|
|
66
|
+
writePersistedKeybindingOverrides,
|
|
67
|
+
} from '../management/keybinding-overrides-storage.js';
|
|
68
|
+
import {
|
|
69
|
+
BUILTIN_EXPLORER_VIEW_CONTAINER_ID,
|
|
70
|
+
publishExplorerRevealRequest,
|
|
71
|
+
runExplorerHostCommandSideEffects,
|
|
72
|
+
} from '../explorer/reveal.js';
|
|
73
|
+
import {
|
|
74
|
+
BUILTIN_EXTENSIONS_FOCUS_COMMAND_ID,
|
|
75
|
+
BUILTIN_EXTENSIONS_VIEW_CONTAINER_ID,
|
|
76
|
+
} from '../extensions/view-data.js';
|
|
77
|
+
import {
|
|
78
|
+
DEFAULT_WORKBENCH_LOCAL_PREFERENCE_STORAGE_KEY,
|
|
79
|
+
isWorkbenchLocalPreferencePersistenceAvailable,
|
|
80
|
+
readPersistedLocalPreferences,
|
|
81
|
+
writePersistedLocalPreferences,
|
|
82
|
+
} from '../management/preference-settings-storage.js';
|
|
83
|
+
import { registerWorkbenchUserCommands } from '../workbench/user-commands.js';
|
|
84
|
+
import { EditorWorkspaceReconciler } from '../editor/workspace-reconcile.js';
|
|
85
|
+
import {
|
|
86
|
+
DEFAULT_EDITOR_DOCUMENT_VIEW_PROVIDERS,
|
|
87
|
+
type EditorDocumentViewProvider,
|
|
88
|
+
} from '../editor/view-providers.js';
|
|
89
|
+
import type { EditorDocumentViewProviderRegistry } from '@workbench-kit/workbench-core';
|
|
90
|
+
|
|
91
|
+
export interface WorkbenchWorkspaceHostPort extends WorkbenchEditorSavePort {
|
|
92
|
+
readonly capabilityId?: string | undefined;
|
|
93
|
+
readonly service?: unknown;
|
|
94
|
+
dispose?(): void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type { WorkbenchStorageAdapter };
|
|
98
|
+
|
|
99
|
+
const DEFAULT_AVAILABLE_EXTENSIONS = [
|
|
100
|
+
...BUILTIN_WORKBENCH_EXTENSIONS,
|
|
101
|
+
...SAMPLE_WORKBENCH_EXTENSIONS,
|
|
102
|
+
] as const;
|
|
103
|
+
|
|
104
|
+
export interface WorkbenchProviderProps {
|
|
105
|
+
availableExtensions?: readonly WorkbenchExtensionDescription[];
|
|
106
|
+
children: ReactNode;
|
|
107
|
+
contextKeyValues?: Readonly<Record<string, ContextKeyValue>> | undefined;
|
|
108
|
+
documentViewProviders?: readonly EditorDocumentViewProvider[] | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* When set with `extensionIntegrityMode` other than `off`, enabled extensions
|
|
111
|
+
* are checked against the lock before registration.
|
|
112
|
+
*/
|
|
113
|
+
extensionsLock?: WorkbenchExtensionsLock | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* Lock verification mode. Default `off` preserves existing hosts.
|
|
116
|
+
* Sample hosts may opt into `fail-closed`.
|
|
117
|
+
*/
|
|
118
|
+
extensionIntegrityMode?: ExtensionIntegrityMode | undefined;
|
|
119
|
+
extensionsConfig?: WorkbenchExtensionsConfig;
|
|
120
|
+
editorStateStorage?: WorkbenchStorageAdapter;
|
|
121
|
+
editorStateStorageKey?: string;
|
|
122
|
+
hostThemes?: readonly WorkbenchHostThemeRegistration[];
|
|
123
|
+
initialKeybindingOverrides?: readonly WorkbenchKeybindingDefinition[];
|
|
124
|
+
initialEditorState?: EditorState;
|
|
125
|
+
initialLayout?: WorkbenchLayoutStateInput;
|
|
126
|
+
initialWorkspaceSettings?: WorkbenchSettingsConfig;
|
|
127
|
+
includeDefaultDocumentViewProviders?: boolean | undefined;
|
|
128
|
+
installedExtensionsStorage?: WorkbenchStorageAdapter;
|
|
129
|
+
installedExtensionsStorageKey?: string;
|
|
130
|
+
keybindingOverridesStorage?: WorkbenchStorageAdapter;
|
|
131
|
+
keybindingOverridesStorageKey?: string;
|
|
132
|
+
layoutStorage?: WorkbenchStorageAdapter;
|
|
133
|
+
layoutStorageKey?: string;
|
|
134
|
+
localPreferenceStorage?: WorkbenchStorageAdapter;
|
|
135
|
+
localPreferenceStorageKey?: string;
|
|
136
|
+
onKeybindingOverridesChange?:
|
|
137
|
+
((overrides: readonly WorkbenchKeybindingDefinition[]) => void) | undefined;
|
|
138
|
+
persistEditorState?: boolean;
|
|
139
|
+
persistKeybindingOverrides?: boolean;
|
|
140
|
+
persistLayout?: boolean;
|
|
141
|
+
persistLocalPreferences?: boolean;
|
|
142
|
+
userCommands?: readonly WorkbenchUserCommandDefinition[];
|
|
143
|
+
workspaceHostPort?: WorkbenchWorkspaceHostPort | undefined;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface WorkbenchContextValue {
|
|
147
|
+
activateCommand(commandId: string): Promise<readonly { readonly extensionId: string }[]>;
|
|
148
|
+
contextKeyService: ContextKeyService;
|
|
149
|
+
editorDocumentViewProviders: EditorDocumentViewProviderRegistry;
|
|
150
|
+
editorService: EditorService;
|
|
151
|
+
executeCommand(commandId: string, ...args: unknown[]): Promise<unknown>;
|
|
152
|
+
extensionRegistry: ExtensionRegistry;
|
|
153
|
+
installedExtensionsStorage?: WorkbenchStorageAdapter;
|
|
154
|
+
installedExtensionsStorageKey: string;
|
|
155
|
+
keybindingOverrides: readonly WorkbenchKeybindingDefinition[];
|
|
156
|
+
layoutService: LayoutService;
|
|
157
|
+
missingExtensionIds: readonly string[];
|
|
158
|
+
preferenceService: PreferenceServiceType;
|
|
159
|
+
resetCommandKeybindingOverride(commandId: string): void;
|
|
160
|
+
setCommandKeybindingOverride(commandId: string, key: string): void;
|
|
161
|
+
waitForExtensionStartup(): Promise<void>;
|
|
162
|
+
workspaceHostPort?: WorkbenchWorkspaceHostPort | undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface WorkbenchProviderServices {
|
|
166
|
+
activateStartup(): void;
|
|
167
|
+
dispose(): void;
|
|
168
|
+
editorDocumentViewProviders: EditorDocumentViewProviderRegistry;
|
|
169
|
+
editorService: EditorService;
|
|
170
|
+
extensionRegistry: ExtensionRegistry;
|
|
171
|
+
layoutService: LayoutService;
|
|
172
|
+
missingExtensionIds: readonly string[];
|
|
173
|
+
preferenceService: PreferenceServiceType;
|
|
174
|
+
waitForExtensionStartup(): Promise<void>;
|
|
175
|
+
workspaceHostPort?: WorkbenchWorkspaceHostPort | undefined;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
interface DeferredProviderDispose {
|
|
179
|
+
readonly services: WorkbenchProviderServices;
|
|
180
|
+
readonly timeout: ReturnType<typeof setTimeout>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const WorkbenchContext = createContext<WorkbenchContextValue | undefined>(undefined);
|
|
184
|
+
|
|
185
|
+
export function WorkbenchProvider({
|
|
186
|
+
availableExtensions,
|
|
187
|
+
children,
|
|
188
|
+
contextKeyValues,
|
|
189
|
+
documentViewProviders,
|
|
190
|
+
editorStateStorage,
|
|
191
|
+
editorStateStorageKey = DEFAULT_WORKBENCH_EDITOR_STATE_STORAGE_KEY,
|
|
192
|
+
extensionIntegrityMode = 'off',
|
|
193
|
+
extensionsConfig,
|
|
194
|
+
extensionsLock,
|
|
195
|
+
hostThemes = [],
|
|
196
|
+
initialEditorState,
|
|
197
|
+
initialKeybindingOverrides,
|
|
198
|
+
initialLayout,
|
|
199
|
+
initialWorkspaceSettings,
|
|
200
|
+
includeDefaultDocumentViewProviders,
|
|
201
|
+
installedExtensionsStorage,
|
|
202
|
+
installedExtensionsStorageKey = DEFAULT_INSTALLED_EXTENSIONS_STORAGE_KEY,
|
|
203
|
+
keybindingOverridesStorage,
|
|
204
|
+
keybindingOverridesStorageKey = DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY,
|
|
205
|
+
layoutStorage,
|
|
206
|
+
layoutStorageKey = DEFAULT_WORKBENCH_LAYOUT_STORAGE_KEY,
|
|
207
|
+
localPreferenceStorage,
|
|
208
|
+
localPreferenceStorageKey = DEFAULT_WORKBENCH_LOCAL_PREFERENCE_STORAGE_KEY,
|
|
209
|
+
onKeybindingOverridesChange,
|
|
210
|
+
persistEditorState,
|
|
211
|
+
persistKeybindingOverrides,
|
|
212
|
+
persistLayout,
|
|
213
|
+
persistLocalPreferences,
|
|
214
|
+
userCommands = [],
|
|
215
|
+
workspaceHostPort,
|
|
216
|
+
}: WorkbenchProviderProps) {
|
|
217
|
+
const hostAvailableExtensions = availableExtensions ?? DEFAULT_AVAILABLE_EXTENSIONS;
|
|
218
|
+
const deferredDisposeRef = useRef<DeferredProviderDispose | undefined>(undefined);
|
|
219
|
+
const shouldPersistEditorState =
|
|
220
|
+
persistEditorState ??
|
|
221
|
+
(editorStateStorage !== undefined || isWorkbenchEditorStatePersistenceAvailable());
|
|
222
|
+
const shouldPersistKeybindingOverrides =
|
|
223
|
+
persistKeybindingOverrides ??
|
|
224
|
+
(keybindingOverridesStorage !== undefined || isWorkbenchKeybindingPersistenceAvailable());
|
|
225
|
+
const shouldPersistLayout =
|
|
226
|
+
persistLayout ?? (layoutStorage !== undefined || isWorkbenchLayoutPersistenceAvailable());
|
|
227
|
+
const shouldPersistLocalPreferences =
|
|
228
|
+
persistLocalPreferences ??
|
|
229
|
+
(localPreferenceStorage !== undefined || isWorkbenchLocalPreferencePersistenceAvailable());
|
|
230
|
+
const resolvedInitialLayout = useMemo(
|
|
231
|
+
() =>
|
|
232
|
+
resolvePersistedWorkbenchLayout(initialLayout, {
|
|
233
|
+
persistLayout: shouldPersistLayout,
|
|
234
|
+
storage: layoutStorage,
|
|
235
|
+
storageKey: layoutStorageKey,
|
|
236
|
+
}),
|
|
237
|
+
[initialLayout, layoutStorage, layoutStorageKey, shouldPersistLayout],
|
|
238
|
+
);
|
|
239
|
+
const resolvedInitialEditorState = useMemo(
|
|
240
|
+
() =>
|
|
241
|
+
initialEditorState ??
|
|
242
|
+
(shouldPersistEditorState
|
|
243
|
+
? readPersistedEditorState(editorStateStorageKey, editorStateStorage)
|
|
244
|
+
: undefined),
|
|
245
|
+
[editorStateStorage, editorStateStorageKey, initialEditorState, shouldPersistEditorState],
|
|
246
|
+
);
|
|
247
|
+
const resolvedInitialKeybindingOverrides = useMemo(
|
|
248
|
+
() =>
|
|
249
|
+
initialKeybindingOverrides ??
|
|
250
|
+
(shouldPersistKeybindingOverrides
|
|
251
|
+
? readPersistedKeybindingOverrides(
|
|
252
|
+
keybindingOverridesStorageKey,
|
|
253
|
+
keybindingOverridesStorage,
|
|
254
|
+
)
|
|
255
|
+
: []),
|
|
256
|
+
[
|
|
257
|
+
initialKeybindingOverrides,
|
|
258
|
+
keybindingOverridesStorage,
|
|
259
|
+
keybindingOverridesStorageKey,
|
|
260
|
+
shouldPersistKeybindingOverrides,
|
|
261
|
+
],
|
|
262
|
+
);
|
|
263
|
+
const [keybindingOverrides, setKeybindingOverridesState] = useState(
|
|
264
|
+
resolvedInitialKeybindingOverrides,
|
|
265
|
+
);
|
|
266
|
+
const contextKeyService = useMemo(() => {
|
|
267
|
+
const service = new ContextKeyService();
|
|
268
|
+
for (const [key, value] of Object.entries(
|
|
269
|
+
createWorkbenchPermissionContextKeys({ role: 'owner' }),
|
|
270
|
+
)) {
|
|
271
|
+
service.set(key, value);
|
|
272
|
+
}
|
|
273
|
+
return service;
|
|
274
|
+
}, []);
|
|
275
|
+
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
return () => {
|
|
278
|
+
contextKeyService.dispose();
|
|
279
|
+
};
|
|
280
|
+
}, [contextKeyService]);
|
|
281
|
+
|
|
282
|
+
useEffect(() => {
|
|
283
|
+
if (contextKeyValues === undefined) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
for (const [key, value] of Object.entries(contextKeyValues)) {
|
|
288
|
+
contextKeyService.set(key, value);
|
|
289
|
+
}
|
|
290
|
+
}, [contextKeyService, contextKeyValues]);
|
|
291
|
+
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
setKeybindingOverridesState(resolvedInitialKeybindingOverrides);
|
|
294
|
+
}, [resolvedInitialKeybindingOverrides]);
|
|
295
|
+
|
|
296
|
+
const setCommandKeybindingOverride = useCallback((commandId: string, key: string) => {
|
|
297
|
+
setKeybindingOverridesState((current) => {
|
|
298
|
+
const without = current.filter((binding) => binding.command !== commandId);
|
|
299
|
+
return [...without, { command: commandId, key }];
|
|
300
|
+
});
|
|
301
|
+
}, []);
|
|
302
|
+
|
|
303
|
+
const resetCommandKeybindingOverride = useCallback((commandId: string) => {
|
|
304
|
+
setKeybindingOverridesState((current) =>
|
|
305
|
+
current.filter((binding) => binding.command !== commandId),
|
|
306
|
+
);
|
|
307
|
+
}, []);
|
|
308
|
+
|
|
309
|
+
useEffect(() => {
|
|
310
|
+
onKeybindingOverridesChange?.(keybindingOverrides);
|
|
311
|
+
if (!shouldPersistKeybindingOverrides) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
writePersistedKeybindingOverrides(
|
|
316
|
+
keybindingOverrides,
|
|
317
|
+
keybindingOverridesStorageKey,
|
|
318
|
+
keybindingOverridesStorage,
|
|
319
|
+
);
|
|
320
|
+
}, [
|
|
321
|
+
keybindingOverrides,
|
|
322
|
+
keybindingOverridesStorage,
|
|
323
|
+
keybindingOverridesStorageKey,
|
|
324
|
+
onKeybindingOverridesChange,
|
|
325
|
+
shouldPersistKeybindingOverrides,
|
|
326
|
+
]);
|
|
327
|
+
|
|
328
|
+
const resolvedInitialLocalPreferences = useMemo(
|
|
329
|
+
() =>
|
|
330
|
+
shouldPersistLocalPreferences
|
|
331
|
+
? readPersistedLocalPreferences(localPreferenceStorageKey, localPreferenceStorage)
|
|
332
|
+
: {},
|
|
333
|
+
[localPreferenceStorage, localPreferenceStorageKey, shouldPersistLocalPreferences],
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
const services = useMemo<WorkbenchProviderServices>(() => {
|
|
337
|
+
const extensionRegistry = new ExtensionRegistry();
|
|
338
|
+
const editorDocumentViewProviders = extensionRegistry.editorDocumentViews;
|
|
339
|
+
const editorDocumentViewProviderDisposables = [
|
|
340
|
+
...(includeDefaultDocumentViewProviders === false
|
|
341
|
+
? []
|
|
342
|
+
: DEFAULT_EDITOR_DOCUMENT_VIEW_PROVIDERS),
|
|
343
|
+
...(documentViewProviders ?? []),
|
|
344
|
+
].map((provider) => editorDocumentViewProviders.registerProvider(provider));
|
|
345
|
+
const layoutService = new LayoutService(resolvedInitialLayout);
|
|
346
|
+
const editorService = createEditorService({
|
|
347
|
+
editorHostFactories: extensionRegistry.editorHostFactories,
|
|
348
|
+
editorResolvers: extensionRegistry.editorResolvers,
|
|
349
|
+
initialState: resolvedInitialEditorState,
|
|
350
|
+
resolveEditorResource: workspaceHostPort?.resolveResource?.bind(workspaceHostPort),
|
|
351
|
+
});
|
|
352
|
+
const installedRecords = loadInstalledExtensions(
|
|
353
|
+
installedExtensionsStorageKey,
|
|
354
|
+
installedExtensionsStorage,
|
|
355
|
+
);
|
|
356
|
+
const baseExtensionsConfig =
|
|
357
|
+
extensionsConfig ??
|
|
358
|
+
({
|
|
359
|
+
enabled: hostAvailableExtensions.map(({ manifest }) => manifest.id),
|
|
360
|
+
recommendations: [],
|
|
361
|
+
} satisfies WorkbenchExtensionsConfig);
|
|
362
|
+
const resolvedAvailableExtensions =
|
|
363
|
+
availableExtensions === undefined
|
|
364
|
+
? resolveInstalledAvailableExtensions(
|
|
365
|
+
hostAvailableExtensions,
|
|
366
|
+
installedRecords,
|
|
367
|
+
baseExtensionsConfig.enabled,
|
|
368
|
+
)
|
|
369
|
+
: hostAvailableExtensions;
|
|
370
|
+
const config = mergeExtensionsConfigWithInstallState(baseExtensionsConfig, installedRecords);
|
|
371
|
+
const resolution = resolveWorkbenchExtensions(config, resolvedAvailableExtensions);
|
|
372
|
+
const integrity = verifyWorkbenchExtensionsAgainstLock(
|
|
373
|
+
resolution.enabledExtensions,
|
|
374
|
+
extensionsLock,
|
|
375
|
+
extensionIntegrityMode,
|
|
376
|
+
);
|
|
377
|
+
if (integrity.diagnostics.length > 0 && typeof console !== 'undefined') {
|
|
378
|
+
for (const diagnostic of integrity.diagnostics) {
|
|
379
|
+
console.warn(`[workbench-kit] ${diagnostic.message}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const extensionDisposables = extensionRegistry.registerExtensions(integrity.accepted);
|
|
383
|
+
const hostThemeDisposables = registerHostWorkbenchThemes(extensionRegistry.themes, hostThemes);
|
|
384
|
+
const editorServiceCapabilityDisposable = extensionRegistry.capabilityRegistry.register({
|
|
385
|
+
id: WORKBENCH_EDITOR_SERVICE_CAPABILITY_ID,
|
|
386
|
+
get: () => editorService,
|
|
387
|
+
});
|
|
388
|
+
const workspaceHostCapabilityDisposable =
|
|
389
|
+
workspaceHostPort?.capabilityId && workspaceHostPort.service !== undefined
|
|
390
|
+
? extensionRegistry.capabilityRegistry.register({
|
|
391
|
+
id: workspaceHostPort.capabilityId,
|
|
392
|
+
get: () => workspaceHostPort.service,
|
|
393
|
+
dispose: workspaceHostPort.dispose,
|
|
394
|
+
})
|
|
395
|
+
: undefined;
|
|
396
|
+
const saveCommandDisposable = workspaceHostPort
|
|
397
|
+
? registerEditorSaveCommand(extensionRegistry.commands, {
|
|
398
|
+
editorSavePort: workspaceHostPort,
|
|
399
|
+
editorService,
|
|
400
|
+
})
|
|
401
|
+
: undefined;
|
|
402
|
+
const userCommandDisposables = registerWorkbenchUserCommands(extensionRegistry, userCommands);
|
|
403
|
+
const preferenceService = new PreferenceService({
|
|
404
|
+
contributionDefaults: collectConfigurationDefaults(
|
|
405
|
+
extensionRegistry.configurations.getConfigurations(),
|
|
406
|
+
),
|
|
407
|
+
initialValuesByScope: {
|
|
408
|
+
local: resolvedInitialLocalPreferences,
|
|
409
|
+
workspace: initialWorkspaceSettings ?? {},
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
let startupActivation: Promise<readonly { readonly extensionId: string }[]> | undefined;
|
|
413
|
+
const ensureStartupActivation = () => {
|
|
414
|
+
startupActivation ??= extensionRegistry.activateStartup();
|
|
415
|
+
return startupActivation;
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
return {
|
|
419
|
+
activateStartup: () => {
|
|
420
|
+
void ensureStartupActivation();
|
|
421
|
+
},
|
|
422
|
+
dispose: () => {
|
|
423
|
+
saveCommandDisposable?.dispose();
|
|
424
|
+
userCommandDisposables.dispose();
|
|
425
|
+
editorServiceCapabilityDisposable.dispose();
|
|
426
|
+
workspaceHostCapabilityDisposable?.dispose();
|
|
427
|
+
hostThemeDisposables.dispose();
|
|
428
|
+
extensionDisposables.dispose();
|
|
429
|
+
if (!workspaceHostCapabilityDisposable) {
|
|
430
|
+
workspaceHostPort?.dispose?.();
|
|
431
|
+
}
|
|
432
|
+
editorService.dispose();
|
|
433
|
+
for (const disposable of editorDocumentViewProviderDisposables) {
|
|
434
|
+
disposable.dispose();
|
|
435
|
+
}
|
|
436
|
+
extensionRegistry.dispose();
|
|
437
|
+
layoutService.dispose();
|
|
438
|
+
preferenceService.dispose();
|
|
439
|
+
},
|
|
440
|
+
editorDocumentViewProviders,
|
|
441
|
+
editorService,
|
|
442
|
+
extensionRegistry,
|
|
443
|
+
layoutService,
|
|
444
|
+
missingExtensionIds: [
|
|
445
|
+
...resolution.missingExtensionIds,
|
|
446
|
+
...integrity.rejected.map((extension) => extension.manifest.id),
|
|
447
|
+
],
|
|
448
|
+
preferenceService,
|
|
449
|
+
waitForExtensionStartup: () => ensureStartupActivation().then(() => undefined),
|
|
450
|
+
workspaceHostPort,
|
|
451
|
+
};
|
|
452
|
+
}, [
|
|
453
|
+
availableExtensions,
|
|
454
|
+
documentViewProviders,
|
|
455
|
+
extensionIntegrityMode,
|
|
456
|
+
extensionsLock,
|
|
457
|
+
hostAvailableExtensions,
|
|
458
|
+
extensionsConfig,
|
|
459
|
+
hostThemes,
|
|
460
|
+
includeDefaultDocumentViewProviders,
|
|
461
|
+
initialWorkspaceSettings,
|
|
462
|
+
installedExtensionsStorage,
|
|
463
|
+
installedExtensionsStorageKey,
|
|
464
|
+
resolvedInitialEditorState,
|
|
465
|
+
resolvedInitialLayout,
|
|
466
|
+
resolvedInitialLocalPreferences,
|
|
467
|
+
userCommands,
|
|
468
|
+
workspaceHostPort,
|
|
469
|
+
]);
|
|
470
|
+
|
|
471
|
+
useEffect(() => {
|
|
472
|
+
if (!shouldPersistLayout) {
|
|
473
|
+
return undefined;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const disposable = services.layoutService.onDidChangeLayout(({ state }) => {
|
|
477
|
+
writePersistedWorkbenchLayout(state, layoutStorageKey, layoutStorage);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
return () => {
|
|
481
|
+
disposable.dispose();
|
|
482
|
+
};
|
|
483
|
+
}, [layoutStorage, layoutStorageKey, services.layoutService, shouldPersistLayout]);
|
|
484
|
+
|
|
485
|
+
useEffect(() => {
|
|
486
|
+
if (!shouldPersistEditorState) {
|
|
487
|
+
return undefined;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const disposable = services.editorService.onDidChangeEditors(({ state }) => {
|
|
491
|
+
writePersistedEditorState(state, editorStateStorageKey, editorStateStorage);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
return () => {
|
|
495
|
+
disposable.dispose();
|
|
496
|
+
};
|
|
497
|
+
}, [editorStateStorage, editorStateStorageKey, services.editorService, shouldPersistEditorState]);
|
|
498
|
+
|
|
499
|
+
useEffect(() => {
|
|
500
|
+
if (!shouldPersistLocalPreferences) {
|
|
501
|
+
return undefined;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const disposable = services.preferenceService.onDidChangePreference((event) => {
|
|
505
|
+
if (event.scope !== 'local') {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
writePersistedLocalPreferences(
|
|
510
|
+
services.preferenceService.getScopedValues('local'),
|
|
511
|
+
localPreferenceStorageKey,
|
|
512
|
+
localPreferenceStorage,
|
|
513
|
+
);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
return () => {
|
|
517
|
+
disposable.dispose();
|
|
518
|
+
};
|
|
519
|
+
}, [
|
|
520
|
+
localPreferenceStorage,
|
|
521
|
+
localPreferenceStorageKey,
|
|
522
|
+
services.preferenceService,
|
|
523
|
+
shouldPersistLocalPreferences,
|
|
524
|
+
]);
|
|
525
|
+
|
|
526
|
+
useEffect(() => {
|
|
527
|
+
const deferredDispose = deferredDisposeRef.current;
|
|
528
|
+
if (deferredDispose?.services === services) {
|
|
529
|
+
clearTimeout(deferredDispose.timeout);
|
|
530
|
+
deferredDisposeRef.current = undefined;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
services.activateStartup();
|
|
534
|
+
|
|
535
|
+
return () => {
|
|
536
|
+
const timeout = setTimeout(() => {
|
|
537
|
+
if (deferredDisposeRef.current?.services === services) {
|
|
538
|
+
deferredDisposeRef.current = undefined;
|
|
539
|
+
}
|
|
540
|
+
services.dispose();
|
|
541
|
+
}, 0);
|
|
542
|
+
|
|
543
|
+
deferredDisposeRef.current = { services, timeout };
|
|
544
|
+
};
|
|
545
|
+
}, [services]);
|
|
546
|
+
|
|
547
|
+
const value = useMemo<WorkbenchContextValue>(
|
|
548
|
+
() => ({
|
|
549
|
+
activateCommand: (commandId) => services.extensionRegistry.activateCommand(commandId),
|
|
550
|
+
contextKeyService,
|
|
551
|
+
editorDocumentViewProviders: services.editorDocumentViewProviders,
|
|
552
|
+
editorService: services.editorService,
|
|
553
|
+
executeCommand: async (commandId, ...args) => {
|
|
554
|
+
const result = await services.extensionRegistry.executeCommand(commandId, ...args);
|
|
555
|
+
await runExplorerHostCommandSideEffects(commandId, args, result, {
|
|
556
|
+
focusExplorerView: () => {
|
|
557
|
+
services.layoutService.setActiveViewContainer(BUILTIN_EXPLORER_VIEW_CONTAINER_ID);
|
|
558
|
+
services.layoutService.setSideBarVisible(true);
|
|
559
|
+
},
|
|
560
|
+
revealPath: publishExplorerRevealRequest,
|
|
561
|
+
});
|
|
562
|
+
if (commandId === BUILTIN_EXTENSIONS_FOCUS_COMMAND_ID) {
|
|
563
|
+
services.layoutService.setActiveViewContainer(BUILTIN_EXTENSIONS_VIEW_CONTAINER_ID);
|
|
564
|
+
services.layoutService.setSideBarVisible(true);
|
|
565
|
+
}
|
|
566
|
+
return result;
|
|
567
|
+
},
|
|
568
|
+
extensionRegistry: services.extensionRegistry,
|
|
569
|
+
installedExtensionsStorage,
|
|
570
|
+
installedExtensionsStorageKey,
|
|
571
|
+
keybindingOverrides,
|
|
572
|
+
layoutService: services.layoutService,
|
|
573
|
+
missingExtensionIds: services.missingExtensionIds,
|
|
574
|
+
preferenceService: services.preferenceService,
|
|
575
|
+
resetCommandKeybindingOverride,
|
|
576
|
+
setCommandKeybindingOverride,
|
|
577
|
+
waitForExtensionStartup: services.waitForExtensionStartup,
|
|
578
|
+
workspaceHostPort: services.workspaceHostPort,
|
|
579
|
+
}),
|
|
580
|
+
[
|
|
581
|
+
contextKeyService,
|
|
582
|
+
installedExtensionsStorage,
|
|
583
|
+
installedExtensionsStorageKey,
|
|
584
|
+
keybindingOverrides,
|
|
585
|
+
resetCommandKeybindingOverride,
|
|
586
|
+
services,
|
|
587
|
+
setCommandKeybindingOverride,
|
|
588
|
+
],
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
return (
|
|
592
|
+
<WorkbenchContext.Provider value={value}>
|
|
593
|
+
<EditorWorkspaceReconciler />
|
|
594
|
+
{children}
|
|
595
|
+
</WorkbenchContext.Provider>
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
export function useWorkbench(): WorkbenchContextValue {
|
|
600
|
+
const value = useContext(WorkbenchContext);
|
|
601
|
+
if (!value) {
|
|
602
|
+
throw new Error('useWorkbench must be used inside WorkbenchProvider.');
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
return value;
|
|
606
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ActivityBarItem } from '@workbench-kit/react/workbench/shell';
|
|
2
|
+
|
|
3
|
+
export const WORKBENCH_PROFILE_ACTIVITY_ITEM_ID = 'workbench-kit.shell.profile' as const;
|
|
4
|
+
export const WORKBENCH_ACCOUNT_ACTIVITY_ITEM_ID = WORKBENCH_PROFILE_ACTIVITY_ITEM_ID;
|
|
5
|
+
export const WORKBENCH_SETTINGS_ACTIVITY_ITEM_ID = 'workbench-kit.shell.settings' as const;
|
|
6
|
+
|
|
7
|
+
export type WorkbenchSecondaryActivityRoute = 'profile' | 'settings';
|
|
8
|
+
|
|
9
|
+
export interface WorkbenchSecondaryActivityItemsInput {
|
|
10
|
+
hasProfile: boolean;
|
|
11
|
+
isProfileOpen: boolean;
|
|
12
|
+
isSettingsOpen: boolean;
|
|
13
|
+
showSettings?: boolean | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createWorkbenchSecondaryActivityItems({
|
|
17
|
+
hasProfile,
|
|
18
|
+
isProfileOpen,
|
|
19
|
+
isSettingsOpen,
|
|
20
|
+
showSettings = true,
|
|
21
|
+
}: WorkbenchSecondaryActivityItemsInput): ActivityBarItem[] {
|
|
22
|
+
return [
|
|
23
|
+
...(hasProfile
|
|
24
|
+
? [
|
|
25
|
+
{
|
|
26
|
+
active: isProfileOpen,
|
|
27
|
+
icon: <i aria-hidden="true" className="codicon codicon-account" />,
|
|
28
|
+
id: WORKBENCH_PROFILE_ACTIVITY_ITEM_ID,
|
|
29
|
+
label: 'Profile',
|
|
30
|
+
title: 'Open profile',
|
|
31
|
+
},
|
|
32
|
+
]
|
|
33
|
+
: []),
|
|
34
|
+
...(showSettings
|
|
35
|
+
? [
|
|
36
|
+
{
|
|
37
|
+
active: isSettingsOpen,
|
|
38
|
+
icon: <i aria-hidden="true" className="codicon codicon-settings-gear" />,
|
|
39
|
+
id: WORKBENCH_SETTINGS_ACTIVITY_ITEM_ID,
|
|
40
|
+
label: 'Settings',
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
: []),
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function getWorkbenchSecondaryActivityRoute(
|
|
48
|
+
itemId: string,
|
|
49
|
+
): WorkbenchSecondaryActivityRoute | undefined {
|
|
50
|
+
if (itemId === WORKBENCH_PROFILE_ACTIVITY_ITEM_ID) {
|
|
51
|
+
return 'profile';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (itemId === WORKBENCH_SETTINGS_ACTIVITY_ITEM_ID) {
|
|
55
|
+
return 'settings';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PreferenceScope } from '@workbench-kit/workbench-config';
|
|
2
|
+
|
|
3
|
+
export const SETTINGS_EXTENSION_ID = 'workbench-kit.builtin.settings';
|
|
4
|
+
|
|
5
|
+
export const WORKBENCH_PREFERENCE_SCOPES = [
|
|
6
|
+
{ id: 'default', label: 'Default' },
|
|
7
|
+
{ id: 'workspace', label: 'Workspace' },
|
|
8
|
+
{ id: 'local', label: 'Local' },
|
|
9
|
+
] as const satisfies ReadonlyArray<{ id: PreferenceScope; label: string }>;
|