@workbench-kit/shell-react 0.0.2-prototype.0.2.41 → 0.0.2-prototype.0.2.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +42 -2
  2. package/package.json +13 -10
  3. package/src/extensions/extension-enablement-controller.ts +40 -9
  4. package/src/extensions/theme-selection-protection.ts +80 -55
  5. package/src/field-remap/chrome-labels.ts +18 -0
  6. package/src/field-remap/convert-note-editor.tsx +30 -24
  7. package/src/field-remap/convert-palette.tsx +6 -0
  8. package/src/field-remap/demo.tsx +8 -2
  9. package/src/field-remap/detail-panel.tsx +225 -192
  10. package/src/field-remap/drag-payload.ts +48 -0
  11. package/src/field-remap/flow-adapter.ts +216 -88
  12. package/src/field-remap/flow-ops.ts +150 -0
  13. package/src/field-remap/flow.tsx +1055 -162
  14. package/src/field-remap/index.ts +2 -0
  15. package/src/field-remap/io-class-browse.tsx +34 -22
  16. package/src/field-remap/keyboard.ts +16 -0
  17. package/src/field-remap/modal-detail.tsx +34 -0
  18. package/src/field-remap/panel.tsx +50 -14
  19. package/src/field-remap/transform-options-editor.tsx +5 -1
  20. package/src/field-remap/view.css +61 -42
  21. package/src/index.ts +7 -0
  22. package/src/management/keybinding-overrides-storage.ts +48 -23
  23. package/src/management/keybinding-settings.tsx +10 -1
  24. package/src/management/use-keybinding-management.ts +69 -19
  25. package/src/shell/appearance-catalog.ts +453 -0
  26. package/src/shell/appearance-controller.ts +331 -0
  27. package/src/shell/appearance-presentation.ts +269 -0
  28. package/src/shell/provider.tsx +147 -18
  29. package/src/shell/settings.tsx +282 -153
  30. package/src/shell/shell.tsx +88 -18
  31. package/src/workbench/appearance-storage.ts +2 -2
  32. package/src/workbench/command-host-controller.tsx +223 -0
  33. package/src/workbench/command-host.tsx +100 -150
  34. package/src/workbench/keybinding-bridge.ts +84 -38
  35. package/src/workbench/shell-command-registration.ts +27 -2
