@lvce-editor/text-search-view 1.17.2 → 1.18.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.
@@ -1026,6 +1026,34 @@ const listen$1 = async (module, options) => {
1026
1026
  return ipc;
1027
1027
  };
1028
1028
 
1029
+ const createSharedLazyRpc = factory => {
1030
+ let rpcPromise;
1031
+ const getOrCreate = () => {
1032
+ if (!rpcPromise) {
1033
+ rpcPromise = factory();
1034
+ }
1035
+ return rpcPromise;
1036
+ };
1037
+ return {
1038
+ async dispose() {
1039
+ const rpc = await getOrCreate();
1040
+ await rpc.dispose();
1041
+ },
1042
+ async invoke(method, ...params) {
1043
+ const rpc = await getOrCreate();
1044
+ return rpc.invoke(method, ...params);
1045
+ },
1046
+ async invokeAndTransfer(method, ...params) {
1047
+ const rpc = await getOrCreate();
1048
+ return rpc.invokeAndTransfer(method, ...params);
1049
+ },
1050
+ async send(method, ...params) {
1051
+ const rpc = await getOrCreate();
1052
+ rpc.send(method, ...params);
1053
+ }
1054
+ };
1055
+ };
1056
+
1029
1057
  const create$7 = async ({
1030
1058
  commandMap,
1031
1059
  isMessagePortOpen = true,
@@ -1061,34 +1089,6 @@ const create$6 = async ({
1061
1089
  });
1062
1090
  };
1063
1091
 
1064
- const createSharedLazyRpc = factory => {
1065
- let rpcPromise;
1066
- const getOrCreate = () => {
1067
- if (!rpcPromise) {
1068
- rpcPromise = factory();
1069
- }
1070
- return rpcPromise;
1071
- };
1072
- return {
1073
- async dispose() {
1074
- const rpc = await getOrCreate();
1075
- await rpc.dispose();
1076
- },
1077
- async invoke(method, ...params) {
1078
- const rpc = await getOrCreate();
1079
- return rpc.invoke(method, ...params);
1080
- },
1081
- async invokeAndTransfer(method, ...params) {
1082
- const rpc = await getOrCreate();
1083
- return rpc.invokeAndTransfer(method, ...params);
1084
- },
1085
- async send(method, ...params) {
1086
- const rpc = await getOrCreate();
1087
- rpc.send(method, ...params);
1088
- }
1089
- };
1090
- };
1091
-
1092
1092
  const create$5 = async ({
1093
1093
  commandMap,
1094
1094
  isMessagePortOpen,
@@ -1135,7 +1135,7 @@ const createMockRpc = ({
1135
1135
  };
1136
1136
 
1137
1137
  const rpcs = Object.create(null);
1138
- const set$8 = (id, rpc) => {
1138
+ const set$9 = (id, rpc) => {
1139
1139
  rpcs[id] = rpc;
1140
1140
  };
1141
1141
  const get$1 = id => {
@@ -1168,7 +1168,7 @@ const create$3 = rpcId => {
1168
1168
  const mockRpc = createMockRpc({
1169
1169
  commandMap
1170
1170
  });
1171
- set$8(rpcId, mockRpc);
1171
+ set$9(rpcId, mockRpc);
1172
1172
  // @ts-ignore
1173
1173
  mockRpc[Symbol.dispose] = () => {
1174
1174
  remove$2(rpcId);
@@ -1177,7 +1177,7 @@ const create$3 = rpcId => {
1177
1177
  return mockRpc;
1178
1178
  },
1179
1179
  set(rpc) {
1180
- set$8(rpcId, rpc);
1180
+ set$9(rpcId, rpc);
1181
1181
  }
1182
1182
  };
1183
1183
  };
@@ -1189,7 +1189,7 @@ const None$2 = 'none';
1189
1189
  const ScrollBar$1 = 'scrollbar';
1190
1190
  const Status = 'status';
1191
1191
  const ToolBar = 'toolbar';
1192
- const Tree$1 = 'tree';
1192
+ const Tree$2 = 'tree';
1193
1193
  const TreeItem$1 = 'treeitem';
1194
1194
 
1195
1195
  const Actions = 'Actions';
@@ -1206,7 +1206,7 @@ const HighlightInserted = 'HighlightInserted';
1206
1206
  const IconButton = 'IconButton';
1207
1207
  const IconButtonDisabled = 'IconButtonDisabled';
1208
1208
  const InputBox = 'InputBox';
1209
- const Label$1 = 'Label';
1209
+ const Label = 'Label';
1210
1210
  const List$1 = 'List';
1211
1211
  const MaskIcon = 'MaskIcon';
1212
1212
  const MaskIconBook = 'MaskIconBook';
@@ -1223,7 +1223,7 @@ const MultilineInputBox = 'MultilineInputBox';
1223
1223
  const ScrollBar = 'ScrollBar';
1224
1224
  const ScrollBarThumb = 'ScrollBarThumb';
1225
1225
  const ScrollBarVertical = 'ScrollBarVertical';
1226
- const Search$3 = 'Search';
1226
+ const Search$2 = 'Search';
1227
1227
  const SearchField = 'SearchField';
1228
1228
  const SearchFieldButton = 'SearchFieldButton';
1229
1229
  const SearchFieldButtonChecked = 'SearchFieldButtonChecked';
@@ -1244,7 +1244,7 @@ const SearchToggleButton = 'SearchToggleButton';
1244
1244
  const SearchToggleButtonExpanded = 'SearchToggleButtonExpanded';
1245
1245
  const SourceControlBadge = 'SourceControlBadge';
1246
1246
  const ToggleDetails = 'ToggleDetails';
1247
- const Tree = 'Tree';
1247
+ const Tree$1 = 'Tree';
1248
1248
  const TreeItem = 'TreeItem';
1249
1249
  const TreeItemActive = 'TreeItemActive';
1250
1250
  const TreeItems$1 = 'TreeItems';
@@ -1254,175 +1254,18 @@ const ViewletSearchMessageIndented = 'ViewletSearchMessageIndented';
1254
1254
 
1255
1255
  const File$2 = 7;
1256
1256
 
1257
- const Audio = 0;
1258
1257
  const Button$2 = 1;
1259
- const Col = 2;
1260
- const ColGroup = 3;
1261
1258
  const Div = 4;
1262
- const H1 = 5;
1263
1259
  const Input = 6;
1264
- const Kbd = 7;
1265
1260
  const Span = 8;
1266
- const Table = 9;
1267
- const TBody = 10;
1268
- const Td = 11;
1269
1261
  const Text = 12;
1270
- const Th = 13;
1271
- const THead = 14;
1272
- const Tr = 15;
1273
- const I = 16;
1274
1262
  const Img = 17;
1275
- const Root = 0;
1276
1263
  const Ins = 20;
1277
1264
  const Del = 21;
1278
- const H2 = 22;
1279
- const H3 = 23;
1280
1265
  const H4 = 24;
1281
- const H5 = 25;
1282
- const H6 = 26;
1283
- const Article = 27;
1284
- const Aside = 28;
1285
- const Footer = 29;
1286
- const Header = 30;
1287
- const Nav = 40;
1288
- const Section = 41;
1289
- const Search$2 = 42;
1290
- const Dd = 43;
1291
- const Dl = 44;
1292
- const Figcaption = 45;
1293
- const Figure = 46;
1294
- const Hr = 47;
1295
- const Li = 48;
1296
- const Ol = 49;
1297
- const P = 50;
1298
- const Pre = 51;
1299
- const A = 53;
1300
- const Abbr = 54;
1301
- const Br = 55;
1302
- const Cite = 56;
1303
- const Data = 57;
1304
- const Time = 58;
1305
- const Tfoot = 59;
1306
- const Ul = 60;
1307
- const Video = 61;
1308
1266
  const TextArea = 62;
1309
- const Select = 63;
1310
- const Option = 64;
1311
- const Code = 65;
1312
- const Label = 66;
1313
- const Dt = 67;
1314
- const Iframe = 68;
1315
- const Main = 69;
1316
- const Strong = 70;
1317
- const Em = 71;
1318
- const Style = 72;
1319
- const Html = 73;
1320
- const Head = 74;
1321
- const Title = 75;
1322
- const Meta = 76;
1323
- const Canvas = 77;
1324
- const Form = 78;
1325
- const BlockQuote = 79;
1326
- const Quote = 80;
1327
- const Circle = 81;
1328
- const Defs = 82;
1329
- const Ellipse = 83;
1330
- const G = 84;
1331
- const Line = 85;
1332
- const Path = 86;
1333
- const Polygon = 87;
1334
- const Polyline = 88;
1335
- const Rect = 89;
1336
- const Svg = 90;
1337
- const Use = 91;
1338
1267
  const Reference = 100;
1339
1268
 
1340
- const VirtualDomElements = {
1341
- __proto__: null,
1342
- A,
1343
- Abbr,
1344
- Article,
1345
- Aside,
1346
- Audio,
1347
- BlockQuote,
1348
- Br,
1349
- Button: Button$2,
1350
- Canvas,
1351
- Circle,
1352
- Cite,
1353
- Code,
1354
- Col,
1355
- ColGroup,
1356
- Data,
1357
- Dd,
1358
- Defs,
1359
- Del,
1360
- Div,
1361
- Dl,
1362
- Dt,
1363
- Ellipse,
1364
- Em,
1365
- Figcaption,
1366
- Figure,
1367
- Footer,
1368
- Form,
1369
- G,
1370
- H1,
1371
- H2,
1372
- H3,
1373
- H4,
1374
- H5,
1375
- H6,
1376
- Head,
1377
- Header,
1378
- Hr,
1379
- Html,
1380
- I,
1381
- Iframe,
1382
- Img,
1383
- Input,
1384
- Ins,
1385
- Kbd,
1386
- Label,
1387
- Li,
1388
- Line,
1389
- Main,
1390
- Meta,
1391
- Nav,
1392
- Ol,
1393
- Option,
1394
- P,
1395
- Path,
1396
- Polygon,
1397
- Polyline,
1398
- Pre,
1399
- Quote,
1400
- Rect,
1401
- Reference,
1402
- Root,
1403
- Search: Search$2,
1404
- Section,
1405
- Select,
1406
- Span,
1407
- Strong,
1408
- Style,
1409
- Svg,
1410
- TBody,
1411
- THead,
1412
- Table,
1413
- Td,
1414
- Text,
1415
- TextArea,
1416
- Tfoot,
1417
- Th,
1418
- Time,
1419
- Title,
1420
- Tr,
1421
- Ul,
1422
- Use,
1423
- Video
1424
- };
1425
-
1426
1269
  const Button$1 = 'event.button';
1427
1270
  const ClientX = 'event.clientX';
1428
1271
  const ClientY = 'event.clientY';
@@ -1443,7 +1286,8 @@ const None$1 = 0;
1443
1286
 
1444
1287
  const LeftClick = 0;
1445
1288
 
1446
- const DialogWorker = 7014;
1289
+ const ClipBoardWorker = 3400;
1290
+ const DialogWorker$1 = 7014;
1447
1291
  const IconThemeWorker = 7009;
1448
1292
  const RendererProcess = 1670;
1449
1293
  const RendererWorker = 1;
@@ -1455,6 +1299,7 @@ const Match$1 = 2;
1455
1299
 
1456
1300
  const FocusElementByName = 'Viewlet.focusElementByName';
1457
1301
  const SetCss = 'Viewlet.setCss';
1302
+ const SetDom2 = 'Viewlet.setDom2';
1458
1303
  const SetFocusContext = 'Viewlet.setFocusContext';
1459
1304
  const SetValueByName = 'Viewlet.setValueByName';
1460
1305
  const SetPatches = 'Viewlet.setPatches';
@@ -1476,10 +1321,31 @@ const FocusSearchWholeWord = 34;
1476
1321
  const FocusToggleDetails = 1010;
1477
1322
  const FocusToggleReplace = 1020;
1478
1323
 
1324
+ const {
1325
+ invoke: invoke$7,
1326
+ set: set$8
1327
+ } = create$3(ClipBoardWorker);
1328
+ const writeText$1 = async text => {
1329
+ return invoke$7('ClipBoard.writeText', text);
1330
+ };
1331
+ const readText$1 = async () => {
1332
+ return invoke$7('ClipBoard.readText');
1333
+ };
1334
+
1479
1335
  const {
1480
1336
  invoke: invoke$6,
1481
1337
  set: set$7
1482
- } = create$3(DialogWorker);
1338
+ } = create$3(DialogWorker$1);
1339
+ const prompt$1 = async (message, options = {}) => {
1340
+ return invoke$6('ConfirmPrompt.prompt', message, options);
1341
+ };
1342
+
1343
+ const DialogWorker = {
1344
+ __proto__: null,
1345
+ invoke: invoke$6,
1346
+ prompt: prompt$1,
1347
+ set: set$7
1348
+ };
1483
1349
 
1484
1350
  const {
1485
1351
  invoke: invoke$5,
@@ -1497,15 +1363,24 @@ const {
1497
1363
 
1498
1364
  const {
1499
1365
  invoke: invoke$3,
1500
- invokeAndTransfer,
1501
1366
  set: set$4
1367
+ } = create$3(TextMeasurementWorker);
1368
+
1369
+ const {
1370
+ invoke: invoke$2,
1371
+ invokeAndTransfer,
1372
+ set: set$3
1502
1373
  } = create$3(RendererWorker);
1503
1374
  const showContextMenu2 = async (uid, menuId, x, y, args) => {
1504
1375
  number(uid);
1505
1376
  number(menuId);
1506
1377
  number(x);
1507
1378
  number(y);
1508
- await invoke$3('ContextMenu.show2', uid, menuId, x, y, args);
1379
+ await invoke$2('ContextMenu.show2', uid, menuId, x, y, args);
1380
+ };
1381
+ const sendMessagePortToClipBoardWorker$1 = async (port, rpcId) => {
1382
+ const command = 'ClipBoard.handleMessagePort';
1383
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToClipBoardWorker', port, command, rpcId);
1509
1384
  };
1510
1385
  const sendMessagePortToTextSearchWorker = async (port, rpcId) => {
1511
1386
  const command = 'HandleMessagePort.handleMessagePort';
@@ -1520,34 +1395,46 @@ const sendMessagePortToIconThemeWorker = async (port, rpcId) => {
1520
1395
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToIconThemeWorker', port, command, rpcId);
1521
1396
  };
1522
1397
  const handleWorkspaceRefresh = async () => {
1523
- return invoke$3('Layout.handleWorkspaceRefresh');
1524
- };
1525
- const writeClipBoardText = async text => {
1526
- await invoke$3('ClipBoard.writeText', /* text */text);
1398
+ return invoke$2('Layout.handleWorkspaceRefresh');
1527
1399
  };
1528
1400
  const sendMessagePortToTextMeasurementWorker = async port => {
1529
1401
  const command = 'TextMeasurement.handleMessagePort';
1530
1402
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToTextMeasurementWorker', port, command, 0);
1531
1403
  };
1532
1404
  const getPreference = async key => {
1533
- return await invoke$3('Preferences.get', key);
1405
+ return await invoke$2('Preferences.get', key);
1534
1406
  };
1535
1407
  const openUri$1 = async (uri, focus, options) => {
1536
- await invoke$3('Main.openUri', uri, focus, options);
1408
+ await invoke$2('Main.openUri', {
1409
+ ...options,
1410
+ focus,
1411
+ uri
1412
+ });
1413
+ };
1414
+ const openUri2 = async ({
1415
+ focus,
1416
+ selections,
1417
+ uri
1418
+ }) => {
1419
+ await invoke$2('Main.openUri', {
1420
+ focus,
1421
+ selections,
1422
+ uri
1423
+ });
1537
1424
  };
1538
1425
 
1539
1426
  const {
1540
- invoke: invoke$2,
1541
- set: set$3
1427
+ invoke: invoke$1,
1428
+ set: set$2
1542
1429
  } = create$3(TextSearchWorker);
1543
1430
  const getIncrementalResults = async (searchId, minLineY, maxLineY) => {
1544
- return invoke$2('TextSearch.getIncrementalResults', searchId, minLineY, maxLineY);
1431
+ return invoke$1('TextSearch.getIncrementalResults', searchId, minLineY, maxLineY);
1545
1432
  };
1546
1433
  const search$1 = async (...args) => {
1547
- return invoke$2('TextSearch.search', ...args);
1434
+ return invoke$1('TextSearch.search', ...args);
1548
1435
  };
1549
1436
  const searchIncremental = async (...args) => {
1550
- return invoke$2('TextSearch.searchIncremental', ...args);
1437
+ return invoke$1('TextSearch.searchIncremental', ...args);
1551
1438
  };
1552
1439
 
1553
1440
  const toCommandId = key => {
@@ -1808,8 +1695,6 @@ const text = data => {
1808
1695
  };
1809
1696
  };
1810
1697
 
1811
- new Set(Object.values(VirtualDomElements));
1812
-
1813
1698
  const SetText = 1;
1814
1699
  const Replace$1 = 2;
1815
1700
  const SetAttribute = 3;
@@ -1820,6 +1705,7 @@ const NavigateParent = 8;
1820
1705
  const RemoveChild = 9;
1821
1706
  const NavigateSibling = 10;
1822
1707
  const SetReferenceNodeUid = 11;
1708
+ const MultiNavigation = 18;
1823
1709
 
1824
1710
  const isKey = key => {
1825
1711
  return key !== 'type' && key !== 'childCount';
@@ -1880,6 +1766,55 @@ const getChildrenWithCount = (nodes, startIndex, childCount) => {
1880
1766
  };
1881
1767
  };
1882
1768
 
1769
+ const isNavigationPatch = patch => {
1770
+ switch (patch.type) {
1771
+ case NavigateChild:
1772
+ case NavigateParent:
1773
+ case NavigateSibling:
1774
+ return true;
1775
+ default:
1776
+ return false;
1777
+ }
1778
+ };
1779
+ const getNavigationIndex = patch => {
1780
+ switch (patch.type) {
1781
+ case NavigateChild:
1782
+ case NavigateSibling:
1783
+ return patch.index;
1784
+ default:
1785
+ return 0;
1786
+ }
1787
+ };
1788
+ const appendNavigationPatch = (patches, type, index) => {
1789
+ const previousPatch = patches.at(-1);
1790
+ if (!previousPatch) {
1791
+ patches.push(type === NavigateParent ? {
1792
+ type
1793
+ } : {
1794
+ index,
1795
+ type
1796
+ });
1797
+ return;
1798
+ }
1799
+ if (previousPatch.type === MultiNavigation) {
1800
+ previousPatch.navigations.push(type, index);
1801
+ return;
1802
+ }
1803
+ if (isNavigationPatch(previousPatch)) {
1804
+ patches[patches.length - 1] = {
1805
+ navigations: [previousPatch.type, getNavigationIndex(previousPatch), type, index],
1806
+ type: MultiNavigation
1807
+ };
1808
+ return;
1809
+ }
1810
+ patches.push(type === NavigateParent ? {
1811
+ type
1812
+ } : {
1813
+ index,
1814
+ type
1815
+ });
1816
+ };
1817
+
1883
1818
  const compareNodes = (oldNode, newNode) => {
1884
1819
  // Check if node type changed - return null to signal incompatible nodes
1885
1820
  // (caller should handle this with a Replace operation)
@@ -1888,14 +1823,11 @@ const compareNodes = (oldNode, newNode) => {
1888
1823
  }
1889
1824
  const patches = [];
1890
1825
  // Handle reference nodes - special handling for uid changes
1891
- if (oldNode.type === Reference) {
1892
- if (oldNode.uid !== newNode.uid) {
1893
- patches.push({
1894
- type: SetReferenceNodeUid,
1895
- uid: newNode.uid
1896
- });
1897
- }
1898
- return patches;
1826
+ if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
1827
+ patches.push({
1828
+ type: SetReferenceNodeUid,
1829
+ uid: newNode.uid
1830
+ });
1899
1831
  }
1900
1832
  // Handle text nodes
1901
1833
  if (oldNode.type === Text && newNode.type === Text) {
@@ -1908,8 +1840,8 @@ const compareNodes = (oldNode, newNode) => {
1908
1840
  return patches;
1909
1841
  }
1910
1842
  // Compare attributes
1911
- const oldKeys = getKeys(oldNode);
1912
- const newKeys = getKeys(newNode);
1843
+ const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
1844
+ const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
1913
1845
  // Check for attribute changes
1914
1846
  for (const key of newKeys) {
1915
1847
  if (oldNode[key] !== newNode[key]) {
@@ -1933,34 +1865,31 @@ const compareNodes = (oldNode, newNode) => {
1933
1865
  };
1934
1866
 
1935
1867
  const treeToArray = node => {
1936
- const result = [node.node];
1937
- for (const child of node.children) {
1938
- result.push(...treeToArray(child));
1868
+ const result = [];
1869
+ const stack = [node];
1870
+ while (stack.length > 0) {
1871
+ const current = stack.pop();
1872
+ result.push(current.node);
1873
+ for (let i = current.children.length - 1; i >= 0; i--) {
1874
+ stack.push(current.children[i]);
1875
+ }
1939
1876
  }
1940
1877
  return result;
1941
1878
  };
1942
1879
 
1943
1880
  const navigateToChild = (patches, currentChildIndex, index) => {
1944
1881
  if (currentChildIndex === -1) {
1945
- patches.push({
1946
- type: NavigateChild,
1947
- index
1948
- });
1882
+ appendNavigationPatch(patches, NavigateChild, index);
1949
1883
  return index;
1950
1884
  }
1951
1885
  if (currentChildIndex !== index) {
1952
- patches.push({
1953
- type: NavigateSibling,
1954
- index
1955
- });
1886
+ appendNavigationPatch(patches, NavigateSibling, index);
1956
1887
  }
1957
1888
  return index;
1958
1889
  };
1959
1890
  const navigateToParent = (patches, currentChildIndex) => {
1960
1891
  if (currentChildIndex >= 0) {
1961
- patches.push({
1962
- type: NavigateParent
1963
- });
1892
+ appendNavigationPatch(patches, NavigateParent, 0);
1964
1893
  }
1965
1894
  return -1;
1966
1895
  };
@@ -1976,6 +1905,29 @@ const replaceTree = (newNode, patches) => {
1976
1905
  nodes: treeToArray(newNode)
1977
1906
  });
1978
1907
  };
1908
+ const appendPatch = (patches, patch) => {
1909
+ switch (patch.type) {
1910
+ case MultiNavigation:
1911
+ for (let i = 0; i < patch.navigations.length; i += 2) {
1912
+ appendNavigationPatch(patches, patch.navigations[i], patch.navigations[i + 1]);
1913
+ }
1914
+ return;
1915
+ case NavigateChild:
1916
+ case NavigateSibling:
1917
+ appendNavigationPatch(patches, patch.type, patch.index);
1918
+ return;
1919
+ case NavigateParent:
1920
+ appendNavigationPatch(patches, patch.type, 0);
1921
+ return;
1922
+ default:
1923
+ patches.push(patch);
1924
+ }
1925
+ };
1926
+ const appendPatches = (patches, newPatches) => {
1927
+ for (const patch of newPatches) {
1928
+ appendPatch(patches, patch);
1929
+ }
1930
+ };
1979
1931
  const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
1980
1932
  const nodePatches = compareNodes(oldNode.node, newNode.node);
1981
1933
  if (nodePatches === null) {
@@ -1984,16 +1936,16 @@ const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index)
1984
1936
  return nextChildIndex;
1985
1937
  }
1986
1938
  const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
1987
- if (nodePatches.length === 0 && !hasChildrenToCompare) {
1939
+ const childPatches = [];
1940
+ if (hasChildrenToCompare) {
1941
+ diffChildren(oldNode.children, newNode.children, childPatches);
1942
+ }
1943
+ if (nodePatches.length === 0 && childPatches.length === 0) {
1988
1944
  return currentChildIndex;
1989
1945
  }
1990
1946
  const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
1991
- if (nodePatches.length > 0) {
1992
- patches.push(...nodePatches);
1993
- }
1994
- if (hasChildrenToCompare) {
1995
- diffChildren(oldNode.children, newNode.children, patches);
1996
- }
1947
+ patches.push(...nodePatches);
1948
+ appendPatches(patches, childPatches);
1997
1949
  return nextChildIndex;
1998
1950
  };
1999
1951
  const diffRootNode = (oldNode, newNode, patches) => {
@@ -2049,7 +2001,7 @@ const diffTrees = (oldTree, newTree, patches, path) => {
2049
2001
  const removeTrailingNavigationPatches = patches => {
2050
2002
  while (patches.length > 0) {
2051
2003
  const patch = patches.at(-1);
2052
- if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
2004
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling && patch.type !== MultiNavigation) {
2053
2005
  break;
2054
2006
  }
2055
2007
  patches.pop();
@@ -2099,6 +2051,95 @@ const clearSearchResults$1 = state => {
2099
2051
  };
2100
2052
  };
2101
2053
 
2054
+ const clamp$1 = (num, min, max) => {
2055
+ return Math.min(Math.max(num, min), max);
2056
+ };
2057
+
2058
+ const File = 1;
2059
+ const Match = 2;
2060
+ const Context = 3;
2061
+
2062
+ const getFilteredResults = (results, collapsedPaths) => {
2063
+ if (collapsedPaths.length === 0) {
2064
+ return results;
2065
+ }
2066
+ const filteredResults = [];
2067
+ let collapsedDepth = -1;
2068
+ for (const result of results) {
2069
+ const depth = result.depth ?? (result.type === File ? 0 : 1);
2070
+ if (collapsedDepth !== -1) {
2071
+ if (depth > collapsedDepth) {
2072
+ continue;
2073
+ }
2074
+ collapsedDepth = -1;
2075
+ }
2076
+ filteredResults.push(result);
2077
+ if (result.type === File && collapsedPaths.includes(result.text)) {
2078
+ collapsedDepth = depth;
2079
+ }
2080
+ }
2081
+ return filteredResults;
2082
+ };
2083
+
2084
+ // TODO optimize this function to return the minimum number
2085
+ // of visible items needed, e.g. when not scrolled 5 items with
2086
+ // 20px fill 100px but when scrolled 6 items are needed
2087
+ const getNumberOfVisibleItems$1 = (listHeight, itemHeight) => {
2088
+ return Math.ceil(listHeight / itemHeight) + 1;
2089
+ };
2090
+
2091
+ const getTreeListItems = results => {
2092
+ const listItems = [];
2093
+ const directories = new Set();
2094
+ let matchDepth = 0;
2095
+ for (const result of results) {
2096
+ if (result.type !== File) {
2097
+ listItems.push({
2098
+ ...result,
2099
+ depth: matchDepth
2100
+ });
2101
+ continue;
2102
+ }
2103
+ const path = result.text.startsWith('./') ? result.text.slice(2) : result.text;
2104
+ const parts = path.split('/');
2105
+ let directory = '';
2106
+ for (let i = 0; i < parts.length - 1; i++) {
2107
+ directory = directory ? `${directory}/${parts[i]}` : parts[i];
2108
+ if (!directories.has(directory)) {
2109
+ directories.add(directory);
2110
+ listItems.push({
2111
+ depth: i,
2112
+ end: 0,
2113
+ isDirectory: true,
2114
+ lineNumber: 0,
2115
+ start: 0,
2116
+ text: directory,
2117
+ type: File
2118
+ });
2119
+ }
2120
+ }
2121
+ matchDepth = parts.length;
2122
+ listItems.push({
2123
+ ...result,
2124
+ depth: matchDepth - 1,
2125
+ text: path
2126
+ });
2127
+ }
2128
+ return listItems;
2129
+ };
2130
+
2131
+ const getScrollBarSize$1 = (size, contentSize, minimumSliderSize) => {
2132
+ if (size >= contentSize) {
2133
+ return 0;
2134
+ }
2135
+ return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
2136
+ };
2137
+ const getScrollBarOffset$1 = (delta, finalDelta, size, scrollBarSize) => {
2138
+ const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
2139
+ return scrollBarOffset;
2140
+ };
2141
+ const getScrollBarY$1 = getScrollBarOffset$1;
2142
+
2102
2143
  const getFilePath = text => {
2103
2144
  // TODO make api stricter so that results always have the same shape
2104
2145
  if (text.startsWith('./')) {
@@ -2107,13 +2148,9 @@ const getFilePath = text => {
2107
2148
  return text;
2108
2149
  };
2109
2150
 
2110
- const File = 1;
2111
- const Match = 2;
2112
- const Context = 3;
2113
-
2114
2151
  const getIconsCached = (dirents, fileIconCache) => {
2115
2152
  return dirents.map(dirent => {
2116
- if (dirent.type !== File) {
2153
+ if (dirent.type !== File || dirent.isDirectory) {
2117
2154
  return '';
2118
2155
  }
2119
2156
  const path = getFilePath(dirent.text);
@@ -2130,7 +2167,7 @@ const getFileName = path => {
2130
2167
  };
2131
2168
 
2132
2169
  const isFile = match => {
2133
- return match.type === File;
2170
+ return match.type === File && !match.isDirectory;
2134
2171
  };
2135
2172
 
2136
2173
  const getMissingDirents = (searchResults, fileIconCache) => {
@@ -2211,60 +2248,72 @@ const getFileIcons = async (items, fileIconCache) => {
2211
2248
  };
2212
2249
  };
2213
2250
 
2214
- const getFilteredResults = (results, collapsedPaths) => {
2215
- if (collapsedPaths.length === 0) {
2216
- return results;
2217
- }
2218
- const filteredResults = [];
2219
- let isExcluded = false;
2220
- for (const result of results) {
2221
- if (result.type === File) {
2222
- filteredResults.push(result);
2223
- isExcluded = collapsedPaths.includes(result.text) ? true : false;
2224
- }
2225
- if ((result.type === Match || result.type === Context) && !isExcluded) {
2226
- filteredResults.push(result);
2227
- }
2251
+ const updateVisibleFileIcons = async (state, fileIconCache) => {
2252
+ const {
2253
+ fileIconCache: currentFileIconCache,
2254
+ listItems,
2255
+ maxLineY,
2256
+ minLineY
2257
+ } = state;
2258
+ const visibleItems = listItems.slice(minLineY, maxLineY);
2259
+ const {
2260
+ icons,
2261
+ newFileIconCache
2262
+ } = await getFileIcons(visibleItems, currentFileIconCache);
2263
+ return {
2264
+ ...state,
2265
+ fileIconCache: newFileIconCache,
2266
+ icons
2267
+ };
2268
+ };
2269
+ const updateVisibleFileIconsWhenRangeChanges = async (oldState, newState) => {
2270
+ if (oldState.listItems === newState.listItems && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY) {
2271
+ return newState;
2228
2272
  }
2229
- return filteredResults;
2273
+ return updateVisibleFileIcons(newState);
2230
2274
  };
2231
2275
 
2232
- // TODO optimize this function to return the minimum number
2233
- // of visible items needed, e.g. when not scrolled 5 items with
2234
- // 20px fill 100px but when scrolled 6 items are needed
2235
- const getNumberOfVisibleItems$1 = (listHeight, itemHeight) => {
2236
- return Math.ceil(listHeight / itemHeight) + 1;
2237
- };
2276
+ const List = 1;
2277
+ const Tree = 2;
2238
2278
 
2239
2279
  const applyCollapsedPaths = async (state, collapsedPaths, listFocusedIndex) => {
2240
2280
  const {
2241
- fileIconCache,
2281
+ deltaY: oldDeltaY,
2242
2282
  headerHeight,
2243
2283
  height,
2244
2284
  itemHeight,
2245
- items
2285
+ items,
2286
+ minimumSliderSize,
2287
+ viewMode
2246
2288
  } = state;
2247
- const filteredResults = getFilteredResults(items, collapsedPaths);
2248
- const {
2249
- icons,
2250
- newFileIconCache
2251
- } = await getFileIcons(filteredResults, fileIconCache);
2289
+ const sourceItems = viewMode === Tree ? getTreeListItems(items) : items;
2290
+ const filteredResults = getFilteredResults(sourceItems, collapsedPaths);
2252
2291
  const total = filteredResults.length;
2253
2292
  const listHeight = height - headerHeight;
2293
+ const contentHeight = total * itemHeight;
2294
+ const finalDeltaY = Math.max(contentHeight - listHeight, 0);
2295
+ const deltaY = clamp$1(oldDeltaY, 0, finalDeltaY);
2296
+ const minLineY = Math.floor(deltaY / itemHeight);
2254
2297
  const numberOfVisible = getNumberOfVisibleItems$1(listHeight, itemHeight);
2255
- const maxLineY = Math.min(numberOfVisible, total);
2256
- return {
2298
+ const maxLineY = Math.min(minLineY + numberOfVisible, total);
2299
+ const scrollBarHeight = getScrollBarSize$1(height, contentHeight, minimumSliderSize);
2300
+ const scrollBarY = finalDeltaY === 0 ? 0 : getScrollBarY$1(deltaY, finalDeltaY, listHeight, scrollBarHeight);
2301
+ const updatedState = {
2257
2302
  ...state,
2258
2303
  collapsedPaths,
2259
- fileIconCache: newFileIconCache,
2304
+ deltaY,
2305
+ finalDeltaY,
2260
2306
  focus: FocusSearchResults,
2261
2307
  focusSource: Script,
2262
- icons,
2263
2308
  listFocused: true,
2264
2309
  listFocusedIndex,
2265
2310
  listItems: filteredResults,
2266
- maxLineY
2311
+ maxLineY,
2312
+ minLineY,
2313
+ scrollBarHeight,
2314
+ scrollBarY
2267
2315
  };
2316
+ return updateVisibleFileIcons(updatedState);
2268
2317
  };
2269
2318
 
2270
2319
  const getPaths = items => {
@@ -2279,12 +2328,13 @@ const getPaths = items => {
2279
2328
  const collapseAll$1 = async state => {
2280
2329
  const {
2281
2330
  items,
2282
- listFocusedIndex
2331
+ listFocusedIndex,
2332
+ listItems
2283
2333
  } = state;
2284
2334
  if (items.length === 0) {
2285
2335
  return state;
2286
2336
  }
2287
- const paths = getPaths(items);
2337
+ const paths = getPaths(listItems);
2288
2338
  return applyCollapsedPaths(state, paths, listFocusedIndex);
2289
2339
  };
2290
2340
 
@@ -2350,13 +2400,6 @@ const getHeaderHeightForFlags = (headerHeight, oldFlags, newFlags) => {
2350
2400
  return newTopHeight + additionalHeight;
2351
2401
  };
2352
2402
 
2353
- const invoke$1 = (method, ...params) => {
2354
- return get$1(TextMeasurementWorker).invoke(method, ...params);
2355
- };
2356
- const set$2 = rpc => {
2357
- set$8(TextMeasurementWorker, rpc);
2358
- };
2359
-
2360
2403
  const SearchMessageFontFamily = 'system-ui';
2361
2404
  const SearchMessageFontSize = 13;
2362
2405
  const SearchMessageLineHeight = 13;
@@ -2368,7 +2411,7 @@ const getSearchMessageHeight = async (message, width, flags) => {
2368
2411
  }
2369
2412
  const horizontalSpace = hasDetailsExpanded(flags) ? SearchMessageExpandedHorizontalSpace : SearchMessageCollapsedHorizontalSpace;
2370
2413
  const availableWidth = Math.max(width - horizontalSpace, 1);
2371
- const textHeight = await invoke$1('TextMeasurement.measureTextBlockHeight', message, SearchMessageFontFamily, SearchMessageFontSize, SearchMessageLineHeight, availableWidth);
2414
+ const textHeight = await invoke$3('TextMeasurement.measureTextBlockHeight', message, SearchMessageFontFamily, SearchMessageFontSize, SearchMessageLineHeight, availableWidth);
2372
2415
  return Math.max(textHeight + VerticalPadding, Minimum);
2373
2416
  };
2374
2417
 
@@ -2392,6 +2435,13 @@ const collapseDetails = async state => {
2392
2435
  };
2393
2436
  };
2394
2437
 
2438
+ const writeText = async text => {
2439
+ await writeText$1(text);
2440
+ };
2441
+ const readText = async () => {
2442
+ return await readText$1();
2443
+ };
2444
+
2395
2445
  const copy$1 = async state => {
2396
2446
  const {
2397
2447
  focusedIndex,
@@ -2401,17 +2451,10 @@ const copy$1 = async state => {
2401
2451
  return state;
2402
2452
  }
2403
2453
  const item = items[focusedIndex];
2404
- await writeClipBoardText(item.text);
2454
+ await writeText(item.text);
2405
2455
  return state;
2406
2456
  };
2407
2457
 
2408
- const writeText = async text => {
2409
- await writeClipBoardText(text);
2410
- };
2411
- const readText = async () => {
2412
- return await invoke$3('ClipBoard.readText');
2413
- };
2414
-
2415
2458
  const getActualIndex$1 = state => {
2416
2459
  const {
2417
2460
  focusedIndex,
@@ -2475,7 +2518,7 @@ const copyPath$1 = async state => {
2475
2518
  return state;
2476
2519
  }
2477
2520
  const item = items[actualIndex];
2478
- await writeClipBoardText(item.text);
2521
+ await writeText(item.text);
2479
2522
  return state;
2480
2523
  };
2481
2524
 
@@ -2490,11 +2533,10 @@ const {
2490
2533
  set: set$1,
2491
2534
  wrapAsyncCommand,
2492
2535
  wrapCommand,
2493
- wrapGetter
2536
+ wrapGetter,
2537
+ wrapSerialCommand
2494
2538
  } = create$2();
2495
2539
 
2496
- const List = 1;
2497
-
2498
2540
  const create$1 = ({
2499
2541
  headerHeight = 0,
2500
2542
  itemHeight,
@@ -2811,18 +2853,6 @@ const removeItemFromItems = (items, index, matchCount, fileCount) => {
2811
2853
  };
2812
2854
  };
2813
2855
 
2814
- const getScrollBarSize$1 = (size, contentSize, minimumSliderSize) => {
2815
- if (size >= contentSize) {
2816
- return 0;
2817
- }
2818
- return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
2819
- };
2820
- const getScrollBarOffset$1 = (delta, finalDelta, size, scrollBarSize) => {
2821
- const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
2822
- return scrollBarOffset;
2823
- };
2824
- const getScrollBarY$1 = getScrollBarOffset$1;
2825
-
2826
2856
  const emptyObject = {};
2827
2857
  const i18nString = (key, placeholders = emptyObject) => {
2828
2858
  if (placeholders === emptyObject) {
@@ -3112,7 +3142,6 @@ const removeIndex = async (state, index) => {
3112
3142
  const {
3113
3143
  deltaY,
3114
3144
  fileCount,
3115
- fileIconCache,
3116
3145
  height,
3117
3146
  itemHeight,
3118
3147
  items,
@@ -3145,19 +3174,12 @@ const removeIndex = async (state, index) => {
3145
3174
  const listHeight = height - headerHeight;
3146
3175
  const scrollBarHeight = getScrollBarSize$1(height, contentHeight, minimumSliderSize);
3147
3176
  const finalDeltaY = Math.max(contentHeight - listHeight, 0);
3148
- const visible = newItems.slice(0, maxLineY);
3149
- const {
3150
- icons,
3151
- newFileIconCache
3152
- } = await getFileIcons(visible, fileIconCache);
3153
- return {
3177
+ const updatedState = {
3154
3178
  ...state,
3155
3179
  deltaY: newDeltaY,
3156
3180
  fileCount: newFileCount,
3157
- fileIconCache: newFileIconCache,
3158
3181
  finalDeltaY,
3159
3182
  headerHeight,
3160
- icons,
3161
3183
  items: newItems,
3162
3184
  listFocusedIndex: newFocusedIndex,
3163
3185
  listItems: newItems,
@@ -3168,6 +3190,7 @@ const removeIndex = async (state, index) => {
3168
3190
  minLineY: newMinLineY,
3169
3191
  scrollBarHeight
3170
3192
  };
3193
+ return updateVisibleFileIcons(updatedState);
3171
3194
  };
3172
3195
 
3173
3196
  const dismissItem = state => {
@@ -3572,7 +3595,7 @@ const getMenuEntriesFile = (state, props) => {
3572
3595
  label: copyAll()
3573
3596
  }, menuEntrySeparator, {
3574
3597
  args: [uri],
3575
- command: 'Search.revealInExplorer',
3598
+ command: 'RevealInExplorer.reveal',
3576
3599
  flags: None$1,
3577
3600
  id: 'revealInExplorerView',
3578
3601
  label: revealInExplorerView()
@@ -3598,7 +3621,7 @@ const getMenuEntriesMatch = (state, props) => {
3598
3621
  label: copyAll()
3599
3622
  }, menuEntrySeparator, {
3600
3623
  args: [uri],
3601
- command: 'Search.revealInExplorer',
3624
+ command: 'RevealInExplorer.reveal',
3602
3625
  flags: None$1,
3603
3626
  id: 'revealInExplorerView',
3604
3627
  label: revealInExplorerView()
@@ -3677,7 +3700,7 @@ const openSearchEditor = async state => {
3677
3700
 
3678
3701
  const getSearchExcludes = async (fallback = []) => {
3679
3702
  try {
3680
- const value = await invoke$3('Preferences.get', 'search.exclude');
3703
+ const value = await invoke$2('Preferences.get', 'search.exclude');
3681
3704
  if (Array.isArray(value)) {
3682
3705
  return value.filter(item => typeof item === 'string');
3683
3706
  }
@@ -3768,7 +3791,7 @@ const getSearchHeaderHeight = (flags, messageHeight, warningHeight) => {
3768
3791
  };
3769
3792
 
3770
3793
  const measureTextHeight = (text, fontFamily, fontSize, lineHeight, width) => {
3771
- return invoke$3('MeasureTextHeight.measureTextBlockHeight', text, fontFamily, fontSize, `${lineHeight}px`, width);
3794
+ return invoke$2('MeasureTextHeight.measureTextBlockHeight', text, fontFamily, fontSize, `${lineHeight}px`, width);
3772
3795
  };
3773
3796
 
3774
3797
  const SearchWarningFontFamily = 'system-ui';
@@ -3808,7 +3831,7 @@ const textSearch = async (root, query, options, assetDir, platform, searchId, ui
3808
3831
  if (!hasOpenEditors(options.flags)) {
3809
3832
  return search$1(root, query, options, assetDir, platform, searchId, uid);
3810
3833
  }
3811
- const openEditorUris = await invoke$3('GetActiveEditor.getOpenEditorUris');
3834
+ const openEditorUris = await invoke$2('GetActiveEditor.getOpenEditorUris');
3812
3835
  return search$1(root, query, {
3813
3836
  ...options,
3814
3837
  openEditorUris
@@ -3846,7 +3869,13 @@ const handleUpdateFull = async (state, update) => {
3846
3869
  const scheme = getProtocol(root);
3847
3870
  const isFileSearch = scheme === '' || scheme === 'file';
3848
3871
  const shouldUsePullBasedSearch = usePullBasedSearch && isFileSearch;
3849
- const searchId = shouldUsePullBasedSearch ? crypto.randomUUID() : '';
3872
+ const searchId = crypto.randomUUID();
3873
+ const current = get(uid);
3874
+ const oldState = current ? current.oldState : state;
3875
+ set$1(uid, oldState, {
3876
+ ...partialNewState,
3877
+ searchId
3878
+ });
3850
3879
  const {
3851
3880
  limitHit,
3852
3881
  results
@@ -3868,6 +3897,10 @@ const handleUpdateFull = async (state, update) => {
3868
3897
  usePullBasedSearch: shouldUsePullBasedSearch,
3869
3898
  useRegularExpression: Boolean(flags & UseRegularExpression$2)
3870
3899
  }, assetDir, platform, searchId, uid);
3900
+ const latestAfterSearch = get(uid);
3901
+ if (latestAfterSearch.newState.searchId !== searchId) {
3902
+ return state;
3903
+ }
3871
3904
  if (!Array.isArray(results)) {
3872
3905
  throw new TypeError('results must be of type array');
3873
3906
  }
@@ -3891,8 +3924,12 @@ const handleUpdateFull = async (state, update) => {
3891
3924
  icons,
3892
3925
  newFileIconCache
3893
3926
  } = await getFileIcons(visible, fileIconCache);
3894
- return {
3895
- ...partialNewState,
3927
+ const latest = get(uid);
3928
+ if (latest.newState.searchId !== searchId) {
3929
+ return state;
3930
+ }
3931
+ const updatedState = {
3932
+ ...latest.newState,
3896
3933
  collapsedPaths: [],
3897
3934
  deltaY: 0,
3898
3935
  fileCount,
@@ -3916,6 +3953,8 @@ const handleUpdateFull = async (state, update) => {
3916
3953
  threads,
3917
3954
  value
3918
3955
  };
3956
+ set$1(uid, latest.oldState, updatedState);
3957
+ return state;
3919
3958
  };
3920
3959
 
3921
3960
  const waitForNextFrame = async () => {
@@ -3955,8 +3994,7 @@ const textSearchIncremental = async (root, query, options, assetDir, platform, s
3955
3994
  minLineY: 0
3956
3995
  };
3957
3996
  set$1(uid, latest2.oldState, updatedState2);
3958
- // @ts-ignore
3959
- await invoke$3('Search.rerender');
3997
+ await invoke$2('Viewlet.requestRender', uid);
3960
3998
  await waitForNextFrame();
3961
3999
  }
3962
4000
  await resultPromise;
@@ -4079,6 +4117,9 @@ const handleUpdatePullBased = async (state, update) => {
4079
4117
  if (!latest) {
4080
4118
  return state;
4081
4119
  }
4120
+ if (latest.newState.searchId !== searchId) {
4121
+ return state;
4122
+ }
4082
4123
  const limitHitWarning = limitHit ? theResultSetOnlyContainsASubSetOfMatches() : '';
4083
4124
  const {
4084
4125
  fileCount,
@@ -4086,15 +4127,21 @@ const handleUpdatePullBased = async (state, update) => {
4086
4127
  } = getTextSearchResultCounts(latest.newState.items);
4087
4128
  const message = getStatusMessage(resultCount, fileCount);
4088
4129
  const [messageHeight, warningHeight] = await Promise.all([getSearchMessageHeight(message, width, flags), getSearchWarningMessageHeight(limitHitWarning, width)]);
4130
+ const current = get(uid);
4131
+ if (current.newState.searchId !== searchId) {
4132
+ return state;
4133
+ }
4089
4134
  const headerHeight = getSearchHeaderHeight(flags, messageHeight, warningHeight);
4090
- return {
4091
- ...latest.newState,
4135
+ const updatedState = {
4136
+ ...current.newState,
4092
4137
  headerHeight,
4093
4138
  limitHit,
4094
4139
  limitHitWarning,
4095
4140
  message,
4096
4141
  messageHeight
4097
4142
  };
4143
+ set$1(uid, current.oldState, updatedState);
4144
+ return state;
4098
4145
  };
4099
4146
 
4100
4147
  const handleUpdateValidationError = (state, update, searchInputErrorMessage) => {
@@ -4150,7 +4197,12 @@ const handleUpdate = async (state, update) => {
4150
4197
  workspacePath
4151
4198
  } = partialNewState;
4152
4199
  if (isEmptyString(value) || isEmptyString(workspacePath)) {
4153
- return handleUpdateEmpty(state, update);
4200
+ const newState = handleUpdateEmpty(state, update);
4201
+ const current = get(newState.uid);
4202
+ if (current) {
4203
+ set$1(newState.uid, current.oldState, newState);
4204
+ }
4205
+ return newState;
4154
4206
  }
4155
4207
  const searchInputErrorMessage = validateSearchInput(value, flags);
4156
4208
  if (searchInputErrorMessage) {
@@ -4180,7 +4232,36 @@ const refresh = async state => {
4180
4232
  };
4181
4233
 
4182
4234
  const viewAsTree = async state => {
4183
- return state;
4235
+ const {
4236
+ headerHeight,
4237
+ height,
4238
+ itemHeight,
4239
+ items,
4240
+ minimumSliderSize
4241
+ } = state;
4242
+ if (items.length === 0) {
4243
+ return state;
4244
+ }
4245
+ const listItems = getTreeListItems(items);
4246
+ const total = listItems.length;
4247
+ const contentHeight = total * itemHeight;
4248
+ const listHeight = height - headerHeight;
4249
+ const finalDeltaY = Math.max(contentHeight - listHeight, 0);
4250
+ const numberOfVisible = getNumberOfVisibleItems$1(listHeight, itemHeight);
4251
+ const maxLineY = Math.min(numberOfVisible, total);
4252
+ const scrollBarHeight = getScrollBarSize$1(height, contentHeight, minimumSliderSize);
4253
+ const updatedState = {
4254
+ ...state,
4255
+ collapsedPaths: [],
4256
+ deltaY: 0,
4257
+ finalDeltaY,
4258
+ listItems,
4259
+ maxLineY,
4260
+ minLineY: 0,
4261
+ scrollBarHeight,
4262
+ viewMode: Tree
4263
+ };
4264
+ return updateVisibleFileIcons(updatedState);
4184
4265
  };
4185
4266
 
4186
4267
  const handleActionClick = async (state, name) => {
@@ -4212,7 +4293,7 @@ const noop = state => {
4212
4293
  };
4213
4294
 
4214
4295
  const applyBulkReplacement = async bulkEdits => {
4215
- await invoke$3('BulkReplacement.applyBulkReplacement', bulkEdits);
4296
+ await invoke$2('BulkReplacement.applyBulkReplacement', bulkEdits);
4216
4297
  };
4217
4298
 
4218
4299
  const getReplacedMessage = (fileCount, replaceCount, replacement) => {
@@ -4279,17 +4360,9 @@ const getReplacingMessage = (fileCount, replaceCount) => {
4279
4360
  return replacingManyOccurrencesInManyFiles(replaceCount, fileCount);
4280
4361
  };
4281
4362
 
4282
- const missingDialogWorkerRelay = 'Command "SendMessagePortToExtensionHostWorker.sendMessagePortToDialogWorker" not found';
4283
- const prompt = async (text, options) => {
4284
- try {
4285
- return await invoke$6('ConfirmPrompt.prompt', text, options);
4286
- } catch (error) {
4287
- if (!String(error).includes(missingDialogWorkerRelay)) {
4288
- throw error;
4289
- }
4290
- return invoke$3('ConfirmPrompt.prompt', text, options);
4291
- }
4292
- };
4363
+ const {
4364
+ prompt
4365
+ } = DialogWorker;
4293
4366
 
4294
4367
  const getReplaceAllConfirmText = (matchCount, fileCount, replacement) => {
4295
4368
  if (matchCount === 1) {
@@ -4362,7 +4435,6 @@ const replaceAllInFocusedFile = async (state, fileIndex) => {
4362
4435
  const {
4363
4436
  deltaY,
4364
4437
  fileCount,
4365
- fileIconCache,
4366
4438
  height,
4367
4439
  itemHeight,
4368
4440
  items,
@@ -4402,19 +4474,12 @@ const replaceAllInFocusedFile = async (state, fileIndex) => {
4402
4474
  const listHeight = height - headerHeight;
4403
4475
  const scrollBarHeight = getScrollBarSize$1(height, contentHeight, minimumSliderSize);
4404
4476
  const finalDeltaY = Math.max(contentHeight - listHeight, 0);
4405
- const visible = newItems.slice(0, newMaxLineY);
4406
- const {
4407
- icons,
4408
- newFileIconCache
4409
- } = await getFileIcons(visible, fileIconCache);
4410
- return {
4477
+ const updatedState = {
4411
4478
  ...state,
4412
4479
  deltaY: newDeltaY,
4413
4480
  fileCount: newFileCount,
4414
- fileIconCache: newFileIconCache,
4415
4481
  finalDeltaY,
4416
4482
  headerHeight,
4417
- icons,
4418
4483
  items: newItems,
4419
4484
  listFocusedIndex: newFocusedIndex,
4420
4485
  listItems: newItems,
@@ -4423,8 +4488,10 @@ const replaceAllInFocusedFile = async (state, fileIndex) => {
4423
4488
  message,
4424
4489
  messageHeight,
4425
4490
  minLineY: newMinLineY,
4426
- scrollBarHeight
4491
+ scrollBarHeight,
4492
+ searchId: ''
4427
4493
  };
4494
+ return updateVisibleFileIcons(updatedState);
4428
4495
  };
4429
4496
  const confirmReplaceAll = async (state, fileIndex) => {
4430
4497
  const {
@@ -4452,9 +4519,11 @@ const replaceAllConfirmed = async (state, fileIndex) => {
4452
4519
  workspacePath
4453
4520
  } = state;
4454
4521
  const bulkEdits = getReplaceElements(items, workspacePath, replacement);
4455
- // TODO this function should return an error message if an error occurred during bulk edit
4456
- await applyBulkReplacement(bulkEdits);
4457
- await handleWorkspaceRefresh();
4522
+ if (bulkEdits.length > 0) {
4523
+ // TODO this function should return an error message if an error occurred during bulk edit
4524
+ await applyBulkReplacement(bulkEdits);
4525
+ await handleWorkspaceRefresh();
4526
+ }
4458
4527
  const fileCount = bulkEdits.length;
4459
4528
  const message = getReplacedMessage(fileCount, matchCount, replacement);
4460
4529
  const {
@@ -4469,7 +4538,8 @@ const replaceAllConfirmed = async (state, fileIndex) => {
4469
4538
  maxLineY: 0,
4470
4539
  message,
4471
4540
  messageHeight,
4472
- minLineY: 0
4541
+ minLineY: 0,
4542
+ searchId: ''
4473
4543
  };
4474
4544
  };
4475
4545
  const replaceAll = async state => {
@@ -4485,7 +4555,9 @@ const replaceAllWithProgress = async context => {
4485
4555
  const state = context.getState();
4486
4556
  const {
4487
4557
  fileCount: totalFileCount,
4488
- matchCount: totalMatchCount
4558
+ matchCount: totalMatchCount,
4559
+ searchId: activeSearchId,
4560
+ uid
4489
4561
  } = state;
4490
4562
  const actualIndex = getActualIndex(state);
4491
4563
  const fileIndex = getFileIndex(state, actualIndex);
@@ -4495,16 +4567,49 @@ const replaceAllWithProgress = async context => {
4495
4567
  if (!shouldReplace) {
4496
4568
  return;
4497
4569
  }
4498
- const message = getReplacingMessage(fileCount, matchCount);
4499
- const messageLayout = await getSearchMessageLayout(state, message);
4570
+ if (context.getState().searchId !== activeSearchId) {
4571
+ return;
4572
+ }
4573
+ const replacementSearchId = crypto.randomUUID();
4574
+ let progressUpdate = {};
4575
+ if (matchCount > 0) {
4576
+ const message = getReplacingMessage(fileCount, matchCount);
4577
+ const messageLayout = await getSearchMessageLayout(state, message);
4578
+ progressUpdate = {
4579
+ ...messageLayout,
4580
+ message
4581
+ };
4582
+ }
4500
4583
  await context.updateState(latestState => ({
4501
4584
  ...latestState,
4502
- ...messageLayout,
4503
- message
4585
+ ...progressUpdate,
4586
+ searchId: replacementSearchId
4504
4587
  }));
4505
- await invoke$3('Search.rerender');
4506
- const updatedState = await replaceAllConfirmed(context.getState(), fileIndex);
4507
- await context.updateState(() => updatedState);
4588
+ if (matchCount > 0) {
4589
+ await invoke$2('Viewlet.requestRender', uid);
4590
+ }
4591
+ const currentBeforeReplacement = get(uid);
4592
+ let replacementState = context.getState();
4593
+ if (currentBeforeReplacement && currentBeforeReplacement.newState.searchId !== replacementSearchId) {
4594
+ if (currentBeforeReplacement.newState.searchId !== activeSearchId) {
4595
+ return;
4596
+ }
4597
+ replacementState = {
4598
+ ...currentBeforeReplacement.newState,
4599
+ ...progressUpdate,
4600
+ searchId: replacementSearchId
4601
+ };
4602
+ }
4603
+ const generationState = {
4604
+ ...replacementState
4605
+ };
4606
+ set$1(uid, generationState, generationState);
4607
+ const updatedState = await replaceAllConfirmed(generationState, fileIndex);
4608
+ const completedGenerationState = {
4609
+ ...updatedState
4610
+ };
4611
+ set$1(uid, completedGenerationState, completedGenerationState);
4612
+ set$1(uid, generationState, updatedState);
4508
4613
  };
4509
4614
 
4510
4615
  const toggleContextLines = async state => {
@@ -4656,21 +4761,11 @@ const handleHeaderFocusOut = state => {
4656
4761
  };
4657
4762
 
4658
4763
  const handleIconThemeChange = async state => {
4659
- const {
4660
- items,
4661
- maxLineY,
4662
- minLineY
4663
- } = state;
4664
- const visibleItems = items.slice(minLineY, maxLineY);
4665
- const {
4666
- icons,
4667
- newFileIconCache
4668
- } = await getFileIcons(visibleItems, {});
4669
- return {
4764
+ const stateWithEmptyIconCache = {
4670
4765
  ...state,
4671
- fileIconCache: newFileIconCache,
4672
- icons
4766
+ fileIconCache: {}
4673
4767
  };
4768
+ return updateVisibleFileIcons(stateWithEmptyIconCache);
4674
4769
  };
4675
4770
 
4676
4771
  const handleIncludeInput = (state, includeValue, inputSource = Script) => {
@@ -4795,6 +4890,7 @@ const getNewSelections = (selections, name, newValue) => {
4795
4890
  }
4796
4891
  };
4797
4892
  };
4893
+
4798
4894
  const updateValue = (state, name, newValue) => {
4799
4895
  const {
4800
4896
  selections
@@ -5025,7 +5121,7 @@ const handleMessagePort = async (port, viewletCommandMap, setAsRendererProcess =
5025
5121
  throw new TypeError(`Viewlet command not found: ${command}`);
5026
5122
  }
5027
5123
  await fn(uid, ...args);
5028
- await invoke$3('Viewlet.requestRender', uid);
5124
+ await invoke$2('Viewlet.requestRender', uid);
5029
5125
  };
5030
5126
  const rpc = await create$7({
5031
5127
  commandMap: {
@@ -5039,7 +5135,7 @@ const handleMessagePort = async (port, viewletCommandMap, setAsRendererProcess =
5039
5135
  };
5040
5136
 
5041
5137
  const openFolder = async () => {
5042
- await invoke$3('Dialog.openFolder');
5138
+ await invoke$2('Dialog.openFolder');
5043
5139
  };
5044
5140
 
5045
5141
  const handleOpenFolderClick = async state => {
@@ -5049,17 +5145,19 @@ const handleOpenFolderClick = async state => {
5049
5145
 
5050
5146
  const handlePullResultsFound = async (state, resultSearchId, newResults) => {
5051
5147
  const {
5052
- fileIconCache,
5053
- height,
5054
- itemHeight,
5055
- listItems,
5056
- minimumSliderSize,
5057
- searchId,
5058
5148
  uid
5059
5149
  } = state;
5060
- if (searchId !== resultSearchId) {
5150
+ const current = get(uid);
5151
+ if (!current || current.newState.searchId !== resultSearchId) {
5061
5152
  return state;
5062
5153
  }
5154
+ const {
5155
+ fileIconCache,
5156
+ height,
5157
+ itemHeight,
5158
+ listItems,
5159
+ minimumSliderSize
5160
+ } = current.newState;
5063
5161
  const allResults = [...listItems, ...newResults];
5064
5162
  const {
5065
5163
  fileCount,
@@ -5069,7 +5167,7 @@ const handlePullResultsFound = async (state, resultSearchId, newResults) => {
5069
5167
  const {
5070
5168
  headerHeight,
5071
5169
  messageHeight
5072
- } = await getSearchMessageLayout(state, message);
5170
+ } = await getSearchMessageLayout(current.newState, message);
5073
5171
  const total = allResults.length;
5074
5172
  const contentHeight = total * itemHeight;
5075
5173
  const listHeight = height - headerHeight;
@@ -5083,6 +5181,9 @@ const handlePullResultsFound = async (state, resultSearchId, newResults) => {
5083
5181
  newFileIconCache
5084
5182
  } = await getFileIcons(visible, fileIconCache);
5085
5183
  const latest = get(uid);
5184
+ if (!latest || latest.newState.searchId !== resultSearchId) {
5185
+ return state;
5186
+ }
5086
5187
  const updatedState = {
5087
5188
  ...latest.newState,
5088
5189
  fileCount,
@@ -5100,16 +5201,11 @@ const handlePullResultsFound = async (state, resultSearchId, newResults) => {
5100
5201
  minLineY: 0,
5101
5202
  scrollBarHeight
5102
5203
  };
5103
- const oldState = latest ? latest.oldState : state;
5104
- set$1(uid, oldState, updatedState);
5105
- await invoke$3('Search.rerender');
5204
+ set$1(uid, latest.oldState, updatedState);
5205
+ await invoke$2('Viewlet.requestRender', uid);
5106
5206
  return state;
5107
5207
  };
5108
5208
 
5109
- const clamp$1 = (num, min, max) => {
5110
- return Math.min(Math.max(num, min), max);
5111
- };
5112
-
5113
5209
  const handleResize = async (state, x, y, width, height) => {
5114
5210
  const {
5115
5211
  deltaY,
@@ -5265,7 +5361,7 @@ const focusIndexScrollUp = (state, index, listHeight, itemHeight, itemsLength) =
5265
5361
  scrollBarY
5266
5362
  };
5267
5363
  };
5268
- const focusIndex = (state, index) => {
5364
+ const focusIndex$1 = (state, index) => {
5269
5365
  const {
5270
5366
  headerHeight,
5271
5367
  height,
@@ -5313,24 +5409,24 @@ const next = (items, index) => {
5313
5409
  const previous = (items, index) => {
5314
5410
  return (index === 0 ? items.length : index) - 1;
5315
5411
  };
5316
- const focusFirst = state => {
5412
+ const focusFirst$1 = state => {
5317
5413
  const firstIndex = first();
5318
- return focusIndex(state, firstIndex);
5414
+ return focusIndex$1(state, firstIndex);
5319
5415
  };
5320
- const focusLast = state => {
5416
+ const focusLast$1 = state => {
5321
5417
  const {
5322
5418
  items
5323
5419
  } = state;
5324
5420
  const lastIndex = last(items);
5325
- return focusIndex(state, lastIndex);
5421
+ return focusIndex$1(state, lastIndex);
5326
5422
  };
5327
- const focusNext = state => {
5423
+ const focusNext$1 = state => {
5328
5424
  const {
5329
5425
  focusedIndex,
5330
5426
  items
5331
5427
  } = state;
5332
5428
  const nextIndex = next(items, focusedIndex);
5333
- return focusIndex(state, nextIndex);
5429
+ return focusIndex$1(state, nextIndex);
5334
5430
  };
5335
5431
 
5336
5432
  // based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
@@ -5341,7 +5437,7 @@ const isLastIndex = (array, index) => {
5341
5437
  const lastIndex = array => {
5342
5438
  return array.length - 1;
5343
5439
  };
5344
- const focusNextPage = state => {
5440
+ const focusNextPage$1 = state => {
5345
5441
  const {
5346
5442
  focusedIndex,
5347
5443
  items,
@@ -5352,9 +5448,9 @@ const focusNextPage = state => {
5352
5448
  return state;
5353
5449
  }
5354
5450
  const indexNextPage = Math.min(maxLineY + (maxLineY - minLineY) - 2, lastIndex(items));
5355
- return focusIndex(state, indexNextPage);
5451
+ return focusIndex$1(state, indexNextPage);
5356
5452
  };
5357
- const focusPrevious = state => {
5453
+ const focusPrevious$1 = state => {
5358
5454
  const {
5359
5455
  focusedIndex,
5360
5456
  items
@@ -5363,9 +5459,9 @@ const focusPrevious = state => {
5363
5459
  return state;
5364
5460
  }
5365
5461
  const previousIndex = previous(items, focusedIndex);
5366
- return focusIndex(state, previousIndex);
5462
+ return focusIndex$1(state, previousIndex);
5367
5463
  };
5368
- const focusPreviousPage = state => {
5464
+ const focusPreviousPage$1 = state => {
5369
5465
  const {
5370
5466
  focusedIndex,
5371
5467
  maxLineY,
@@ -5375,7 +5471,7 @@ const focusPreviousPage = state => {
5375
5471
  return state;
5376
5472
  }
5377
5473
  const indexPreviousPage = Math.max(minLineY - (maxLineY - minLineY) + 1, 0);
5378
- return focusIndex(state, indexPreviousPage);
5474
+ return focusIndex$1(state, indexPreviousPage);
5379
5475
  };
5380
5476
  const handleScrollBarCaptureLost = state => {
5381
5477
  return {
@@ -5426,7 +5522,7 @@ const setDeltaY = (state, value) => {
5426
5522
  scrollBarY
5427
5523
  };
5428
5524
  };
5429
- const handleScrollBarClick = (state, eventY) => {
5525
+ const handleScrollBarClick$1 = (state, eventY) => {
5430
5526
  const {
5431
5527
  deltaY,
5432
5528
  finalDeltaY,
@@ -5465,7 +5561,7 @@ const getNewPercent = (contentHeight, scrollBarHeight, relativeY) => {
5465
5561
  // clicked at bottom
5466
5562
  return 1;
5467
5563
  };
5468
- const handleScrollBarMove = (state, eventY) => {
5564
+ const handleScrollBarMove$1 = (state, eventY) => {
5469
5565
  const {
5470
5566
  finalDeltaY,
5471
5567
  handleOffset,
@@ -5486,6 +5582,54 @@ const handleWheel$1 = (state, deltaMode, deltaY) => {
5486
5582
  return setDeltaY(state, state.deltaY + deltaY);
5487
5583
  };
5488
5584
 
5585
+ const applyListOperation = async (state, operation) => {
5586
+ const {
5587
+ items,
5588
+ listItems
5589
+ } = state;
5590
+ const listState = {
5591
+ ...state,
5592
+ items: listItems
5593
+ };
5594
+ const updatedListState = operation(listState);
5595
+ if (updatedListState === listState) {
5596
+ return state;
5597
+ }
5598
+ const updatedState = {
5599
+ ...updatedListState,
5600
+ items
5601
+ };
5602
+ return updateVisibleFileIconsWhenRangeChanges(state, updatedState);
5603
+ };
5604
+
5605
+ const focusFirst = async state => {
5606
+ return applyListOperation(state, focusFirst$1);
5607
+ };
5608
+
5609
+ const focusIndex = async (state, index) => {
5610
+ return applyListOperation(state, listState => focusIndex$1(listState, index));
5611
+ };
5612
+
5613
+ const focusLast = async state => {
5614
+ return applyListOperation(state, focusLast$1);
5615
+ };
5616
+
5617
+ const focusNext = async state => {
5618
+ return applyListOperation(state, focusNext$1);
5619
+ };
5620
+
5621
+ const focusNextPage = async state => {
5622
+ return applyListOperation(state, focusNextPage$1);
5623
+ };
5624
+
5625
+ const focusPrevious = async state => {
5626
+ return applyListOperation(state, focusPrevious$1);
5627
+ };
5628
+
5629
+ const focusPreviousPage = async state => {
5630
+ return applyListOperation(state, focusPreviousPage$1);
5631
+ };
5632
+
5489
5633
  const getListIndex = (eventX, eventY, x, y, deltaY, itemHeight, topHeight, itemCount) => {
5490
5634
  const relativeY = eventY - y - topHeight + deltaY;
5491
5635
  const index = Math.floor(relativeY / itemHeight);
@@ -5532,8 +5676,10 @@ const selectIndexPreview = async (state, searchResult, index) => {
5532
5676
  const fileResult = listItems[fileIndex];
5533
5677
  const relativePath = getRelativePath(fileResult.text);
5534
5678
  const absolutePath = `${workspacePath}${relativePath}`;
5535
- await openUri(absolutePath, true, {
5536
- selections: new Uint32Array([rowIndex, startColumnIndex, rowIndex, endColumnIndex])
5679
+ await openUri2({
5680
+ focus: true,
5681
+ selections: new Uint32Array([rowIndex, startColumnIndex, rowIndex, endColumnIndex]),
5682
+ uri: absolutePath
5537
5683
  });
5538
5684
  return {
5539
5685
  ...state,
@@ -5603,31 +5749,16 @@ const handleListPointerDown = async (state, button, name) => {
5603
5749
  };
5604
5750
  };
5605
5751
 
5752
+ const handleScrollBarClick = async (state, eventY) => {
5753
+ return applyListOperation(state, listState => handleScrollBarClick$1(listState, eventY));
5754
+ };
5755
+
5756
+ const handleScrollBarMove = async (state, eventY) => {
5757
+ return applyListOperation(state, listState => handleScrollBarMove$1(listState, eventY));
5758
+ };
5759
+
5606
5760
  const handleWheel = async (state, deltaMode, deltaY) => {
5607
- const {
5608
- maxLineY: oldMaxLineY,
5609
- minLineY: oldMinLineY
5610
- } = state;
5611
- const newState = handleWheel$1(state, deltaMode, deltaY);
5612
- if (newState.minLineY === oldMinLineY && newState.maxLineY === oldMaxLineY) {
5613
- return newState;
5614
- }
5615
- const {
5616
- fileIconCache,
5617
- listItems,
5618
- maxLineY,
5619
- minLineY
5620
- } = newState;
5621
- const visibleItems = listItems.slice(minLineY, maxLineY);
5622
- const {
5623
- icons,
5624
- newFileIconCache
5625
- } = await getFileIcons(visibleItems, fileIconCache);
5626
- return {
5627
- ...newState,
5628
- fileIconCache: newFileIconCache,
5629
- icons
5630
- };
5761
+ return applyListOperation(state, listState => handleWheel$1(listState, deltaMode, deltaY));
5631
5762
  };
5632
5763
 
5633
5764
  const getUsePullBasedSearch = async () => {
@@ -5863,24 +5994,32 @@ const getTreeItemIndent = depth => {
5863
5994
  return baseIndent + depth * defaultIndent;
5864
5995
  };
5865
5996
 
5866
- const getSearchDisplayResultFile = (results, fileIcons, i, setSize, collapsedPaths, text, posInSet, relativeIndex, focused, renderFolderPaths, originalResults) => {
5997
+ const normalizeRelativePath = path => {
5998
+ if (path.startsWith('./')) {
5999
+ return path.slice(2);
6000
+ }
6001
+ return path;
6002
+ };
6003
+
6004
+ const getSearchDisplayResultFile = (results, fileIcons, i, setSize, collapsedPaths, text, posInSet, relativeIndex, focused, renderFolderPaths, originalResults, resultDepth, isDirectory) => {
5867
6005
  const path = text;
5868
6006
  const absolutePath = getRelativePath(path);
5869
6007
  const baseName = pathBaseName(path);
5870
6008
  const relativeFolderPath = getRelativeFolderPath(path);
5871
- const displayText = renderFolderPaths && relativeFolderPath ? `${baseName} — ${relativeFolderPath}` : baseName;
5872
- const index = originalResults.indexOf(results[i]);
5873
- const matchCount = getMatchCount(originalResults, index);
6009
+ const displayText = renderFolderPaths && relativeFolderPath && !isDirectory ? `${baseName} — ${relativeFolderPath}` : baseName;
6010
+ const normalizedPath = normalizeRelativePath(path);
6011
+ const index = originalResults.findIndex(result => result.type === results[i].type && normalizeRelativePath(result.text) === normalizedPath);
6012
+ const matchCount = isDirectory ? 0 : getMatchCount(originalResults, index);
5874
6013
  const expanded = collapsedPaths.includes(path) ? Collapsed : Expanded;
5875
- const badgeText = String(matchCount);
5876
- const depth = 0;
6014
+ const badgeText = isDirectory ? '' : String(matchCount);
6015
+ const depth = resultDepth ?? 0;
5877
6016
  const indent = getTreeItemIndent(depth);
5878
6017
  return {
5879
6018
  badgeText,
5880
6019
  depth,
5881
6020
  expanded,
5882
6021
  focused,
5883
- icon: fileIcons[relativeIndex],
6022
+ icon: isDirectory ? '' : fileIcons[relativeIndex],
5884
6023
  indent,
5885
6024
  matchLength: 0,
5886
6025
  matchStart: 0,
@@ -5892,8 +6031,8 @@ const getSearchDisplayResultFile = (results, fileIcons, i, setSize, collapsedPat
5892
6031
  };
5893
6032
  };
5894
6033
 
5895
- const getDisplayResultMatch = (setSize, searchTermLength, replacement, text, posInSet, start, focused) => {
5896
- const depth = 1;
6034
+ const getDisplayResultMatch = (setSize, searchTermLength, replacement, text, posInSet, start, focused, resultDepth = 1) => {
6035
+ const depth = resultDepth;
5897
6036
  const indent = getTreeItemIndent(depth);
5898
6037
  return {
5899
6038
  badgeText: '',
@@ -5915,6 +6054,8 @@ const getDisplayResultMatch = (setSize, searchTermLength, replacement, text, pos
5915
6054
  const getDisplayResult = (results, fileIcons, i, setSize, searchTermLength, replacement, focusedIndex, collapsedPaths, renderFolderPaths, minLineY, originalResults) => {
5916
6055
  const result = results[i];
5917
6056
  const {
6057
+ depth,
6058
+ isDirectory,
5918
6059
  start,
5919
6060
  text,
5920
6061
  type
@@ -5924,11 +6065,11 @@ const getDisplayResult = (results, fileIcons, i, setSize, searchTermLength, repl
5924
6065
  const relativeIndex = i - minLineY;
5925
6066
  switch (type) {
5926
6067
  case Context:
5927
- return getDisplayResultMatch(setSize, 0, '', text, posInSet, 0, focused);
6068
+ return getDisplayResultMatch(setSize, 0, '', text, posInSet, 0, focused, depth);
5928
6069
  case File:
5929
- return getSearchDisplayResultFile(results, fileIcons, i, setSize, collapsedPaths, text, posInSet, relativeIndex, focused, renderFolderPaths, originalResults);
6070
+ return getSearchDisplayResultFile(results, fileIcons, i, setSize, collapsedPaths, text, posInSet, relativeIndex, focused, renderFolderPaths, originalResults, depth, isDirectory);
5930
6071
  case Match:
5931
- return getDisplayResultMatch(setSize, searchTermLength, replacement, text, posInSet, start, focused);
6072
+ return getDisplayResultMatch(setSize, searchTermLength, replacement, text, posInSet, start, focused, depth);
5932
6073
  default:
5933
6074
  throw new Error('unexpected search result type');
5934
6075
  }
@@ -6698,7 +6839,7 @@ const highlighted = {
6698
6839
  };
6699
6840
  const label1 = {
6700
6841
  childCount: 1,
6701
- className: mergeClassNames(Label$1, Grow),
6842
+ className: mergeClassNames(Label, Grow),
6702
6843
  type: Div
6703
6844
  };
6704
6845
  const label3 = {
@@ -6816,10 +6957,10 @@ const getSearchResultsVirtualDom = (visibleItems, focusOutline, scrollbarHeight,
6816
6957
  const childCount = scrollbarHeight === 0 ? 1 : 2;
6817
6958
  return [{
6818
6959
  childCount,
6819
- className: mergeClassNames(Viewlet, List$1, Tree, focusOutline ? FocusOutline : Empty$1),
6960
+ className: mergeClassNames(Viewlet, List$1, Tree$1, focusOutline ? FocusOutline : Empty$1),
6820
6961
  onBlur: HandleListBlur,
6821
6962
  onFocus: HandleListFocus,
6822
- role: Tree$1,
6963
+ role: Tree$2,
6823
6964
  tabIndex: Focusable,
6824
6965
  type: Div
6825
6966
  // TODO renable this when dom diffing is supported
@@ -6827,7 +6968,7 @@ const getSearchResultsVirtualDom = (visibleItems, focusOutline, scrollbarHeight,
6827
6968
  }, ...getTreeItemsVirtualDom(visibleItems, deltaY, itemHeight), ...getScrollBarVirtualDom(scrollbarHeight, scrollBarY, scrollBarValue)];
6828
6969
  };
6829
6970
 
6830
- const className = mergeClassNames(Viewlet, Search$3);
6971
+ const className = mergeClassNames(Viewlet, Search$2);
6831
6972
  const getSearchVirtualDom = (visibleItems, flags, message, focusOutline, searchInputErrorMessage, scrollBarHeight, scrollBarY, scrollBarValue, deltaY, itemHeight, matchCount, limitHitWarning, focus = 0, initial = false, isSearchEditor = false, contextLines = 1, contextLinesEnabled = false, workspacePath) => {
6832
6973
  if (initial) {
6833
6974
  return [];
@@ -6850,8 +6991,11 @@ const getDom = newState => {
6850
6991
 
6851
6992
  // TODO cache rendered dom so that it can be used for dom diffing
6852
6993
  const renderIncremental = (oldState, newState) => {
6853
- const oldDom = getDom(oldState);
6854
6994
  const newDom = getDom(newState);
6995
+ if (oldState.replacement !== newState.replacement) {
6996
+ return [SetDom2, newState.uid, newDom];
6997
+ }
6998
+ const oldDom = getDom(oldState);
6855
6999
  const patches = diffTree(oldDom, newDom);
6856
7000
  return [SetPatches, newState.uid, patches];
6857
7001
  };
@@ -6913,6 +7057,9 @@ const applyRender = (oldState, newState, diffResult) => {
6913
7057
  const renderDirect = async (uid, commands) => {
6914
7058
  const rendererWorkerCommands = commands.filter(command => command[0] === SetFocusContext);
6915
7059
  const rendererProcessCommands = commands.filter(command => command[0] !== SetFocusContext);
7060
+ if (rendererProcessCommands.length === 0) {
7061
+ return rendererWorkerCommands;
7062
+ }
6916
7063
  const transactionId = await invoke('Viewlet.queueCommands', uid, rendererProcessCommands);
6917
7064
  return [...rendererWorkerCommands, ['Viewlet.commitPending', uid, transactionId]];
6918
7065
  };
@@ -6931,6 +7078,13 @@ const render2 = (uid, diffResult) => {
6931
7078
 
6932
7079
  const Button = 1;
6933
7080
 
7081
+ const getActionButtonClassName = enabled => {
7082
+ if (enabled) {
7083
+ return IconButton;
7084
+ }
7085
+ return mergeClassNames(IconButton, IconButtonDisabled);
7086
+ };
7087
+
6934
7088
  const getIconVirtualDom = (icon, type = Div) => {
6935
7089
  return {
6936
7090
  childCount: 0,
@@ -6940,12 +7094,6 @@ const getIconVirtualDom = (icon, type = Div) => {
6940
7094
  };
6941
7095
  };
6942
7096
 
6943
- const getClassName = enabled => {
6944
- if (enabled) {
6945
- return IconButton;
6946
- }
6947
- return mergeClassNames(IconButton, IconButtonDisabled);
6948
- };
6949
7097
  const getActionButtonVirtualDom = action => {
6950
7098
  const {
6951
7099
  enabled,
@@ -6953,7 +7101,7 @@ const getActionButtonVirtualDom = action => {
6953
7101
  id,
6954
7102
  label
6955
7103
  } = action;
6956
- const className = getClassName(enabled);
7104
+ const className = getActionButtonClassName(enabled);
6957
7105
  const disabled = !enabled;
6958
7106
  return [{
6959
7107
  childCount: 1,
@@ -7022,7 +7170,7 @@ const getActions = state => {
7022
7170
  type: Button
7023
7171
  }, {
7024
7172
  command: '',
7025
- enabled: hasSearchResults,
7173
+ enabled: true,
7026
7174
  icon: ListFlat,
7027
7175
  id: ViewAsTree,
7028
7176
  label: viewAsTree$1(),
@@ -7131,19 +7279,6 @@ const rerender = state => {
7131
7279
  };
7132
7280
  };
7133
7281
 
7134
- const revealInExplorerActual = async uri => {
7135
- await invoke$3('SideBar.show', 'Explorer');
7136
- const states = await invoke$3('Viewlet.getAllStates');
7137
- const viewlets = Object.values(states);
7138
- const sideBar = viewlets.find(viewlet => viewlet.currentViewletId === 'Explorer');
7139
- const explorerUid = Math.max(...viewlets.filter(viewlet => viewlet.parentUid === sideBar.uid).map(viewlet => viewlet.uid));
7140
- await invoke$3('Viewlet.executeViewletCommand', explorerUid, 'reveal', uri);
7141
- };
7142
- const revealInExplorer = async (state, uri) => {
7143
- await revealInExplorerActual(uri);
7144
- return state;
7145
- };
7146
-
7147
7282
  const saveState = state => {
7148
7283
  const {
7149
7284
  collapsedPaths,
@@ -7247,6 +7382,7 @@ const getNewHistory = (history, newValue) => {
7247
7382
  const cutHistory = newHistory.slice(0, maxHistoryLength);
7248
7383
  return cutHistory;
7249
7384
  };
7385
+
7250
7386
  const submit = state => {
7251
7387
  const {
7252
7388
  history,
@@ -7366,16 +7502,16 @@ const commandMap$1 = {
7366
7502
  'TextSearch.handleActionClick': wrapCommand(handleActionClick),
7367
7503
  'TextSearch.handleClickAt': wrapCommand(handleClickAt),
7368
7504
  'TextSearch.handleContextMenu': wrapCommand(handleContextMenu),
7369
- 'TextSearch.handleExcludeInput': wrapCommand(handleExcludeInput),
7505
+ 'TextSearch.handleExcludeInput': wrapSerialCommand(handleExcludeInput),
7370
7506
  'TextSearch.handleFocusIn': wrapCommand(handleFocusIn),
7371
7507
  'TextSearch.handleHeaderClick': wrapCommand(handleHeaderClick),
7372
7508
  'TextSearch.handleHeaderContextMenu': wrapCommand(handleHeaderContextMenu),
7373
7509
  'TextSearch.handleHeaderFocusIn': wrapCommand(handleHeaderFocusIn),
7374
7510
  'TextSearch.handleHeaderFocusOut': wrapCommand(handleHeaderFocusOut),
7375
7511
  'TextSearch.handleIconThemeChange': wrapCommand(handleIconThemeChange),
7376
- 'TextSearch.handleIncludeInput': wrapCommand(handleIncludeInput),
7377
- 'TextSearch.handleInput': wrapCommand(handleInput),
7378
- 'TextSearch.handleInput2': wrapCommand(handleInput2),
7512
+ 'TextSearch.handleIncludeInput': wrapSerialCommand(handleIncludeInput),
7513
+ 'TextSearch.handleInput': wrapSerialCommand(handleInput),
7514
+ 'TextSearch.handleInput2': wrapSerialCommand(handleInput2),
7379
7515
  'TextSearch.handleInputBlur': wrapCommand(handleInputBlur),
7380
7516
  'TextSearch.handleInputContextMenu': wrapCommand(handleInputContextMenu),
7381
7517
  'TextSearch.handleInputCopy': wrapCommand(handleInputCopy),
@@ -7390,7 +7526,7 @@ const commandMap$1 = {
7390
7526
  'TextSearch.handleMessagePort': handleDirectMessagePort,
7391
7527
  'TextSearch.handleOpenFolderClick': wrapCommand(handleOpenFolderClick),
7392
7528
  'TextSearch.handlePullResultsFound': wrapCommand(handlePullResultsFound),
7393
- 'TextSearch.handleReplaceInput': wrapCommand(handleReplaceInput),
7529
+ 'TextSearch.handleReplaceInput': wrapSerialCommand(handleReplaceInput),
7394
7530
  'TextSearch.handleResize': wrapCommand(handleResize),
7395
7531
  'TextSearch.handleScrollBarCaptureLost': wrapCommand(handleScrollBarCaptureLost),
7396
7532
  'TextSearch.handleScrollBarClick': wrapCommand(handleScrollBarClick),
@@ -7399,9 +7535,9 @@ const commandMap$1 = {
7399
7535
  'TextSearch.handleWheel': wrapCommand(handleWheel),
7400
7536
  'TextSearch.handleWorkspaceChange': wrapCommand(handleWorkspaceChange),
7401
7537
  'TextSearch.loadContent': wrapCommand(loadContent),
7402
- 'TextSearch.nextHistoryResult': wrapCommand(nextHistoryResult),
7538
+ 'TextSearch.nextHistoryResult': wrapSerialCommand(nextHistoryResult),
7403
7539
  'TextSearch.openSearchEditor': wrapCommand(openSearchEditor),
7404
- 'TextSearch.previousHistoryResult': wrapCommand(previousHistoryResult),
7540
+ 'TextSearch.previousHistoryResult': wrapSerialCommand(previousHistoryResult),
7405
7541
  'TextSearch.refresh': wrapCommand(refresh),
7406
7542
  'TextSearch.removeCurrent': wrapCommand(removeCurrent),
7407
7543
  'TextSearch.removeIndex': wrapCommand(removeIndex),
@@ -7415,24 +7551,34 @@ const commandMap$1 = {
7415
7551
  'TextSearch.replaceAllInFile': wrapCommand(replaceAllInFile),
7416
7552
  'TextSearch.rerender': rerender,
7417
7553
  'TextSearch.restoreState': restoreState,
7418
- 'TextSearch.revealInExplorer': wrapCommand(revealInExplorer),
7419
7554
  'TextSearch.saveState': wrapGetter(saveState),
7420
7555
  'TextSearch.selectIndex': wrapCommand(selectIndex),
7421
- 'TextSearch.setLimit': wrapCommand(setLimit),
7422
- 'TextSearch.submit': wrapCommand(submit),
7556
+ 'TextSearch.setLimit': wrapSerialCommand(setLimit),
7557
+ 'TextSearch.submit': wrapSerialCommand(submit),
7423
7558
  'TextSearch.terminate': terminate,
7424
7559
  'TextSearch.textSearch': textSearch,
7425
- 'TextSearch.toggleMatchCase': wrapCommand(toggleMatchCase),
7426
- 'TextSearch.toggleMatchWholeWord': wrapCommand(toggleMatchWholeWord),
7427
- 'TextSearch.toggleOpenEditors': wrapCommand(toggleOpenEditors),
7560
+ 'TextSearch.toggleMatchCase': wrapSerialCommand(toggleMatchCase),
7561
+ 'TextSearch.toggleMatchWholeWord': wrapSerialCommand(toggleMatchWholeWord),
7562
+ 'TextSearch.toggleOpenEditors': wrapSerialCommand(toggleOpenEditors),
7428
7563
  'TextSearch.togglePreserveCase': wrapCommand(togglePreserveCase),
7429
- 'TextSearch.toggleReplace': wrapCommand(toggleReplace),
7564
+ 'TextSearch.toggleReplace': wrapSerialCommand(toggleReplace),
7430
7565
  'TextSearch.toggleSearchDetails': wrapCommand(toggleDetailsExpanded),
7431
- 'TextSearch.toggleUseIgnoreFiles': wrapCommand(toggleUseIgnoreFiles),
7432
- 'TextSearch.toggleUseRegularExpression': wrapCommand(toggleUseRegularExpression),
7566
+ 'TextSearch.toggleUseIgnoreFiles': wrapSerialCommand(toggleUseIgnoreFiles),
7567
+ 'TextSearch.toggleUseRegularExpression': wrapSerialCommand(toggleUseRegularExpression),
7433
7568
  'TextSearch.viewAsTree': wrapCommand(viewAsTree)
7434
7569
  };
7435
7570
 
7571
+ const sendMessagePortToClipBoardWorker = async port => {
7572
+ await sendMessagePortToClipBoardWorker$1(port, 0);
7573
+ };
7574
+ const initializeClipBoardWorker = async () => {
7575
+ const rpc = await create$5({
7576
+ commandMap: {},
7577
+ send: sendMessagePortToClipBoardWorker
7578
+ });
7579
+ set$8(rpc);
7580
+ };
7581
+
7436
7582
  const initializeDialogWorker = async () => {
7437
7583
  const rpc = await create$5({
7438
7584
  commandMap: {},
@@ -7466,7 +7612,7 @@ const initializeTextMeasurementWorker = async () => {
7466
7612
  commandMap: {},
7467
7613
  send: send$1
7468
7614
  });
7469
- set$2(rpc);
7615
+ set$4(rpc);
7470
7616
  };
7471
7617
 
7472
7618
  const commandMap = {
@@ -7485,7 +7631,7 @@ const launchTextSearchWorker = async () => {
7485
7631
 
7486
7632
  const initializeTextSearchWorker = async () => {
7487
7633
  const rpc = await launchTextSearchWorker();
7488
- set$3(rpc);
7634
+ set$2(rpc);
7489
7635
  };
7490
7636
 
7491
7637
  const listen = async () => {
@@ -7493,8 +7639,8 @@ const listen = async () => {
7493
7639
  const rpc = await create$4({
7494
7640
  commandMap: commandMap$1
7495
7641
  });
7496
- set$4(rpc);
7497
- await Promise.all([initializeDialogWorker(), initializeIconThemeWorker(), initializeTextMeasurementWorker(), initializeTextSearchWorker()]);
7642
+ set$3(rpc);
7643
+ await Promise.all([initializeClipBoardWorker(), initializeDialogWorker(), initializeIconThemeWorker(), initializeTextMeasurementWorker(), initializeTextSearchWorker()]);
7498
7644
  };
7499
7645
 
7500
7646
  const main = async () => {