@lvce-editor/file-search-worker 3.4.0 → 3.6.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.
@@ -54,6 +54,53 @@ class VError extends Error {
54
54
  }
55
55
  }
56
56
 
57
+ class AssertionError extends Error {
58
+ constructor(message) {
59
+ super(message);
60
+ this.name = 'AssertionError';
61
+ }
62
+ }
63
+ const getType = value => {
64
+ switch (typeof value) {
65
+ case 'number':
66
+ return 'number';
67
+ case 'function':
68
+ return 'function';
69
+ case 'string':
70
+ return 'string';
71
+ case 'object':
72
+ if (value === null) {
73
+ return 'null';
74
+ }
75
+ if (Array.isArray(value)) {
76
+ return 'array';
77
+ }
78
+ return 'object';
79
+ case 'boolean':
80
+ return 'boolean';
81
+ default:
82
+ return 'unknown';
83
+ }
84
+ };
85
+ const object = value => {
86
+ const type = getType(value);
87
+ if (type !== 'object') {
88
+ throw new AssertionError('expected value to be of type object');
89
+ }
90
+ };
91
+ const number = value => {
92
+ const type = getType(value);
93
+ if (type !== 'number') {
94
+ throw new AssertionError('expected value to be of type number');
95
+ }
96
+ };
97
+ const array = value => {
98
+ const type = getType(value);
99
+ if (type !== 'array') {
100
+ throw new AssertionError('expected value to be of type array');
101
+ }
102
+ };
103
+
57
104
  const isMessagePort = value => {
58
105
  return value && value instanceof MessagePort;
59
106
  };
@@ -381,7 +428,7 @@ const IpcChildWithModuleWorkerAndMessagePort$1 = {
381
428
  };
382
429
 
383
430
  const Two = '2.0';