@@ -3,6 +3,7 @@ import {
3
3
  useCallback,
4
4
  useContext,
5
5
  useEffect,
6
+ useLayoutEffect,
6
7
  useMemo,
7
8
  useRef,
8
9
  useState,
@@ -46,9 +47,15 @@ import {
46
47
  import {
47
48
  ContextKeyService,
48
49
  createWorkbenchPermissionContextKeys,
50
+ projectCommandRegistryKeybindings,
51
+ resetManagedKeybindingOverride,
52
+ resolveWorkbenchShortcutPlatform,
53
+ setManagedKeybindingOverride,
49
54
  type CommandRegistry,
55
+ type CommandRegistryKeybindingProjection,
50
56
  type ContextKeyValue,
51
57
  type KeybindingRegistry,
58
+ type WorkbenchShortcutPlatform,
52
59
  } from '@workbench-kit/platform';
53
60
  import type {
54
61
  WorkbenchExtensionsConfig,
@@ -74,6 +81,7 @@ import {
74
81
  isWorkbenchKeybindingPersistenceAvailable,
75
82
  readPersistedKeybindingOverridesResult,
76
83
  writePersistedKeybindingOverridesResult,
84
+ type PersistedKeybindingOverridesReadResult,
77
85
  } from '../management/keybinding-overrides-storage.js';
78
86
  import {
79
87
  BUILTIN_EXPLORER_VIEW_CONTAINER_ID,
@@ -199,7 +207,10 @@ export interface WorkbenchContextValue {
199
207
  installedExtensionsStorage?: WorkbenchStorageAdapter;
200
208
  installedExtensionsStorageKey: string;
201
209
  keybindings: KeybindingRegistry;
210
+ keybindingEditingDisabledReason?: string | undefined;
202
211
  keybindingOverrides: readonly WorkbenchKeybindingDefinition[];
212
+ keybindingPlatform: WorkbenchShortcutPlatform;
213
+ keybindingProjection: CommandRegistryKeybindingProjection;
203
214
  layoutService: LayoutService;
204
215
  localizations: LocalizationRegistry;
205
216
  menus: MenuRegistry;
@@ -237,8 +248,10 @@ interface DeferredProviderDispose {
237
248
  }
238
249
 
239
250
  interface KeybindingOverridesState {
251
+ readonly dirty: boolean;
240
252
  readonly initialOverrides: readonly WorkbenchKeybindingDefinition[] | undefined;
241
253
  readonly overrides: readonly WorkbenchKeybindingDefinition[];
254
+ readonly platform: WorkbenchShortcutPlatform;
242
255
  readonly shouldPersist: boolean;
243
256
  readonly storage: WorkbenchStorageAdapter | undefined;
244
257
  readonly storageKey: string;
@@ -253,9 +266,11 @@ function isKeybindingStateCurrent(
253
266
  shouldPersist: boolean,
254
267
  storage: WorkbenchStorageAdapter | undefined,
255
268
  storageKey: string,
269
+ platform: WorkbenchShortcutPlatform,
256
270
  ): boolean {
257
271
  return (
258
272
  state.initialOverrides === initialOverrides &&
273
+ state.platform === platform &&
259
274
  state.shouldPersist === shouldPersist &&
260
275
  state.storage === storage &&
261
276
  state.storageKey === storageKey
@@ -264,19 +279,21 @@ function isKeybindingStateCurrent(
264
279
 
265
280
  function createKeybindingOverridesState(
266
281
  initialOverrides: readonly WorkbenchKeybindingDefinition[] | undefined,
267
- resolvedOverrides: readonly WorkbenchKeybindingDefinition[],
268
- readFailed: boolean,
282
+ resolved: PersistedKeybindingOverridesReadResult,
269
283
  shouldPersist: boolean,
270
284
  storage: WorkbenchStorageAdapter | undefined,
271
285
  storageKey: string,
286
+ platform: WorkbenchShortcutPlatform,
272
287
  ): KeybindingOverridesState {
273
288
  return {
289
+ dirty: false,
274
290
  initialOverrides,
275
- overrides: resolvedOverrides,
291
+ overrides: resolved.value,
292
+ platform,
276
293
  shouldPersist,
277
294
  storage,
278
295
  storageKey,
279
- writeEligible: initialOverrides !== undefined || !readFailed,
296
+ writeEligible: resolved.writeEligible,
280
297
  };
281
298
  }
282
299
 
@@ -340,6 +357,7 @@ export function WorkbenchProvider({
340
357
  const shouldPersistKeybindingOverrides =
341
358
  persistKeybindingOverrides ??
342
359
  (keybindingOverridesStorage !== undefined || isWorkbenchKeybindingPersistenceAvailable());
360
+ const keybindingPlatform = resolveWorkbenchShortcutPlatform();
343
361
  const shouldPersistLayout =
344
362
  persistLayout ?? (layoutStorage !== undefined || isWorkbenchLayoutPersistenceAvailable());
345
363
  const shouldPersistLocalPreferences =
@@ -366,18 +384,25 @@ export function WorkbenchProvider({
366
384
  [editorStateStorage, editorStateStorageKey, initialEditorState, shouldPersistEditorState],
367
385
  );
368
386
  const resolvedInitialEditorState = resolvedInitialEditorStateResult.value;
369
- const resolvedInitialKeybindingOverridesResult = useMemo(
387
+ const resolvedInitialKeybindingOverridesResult = useMemo<PersistedKeybindingOverridesReadResult>(
370
388
  () =>
371
389
  initialKeybindingOverrides !== undefined
372
- ? { value: initialKeybindingOverrides }
390
+ ? {
391
+ entries: initialKeybindingOverrides,
392
+ format: 'v1',
393
+ value: initialKeybindingOverrides,
394
+ writeEligible: true,
395
+ }
373
396
  : shouldPersistKeybindingOverrides
374
397
  ? readPersistedKeybindingOverridesResult(
375
398
  keybindingOverridesStorageKey,
376
399
  keybindingOverridesStorage,
400
+ { platform: keybindingPlatform },
377
401
  )
378
- : { value: [] },
402
+ : { entries: [], format: 'missing', value: [], writeEligible: true },
379
403
  [
380
404
  initialKeybindingOverrides,
405
+ keybindingPlatform,
381
406
  keybindingOverridesStorage,
382
407
  keybindingOverridesStorageKey,
383
408
  shouldPersistKeybindingOverrides,
@@ -387,23 +412,32 @@ export function WorkbenchProvider({
387
412
  const [keybindingState, setKeybindingState] = useState<KeybindingOverridesState>(() =>
388
413
  createKeybindingOverridesState(
389
414
  initialKeybindingOverrides,
390
- resolvedInitialKeybindingOverrides,
391
- resolvedInitialKeybindingOverridesResult.diagnostic !== undefined,
415
+ resolvedInitialKeybindingOverridesResult,
392
416
  shouldPersistKeybindingOverrides,
393
417
  keybindingOverridesStorage,
394
418
  keybindingOverridesStorageKey,
419
+ keybindingPlatform,
395
420
  ),
396
421
  );
422
+ const handledKeybindingWriteRef = useRef<KeybindingOverridesState | undefined>(undefined);
397
423
  const keybindingStateIsCurrent = isKeybindingStateCurrent(
398
424
  keybindingState,
399
425
  initialKeybindingOverrides,
400
426
  shouldPersistKeybindingOverrides,
401
427
  keybindingOverridesStorage,
402
428
  keybindingOverridesStorageKey,
429
+ keybindingPlatform,
403
430
  );
404
431
  const keybindingOverrides = keybindingStateIsCurrent
405
432
  ? keybindingState.overrides
406
433
  : resolvedInitialKeybindingOverrides;
434
+ const keybindingWriteEligible = keybindingStateIsCurrent
435
+ ? keybindingState.writeEligible
436
+ : resolvedInitialKeybindingOverridesResult.writeEligible;
437
+ const keybindingEditingDisabledReason = keybindingWriteEligible
438
+ ? undefined
439
+ : (resolvedInitialKeybindingOverridesResult.diagnostic?.message ??
440
+ 'Stored keyboard shortcuts cannot be edited in this version.');
407
441
  const [contextKeyService] = useState(() => createInitialContextKeyService(contextKeyValues));
408
442
 
409
443
  useEffect(() => {
@@ -430,23 +464,25 @@ export function WorkbenchProvider({
430
464
  shouldPersistKeybindingOverrides,
431
465
  keybindingOverridesStorage,
432
466
  keybindingOverridesStorageKey,
467
+ keybindingPlatform,
433
468
  )
434
469
  ? current
435
470
  : createKeybindingOverridesState(
436
471
  initialKeybindingOverrides,
437
- resolvedInitialKeybindingOverrides,
438
- resolvedInitialKeybindingOverridesResult.diagnostic !== undefined,
472
+ resolvedInitialKeybindingOverridesResult,
439
473
  shouldPersistKeybindingOverrides,
440
474
  keybindingOverridesStorage,
441
475
  keybindingOverridesStorageKey,
476
+ keybindingPlatform,
442
477
  ),
443
478
  );
444
479
  }, [
445
480
  initialKeybindingOverrides,
446
481
  keybindingOverridesStorage,
447
482
  keybindingOverridesStorageKey,
483
+ keybindingPlatform,
448
484
  resolvedInitialKeybindingOverrides,
449
- resolvedInitialKeybindingOverridesResult.diagnostic,
485
+ resolvedInitialKeybindingOverridesResult,
450
486
  shouldPersistKeybindingOverrides,
451
487
  ]);
452
488
 
@@ -459,25 +495,53 @@ export function WorkbenchProvider({
459
495
  shouldPersistKeybindingOverrides,
460
496
  keybindingOverridesStorage,
461
497
  keybindingOverridesStorageKey,
498
+ keybindingPlatform,
462
499
  )
463
500
  ? current.overrides
464
501
  : resolvedInitialKeybindingOverrides;
465
- const without = currentOverrides.filter((binding) => binding.command !== commandId);
502
+ const currentWriteEligible = isKeybindingStateCurrent(
503
+ current,
504
+ initialKeybindingOverrides,
505
+ shouldPersistKeybindingOverrides,
506
+ keybindingOverridesStorage,
507
+ keybindingOverridesStorageKey,
508
+ keybindingPlatform,
509
+ )
510
+ ? current.writeEligible
511
+ : resolvedInitialKeybindingOverridesResult.writeEligible;
512
+ if (!currentWriteEligible) {
513
+ return current;
514
+ }
515
+
516
+ const result = setManagedKeybindingOverride({
517
+ commandId,
518
+ key,
519
+ overrides: currentOverrides,
520
+ platform: keybindingPlatform,
521
+ });
522
+ if (!result.changed) {
523
+ return current;
524
+ }
525
+
466
526
  return {
527
+ dirty: true,
467
528
  initialOverrides: initialKeybindingOverrides,
468
- overrides: [...without, { command: commandId, key }],
529
+ overrides: result.overrides,
530
+ platform: keybindingPlatform,
469
531
  shouldPersist: shouldPersistKeybindingOverrides,
470
532
  storage: keybindingOverridesStorage,
471
533
  storageKey: keybindingOverridesStorageKey,
472
- writeEligible: true,
534
+ writeEligible: currentWriteEligible,
473
535
  };
474
536
  });
475
537
  },
476
538
  [
477
539
  initialKeybindingOverrides,
540
+ keybindingPlatform,
478
541
  keybindingOverridesStorage,
479
542
  keybindingOverridesStorageKey,
480
543
  resolvedInitialKeybindingOverrides,
544
+ resolvedInitialKeybindingOverridesResult.writeEligible,
481
545
  shouldPersistKeybindingOverrides,
482
546
  ],
483
547
  );
@@ -491,33 +555,66 @@ export function WorkbenchProvider({
491
555
  shouldPersistKeybindingOverrides,
492
556
  keybindingOverridesStorage,
493
557
  keybindingOverridesStorageKey,
558
+ keybindingPlatform,
494
559
  )
495
560
  ? current.overrides
496
561
  : resolvedInitialKeybindingOverrides;
562
+ const currentWriteEligible = isKeybindingStateCurrent(
563
+ current,
564
+ initialKeybindingOverrides,
565
+ shouldPersistKeybindingOverrides,
566
+ keybindingOverridesStorage,
567
+ keybindingOverridesStorageKey,
568
+ keybindingPlatform,
569
+ )
570
+ ? current.writeEligible
571
+ : resolvedInitialKeybindingOverridesResult.writeEligible;
572
+ if (!currentWriteEligible) {
573
+ return current;
574
+ }
575
+
576
+ const result = resetManagedKeybindingOverride({
577
+ commandId,
578
+ overrides: currentOverrides,
579
+ platform: keybindingPlatform,
580
+ });
581
+ if (!result.changed) {
582
+ return current;
583
+ }
584
+
497
585
  return {
586
+ dirty: true,
498
587
  initialOverrides: initialKeybindingOverrides,
499
- overrides: currentOverrides.filter((binding) => binding.command !== commandId),
588
+ overrides: result.overrides,
589
+ platform: keybindingPlatform,
500
590
  shouldPersist: shouldPersistKeybindingOverrides,
501
591
  storage: keybindingOverridesStorage,
502
592
  storageKey: keybindingOverridesStorageKey,
503
- writeEligible: true,
593
+ writeEligible: currentWriteEligible,
504
594
  };
505
595
  });
506
596
  },
507
597
  [
508
598
  initialKeybindingOverrides,
599
+ keybindingPlatform,
509
600
  keybindingOverridesStorage,
510
601
  keybindingOverridesStorageKey,
511
602
  resolvedInitialKeybindingOverrides,
603
+ resolvedInitialKeybindingOverridesResult.writeEligible,
512
604
  shouldPersistKeybindingOverrides,
513
605
  ],
514
606
  );
515
607
 
516
608
  useEffect(() => {
517
- if (!keybindingStateIsCurrent) {
609
+ if (
610
+ !keybindingStateIsCurrent ||
611
+ !keybindingState.dirty ||
612
+ handledKeybindingWriteRef.current === keybindingState
613
+ ) {
518
614
  return;
519
615
  }
520
616
 
617
+ handledKeybindingWriteRef.current = keybindingState;
521
618
  onKeybindingOverridesChange?.(keybindingState.overrides);
522
619
  if (!shouldPersistKeybindingOverrides || !keybindingState.writeEligible) {
523
620
  return;
@@ -571,6 +668,7 @@ export function WorkbenchProvider({
571
668
  initialKeybindingOverrides,
572
669
  keybindingOverridesStorage,
573
670
  keybindingOverridesStorageKey,
671
+ keybindingPlatform,
574
672
  shouldPersistKeybindingOverrides,
575
673
  ],
576
674
  diagnosticHandlerRef,
@@ -748,6 +846,31 @@ export function WorkbenchProvider({
748
846
  diagnosticHandlerRef,
749
847
  ]);
750
848
 
849
+ const [commandKeybindingRevision, setCommandKeybindingRevision] = useState(
850
+ () => services.extensionRegistry.commands.revision,
851
+ );
852
+ useLayoutEffect(() => {
853
+ const updateRevision = () => {
854
+ setCommandKeybindingRevision(services.extensionRegistry.commands.revision);
855
+ };
856
+ const commandDisposable =
857
+ services.extensionRegistry.commands.onDidChangeCommands(updateRevision);
858
+ updateRevision();
859
+
860
+ return () => {
861
+ commandDisposable.dispose();
862
+ };
863
+ }, [services.extensionRegistry.commands]);
864
+ const keybindingProjection = useMemo(
865
+ () =>
866
+ projectCommandRegistryKeybindings({
867
+ context: undefined,
868
+ platform: keybindingPlatform,
869
+ registry: services.extensionRegistry.commands,
870
+ }),
871
+ [commandKeybindingRevision, keybindingPlatform, services.extensionRegistry.commands],
872
+ );
873
+
751
874
  useEffect(() => {
752
875
  if (!shouldPersistLayout) {
753
876
  return undefined;
@@ -886,7 +1009,10 @@ export function WorkbenchProvider({
886
1009
  installedExtensionsStorage,
887
1010
  installedExtensionsStorageKey,
888
1011
  keybindings: services.extensionRegistry.keybindings,
1012
+ keybindingEditingDisabledReason,
889
1013
  keybindingOverrides,
1014
+ keybindingPlatform,
1015
+ keybindingProjection,
890
1016
  layoutService: services.layoutService,
891
1017
  localizations: services.extensionRegistry.localizations,
892
1018
  menus: services.extensionRegistry.menus,
@@ -908,7 +1034,10 @@ export function WorkbenchProvider({
908
1034
  contextKeyService,
909
1035
  installedExtensionsStorage,
910
1036
  installedExtensionsStorageKey,
1037
+ keybindingEditingDisabledReason,
911
1038
  keybindingOverrides,
1039
+ keybindingPlatform,
1040
+ keybindingProjection,
912
1041
  resetCommandKeybindingOverride,
913
1042
  services,
914
1043
  setCommandKeybindingOverride,