@lvce-editor/quick-pick-worker 4.32.0 → 4.33.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.
@@ -67,7 +67,7 @@ const String$1 = 4;
67
67
  const Boolean$1 = 5;
68
68
  const Function = 6;
69
69
  const Null = 7;
70
- const Unknown = 8;
70
+ const Unknown$1 = 8;
71
71
  const getType = value => {
72
72
  switch (typeof value) {
73
73
  case 'number':
@@ -87,7 +87,7 @@ const getType = value => {
87
87
  case 'boolean':
88
88
  return Boolean$1;
89
89
  default:
90
- return Unknown;
90
+ return Unknown$1;
91
91
  }
92
92
  };
93
93
  const object = value => {
@@ -1229,6 +1229,279 @@ const Text = 12;
1229
1229
  const Img = 17;
1230
1230
  const Reference = 100;
1231
1231
 
1232
+ const Unknown = 0;
1233
+ const Backspace = 1;
1234
+ const Tab = 2;
1235
+ const Enter$1 = 3;
1236
+ const Ctrl = 4;
1237
+ const Alt = 5;
1238
+ const PauseBreak = 6;
1239
+ const CapsLock = 7;
1240
+ const Escape$1 = 8;
1241
+ const Space$1 = 9;
1242
+ const PageUp$1 = 10;
1243
+ const PageDown$1 = 11;
1244
+ const End = 255;
1245
+ const Home = 12;
1246
+ const LeftArrow = 13;
1247
+ const UpArrow$1 = 14;
1248
+ const RightArrow = 15;
1249
+ const DownArrow$1 = 16;
1250
+ const Insert = 17;
1251
+ const Delete = 18;
1252
+ const Digit0 = 19;
1253
+ const Digit1 = 20;
1254
+ const Digit2 = 21;
1255
+ const Digit3 = 22;
1256
+ const Digit4 = 23;
1257
+ const Digit5 = 24;
1258
+ const Digit6 = 25;
1259
+ const Digit7 = 26;
1260
+ const Digit8 = 27;
1261
+ const Digit9 = 28;
1262
+ const KeyA = 29;
1263
+ const KeyB = 30;
1264
+ const KeyC = 31;
1265
+ const KeyD = 32;
1266
+ const KeyE = 33;
1267
+ const KeyF = 34;
1268
+ const KeyG = 35;
1269
+ const KeyH = 36;
1270
+ const KeyI = 37;
1271
+ const KeyJ = 38;
1272
+ const KeyK = 39;
1273
+ const KeyL = 40;
1274
+ const KeyM = 41;
1275
+ const KeyN = 42;
1276
+ const KeyO = 43;
1277
+ const KeyP = 44;
1278
+ const KeyQ = 45;
1279
+ const KeyR = 46;
1280
+ const KeyS = 47;
1281
+ const KeyT = 48;
1282
+ const KeyU = 49;
1283
+ const KeyV = 50;
1284
+ const KeyW = 51;
1285
+ const KeyX = 52;
1286
+ const KeyY = 53;
1287
+ const KeyZ = 54;
1288
+ const Meta = 55;
1289
+ const ContextMenu = 56;
1290
+ const F1 = 57;
1291
+ const F2 = 58;
1292
+ const F3 = 59;
1293
+ const F4 = 60;
1294
+ const F5 = 61;
1295
+ const F6 = 62;
1296
+ const F7 = 63;
1297
+ const F8 = 64;
1298
+ const F9 = 65;
1299
+ const F10 = 66;
1300
+ const F11 = 67;
1301
+ const F12 = 68;
1302
+ const F13 = 69;
1303
+ const F14 = 70;
1304
+ const F15 = 71;
1305
+ const F16 = 72;
1306
+ const F17 = 72;
1307
+ const F18 = 74;
1308
+ const F19 = 75;
1309
+ const F20 = 76;
1310
+ const F21 = 77;
1311
+ const F22 = 78;
1312
+ const F23 = 79;
1313
+ const F24 = 80;
1314
+ const NumLock = 81;
1315
+ const ScrollLock = 82;
1316
+ const SemiColon = 83;
1317
+ const Equal = 84;
1318
+ const Comma = 85;
1319
+ const Minus = 86;
1320
+ const Period = 87;
1321
+ const Slash$1 = 88;
1322
+ const Backquote = 89;
1323
+ const BracketLeft = 90;
1324
+ const Backslash = 91;
1325
+ const BracketRight = 92;
1326
+ const Quote = 93;
1327
+ const OEM_8 = 94;
1328
+ const IntlBackslash = 95;
1329
+ const Numpad0 = 96;
1330
+ const Numpad1 = 97;
1331
+ const Numpad2 = 98;
1332
+ const Numpad3 = 99;
1333
+ const Numpad4 = 100;
1334
+ const Numpad5 = 101;
1335
+ const Numpad6 = 102;
1336
+ const Numpad7 = 103;
1337
+ const Numpad8 = 104;
1338
+ const Numpad9 = 105;
1339
+ const NumpadMultiply = 106;
1340
+ const NumpadAdd = 107;
1341
+ const NumpadSeparator = 108;
1342
+ const NumpadSubtract = 109;
1343
+ const NumpadDecimal = 110;
1344
+ const NumpadDivide = 111;
1345
+ const KeyInComposition = 112;
1346
+ const ABNT_C1 = 113;
1347
+ const ABNT_C2 = 114;
1348
+ const AudioVolumeMute = 115;
1349
+ const AudioVolumeUp = 116;
1350
+ const AudioVolumeDown = 117;
1351
+ const BrowserSearch = 118;
1352
+ const BrowserHome = 119;
1353
+ const BrowserBack = 120;
1354
+ const BrowserForward = 121;
1355
+ const MediaTrackNext = 122;
1356
+ const MediaTrackPrevious = 123;
1357
+ const MediaStop = 124;
1358
+ const MediaPlayPause = 125;
1359
+ const LaunchMediaPlayer = 126;
1360
+ const LaunchMail = 127;
1361
+ const LaunchApp2 = 128;
1362
+ const Clear = 129;
1363
+ const MaxValue = 130;
1364
+ const Star = 131;
1365
+ const Plus = 132;
1366
+
1367
+ const KeyCode = {
1368
+ __proto__: null,
1369
+ ABNT_C1,
1370
+ ABNT_C2,
1371
+ Alt,
1372
+ AudioVolumeDown,
1373
+ AudioVolumeMute,
1374
+ AudioVolumeUp,
1375
+ Backquote,
1376
+ Backslash,
1377
+ Backspace,
1378
+ BracketLeft,
1379
+ BracketRight,
1380
+ BrowserBack,
1381
+ BrowserForward,
1382
+ BrowserHome,
1383
+ BrowserSearch,
1384
+ CapsLock,
1385
+ Clear,
1386
+ Comma,
1387
+ ContextMenu,
1388
+ Ctrl,
1389
+ Delete,
1390
+ Digit0,
1391
+ Digit1,
1392
+ Digit2,
1393
+ Digit3,
1394
+ Digit4,
1395
+ Digit5,
1396
+ Digit6,
1397
+ Digit7,
1398
+ Digit8,
1399
+ Digit9,
1400
+ DownArrow: DownArrow$1,
1401
+ End,
1402
+ Enter: Enter$1,
1403
+ Equal,
1404
+ Escape: Escape$1,
1405
+ F1,
1406
+ F10,
1407
+ F11,
1408
+ F12,
1409
+ F13,
1410
+ F14,
1411
+ F15,
1412
+ F16,
1413
+ F17,
1414
+ F18,
1415
+ F19,
1416
+ F2,
1417
+ F20,
1418
+ F21,
1419
+ F22,
1420
+ F23,
1421
+ F24,
1422
+ F3,
1423
+ F4,
1424
+ F5,
1425
+ F6,
1426
+ F7,
1427
+ F8,
1428
+ F9,
1429
+ Home,
1430
+ Insert,
1431
+ IntlBackslash,
1432
+ KeyA,
1433
+ KeyB,
1434
+ KeyC,
1435
+ KeyD,
1436
+ KeyE,
1437
+ KeyF,
1438
+ KeyG,
1439
+ KeyH,
1440
+ KeyI,
1441
+ KeyInComposition,
1442
+ KeyJ,
1443
+ KeyK,
1444
+ KeyL,
1445
+ KeyM,
1446
+ KeyN,
1447
+ KeyO,
1448
+ KeyP,
1449
+ KeyQ,
1450
+ KeyR,
1451
+ KeyS,
1452
+ KeyT,
1453
+ KeyU,
1454
+ KeyV,
1455
+ KeyW,
1456
+ KeyX,
1457
+ KeyY,
1458
+ KeyZ,
1459
+ LaunchApp2,
1460
+ LaunchMail,
1461
+ LaunchMediaPlayer,
1462
+ LeftArrow,
1463
+ MaxValue,
1464
+ MediaPlayPause,
1465
+ MediaStop,
1466
+ MediaTrackNext,
1467
+ MediaTrackPrevious,
1468
+ Meta,
1469
+ Minus,
1470
+ NumLock,
1471
+ Numpad0,
1472
+ Numpad1,
1473
+ Numpad2,
1474
+ Numpad3,
1475
+ Numpad4,
1476
+ Numpad5,
1477
+ Numpad6,
1478
+ Numpad7,
1479
+ Numpad8,
1480
+ Numpad9,
1481
+ NumpadAdd,
1482
+ NumpadDecimal,
1483
+ NumpadDivide,
1484
+ NumpadMultiply,
1485
+ NumpadSeparator,
1486
+ NumpadSubtract,
1487
+ OEM_8,
1488
+ PageDown: PageDown$1,
1489
+ PageUp: PageUp$1,
1490
+ PauseBreak,
1491
+ Period,
1492
+ Plus,
1493
+ Quote,
1494
+ RightArrow,
1495
+ ScrollLock,
1496
+ SemiColon,
1497
+ Slash: Slash$1,
1498
+ Space: Space$1,
1499
+ Star,
1500
+ Tab,
1501
+ Unknown,
1502
+ UpArrow: UpArrow$1
1503
+ };
1504
+
1232
1505
  const EditorWorker = 99;
1233
1506
  const ExtensionManagementWorker = 9006;
1234
1507
  const RendererProcess = 1670;
@@ -1393,6 +1666,47 @@ const close = async state => {
1393
1666
  return state;
1394
1667
  };
1395
1668
 
1669
+ const Commands = 'quickPick://commands';
1670
+ const EveryThing = 'quickPick://everything';
1671
+ const Recent = 'quickPick://recent';
1672
+ const ColorTheme = 'quickPick://color-theme';
1673
+ const LanguageMode = 'quickPick://language-mode';
1674
+ const Symbol$2 = 'quickPick://symbol';
1675
+ const View$2 = 'quickPick://view';
1676
+ const Help$1 = 'quickPick://help';
1677
+ const WorkspaceSymbol$1 = 'quickPick://workspace-symbol';
1678
+ const Custom = 'quickPick://custom';
1679
+ const GoToLine$1 = 'quickPick://go-to-line';
1680
+ const EndOfLine = 'quickPick://end-of-line';
1681
+ const Indentation = 'quickPick://indentation';
1682
+
1683
+ const getQuickPickProviderId = prefix => {
1684
+ switch (prefix) {
1685
+ case ColorTheme:
1686
+ return ColorTheme$1;
1687
+ case Commands:
1688
+ case EveryThing:
1689
+ case GoToLine$1:
1690
+ case Help$1:
1691
+ case Symbol$2:
1692
+ case View$2:
1693
+ case WorkspaceSymbol$1:
1694
+ return EveryThing$1;
1695
+ case Custom:
1696
+ return Custom$1;
1697
+ case EndOfLine:
1698
+ return EndOfLine$1;
1699
+ case Indentation:
1700
+ return Indentation$1;
1701
+ case LanguageMode:
1702
+ return LanguageMode$1;
1703
+ case Recent:
1704
+ return Recent$1;
1705
+ default:
1706
+ return File$1;
1707
+ }
1708
+ };
1709
+
1396
1710
  const User = 1;
1397
1711
  const Script = 2;
1398
1712
 
@@ -1929,6 +2243,7 @@ const handleScrollBarPointerUp = (state, pointerId) => {
1929
2243
  };
1930
2244
 
1931
2245
  const create = (uid, uri, listItemHeight, x, y, width, height, platform, args, _renderAllItems, workspaceUri, assetDir, applicationId) => {
2246
+ const providerId = getQuickPickProviderId(uri);
1932
2247
  const state = {
1933
2248
  allowEmptyResult: false,
1934
2249
  applicationId,
@@ -1960,6 +2275,7 @@ const create = (uid, uri, listItemHeight, x, y, width, height, platform, args, _
1960
2275
  inputSource: User,
1961
2276
  placeholder: '',
1962
2277
  platform,
2278
+ providerId,
1963
2279
  value: ''
1964
2280
  };
1965
2281
  set$5(uid, state, state);
@@ -2336,32 +2652,32 @@ const getNewValue = (value, inputType, data, selectionStart, selectionEnd) => {
2336
2652
  };
2337
2653
 
2338
2654
  const Command = '>';
2339
- const Symbol$2 = '@';
2340
- const WorkspaceSymbol$1 = '#';
2341
- const GoToLine$1 = ':';
2342
- const View$2 = 'view ';
2655
+ const Symbol$1 = '@';
2656
+ const WorkspaceSymbol = '#';
2657
+ const GoToLine = ':';
2658
+ const View$1 = 'view ';
2343
2659
  const None$1 = '';
2344
- const Help$1 = '?';
2660
+ const Help = '?';
2345
2661
  const GoToColumn = '::';
2346
2662
 
2347
2663
  const getQuickPickPrefix = value => {
2348
2664
  if (value.startsWith(Command)) {
2349
2665
  return Command;
2350
2666
  }
2351
- if (value.startsWith(Symbol$2)) {
2352
- return Symbol$2;
2667
+ if (value.startsWith(Symbol$1)) {
2668
+ return Symbol$1;
2353
2669
  }
2354
- if (value.startsWith(WorkspaceSymbol$1)) {
2355
- return WorkspaceSymbol$1;
2670
+ if (value.startsWith(WorkspaceSymbol)) {
2671
+ return WorkspaceSymbol;
2356
2672
  }
2357
2673
  if (value.startsWith(GoToColumn)) {
2358
2674
  return GoToColumn;
2359
2675
  }
2360
- if (value.startsWith(GoToLine$1)) {
2361
- return GoToLine$1;
2676
+ if (value.startsWith(GoToLine)) {
2677
+ return GoToLine;
2362
2678
  }
2363
- if (value.startsWith(View$2)) {
2364
- return View$2;
2679
+ if (value.startsWith(View$1)) {
2680
+ return View$1;
2365
2681
  }
2366
2682
  return None$1;
2367
2683
  };
@@ -2378,15 +2694,15 @@ const getQuickPickSubProviderId = (id, prefix) => {
2378
2694
  return Commands$1;
2379
2695
  case GoToColumn:
2380
2696
  return GoToColumn$1;
2381
- case GoToLine$1:
2697
+ case GoToLine:
2382
2698
  return GoToLine$2;
2383
- case Help$1:
2699
+ case Help:
2384
2700
  return Help$2;
2385
- case Symbol$2:
2701
+ case Symbol$1:
2386
2702
  return Symbol$3;
2387
- case View$2:
2703
+ case View$1:
2388
2704
  return View$3;
2389
- case WorkspaceSymbol$1:
2705
+ case WorkspaceSymbol:
2390
2706
  return WorkspaceSymbol$2;
2391
2707
  default:
2392
2708
  return File$1;
@@ -3493,7 +3809,7 @@ const getPicksGoToLineBase = async () => {
3493
3809
  };
3494
3810
 
3495
3811
  const parseGoToLinePosition = value => {
3496
- const [lineString, columnString = '1'] = value.slice(GoToLine$1.length).split(':');
3812
+ const [lineString, columnString = '1'] = value.slice(GoToLine.length).split(':');
3497
3813
  const line = Number(lineString);
3498
3814
  const column = Number(columnString);
3499
3815
  if (!Number.isSafeInteger(line) || !Number.isSafeInteger(column) || line < 1 || column < 1) {
@@ -3506,10 +3822,10 @@ const parseGoToLinePosition = value => {
3506
3822
  };
3507
3823
 
3508
3824
  const getPicks$a = async value => {
3509
- if (value === GoToLine$1) {
3825
+ if (value === GoToLine) {
3510
3826
  return getPicksGoToLineBase();
3511
3827
  }
3512
- if (value.startsWith(GoToLine$1)) {
3828
+ if (value.startsWith(GoToLine)) {
3513
3829
  const position = parseGoToLinePosition(value);
3514
3830
  if (!position) {
3515
3831
  return getPicksGoToLineBase();
@@ -3531,7 +3847,7 @@ const DotDotDot = '...';
3531
3847
  const Colon = ':';
3532
3848
  const Percent = '%';
3533
3849
  const AngleBracket = '>';
3534
- const View$1 = 'view';
3850
+ const View = 'view';
3535
3851
 
3536
3852
  const getPicks$9 = async () => {
3537
3853
  return [{
@@ -3579,7 +3895,7 @@ const getPicks$9 = async () => {
3579
3895
  direntType: None$2,
3580
3896
  fileIcon: '',
3581
3897
  icon: '',
3582
- label: View$1,
3898
+ label: View,
3583
3899
  matches: [],
3584
3900
  uri: ''
3585
3901
  }];
@@ -3951,7 +4267,7 @@ const selectPickGoToColumn = async (item, value) => {
3951
4267
  };
3952
4268
 
3953
4269
  const selectPick$7 = async (item, value) => {
3954
- if (value.startsWith(GoToLine$1)) {
4270
+ if (value.startsWith(GoToLine)) {
3955
4271
  const position = parseGoToLinePosition(value);
3956
4272
  if (position) {
3957
4273
  await goToPositionAndFocus(position.rowIndex, position.columnIndex);
@@ -4051,323 +4367,441 @@ const getPicks = (id, searchValue, args, {
4051
4367
  });
4052
4368
  };
4053
4369
 
4054
- const requestVersions = new Map();
4055
- const requestVersionGenerator = {
4056
- value: 0
4370
+ const mergeClassNames = (...classNames) => {
4371
+ return classNames.filter(Boolean).join(' ');
4057
4372
  };
4058
- const isSamePicker = (state, latestState) => {
4059
- return latestState.uri === state.uri && latestState.args === state.args;
4373
+
4374
+ const text = data => {
4375
+ return {
4376
+ childCount: 0,
4377
+ text: data,
4378
+ type: Text
4379
+ };
4060
4380
  };
4061
- const isQuickInput = args => {
4062
- const options = args.at(-1);
4063
- return options?.mode === 'quickInput';
4381
+
4382
+ const SetText = 1;
4383
+ const Replace = 2;
4384
+ const SetAttribute = 3;
4385
+ const RemoveAttribute = 4;
4386
+ const Add = 6;
4387
+ const NavigateChild = 7;
4388
+ const NavigateParent = 8;
4389
+ const RemoveChild = 9;
4390
+ const NavigateSibling = 10;
4391
+ const SetReferenceNodeUid = 11;
4392
+ const MultiNavigation = 18;
4393
+
4394
+ const isKey = key => {
4395
+ return key !== 'type' && key !== 'childCount';
4064
4396
  };
4065
- const isStaticQuickInput = args => {
4066
- const options = args.at(-1);
4067
- return options?.mode === 'quickInput' && options.quickInputId === undefined;
4397
+
4398
+ const getKeys = node => {
4399
+ const keys = Object.keys(node).filter(isKey);
4400
+ return keys;
4068
4401
  };
4069
- const setValue = async (state, newValue) => {
4070
- const {
4071
- args,
4072
- assetDir,
4073
- fileIconCache,
4074
- height,
4075
- itemHeight,
4076
- maxLineY,
4077
- minLineY,
4078
- platform,
4079
- providerId,
4080
- value
4081
- } = state;
4082
- if (value === newValue) {
4083
- return state;
4402
+
4403
+ const arrayToTree = nodes => {
4404
+ const result = [];
4405
+ let i = 0;
4406
+ while (i < nodes.length) {
4407
+ const node = nodes[i];
4408
+ const {
4409
+ children,
4410
+ nodesConsumed
4411
+ } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
4412
+ result.push({
4413
+ node,
4414
+ children
4415
+ });
4416
+ i += 1 + nodesConsumed;
4084
4417
  }
4085
- if (isTextInput(args)) {
4418
+ return result;
4419
+ };
4420
+ const getChildrenWithCount = (nodes, startIndex, childCount) => {
4421
+ if (childCount === 0) {
4086
4422
  return {
4087
- ...state,
4088
- inputSource: Script,
4089
- value: newValue
4423
+ children: [],
4424
+ nodesConsumed: 0
4090
4425
  };
4091
4426
  }
4092
- const prefix = getQuickPickPrefix(newValue);
4093
- const subId = getQuickPickSubProviderId(providerId, prefix);
4094
- const quickInput = isQuickInput(args);
4095
- const reuseFilePicks = !state.initial && canReuseFilePicks(providerId, value, newValue, state.picks.length);
4096
- const newPicks = isStaticQuickInput(args) || subId === LanguageMode$1 || reuseFilePicks ? state.picks : await getPicks(subId, newValue, args, {
4097
- applicationId: state.applicationId,
4098
- assetDir,
4099
- platform
4100
- });
4101
- const filterValue = quickInput ? '' : getFilterValue(providerId, subId, newValue);
4102
- const items = filterQuickPickItems(newPicks, filterValue, subId === Commands$1);
4103
- const focusedIndex = items.length === 0 ? -1 : 0;
4104
- const sliced = items.slice(minLineY, maxLineY);
4105
- const {
4106
- icons,
4107
- newFileIconCache
4108
- } = await getQuickPickFileIcons(sliced, fileIconCache);
4109
- const listHeight = getListHeight$1(items.length, itemHeight, height);
4110
- const finalDeltaY = getFinalDeltaY(listHeight, itemHeight, items.length);
4427
+ const children = [];
4428
+ let i = startIndex;
4429
+ let remaining = childCount;
4430
+ let totalConsumed = 0;
4431
+ while (remaining > 0 && i < nodes.length) {
4432
+ const node = nodes[i];
4433
+ const nodeChildCount = node.childCount || 0;
4434
+ const {
4435
+ children: nodeChildren,
4436
+ nodesConsumed
4437
+ } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
4438
+ children.push({
4439
+ node,
4440
+ children: nodeChildren
4441
+ });
4442
+ const nodeSize = 1 + nodesConsumed;
4443
+ i += nodeSize;
4444
+ totalConsumed += nodeSize;
4445
+ remaining--;
4446
+ }
4111
4447
  return {
4112
- ...state,
4113
- fileIconCache: newFileIconCache,
4114
- finalDeltaY,
4115
- focusedIndex,
4116
- icons,
4117
- inputSource: Script,
4118
- items,
4119
- picks: newPicks,
4120
- value: newValue
4448
+ children,
4449
+ nodesConsumed: totalConsumed
4121
4450
  };
4122
4451
  };
4123
- const setValueWithContext = async (context, newValue) => {
4124
- const state = context.getState();
4125
- if (state.value === newValue) {
4452
+
4453
+ const isNavigationPatch = patch => {
4454
+ switch (patch.type) {
4455
+ case NavigateChild:
4456
+ case NavigateParent:
4457
+ case NavigateSibling:
4458
+ return true;
4459
+ default:
4460
+ return false;
4461
+ }
4462
+ };
4463
+ const getNavigationIndex = patch => {
4464
+ switch (patch.type) {
4465
+ case NavigateChild:
4466
+ case NavigateSibling:
4467
+ return patch.index;
4468
+ default:
4469
+ return 0;
4470
+ }
4471
+ };
4472
+ const appendNavigationPatch = (patches, type, index) => {
4473
+ const previousPatch = patches.at(-1);
4474
+ if (!previousPatch) {
4475
+ patches.push(type === NavigateParent ? {
4476
+ type
4477
+ } : {
4478
+ index,
4479
+ type
4480
+ });
4126
4481
  return;
4127
4482
  }
4128
- const requestVersion = ++requestVersionGenerator.value;
4129
- requestVersions.set(state.uid, requestVersion);
4130
- const result = await setValue(state, newValue);
4131
- await context.updateState(latestState => {
4132
- if (requestVersions.get(latestState.uid) !== requestVersion || !isSamePicker(state, latestState)) {
4133
- return latestState;
4134
- }
4135
- return {
4136
- ...latestState,
4137
- fileIconCache: result.fileIconCache,
4138
- finalDeltaY: result.finalDeltaY,
4139
- focusedIndex: result.focusedIndex,
4140
- icons: result.icons,
4141
- inputSource: result.inputSource,
4142
- items: result.items,
4143
- picks: result.picks,
4144
- value: result.value
4483
+ if (previousPatch.type === MultiNavigation) {
4484
+ previousPatch.navigations.push(type, index);
4485
+ return;
4486
+ }
4487
+ if (isNavigationPatch(previousPatch)) {
4488
+ patches[patches.length - 1] = {
4489
+ navigations: [previousPatch.type, getNavigationIndex(previousPatch), type, index],
4490
+ type: MultiNavigation
4145
4491
  };
4146
- });
4147
- if (requestVersions.get(state.uid) === requestVersion) {
4148
- requestVersions.delete(state.uid);
4492
+ return;
4149
4493
  }
4494
+ patches.push(type === NavigateParent ? {
4495
+ type
4496
+ } : {
4497
+ index,
4498
+ type
4499
+ });
4150
4500
  };
4151
4501
 
4152
- const handleInputWithContext = async (context, newValue, cursorOffset, inputSource = Script) => {
4153
- const state = context.getState();
4154
- if (state.value !== newValue) {
4155
- await setValueWithContext(context, newValue);
4502
+ const compareNodes = (oldNode, newNode) => {
4503
+ // Check if node type changed - return null to signal incompatible nodes
4504
+ // (caller should handle this with a Replace operation)
4505
+ if (oldNode.type !== newNode.type) {
4506
+ return null;
4156
4507
  }
4157
- await context.updateState(latestState => {
4158
- if (latestState.value !== newValue) {
4159
- return latestState;
4508
+ const patches = [];
4509
+ // Handle reference nodes - special handling for uid changes
4510
+ if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
4511
+ patches.push({
4512
+ type: SetReferenceNodeUid,
4513
+ uid: newNode.uid
4514
+ });
4515
+ }
4516
+ // Handle text nodes
4517
+ if (oldNode.type === Text && newNode.type === Text) {
4518
+ if (oldNode.text !== newNode.text) {
4519
+ patches.push({
4520
+ type: SetText,
4521
+ value: newNode.text
4522
+ });
4160
4523
  }
4161
- return {
4162
- ...latestState,
4163
- cursorOffset,
4164
- inputSource
4165
- };
4166
- });
4167
- };
4168
-
4169
- // TODO when user types letters -> no need to query provider again -> just filter existing results
4170
- const handleInput = async (state, newValue, cursorOffset, inputSource = Script) => {
4171
- if (state.value === newValue) {
4172
- return {
4173
- ...state,
4174
- cursorOffset,
4175
- inputSource
4176
- };
4524
+ return patches;
4177
4525
  }
4178
- const newState = await setValue(state, newValue);
4179
- return {
4180
- ...newState,
4181
- cursorOffset,
4182
- inputSource
4183
- };
4184
- };
4185
-
4186
- const handleBeforeInput = (state, inputType, data, selectionStart, selectionEnd) => {
4187
- string(inputType);
4188
- number(selectionStart);
4189
- number(selectionEnd);
4190
- const {
4191
- value
4192
- } = state;
4193
- const {
4194
- cursorOffset,
4195
- newValue
4196
- } = getNewValue(value, inputType, data, selectionStart, selectionEnd);
4197
- return handleInput(state, newValue, cursorOffset, User);
4198
- };
4199
-
4200
- const getCancelResult = args => {
4201
- const last = args.at(-1);
4202
- if (last && typeof last === 'object' &&
4203
- // @ts-ignore
4204
- last.mode === 'quickPick') {
4205
- return undefined;
4526
+ // Compare attributes
4527
+ const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
4528
+ const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
4529
+ // Check for attribute changes
4530
+ for (const key of newKeys) {
4531
+ if (oldNode[key] !== newNode[key]) {
4532
+ patches.push({
4533
+ type: SetAttribute,
4534
+ key,
4535
+ value: newNode[key]
4536
+ });
4537
+ }
4206
4538
  }
4207
- return {
4208
- canceled: true,
4209
- inputValue: ''
4210
- };
4211
- };
4212
- const handleBlur = async state => {
4213
- const {
4214
- args,
4215
- providerId
4216
- } = state;
4217
- if (providerId === Custom$1) {
4218
- const options = args.at(-1);
4219
- if (!options?.executeItemCommand) {
4220
- const resolveId = args[2];
4221
- await invoke$4('QuickPick.executeCallback', resolveId, getCancelResult(args));
4539
+ // Check for removed attributes
4540
+ for (const key of oldKeys) {
4541
+ if (!Object.hasOwn(newNode, key)) {
4542
+ patches.push({
4543
+ type: RemoveAttribute,
4544
+ key
4545
+ });
4222
4546
  }
4223
4547
  }
4224
- await closeWidget(state.uid);
4225
- return state;
4548
+ return patches;
4226
4549
  };
4227
4550
 
4228
- const getIndex = (top, headerHeight, itemHeight, y) => {
4229
- const relativeY = y - top - headerHeight;
4230
- const index = Math.floor(relativeY / itemHeight);
4231
- return index;
4551
+ const treeToArray = node => {
4552
+ const result = [];
4553
+ const stack = [node];
4554
+ while (stack.length > 0) {
4555
+ const current = stack.pop();
4556
+ result.push(current.node);
4557
+ for (let i = current.children.length - 1; i >= 0; i--) {
4558
+ stack.push(current.children[i]);
4559
+ }
4560
+ }
4561
+ return result;
4232
4562
  };
4233
4563
 
4234
- const Commands = 'quickPick://commands';
4235
- const EveryThing = 'quickPick://everything';
4236
- const Recent = 'quickPick://recent';
4237
- const ColorTheme = 'quickPick://color-theme';
4238
- const LanguageMode = 'quickPick://language-mode';
4239
- const Symbol$1 = 'quickPick://symbol';
4240
- const View = 'quickPick://view';
4241
- const Help = 'quickPick://help';
4242
- const WorkspaceSymbol = 'quickPick://workspace-symbol';
4243
- const Custom = 'quickPick://custom';
4244
- const GoToLine = 'quickPick://go-to-line';
4245
- const EndOfLine = 'quickPick://end-of-line';
4246
- const Indentation = 'quickPick://indentation';
4247
-
4248
- const getDefaultValue = (id, uri = '', args = []) => {
4249
- if (uri === GoToLine) {
4250
- const line = Number(args[1]);
4251
- const column = Number(args[2]);
4252
- if (Number.isSafeInteger(line) && Number.isSafeInteger(column) && line >= 1 && column >= 1) {
4253
- return `${GoToLine$1}${line}:${column}`;
4254
- }
4255
- return GoToLine$1;
4564
+ const navigateToChild = (patches, currentChildIndex, index) => {
4565
+ if (currentChildIndex === -1) {
4566
+ appendNavigationPatch(patches, NavigateChild, index);
4567
+ return index;
4256
4568
  }
4257
- if (uri === WorkspaceSymbol) {
4258
- return WorkspaceSymbol$1;
4569
+ if (currentChildIndex !== index) {
4570
+ appendNavigationPatch(patches, NavigateSibling, index);
4259
4571
  }
4260
- switch (id) {
4261
- case EveryThing$1:
4262
- return Command;
4263
- default:
4264
- return '';
4572
+ return index;
4573
+ };
4574
+ const navigateToParent = (patches, currentChildIndex) => {
4575
+ if (currentChildIndex >= 0) {
4576
+ appendNavigationPatch(patches, NavigateParent, 0);
4265
4577
  }
4578
+ return -1;
4266
4579
  };
4267
-
4268
- const getQuickPickProviderId = prefix => {
4269
- switch (prefix) {
4270
- case ColorTheme:
4271
- return ColorTheme$1;
4272
- case Commands:
4273
- case EveryThing:
4274
- case GoToLine:
4275
- case Help:
4276
- case Symbol$1:
4277
- case View:
4278
- case WorkspaceSymbol:
4279
- return EveryThing$1;
4280
- case Custom:
4281
- return Custom$1;
4282
- case EndOfLine:
4283
- return EndOfLine$1;
4284
- case Indentation:
4285
- return Indentation$1;
4286
- case LanguageMode:
4287
- return LanguageMode$1;
4288
- case Recent:
4289
- return Recent$1;
4580
+ const addTree = (newNode, patches) => {
4581
+ patches.push({
4582
+ type: Add,
4583
+ nodes: treeToArray(newNode)
4584
+ });
4585
+ };
4586
+ const replaceTree = (newNode, patches) => {
4587
+ patches.push({
4588
+ type: Replace,
4589
+ nodes: treeToArray(newNode)
4590
+ });
4591
+ };
4592
+ const appendPatch = (patches, patch) => {
4593
+ switch (patch.type) {
4594
+ case MultiNavigation:
4595
+ for (let i = 0; i < patch.navigations.length; i += 2) {
4596
+ appendNavigationPatch(patches, patch.navigations[i], patch.navigations[i + 1]);
4597
+ }
4598
+ return;
4599
+ case NavigateChild:
4600
+ case NavigateSibling:
4601
+ appendNavigationPatch(patches, patch.type, patch.index);
4602
+ return;
4603
+ case NavigateParent:
4604
+ appendNavigationPatch(patches, patch.type, 0);
4605
+ return;
4290
4606
  default:
4291
- return File$1;
4607
+ patches.push(patch);
4292
4608
  }
4293
4609
  };
4294
-
4295
- const callbacks = [];
4296
- const waitUntilVisible = () => {
4297
- const {
4298
- promise,
4299
- resolve
4300
- } = Promise.withResolvers();
4301
- callbacks.push(resolve);
4302
- return promise;
4303
- };
4304
- const notifyVisible = () => {
4305
- const pendingCallbacks = [...callbacks];
4306
- callbacks.length = 0;
4307
- for (const callback of pendingCallbacks) {
4308
- callback();
4610
+ const appendPatches = (patches, newPatches) => {
4611
+ for (const patch of newPatches) {
4612
+ appendPatch(patches, patch);
4309
4613
  }
4310
4614
  };
4311
-
4312
- const parseArgs = (subId, args) => {
4313
- if (subId !== Custom$1) {
4314
- return {
4315
- ignoreFocusOut: false,
4316
- initialValue: '',
4317
- placeholder: ''
4318
- };
4615
+ const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
4616
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
4617
+ if (nodePatches === null) {
4618
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
4619
+ replaceTree(newNode, patches);
4620
+ return nextChildIndex;
4319
4621
  }
4320
- const last = args.at(-1);
4321
- if (!last || typeof last !== 'object') {
4322
- return {
4323
- ignoreFocusOut: false,
4324
- initialValue: '',
4325
- placeholder: ''
4326
- };
4622
+ const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
4623
+ const childPatches = [];
4624
+ if (hasChildrenToCompare) {
4625
+ diffChildren(oldNode.children, newNode.children, childPatches);
4327
4626
  }
4328
- return {
4329
- // @ts-ignore
4330
- ignoreFocusOut: Boolean(last.ignoreFocusOut),
4331
- // @ts-ignore
4332
- initialValue: last.initialValue ? String(last.initialValue) : '',
4333
- // @ts-ignore
4334
- placeholder: last.placeholder ? String(last.placeholder) : ''
4335
- };
4627
+ if (nodePatches.length === 0 && childPatches.length === 0) {
4628
+ return currentChildIndex;
4629
+ }
4630
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
4631
+ patches.push(...nodePatches);
4632
+ appendPatches(patches, childPatches);
4633
+ return nextChildIndex;
4336
4634
  };
4337
- const getLoadedState = async state => {
4338
- const {
4339
- args,
4340
- assetDir,
4635
+ const diffRootNode = (oldNode, newNode, patches) => {
4636
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
4637
+ if (nodePatches === null) {
4638
+ replaceTree(newNode, patches);
4639
+ return;
4640
+ }
4641
+ if (nodePatches.length > 0) {
4642
+ patches.push(...nodePatches);
4643
+ }
4644
+ if (oldNode.children.length > 0 || newNode.children.length > 0) {
4645
+ diffChildren(oldNode.children, newNode.children, patches);
4646
+ }
4647
+ };
4648
+ const diffChildren = (oldChildren, newChildren, patches) => {
4649
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
4650
+ let currentChildIndex = -1;
4651
+ const indicesToRemove = [];
4652
+ for (let i = 0; i < maxLength; i++) {
4653
+ const oldNode = oldChildren[i];
4654
+ const newNode = newChildren[i];
4655
+ if (!oldNode && !newNode) {
4656
+ continue;
4657
+ }
4658
+ if (!oldNode) {
4659
+ currentChildIndex = navigateToParent(patches, currentChildIndex);
4660
+ addTree(newNode, patches);
4661
+ continue;
4662
+ }
4663
+ if (!newNode) {
4664
+ indicesToRemove.push(i);
4665
+ continue;
4666
+ }
4667
+ currentChildIndex = diffExistingChild(oldNode, newNode, patches, currentChildIndex, i);
4668
+ }
4669
+ navigateToParent(patches, currentChildIndex);
4670
+ for (let j = indicesToRemove.length - 1; j >= 0; j--) {
4671
+ patches.push({
4672
+ type: RemoveChild,
4673
+ index: indicesToRemove[j]
4674
+ });
4675
+ }
4676
+ };
4677
+ const diffTrees = (oldTree, newTree, patches, path) => {
4678
+ if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
4679
+ diffRootNode(oldTree[0], newTree[0], patches);
4680
+ return;
4681
+ }
4682
+ diffChildren(oldTree, newTree, patches);
4683
+ };
4684
+
4685
+ const removeTrailingNavigationPatches = patches => {
4686
+ while (patches.length > 0) {
4687
+ const patch = patches.at(-1);
4688
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling && patch.type !== MultiNavigation) {
4689
+ break;
4690
+ }
4691
+ patches.pop();
4692
+ }
4693
+ return patches;
4694
+ };
4695
+
4696
+ const diffTree = (oldNodes, newNodes) => {
4697
+ // Step 1: Convert flat arrays to tree structures
4698
+ const oldTree = arrayToTree(oldNodes);
4699
+ const newTree = arrayToTree(newNodes);
4700
+ // Step 3: Compare the trees
4701
+ const patches = [];
4702
+ diffTrees(oldTree, newTree, patches, []);
4703
+ // Remove trailing navigation patches since they serve no purpose
4704
+ return removeTrailingNavigationPatches(patches);
4705
+ };
4706
+
4707
+ const keyNames = new Map(Object.entries(KeyCode).map(([name, code]) => [code, name.replace(/^(Key|Digit)/, '')]));
4708
+ const getKeyLabel = key => {
4709
+ if (typeof key === 'string') {
4710
+ return key;
4711
+ }
4712
+ if (typeof key !== 'number' || !Number.isSafeInteger(key) || key <= 0) {
4713
+ return '';
4714
+ }
4715
+ const name = keyNames.get(key & 0xff);
4716
+ if (!name || name === 'Unknown') {
4717
+ return '';
4718
+ }
4719
+ return [...(key & 2048 ? ['Ctrl'] : []), ...(key & 1024 ? ['Shift'] : []), ...(key & 512 ? ['Alt'] : []), ...(key & 256 ? ['Meta'] : []), name].join('+');
4720
+ };
4721
+ const loadUserKeyBindings = async invoke => {
4722
+ try {
4723
+ const content = await invoke('FileSystem.readFile', 'app://keybindings.json');
4724
+ const parsed = JSON.parse(content);
4725
+ return Array.isArray(parsed) ? parsed.filter(entry => entry && (entry.source === 'User' || typeof entry.key === 'string' && !entry.source)) : [];
4726
+ } catch {
4727
+ return [];
4728
+ }
4729
+ };
4730
+ const loadCommandKeyBindings = async applicationId => {
4731
+ const invoke = (method, ...args) => applicationId === undefined ? invoke$4(method, ...args) : invoke$4('Application.execute', applicationId, method, ...args);
4732
+ try {
4733
+ if ((await invoke('Preferences.get', 'quickPick.showKeyBindings')) !== true) {
4734
+ return {};
4735
+ }
4736
+ const defaults = await invoke('KeyBindingsInitial.getKeyBindings');
4737
+ const user = await loadUserKeyBindings(invoke);
4738
+ const bindings = Object.create(null);
4739
+ for (const entry of [...user, ...defaults]) {
4740
+ const command = entry.command === 'ExtensionHost.executeCommand' ? `ext.${entry.args?.[0]}` : entry.command;
4741
+ const label = getKeyLabel(entry.key);
4742
+ if (typeof command === 'string' && label && !Object.hasOwn(bindings, command)) {
4743
+ bindings[command] = label;
4744
+ }
4745
+ }
4746
+ return bindings;
4747
+ } catch {
4748
+ return {};
4749
+ }
4750
+ };
4751
+
4752
+ const requestVersions = new Map();
4753
+ const requestVersionGenerator = {
4754
+ value: 0
4755
+ };
4756
+ const isSamePicker = (state, latestState) => {
4757
+ return latestState.uri === state.uri && latestState.args === state.args;
4758
+ };
4759
+ const isQuickInput = args => {
4760
+ const options = args.at(-1);
4761
+ return options?.mode === 'quickInput';
4762
+ };
4763
+ const isStaticQuickInput = args => {
4764
+ const options = args.at(-1);
4765
+ return options?.mode === 'quickInput' && options.quickInputId === undefined;
4766
+ };
4767
+ const setValue = async (state, newValue) => {
4768
+ const {
4769
+ args,
4770
+ assetDir,
4341
4771
  fileIconCache,
4342
4772
  height,
4343
4773
  itemHeight,
4344
4774
  maxVisibleItems,
4345
4775
  platform,
4346
- uri
4776
+ providerId,
4777
+ value
4347
4778
  } = state;
4348
- const id = getQuickPickProviderId(uri);
4349
- const value = getDefaultValue(id, uri, args);
4350
- const prefix = getQuickPickPrefix(value);
4351
- const subId = getQuickPickSubProviderId(id, prefix);
4352
- const newPicks = await getPicks(subId, value, args, {
4779
+ if (value === newValue) {
4780
+ return state;
4781
+ }
4782
+ if (isTextInput(args)) {
4783
+ return {
4784
+ ...state,
4785
+ inputSource: Script,
4786
+ value: newValue
4787
+ };
4788
+ }
4789
+ const prefix = getQuickPickPrefix(newValue);
4790
+ const subId = getQuickPickSubProviderId(providerId, prefix);
4791
+ const previousSubId = getQuickPickSubProviderId(providerId, getQuickPickPrefix(value));
4792
+ const commandKeyBindings = subId === Commands$1 && previousSubId !== subId ? await loadCommandKeyBindings(state.applicationId) : state.commandKeyBindings;
4793
+ const quickInput = isQuickInput(args);
4794
+ const reuseFilePicks = !state.initial && canReuseFilePicks(providerId, value, newValue, state.picks.length);
4795
+ const newPicks = isStaticQuickInput(args) || subId === LanguageMode$1 || reuseFilePicks ? state.picks : await getPicks(subId, newValue, args, {
4353
4796
  applicationId: state.applicationId,
4354
4797
  assetDir,
4355
4798
  platform
4356
4799
  });
4357
- array(newPicks);
4358
- let colorTheme = '';
4359
- if (subId === ColorTheme$1) {
4360
- try {
4361
- colorTheme = await invoke$4('ColorTheme.getColorTheme');
4362
- } catch {
4363
- // The worker can be released before the renderer endpoint.
4364
- }
4365
- }
4366
- const filterValue = getFilterValue(id, subId, value);
4367
- const items = isTextInput(args) ? newPicks : filterQuickPickItems(newPicks, filterValue, subId === Commands$1);
4368
- const focusedIndex = subId === ColorTheme$1 ? Math.max(items.findIndex(item => item.label === colorTheme), 0) : 0;
4369
- const minLineY = Math.max(Math.min(focusedIndex - maxVisibleItems + 1, items.length - maxVisibleItems), 0);
4370
- const maxLineY = Math.min(minLineY + maxVisibleItems, items.length);
4800
+ const filterValue = quickInput ? '' : getFilterValue(providerId, subId, newValue);
4801
+ const items = filterQuickPickItems(newPicks, filterValue, subId === Commands$1);
4802
+ const focusedIndex = items.length === 0 ? -1 : 0;
4803
+ const minLineY = 0;
4804
+ const maxLineY = Math.min(maxVisibleItems, items.length);
4371
4805
  const sliced = items.slice(minLineY, maxLineY);
4372
4806
  const {
4373
4807
  icons,
@@ -4375,96 +4809,342 @@ const getLoadedState = async state => {
4375
4809
  } = await getQuickPickFileIcons(sliced, fileIconCache);
4376
4810
  const listHeight = getListHeight$1(items.length, itemHeight, height);
4377
4811
  const finalDeltaY = getFinalDeltaY(listHeight, itemHeight, items.length);
4378
- const parsedArgs = parseArgs(subId, args);
4379
- const finalValue = parsedArgs.initialValue || value;
4380
4812
  return {
4381
4813
  ...state,
4382
- args,
4383
- cursorOffset: value.length,
4384
- deltaY: minLineY * itemHeight,
4814
+ commandKeyBindings,
4815
+ deltaY: 0,
4385
4816
  fileIconCache: newFileIconCache,
4386
4817
  finalDeltaY,
4387
- focused: true,
4388
4818
  focusedIndex,
4389
4819
  icons,
4390
- initial: false,
4391
4820
  inputSource: Script,
4392
4821
  items,
4393
4822
  maxLineY,
4394
4823
  minLineY,
4395
4824
  picks: newPicks,
4396
- placeholder: parsedArgs.placeholder,
4397
- providerId: id,
4398
- state: Finished,
4399
- value: finalValue
4825
+ value: newValue
4400
4826
  };
4401
4827
  };
4402
- const loadContent = async state => {
4403
- const newState = await getLoadedState(state);
4404
- notifyVisible();
4405
- return newState;
4406
- };
4407
- const loadContentWithContext = async context => {
4828
+ const setValueWithContext = async (context, newValue) => {
4408
4829
  const state = context.getState();
4409
- const loadedState = await getLoadedState(state);
4410
- await context.updateState(latestState => ({
4411
- ...latestState,
4412
- cursorOffset: loadedState.cursorOffset,
4413
- deltaY: loadedState.deltaY,
4414
- fileIconCache: loadedState.fileIconCache,
4415
- finalDeltaY: loadedState.finalDeltaY,
4416
- focused: loadedState.focused,
4417
- focusedIndex: loadedState.focusedIndex,
4418
- icons: loadedState.icons,
4419
- initial: loadedState.initial,
4420
- inputSource: loadedState.inputSource,
4421
- items: loadedState.items,
4422
- maxLineY: loadedState.maxLineY,
4423
- minLineY: loadedState.minLineY,
4424
- picks: loadedState.picks,
4425
- placeholder: loadedState.placeholder,
4426
- providerId: loadedState.providerId,
4427
- state: loadedState.state,
4428
- value: loadedState.value
4429
- }));
4430
- notifyVisible();
4830
+ if (state.value === newValue) {
4831
+ return;
4832
+ }
4833
+ const requestVersion = ++requestVersionGenerator.value;
4834
+ requestVersions.set(state.uid, requestVersion);
4835
+ const result = await setValue(state, newValue);
4836
+ await context.updateState(latestState => {
4837
+ if (requestVersions.get(latestState.uid) !== requestVersion || !isSamePicker(state, latestState)) {
4838
+ return latestState;
4839
+ }
4840
+ return {
4841
+ ...latestState,
4842
+ commandKeyBindings: result.commandKeyBindings,
4843
+ deltaY: result.deltaY,
4844
+ fileIconCache: result.fileIconCache,
4845
+ finalDeltaY: result.finalDeltaY,
4846
+ focusedIndex: result.focusedIndex,
4847
+ icons: result.icons,
4848
+ inputSource: result.inputSource,
4849
+ items: result.items,
4850
+ maxLineY: result.maxLineY,
4851
+ minLineY: result.minLineY,
4852
+ picks: result.picks,
4853
+ value: result.value
4854
+ };
4855
+ });
4856
+ if (requestVersions.get(state.uid) === requestVersion) {
4857
+ requestVersions.delete(state.uid);
4858
+ }
4431
4859
  };
4432
4860
 
4433
- const getPick = (items, index) => {
4434
- array(items);
4435
- number(index);
4436
- // if (index < state.recentPicks.length) {
4437
- // return state.recentPicks[index]
4438
- // }
4439
- // index -= state.recentPicks.length
4440
- if (index < items.length) {
4441
- return items[index];
4861
+ const handleInputWithContext = async (context, newValue, cursorOffset, inputSource = Script) => {
4862
+ const state = context.getState();
4863
+ if (state.value !== newValue) {
4864
+ await setValueWithContext(context, newValue);
4442
4865
  }
4443
- console.warn('no pick matching index', index);
4444
- return undefined;
4866
+ await context.updateState(latestState => {
4867
+ if (latestState.value !== newValue) {
4868
+ return latestState;
4869
+ }
4870
+ return {
4871
+ ...latestState,
4872
+ cursorOffset,
4873
+ inputSource
4874
+ };
4875
+ });
4445
4876
  };
4446
4877
 
4447
- const createCustomPick = value => {
4878
+ // TODO when user types letters -> no need to query provider again -> just filter existing results
4879
+ const handleInput = async (state, newValue, cursorOffset, inputSource = Script) => {
4880
+ if (state.value === newValue) {
4881
+ return {
4882
+ ...state,
4883
+ cursorOffset,
4884
+ inputSource
4885
+ };
4886
+ }
4887
+ const newState = await setValue(state, newValue);
4448
4888
  return {
4449
- description: '',
4450
- direntType: 0,
4451
- fileIcon: '',
4452
- icon: '',
4453
- label: value,
4454
- matches: [],
4455
- uri: ''
4889
+ ...newState,
4890
+ cursorOffset,
4891
+ inputSource
4456
4892
  };
4457
4893
  };
4458
- const shouldCloseBeforeSelect = (subId, pick) => {
4459
- if (subId === Recent$1) {
4460
- return true;
4461
- }
4462
- if (subId !== Commands$1) {
4463
- return false;
4464
- }
4465
- const {
4466
- id
4467
- } = pick;
4894
+
4895
+ const handleBeforeInput = (state, inputType, data, selectionStart, selectionEnd) => {
4896
+ string(inputType);
4897
+ number(selectionStart);
4898
+ number(selectionEnd);
4899
+ const {
4900
+ value
4901
+ } = state;
4902
+ const {
4903
+ cursorOffset,
4904
+ newValue
4905
+ } = getNewValue(value, inputType, data, selectionStart, selectionEnd);
4906
+ return handleInput(state, newValue, cursorOffset, User);
4907
+ };
4908
+
4909
+ const getCancelResult = args => {
4910
+ const last = args.at(-1);
4911
+ if (last && typeof last === 'object' &&
4912
+ // @ts-ignore
4913
+ last.mode === 'quickPick') {
4914
+ return undefined;
4915
+ }
4916
+ return {
4917
+ canceled: true,
4918
+ inputValue: ''
4919
+ };
4920
+ };
4921
+ const handleBlur = async state => {
4922
+ const {
4923
+ args,
4924
+ providerId
4925
+ } = state;
4926
+ if (providerId === Custom$1) {
4927
+ const options = args.at(-1);
4928
+ if (!options?.executeItemCommand) {
4929
+ const resolveId = args[2];
4930
+ await invoke$4('QuickPick.executeCallback', resolveId, getCancelResult(args));
4931
+ }
4932
+ }
4933
+ await closeWidget(state.uid);
4934
+ return state;
4935
+ };
4936
+
4937
+ const getIndex = (top, headerHeight, itemHeight, y) => {
4938
+ const relativeY = y - top - headerHeight;
4939
+ const index = Math.floor(relativeY / itemHeight);
4940
+ return index;
4941
+ };
4942
+
4943
+ const getDefaultValue = (id, uri = '', args = []) => {
4944
+ if (uri === GoToLine$1) {
4945
+ const line = Number(args[1]);
4946
+ const column = Number(args[2]);
4947
+ if (Number.isSafeInteger(line) && Number.isSafeInteger(column) && line >= 1 && column >= 1) {
4948
+ return `${GoToLine}${line}:${column}`;
4949
+ }
4950
+ return GoToLine;
4951
+ }
4952
+ if (uri === WorkspaceSymbol$1) {
4953
+ return WorkspaceSymbol;
4954
+ }
4955
+ switch (id) {
4956
+ case EveryThing$1:
4957
+ return Command;
4958
+ default:
4959
+ return '';
4960
+ }
4961
+ };
4962
+
4963
+ const callbacks = [];
4964
+ const waitUntilVisible = () => {
4965
+ const {
4966
+ promise,
4967
+ resolve
4968
+ } = Promise.withResolvers();
4969
+ callbacks.push(resolve);
4970
+ return promise;
4971
+ };
4972
+ const notifyVisible = () => {
4973
+ const pendingCallbacks = [...callbacks];
4974
+ callbacks.length = 0;
4975
+ for (const callback of pendingCallbacks) {
4976
+ callback();
4977
+ }
4978
+ };
4979
+
4980
+ const parseArgs = (subId, args) => {
4981
+ if (subId !== Custom$1) {
4982
+ return {
4983
+ ignoreFocusOut: false,
4984
+ initialValue: '',
4985
+ placeholder: ''
4986
+ };
4987
+ }
4988
+ const last = args.at(-1);
4989
+ if (!last || typeof last !== 'object') {
4990
+ return {
4991
+ ignoreFocusOut: false,
4992
+ initialValue: '',
4993
+ placeholder: ''
4994
+ };
4995
+ }
4996
+ return {
4997
+ // @ts-ignore
4998
+ ignoreFocusOut: Boolean(last.ignoreFocusOut),
4999
+ // @ts-ignore
5000
+ initialValue: last.initialValue ? String(last.initialValue) : '',
5001
+ // @ts-ignore
5002
+ placeholder: last.placeholder ? String(last.placeholder) : ''
5003
+ };
5004
+ };
5005
+ const getLoadedState = async state => {
5006
+ const {
5007
+ args,
5008
+ assetDir,
5009
+ fileIconCache,
5010
+ height,
5011
+ itemHeight,
5012
+ maxVisibleItems,
5013
+ platform,
5014
+ uri
5015
+ } = state;
5016
+ const id = getQuickPickProviderId(uri);
5017
+ const value = getDefaultValue(id, uri, args);
5018
+ const prefix = getQuickPickPrefix(value);
5019
+ const subId = getQuickPickSubProviderId(id, prefix);
5020
+ const commandKeyBindings = subId === Commands$1 ? await loadCommandKeyBindings(state.applicationId) : {};
5021
+ const newPicks = await getPicks(subId, value, args, {
5022
+ applicationId: state.applicationId,
5023
+ assetDir,
5024
+ platform
5025
+ });
5026
+ array(newPicks);
5027
+ let colorTheme = '';
5028
+ if (subId === ColorTheme$1) {
5029
+ try {
5030
+ colorTheme = await invoke$4('ColorTheme.getColorTheme');
5031
+ } catch {
5032
+ // The worker can be released before the renderer endpoint.
5033
+ }
5034
+ }
5035
+ const filterValue = getFilterValue(id, subId, value);
5036
+ const items = isTextInput(args) ? newPicks : filterQuickPickItems(newPicks, filterValue, subId === Commands$1);
5037
+ const focusedIndex = subId === ColorTheme$1 ? Math.max(items.findIndex(item => item.label === colorTheme), 0) : 0;
5038
+ const minLineY = Math.max(Math.min(focusedIndex - maxVisibleItems + 1, items.length - maxVisibleItems), 0);
5039
+ const maxLineY = Math.min(minLineY + maxVisibleItems, items.length);
5040
+ const sliced = items.slice(minLineY, maxLineY);
5041
+ const {
5042
+ icons,
5043
+ newFileIconCache
5044
+ } = await getQuickPickFileIcons(sliced, fileIconCache);
5045
+ const listHeight = getListHeight$1(items.length, itemHeight, height);
5046
+ const finalDeltaY = getFinalDeltaY(listHeight, itemHeight, items.length);
5047
+ const parsedArgs = parseArgs(subId, args);
5048
+ const finalValue = parsedArgs.initialValue || value;
5049
+ const latest = get$3(state.uid);
5050
+ if (latest && latest.newState.uri === state.uri && latest.newState.args === state.args && latest.newState.value !== state.value) {
5051
+ return state;
5052
+ }
5053
+ return {
5054
+ ...state,
5055
+ args,
5056
+ commandKeyBindings,
5057
+ cursorOffset: value.length,
5058
+ deltaY: minLineY * itemHeight,
5059
+ fileIconCache: newFileIconCache,
5060
+ finalDeltaY,
5061
+ focused: true,
5062
+ focusedIndex,
5063
+ icons,
5064
+ initial: false,
5065
+ inputSource: Script,
5066
+ items,
5067
+ maxLineY,
5068
+ minLineY,
5069
+ picks: newPicks,
5070
+ placeholder: parsedArgs.placeholder,
5071
+ providerId: id,
5072
+ state: Finished,
5073
+ value: finalValue
5074
+ };
5075
+ };
5076
+ const loadContent = async state => {
5077
+ const newState = await getLoadedState(state);
5078
+ notifyVisible();
5079
+ return newState;
5080
+ };
5081
+ const loadContentWithContext = async context => {
5082
+ const state = context.getState();
5083
+ const loadedState = await getLoadedState(state);
5084
+ await context.updateState(latestState => {
5085
+ if (latestState.value !== state.value || latestState.uri !== state.uri || latestState.args !== state.args) {
5086
+ return latestState;
5087
+ }
5088
+ return {
5089
+ ...latestState,
5090
+ commandKeyBindings: loadedState.commandKeyBindings,
5091
+ cursorOffset: loadedState.cursorOffset,
5092
+ deltaY: loadedState.deltaY,
5093
+ fileIconCache: loadedState.fileIconCache,
5094
+ finalDeltaY: loadedState.finalDeltaY,
5095
+ focused: loadedState.focused,
5096
+ focusedIndex: loadedState.focusedIndex,
5097
+ icons: loadedState.icons,
5098
+ initial: loadedState.initial,
5099
+ inputSource: loadedState.inputSource,
5100
+ items: loadedState.items,
5101
+ maxLineY: loadedState.maxLineY,
5102
+ minLineY: loadedState.minLineY,
5103
+ picks: loadedState.picks,
5104
+ placeholder: loadedState.placeholder,
5105
+ providerId: loadedState.providerId,
5106
+ state: loadedState.state,
5107
+ value: loadedState.value
5108
+ };
5109
+ });
5110
+ notifyVisible();
5111
+ };
5112
+
5113
+ const getPick = (items, index) => {
5114
+ array(items);
5115
+ number(index);
5116
+ // if (index < state.recentPicks.length) {
5117
+ // return state.recentPicks[index]
5118
+ // }
5119
+ // index -= state.recentPicks.length
5120
+ if (index < items.length) {
5121
+ return items[index];
5122
+ }
5123
+ console.warn('no pick matching index', index);
5124
+ return undefined;
5125
+ };
5126
+
5127
+ const createCustomPick = value => {
5128
+ return {
5129
+ description: '',
5130
+ direntType: 0,
5131
+ fileIcon: '',
5132
+ icon: '',
5133
+ label: value,
5134
+ matches: [],
5135
+ uri: ''
5136
+ };
5137
+ };
5138
+ const shouldCloseBeforeSelect = (subId, pick) => {
5139
+ if (subId === Recent$1) {
5140
+ return true;
5141
+ }
5142
+ if (subId !== Commands$1) {
5143
+ return false;
5144
+ }
5145
+ const {
5146
+ id
5147
+ } = pick;
4468
5148
  return typeof id === 'string' && (id.startsWith('ext.') || id === 'Main.openKeyBindings');
4469
5149
  };
4470
5150
  const selectIndex = async (state, index, button = /* left */0) => {
@@ -4578,471 +5258,148 @@ const handleMessagePort = async port => {
4578
5258
  };
4579
5259
 
4580
5260
  const state = {
4581
- connected: false
4582
- };
4583
- const isConnected = () => {
4584
- const {
4585
- connected
4586
- } = state;
4587
- return connected;
4588
- };
4589
- const invoke$1 = (method, ...params) => {
4590
- return invoke$5(method, ...params);
4591
- };
4592
- const set = rpc => {
4593
- set$7(rpc);
4594
- state.connected = true;
4595
- };
4596
-
4597
- const handleRendererProcessMessagePort = async (port, viewletCommandMap, setAsRendererProcess = true) => {
4598
- const executeViewletCommand = async (uid, command, ...args) => {
4599
- const fn = viewletCommandMap[`QuickPick.${command}`];
4600
- if (typeof fn !== 'function') {
4601
- throw new TypeError(`Viewlet command not found: ${command}`);
4602
- }
4603
- await fn(uid, ...args);
4604
- await invoke$4('Viewlet.requestRender', uid);
4605
- };
4606
- const rpc = await create$8({
4607
- commandMap: {
4608
- 'Viewlet.executeViewletCommand': executeViewletCommand
4609
- },
4610
- messagePort: port
4611
- });
4612
- if (setAsRendererProcess) {
4613
- set(rpc);
4614
- }
4615
- };
4616
-
4617
- const handleStatusBarMessagePort = async port => {
4618
- await create$8({
4619
- commandMap: commandMapRef,
4620
- isMessagePortOpen: true,
4621
- messagePort: port
4622
- });
4623
- };
4624
-
4625
- const initialize = async () => {
4626
- // not needed anymore
4627
- };
4628
-
4629
- const invoke = async (applicationId, method, ...args) => {
4630
- return applicationId === undefined ? invoke$4(method, ...args) : invoke$4('Application.execute', applicationId, method, ...args);
4631
- };
4632
-
4633
- const QuickPick$2 = 'QuickPick';
4634
-
4635
- const openStatusBarPicker = async (picker, ...args) => {
4636
- await invoke(undefined, 'Viewlet.openWidget', QuickPick$2, picker, ...args);
4637
- };
4638
-
4639
- const getCss = (scrollBarHeight, scrollBarTop, quickPickItemsHeight) => {
4640
- return `.QuickPick {
4641
- --QuickPickItemsHeight: ${quickPickItemsHeight}px;
4642
- --ScrollBarThumbHeight: ${scrollBarHeight}px;
4643
- --ScrollBarThumbTop: ${scrollBarTop}px;
4644
- }
4645
- .QuickPick .QuickPickItems {
4646
- height: var(--QuickPickItemsHeight);
4647
- }
4648
- .QuickPick .ScrollBarThumb {
4649
- height: var(--ScrollBarThumbHeight);
4650
- translate: 0px var(--ScrollBarThumbTop);
4651
- }`;
4652
- };
4653
-
4654
- const getQuickPickItemsHeight = height => {
4655
- if (height === 0) {
4656
- return 20;
4657
- }
4658
- return height;
4659
- };
4660
- const renderCss = (_oldState, newState) => {
4661
- const {
4662
- deltaY,
4663
- finalDeltaY,
4664
- headerHeight,
4665
- height,
4666
- itemHeight,
4667
- items,
4668
- minimumSliderSize,
4669
- uid
4670
- } = newState;
4671
- const quickPickItemsHeight = getQuickPickItemsHeight(height);
4672
- const listHeight = getListHeight$1(items.length, itemHeight, quickPickItemsHeight);
4673
- const contentHeight = items.length * itemHeight;
4674
- const scrollBarHeight = getScrollBarSize(listHeight, contentHeight, minimumSliderSize);
4675
- const scrollBarTop = Math.round(getScrollBarY(deltaY, finalDeltaY, quickPickItemsHeight - headerHeight, scrollBarHeight));
4676
- const css = getCss(scrollBarHeight, scrollBarTop, quickPickItemsHeight);
4677
- return [SetCss, uid, css];
4678
- };
4679
-
4680
- const SetCursorOffset = 'setCursorOffset';
4681
- const SetFocusedIndex = 'setFocusedIndex';
4682
- const SetItemsHeight = 'setItemsHeight';
4683
-
4684
- const renderCursorOffset = (_oldState, newState) => {
4685
- return ['Viewlet.send', newState.uid, /* method */SetCursorOffset, /* cursorOffset */newState.cursorOffset];
4686
- };
4687
-
4688
- const QuickPickInput = 'QuickPickInput';
4689
-
4690
- const renderFocus = (_oldState, newState) => {
4691
- return ['Viewlet.focusElementByName', newState.uid, QuickPickInput];
4692
- };
4693
-
4694
- const renderFocusedIndex = (oldState, newState) => {
4695
- const oldFocusedIndex = oldState.focusedIndex - oldState.minLineY;
4696
- const newFocusedIndex = newState.focusedIndex - newState.minLineY;
4697
- return ['Viewlet.send', newState.uid, /* method */SetFocusedIndex, /* oldFocusedIndex */oldFocusedIndex, /* newFocusedIndex */newFocusedIndex];
4698
- };
4699
-
4700
- const renderHeight = (_oldState, newState) => {
4701
- const {
4702
- height,
4703
- uid
4704
- } = newState;
4705
- if (height === 0) {
4706
- return ['Viewlet.send', uid, /* method */SetItemsHeight, /* height */20];
4707
- }
4708
- return ['Viewlet.send', uid, /* method */SetItemsHeight, /* height */height];
4709
- };
4710
-
4711
- const mergeClassNames = (...classNames) => {
4712
- return classNames.filter(Boolean).join(' ');
4713
- };
4714
-
4715
- const text = data => {
4716
- return {
4717
- childCount: 0,
4718
- text: data,
4719
- type: Text
4720
- };
4721
- };
4722
-
4723
- const SetText = 1;
4724
- const Replace = 2;
4725
- const SetAttribute = 3;
4726
- const RemoveAttribute = 4;
4727
- const Add = 6;
4728
- const NavigateChild = 7;
4729
- const NavigateParent = 8;
4730
- const RemoveChild = 9;
4731
- const NavigateSibling = 10;
4732
- const SetReferenceNodeUid = 11;
4733
- const MultiNavigation = 18;
4734
-
4735
- const isKey = key => {
4736
- return key !== 'type' && key !== 'childCount';
4737
- };
4738
-
4739
- const getKeys = node => {
4740
- const keys = Object.keys(node).filter(isKey);
4741
- return keys;
4742
- };
4743
-
4744
- const arrayToTree = nodes => {
4745
- const result = [];
4746
- let i = 0;
4747
- while (i < nodes.length) {
4748
- const node = nodes[i];
4749
- const {
4750
- children,
4751
- nodesConsumed
4752
- } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
4753
- result.push({
4754
- node,
4755
- children
4756
- });
4757
- i += 1 + nodesConsumed;
4758
- }
4759
- return result;
4760
- };
4761
- const getChildrenWithCount = (nodes, startIndex, childCount) => {
4762
- if (childCount === 0) {
4763
- return {
4764
- children: [],
4765
- nodesConsumed: 0
4766
- };
4767
- }
4768
- const children = [];
4769
- let i = startIndex;
4770
- let remaining = childCount;
4771
- let totalConsumed = 0;
4772
- while (remaining > 0 && i < nodes.length) {
4773
- const node = nodes[i];
4774
- const nodeChildCount = node.childCount || 0;
4775
- const {
4776
- children: nodeChildren,
4777
- nodesConsumed
4778
- } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
4779
- children.push({
4780
- node,
4781
- children: nodeChildren
4782
- });
4783
- const nodeSize = 1 + nodesConsumed;
4784
- i += nodeSize;
4785
- totalConsumed += nodeSize;
4786
- remaining--;
4787
- }
4788
- return {
4789
- children,
4790
- nodesConsumed: totalConsumed
4791
- };
4792
- };
4793
-
4794
- const isNavigationPatch = patch => {
4795
- switch (patch.type) {
4796
- case NavigateChild:
4797
- case NavigateParent:
4798
- case NavigateSibling:
4799
- return true;
4800
- default:
4801
- return false;
4802
- }
4803
- };
4804
- const getNavigationIndex = patch => {
4805
- switch (patch.type) {
4806
- case NavigateChild:
4807
- case NavigateSibling:
4808
- return patch.index;
4809
- default:
4810
- return 0;
4811
- }
4812
- };
4813
- const appendNavigationPatch = (patches, type, index) => {
4814
- const previousPatch = patches.at(-1);
4815
- if (!previousPatch) {
4816
- patches.push(type === NavigateParent ? {
4817
- type
4818
- } : {
4819
- index,
4820
- type
4821
- });
4822
- return;
4823
- }
4824
- if (previousPatch.type === MultiNavigation) {
4825
- previousPatch.navigations.push(type, index);
4826
- return;
4827
- }
4828
- if (isNavigationPatch(previousPatch)) {
4829
- patches[patches.length - 1] = {
4830
- navigations: [previousPatch.type, getNavigationIndex(previousPatch), type, index],
4831
- type: MultiNavigation
4832
- };
4833
- return;
4834
- }
4835
- patches.push(type === NavigateParent ? {
4836
- type
4837
- } : {
4838
- index,
4839
- type
4840
- });
4841
- };
4842
-
4843
- const compareNodes = (oldNode, newNode) => {
4844
- // Check if node type changed - return null to signal incompatible nodes
4845
- // (caller should handle this with a Replace operation)
4846
- if (oldNode.type !== newNode.type) {
4847
- return null;
4848
- }
4849
- const patches = [];
4850
- // Handle reference nodes - special handling for uid changes
4851
- if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
4852
- patches.push({
4853
- type: SetReferenceNodeUid,
4854
- uid: newNode.uid
4855
- });
4856
- }
4857
- // Handle text nodes
4858
- if (oldNode.type === Text && newNode.type === Text) {
4859
- if (oldNode.text !== newNode.text) {
4860
- patches.push({
4861
- type: SetText,
4862
- value: newNode.text
4863
- });
4864
- }
4865
- return patches;
4866
- }
4867
- // Compare attributes
4868
- const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
4869
- const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
4870
- // Check for attribute changes
4871
- for (const key of newKeys) {
4872
- if (oldNode[key] !== newNode[key]) {
4873
- patches.push({
4874
- type: SetAttribute,
4875
- key,
4876
- value: newNode[key]
4877
- });
4878
- }
4879
- }
4880
- // Check for removed attributes
4881
- for (const key of oldKeys) {
4882
- if (!Object.hasOwn(newNode, key)) {
4883
- patches.push({
4884
- type: RemoveAttribute,
4885
- key
4886
- });
4887
- }
4888
- }
4889
- return patches;
5261
+ connected: false
5262
+ };
5263
+ const isConnected = () => {
5264
+ const {
5265
+ connected
5266
+ } = state;
5267
+ return connected;
5268
+ };
5269
+ const invoke$1 = (method, ...params) => {
5270
+ return invoke$5(method, ...params);
5271
+ };
5272
+ const set = rpc => {
5273
+ set$7(rpc);
5274
+ state.connected = true;
4890
5275
  };
4891
5276
 
4892
- const treeToArray = node => {
4893
- const result = [];
4894
- const stack = [node];
4895
- while (stack.length > 0) {
4896
- const current = stack.pop();
4897
- result.push(current.node);
4898
- for (let i = current.children.length - 1; i >= 0; i--) {
4899
- stack.push(current.children[i]);
5277
+ const handleRendererProcessMessagePort = async (port, viewletCommandMap, setAsRendererProcess = true) => {
5278
+ const executeViewletCommand = async (uid, command, ...args) => {
5279
+ const fn = viewletCommandMap[`QuickPick.${command}`];
5280
+ if (typeof fn !== 'function') {
5281
+ throw new TypeError(`Viewlet command not found: ${command}`);
4900
5282
  }
5283
+ await fn(uid, ...args);
5284
+ await invoke$4('Viewlet.requestRender', uid);
5285
+ };
5286
+ const rpc = await create$8({
5287
+ commandMap: {
5288
+ 'Viewlet.executeViewletCommand': executeViewletCommand
5289
+ },
5290
+ messagePort: port
5291
+ });
5292
+ if (setAsRendererProcess) {
5293
+ set(rpc);
4901
5294
  }
4902
- return result;
4903
5295
  };
4904
5296
 
4905
- const navigateToChild = (patches, currentChildIndex, index) => {
4906
- if (currentChildIndex === -1) {
4907
- appendNavigationPatch(patches, NavigateChild, index);
4908
- return index;
4909
- }
4910
- if (currentChildIndex !== index) {
4911
- appendNavigationPatch(patches, NavigateSibling, index);
4912
- }
4913
- return index;
4914
- };
4915
- const navigateToParent = (patches, currentChildIndex) => {
4916
- if (currentChildIndex >= 0) {
4917
- appendNavigationPatch(patches, NavigateParent, 0);
4918
- }
4919
- return -1;
4920
- };
4921
- const addTree = (newNode, patches) => {
4922
- patches.push({
4923
- type: Add,
4924
- nodes: treeToArray(newNode)
5297
+ const handleStatusBarMessagePort = async port => {
5298
+ await create$8({
5299
+ commandMap: commandMapRef,
5300
+ isMessagePortOpen: true,
5301
+ messagePort: port
4925
5302
  });
4926
5303
  };
4927
- const replaceTree = (newNode, patches) => {
4928
- patches.push({
4929
- type: Replace,
4930
- nodes: treeToArray(newNode)
4931
- });
5304
+
5305
+ const initialize = async () => {
5306
+ // not needed anymore
4932
5307
  };
4933
- const appendPatch = (patches, patch) => {
4934
- switch (patch.type) {
4935
- case MultiNavigation:
4936
- for (let i = 0; i < patch.navigations.length; i += 2) {
4937
- appendNavigationPatch(patches, patch.navigations[i], patch.navigations[i + 1]);
4938
- }
4939
- return;
4940
- case NavigateChild:
4941
- case NavigateSibling:
4942
- appendNavigationPatch(patches, patch.type, patch.index);
4943
- return;
4944
- case NavigateParent:
4945
- appendNavigationPatch(patches, patch.type, 0);
4946
- return;
4947
- default:
4948
- patches.push(patch);
4949
- }
5308
+
5309
+ const invoke = async (applicationId, method, ...args) => {
5310
+ return applicationId === undefined ? invoke$4(method, ...args) : invoke$4('Application.execute', applicationId, method, ...args);
4950
5311
  };
4951
- const appendPatches = (patches, newPatches) => {
4952
- for (const patch of newPatches) {
4953
- appendPatch(patches, patch);
4954
- }
5312
+
5313
+ const QuickPick$2 = 'QuickPick';
5314
+
5315
+ const openStatusBarPicker = async (picker, ...args) => {
5316
+ await invoke(undefined, 'Viewlet.openWidget', QuickPick$2, picker, ...args);
4955
5317
  };
4956
- const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
4957
- const nodePatches = compareNodes(oldNode.node, newNode.node);
4958
- if (nodePatches === null) {
4959
- const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
4960
- replaceTree(newNode, patches);
4961
- return nextChildIndex;
4962
- }
4963
- const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
4964
- const childPatches = [];
4965
- if (hasChildrenToCompare) {
4966
- diffChildren(oldNode.children, newNode.children, childPatches);
4967
- }
4968
- if (nodePatches.length === 0 && childPatches.length === 0) {
4969
- return currentChildIndex;
4970
- }
4971
- const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
4972
- patches.push(...nodePatches);
4973
- appendPatches(patches, childPatches);
4974
- return nextChildIndex;
5318
+
5319
+ const getCss = (scrollBarHeight, scrollBarTop, quickPickItemsHeight) => {
5320
+ return `.QuickPick {
5321
+ --QuickPickItemsHeight: ${quickPickItemsHeight}px;
5322
+ --ScrollBarThumbHeight: ${scrollBarHeight}px;
5323
+ --ScrollBarThumbTop: ${scrollBarTop}px;
5324
+ }
5325
+ .QuickPick .QuickPickItems {
5326
+ height: var(--QuickPickItemsHeight);
5327
+ }
5328
+ .QuickPick .ScrollBarThumb {
5329
+ height: var(--ScrollBarThumbHeight);
5330
+ translate: 0px var(--ScrollBarThumbTop);
5331
+ }
5332
+ .QuickPickKeyBinding {
5333
+ margin-left: auto;
5334
+ display: flex;
5335
+ gap: 2px;
5336
+ flex-shrink: 0;
5337
+ pointer-events: none;
5338
+ }
5339
+ .QuickPickKeyBinding .Key {
5340
+ padding: 0 4px;
5341
+ line-height: 16px;
5342
+ }
5343
+ .QuickPickItem:has(.QuickPickKeyBinding) .QuickPickItemLabel {
5344
+ flex-shrink: 1;
5345
+ }`;
4975
5346
  };
4976
- const diffRootNode = (oldNode, newNode, patches) => {
4977
- const nodePatches = compareNodes(oldNode.node, newNode.node);
4978
- if (nodePatches === null) {
4979
- replaceTree(newNode, patches);
4980
- return;
4981
- }
4982
- if (nodePatches.length > 0) {
4983
- patches.push(...nodePatches);
4984
- }
4985
- if (oldNode.children.length > 0 || newNode.children.length > 0) {
4986
- diffChildren(oldNode.children, newNode.children, patches);
5347
+
5348
+ const getQuickPickItemsHeight = height => {
5349
+ if (height === 0) {
5350
+ return 20;
4987
5351
  }
5352
+ return height;
4988
5353
  };
4989
- const diffChildren = (oldChildren, newChildren, patches) => {
4990
- const maxLength = Math.max(oldChildren.length, newChildren.length);
4991
- let currentChildIndex = -1;
4992
- const indicesToRemove = [];
4993
- for (let i = 0; i < maxLength; i++) {
4994
- const oldNode = oldChildren[i];
4995
- const newNode = newChildren[i];
4996
- if (!oldNode && !newNode) {
4997
- continue;
4998
- }
4999
- if (!oldNode) {
5000
- currentChildIndex = navigateToParent(patches, currentChildIndex);
5001
- addTree(newNode, patches);
5002
- continue;
5003
- }
5004
- if (!newNode) {
5005
- indicesToRemove.push(i);
5006
- continue;
5007
- }
5008
- currentChildIndex = diffExistingChild(oldNode, newNode, patches, currentChildIndex, i);
5009
- }
5010
- navigateToParent(patches, currentChildIndex);
5011
- for (let j = indicesToRemove.length - 1; j >= 0; j--) {
5012
- patches.push({
5013
- type: RemoveChild,
5014
- index: indicesToRemove[j]
5015
- });
5016
- }
5354
+ const renderCss = (_oldState, newState) => {
5355
+ const {
5356
+ deltaY,
5357
+ finalDeltaY,
5358
+ headerHeight,
5359
+ height,
5360
+ itemHeight,
5361
+ items,
5362
+ minimumSliderSize,
5363
+ uid
5364
+ } = newState;
5365
+ const quickPickItemsHeight = getQuickPickItemsHeight(height);
5366
+ const listHeight = getListHeight$1(items.length, itemHeight, quickPickItemsHeight);
5367
+ const contentHeight = items.length * itemHeight;
5368
+ const scrollBarHeight = getScrollBarSize(listHeight, contentHeight, minimumSliderSize);
5369
+ const scrollBarTop = Math.round(getScrollBarY(deltaY, finalDeltaY, quickPickItemsHeight - headerHeight, scrollBarHeight));
5370
+ const css = getCss(scrollBarHeight, scrollBarTop, quickPickItemsHeight);
5371
+ return [SetCss, uid, css];
5017
5372
  };
5018
- const diffTrees = (oldTree, newTree, patches, path) => {
5019
- if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
5020
- diffRootNode(oldTree[0], newTree[0], patches);
5021
- return;
5022
- }
5023
- diffChildren(oldTree, newTree, patches);
5373
+
5374
+ const SetCursorOffset = 'setCursorOffset';
5375
+ const SetFocusedIndex = 'setFocusedIndex';
5376
+ const SetItemsHeight = 'setItemsHeight';
5377
+
5378
+ const renderCursorOffset = (_oldState, newState) => {
5379
+ return ['Viewlet.send', newState.uid, /* method */SetCursorOffset, /* cursorOffset */newState.cursorOffset];
5024
5380
  };
5025
5381
 
5026
- const removeTrailingNavigationPatches = patches => {
5027
- while (patches.length > 0) {
5028
- const patch = patches.at(-1);
5029
- if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling && patch.type !== MultiNavigation) {
5030
- break;
5031
- }
5032
- patches.pop();
5033
- }
5034
- return patches;
5382
+ const QuickPickInput = 'QuickPickInput';
5383
+
5384
+ const renderFocus = (_oldState, newState) => {
5385
+ return ['Viewlet.focusElementByName', newState.uid, QuickPickInput];
5035
5386
  };
5036
5387
 
5037
- const diffTree = (oldNodes, newNodes) => {
5038
- // Step 1: Convert flat arrays to tree structures
5039
- const oldTree = arrayToTree(oldNodes);
5040
- const newTree = arrayToTree(newNodes);
5041
- // Step 3: Compare the trees
5042
- const patches = [];
5043
- diffTrees(oldTree, newTree, patches, []);
5044
- // Remove trailing navigation patches since they serve no purpose
5045
- return removeTrailingNavigationPatches(patches);
5388
+ const renderFocusedIndex = (oldState, newState) => {
5389
+ const oldFocusedIndex = oldState.focusedIndex - oldState.minLineY;
5390
+ const newFocusedIndex = newState.focusedIndex - newState.minLineY;
5391
+ return ['Viewlet.send', newState.uid, /* method */SetFocusedIndex, /* oldFocusedIndex */oldFocusedIndex, /* newFocusedIndex */newFocusedIndex];
5392
+ };
5393
+
5394
+ const renderHeight = (_oldState, newState) => {
5395
+ const {
5396
+ height,
5397
+ uid
5398
+ } = newState;
5399
+ if (height === 0) {
5400
+ return ['Viewlet.send', uid, /* method */SetItemsHeight, /* height */20];
5401
+ }
5402
+ return ['Viewlet.send', uid, /* method */SetItemsHeight, /* height */height];
5046
5403
  };
5047
5404
 
5048
5405
  const getVisible$1 = (items, minLineY, maxLineY, icons) => {
@@ -5091,15 +5448,21 @@ const getHighlightSections = (highlights, label) => {
5091
5448
  return sections;
5092
5449
  };
5093
5450
 
5094
- const getVisible = (setSize, protoVisibleItems, minLineY, focusedIndex) => {
5451
+ const getVisible = (setSize, protoVisibleItems, minLineY, focusedIndex, keyBindings = {}) => {
5095
5452
  const visibleFocusedIndex = focusedIndex - minLineY;
5096
5453
  const visibleItems = protoVisibleItems.map((visibleItem, i) => {
5454
+ const {
5455
+ id
5456
+ } = visibleItem;
5097
5457
  const highlights = visibleItem.matches.slice(1);
5098
5458
  const sections = getHighlightSections(highlights, visibleItem.label);
5099
5459
  return {
5100
5460
  ...visibleItem,
5101
5461
  highlights: sections,
5102
5462
  isActive: i === visibleFocusedIndex,
5463
+ ...(id && Object.hasOwn(keyBindings, id) && {
5464
+ keyBinding: keyBindings[id]
5465
+ }),
5103
5466
  posInSet: minLineY + i + 1,
5104
5467
  setSize
5105
5468
  };
@@ -5126,7 +5489,8 @@ const createQuickPickViewModel = (oldState, newState) => {
5126
5489
  value
5127
5490
  } = newState;
5128
5491
  const protoVisibleItems = getVisible$1(items, minLineY, maxLineY, icons);
5129
- const visibleItems = getVisible(items.length, protoVisibleItems, minLineY, focusedIndex);
5492
+ const isCommands = getQuickPickSubProviderId(newState.providerId, getQuickPickPrefix(value)) === Commands$1;
5493
+ const visibleItems = getVisible(items.length, protoVisibleItems, minLineY, focusedIndex, isCommands ? newState.commandKeyBindings : {});
5130
5494
  const oldFocusedIndex = oldState.focusedIndex - oldState.minLineY;
5131
5495
  const newFocusedIndex = focusedIndex - minLineY;
5132
5496
  const itemCount = items.length;
@@ -5340,6 +5704,22 @@ const getQuickPickItemVirtualDom = visibleItem => {
5340
5704
  type: Div
5341
5705
  }, text(description));
5342
5706
  }
5707
+ if (visibleItem.keyBinding) {
5708
+ parent.childCount++;
5709
+ const keys = visibleItem.keyBinding.split('+');
5710
+ dom.push({
5711
+ childCount: keys.length,
5712
+ className: 'QuickPickKeyBinding',
5713
+ type: Div
5714
+ });
5715
+ for (const key of keys) {
5716
+ dom.push({
5717
+ childCount: 1,
5718
+ className: 'Key',
5719
+ type: Span
5720
+ }, text(key));
5721
+ }
5722
+ }
5343
5723
  if (removeButton) {
5344
5724
  parent.childCount++;
5345
5725
  dom.push({