384
- const create$4 = (method, params) => {
431
+ const create$4$1 = (method, params) => {
385
432
  return {
386
433
  jsonrpc: Two,
387
434
  method,
@@ -389,32 +436,32 @@ const create$4 = (method, params) => {
389
436
  };
390
437
  };
391
438
  const callbacks = Object.create(null);
392
- const set = (id, fn) => {
439
+ const set$1 = (id, fn) => {
393
440
  callbacks[id] = fn;
394
441
  };
395
- const get = id => {
442
+ const get$1 = id => {
396
443
  return callbacks[id];
397
444
  };
398
445
  const remove$2 = id => {
399
446
  delete callbacks[id];
400
447
  };
401
448
  let id = 0;
402
- const create$3 = () => {
449
+ const create$3$1 = () => {
403
450
  return ++id;
404
451
  };
405
452
  const registerPromise = () => {
406
- const id = create$3();
453
+ const id = create$3$1();
407
454
  const {
408
455
  resolve,
409
456
  promise
410
457
  } = Promise.withResolvers();
411
- set(id, resolve);
458
+ set$1(id, resolve);
412
459
  return {
413
460
  id,
414
461
  promise
415
462
  };
416
463
  };
417
- const create$2 = (method, params) => {
464
+ const create$2$1 = (method, params) => {
418
465
  const {
419
466
  id,
420
467
  promise
@@ -565,7 +612,7 @@ const warn$1 = (...args) => {
565
612
  console.warn(...args);
566
613
  };
567
614
  const resolve = (id, response) => {
568
- const fn = get(id);
615
+ const fn = get$1(id);
569
616
  if (!fn) {
570
617
  console.log(response);
571
618
  warn$1(`callback ${id} may already be disposed`);
@@ -604,7 +651,7 @@ const getErrorProperty = (error, prettyError) => {
604
651
  }
605
652
  };
606
653
  };
607
- const create$1 = (message, error) => {
654
+ const create$1$1 = (message, error) => {
608
655
  return {
609
656
  jsonrpc: Two,
610
657
  id: message.id,
@@ -615,7 +662,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
615
662
  const prettyError = preparePrettyError(error);
616
663
  logError(error, prettyError);
617
664
  const errorProperty = getErrorProperty(error, prettyError);
618
- return create$1(message, errorProperty);
665
+ return create$1$1(message, errorProperty);
619
666
  };
620
667
  const create$5 = (message, result) => {
621
668
  return {
@@ -706,7 +753,7 @@ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
706
753
  const {
707
754
  message,
708
755
  promise
709
- } = create$2(method, params);
756
+ } = create$2$1(method, params);
710
757
  if (useSendAndTransfer && ipc.sendAndTransfer) {
711
758
  ipc.sendAndTransfer(message);
712
759
  } else {
@@ -716,7 +763,7 @@ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
716
763
  return unwrapJsonRpcResult(responseMessage);
717
764
  };
718
765
  const send = (transport, method, ...params) => {
719
- const message = create$4(method, params);
766
+ const message = create$4$1(method, params);
720
767
  transport.send(message);
721
768
  };
722
769
  const invoke$2 = (ipc, method, ...params) => {
@@ -790,7 +837,7 @@ const listen$1 = async (module, options) => {
790
837
  const ipc = module.wrap(rawIpc);
791
838
  return ipc;
792
839
  };
793
- const create = async ({
840
+ const create$4 = async ({
794
841
  commandMap
795
842
  }) => {
796
843
  // TODO create a commandMap per rpc instance
@@ -802,247 +849,399 @@ const create = async ({
802
849
  };
803
850
  const WebWorkerRpcClient = {
804
851
  __proto__: null,
805
- create
852
+ create: create$4
806
853
  };
807
854
 
808
- const assetDir = '';
809
-
810
- const Directory$1 = 3;
811
- const File$2 = 7;
855
+ const User = 1;
856
+ const Script = 2;
812
857
 
813
- const fileMapUrl = `${assetDir}/config/fileMap.json`;
858
+ const minimumSliderSize = 20;
814
859
 
815
- const getBlob$2 = async url => {
816
- try {
817
- const response = await fetch(url);
818
- if (!response.ok) {
819
- throw new Error(response.statusText);
820
- }
821
- const text = await response.blob();
822
- return text;
823
- } catch (error) {
824
- throw new VError(error, `Failed to request blob for ${url}`);
825
- }
860
+ const handleError = async (error, notify = true, prefix = '') => {
861
+ console.error(error);
826
862
  };
827
-
828
- const getJson = async url => {
829
- try {
830
- const response = await fetch(url);
831
- if (!response.ok) {
832
- throw new Error(response.statusText);
833
- }
834
- const text = await response.json();
835
- return text;
836
- } catch (error) {
837
- throw new VError(error, `Failed to request json for ${url}`);
838
- }
863
+ const showErrorDialog = async () => {};
864
+ const warn = (...args) => {
865
+ console.warn(...args);
839
866
  };
840
867
 
841
- const getText = async url => {
842
- try {
843
- const response = await fetch(url);
844
- if (!response.ok) {
845
- throw new Error(response.statusText);
846
- }
847
- const text = await response.text();
848
- return text;
849
- } catch (error) {
850
- throw new VError(error, `Failed to request text for ${url}`);
851
- }
868
+ const state$5 = {
869
+ menuEntries: []
870
+ };
871
+ const getAll = () => {
872
+ return state$5.menuEntries;
852
873
  };
853
874
 
854
- const Slash$1 = '/';
875
+ const Hide = 'hide';
876
+ const KeepOpen = '';
855
877
 
856
- const Slash = Slash$1;
878
+ const emptyObject = {};
879
+ const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
880
+ const i18nString = (key, placeholders = emptyObject) => {
881
+ if (placeholders === emptyObject) {
882
+ return key;
883
+ }
884
+ const replacer = (match, rest) => {
885
+ return placeholders[rest];
886
+ };
887
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
888
+ };
857
889
 
858
- // TODO move all of this to an extension
890
+ const Files = 'Files';
891
+ const GoToFile = 'Go to file';
892
+ const NoMatchingColorThemesFound = 'No matching color themes found';
893
+ const NoMatchingResults = 'No matching results';
894
+ const NoRecentlyOpenedFoldersFound = 'No recently opened folders found';
895
+ const NoResults = 'No Results';
896
+ const NoSymbolFound = 'No symbol found';
897
+ const NoWorkspaceSymbolsFound = 'no workspace symbols found';
898
+ const OpenRecent = 'Open Recent';
899
+ const SelectColorTheme = 'Select Color Theme';
900
+ const SelectToOpen = 'Select to open';
901
+ const ShowAndRunCommands = 'Show And Run Commands';
902
+ const TypeNameOfCommandToRun = 'Type the name of a command to run.';
859
903
 
860
- const readFile$1 = async uri => {
861
- const fetchUri = `${assetDir}${uri}`;
862
- const text = await getText(fetchUri);
863
- return text;
904
+ const noMatchingColorThemesFound = () => {
905
+ return i18nString(NoMatchingColorThemesFound);
864
906
  };
865
- const writeFile$1 = () => {
866
- throw new Error('not implemented');
907
+ const selectColorTheme = () => {
908
+ return i18nString(SelectColorTheme);
867
909
  };
868
- const mkdir$1 = () => {
869
- throw new Error('not implemented');
910
+ const typeNameofCommandToRun = () => {
911
+ return i18nString(TypeNameOfCommandToRun);
870
912
  };
871
- const remove$1 = () => {
872
- throw new Error('not implemented');
913
+ const showAndRunCommands = () => {
914
+ return i18nString(ShowAndRunCommands);
873
915
  };
874
- const readDirWithFileTypes$1 = async uri => {
875
- const fileList = await getJson(fileMapUrl);
876
- const dirents = [];
877
- for (const fileUri of fileList) {
878
- if (fileUri.startsWith(uri)) {
879
- const rest = fileUri.slice(uri.length + 1);
880
- if (rest.includes(Slash)) {
881
- const name = rest.slice(0, rest.indexOf(Slash));
882
- if (dirents.some(dirent => dirent.name === name)) {
883
- continue;
884
- }
885
- dirents.push({
886
- type: Directory$1,
887
- name
888
- });
889
- } else {
890
- dirents.push({
891
- type: File$2,
892
- name: rest
893
- });
894
- }
895
- }
896
- }
897
- return dirents;
916
+ const noMatchingResults = () => {
917
+ return i18nString(NoMatchingResults);
898
918
  };
899
- const chmod$1 = () => {
900
- throw new Error('[memfs] chmod not implemented');
919
+ const files = () => {
920
+ return i18nString(Files);
901
921
  };
902
- const getBlob$1 = async (uri, type) => {
903
- const fetchUri = `${assetDir}${uri}`;
904
- const blob = getBlob$2(fetchUri);
905
- return blob;
922
+ const goToFile = () => {
923
+ return i18nString(GoToFile);
906
924
  };
907
-
908
- class FileNotFoundError extends Error {
909
- constructor(uri) {
910
- super(`File not found: ${uri}`);
911
- this.code = 'ENOENT';
912
- }
913
- }
914
-
915
- const ApplicationJson = 'application/json';
916
- const AudioMpeg = 'audio/mpeg';
917
- const FontTtf = 'font/ttf';
918
- const ImagePng = 'image/png';
919
- const ImageSvgXml = 'image/svg+xml';
920
- const TextCss = 'text/css';
921
- const TextHtml = 'text/html';
922
- const TextJavaScript = 'text/javascript';
923
- const TextPlain = 'text/plain';
924
- const VideoWebm = 'video/webm';
925
-
926
- const getMimeType = fileExtension => {
927
- switch (fileExtension) {
928
- case '.html':
929
- return TextHtml;
930
- case '.css':
931
- return TextCss;
932
- case '.ttf':
933
- return FontTtf;
934
- case '.js':
935
- case '.mjs':
936
- case '.ts':
937
- return TextJavaScript;
938
- case '.svg':
939
- return ImageSvgXml;
940
- case '.png':
941
- return ImagePng;
942
- case '.json':
943
- case '.map':
944
- return ApplicationJson;
945
- case '.mp3':
946
- return AudioMpeg;
947
- case '.webm':
948
- return VideoWebm;
949
- case '.txt':
950
- return TextPlain;
951
- default:
952
- return '';
953
- }
925
+ const noResults = () => {
926
+ return i18nString(NoResults);
954
927
  };
955
-
956
- const dirname = (pathSeparator, path) => {
957
- const index = path.lastIndexOf(pathSeparator);
958
- if (index === -1) {
959
- return path;
960
- }
961
- return path.slice(0, index);
928
+ const selectToOpen = () => {
929
+ return i18nString(SelectToOpen);
962
930
  };
963
- const extname = path => {
964
- const index = path.lastIndexOf('.');
965
- if (index === -1) {
966
- return '';
967
- }
968
- return path.slice(index);
931
+ const openRecent = () => {
932
+ return i18nString(OpenRecent);
969
933
  };
970
-
971
- const getContentType = uri => {
972
- const extension = extname(uri);
973
- const mime = getMimeType(extension);
974
- return mime;
934
+ const noRecentlyOpenedFoldersFound = () => {
935
+ return i18nString(NoRecentlyOpenedFoldersFound);
936
+ };
937
+ const noSymbolFound = () => {
938
+ return i18nString(NoSymbolFound);
939
+ };
940
+ const noWorkspaceSymbolsFound = () => {
941
+ return i18nString(NoWorkspaceSymbolsFound);
975
942
  };
976
943
 
977
- // TODO move this to an extension?
944
+ const state$4 = {
945
+ rpc: undefined
946
+ };
978
947
 
979
- const state$5 = {
980
- files: Object.create(null)
948
+ // TODO use rpc registry
949
+ const invoke$1 = (method, ...params) => {
950
+ const rpc = state$4.rpc;
951
+ // @ts-ignore
952
+ return rpc.invoke(method, ...params);
981
953
  };
982
- const getDirent = uri => {
983
- return state$5.files[uri];
954
+ const setRpc = rpc => {
955
+ state$4.rpc = rpc;
984
956
  };
985
- const readFile = uri => {
986
- const dirent = getDirent(uri);
987
- if (!dirent) {
988
- throw new FileNotFoundError(uri);
989
- }
990
- if (dirent.type !== File$2) {
991
- throw new Error('file is a directory');
992
- }
993
- return dirent.content;
957
+
958
+ const name$8 = 'command';
959
+ const getPlaceholder$b = () => {
960
+ return typeNameofCommandToRun();
994
961
  };
995
- const ensureParentDir = uri => {
996
- const startIndex = 0;
997
- let endIndex = uri.indexOf(Slash);
998
- while (endIndex >= 0) {
999
- const part = uri.slice(startIndex, endIndex + 1);
1000
- state$5.files[part] = {
1001
- type: Directory$1,
1002
- content: ''
1003
- };
1004
- endIndex = uri.indexOf(Slash, endIndex + 1);
1005
- }
962
+ const helpEntries = () => {
963
+ return [{
964
+ description: showAndRunCommands(),
965
+ category: 'global commands'
966
+ }];
1006
967
  };
1007
- const writeFile = (uri, content) => {
1008
- const dirent = getDirent(uri);
1009
- if (dirent) {
1010
- dirent.content = content;
1011
- } else {
1012
- ensureParentDir(uri);
1013
- state$5.files[uri] = {
1014
- type: File$2,
1015
- content
1016
- };
1017
- }
968
+ const getLabel$5 = () => {
969
+ return '';
1018
970
  };
1019
- const mkdir = uri => {
1020
- if (!uri.endsWith(Slash)) {
1021
- uri += Slash;
1022
- }
1023
- ensureParentDir(uri);
1024
- state$5.files[uri] = {
1025
- type: Directory$1,
1026
- content: ''
971
+ const getNoResults$a = () => {
972
+ return {
973
+ label: noMatchingResults()
1027
974
  };
1028
975
  };
1029
- const remove = uri => {
1030
- const toDelete = [];
1031
- for (const key of Object.keys(state$5.files)) {
1032
- if (key.startsWith(uri)) {
1033
- toDelete.push(key);
1034
- }
976
+
977
+ // TODO combine Ajax with cache (specify strategy: cacheFirst, networkFirst)
978
+ const getBuiltinPicks = async () => {
979
+ const builtinPicks = getAll();
980
+ return builtinPicks;
981
+ };
982
+ const prefixIdWithExt = item => {
983
+ if (!item.label) {
984
+ warn('[QuickPick] item has missing label', item);
985
+ }
986
+ if (!item.id) {
987
+ warn('[QuickPick] item has missing id', item);
988
+ }
989
+ return {
990
+ ...item,
991
+ id: `ext.${item.id}`,
992
+ label: item.label || item.id
993
+ };
994
+ };
995
+ const getExtensionPicks = async () => {
996
+ try {
997
+ // TODO don't call this every time
998
+ const extensionPicks = await invoke$1('ExtensionHostCommands.getCommands');
999
+ if (!extensionPicks) {
1000
+ return [];
1001
+ }
1002
+ const mappedPicks = extensionPicks.map(prefixIdWithExt);
1003
+ return mappedPicks;
1004
+ } catch (error) {
1005
+ console.error(`Failed to get extension picks: ${error}`);
1006
+ return [];
1007
+ }
1008
+ };
1009
+
1010
+ // TODO send strings to renderer process only once for next occurrence send uint16array of ids of strings
1011
+
1012
+ const getPicks$b = async () => {
1013
+ const builtinPicks = await getBuiltinPicks();
1014
+ const extensionPicks = await getExtensionPicks();
1015
+ return [...builtinPicks, ...extensionPicks];
1016
+ };
1017
+ const shouldHide = item => {
1018
+ if (item.id === 'Viewlet.openWidget' && item.args[0] === 'QuickPick') {
1019
+ return false;
1020
+ }
1021
+ return true;
1022
+ };
1023
+ const selectPickBuiltin = async item => {
1024
+ const args = item.args || [];
1025
+ // TODO ids should be all numbers for efficiency -> also directly can call command
1026
+ await invoke$1(item.id, ...args);
1027
+ if (shouldHide(item)) {
1028
+ return {
1029
+ command: Hide
1030
+ };
1031
+ }
1032
+ return {
1033
+ command: KeepOpen
1034
+ };
1035
+ };
1036
+ const selectPickExtension = async item => {
1037
+ const id = item.id.slice(4); // TODO lots of string allocation with 'ext.' find a better way to separate builtin commands from extension commands
1038
+ try {
1039
+ await invoke$1('ExtensionHostCommands.executeCommand', id);
1040
+ } catch (error) {
1041
+ await handleError(error, false);
1042
+ // @ts-ignore
1043
+ await showErrorDialog();
1044
+ }
1045
+ return {
1046
+ command: Hide
1047
+ };
1048
+ };
1049
+ const selectPick$b = async item => {
1050
+ if (item.id.startsWith('ext.')) {
1051
+ return selectPickExtension(item);
1052
+ }
1053
+ return selectPickBuiltin(item);
1054
+ };
1055
+ const getFilterValue$a = value => {
1056
+ return value;
1057
+ };
1058
+ const getPickFilterValue$6 = pick => {
1059
+ return pick.label;
1060
+ };
1061
+ const getPickLabel$5 = pick => {
1062
+ return pick.label;
1063
+ };
1064
+ const getPickIcon$5 = () => {
1065
+ return '';
1066
+ };
1067
+
1068
+ const QuickPickEntriesCommand = {
1069
+ __proto__: null,
1070
+ getFilterValue: getFilterValue$a,
1071
+ getLabel: getLabel$5,
1072
+ getNoResults: getNoResults$a,
1073
+ getPickFilterValue: getPickFilterValue$6,
1074
+ getPickIcon: getPickIcon$5,
1075
+ getPickLabel: getPickLabel$5,
1076
+ getPicks: getPicks$b,
1077
+ getPlaceholder: getPlaceholder$b,
1078
+ helpEntries,
1079
+ name: name$8,
1080
+ selectPick: selectPick$b
1081
+ };
1082
+
1083
+ const execute = async (method, ...params) => {
1084
+ // TODO
1085
+ };
1086
+
1087
+ const RE_PROTOCOL = /^([a-z-]+):\/\//;
1088
+ const getProtocol = uri => {
1089
+ const protocolMatch = uri.match(RE_PROTOCOL);
1090
+ if (protocolMatch) {
1091
+ return protocolMatch[1];
1092
+ }
1093
+ return '';
1094
+ };
1095
+
1096
+ const Memfs = 'memfs';
1097
+ const Html = 'html';
1098
+ const Fetch = 'fetch';
1099
+
1100
+ const Directory$1 = 3;
1101
+ const File$2 = 7;
1102
+
1103
+ class FileNotFoundError extends Error {
1104
+ constructor(uri) {
1105
+ super(`File not found: ${uri}`);
1106
+ this.code = 'ENOENT';
1107
+ }
1108
+ }
1109
+
1110
+ const ApplicationJson = 'application/json';
1111
+ const AudioMpeg = 'audio/mpeg';
1112
+ const FontTtf = 'font/ttf';
1113
+ const ImagePng = 'image/png';
1114
+ const ImageSvgXml = 'image/svg+xml';
1115
+ const TextCss = 'text/css';
1116
+ const TextHtml = 'text/html';
1117
+ const TextJavaScript = 'text/javascript';
1118
+ const TextPlain = 'text/plain';
1119
+ const VideoWebm = 'video/webm';
1120
+
1121
+ const getMimeType = fileExtension => {
1122
+ switch (fileExtension) {
1123
+ case '.html':
1124
+ return TextHtml;
1125
+ case '.css':
1126
+ return TextCss;
1127
+ case '.ttf':
1128
+ return FontTtf;
1129
+ case '.js':
1130
+ case '.mjs':
1131
+ case '.ts':
1132
+ return TextJavaScript;
1133
+ case '.svg':
1134
+ return ImageSvgXml;
1135
+ case '.png':
1136
+ return ImagePng;
1137
+ case '.json':
1138
+ case '.map':
1139
+ return ApplicationJson;
1140
+ case '.mp3':
1141
+ return AudioMpeg;
1142
+ case '.webm':
1143
+ return VideoWebm;
1144
+ case '.txt':
1145
+ return TextPlain;
1146
+ default:
1147
+ return '';
1148
+ }
1149
+ };
1150
+
1151
+ const dirname = (pathSeparator, path) => {
1152
+ const index = path.lastIndexOf(pathSeparator);
1153
+ if (index === -1) {
1154
+ return path;
1155
+ }
1156
+ return path.slice(0, index);
1157
+ };
1158
+ const extname = path => {
1159
+ const index = path.lastIndexOf('.');
1160
+ if (index === -1) {
1161
+ return '';
1162
+ }
1163
+ return path.slice(index);
1164
+ };
1165
+
1166
+ const getContentType = uri => {
1167
+ const extension = extname(uri);
1168
+ const mime = getMimeType(extension);
1169
+ return mime;
1170
+ };
1171
+
1172
+ const Slash$1 = '/';
1173
+
1174
+ const Slash = Slash$1;
1175
+
1176
+ // TODO move this to an extension?
1177
+
1178
+ const state$3 = {
1179
+ files: Object.create(null)
1180
+ };
1181
+ const getDirent = uri => {
1182
+ return state$3.files[uri];
1183
+ };
1184
+ const readFile$1 = uri => {
1185
+ const dirent = getDirent(uri);
1186
+ if (!dirent) {
1187
+ throw new FileNotFoundError(uri);
1188
+ }
1189
+ if (dirent.type !== File$2) {
1190
+ throw new Error('file is a directory');
1191
+ }
1192
+ return dirent.content;
1193
+ };
1194
+ const ensureParentDir = uri => {
1195
+ const startIndex = 0;
1196
+ let endIndex = uri.indexOf(Slash);
1197
+ while (endIndex >= 0) {
1198
+ const part = uri.slice(startIndex, endIndex + 1);
1199
+ state$3.files[part] = {
1200
+ type: Directory$1,
1201
+ content: ''
1202
+ };
1203
+ endIndex = uri.indexOf(Slash, endIndex + 1);
1204
+ }
1205
+ };
1206
+ const writeFile$1 = (uri, content) => {
1207
+ const dirent = getDirent(uri);
1208
+ if (dirent) {
1209
+ dirent.content = content;
1210
+ } else {
1211
+ ensureParentDir(uri);
1212
+ state$3.files[uri] = {
1213
+ type: File$2,
1214
+ content
1215
+ };
1216
+ }
1217
+ };
1218
+ const mkdir$1 = uri => {
1219
+ if (!uri.endsWith(Slash)) {
1220
+ uri += Slash;
1221
+ }
1222
+ ensureParentDir(uri);
1223
+ state$3.files[uri] = {
1224
+ type: Directory$1,
1225
+ content: ''
1226
+ };
1227
+ };
1228
+ const remove$1 = uri => {
1229
+ const toDelete = [];
1230
+ for (const key of Object.keys(state$3.files)) {
1231
+ if (key.startsWith(uri)) {
1232
+ toDelete.push(key);
1233
+ }
1035
1234
  }
1036
1235
  for (const key of toDelete) {
1037
- delete state$5.files[key];
1236
+ delete state$3.files[key];
1038
1237
  }
1039
1238
  };
1040
- const readDirWithFileTypes = uri => {
1239
+ const readDirWithFileTypes$1 = uri => {
1041
1240
  if (!uri.endsWith(Slash)) {
1042
1241
  uri += Slash;
1043
1242
  }
1044
1243
  const dirents = [];
1045
- for (const [key, value] of Object.entries(state$5.files)) {
1244
+ for (const [key, value] of Object.entries(state$3.files)) {
1046
1245
  if (key.startsWith(uri)) {
1047
1246
  // @ts-ignore
1048
1247
  switch (value.type) {
@@ -1069,8 +1268,8 @@ const readDirWithFileTypes = uri => {
1069
1268
  }
1070
1269
  return dirents;
1071
1270
  };
1072
- const getBlob = (uri, type) => {
1073
- const content = readFile(uri);
1271
+ const getBlob$2 = (uri, type) => {
1272
+ const content = readFile$1(uri);
1074
1273
  const contentType = type || getContentType(uri);
1075
1274
  const blob = new Blob([content], {
1076
1275
  type: contentType
@@ -1078,1481 +1277,1596 @@ const getBlob = (uri, type) => {
1078
1277
  return blob;
1079
1278
  };
1080
1279
  const getBlobUrl = (uri, type) => {
1081
- const blob = getBlob(uri, type);
1280
+ const blob = getBlob$2(uri, type);
1082
1281
  const url = URL.createObjectURL(blob);
1083
1282
  return url;
1084
1283
  };
1085
- const chmod = () => {
1284
+ const chmod$1 = () => {
1086
1285
  throw new Error('[memfs] chmod not implemented');
1087
1286
  };
1088
1287
  const getFiles = () => {
1089
- return state$5.files;
1288
+ return state$3.files;
1090
1289
  };
1091
1290
 
1092
- const emptyMatches = [];
1291
+ const searchFile$4 = async () => {
1292
+ const files = await getFiles();
1293
+ const keys = Object.keys(files);
1294
+ return keys;
1295
+ };
1093
1296
 
1094
- const convertToPick = item => {
1095
- return {
1096
- pick: item,
1097
- matches: emptyMatches
1098
- };
1297
+ const SearchFileMemfs = {
1298
+ __proto__: null,
1299
+ searchFile: searchFile$4
1099
1300
  };
1100
1301
 
1101
- const Diagonal = 1;
1102
- const Left = 2;
1103
-
1104
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1105
-
1106
- const createTable = size => {
1107
- const table = [];
1108
- for (let i = 0; i < size; i++) {
1109
- const row = new Uint8Array(size);
1110
- table.push(row);
1111
- }
1112
- return table;
1113
- };
1114
- const EmptyMatches = [];
1115
- const Dash = '-';
1116
- const Dot = '.';
1117
- const EmptyString = '';
1118
- const Space = ' ';
1119
- const Underline = '_';
1120
- const T = 't';
1121
- const isLowerCase = char => {
1122
- return char === char.toLowerCase();
1123
- };
1124
- const isUpperCase = char => {
1125
- return char === char.toUpperCase();
1126
- };
1302
+ const assetDir = '';
1127
1303
 
1128
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1129
- const isGap = (columnCharBefore, columnChar) => {
1130
- switch (columnCharBefore) {
1131
- case Dash:
1132
- case Underline:
1133
- case EmptyString:
1134
- case T:
1135
- case Space:
1136
- case Dot:
1137
- return true;
1138
- }
1139
- if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
1140
- return true;
1141
- }
1142
- return false;
1143
- };
1304
+ const fileMapUrl = `${assetDir}/config/fileMap.json`;
1144
1305
 
1145
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1146
- const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch) => {
1147
- if (rowCharLow !== columnCharLow) {
1148
- return -1;
1149
- }
1150
- const isMatch = rowChar === columnChar;
1151
- if (isMatch) {
1152
- if (isDiagonalMatch) {
1153
- return 8;
1154
- }
1155
- if (isGap(columnCharBefore, columnChar)) {
1156
- return 8;
1306
+ const getJson = async url => {
1307
+ try {
1308
+ const response = await fetch(url);
1309
+ if (!response.ok) {
1310
+ throw new Error(response.statusText);
1157
1311
  }
1158
- return 5;
1159
- }
1160
- if (isGap(columnCharBefore, columnChar)) {
1161
- return 8;
1312
+ const text = await response.json();
1313
+ return text;
1314
+ } catch (error) {
1315
+ throw new VError(error, `Failed to request json for ${url}`);
1162
1316
  }
1163
- return 5;
1164
1317
  };
1165
1318
 
1166
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1167
-
1168
- const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
1169
- while (patternPos < patternLen && wordPos < wordLen) {
1170
- if (patternLow[patternPos] === wordLow[wordPos]) {
1171
- patternPos += 1;
1172
- }
1173
- wordPos += 1;
1319
+ const removeLeadingSlash = path => {
1320
+ if (path.startsWith('/')) {
1321
+ return path.slice(1);
1174
1322
  }
1175
- return patternPos === patternLen; // pattern must be exhausted
1323
+ return path;
1176
1324
  };
1177
1325
 
1178
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1179
- const traceHighlights = (table, arrows, patternLength, wordLength) => {
1180
- let row = patternLength;
1181
- let column = wordLength;
1182
- const matches = [];
1183
- while (row >= 1 && column >= 1) {
1184
- const arrow = arrows[row][column];
1185
- if (arrow === Left) {
1186
- column--;
1187
- } else if (arrow === Diagonal) {
1188
- row--;
1189
- column--;
1190
- const start = column + 1;
1191
- while (row >= 1 && column >= 1) {
1192
- const arrow = arrows[row][column];
1193
- if (arrow === Left) {
1194
- break;
1195
- }
1196
- if (arrow === Diagonal) {
1197
- row--;
1198
- column--;
1199
- }
1200
- }
1201
- const end = column;
1202
- matches.unshift(end, start);
1203
- }
1326
+ // TODO simplify code
1327
+ // 1. don't have playground prefix in fileMap json
1328
+ // 2. remove code here that removes the prefix
1329
+ const searchFile$3 = async path => {
1330
+ const fileList = await getJson(fileMapUrl);
1331
+ const result = fileList.map(removeLeadingSlash);
1332
+ const prefixLength = path.length - 'file:///'.length;
1333
+ const final = [];
1334
+ for (const item of result) {
1335
+ final.push(item.slice(prefixLength));
1204
1336
  }
1205
- matches.unshift(table[patternLength][wordLength - 1]);
1206
- return matches;
1337
+ return final;
1207
1338
  };
1208
1339
 
1209
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1210
- const gridSize = 128;
1211
- const table = createTable(gridSize);
1212
- const arrows = createTable(gridSize);
1213
- const fuzzySearch = (pattern, word) => {
1214
- const patternLength = Math.min(pattern.length, gridSize - 1);
1215
- const wordLength = Math.min(word.length, gridSize - 1);
1216
- const patternLower = pattern.toLowerCase();
1217
- const wordLower = word.toLowerCase();
1218
- if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
1219
- return EmptyMatches;
1220
- }
1221
- let strongMatch = false;
1222
- for (let row = 1; row < patternLength + 1; row++) {
1223
- const rowChar = pattern[row - 1];
1224
- const rowCharLow = patternLower[row - 1];
1225
- for (let column = 1; column < wordLength + 1; column++) {
1226
- const columnChar = word[column - 1];
1227
- const columnCharLow = wordLower[column - 1];
1228
- const columnCharBefore = word[column - 2] || '';
1229
- const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
1230
- const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch);
1231
- if (row === 1 && score > 5) {
1232
- strongMatch = true;
1233
- }
1234
- let diagonalScore = score + table[row - 1][column - 1];
1235
- if (isDiagonalMatch && score !== -1) {
1236
- diagonalScore += 2;
1237
- }
1238
- const leftScore = table[row][column - 1];
1239
- if (leftScore > diagonalScore) {
1240
- table[row][column] = leftScore;
1241
- arrows[row][column] = Left;
1242
- } else {
1243
- table[row][column] = diagonalScore;
1244
- arrows[row][column] = Diagonal;
1245
- }
1246
- }
1247
- }
1248
- if (!strongMatch) {
1249
- return EmptyMatches;
1250
- }
1251
- const highlights = traceHighlights(table, arrows, patternLength, wordLength);
1252
- return highlights;
1340
+ const SearchFileFetch = {
1341
+ __proto__: null,
1342
+ searchFile: searchFile$3
1253
1343
  };
1254
1344
 
1255
- const filterQuickPickItem = (pattern, word) => {
1256
- const matches = fuzzySearch(pattern, word);
1257
- return matches;
1258
- };
1345
+ const Directory = 'directory';
1346
+ const File$1 = 'file';
1259
1347
 
1260
- const getBaseName = path => {
1261
- return path.slice(path.lastIndexOf('/') + 1);
1262
- };
1348
+ // based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
1263
1349
 
1264
- const filterQuickPickItems = (items, value) => {
1265
- if (!value) {
1266
- return items.map(convertToPick);
1267
- }
1268
- const results = [];
1269
- for (const item of items) {
1270
- const baseName = getBaseName(item);
1271
- const matches = filterQuickPickItem(value, baseName);
1272
- if (matches.length > 0) {
1273
- results.push({
1274
- pick: item,
1275
- matches
1276
- });
1277
- }
1350
+ const fromAsync = async asyncIterable => {
1351
+ const children = [];
1352
+ for await (const value of asyncIterable) {
1353
+ children.push(value);
1278
1354
  }
1279
- return results;
1355
+ return children;
1280
1356
  };
1281
1357
 
1282
- const Enter = 3;
1283
- const Escape = 8;
1284
- const PageUp = 10;
1285
- const PageDown = 11;
1286
- const UpArrow = 14;
1287
- const DownArrow = 16;
1288
-
1289
- const FocusQuickPickInput = 20;
1290
-
1291
- const getKeyBindings = () => {
1292
- return [{
1293
- key: Escape,
1294
- command: 'Viewlet.closeWidget',
1295
- args: ['QuickPick'],
1296
- when: FocusQuickPickInput
1297
- }, {
1298
- key: UpArrow,
1299
- command: 'QuickPick.focusPrevious',
1300
- when: FocusQuickPickInput
1301
- }, {
1302
- key: DownArrow,
1303
- command: 'QuickPick.focusNext',
1304
- when: FocusQuickPickInput
1305
- }, {
1306
- key: PageUp,
1307
- command: 'QuickPick.focusFirst',
1308
- when: FocusQuickPickInput
1309
- }, {
1310
- key: PageDown,
1311
- command: 'QuickPick.focusLast',
1312
- when: FocusQuickPickInput
1313
- }, {
1314
- key: Enter,
1315
- command: 'QuickPick.selectCurrentIndex',
1316
- when: FocusQuickPickInput
1317
- }];
1318
- };
1358
+ /**
1359
+ * Do not use directly, use FileSystemHtml.getChildHandles
1360
+ * instead which prompts for the required permission to
1361
+ * retrieve the child handles
1362
+ *
1363
+ */
1319
1364
 
1320
- // TODO support file icons
1321
- const getFolderIcon = () => {
1322
- return '';
1365
+ const getChildHandles = async handle => {
1366
+ // @ts-ignore
1367
+ const handles = await fromAsync(handle.values());
1368
+ return handles;
1323
1369
  };
1324
1370
 
1325
- const Hide = 'hide';
1326
- const KeepOpen = '';
1327
-
1328
- const emptyObject = {};
1329
- const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1330
- const i18nString = (key, placeholders = emptyObject) => {
1331
- if (placeholders === emptyObject) {
1332
- return key;
1371
+ const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
1372
+ let idbProxyableTypes;
1373
+ let cursorAdvanceMethods;
1374
+ // This is a function to prevent it throwing up in node environments.
1375
+ function getIdbProxyableTypes() {
1376
+ return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
1377
+ }
1378
+ // This is a function to prevent it throwing up in node environments.
1379
+ function getCursorAdvanceMethods() {
1380
+ return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
1381
+ }
1382
+ const transactionDoneMap = new WeakMap();
1383
+ const transformCache = new WeakMap();
1384
+ const reverseTransformCache = new WeakMap();
1385
+ function promisifyRequest(request) {
1386
+ const promise = new Promise((resolve, reject) => {
1387
+ const unlisten = () => {
1388
+ request.removeEventListener('success', success);
1389
+ request.removeEventListener('error', error);
1390
+ };
1391
+ const success = () => {
1392
+ resolve(wrap(request.result));
1393
+ unlisten();
1394
+ };
1395
+ const error = () => {
1396
+ reject(request.error);
1397
+ unlisten();
1398
+ };
1399
+ request.addEventListener('success', success);
1400
+ request.addEventListener('error', error);
1401
+ });
1402
+ // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
1403
+ // is because we create many promises from a single IDBRequest.
1404
+ reverseTransformCache.set(promise, request);
1405
+ return promise;
1406
+ }
1407
+ function cacheDonePromiseForTransaction(tx) {
1408
+ // Early bail if we've already created a done promise for this transaction.
1409
+ if (transactionDoneMap.has(tx)) return;
1410
+ const done = new Promise((resolve, reject) => {
1411
+ const unlisten = () => {
1412
+ tx.removeEventListener('complete', complete);
1413
+ tx.removeEventListener('error', error);
1414
+ tx.removeEventListener('abort', error);
1415
+ };
1416
+ const complete = () => {
1417
+ resolve();
1418
+ unlisten();
1419
+ };
1420
+ const error = () => {
1421
+ reject(tx.error || new DOMException('AbortError', 'AbortError'));
1422
+ unlisten();
1423
+ };
1424
+ tx.addEventListener('complete', complete);
1425
+ tx.addEventListener('error', error);
1426
+ tx.addEventListener('abort', error);
1427
+ });
1428
+ // Cache it for later retrieval.
1429
+ transactionDoneMap.set(tx, done);
1430
+ }
1431
+ let idbProxyTraps = {
1432
+ get(target, prop, receiver) {
1433
+ if (target instanceof IDBTransaction) {
1434
+ // Special handling for transaction.done.
1435
+ if (prop === 'done') return transactionDoneMap.get(target);
1436
+ // Make tx.store return the only store in the transaction, or undefined if there are many.
1437
+ if (prop === 'store') {
1438
+ return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
1439
+ }
1440
+ }
1441
+ // Else transform whatever we get back.
1442
+ return wrap(target[prop]);
1443
+ },
1444
+ set(target, prop, value) {
1445
+ target[prop] = value;
1446
+ return true;
1447
+ },
1448
+ has(target, prop) {
1449
+ if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
1450
+ return true;
1451
+ }
1452
+ return prop in target;
1333
1453
  }
1334
- const replacer = (match, rest) => {
1335
- return placeholders[rest];
1336
- };
1337
- return key.replaceAll(RE_PLACEHOLDER, replacer);
1338
1454
  };
1455
+ function replaceTraps(callback) {
1456
+ idbProxyTraps = callback(idbProxyTraps);
1457
+ }
1458
+ function wrapFunction(func) {
1459
+ // Due to expected object equality (which is enforced by the caching in `wrap`), we
1460
+ // only create one new func per func.
1461
+ // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
1462
+ // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
1463
+ // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
1464
+ // with real promises, so each advance methods returns a new promise for the cursor object, or
1465
+ // undefined if the end of the cursor has been reached.
1466
+ if (getCursorAdvanceMethods().includes(func)) {
1467
+ return function (...args) {
1468
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
1469
+ // the original object.
1470
+ func.apply(unwrap(this), args);
1471
+ return wrap(this.request);
1472
+ };
1473
+ }
1474
+ return function (...args) {
1475
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
1476
+ // the original object.
1477
+ return wrap(func.apply(unwrap(this), args));
1478
+ };
1479
+ }
1480
+ function transformCachableValue(value) {
1481
+ if (typeof value === 'function') return wrapFunction(value);
1482
+ // This doesn't return, it just creates a 'done' promise for the transaction,
1483
+ // which is later returned for transaction.done (see idbObjectHandler).
1484
+ if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
1485
+ if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
1486
+ // Return the same value back if we're not going to transform it.
1487
+ return value;
1488
+ }
1489
+ function wrap(value) {
1490
+ // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
1491
+ // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
1492
+ if (value instanceof IDBRequest) return promisifyRequest(value);
1493
+ // If we've already transformed this value before, reuse the transformed value.
1494
+ // This is faster, but it also provides object equality.
1495
+ if (transformCache.has(value)) return transformCache.get(value);
1496
+ const newValue = transformCachableValue(value);
1497
+ // Not all types are transformed.
1498
+ // These may be primitive types, so they can't be WeakMap keys.
1499
+ if (newValue !== value) {
1500
+ transformCache.set(value, newValue);
1501
+ reverseTransformCache.set(newValue, value);
1502
+ }
1503
+ return newValue;
1504
+ }
1505
+ const unwrap = value => reverseTransformCache.get(value);
1339
1506
 
1340
1507
  /**
1341
- * @enum {string}
1508
+ * Open a database.
1509
+ *
1510
+ * @param name Name of the database.
1511
+ * @param version Schema version.
1512
+ * @param callbacks Additional callbacks.
1342
1513
  */
1343
- const UiStrings = {
1344
- Files: 'Files',
1345
- GoToFile: 'Go to file',
1346
- NoMatchingColorThemesFound: 'No matching color themes found',
1347
- NoMatchingResults: 'No matching results',
1348
- NoRecentlyOpenedFoldersFound: 'No recently opened folders found',
1349
- NoResults: 'No Results',
1350
- NoSymbolFound: 'No symbol found',
1351
- NoWorkspaceSymbolsFound: 'no workspace symbols found',
1352
- OpenRecent: 'Open Recent',
1353
- SelectColorTheme: 'Select Color Theme',
1354
- SelectToOpen: 'Select to open',
1355
- ShowAndRunCommands: 'Show And Run Commands',
1356
- TypeNameOfCommandToRun: 'Type the name of a command to run.',
1357
- TypeTheNameOfAViewToOpen: 'Type the name of a view, output channel or terminal to open.'
1358
- };
1359
- const noMatchingColorThemesFound = () => {
1360
- return i18nString(UiStrings.NoMatchingColorThemesFound);
1361
- };
1362
- const selectColorTheme = () => {
1363
- return i18nString(UiStrings.SelectColorTheme);
1364
- };
1365
- const typeNameofCommandToRun = () => {
1366
- return i18nString(UiStrings.TypeNameOfCommandToRun);
1367
- };
1368
- const showAndRunCommands = () => {
1369
- return i18nString(UiStrings.ShowAndRunCommands);
1370
- };
1371
- const noMatchingResults = () => {
1372
- return i18nString(UiStrings.NoMatchingResults);
1373
- };
1374
- const files = () => {
1375
- return i18nString(UiStrings.Files);
1376
- };
1377
- const goToFile = () => {
1378
- return i18nString(UiStrings.GoToFile);
1379
- };
1380
- const noResults = () => {
1381
- return i18nString(UiStrings.NoResults);
1382
- };
1383
- const selectToOpen = () => {
1384
- return i18nString(UiStrings.SelectToOpen);
1385
- };
1386
- const openRecent = () => {
1387
- return i18nString(UiStrings.OpenRecent);
1388
- };
1389
- const noRecentlyOpenedFoldersFound = () => {
1390
- return i18nString(UiStrings.NoRecentlyOpenedFoldersFound);
1391
- };
1392
- const noSymbolFound = () => {
1393
- return i18nString(UiStrings.NoSymbolFound);
1394
- };
1395
- const noWorkspaceSymbolsFound = () => {
1396
- return i18nString(UiStrings.NoWorkspaceSymbolsFound);
1397
- };
1398
-
1399
- const state$4 = {
1400
- rpc: undefined
1401
- };
1402
- const invoke$1 = (method, ...params) => {
1403
- const rpc = state$4.rpc;
1404
- // @ts-ignore
1405
- return rpc.invoke(method, ...params);
1406
- };
1407
- const setRpc = rpc => {
1408
- state$4.rpc = rpc;
1409
- };
1410
-
1411
- // TODO this should be in FileSystem module
1412
- const pathBaseName = path => {
1413
- return path.slice(path.lastIndexOf('/') + 1);
1414
- };
1415
-
1416
- // TODO this should be in FileSystem module
1417
- const pathDirName = path => {
1418
- const pathSeparator = '/';
1419
- const index = path.lastIndexOf(pathSeparator);
1420
- if (index === -1) {
1421
- return '';
1514
+ function openDB(name, version, {
1515
+ blocked,
1516
+ upgrade,
1517
+ blocking,
1518
+ terminated
1519
+ } = {}) {
1520
+ const request = indexedDB.open(name, version);
1521
+ const openPromise = wrap(request);
1522
+ if (upgrade) {
1523
+ request.addEventListener('upgradeneeded', event => {
1524
+ upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
1525
+ });
1422
1526
  }
1423
- return path.slice(0, index);
1424
- };
1425
-
1426
- const getRecentlyOpened = () => {
1427
- return invoke$1(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
1428
- };
1429
- const openWorkspaceFolder = uri => {
1430
- return invoke$1(/* Workspace.setPath */'Workspace.setPath', /* path */uri);
1431
- };
1432
- const getPlaceholder$b = () => {
1433
- return selectToOpen();
1434
- };
1435
- const getLabel$5 = () => {
1436
- return openRecent();
1437
- };
1438
- const getHelpEntries$9 = () => {
1439
- return [];
1440
- };
1441
- const getNoResults$a = () => {
1442
- return {
1443
- label: noRecentlyOpenedFoldersFound()
1444
- };
1445
- };
1446
-
1447
- // TODO could also change api so that getPicks returns an array of anything
1448
- // and the transformPick gets the label for each pick
1449
- // This would make the code more module since the code for getting the picks
1450
- // would be more independent of the specific data format of the quickpick provider
1451
-
1452
- const getPicks$b = async () => {
1453
- const recentlyOpened = await getRecentlyOpened();
1454
- return recentlyOpened;
1455
- };
1456
-
1457
- // TODO selectPick should be independent of show/hide
1458
- const selectPick$b = async pick => {
1459
- const path = pick;
1460
- await openWorkspaceFolder(path);
1461
- return {
1462
- command: Hide
1463
- };
1464
- };
1465
- const getFilterValue$a = value => {
1466
- return pathBaseName(value);
1467
- };
1468
- const getPickFilterValue$6 = pick => {
1469
- return pathBaseName(pick);
1470
- };
1471
- const getPickLabel$5 = pick => {
1472
- return pathBaseName(pick);
1473
- };
1474
- const getPickDescription$3 = pick => {
1475
- return pathDirName(pick);
1476
- };
1477
- const getPickIcon$5 = () => {
1478
- return '';
1479
- };
1480
- const getPickFileIcon$2 = () => {
1481
- return getFolderIcon();
1482
- };
1483
-
1484
- const QuickPickEntriesOpenRecent = {
1485
- __proto__: null,
1486
- getFilterValue: getFilterValue$a,
1487
- getHelpEntries: getHelpEntries$9,
1488
- getLabel: getLabel$5,
1489
- getNoResults: getNoResults$a,
1490
- getPickDescription: getPickDescription$3,
1491
- getPickFileIcon: getPickFileIcon$2,
1492
- getPickFilterValue: getPickFilterValue$6,
1493
- getPickIcon: getPickIcon$5,
1494
- getPickLabel: getPickLabel$5,
1495
- getPicks: getPicks$b,
1496
- getPlaceholder: getPlaceholder$b,
1497
- selectPick: selectPick$b
1498
- };
1499
-
1500
- const CommandPalette = 'quickPick://commandPalette';
1501
- const File$1 = 'quickPick://file';
1502
- const EveryThing = 'quickPick://everything';
1503
- const Number$1 = 'quickPick://number';
1504
- const Recent = 'quickPick://recent';
1505
- const ColorTheme = 'quickPick://color-theme';
1506
- const Symbol$2 = 'quickPick://symbol';
1507
- const View$1 = 'quickPick://view';
1508
- const WorkspaceSymbol$1 = 'quickPick://workspace-symbol';
1509
- const Custom = 'quickPick://custom';
1510
-
1511
- const loadQuickPickEntries = moduleId => {
1512
- switch (moduleId) {
1513
- case Recent:
1514
- return QuickPickEntriesOpenRecent;
1515
- default:
1516
- throw new Error(`unknown module "${moduleId}"`);
1527
+ if (blocked) {
1528
+ request.addEventListener('blocked', event => blocked(
1529
+ // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
1530
+ event.oldVersion, event.newVersion, event));
1531
+ }
1532
+ openPromise.then(db => {
1533
+ if (terminated) db.addEventListener('close', () => terminated());
1534
+ if (blocking) {
1535
+ db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
1536
+ }
1537
+ }).catch(() => {});
1538
+ return openPromise;
1539
+ }
1540
+ const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
1541
+ const writeMethods = ['put', 'add', 'delete', 'clear'];
1542
+ const cachedMethods = new Map();
1543
+ function getMethod(target, prop) {
1544
+ if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
1545
+ return;
1546
+ }
1547
+ if (cachedMethods.get(prop)) return cachedMethods.get(prop);
1548
+ const targetFuncName = prop.replace(/FromIndex$/, '');
1549
+ const useIndex = prop !== targetFuncName;
1550
+ const isWrite = writeMethods.includes(targetFuncName);
1551
+ if (
1552
+ // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
1553
+ !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
1554
+ return;
1555
+ }
1556
+ const method = async function (storeName, ...args) {
1557
+ // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
1558
+ const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
1559
+ let target = tx.store;
1560
+ if (useIndex) target = target.index(args.shift());
1561
+ // Must reject if op rejects.
1562
+ // If it's a write operation, must reject if tx.done rejects.
1563
+ // Must reject with op rejection first.
1564
+ // Must resolve with op value.
1565
+ // Must handle both promises (no unhandled rejections)
1566
+ return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
1567
+ };
1568
+ cachedMethods.set(prop, method);
1569
+ return method;
1570
+ }
1571
+ replaceTraps(oldTraps => ({
1572
+ ...oldTraps,
1573
+ get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
1574
+ has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
1575
+ }));
1576
+ const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
1577
+ const methodMap = {};
1578
+ const advanceResults = new WeakMap();
1579
+ const ittrProxiedCursorToOriginalProxy = new WeakMap();
1580
+ const cursorIteratorTraps = {
1581
+ get(target, prop) {
1582
+ if (!advanceMethodProps.includes(prop)) return target[prop];
1583
+ let cachedFunc = methodMap[prop];
1584
+ if (!cachedFunc) {
1585
+ cachedFunc = methodMap[prop] = function (...args) {
1586
+ advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
1587
+ };
1588
+ }
1589
+ return cachedFunc;
1517
1590
  }
1518
1591
  };
1592
+ async function* iterate(...args) {
1593
+ // tslint:disable-next-line:no-this-assignment
1594
+ let cursor = this;
1595
+ if (!(cursor instanceof IDBCursor)) {
1596
+ cursor = await cursor.openCursor(...args);
1597
+ }
1598
+ if (!cursor) return;
1599
+ cursor = cursor;
1600
+ const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
1601
+ ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
1602
+ // Map this double-proxy back to the original, so other cursor methods work.
1603
+ reverseTransformCache.set(proxiedCursor, unwrap(cursor));
1604
+ while (cursor) {
1605
+ yield proxiedCursor;
1606
+ // If one of the advancing methods was not called, call continue().
1607
+ cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
1608
+ advanceResults.delete(proxiedCursor);
1609
+ }
1610
+ }
1611
+ function isIteratorProp(target, prop) {
1612
+ return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
1613
+ }
1614
+ replaceTraps(oldTraps => ({
1615
+ ...oldTraps,
1616
+ get(target, prop, receiver) {
1617
+ if (isIteratorProp(target, prop)) return iterate;
1618
+ return oldTraps.get(target, prop, receiver);
1619
+ },
1620
+ has(target, prop) {
1621
+ return isIteratorProp(target, prop) || oldTraps.has(target, prop);
1622
+ }
1623
+ }));
1519
1624
 
1520
- const getColorThemeNames = async () => {
1521
- return invoke$1(/* Ajax.getJson */'ColorTheme.getColorThemeNames');
1522
- };
1523
-
1524
- const setColorTheme = id => {
1525
- return invoke$1(/* ColorTheme.setColorTheme */'ColorTheme.setColorTheme', /* colorThemeId */id);
1526
- };
1527
- const getPlaceholder$a = () => {
1528
- return selectColorTheme();
1529
- };
1530
- const getLabel$4 = () => {
1531
- return selectColorTheme();
1532
- };
1533
- const getPicks$a = async searchValue => {
1534
- const colorThemeNames = await getColorThemeNames();
1535
- return colorThemeNames;
1536
- };
1537
- const selectPick$a = async pick => {
1538
- await setColorTheme(/* colorThemeId */pick);
1539
- return {
1540
- command: Hide
1541
- };
1542
- };
1543
- const focusPick = async pick => {
1544
- await setColorTheme(/* colorThemeId */pick);
1545
- };
1546
- const getFilterValue$9 = value => {
1547
- return value;
1548
- };
1549
- const getNoResults$9 = () => {
1550
- return {
1551
- label: noMatchingColorThemesFound()
1552
- };
1553
- };
1554
- const getPickFilterValue$5 = pick => {
1555
- return pick;
1556
- };
1557
- const getPickLabel$4 = pick => {
1558
- return pick;
1559
- };
1560
- const getPickIcon$4 = pick => {
1561
- return '';
1562
- };
1563
-
1564
- const QuickPickEntriesColorTheme = {
1565
- __proto__: null,
1566
- focusPick,
1567
- getFilterValue: getFilterValue$9,
1568
- getLabel: getLabel$4,
1569
- getNoResults: getNoResults$9,
1570
- getPickFilterValue: getPickFilterValue$5,
1571
- getPickIcon: getPickIcon$4,
1572
- getPickLabel: getPickLabel$4,
1573
- getPicks: getPicks$a,
1574
- getPlaceholder: getPlaceholder$a,
1575
- selectPick: selectPick$a,
1576
- setColorTheme
1577
- };
1578
-
1579
- const Tag$1 = 'Tag';
1580
- const Cloud$1 = 'Cloud';
1581
- const SourceControl$1 = 'SourceControl';
1582
- const None$1 = '';
1625
+ const state$2 = {
1626
+ dbVersion: 1};
1583
1627
 
1584
- const SourceControl = 1;
1585
- const Cloud = 2;
1586
- const Tag = 3;
1628
+ // TODO high memory usage in idb because of transactionDoneMap
1587
1629
 
1588
- const name$8 = 'custom';
1589
- const state$3 = {
1590
- args: []
1591
- };
1592
- const setArgs = args => {
1593
- state$3.args = args;
1594
- };
1595
- const getPlaceholder$9 = () => {
1596
- return '';
1630
+ const getHandleDb = async () => {
1631
+ // @ts-ignore
1632
+ const db = await openDB('handle', state$2.dbVersion, {
1633
+ async upgrade(db) {
1634
+ if (!db.objectStoreNames.contains('file-handles-store')) {
1635
+ await db.createObjectStore('file-handles-store', {});
1636
+ }
1637
+ }
1638
+ });
1639
+ return db;
1597
1640
  };
1598
- const getLabel$3 = () => {
1599
- return 'Custom';
1641
+ const getHandle$1 = async uri => {
1642
+ const handleDb = await getHandleDb();
1643
+ const handle = await handleDb.get('file-handles-store', uri);
1644
+ return handle;
1600
1645
  };
1601
1646
 
1602
- // TODO help entries should not be here
1603
- const getHelpEntries$8 = () => {
1604
- return [];
1605
- };
1606
- const getNoResults$8 = () => {
1607
- return {
1608
- label: noMatchingResults()
1609
- };
1610
- };
1611
- const getPicks$9 = async searchValue => {
1612
- const items = state$3.args[1] || [];
1613
- return items;
1614
- };
1615
- const selectPick$9 = async pick => {
1616
- const {
1617
- args
1618
- } = state$3;
1619
- const resolve = args[2];
1620
- resolve(pick);
1621
- return {
1622
- command: Hide
1623
- };
1624
- };
1625
- const getFilterValue$8 = value => {
1626
- return value;
1627
- };
1628
- const getPickFilterValue$4 = pick => {
1629
- return pick;
1630
- };
1631
- const getPickLabel$3 = pick => {
1632
- return pick.label;
1647
+ const getHandle = async uri => {
1648
+ try {
1649
+ // TODO retrieve handle from state or from indexeddb
1650
+ // TODO if not found, throw error
1651
+ const handle = await getHandle$1(uri);
1652
+ return handle;
1653
+ } catch (error) {
1654
+ throw new VError(error, 'Failed to get handle');
1655
+ }
1633
1656
  };
1634
- const getPickDescription$2 = pick => {
1635
- return pick.description || '';
1657
+
1658
+ const getDirectoryHandle = async uri => {
1659
+ const handle = await getHandle(uri);
1660
+ if (handle) {
1661
+ return handle;
1662
+ }
1663
+ const dirname$1 = dirname('/', uri);
1664
+ if (uri === dirname$1) {
1665
+ return undefined;
1666
+ }
1667
+ return getDirectoryHandle(dirname$1);
1636
1668
  };
1637
- const convertIcon = icon => {
1638
- switch (icon) {
1639
- case SourceControl:
1640
- return SourceControl$1;
1641
- case Cloud:
1642
- return Cloud$1;
1643
- case Tag:
1644
- return Tag$1;
1645
- default:
1646
- return None$1;
1669
+ const toIgnore = ['.git', 'node_modules', 'dist', 'dist2'];
1670
+ const searchFilesRecursively = async (all, parent, handle) => {
1671
+ const childHandles = await getChildHandles(handle);
1672
+ const promises = [];
1673
+ for (const childHandle of childHandles) {
1674
+ if (toIgnore.includes(childHandle.name)) {
1675
+ continue;
1676
+ }
1677
+ const absolutePath = parent + '/' + childHandle.name;
1678
+ switch (childHandle.kind) {
1679
+ case Directory:
1680
+ promises.push(searchFilesRecursively(all, absolutePath, childHandle));
1681
+ break;
1682
+ case File$1:
1683
+ all.push(absolutePath);
1684
+ break;
1685
+ }
1647
1686
  }
1687
+ await Promise.all(promises);
1648
1688
  };
1649
- const getPickIcon$3 = pick => {
1650
- return convertIcon(pick.icon);
1689
+ const searchFile$2 = async uri => {
1690
+ const path = uri.slice('html://'.length);
1691
+ const handle = await getDirectoryHandle(path);
1692
+ if (!handle) {
1693
+ // @ts-ignore
1694
+ throw new VError(`Folder not found ${uri}`);
1695
+ }
1696
+ const all = [];
1697
+ await searchFilesRecursively(all, '', handle);
1698
+ return all;
1651
1699
  };
1652
1700
 
1653
- const QuickPickEntriesCustom = {
1701
+ const SearchFileHtml = {
1654
1702
  __proto__: null,
1655
- getFilterValue: getFilterValue$8,
1656
- getHelpEntries: getHelpEntries$8,
1657
- getLabel: getLabel$3,
1658
- getNoResults: getNoResults$8,
1659
- getPickDescription: getPickDescription$2,
1660
- getPickFilterValue: getPickFilterValue$4,
1661
- getPickIcon: getPickIcon$3,
1662
- getPickLabel: getPickLabel$3,
1663
- getPicks: getPicks$9,
1664
- getPlaceholder: getPlaceholder$9,
1665
- name: name$8,
1666
- selectPick: selectPick$9,
1667
- setArgs,
1668
- state: state$3
1669
- };
1670
-
1671
- const handleError = async (error, notify = true, prefix = '') => {
1672
- console.error(error);
1673
- };
1674
- const showErrorDialog = async () => {};
1675
- const warn = (...args) => {
1676
- console.warn(...args);
1703
+ searchFile: searchFile$2
1677
1704
  };
1678
1705
 
1679
- const state$2 = {
1680
- menuEntries: []
1681
- };
1682
- const getAll = () => {
1683
- return state$2.menuEntries;
1684
- };
1706
+ const emptyMatches = [];
1685
1707
 
1686
- const name$7 = 'command';
1687
- const getPlaceholder$8 = () => {
1688
- return typeNameofCommandToRun();
1689
- };
1690
- const helpEntries = () => {
1691
- return [{
1692
- description: showAndRunCommands(),
1693
- category: 'global commands'
1694
- }];
1695
- };
1696
- const getLabel$2 = () => {
1697
- return '';
1698
- };
1699
- const getNoResults$7 = () => {
1708
+ const convertToPick = item => {
1700
1709
  return {
1701
- label: noMatchingResults()
1710
+ pick: item,
1711
+ matches: emptyMatches
1702
1712
  };
1703
1713
  };
1704
1714
 
1705
- // TODO combine Ajax with cache (specify strategy: cacheFirst, networkFirst)
1706
- const getBuiltinPicks = async () => {
1707
- const builtinPicks = getAll();
1708
- return builtinPicks;
1715
+ const Diagonal = 1;
1716
+ const Left = 2;
1717
+
1718
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1719
+
1720
+ const createTable = size => {
1721
+ const table = [];
1722
+ for (let i = 0; i < size; i++) {
1723
+ const row = new Uint8Array(size);
1724
+ table.push(row);
1725
+ }
1726
+ return table;
1709
1727
  };
1710
- const prefixIdWithExt = item => {
1711
- if (!item.label) {
1712
- warn('[QuickPick] item has missing label', item);
1728
+ const EmptyMatches = [];
1729
+ const Dash = '-';
1730
+ const Dot = '.';
1731
+ const EmptyString = '';
1732
+ const Space = ' ';
1733
+ const Underline = '_';
1734
+ const T = 't';
1735
+ const isLowerCase = char => {
1736
+ return char === char.toLowerCase();
1737
+ };
1738
+ const isUpperCase = char => {
1739
+ return char === char.toUpperCase();
1740
+ };
1741
+
1742
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1743
+ const isGap = (columnCharBefore, columnChar) => {
1744
+ switch (columnCharBefore) {
1745
+ case Dash:
1746
+ case Underline:
1747
+ case EmptyString:
1748
+ case T:
1749
+ case Space:
1750
+ case Dot:
1751
+ return true;
1713
1752
  }
1714
- if (!item.id) {
1715
- warn('[QuickPick] item has missing id', item);
1753
+ if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
1754
+ return true;
1716
1755
  }
1717
- return {
1718
- ...item,
1719
- id: `ext.${item.id}`,
1720
- label: item.label || item.id
1721
- };
1756
+ return false;
1722
1757
  };
1723
- const getExtensionPicks = async () => {
1724
- try {
1725
- // TODO don't call this every time
1726
- const extensionPicks = await invoke$1('ExtensionHostCommands.getCommands');
1727
- if (!extensionPicks) {
1728
- return [];
1758
+
1759
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1760
+ const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch) => {
1761
+ if (rowCharLow !== columnCharLow) {
1762
+ return -1;
1763
+ }
1764
+ const isMatch = rowChar === columnChar;
1765
+ if (isMatch) {
1766
+ if (isDiagonalMatch) {
1767
+ return 8;
1729
1768
  }
1730
- const mappedPicks = extensionPicks.map(prefixIdWithExt);
1731
- return mappedPicks;
1732
- } catch (error) {
1733
- console.error(`Failed to get extension picks: ${error}`);
1734
- return [];
1769
+ if (isGap(columnCharBefore, columnChar)) {
1770
+ return 8;
1771
+ }
1772
+ return 5;
1735
1773
  }
1774
+ if (isGap(columnCharBefore, columnChar)) {
1775
+ return 8;
1776
+ }
1777
+ return 5;
1736
1778
  };
1737
1779
 
1738
- // TODO send strings to renderer process only once for next occurrence send uint16array of ids of strings
1780
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1739
1781
 
1740
- const getPicks$8 = async () => {
1741
- const builtinPicks = await getBuiltinPicks();
1742
- const extensionPicks = await getExtensionPicks();
1743
- return [...builtinPicks, ...extensionPicks];
1744
- };
1745
- const shouldHide = item => {
1746
- if (item.id === 'Viewlet.openWidget' && item.args[0] === 'QuickPick') {
1747
- return false;
1782
+ const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
1783
+ while (patternPos < patternLen && wordPos < wordLen) {
1784
+ if (patternLow[patternPos] === wordLow[wordPos]) {
1785
+ patternPos += 1;
1786
+ }
1787
+ wordPos += 1;
1748
1788
  }
1749
- return true;
1789
+ return patternPos === patternLen; // pattern must be exhausted
1750
1790
  };
1751
- const selectPickBuiltin = async item => {
1752
- const args = item.args || [];
1753
- // TODO ids should be all numbers for efficiency -> also directly can call command
1754
- await invoke$1(item.id, ...args);
1755
- if (shouldHide(item)) {
1756
- return {
1757
- command: Hide
1758
- };
1791
+
1792
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1793
+ const traceHighlights = (table, arrows, patternLength, wordLength) => {
1794
+ let row = patternLength;
1795
+ let column = wordLength;
1796
+ const matches = [];
1797
+ while (row >= 1 && column >= 1) {
1798
+ const arrow = arrows[row][column];
1799
+ if (arrow === Left) {
1800
+ column--;
1801
+ } else if (arrow === Diagonal) {
1802
+ row--;
1803
+ column--;
1804
+ const start = column + 1;
1805
+ while (row >= 1 && column >= 1) {
1806
+ const arrow = arrows[row][column];
1807
+ if (arrow === Left) {
1808
+ break;
1809
+ }
1810
+ if (arrow === Diagonal) {
1811
+ row--;
1812
+ column--;
1813
+ }
1814
+ }
1815
+ const end = column;
1816
+ matches.unshift(end, start);
1817
+ }
1759
1818
  }
1760
- return {
1761
- command: KeepOpen
1762
- };
1819
+ matches.unshift(table[patternLength][wordLength - 1]);
1820
+ return matches;
1763
1821
  };
1764
- const selectPickExtension = async item => {
1765
- const id = item.id.slice(4); // TODO lots of string allocation with 'ext.' find a better way to separate builtin commands from extension commands
1766
- try {
1767
- await invoke$1('ExtensionHostCommands.executeCommand', id);
1768
- } catch (error) {
1769
- await handleError(error, false);
1770
- // @ts-ignore
1771
- await showErrorDialog();
1822
+
1823
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1824
+ const gridSize = 128;
1825
+ const table = createTable(gridSize);
1826
+ const arrows = createTable(gridSize);
1827
+ const fuzzySearch = (pattern, word) => {
1828
+ const patternLength = Math.min(pattern.length, gridSize - 1);
1829
+ const wordLength = Math.min(word.length, gridSize - 1);
1830
+ const patternLower = pattern.toLowerCase();
1831
+ const wordLower = word.toLowerCase();
1832
+ if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
1833
+ return EmptyMatches;
1772
1834
  }
1773
- return {
1774
- command: Hide
1775
- };
1776
- };
1777
- const selectPick$8 = async item => {
1778
- if (item.id.startsWith('ext.')) {
1779
- return selectPickExtension(item);
1835
+ let strongMatch = false;
1836
+ for (let row = 1; row < patternLength + 1; row++) {
1837
+ const rowChar = pattern[row - 1];
1838
+ const rowCharLow = patternLower[row - 1];
1839
+ for (let column = 1; column < wordLength + 1; column++) {
1840
+ const columnChar = word[column - 1];
1841
+ const columnCharLow = wordLower[column - 1];
1842
+ const columnCharBefore = word[column - 2] || '';
1843
+ const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
1844
+ const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch);
1845
+ if (row === 1 && score > 5) {
1846
+ strongMatch = true;
1847
+ }
1848
+ let diagonalScore = score + table[row - 1][column - 1];
1849
+ if (isDiagonalMatch && score !== -1) {
1850
+ diagonalScore += 2;
1851
+ }
1852
+ const leftScore = table[row][column - 1];
1853
+ if (leftScore > diagonalScore) {
1854
+ table[row][column] = leftScore;
1855
+ arrows[row][column] = Left;
1856
+ } else {
1857
+ table[row][column] = diagonalScore;
1858
+ arrows[row][column] = Diagonal;
1859
+ }
1860
+ }
1780
1861
  }
1781
- return selectPickBuiltin(item);
1782
- };
1783
- const getFilterValue$7 = value => {
1784
- return value;
1785
- };
1786
- const getPickFilterValue$3 = pick => {
1787
- return pick.label;
1788
- };
1789
- const getPickLabel$2 = pick => {
1790
- return pick.label;
1791
- };
1792
- const getPickIcon$2 = () => {
1793
- return '';
1862
+ if (!strongMatch) {
1863
+ return EmptyMatches;
1864
+ }
1865
+ const highlights = traceHighlights(table, arrows, patternLength, wordLength);
1866
+ return highlights;
1794
1867
  };
1795
1868
 
1796
- const QuickPickEntriesCommand = {
1797
- __proto__: null,
1798
- getFilterValue: getFilterValue$7,
1799
- getLabel: getLabel$2,
1800
- getNoResults: getNoResults$7,
1801
- getPickFilterValue: getPickFilterValue$3,
1802
- getPickIcon: getPickIcon$2,
1803
- getPickLabel: getPickLabel$2,
1804
- getPicks: getPicks$8,
1805
- getPlaceholder: getPlaceholder$8,
1806
- helpEntries,
1807
- name: name$7,
1808
- selectPick: selectPick$8
1869
+ const filterQuickPickItem = (pattern, word) => {
1870
+ const matches = fuzzySearch(pattern, word);
1871
+ return matches;
1809
1872
  };
1810
1873
 
1811
- const execute = async (method, ...params) => {
1812
- // TODO
1874
+ const getBaseName = path => {
1875
+ return path.slice(path.lastIndexOf('/') + 1);
1813
1876
  };
1814
1877
 
1815
- const RE_PROTOCOL = /^([a-z-]+):\/\//;
1816
- const getProtocol = uri => {
1817
- const protocolMatch = uri.match(RE_PROTOCOL);
1818
- if (protocolMatch) {
1819
- return protocolMatch[1];
1878
+ const filterQuickPickItems = (items, value) => {
1879
+ if (!value) {
1880
+ return items.map(convertToPick);
1820
1881
  }
1821
- return '';
1882
+ const results = [];
1883
+ for (const item of items) {
1884
+ const baseName = getBaseName(item);
1885
+ const matches = filterQuickPickItem(value, baseName);
1886
+ if (matches.length > 0) {
1887
+ results.push({
1888
+ pick: item,
1889
+ matches
1890
+ });
1891
+ }
1892
+ }
1893
+ return results;
1822
1894
  };
1823
1895
 
1824
- const Memfs = 'memfs';
1825
- const Html = 'html';
1826
- const Fetch = 'fetch';
1827
-
1828
- const searchFile$4 = async () => {
1829
- const files = await getFiles();
1830
- const keys = Object.keys(files);
1831
- return keys;
1896
+ const getFileSearchRipGrepArgs = () => {
1897
+ const ripGrepArgs = ['--files', '--sort-files'];
1898
+ return ripGrepArgs;
1832
1899
  };
1833
1900
 
1834
- const SearchFileMemfs = {
1835
- __proto__: null,
1836
- searchFile: searchFile$4
1901
+ const invoke = (method, ...params) => {
1902
+ return invoke$1('SearchProcess.invoke', method, ...params);
1837
1903
  };
1838
1904
 
1839
- const removeLeadingSlash = path => {
1840
- if (path.startsWith('/')) {
1841
- return path.slice(1);
1905
+ const splitLines = lines => {
1906
+ if (!lines) {
1907
+ return [];
1842
1908
  }
1843
- return path;
1909
+ return lines.split('\n');
1844
1910
  };
1845
1911
 
1846
- // TODO simplify code
1847
- // 1. don't have playground prefix in fileMap json
1848
- // 2. remove code here that removes the prefix
1849
- const searchFile$3 = async path => {
1850
- const fileList = await getJson(fileMapUrl);
1851
- const result = fileList.map(removeLeadingSlash);
1852
- const prefixLength = path.length - 'file:///'.length;
1853
- const final = [];
1854
- for (const item of result) {
1855
- final.push(item.slice(prefixLength));
1912
+ // TODO create direct connection from electron to file search worker using message ports
1913
+
1914
+ const searchFile$1 = async (path, value, prepare) => {
1915
+ const ripGrepArgs = getFileSearchRipGrepArgs();
1916
+ const options = {
1917
+ ripGrepArgs,
1918
+ searchPath: path,
1919
+ limit: 9_999_999
1920
+ };
1921
+ const stdout = await invoke('SearchFile.searchFile', options);
1922
+ const lines = splitLines(stdout);
1923
+ if (!prepare) {
1924
+ return lines;
1856
1925
  }
1857
- return final;
1926
+ const filtered = filterQuickPickItems(lines, value);
1927
+ return filtered;
1858
1928
  };
1859
1929
 
1860
- const SearchFileFetch = {
1930
+ const SearchFileRipGrep = {
1861
1931
  __proto__: null,
1862
- searchFile: searchFile$3
1932
+ searchFile: searchFile$1
1863
1933
  };
1864
1934
 
1865
- const Directory = 'directory';
1866
- const File = 'file';
1935
+ const getModule = protocol => {
1936
+ switch (protocol) {
1937
+ case Memfs:
1938
+ return SearchFileMemfs;
1939
+ case Fetch:
1940
+ return SearchFileFetch;
1941
+ case Html:
1942
+ return SearchFileHtml;
1943
+ default:
1944
+ return SearchFileRipGrep;
1945
+ }
1946
+ };
1947
+ const searchFile = async (path, value, prepare, assetDir) => {
1948
+ const protocol = getProtocol(path);
1949
+ // TODO call different providers depending on protocol
1950
+ const module = await getModule(protocol);
1951
+ const result = await module.searchFile(path, value, prepare, assetDir);
1952
+ return result;
1953
+ };
1867
1954
 
1868
- // based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
1955
+ // TODO this should be in FileSystem module
1956
+ const pathBaseName = path => {
1957
+ return path.slice(path.lastIndexOf('/') + 1);
1958
+ };
1869
1959
 
1870
- const fromAsync = async asyncIterable => {
1871
- const children = [];
1872
- for await (const value of asyncIterable) {
1873
- children.push(value);
1960
+ // TODO this should be in FileSystem module
1961
+ const pathDirName = path => {
1962
+ const pathSeparator = '/';
1963
+ const index = path.lastIndexOf(pathSeparator);
1964
+ if (index === -1) {
1965
+ return '';
1874
1966
  }
1875
- return children;
1967
+ return path.slice(0, index);
1876
1968
  };
1877
1969
 
1878
- /**
1879
- * Do not use directly, use FileSystemHtml.getChildHandles
1880
- * instead which prompts for the required permission to
1881
- * retrieve the child handles
1882
- *
1883
- */
1884
-
1885
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
1886
- const getChildHandles = async handle => {
1887
- // @ts-ignore
1888
- const handles = await fromAsync(handle.values());
1889
- return handles;
1970
+ const name$7 = 'file';
1971
+ const getPlaceholder$a = () => {
1972
+ return '';
1973
+ };
1974
+ const getLabel$4 = () => {
1975
+ return files();
1890
1976
  };
1891
1977
 
1892
- const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
1893
- let idbProxyableTypes;
1894
- let cursorAdvanceMethods;
1895
- // This is a function to prevent it throwing up in node environments.
1896
- function getIdbProxyableTypes() {
1897
- return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
1898
- }
1899
- // This is a function to prevent it throwing up in node environments.
1900
- function getCursorAdvanceMethods() {
1901
- return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
1902
- }
1903
- const transactionDoneMap = new WeakMap();
1904
- const transformCache = new WeakMap();
1905
- const reverseTransformCache = new WeakMap();
1906
- function promisifyRequest(request) {
1907
- const promise = new Promise((resolve, reject) => {
1908
- const unlisten = () => {
1909
- request.removeEventListener('success', success);
1910
- request.removeEventListener('error', error);
1911
- };
1912
- const success = () => {
1913
- resolve(wrap(request.result));
1914
- unlisten();
1915
- };
1916
- const error = () => {
1917
- reject(request.error);
1918
- unlisten();
1919
- };
1920
- request.addEventListener('success', success);
1921
- request.addEventListener('error', error);
1922
- });
1923
- // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
1924
- // is because we create many promises from a single IDBRequest.
1925
- reverseTransformCache.set(promise, request);
1926
- return promise;
1927
- }
1928
- function cacheDonePromiseForTransaction(tx) {
1929
- // Early bail if we've already created a done promise for this transaction.
1930
- if (transactionDoneMap.has(tx)) return;
1931
- const done = new Promise((resolve, reject) => {
1932
- const unlisten = () => {
1933
- tx.removeEventListener('complete', complete);
1934
- tx.removeEventListener('error', error);
1935
- tx.removeEventListener('abort', error);
1936
- };
1937
- const complete = () => {
1938
- resolve();
1939
- unlisten();
1940
- };
1941
- const error = () => {
1942
- reject(tx.error || new DOMException('AbortError', 'AbortError'));
1943
- unlisten();
1944
- };
1945
- tx.addEventListener('complete', complete);
1946
- tx.addEventListener('error', error);
1947
- tx.addEventListener('abort', error);
1948
- });
1949
- // Cache it for later retrieval.
1950
- transactionDoneMap.set(tx, done);
1951
- }
1952
- let idbProxyTraps = {
1953
- get(target, prop, receiver) {
1954
- if (target instanceof IDBTransaction) {
1955
- // Special handling for transaction.done.
1956
- if (prop === 'done') return transactionDoneMap.get(target);
1957
- // Make tx.store return the only store in the transaction, or undefined if there are many.
1958
- if (prop === 'store') {
1959
- return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
1960
- }
1961
- }
1962
- // Else transform whatever we get back.
1963
- return wrap(target[prop]);
1964
- },
1965
- set(target, prop, value) {
1966
- target[prop] = value;
1967
- return true;
1968
- },
1969
- has(target, prop) {
1970
- if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
1971
- return true;
1972
- }
1973
- return prop in target;
1974
- }
1978
+ // TODO help entries should not be here
1979
+ const getHelpEntries$9 = () => {
1980
+ return [{
1981
+ description: goToFile(),
1982
+ category: 'global commands'
1983
+ }];
1975
1984
  };
1976
- function replaceTraps(callback) {
1977
- idbProxyTraps = callback(idbProxyTraps);
1978
- }
1979
- function wrapFunction(func) {
1980
- // Due to expected object equality (which is enforced by the caching in `wrap`), we
1981
- // only create one new func per func.
1982
- // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
1983
- // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
1984
- // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
1985
- // with real promises, so each advance methods returns a new promise for the cursor object, or
1986
- // undefined if the end of the cursor has been reached.
1987
- if (getCursorAdvanceMethods().includes(func)) {
1988
- return function (...args) {
1989
- // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
1990
- // the original object.
1991
- func.apply(unwrap(this), args);
1992
- return wrap(this.request);
1993
- };
1994
- }
1995
- return function (...args) {
1996
- // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
1997
- // the original object.
1998
- return wrap(func.apply(unwrap(this), args));
1985
+ const getNoResults$9 = () => {
1986
+ return {
1987
+ label: noMatchingResults()
1999
1988
  };
2000
- }
2001
- function transformCachableValue(value) {
2002
- if (typeof value === 'function') return wrapFunction(value);
2003
- // This doesn't return, it just creates a 'done' promise for the transaction,
2004
- // which is later returned for transaction.done (see idbObjectHandler).
2005
- if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
2006
- if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
2007
- // Return the same value back if we're not going to transform it.
2008
- return value;
2009
- }
2010
- function wrap(value) {
2011
- // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
2012
- // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
2013
- if (value instanceof IDBRequest) return promisifyRequest(value);
2014
- // If we've already transformed this value before, reuse the transformed value.
2015
- // This is faster, but it also provides object equality.
2016
- if (transformCache.has(value)) return transformCache.get(value);
2017
- const newValue = transformCachableValue(value);
2018
- // Not all types are transformed.
2019
- // These may be primitive types, so they can't be WeakMap keys.
2020
- if (newValue !== value) {
2021
- transformCache.set(value, newValue);
2022
- reverseTransformCache.set(newValue, value);
2023
- }
2024
- return newValue;
2025
- }
2026
- const unwrap = value => reverseTransformCache.get(value);
2027
-
2028
- /**
2029
- * Open a database.
2030
- *
2031
- * @param name Name of the database.
2032
- * @param version Schema version.
2033
- * @param callbacks Additional callbacks.
2034
- */
2035
- function openDB(name, version, {
2036
- blocked,
2037
- upgrade,
2038
- blocking,
2039
- terminated
2040
- } = {}) {
2041
- const request = indexedDB.open(name, version);
2042
- const openPromise = wrap(request);
2043
- if (upgrade) {
2044
- request.addEventListener('upgradeneeded', event => {
2045
- upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
2046
- });
2047
- }
2048
- if (blocked) {
2049
- request.addEventListener('blocked', event => blocked(
2050
- // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
2051
- event.oldVersion, event.newVersion, event));
2052
- }
2053
- openPromise.then(db => {
2054
- if (terminated) db.addEventListener('close', () => terminated());
2055
- if (blocking) {
2056
- db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
2057
- }
2058
- }).catch(() => {});
2059
- return openPromise;
2060
- }
2061
- const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
2062
- const writeMethods = ['put', 'add', 'delete', 'clear'];
2063
- const cachedMethods = new Map();
2064
- function getMethod(target, prop) {
2065
- if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
2066
- return;
1989
+ };
1990
+ const getPicks$a = async searchValue => {
1991
+ {
1992
+ return [];
2067
1993
  }
2068
- if (cachedMethods.get(prop)) return cachedMethods.get(prop);
2069
- const targetFuncName = prop.replace(/FromIndex$/, '');
2070
- const useIndex = prop !== targetFuncName;
2071
- const isWrite = writeMethods.includes(targetFuncName);
2072
- if (
2073
- // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
2074
- !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
2075
- return;
1994
+ };
1995
+ const selectPick$a = async pick => {
1996
+ if (typeof pick === 'object') {
1997
+ pick = pick.pick;
2076
1998
  }
2077
- const method = async function (storeName, ...args) {
2078
- // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
2079
- const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
2080
- let target = tx.store;
2081
- if (useIndex) target = target.index(args.shift());
2082
- // Must reject if op rejects.
2083
- // If it's a write operation, must reject if tx.done rejects.
2084
- // Must reject with op rejection first.
2085
- // Must resolve with op value.
2086
- // Must handle both promises (no unhandled rejections)
2087
- return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
1999
+ const workspace = '';
2000
+ const absolutePath = `${workspace}/${pick}`;
2001
+ await execute(/* Main.openUri */'Main.openUri', /* uri */absolutePath);
2002
+ return {
2003
+ command: Hide
2088
2004
  };
2089
- cachedMethods.set(prop, method);
2090
- return method;
2091
- }
2092
- replaceTraps(oldTraps => ({
2093
- ...oldTraps,
2094
- get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
2095
- has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
2096
- }));
2097
- const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
2098
- const methodMap = {};
2099
- const advanceResults = new WeakMap();
2100
- const ittrProxiedCursorToOriginalProxy = new WeakMap();
2101
- const cursorIteratorTraps = {
2102
- get(target, prop) {
2103
- if (!advanceMethodProps.includes(prop)) return target[prop];
2104
- let cachedFunc = methodMap[prop];
2105
- if (!cachedFunc) {
2106
- cachedFunc = methodMap[prop] = function (...args) {
2107
- advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
2108
- };
2109
- }
2110
- return cachedFunc;
2111
- }
2112
2005
  };
2113
- async function* iterate(...args) {
2114
- // tslint:disable-next-line:no-this-assignment
2115
- let cursor = this;
2116
- if (!(cursor instanceof IDBCursor)) {
2117
- cursor = await cursor.openCursor(...args);
2006
+ const getFilterValue$9 = value => {
2007
+ return value;
2008
+ };
2009
+ const getPickFilterValue$5 = pick => {
2010
+ if (typeof pick === 'object') {
2011
+ pick = pick.pick;
2118
2012
  }
2119
- if (!cursor) return;
2120
- cursor = cursor;
2121
- const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
2122
- ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
2123
- // Map this double-proxy back to the original, so other cursor methods work.
2124
- reverseTransformCache.set(proxiedCursor, unwrap(cursor));
2125
- while (cursor) {
2126
- yield proxiedCursor;
2127
- // If one of the advancing methods was not called, call continue().
2128
- cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
2129
- advanceResults.delete(proxiedCursor);
2013
+ return pick;
2014
+ };
2015
+ const getPickLabel$4 = pick => {
2016
+ if (typeof pick === 'object') {
2017
+ pick = pick.pick;
2130
2018
  }
2131
- }
2132
- function isIteratorProp(target, prop) {
2133
- return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
2134
- }
2135
- replaceTraps(oldTraps => ({
2136
- ...oldTraps,
2137
- get(target, prop, receiver) {
2138
- if (isIteratorProp(target, prop)) return iterate;
2139
- return oldTraps.get(target, prop, receiver);
2140
- },
2141
- has(target, prop) {
2142
- return isIteratorProp(target, prop) || oldTraps.has(target, prop);
2019
+ const baseName = pathBaseName(pick);
2020
+ return baseName;
2021
+ };
2022
+ const getPickDescription$4 = pick => {
2023
+ if (typeof pick === 'object') {
2024
+ pick = pick.pick;
2143
2025
  }
2144
- }));
2026
+ const dirName = pathDirName(pick);
2027
+ return dirName;
2028
+ };
2029
+ const getPickIcon$4 = () => {
2030
+ return '';
2031
+ };
2032
+ const getPickFileIcon$2 = pick => {
2033
+ return '';
2034
+ };
2035
+ const isPrepared$1 = () => {
2036
+ const workspace = '';
2037
+ // TODO protocol should always be defined. For files it should use file protocol
2038
+ const protocol = getProtocol(workspace);
2039
+ return !protocol;
2040
+ };
2145
2041
 
2146
- const state$1 = {
2147
- databases: Object.create(null),
2148
- eventId: 0,
2149
- dbVersion: 1,
2150
- cachedDb: undefined
2042
+ const QuickPickEntriesFile = {
2043
+ __proto__: null,
2044
+ getFilterValue: getFilterValue$9,
2045
+ getHelpEntries: getHelpEntries$9,
2046
+ getLabel: getLabel$4,
2047
+ getNoResults: getNoResults$9,
2048
+ getPickDescription: getPickDescription$4,
2049
+ getPickFileIcon: getPickFileIcon$2,
2050
+ getPickFilterValue: getPickFilterValue$5,
2051
+ getPickIcon: getPickIcon$4,
2052
+ getPickLabel: getPickLabel$4,
2053
+ getPicks: getPicks$a,
2054
+ getPlaceholder: getPlaceholder$a,
2055
+ isPrepared: isPrepared$1,
2056
+ name: name$7,
2057
+ selectPick: selectPick$a
2058
+ };
2059
+
2060
+ const name$6 = 'goToLine';
2061
+ const getPlaceholder$9 = () => {
2062
+ return '';
2063
+ };
2064
+ const getHelpEntries$8 = () => {
2065
+ return [];
2066
+ };
2067
+ const getNoResults$8 = () => {
2068
+ return undefined;
2069
+ };
2070
+ const getPicks$9 = async () => {
2071
+ const picks = [{
2072
+ label: '1'
2073
+ }, {
2074
+ label: '2'
2075
+ }, {
2076
+ label: '3'
2077
+ }, {
2078
+ label: '4'
2079
+ }, {
2080
+ label: '5'
2081
+ }, {
2082
+ label: '6'
2083
+ }];
2084
+ return picks;
2085
+ };
2086
+ const selectPick$9 = async item => {
2087
+ const rowIndex = Number.parseInt(item.label);
2088
+ const position = {
2089
+ rowIndex,
2090
+ columnIndex: 5
2091
+ };
2092
+ await execute(/* EditorSetCursor.editorSetCursor */'TODO', /* position */position);
2093
+ // TODO put cursor onto that line
2094
+ return {
2095
+ command: Hide
2096
+ };
2097
+ };
2098
+ const getFilterValue$8 = value => {
2099
+ return value;
2100
+ };
2101
+
2102
+ const QuickPickEntriesGoToLine = {
2103
+ __proto__: null,
2104
+ getFilterValue: getFilterValue$8,
2105
+ getHelpEntries: getHelpEntries$8,
2106
+ getNoResults: getNoResults$8,
2107
+ getPicks: getPicks$9,
2108
+ getPlaceholder: getPlaceholder$9,
2109
+ name: name$6,
2110
+ selectPick: selectPick$9
2111
+ };
2112
+
2113
+ const name$5 = 'noop';
2114
+ const getPlaceholder$8 = () => {
2115
+ return '';
2116
+ };
2117
+ const getHelpEntries$7 = () => {
2118
+ return [];
2119
+ };
2120
+ const getNoResults$7 = () => {
2121
+ return noResults();
2122
+ };
2123
+ const getPicks$8 = async value => {
2124
+ return [];
2125
+ };
2126
+ const selectPick$8 = async item => {
2127
+ return {
2128
+ command: Hide
2129
+ };
2130
+ };
2131
+ const getFilterValue$7 = value => {
2132
+ return value;
2133
+ };
2134
+ const getPickFilterValue$4 = pick => {
2135
+ return pick;
2136
+ };
2137
+
2138
+ const QuickPickNoop = {
2139
+ __proto__: null,
2140
+ getFilterValue: getFilterValue$7,
2141
+ getHelpEntries: getHelpEntries$7,
2142
+ getNoResults: getNoResults$7,
2143
+ getPickFilterValue: getPickFilterValue$4,
2144
+ getPicks: getPicks$8,
2145
+ getPlaceholder: getPlaceholder$8,
2146
+ name: name$5,
2147
+ selectPick: selectPick$8
2148
+ };
2149
+
2150
+ const name$4 = 'symbol';
2151
+ const getPlaceholder$7 = () => {
2152
+ return '';
2153
+ };
2154
+ const getHelpEntries$6 = () => {
2155
+ return [];
2156
+ };
2157
+ const getNoResults$6 = () => {
2158
+ return {
2159
+ label: noSymbolFound()
2160
+ };
2161
+ };
2162
+ const getPicks$7 = async () => {
2163
+ const picks = [];
2164
+ return picks;
2165
+ };
2166
+ const selectPick$7 = async item => {
2167
+ return {
2168
+ command: Hide
2169
+ };
2170
+ };
2171
+ const getFilterValue$6 = value => {
2172
+ return value;
2173
+ };
2174
+
2175
+ const QuickPickEntriesSymbol = {
2176
+ __proto__: null,
2177
+ getFilterValue: getFilterValue$6,
2178
+ getHelpEntries: getHelpEntries$6,
2179
+ getNoResults: getNoResults$6,
2180
+ getPicks: getPicks$7,
2181
+ getPlaceholder: getPlaceholder$7,
2182
+ name: name$4,
2183
+ selectPick: selectPick$7
2184
+ };
2185
+
2186
+ // TODO probably not needed
2187
+
2188
+ const getPlaceholder$6 = () => {
2189
+ return typeNameofCommandToRun();
2190
+ };
2191
+ const getHelpEntries$5 = () => {
2192
+ return undefined;
2193
+ };
2194
+ const getPicks$6 = async () => {
2195
+ // const views = ViewService.getViews()
2196
+ // const picks = views.map(toPick)
2197
+ // return picks
2198
+ return [];
2199
+ };
2200
+ const selectPick$6 = async item => {
2201
+ // Command.execute(/* openView */ 549, /* viewName */ item.label)
2202
+ // return {
2203
+ // command: QuickPickReturnValue.Hide,
2204
+ // }
2205
+ };
2206
+ const getFilterValue$5 = value => {
2207
+ return value;
2151
2208
  };
2152
2209
 
2153
- // TODO high memory usage in idb because of transactionDoneMap
2210
+ const QuickPickEntriesView = {
2211
+ __proto__: null,
2212
+ getFilterValue: getFilterValue$5,
2213
+ getHelpEntries: getHelpEntries$5,
2214
+ getPicks: getPicks$6,
2215
+ getPlaceholder: getPlaceholder$6,
2216
+ selectPick: selectPick$6
2217
+ };
2154
2218
 
2155
- const getHandleDb = async () => {
2156
- // @ts-ignore
2157
- const db = await openDB('handle', state$1.dbVersion, {
2158
- async upgrade(db) {
2159
- if (!db.objectStoreNames.contains('file-handles-store')) {
2160
- await db.createObjectStore('file-handles-store', {});
2161
- }
2162
- }
2163
- });
2164
- return db;
2219
+ const name$3 = 'workspace-symbol';
2220
+ const getPlaceholder$5 = () => {
2221
+ return '';
2165
2222
  };
2166
- const getHandle$1 = async uri => {
2167
- const handleDb = await getHandleDb();
2168
- const handle = await handleDb.get('file-handles-store', uri);
2169
- return handle;
2223
+ const getHelpEntries$4 = () => {
2224
+ return [];
2225
+ };
2226
+ const getNoResults$5 = () => {
2227
+ return {
2228
+ label: noWorkspaceSymbolsFound()
2229
+ };
2230
+ };
2231
+ const getPicks$5 = async () => {
2232
+ const picks = [];
2233
+ return picks;
2234
+ };
2235
+ const selectPick$5 = async item => {
2236
+ return {
2237
+ command: Hide
2238
+ };
2239
+ };
2240
+ const getFilterValue$4 = value => {
2241
+ return value;
2170
2242
  };
2171
2243
 
2172
- const getHandle = async uri => {
2173
- try {
2174
- // TODO retrieve handle from state or from indexeddb
2175
- // TODO if not found, throw error
2176
- const handle = await getHandle$1(uri);
2177
- return handle;
2178
- } catch (error) {
2179
- throw new VError(error, 'Failed to get handle');
2180
- }
2244
+ const QuickPickEntriesWorkspaceSymbol = {
2245
+ __proto__: null,
2246
+ getFilterValue: getFilterValue$4,
2247
+ getHelpEntries: getHelpEntries$4,
2248
+ getNoResults: getNoResults$5,
2249
+ getPicks: getPicks$5,
2250
+ getPlaceholder: getPlaceholder$5,
2251
+ name: name$3,
2252
+ selectPick: selectPick$5
2181
2253
  };
2182
2254
 
2183
- const getDirectoryHandle = async uri => {
2184
- const handle = await getHandle(uri);
2185
- if (handle) {
2186
- return handle;
2255
+ const Command = '>';
2256
+ const Symbol$2 = '@';
2257
+ const WorkspaceSymbol$1 = '#';
2258
+ const GoToLine = ':';
2259
+ const View$1 = 'view ';
2260
+ const None$2 = '';
2261
+
2262
+ // TODO avoid global variable
2263
+
2264
+ const state$1 = {
2265
+ // providerId: PROVIDER_NOOP,
2266
+ provider: QuickPickNoop,
2267
+ prefix: 'string-that-should-never-match-another-string'
2268
+ };
2269
+
2270
+ /**
2271
+ * @type {string}
2272
+ */
2273
+ const name$2 = 'everything';
2274
+ const getPlaceholder$4 = () => {
2275
+ return state$1.provider.getPlaceholder();
2276
+ };
2277
+ const getLabel$3 = () => {
2278
+ return '';
2279
+ };
2280
+ const getHelpEntries$3 = () => {
2281
+ return state$1.provider.getHelpEntries();
2282
+ };
2283
+ const getNoResults$4 = () => {
2284
+ return state$1.provider.getNoResults();
2285
+ };
2286
+ const getPrefix = value => {
2287
+ if (value.startsWith(Command)) {
2288
+ return Command;
2187
2289
  }
2188
- const dirname$1 = dirname('/', uri);
2189
- if (uri === dirname$1) {
2190
- return undefined;
2290
+ if (value.startsWith(Symbol$2)) {
2291
+ return Symbol$2;
2191
2292
  }
2192
- return getDirectoryHandle(dirname$1);
2293
+ if (value.startsWith(WorkspaceSymbol$1)) {
2294
+ return WorkspaceSymbol$1;
2295
+ }
2296
+ if (value.startsWith(GoToLine)) {
2297
+ return GoToLine;
2298
+ }
2299
+ if (value.startsWith(View$1)) {
2300
+ return View$1;
2301
+ }
2302
+ return None$2;
2193
2303
  };
2194
- const toIgnore = ['.git', 'node_modules', 'dist', 'dist2'];
2195
- const searchFilesRecursively = async (all, parent, handle) => {
2196
- const childHandles = await getChildHandles(handle);
2197
- const promises = [];
2198
- for (const childHandle of childHandles) {
2199
- if (toIgnore.includes(childHandle.name)) {
2200
- continue;
2201
- }
2202
- const absolutePath = parent + '/' + childHandle.name;
2203
- switch (childHandle.kind) {
2204
- case Directory:
2205
- promises.push(searchFilesRecursively(all, absolutePath, childHandle));
2206
- break;
2207
- case File:
2208
- all.push(absolutePath);
2209
- break;
2210
- }
2304
+ const getQuickPickProvider = prefix => {
2305
+ // TODO could use enum for prefix
2306
+ // TODO could use regex to extract prefix
2307
+ // TODO or could check first letter char code (less comparisons)
2308
+ switch (prefix) {
2309
+ case Command:
2310
+ return QuickPickEntriesCommand;
2311
+ case Symbol$2:
2312
+ return QuickPickEntriesSymbol;
2313
+ case WorkspaceSymbol$1:
2314
+ return QuickPickEntriesWorkspaceSymbol;
2315
+ case GoToLine:
2316
+ return QuickPickEntriesGoToLine;
2317
+ case View$1:
2318
+ return QuickPickEntriesView;
2319
+ default:
2320
+ return QuickPickEntriesFile;
2211
2321
  }
2212
- await Promise.all(promises);
2213
2322
  };
2214
- const searchFile$2 = async uri => {
2215
- const path = uri.slice('html://'.length);
2216
- const handle = await getDirectoryHandle(path);
2217
- if (!handle) {
2323
+ const getPicks$4 = async value => {
2324
+ const prefix = getPrefix(value);
2325
+ // TODO race condition
2326
+ if (state$1.prefix !== prefix) {
2327
+ state$1.prefix = prefix;
2218
2328
  // @ts-ignore
2219
- throw new VError(`Folder not found ${uri}`);
2329
+ state$1.provider = await getQuickPickProvider(prefix);
2220
2330
  }
2221
- const all = [];
2222
- await searchFilesRecursively(all, '', handle);
2223
- return all;
2331
+ // TODO this line is a bit duplicated with getFilterValue
2332
+ const slicedValue = value.slice(prefix.length);
2333
+ const picks = await state$1.provider.getPicks(slicedValue);
2334
+ return picks;
2224
2335
  };
2225
-
2226
- const SearchFileHtml = {
2227
- __proto__: null,
2228
- searchFile: searchFile$2
2336
+ const selectPick$4 = item => {
2337
+ const {
2338
+ provider
2339
+ } = state$1;
2340
+ return provider.selectPick(item);
2229
2341
  };
2230
-
2231
- const getFileSearchRipGrepArgs = () => {
2232
- const ripGrepArgs = ['--files', '--sort-files'];
2233
- return ripGrepArgs;
2342
+ const openCommandPalette = () => {
2343
+ // show('>')
2234
2344
  };
2235
-
2236
- const invoke = (method, ...params) => {
2237
- return invoke$1('SearchProcess.invoke', method, ...params);
2345
+ const openView = () => {
2346
+ // show('view ')
2238
2347
  };
2239
-
2240
- const splitLines = lines => {
2241
- if (!lines) {
2242
- return [];
2243
- }
2244
- return lines.split('\n');
2348
+ const getFilterValue$3 = value => {
2349
+ return value.slice(state$1.prefix.length);
2245
2350
  };
2246
-
2247
- // TODO create direct connection from electron to file search worker using message ports
2248
-
2249
- const searchFile$1 = async (path, value, prepare) => {
2250
- const ripGrepArgs = getFileSearchRipGrepArgs();
2251
- const options = {
2252
- ripGrepArgs,
2253
- searchPath: path,
2254
- limit: 9_999_999
2255
- };
2256
- const stdout = await invoke('SearchFile.searchFile', options);
2257
- const lines = splitLines(stdout);
2258
- if (!prepare) {
2259
- return lines;
2351
+ const getPickFilterValue$3 = pick => {
2352
+ const {
2353
+ provider
2354
+ } = state$1;
2355
+ return provider.getPickFilterValue(pick);
2356
+ };
2357
+ const getPickDescription$3 = pick => {
2358
+ const {
2359
+ provider
2360
+ } = state$1;
2361
+ // @ts-ignore
2362
+ if (provider.getPickDescription) {
2363
+ // @ts-ignore
2364
+ return provider.getPickDescription(pick);
2260
2365
  }
2261
- const filtered = filterQuickPickItems(lines, value);
2262
- return filtered;
2366
+ return '';
2263
2367
  };
2264
-
2265
- const SearchFileRipGrep = {
2266
- __proto__: null,
2267
- searchFile: searchFile$1
2368
+ const getPickLabel$3 = pick => {
2369
+ const {
2370
+ provider
2371
+ } = state$1;
2372
+ // @ts-ignore
2373
+ return provider.getPickLabel(pick);
2268
2374
  };
2269
-
2270
- const getModule = protocol => {
2271
- switch (protocol) {
2272
- case Memfs:
2273
- return SearchFileMemfs;
2274
- case Fetch:
2275
- return SearchFileFetch;
2276
- case Html:
2277
- return SearchFileHtml;
2278
- default:
2279
- return SearchFileRipGrep;
2375
+ const getPickIcon$3 = pick => {
2376
+ const {
2377
+ provider
2378
+ } = state$1;
2379
+ // @ts-ignore
2380
+ return provider.getPickIcon(pick);
2381
+ };
2382
+ const getPickFileIcon$1 = pick => {
2383
+ const {
2384
+ provider
2385
+ } = state$1;
2386
+ // @ts-ignore
2387
+ if (provider.getPickFileIcon) {
2388
+ // @ts-ignore
2389
+ return provider.getPickFileIcon(pick);
2280
2390
  }
2391
+ return '';
2281
2392
  };
2282
- const searchFile = async (path, value, prepare, assetDir) => {
2283
- const protocol = getProtocol(path);
2284
- // TODO call different providers depending on protocol
2285
- const module = await getModule(protocol);
2286
- const result = await module.searchFile(path, value, prepare, assetDir);
2287
- return result;
2393
+ const isPrepared = () => {
2394
+ const {
2395
+ provider
2396
+ } = state$1;
2397
+ // @ts-ignore
2398
+ if (provider.isPrepared) {
2399
+ // @ts-ignore
2400
+ return provider.isPrepared();
2401
+ }
2402
+ return false;
2288
2403
  };
2289
2404
 
2290
- const name$6 = 'file';
2291
- const getPlaceholder$7 = () => {
2292
- return '';
2293
- };
2294
- const getLabel$1 = () => {
2295
- return files();
2405
+ const QuickPickEntriesEverything = {
2406
+ __proto__: null,
2407
+ getFilterValue: getFilterValue$3,
2408
+ getHelpEntries: getHelpEntries$3,
2409
+ getLabel: getLabel$3,
2410
+ getNoResults: getNoResults$4,
2411
+ getPickDescription: getPickDescription$3,
2412
+ getPickFileIcon: getPickFileIcon$1,
2413
+ getPickFilterValue: getPickFilterValue$3,
2414
+ getPickIcon: getPickIcon$3,
2415
+ getPickLabel: getPickLabel$3,
2416
+ getPicks: getPicks$4,
2417
+ getPlaceholder: getPlaceholder$4,
2418
+ isPrepared,
2419
+ name: name$2,
2420
+ openCommandPalette,
2421
+ openView,
2422
+ selectPick: selectPick$4,
2423
+ state: state$1
2296
2424
  };
2297
2425
 
2298
- // TODO help entries should not be here
2299
- const getHelpEntries$7 = () => {
2300
- return [{
2301
- description: goToFile(),
2302
- category: 'global commands'
2303
- }];
2426
+ const Default = 0;
2427
+ const Finished = 2;
2428
+
2429
+ const create$3 = () => {
2430
+ const states = Object.create(null);
2431
+ return {
2432
+ get(uid) {
2433
+ return states[uid];
2434
+ },
2435
+ set(uid, oldState, newState) {
2436
+ states[uid] = {
2437
+ oldState,
2438
+ newState
2439
+ };
2440
+ }
2441
+ };
2304
2442
  };
2305
- const getNoResults$6 = () => {
2443
+
2444
+ const {
2445
+ get,
2446
+ set
2447
+ } = create$3();
2448
+
2449
+ const create$2 = ({
2450
+ itemHeight,
2451
+ headerHeight = 0,
2452
+ minimumSliderSize = 20
2453
+ }) => {
2306
2454
  return {
2307
- label: noMatchingResults()
2455
+ deltaY: 0,
2456
+ minLineY: 0,
2457
+ maxLineY: 0,
2458
+ finalDeltaY: 0,
2459
+ itemHeight,
2460
+ headerHeight,
2461
+ items: [],
2462
+ minimumSliderSize,
2463
+ focusedIndex: -1,
2464
+ touchOffsetY: 0,
2465
+ touchTimeStamp: 0,
2466
+ touchDifference: 0,
2467
+ scrollBarHeight: 0,
2468
+ scrollBarActive: false
2308
2469
  };
2309
2470
  };
2310
- const getPicks$7 = async searchValue => {
2311
- {
2312
- return [];
2471
+ const getListHeight = (height, headerHeight) => {
2472
+ if (headerHeight) {
2473
+ return height - headerHeight;
2313
2474
  }
2475
+ return headerHeight;
2314
2476
  };
2315
- const selectPick$7 = async pick => {
2316
- if (typeof pick === 'object') {
2317
- pick = pick.pick;
2318
- }
2319
- const workspace = '';
2320
- const absolutePath = `${workspace}/${pick}`;
2321
- await execute(/* Main.openUri */'Main.openUri', /* uri */absolutePath);
2477
+ const setDeltaY = (state, deltaY) => {
2478
+ object(state);
2479
+ number(deltaY);
2480
+ const {
2481
+ itemHeight,
2482
+ items,
2483
+ height,
2484
+ headerHeight
2485
+ } = state;
2486
+ const listHeight = getListHeight(height, headerHeight);
2487
+ const itemsLength = items.length;
2488
+ const finalDeltaY = itemsLength * itemHeight - listHeight;
2489
+ if (deltaY < 0) {
2490
+ deltaY = 0;
2491
+ } else if (deltaY > finalDeltaY) {
2492
+ deltaY = Math.max(finalDeltaY, 0);
2493
+ }
2494
+ if (state.deltaY === deltaY) {
2495
+ return state;
2496
+ }
2497
+ const minLineY = Math.round(deltaY / itemHeight);
2498
+ const maxLineY = minLineY + Math.round(listHeight / itemHeight);
2499
+ number(minLineY);
2500
+ number(maxLineY);
2322
2501
  return {
2323
- command: Hide
2502
+ ...state,
2503
+ deltaY,
2504
+ minLineY,
2505
+ maxLineY
2324
2506
  };
2325
2507
  };
2326
- const getFilterValue$6 = value => {
2327
- return value;
2328
- };
2329
- const getPickFilterValue$2 = pick => {
2330
- if (typeof pick === 'object') {
2331
- pick = pick.pick;
2332
- }
2333
- return pick;
2508
+ const handleWheel = (state, deltaMode, deltaY) => {
2509
+ object(state);
2510
+ number(deltaMode);
2511
+ number(deltaY);
2512
+ return setDeltaY(state, state.deltaY + deltaY);
2513
+ };
2514
+
2515
+ const create$1 = (uid, uri, listItemHeight, x, y, width, height, platform, args) => {
2516
+ const state = {
2517
+ uid,
2518
+ state: Default,
2519
+ picks: [],
2520
+ recentPicks: [],
2521
+ recentPickIds: new Map(),
2522
+ // TODO use object.create(null) instead
2523
+ versionId: 0,
2524
+ provider: QuickPickEntriesEverything,
2525
+ // TODO make this dynamic again
2526
+ warned: [],
2527
+ visiblePicks: [],
2528
+ maxVisibleItems: 10,
2529
+ uri,
2530
+ cursorOffset: 0,
2531
+ height: 300,
2532
+ top: 50,
2533
+ width: 600,
2534
+ ...create$2({
2535
+ itemHeight: listItemHeight,
2536
+ headerHeight: 30,
2537
+ minimumSliderSize: minimumSliderSize
2538
+ }),
2539
+ inputSource: User,
2540
+ args,
2541
+ focused: false,
2542
+ platform,
2543
+ value: ''
2544
+ };
2545
+ set(uid, state, state);
2546
+ };
2547
+
2548
+ const create = (uid, uri, listItemHeight, x, y, width, height, platform, args) => {
2549
+ const state = {
2550
+ uid,
2551
+ state: Default,
2552
+ picks: [],
2553
+ recentPicks: [],
2554
+ recentPickIds: new Map(),
2555
+ // TODO use object.create(null) instead
2556
+ versionId: 0,
2557
+ provider: QuickPickEntriesEverything,
2558
+ // TODO make this dynamic again
2559
+ warned: [],
2560
+ visiblePicks: [],
2561
+ maxVisibleItems: 10,
2562
+ uri,
2563
+ cursorOffset: 0,
2564
+ height: 300,
2565
+ top: 50,
2566
+ width: 600,
2567
+ ...create$2({
2568
+ itemHeight: listItemHeight,
2569
+ headerHeight: 30,
2570
+ minimumSliderSize: minimumSliderSize
2571
+ }),
2572
+ inputSource: User,
2573
+ args,
2574
+ focused: false,
2575
+ platform,
2576
+ value: ''
2577
+ };
2578
+ set(uid, state, state);
2579
+ return state;
2334
2580
  };
2335
- const getPickLabel$1 = pick => {
2336
- if (typeof pick === 'object') {
2337
- pick = pick.pick;
2581
+
2582
+ const getBlob$1 = async url => {
2583
+ try {
2584
+ const response = await fetch(url);
2585
+ if (!response.ok) {
2586
+ throw new Error(response.statusText);
2587
+ }
2588
+ const text = await response.blob();
2589
+ return text;
2590
+ } catch (error) {
2591
+ throw new VError(error, `Failed to request blob for ${url}`);
2338
2592
  }
2339
- const baseName = pathBaseName(pick);
2340
- return baseName;
2341
2593
  };
2342
- const getPickDescription$1 = pick => {
2343
- if (typeof pick === 'object') {
2344
- pick = pick.pick;
2594
+
2595
+ const getText = async url => {
2596
+ try {
2597
+ const response = await fetch(url);
2598
+ if (!response.ok) {
2599
+ throw new Error(response.statusText);
2600
+ }
2601
+ const text = await response.text();
2602
+ return text;
2603
+ } catch (error) {
2604
+ throw new VError(error, `Failed to request text for ${url}`);
2345
2605
  }
2346
- const dirName = pathDirName(pick);
2347
- return dirName;
2348
- };
2349
- const getPickIcon$1 = () => {
2350
- return '';
2351
2606
  };
2352
- const getPickFileIcon$1 = pick => {
2353
- return '';
2607
+
2608
+ // TODO move all of this to an extension
2609
+
2610
+ const readFile = async uri => {
2611
+ const fetchUri = `${assetDir}${uri}`;
2612
+ const text = await getText(fetchUri);
2613
+ return text;
2354
2614
  };
2355
- const isPrepared$1 = () => {
2356
- const workspace = '';
2357
- // TODO protocol should always be defined. For files it should use file protocol
2358
- const protocol = getProtocol(workspace);
2359
- return !protocol;
2615
+ const writeFile = () => {
2616
+ throw new Error('not implemented');
2360
2617
  };
2361
-
2362
- const QuickPickEntriesFile = {
2363
- __proto__: null,
2364
- getFilterValue: getFilterValue$6,
2365
- getHelpEntries: getHelpEntries$7,
2366
- getLabel: getLabel$1,
2367
- getNoResults: getNoResults$6,
2368
- getPickDescription: getPickDescription$1,
2369
- getPickFileIcon: getPickFileIcon$1,
2370
- getPickFilterValue: getPickFilterValue$2,
2371
- getPickIcon: getPickIcon$1,
2372
- getPickLabel: getPickLabel$1,
2373
- getPicks: getPicks$7,
2374
- getPlaceholder: getPlaceholder$7,
2375
- isPrepared: isPrepared$1,
2376
- name: name$6,
2377
- selectPick: selectPick$7
2618
+ const mkdir = () => {
2619
+ throw new Error('not implemented');
2378
2620
  };
2379
-
2380
- const name$5 = 'goToLine';
2381
- const getPlaceholder$6 = () => {
2382
- return '';
2621
+ const remove = () => {
2622
+ throw new Error('not implemented');
2383
2623
  };
2384
- const getHelpEntries$6 = () => {
2385
- return [];
2624
+ const readDirWithFileTypes = async uri => {
2625
+ const fileList = await getJson(fileMapUrl);
2626
+ const dirents = [];
2627
+ for (const fileUri of fileList) {
2628
+ if (fileUri.startsWith(uri)) {
2629
+ const rest = fileUri.slice(uri.length + 1);
2630
+ if (rest.includes(Slash)) {
2631
+ const name = rest.slice(0, rest.indexOf(Slash));
2632
+ if (dirents.some(dirent => dirent.name === name)) {
2633
+ continue;
2634
+ }
2635
+ dirents.push({
2636
+ type: Directory$1,
2637
+ name
2638
+ });
2639
+ } else {
2640
+ dirents.push({
2641
+ type: File$2,
2642
+ name: rest
2643
+ });
2644
+ }
2645
+ }
2646
+ }
2647
+ return dirents;
2386
2648
  };
2387
- const getNoResults$5 = () => {
2388
- return undefined;
2649
+ const chmod = () => {
2650
+ throw new Error('[memfs] chmod not implemented');
2389
2651
  };
2390
- const getPicks$6 = async () => {
2391
- const picks = [{
2392
- label: '1'
2393
- }, {
2394
- label: '2'
2395
- }, {
2396
- label: '3'
2397
- }, {
2398
- label: '4'
2399
- }, {
2400
- label: '5'
2401
- }, {
2402
- label: '6'
2403
- }];
2404
- return picks;
2652
+ const getBlob = async (uri, type) => {
2653
+ const fetchUri = `${assetDir}${uri}`;
2654
+ const blob = getBlob$1(fetchUri);
2655
+ return blob;
2405
2656
  };
2406
- const selectPick$6 = async item => {
2407
- const rowIndex = Number.parseInt(item.label);
2408
- const position = {
2409
- rowIndex,
2410
- columnIndex: 5
2411
- };
2412
- await execute(/* EditorSetCursor.editorSetCursor */'TODO', /* position */position);
2413
- // TODO put cursor onto that line
2657
+
2658
+ const focusIndex = async (state, index) => {
2659
+ const {
2660
+ provider,
2661
+ maxVisibleItems,
2662
+ items,
2663
+ minLineY,
2664
+ maxLineY
2665
+ } = state;
2666
+ // TODO get types working
2667
+ // @ts-ignore
2668
+ if (provider.focusPick) {
2669
+ // @ts-ignore
2670
+ await provider.focusPick(items[index].pick);
2671
+ }
2672
+ if (index < minLineY + 1) {
2673
+ const minLineY = index;
2674
+ const maxLineY = Math.min(index + maxVisibleItems, items.length - 1);
2675
+ // TODO need to scroll up
2676
+ return {
2677
+ ...state,
2678
+ minLineY,
2679
+ maxLineY,
2680
+ focusedIndex: index
2681
+ };
2682
+ }
2683
+ if (index >= maxLineY - 1) {
2684
+ // TODO need to scroll down
2685
+ const maxLineY = index + 1;
2686
+ const minLineY = Math.max(maxLineY - maxVisibleItems, 0);
2687
+ return {
2688
+ ...state,
2689
+ minLineY,
2690
+ maxLineY,
2691
+ focusedIndex: index
2692
+ };
2693
+ }
2414
2694
  return {
2415
- command: Hide
2695
+ ...state,
2696
+ focusedIndex: index
2416
2697
  };
2417
2698
  };
2418
- const getFilterValue$5 = value => {
2419
- return value;
2420
- };
2421
2699
 
2422
- const QuickPickEntriesGoToLine = {
2423
- __proto__: null,
2424
- getFilterValue: getFilterValue$5,
2425
- getHelpEntries: getHelpEntries$6,
2426
- getNoResults: getNoResults$5,
2427
- getPicks: getPicks$6,
2428
- getPlaceholder: getPlaceholder$6,
2429
- name: name$5,
2430
- selectPick: selectPick$6
2700
+ const next = (items, index) => {
2701
+ return (index + 1) % items.length;
2431
2702
  };
2432
2703
 
2433
- const name$4 = 'noop';
2434
- const getPlaceholder$5 = () => {
2435
- return '';
2436
- };
2437
- const getHelpEntries$5 = () => {
2438
- return [];
2439
- };
2440
- const getNoResults$4 = () => {
2441
- return noResults();
2704
+ const focusNext = state => {
2705
+ const {
2706
+ items,
2707
+ focusedIndex
2708
+ } = state;
2709
+ const nextIndex = next(items, focusedIndex);
2710
+ return focusIndex(state, nextIndex);
2442
2711
  };
2443
- const getPicks$5 = async value => {
2444
- return [];
2712
+
2713
+ const Enter = 3;
2714
+ const Escape = 8;
2715
+ const PageUp = 10;
2716
+ const PageDown = 11;
2717
+ const UpArrow = 14;
2718
+ const DownArrow = 16;
2719
+
2720
+ const FocusQuickPickInput = 20;
2721
+
2722
+ const getKeyBindings = () => {
2723
+ return [{
2724
+ key: Escape,
2725
+ command: 'Viewlet.closeWidget',
2726
+ args: ['QuickPick'],
2727
+ when: FocusQuickPickInput
2728
+ }, {
2729
+ key: UpArrow,
2730
+ command: 'QuickPick.focusPrevious',
2731
+ when: FocusQuickPickInput
2732
+ }, {
2733
+ key: DownArrow,
2734
+ command: 'QuickPick.focusNext',
2735
+ when: FocusQuickPickInput
2736
+ }, {
2737
+ key: PageUp,
2738
+ command: 'QuickPick.focusFirst',
2739
+ when: FocusQuickPickInput
2740
+ }, {
2741
+ key: PageDown,
2742
+ command: 'QuickPick.focusLast',
2743
+ when: FocusQuickPickInput
2744
+ }, {
2745
+ key: Enter,
2746
+ command: 'QuickPick.selectCurrentIndex',
2747
+ when: FocusQuickPickInput
2748
+ }];
2445
2749
  };
2446
- const selectPick$5 = async item => {
2447
- return {
2448
- command: Hide
2449
- };
2750
+
2751
+ const closeWidget = async id => {
2752
+ await invoke$1('Viewlet.closeWidget', id);
2450
2753
  };
2451
- const getFilterValue$4 = value => {
2452
- return value;
2754
+
2755
+ const handleBlur = async state => {
2756
+ await closeWidget(state.uid);
2757
+ return state;
2453
2758
  };
2454
- const getPickFilterValue$1 = pick => {
2455
- return pick;
2759
+
2760
+ const getDefaultValue = uri => {
2761
+ switch (uri) {
2762
+ case 'quickPick://everything':
2763
+ return '>';
2764
+ default:
2765
+ return '';
2766
+ }
2456
2767
  };
2457
2768
 
2458
- const QuickPickNoop = {
2459
- __proto__: null,
2460
- getFilterValue: getFilterValue$4,
2461
- getHelpEntries: getHelpEntries$5,
2462
- getNoResults: getNoResults$4,
2463
- getPickFilterValue: getPickFilterValue$1,
2464
- getPicks: getPicks$5,
2465
- getPlaceholder: getPlaceholder$5,
2466
- name: name$4,
2467
- selectPick: selectPick$5
2769
+ const getColorThemeNames = async () => {
2770
+ return invoke$1(/* Ajax.getJson */'ColorTheme.getColorThemeNames');
2468
2771
  };
2469
2772
 
2470
- const name$3 = 'symbol';
2471
- const getPlaceholder$4 = () => {
2472
- return '';
2773
+ const setColorTheme = id => {
2774
+ return invoke$1(/* ColorTheme.setColorTheme */'ColorTheme.setColorTheme', /* colorThemeId */id);
2473
2775
  };
2474
- const getHelpEntries$4 = () => {
2475
- return [];
2776
+ const getPlaceholder$3 = () => {
2777
+ return selectColorTheme();
2476
2778
  };
2477
- const getNoResults$3 = () => {
2478
- return {
2479
- label: noSymbolFound()
2480
- };
2779
+ const getLabel$2 = () => {
2780
+ return selectColorTheme();
2481
2781
  };
2482
- const getPicks$4 = async () => {
2483
- const picks = [];
2484
- return picks;
2782
+ const getPicks$3 = async searchValue => {
2783
+ const colorThemeNames = await getColorThemeNames();
2784
+ return colorThemeNames;
2485
2785
  };
2486
- const selectPick$4 = async item => {
2786
+ const selectPick$3 = async pick => {
2787
+ await setColorTheme(/* colorThemeId */pick);
2487
2788
  return {
2488
2789
  command: Hide
2489
2790
  };
2490
2791
  };
2491
- const getFilterValue$3 = value => {
2492
- return value;
2493
- };
2494
-
2495
- const QuickPickEntriesSymbol = {
2496
- __proto__: null,
2497
- getFilterValue: getFilterValue$3,
2498
- getHelpEntries: getHelpEntries$4,
2499
- getNoResults: getNoResults$3,
2500
- getPicks: getPicks$4,
2501
- getPlaceholder: getPlaceholder$4,
2502
- name: name$3,
2503
- selectPick: selectPick$4
2792
+ const focusPick = async pick => {
2793
+ await setColorTheme(/* colorThemeId */pick);
2504
2794
  };
2505
-
2506
- // TODO probably not needed
2507
-
2508
- const getPlaceholder$3 = () => {
2509
- return typeNameofCommandToRun();
2795
+ const getFilterValue$2 = value => {
2796
+ return value;
2510
2797
  };
2511
- const getHelpEntries$3 = () => {
2512
- return undefined;
2798
+ const getNoResults$3 = () => {
2799
+ return {
2800
+ label: noMatchingColorThemesFound()
2801
+ };
2513
2802
  };
2514
- const getPicks$3 = async () => {
2515
- // const views = ViewService.getViews()
2516
- // const picks = views.map(toPick)
2517
- // return picks
2518
- return [];
2803
+ const getPickFilterValue$2 = pick => {
2804
+ return pick;
2519
2805
  };
2520
- const selectPick$3 = async item => {
2521
- // Command.execute(/* openView */ 549, /* viewName */ item.label)
2522
- // return {
2523
- // command: QuickPickReturnValue.Hide,
2524
- // }
2806
+ const getPickLabel$2 = pick => {
2807
+ return pick;
2525
2808
  };
2526
- const getFilterValue$2 = value => {
2527
- return value;
2809
+ const getPickIcon$2 = pick => {
2810
+ return '';
2528
2811
  };
2529
2812
 
2530
- const QuickPickEntriesView = {
2813
+ const QuickPickEntriesColorTheme = {
2531
2814
  __proto__: null,
2815
+ focusPick,
2532
2816
  getFilterValue: getFilterValue$2,
2533
- getHelpEntries: getHelpEntries$3,
2817
+ getLabel: getLabel$2,
2818
+ getNoResults: getNoResults$3,
2819
+ getPickFilterValue: getPickFilterValue$2,
2820
+ getPickIcon: getPickIcon$2,
2821
+ getPickLabel: getPickLabel$2,
2534
2822
  getPicks: getPicks$3,
2535
2823
  getPlaceholder: getPlaceholder$3,
2536
- selectPick: selectPick$3
2824
+ selectPick: selectPick$3,
2825
+ setColorTheme
2537
2826
  };
2538
2827
 
2539
- const name$2 = 'workspace-symbol';
2828
+ const Tag$1 = 'Tag';
2829
+ const Cloud$1 = 'Cloud';
2830
+ const SourceControl$1 = 'SourceControl';
2831
+ const None$1 = '';
2832
+
2833
+ const SourceControl = 1;
2834
+ const Cloud = 2;
2835
+ const Tag = 3;
2836
+
2837
+ const name$1 = 'custom';
2838
+ const state = {
2839
+ args: []
2840
+ };
2841
+ const setArgs = args => {
2842
+ state.args = args;
2843
+ };
2540
2844
  const getPlaceholder$2 = () => {
2541
2845
  return '';
2542
2846
  };
2847
+ const getLabel$1 = () => {
2848
+ return 'Custom';
2849
+ };
2850
+
2851
+ // TODO help entries should not be here
2543
2852
  const getHelpEntries$2 = () => {
2544
2853
  return [];
2545
2854
  };
2546
2855
  const getNoResults$2 = () => {
2547
2856
  return {
2548
- label: noWorkspaceSymbolsFound()
2857
+ label: noMatchingResults()
2549
2858
  };
2550
2859
  };
2551
- const getPicks$2 = async () => {
2552
- const picks = [];
2553
- return picks;
2860
+ const getPicks$2 = async searchValue => {
2861
+ const items = state.args[1] || [];
2862
+ return items;
2554
2863
  };
2555
- const selectPick$2 = async item => {
2864
+ const selectPick$2 = async pick => {
2865
+ const {
2866
+ args
2867
+ } = state;
2868
+ const resolve = args[2];
2869
+ resolve(pick);
2556
2870
  return {
2557
2871
  command: Hide
2558
2872
  };
@@ -2560,202 +2874,62 @@ const selectPick$2 = async item => {
2560
2874
  const getFilterValue$1 = value => {
2561
2875
  return value;
2562
2876
  };
2563
-
2564
- const QuickPickEntriesWorkspaceSymbol = {
2565
- __proto__: null,
2566
- getFilterValue: getFilterValue$1,
2567
- getHelpEntries: getHelpEntries$2,
2568
- getNoResults: getNoResults$2,
2569
- getPicks: getPicks$2,
2570
- getPlaceholder: getPlaceholder$2,
2571
- name: name$2,
2572
- selectPick: selectPick$2
2573
- };
2574
-
2575
- const Command = '>';
2576
- const Symbol$1 = '@';
2577
- const WorkspaceSymbol = '#';
2578
- const GoToLine = ':';
2579
- const View = 'view ';
2580
- const None = '';
2581
-
2582
- // TODO avoid global variable
2583
-
2584
- const state = {
2585
- // providerId: PROVIDER_NOOP,
2586
- provider: QuickPickNoop,
2587
- prefix: 'string-that-should-never-match-another-string'
2588
- };
2589
-
2590
- /**
2591
- * @type {string}
2592
- */
2593
- const name$1 = 'everything';
2594
- const getPlaceholder$1 = () => {
2595
- return state.provider.getPlaceholder();
2596
- };
2597
- const getLabel = () => {
2598
- return '';
2599
- };
2600
- const getHelpEntries$1 = () => {
2601
- return state.provider.getHelpEntries();
2602
- };
2603
- const getNoResults$1 = () => {
2604
- return state.provider.getNoResults();
2605
- };
2606
- const getPrefix = value => {
2607
- if (value.startsWith(Command)) {
2608
- return Command;
2609
- }
2610
- if (value.startsWith(Symbol$1)) {
2611
- return Symbol$1;
2612
- }
2613
- if (value.startsWith(WorkspaceSymbol)) {
2614
- return WorkspaceSymbol;
2615
- }
2616
- if (value.startsWith(GoToLine)) {
2617
- return GoToLine;
2618
- }
2619
- if (value.startsWith(View)) {
2620
- return View;
2621
- }
2622
- return None;
2623
- };
2624
- const getQuickPickProvider = prefix => {
2625
- // TODO could use enum for prefix
2626
- // TODO could use regex to extract prefix
2627
- // TODO or could check first letter char code (less comparisons)
2628
- switch (prefix) {
2629
- case Command:
2630
- return QuickPickEntriesCommand;
2631
- case Symbol$1:
2632
- return QuickPickEntriesSymbol;
2633
- case WorkspaceSymbol:
2634
- return QuickPickEntriesWorkspaceSymbol;
2635
- case GoToLine:
2636
- return QuickPickEntriesGoToLine;
2637
- case View:
2638
- return QuickPickEntriesView;
2639
- default:
2640
- return QuickPickEntriesFile;
2641
- }
2642
- };
2643
- const getPicks$1 = async value => {
2644
- const prefix = getPrefix(value);
2645
- // TODO race condition
2646
- if (state.prefix !== prefix) {
2647
- state.prefix = prefix;
2648
- // @ts-ignore
2649
- state.provider = await getQuickPickProvider(prefix);
2650
- }
2651
- // TODO this line is a bit duplicated with getFilterValue
2652
- const slicedValue = value.slice(prefix.length);
2653
- const picks = await state.provider.getPicks(slicedValue);
2654
- return picks;
2655
- };
2656
- const selectPick$1 = item => {
2657
- const {
2658
- provider
2659
- } = state;
2660
- return provider.selectPick(item);
2661
- };
2662
- const openCommandPalette = () => {
2663
- // show('>')
2664
- };
2665
- const openView = () => {
2666
- // show('view ')
2667
- };
2668
- const getFilterValue = value => {
2669
- return value.slice(state.prefix.length);
2670
- };
2671
- const getPickFilterValue = pick => {
2672
- const {
2673
- provider
2674
- } = state;
2675
- return provider.getPickFilterValue(pick);
2676
- };
2677
- const getPickDescription = pick => {
2678
- const {
2679
- provider
2680
- } = state;
2681
- // @ts-ignore
2682
- if (provider.getPickDescription) {
2683
- // @ts-ignore
2684
- return provider.getPickDescription(pick);
2685
- }
2686
- return '';
2687
- };
2688
- const getPickLabel = pick => {
2689
- const {
2690
- provider
2691
- } = state;
2692
- // @ts-ignore
2693
- return provider.getPickLabel(pick);
2694
- };
2695
- const getPickIcon = pick => {
2696
- const {
2697
- provider
2698
- } = state;
2699
- // @ts-ignore
2700
- return provider.getPickIcon(pick);
2877
+ const getPickFilterValue$1 = pick => {
2878
+ return pick;
2701
2879
  };
2702
- const getPickFileIcon = pick => {
2703
- const {
2704
- provider
2705
- } = state;
2706
- // @ts-ignore
2707
- if (provider.getPickFileIcon) {
2708
- // @ts-ignore
2709
- return provider.getPickFileIcon(pick);
2710
- }
2711
- return '';
2880
+ const getPickLabel$1 = pick => {
2881
+ return pick.label;
2712
2882
  };
2713
- const isPrepared = () => {
2714
- const {
2715
- provider
2716
- } = state;
2717
- // @ts-ignore
2718
- if (provider.isPrepared) {
2719
- // @ts-ignore
2720
- return provider.isPrepared();
2883
+ const getPickDescription$2 = pick => {
2884
+ return pick.description || '';
2885
+ };
2886
+ const convertIcon = icon => {
2887
+ switch (icon) {
2888
+ case SourceControl:
2889
+ return SourceControl$1;
2890
+ case Cloud:
2891
+ return Cloud$1;
2892
+ case Tag:
2893
+ return Tag$1;
2894
+ default:
2895
+ return None$1;
2721
2896
  }
2722
- return false;
2897
+ };
2898
+ const getPickIcon$1 = pick => {
2899
+ return convertIcon(pick.icon);
2723
2900
  };
2724
2901
 
2725
- const QuickPickEntriesEverything = {
2902
+ const QuickPickEntriesCustom = {
2726
2903
  __proto__: null,
2727
- getFilterValue,
2728
- getHelpEntries: getHelpEntries$1,
2729
- getLabel,
2730
- getNoResults: getNoResults$1,
2731
- getPickDescription,
2732
- getPickFileIcon,
2733
- getPickFilterValue,
2734
- getPickIcon,
2735
- getPickLabel,
2736
- getPicks: getPicks$1,
2737
- getPlaceholder: getPlaceholder$1,
2738
- isPrepared,
2904
+ getFilterValue: getFilterValue$1,
2905
+ getHelpEntries: getHelpEntries$2,
2906
+ getLabel: getLabel$1,
2907
+ getNoResults: getNoResults$2,
2908
+ getPickDescription: getPickDescription$2,
2909
+ getPickFilterValue: getPickFilterValue$1,
2910
+ getPickIcon: getPickIcon$1,
2911
+ getPickLabel: getPickLabel$1,
2912
+ getPicks: getPicks$2,
2913
+ getPlaceholder: getPlaceholder$2,
2739
2914
  name: name$1,
2740
- openCommandPalette,
2741
- openView,
2742
- selectPick: selectPick$1,
2915
+ selectPick: selectPick$2,
2916
+ setArgs,
2743
2917
  state
2744
2918
  };
2745
2919
 
2746
2920
  const name = 'number';
2747
- const getPlaceholder = () => {
2921
+ const getPlaceholder$1 = () => {
2748
2922
  return '';
2749
2923
  };
2750
- const getHelpEntries = () => {
2924
+ const getHelpEntries$1 = () => {
2751
2925
  return [];
2752
2926
  };
2753
- const getNoResults = () => {
2927
+ const getNoResults$1 = () => {
2754
2928
  return {
2755
2929
  label: noMatchingResults()
2756
2930
  };
2757
2931
  };
2758
- const getPicks = async () => {
2932
+ const getPicks$1 = async () => {
2759
2933
  const picks = [{
2760
2934
  label: '1'
2761
2935
  }, {
@@ -2779,7 +2953,7 @@ const getPicks = async () => {
2779
2953
  }];
2780
2954
  return picks;
2781
2955
  };
2782
- const selectPick = async item => {
2956
+ const selectPick$1 = async item => {
2783
2957
  return {
2784
2958
  command: Hide
2785
2959
  };
@@ -2787,20 +2961,110 @@ const selectPick = async item => {
2787
2961
 
2788
2962
  const QuickPickEntriesNumber = {
2789
2963
  __proto__: null,
2964
+ getHelpEntries: getHelpEntries$1,
2965
+ getNoResults: getNoResults$1,
2966
+ getPicks: getPicks$1,
2967
+ getPlaceholder: getPlaceholder$1,
2968
+ name,
2969
+ selectPick: selectPick$1
2970
+ };
2971
+
2972
+ // TODO support file icons
2973
+ const getFolderIcon = () => {
2974
+ return '';
2975
+ };
2976
+
2977
+ const getRecentlyOpened = () => {
2978
+ return invoke$1(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
2979
+ };
2980
+ const openWorkspaceFolder = uri => {
2981
+ return invoke$1(/* Workspace.setPath */'Workspace.setPath', /* path */uri);
2982
+ };
2983
+ const getPlaceholder = () => {
2984
+ return selectToOpen();
2985
+ };
2986
+ const getLabel = () => {
2987
+ return openRecent();
2988
+ };
2989
+ const getHelpEntries = () => {
2990
+ return [];
2991
+ };
2992
+ const getNoResults = () => {
2993
+ return {
2994
+ label: noRecentlyOpenedFoldersFound()
2995
+ };
2996
+ };
2997
+
2998
+ // TODO could also change api so that getPicks returns an array of anything
2999
+ // and the transformPick gets the label for each pick
3000
+ // This would make the code more module since the code for getting the picks
3001
+ // would be more independent of the specific data format of the quickpick provider
3002
+
3003
+ const getPicks = async () => {
3004
+ const recentlyOpened = await getRecentlyOpened();
3005
+ return recentlyOpened;
3006
+ };
3007
+
3008
+ // TODO selectPick should be independent of show/hide
3009
+ const selectPick = async pick => {
3010
+ const path = pick;
3011
+ await openWorkspaceFolder(path);
3012
+ return {
3013
+ command: Hide
3014
+ };
3015
+ };
3016
+ const getFilterValue = value => {
3017
+ return pathBaseName(value);
3018
+ };
3019
+ const getPickFilterValue = pick => {
3020
+ return pathBaseName(pick);
3021
+ };
3022
+ const getPickLabel = pick => {
3023
+ return pathBaseName(pick);
3024
+ };
3025
+ const getPickDescription$1 = pick => {
3026
+ return pathDirName(pick);
3027
+ };
3028
+ const getPickIcon = () => {
3029
+ return '';
3030
+ };
3031
+ const getPickFileIcon = () => {
3032
+ return getFolderIcon();
3033
+ };
3034
+
3035
+ const QuickPickEntriesOpenRecent = {
3036
+ __proto__: null,
3037
+ getFilterValue,
2790
3038
  getHelpEntries,
3039
+ getLabel,
2791
3040
  getNoResults,
3041
+ getPickDescription: getPickDescription$1,
3042
+ getPickFileIcon,
3043
+ getPickFilterValue,
3044
+ getPickIcon,
3045
+ getPickLabel,
2792
3046
  getPicks,
2793
3047
  getPlaceholder,
2794
- name,
2795
3048
  selectPick
2796
3049
  };
2797
3050
 
3051
+ const CommandPalette = 'quickPick://commandPalette';
3052
+ const File = 'quickPick://file';
3053
+ const EveryThing = 'quickPick://everything';
3054
+ const Number$1 = 'quickPick://number';
3055
+ const Recent = 'quickPick://recent';
3056
+ const ColorTheme = 'quickPick://color-theme';
3057
+ const Symbol$1 = 'quickPick://symbol';
3058
+ const View = 'quickPick://view';
3059
+ const WorkspaceSymbol = 'quickPick://workspace-symbol';
3060
+ const Custom = 'quickPick://custom';
3061
+
2798
3062
  const load = moduleId => {
2799
3063
  switch (moduleId) {
2800
3064
  case CommandPalette:
2801
- case File$1:
3065
+ case File:
2802
3066
  case EveryThing:
2803
- case WorkspaceSymbol$1:
3067
+ case WorkspaceSymbol:
2804
3068
  return QuickPickEntriesEverything;
2805
3069
  case Number$1:
2806
3070
  return QuickPickEntriesNumber;
@@ -2808,9 +3072,9 @@ const load = moduleId => {
2808
3072
  return QuickPickEntriesOpenRecent;
2809
3073
  case ColorTheme:
2810
3074
  return QuickPickEntriesColorTheme;
2811
- case Symbol$2:
3075
+ case Symbol$1:
2812
3076
  return QuickPickEntriesSymbol;
2813
- case View$1:
3077
+ case View:
2814
3078
  return QuickPickEntriesView;
2815
3079
  case Custom:
2816
3080
  return QuickPickEntriesCustom;
@@ -2819,31 +3083,412 @@ const load = moduleId => {
2819
3083
  }
2820
3084
  };
2821
3085
 
3086
+ const loadContent = async state => {
3087
+ const {
3088
+ uri,
3089
+ args
3090
+ } = state;
3091
+ const value = getDefaultValue(uri);
3092
+ const provider = await load(uri);
3093
+ // @ts-ignore
3094
+ if (provider.setArgs) {
3095
+ // @ts-ignore
3096
+ provider.setArgs(args);
3097
+ }
3098
+ const newPicks = await provider.getPicks(value);
3099
+ array(newPicks);
3100
+ // @ts-ignore
3101
+ const filterValue = provider.getFilterValue(value);
3102
+ const items = filterQuickPickItems(state.items, filterValue);
3103
+ // @ts-ignore
3104
+ provider.getLabel();
3105
+ const minLineY = 0;
3106
+ const maxLineY = Math.min(minLineY + state.maxVisibleItems, newPicks.length);
3107
+ return {
3108
+ ...state,
3109
+ picks: newPicks,
3110
+ items,
3111
+ focusedIndex: 0,
3112
+ state: Finished,
3113
+ minLineY,
3114
+ maxLineY,
3115
+ value,
3116
+ cursorOffset: value.length,
3117
+ provider,
3118
+ inputSource: Script,
3119
+ focused: true
3120
+ };
3121
+ };
3122
+
3123
+ const loadQuickPickEntries = moduleId => {
3124
+ switch (moduleId) {
3125
+ case Recent:
3126
+ return QuickPickEntriesOpenRecent;
3127
+ default:
3128
+ throw new Error(`unknown module "${moduleId}"`);
3129
+ }
3130
+ };
3131
+
3132
+ const RenderItems = 1;
3133
+ const RenderFocus = 2;
3134
+ const RenderValue = 3;
3135
+ const RenderCursorOffset = 7;
3136
+ const RenderFocusedIndex = 8;
3137
+ const Height = 9;
3138
+
3139
+ const FileIcon = 'FileIcon';
3140
+ const Label = 'Label';
3141
+ const QuickPickHighlight = 'QuickPickHighlight';
3142
+ const QuickPickItem = 'QuickPickItem';
3143
+ const QuickPickItemActive = 'QuickPickItemActive';
3144
+ const QuickPickItemDescription = 'QuickPickItemDescription';
3145
+ const QuickPickItemLabel = 'QuickPickItemLabel';
3146
+
3147
+ const None = 'none';
3148
+ const Option = 'option';
3149
+
3150
+ const Div = 4;
3151
+ const Span = 8;
3152
+ const Text = 12;
3153
+ const Img = 17;
3154
+
3155
+ const getFileIconVirtualDom = icon => {
3156
+ return {
3157
+ type: Img,
3158
+ className: FileIcon,
3159
+ src: icon,
3160
+ role: None,
3161
+ childCount: 0
3162
+ };
3163
+ };
3164
+
3165
+ const text = data => {
3166
+ return {
3167
+ type: Text,
3168
+ text: data,
3169
+ childCount: 0
3170
+ };
3171
+ };
3172
+
3173
+ const quickPickHighlight = {
3174
+ type: Span,
3175
+ className: QuickPickHighlight,
3176
+ childCount: 1
3177
+ };
3178
+ const addHighlights = (dom, highlights, label) => {
3179
+ const labelDom = {
3180
+ type: Div,
3181
+ className: QuickPickItemLabel,
3182
+ childCount: 0
3183
+ };
3184
+ dom.push(labelDom);
3185
+ let position = 0;
3186
+ for (let i = 0; i < highlights.length; i += 2) {
3187
+ const highlightStart = highlights[i];
3188
+ const highlightEnd = highlights[i + 1];
3189
+ if (position < highlightStart) {
3190
+ const beforeText = label.slice(position, highlightStart);
3191
+ labelDom.childCount++;
3192
+ dom.push(text(beforeText));
3193
+ }
3194
+ const highlightText = label.slice(highlightStart, highlightEnd);
3195
+ labelDom.childCount++;
3196
+ dom.push(quickPickHighlight, text(highlightText));
3197
+ position = highlightEnd;
3198
+ }
3199
+ if (position < label.length) {
3200
+ const afterText = label.slice(position);
3201
+ labelDom.childCount++;
3202
+ dom.push(text(afterText));
3203
+ }
3204
+ };
3205
+ const getQuickPickItemVirtualDom = visibleItem => {
3206
+ const {
3207
+ posInSet,
3208
+ label,
3209
+ setSize,
3210
+ isActive,
3211
+ description,
3212
+ icon,
3213
+ matches,
3214
+ fileIcon
3215
+ } = visibleItem;
3216
+ const highlights = matches.slice(1);
3217
+ const dom = [];
3218
+ dom.push({
3219
+ type: Div,
3220
+ className: QuickPickItem,
3221
+ role: Option,
3222
+ ariaPosInSet: posInSet,
3223
+ ariaSetSize: setSize,
3224
+ childCount: 1
3225
+ });
3226
+ const parent = dom[0];
3227
+ if (isActive) {
3228
+ // @ts-ignore
3229
+ parent.id = 'QuickPickItemActive';
3230
+ parent.className += ' ' + QuickPickItemActive;
3231
+ }
3232
+ if (fileIcon) {
3233
+ parent.childCount++;
3234
+ dom.push(getFileIconVirtualDom(fileIcon));
3235
+ } else if (icon) {
3236
+ parent.childCount++;
3237
+ dom.push({
3238
+ type: Div,
3239
+ className: `QuickPickMaskIcon MaskIcon MaskIcon${icon}`,
3240
+ childCount: 0
3241
+ });
3242
+ }
3243
+ addHighlights(dom, highlights, label);
3244
+ if (description) {
3245
+ parent.childCount++;
3246
+ dom.push({
3247
+ type: Div,
3248
+ className: QuickPickItemDescription,
3249
+ childCount: 1
3250
+ }, text(description));
3251
+ }
3252
+ return dom;
3253
+ };
3254
+
3255
+ const getQuickPickItemsVirtualDom = visibleItems => {
3256
+ if (visibleItems.length === 0) {
3257
+ return [{
3258
+ type: Div,
3259
+ className: 'QuickPickItem QuickPickItemActive QuickPickStatus',
3260
+ childCount: 1
3261
+ }, {
3262
+ type: Div,
3263
+ className: Label,
3264
+ childCount: 1
3265
+ }, text('No Results')];
3266
+ }
3267
+ const dom = visibleItems.flatMap(getQuickPickItemVirtualDom);
3268
+ return dom;
3269
+ };
3270
+
3271
+ const getPickDescription = (provider, pick) => {
3272
+ if (provider.getPickDescription) {
3273
+ return provider.getPickDescription(pick);
3274
+ }
3275
+ return '';
3276
+ };
3277
+ const getFileIcon = (provider, pick) => {
3278
+ if (provider.getPickFileIcon) {
3279
+ return provider.getPickFileIcon(pick);
3280
+ }
3281
+ return '';
3282
+ };
3283
+ const getVisible = (provider, items, minLineY, maxLineY, focusedIndex) => {
3284
+ const visibleItems = [];
3285
+ const setSize = items.length;
3286
+ const max = Math.min(setSize, maxLineY);
3287
+ for (let i = minLineY; i < max; i++) {
3288
+ const item = items[i];
3289
+ const pick = item.pick;
3290
+ const label = provider.getPickLabel(pick);
3291
+ const description = getPickDescription(provider, pick);
3292
+ const icon = provider.getPickIcon(pick);
3293
+ const fileIcon = getFileIcon(provider, pick);
3294
+ visibleItems.push({
3295
+ label,
3296
+ description,
3297
+ icon,
3298
+ fileIcon,
3299
+ posInSet: i + 1,
3300
+ setSize,
3301
+ isActive: i === focusedIndex,
3302
+ matches: item.matches
3303
+ });
3304
+ }
3305
+ return visibleItems;
3306
+ };
3307
+
3308
+ const SetCursorOffset = 'setCursorOffset';
3309
+ const SetFocusedIndex = 'setFocusedIndex';
3310
+ const SetItemsHeight = 'setItemsHeight';
3311
+ const SetValue = 'setValue';
3312
+
3313
+ const renderValue = (oldState, newState) => {
3314
+ return [/* method */SetValue, /* value */newState.value];
3315
+ };
3316
+ const renderCursorOffset = (oldState, newState) => {
3317
+ return [/* method */SetCursorOffset, /* cursorOffset */newState.cursorOffset];
3318
+ };
3319
+ const renderItems = (oldState, newState) => {
3320
+ const visibleItems = getVisible(newState.provider, newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex);
3321
+ const dom = getQuickPickItemsVirtualDom(visibleItems);
3322
+ return [/* method */'setItemsDom', dom];
3323
+ };
3324
+ const renderFocusedIndex = (oldState, newState) => {
3325
+ const oldFocusedIndex = oldState.focusedIndex - oldState.minLineY;
3326
+ const newFocusedIndex = newState.focusedIndex - newState.minLineY;
3327
+ return [/* method */SetFocusedIndex, /* oldFocusedIndex */oldFocusedIndex, /* newFocusedIndex */newFocusedIndex];
3328
+ };
3329
+ const renderHeight = (oldState, newState) => {
3330
+ if (newState.items.length === 0) {
3331
+ return [/* method */SetItemsHeight, /* height */newState.itemHeight];
3332
+ }
3333
+ const maxLineY = Math.min(newState.maxLineY, newState.items.length);
3334
+ const itemCount = maxLineY - newState.minLineY;
3335
+ const height = itemCount * newState.itemHeight;
3336
+ return [/* method */SetItemsHeight, /* height */height];
3337
+ };
3338
+ const renderFocus = (oldState, newState) => {
3339
+ const selector = newState.focused ? '.InputBox' : '';
3340
+ return ['Viewlet.focusSelector', selector];
3341
+ };
3342
+ const getRenderer = diffType => {
3343
+ switch (diffType) {
3344
+ case RenderValue:
3345
+ return renderValue;
3346
+ case RenderCursorOffset:
3347
+ return renderCursorOffset;
3348
+ case RenderItems:
3349
+ return renderItems;
3350
+ case RenderFocusedIndex:
3351
+ return renderFocusedIndex;
3352
+ case Height:
3353
+ return renderHeight;
3354
+ case RenderFocus:
3355
+ return renderFocus;
3356
+ default:
3357
+ throw new Error('unknown renderer');
3358
+ }
3359
+ };
3360
+
3361
+ const applyRender = (oldState, newState, diffResult) => {
3362
+ const commands = [];
3363
+ for (const item of diffResult) {
3364
+ const fn = getRenderer(item);
3365
+ commands.push(fn(oldState, newState));
3366
+ }
3367
+ return commands;
3368
+ };
3369
+
3370
+ const diffType$4 = RenderFocus;
3371
+ const isEqual$4 = (oldState, newState) => {
3372
+ return oldState.focused === newState.focused;
3373
+ };
3374
+
3375
+ const DiffFocus = {
3376
+ __proto__: null,
3377
+ diffType: diffType$4,
3378
+ isEqual: isEqual$4
3379
+ };
3380
+
3381
+ const diffType$3 = RenderFocusedIndex;
3382
+ const isEqual$3 = (oldState, newState) => {
3383
+ return oldState.focusedIndex === newState.focusedIndex;
3384
+ };
3385
+
3386
+ const DiffFocusedIndex = {
3387
+ __proto__: null,
3388
+ diffType: diffType$3,
3389
+ isEqual: isEqual$3
3390
+ };
3391
+
3392
+ const diffType$2 = Height;
3393
+ const isEqual$2 = (oldState, newState) => {
3394
+ return oldState.items.length === newState.items.length;
3395
+ };
3396
+
3397
+ const DiffHeight = {
3398
+ __proto__: null,
3399
+ diffType: diffType$2,
3400
+ isEqual: isEqual$2
3401
+ };
3402
+
3403
+ const diffType$1 = RenderItems;
3404
+ const isEqual$1 = (oldState, newState) => {
3405
+ return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex;
3406
+ };
3407
+
3408
+ const DiffItems = {
3409
+ __proto__: null,
3410
+ diffType: diffType$1,
3411
+ isEqual: isEqual$1
3412
+ };
3413
+
3414
+ const diffType = RenderValue;
3415
+ const isEqual = (oldState, newState) => {
3416
+ return newState.inputSource === User || oldState.value === newState.value;
3417
+ };
3418
+
3419
+ const DiffValue = {
3420
+ __proto__: null,
3421
+ diffType,
3422
+ isEqual
3423
+ };
3424
+
3425
+ const modules = [DiffHeight, DiffItems, DiffFocus, DiffFocus, DiffValue, DiffFocusedIndex];
3426
+
3427
+ const diff = (oldState, newState) => {
3428
+ const diffResult = [];
3429
+ for (const module of modules) {
3430
+ if (!module.isEqual(oldState, newState)) {
3431
+ diffResult.push(module.diffType);
3432
+ }
3433
+ }
3434
+ return diffResult;
3435
+ };
3436
+
3437
+ const doRender = uid => {
3438
+ const {
3439
+ oldState,
3440
+ newState
3441
+ } = get(uid);
3442
+ const diffResult = diff(oldState, newState);
3443
+ return applyRender(oldState, newState, diffResult);
3444
+ };
3445
+
3446
+ const wrapCommand = fn => {
3447
+ const wrapped = async (uid, ...args) => {
3448
+ const {
3449
+ newState
3450
+ } = get(uid);
3451
+ const newerState = await fn(newState, ...args);
3452
+ set(uid, newState, newerState);
3453
+ };
3454
+ return wrapped;
3455
+ };
3456
+
2822
3457
  const commandMap = {
2823
- 'FileSystemFetch.chmod': chmod$1,
2824
- 'FileSystemFetch.getBlob': getBlob$1,
2825
- 'FileSystemFetch.mkdir': mkdir$1,
2826
- 'FileSystemFetch.readDirWithFileTypes': readDirWithFileTypes$1,
2827
- 'FileSystemFetch.readFile': readFile$1,
2828
- 'FileSystemFetch.remove': remove$1,
2829
- 'FileSystemFetch.writeFile': writeFile$1,
2830
- 'FileSystemMemory.chmod': chmod,
2831
- 'FileSystemMemory.getBlob': getBlob,
2832
- 'FileSystemMemory.getBlobUrl': getBlobUrl,
2833
- 'FileSystemMemory.getFiles': getFiles,
2834
- 'FileSystemMemory.mkdir': mkdir,
2835
- 'FileSystemMemory.readDirWithFileTypes': readDirWithFileTypes,
2836
- 'FileSystemMemory.readFile': readFile,
2837
- 'FileSystemMemory.remove': remove,
2838
- 'FileSystemMemory.writeFile': writeFile,
3458
+ 'QuickPick.create': create,
3459
+ 'QuickPick.create2': create$1,
3460
+ 'QuickPick.focusIndex': wrapCommand(focusIndex),
3461
+ 'QuickPick.focusNext': wrapCommand(focusNext),
2839
3462
  'QuickPick.getKeyBindings': getKeyBindings,
2840
- 'QuickPick.loadEntries': loadQuickPickEntries,
3463
+ 'QuickPick.handleBlur': wrapCommand(handleBlur),
3464
+ 'QuickPick.handleWheel': wrapCommand(handleWheel),
3465
+ 'QuickPick.setDeltaY': wrapCommand(setDeltaY),
3466
+ 'QuickPick.loadContent': wrapCommand(loadContent),
2841
3467
  'QuickPick.loadEntries2': load,
3468
+ 'QuickPick.render': doRender,
2842
3469
  'SearchFile.filter': filterQuickPickItems,
2843
3470
  'SearchFile.searchFile': searchFile,
2844
3471
  'SearchFile.searchFileWithFetch': searchFile$3,
2845
3472
  'SearchFile.searchFileWithHtml': searchFile$2,
2846
- 'SearchFile.searchFileWithRipGrep': searchFile$1
3473
+ 'SearchFile.searchFileWithRipGrep': searchFile$1,
3474
+ // deprecated
3475
+ 'QuickPick.loadEntries': loadQuickPickEntries,
3476
+ 'FileSystemFetch.chmod': chmod,
3477
+ 'FileSystemFetch.getBlob': getBlob,
3478
+ 'FileSystemFetch.mkdir': mkdir,
3479
+ 'FileSystemFetch.readDirWithFileTypes': readDirWithFileTypes,
3480
+ 'FileSystemFetch.readFile': readFile,
3481
+ 'FileSystemFetch.remove': remove,
3482
+ 'FileSystemFetch.writeFile': writeFile,
3483
+ 'FileSystemMemory.chmod': chmod$1,
3484
+ 'FileSystemMemory.getBlob': getBlob$2,
3485
+ 'FileSystemMemory.getBlobUrl': getBlobUrl,
3486
+ 'FileSystemMemory.getFiles': getFiles,
3487
+ 'FileSystemMemory.mkdir': mkdir$1,
3488
+ 'FileSystemMemory.readDirWithFileTypes': readDirWithFileTypes$1,
3489
+ 'FileSystemMemory.readFile': readFile$1,
3490
+ 'FileSystemMemory.remove': remove$1,
3491
+ 'FileSystemMemory.writeFile': writeFile$1
2847
3492
  };
2848
3493
 
2849
3494
  const listen = async () => {