@ncukondo/reference-manager 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/format-BPeCbpFG.js +924 -0
- package/dist/chunks/format-BPeCbpFG.js.map +1 -0
- package/dist/chunks/{index-CEYp8OSj.js → index-7bmkSgzh.js} +3 -3
- package/dist/chunks/{index-CEYp8OSj.js.map → index-7bmkSgzh.js.map} +1 -1
- package/dist/chunks/{index-Bzl4_3Ki.js → index-BzHJQ7Or.js} +2 -2
- package/dist/chunks/index-BzHJQ7Or.js.map +1 -0
- package/dist/chunks/{index-4SVOiraD.js → index-Ddq16wFm.js} +15 -15
- package/dist/chunks/{index-4SVOiraD.js.map → index-Ddq16wFm.js.map} +1 -1
- package/dist/chunks/{reference-select-CgM-RBIa.js → reference-select-Cs3hsy-1.js} +2 -2
- package/dist/chunks/{reference-select-CgM-RBIa.js.map → reference-select-Cs3hsy-1.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/features/interactive/components/SearchableMultiSelect.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/format-C6FA-7hE.js +0 -397
- package/dist/chunks/format-C6FA-7hE.js.map +0 -1
- package/dist/chunks/index-Bzl4_3Ki.js.map +0 -1
|
@@ -0,0 +1,924 @@
|
|
|
1
|
+
import { j as jsxRuntimeExports } from "./jsx-runtime-Q5cUjSur.js";
|
|
2
|
+
import { useFocus, useStdout, useInput, Box, Text } from "ink";
|
|
3
|
+
import { useState, useMemo, useEffect, useCallback } from "react";
|
|
4
|
+
const ANSI_BACKGROUND_OFFSET = 10;
|
|
5
|
+
const wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
6
|
+
const wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
7
|
+
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
8
|
+
const styles = {
|
|
9
|
+
modifier: {
|
|
10
|
+
reset: [0, 0],
|
|
11
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
12
|
+
bold: [1, 22],
|
|
13
|
+
dim: [2, 22],
|
|
14
|
+
italic: [3, 23],
|
|
15
|
+
underline: [4, 24],
|
|
16
|
+
overline: [53, 55],
|
|
17
|
+
inverse: [7, 27],
|
|
18
|
+
hidden: [8, 28],
|
|
19
|
+
strikethrough: [9, 29]
|
|
20
|
+
},
|
|
21
|
+
color: {
|
|
22
|
+
black: [30, 39],
|
|
23
|
+
red: [31, 39],
|
|
24
|
+
green: [32, 39],
|
|
25
|
+
yellow: [33, 39],
|
|
26
|
+
blue: [34, 39],
|
|
27
|
+
magenta: [35, 39],
|
|
28
|
+
cyan: [36, 39],
|
|
29
|
+
white: [37, 39],
|
|
30
|
+
// Bright color
|
|
31
|
+
blackBright: [90, 39],
|
|
32
|
+
gray: [90, 39],
|
|
33
|
+
// Alias of `blackBright`
|
|
34
|
+
grey: [90, 39],
|
|
35
|
+
// Alias of `blackBright`
|
|
36
|
+
redBright: [91, 39],
|
|
37
|
+
greenBright: [92, 39],
|
|
38
|
+
yellowBright: [93, 39],
|
|
39
|
+
blueBright: [94, 39],
|
|
40
|
+
magentaBright: [95, 39],
|
|
41
|
+
cyanBright: [96, 39],
|
|
42
|
+
whiteBright: [97, 39]
|
|
43
|
+
},
|
|
44
|
+
bgColor: {
|
|
45
|
+
bgBlack: [40, 49],
|
|
46
|
+
bgRed: [41, 49],
|
|
47
|
+
bgGreen: [42, 49],
|
|
48
|
+
bgYellow: [43, 49],
|
|
49
|
+
bgBlue: [44, 49],
|
|
50
|
+
bgMagenta: [45, 49],
|
|
51
|
+
bgCyan: [46, 49],
|
|
52
|
+
bgWhite: [47, 49],
|
|
53
|
+
// Bright color
|
|
54
|
+
bgBlackBright: [100, 49],
|
|
55
|
+
bgGray: [100, 49],
|
|
56
|
+
// Alias of `bgBlackBright`
|
|
57
|
+
bgGrey: [100, 49],
|
|
58
|
+
// Alias of `bgBlackBright`
|
|
59
|
+
bgRedBright: [101, 49],
|
|
60
|
+
bgGreenBright: [102, 49],
|
|
61
|
+
bgYellowBright: [103, 49],
|
|
62
|
+
bgBlueBright: [104, 49],
|
|
63
|
+
bgMagentaBright: [105, 49],
|
|
64
|
+
bgCyanBright: [106, 49],
|
|
65
|
+
bgWhiteBright: [107, 49]
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
Object.keys(styles.modifier);
|
|
69
|
+
const foregroundColorNames = Object.keys(styles.color);
|
|
70
|
+
const backgroundColorNames = Object.keys(styles.bgColor);
|
|
71
|
+
[...foregroundColorNames, ...backgroundColorNames];
|
|
72
|
+
function assembleStyles() {
|
|
73
|
+
const codes = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
75
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
76
|
+
styles[styleName] = {
|
|
77
|
+
open: `\x1B[${style[0]}m`,
|
|
78
|
+
close: `\x1B[${style[1]}m`
|
|
79
|
+
};
|
|
80
|
+
group[styleName] = styles[styleName];
|
|
81
|
+
codes.set(style[0], style[1]);
|
|
82
|
+
}
|
|
83
|
+
Object.defineProperty(styles, groupName, {
|
|
84
|
+
value: group,
|
|
85
|
+
enumerable: false
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
Object.defineProperty(styles, "codes", {
|
|
89
|
+
value: codes,
|
|
90
|
+
enumerable: false
|
|
91
|
+
});
|
|
92
|
+
styles.color.close = "\x1B[39m";
|
|
93
|
+
styles.bgColor.close = "\x1B[49m";
|
|
94
|
+
styles.color.ansi = wrapAnsi16();
|
|
95
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
96
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
97
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
98
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
99
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
100
|
+
Object.defineProperties(styles, {
|
|
101
|
+
rgbToAnsi256: {
|
|
102
|
+
value(red, green, blue) {
|
|
103
|
+
if (red === green && green === blue) {
|
|
104
|
+
if (red < 8) {
|
|
105
|
+
return 16;
|
|
106
|
+
}
|
|
107
|
+
if (red > 248) {
|
|
108
|
+
return 231;
|
|
109
|
+
}
|
|
110
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
111
|
+
}
|
|
112
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
113
|
+
},
|
|
114
|
+
enumerable: false
|
|
115
|
+
},
|
|
116
|
+
hexToRgb: {
|
|
117
|
+
value(hex) {
|
|
118
|
+
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
119
|
+
if (!matches) {
|
|
120
|
+
return [0, 0, 0];
|
|
121
|
+
}
|
|
122
|
+
let [colorString] = matches;
|
|
123
|
+
if (colorString.length === 3) {
|
|
124
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
125
|
+
}
|
|
126
|
+
const integer = Number.parseInt(colorString, 16);
|
|
127
|
+
return [
|
|
128
|
+
/* eslint-disable no-bitwise */
|
|
129
|
+
integer >> 16 & 255,
|
|
130
|
+
integer >> 8 & 255,
|
|
131
|
+
integer & 255
|
|
132
|
+
/* eslint-enable no-bitwise */
|
|
133
|
+
];
|
|
134
|
+
},
|
|
135
|
+
enumerable: false
|
|
136
|
+
},
|
|
137
|
+
hexToAnsi256: {
|
|
138
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
139
|
+
enumerable: false
|
|
140
|
+
},
|
|
141
|
+
ansi256ToAnsi: {
|
|
142
|
+
value(code) {
|
|
143
|
+
if (code < 8) {
|
|
144
|
+
return 30 + code;
|
|
145
|
+
}
|
|
146
|
+
if (code < 16) {
|
|
147
|
+
return 90 + (code - 8);
|
|
148
|
+
}
|
|
149
|
+
let red;
|
|
150
|
+
let green;
|
|
151
|
+
let blue;
|
|
152
|
+
if (code >= 232) {
|
|
153
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
154
|
+
green = red;
|
|
155
|
+
blue = red;
|
|
156
|
+
} else {
|
|
157
|
+
code -= 16;
|
|
158
|
+
const remainder = code % 36;
|
|
159
|
+
red = Math.floor(code / 36) / 5;
|
|
160
|
+
green = Math.floor(remainder / 6) / 5;
|
|
161
|
+
blue = remainder % 6 / 5;
|
|
162
|
+
}
|
|
163
|
+
const value = Math.max(red, green, blue) * 2;
|
|
164
|
+
if (value === 0) {
|
|
165
|
+
return 30;
|
|
166
|
+
}
|
|
167
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
168
|
+
if (value === 2) {
|
|
169
|
+
result += 60;
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
},
|
|
173
|
+
enumerable: false
|
|
174
|
+
},
|
|
175
|
+
rgbToAnsi: {
|
|
176
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
177
|
+
enumerable: false
|
|
178
|
+
},
|
|
179
|
+
hexToAnsi: {
|
|
180
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
181
|
+
enumerable: false
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return styles;
|
|
185
|
+
}
|
|
186
|
+
const ansiStyles = assembleStyles();
|
|
187
|
+
function isAmbiguous(x) {
|
|
188
|
+
return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
|
|
189
|
+
}
|
|
190
|
+
function isFullWidth(x) {
|
|
191
|
+
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
192
|
+
}
|
|
193
|
+
function isWide(x) {
|
|
194
|
+
return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
195
|
+
}
|
|
196
|
+
function validate(codePoint) {
|
|
197
|
+
if (!Number.isSafeInteger(codePoint)) {
|
|
198
|
+
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
|
|
202
|
+
validate(codePoint);
|
|
203
|
+
if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
|
|
204
|
+
return 2;
|
|
205
|
+
}
|
|
206
|
+
return 1;
|
|
207
|
+
}
|
|
208
|
+
function isFullwidthCodePoint(codePoint) {
|
|
209
|
+
if (!Number.isInteger(codePoint)) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
return isFullWidth(codePoint) || isWide(codePoint);
|
|
213
|
+
}
|
|
214
|
+
const ESCAPES = /* @__PURE__ */ new Set([27, 155]);
|
|
215
|
+
const CODE_POINT_0 = "0".codePointAt(0);
|
|
216
|
+
const CODE_POINT_9 = "9".codePointAt(0);
|
|
217
|
+
const MAX_ANSI_SEQUENCE_LENGTH = 19;
|
|
218
|
+
const endCodesSet = /* @__PURE__ */ new Set();
|
|
219
|
+
const endCodesMap = /* @__PURE__ */ new Map();
|
|
220
|
+
for (const [start, end] of ansiStyles.codes) {
|
|
221
|
+
endCodesSet.add(ansiStyles.color.ansi(end));
|
|
222
|
+
endCodesMap.set(ansiStyles.color.ansi(start), ansiStyles.color.ansi(end));
|
|
223
|
+
}
|
|
224
|
+
function getEndCode(code) {
|
|
225
|
+
if (endCodesSet.has(code)) {
|
|
226
|
+
return code;
|
|
227
|
+
}
|
|
228
|
+
if (endCodesMap.has(code)) {
|
|
229
|
+
return endCodesMap.get(code);
|
|
230
|
+
}
|
|
231
|
+
code = code.slice(2);
|
|
232
|
+
if (code.includes(";")) {
|
|
233
|
+
code = code[0] + "0";
|
|
234
|
+
}
|
|
235
|
+
const returnValue = ansiStyles.codes.get(Number.parseInt(code, 10));
|
|
236
|
+
if (returnValue) {
|
|
237
|
+
return ansiStyles.color.ansi(returnValue);
|
|
238
|
+
}
|
|
239
|
+
return ansiStyles.reset.open;
|
|
240
|
+
}
|
|
241
|
+
function findNumberIndex(string) {
|
|
242
|
+
for (let index = 0; index < string.length; index++) {
|
|
243
|
+
const codePoint = string.codePointAt(index);
|
|
244
|
+
if (codePoint >= CODE_POINT_0 && codePoint <= CODE_POINT_9) {
|
|
245
|
+
return index;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return -1;
|
|
249
|
+
}
|
|
250
|
+
function parseAnsiCode(string, offset) {
|
|
251
|
+
string = string.slice(offset, offset + MAX_ANSI_SEQUENCE_LENGTH);
|
|
252
|
+
const startIndex = findNumberIndex(string);
|
|
253
|
+
if (startIndex !== -1) {
|
|
254
|
+
let endIndex = string.indexOf("m", startIndex);
|
|
255
|
+
if (endIndex === -1) {
|
|
256
|
+
endIndex = string.length;
|
|
257
|
+
}
|
|
258
|
+
return string.slice(0, endIndex + 1);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function tokenize(string, endCharacter = Number.POSITIVE_INFINITY) {
|
|
262
|
+
const returnValue = [];
|
|
263
|
+
let index = 0;
|
|
264
|
+
let visibleCount = 0;
|
|
265
|
+
while (index < string.length) {
|
|
266
|
+
const codePoint = string.codePointAt(index);
|
|
267
|
+
if (ESCAPES.has(codePoint)) {
|
|
268
|
+
const code = parseAnsiCode(string, index);
|
|
269
|
+
if (code) {
|
|
270
|
+
returnValue.push({
|
|
271
|
+
type: "ansi",
|
|
272
|
+
code,
|
|
273
|
+
endCode: getEndCode(code)
|
|
274
|
+
});
|
|
275
|
+
index += code.length;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const isFullWidth2 = isFullwidthCodePoint(codePoint);
|
|
280
|
+
const character = String.fromCodePoint(codePoint);
|
|
281
|
+
returnValue.push({
|
|
282
|
+
type: "character",
|
|
283
|
+
value: character,
|
|
284
|
+
isFullWidth: isFullWidth2
|
|
285
|
+
});
|
|
286
|
+
index += character.length;
|
|
287
|
+
visibleCount += isFullWidth2 ? 2 : character.length;
|
|
288
|
+
if (visibleCount >= endCharacter) {
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return returnValue;
|
|
293
|
+
}
|
|
294
|
+
function reduceAnsiCodes(codes) {
|
|
295
|
+
let returnValue = [];
|
|
296
|
+
for (const code of codes) {
|
|
297
|
+
if (code.code === ansiStyles.reset.open) {
|
|
298
|
+
returnValue = [];
|
|
299
|
+
} else if (endCodesSet.has(code.code)) {
|
|
300
|
+
returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.code);
|
|
301
|
+
} else {
|
|
302
|
+
returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.endCode);
|
|
303
|
+
returnValue.push(code);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return returnValue;
|
|
307
|
+
}
|
|
308
|
+
function undoAnsiCodes(codes) {
|
|
309
|
+
const reduced = reduceAnsiCodes(codes);
|
|
310
|
+
const endCodes = reduced.map(({ endCode }) => endCode);
|
|
311
|
+
return endCodes.reverse().join("");
|
|
312
|
+
}
|
|
313
|
+
function sliceAnsi(string, start, end) {
|
|
314
|
+
const tokens = tokenize(string, end);
|
|
315
|
+
let activeCodes = [];
|
|
316
|
+
let position = 0;
|
|
317
|
+
let returnValue = "";
|
|
318
|
+
let include = false;
|
|
319
|
+
for (const token of tokens) {
|
|
320
|
+
if (end !== void 0 && position >= end) {
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
if (token.type === "ansi") {
|
|
324
|
+
activeCodes.push(token);
|
|
325
|
+
if (include) {
|
|
326
|
+
returnValue += token.code;
|
|
327
|
+
}
|
|
328
|
+
} else {
|
|
329
|
+
if (!include && position >= start) {
|
|
330
|
+
include = true;
|
|
331
|
+
activeCodes = reduceAnsiCodes(activeCodes);
|
|
332
|
+
returnValue = activeCodes.map(({ code }) => code).join("");
|
|
333
|
+
}
|
|
334
|
+
if (include) {
|
|
335
|
+
returnValue += token.value;
|
|
336
|
+
}
|
|
337
|
+
position += token.isFullWidth ? 2 : token.value.length;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
returnValue += undoAnsiCodes(activeCodes);
|
|
341
|
+
return returnValue;
|
|
342
|
+
}
|
|
343
|
+
function ansiRegex({ onlyFirst = false } = {}) {
|
|
344
|
+
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
345
|
+
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
346
|
+
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
|
|
347
|
+
const pattern = `${osc}|${csi}`;
|
|
348
|
+
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
349
|
+
}
|
|
350
|
+
const regex = ansiRegex();
|
|
351
|
+
function stripAnsi(string) {
|
|
352
|
+
if (typeof string !== "string") {
|
|
353
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
354
|
+
}
|
|
355
|
+
return string.replace(regex, "");
|
|
356
|
+
}
|
|
357
|
+
const segmenter = new Intl.Segmenter();
|
|
358
|
+
const zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Mark}|\\p{Surrogate})+$", "v");
|
|
359
|
+
const leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Mark}\\p{Surrogate}]+", "v");
|
|
360
|
+
const rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
|
|
361
|
+
function baseVisible(segment) {
|
|
362
|
+
return segment.replace(leadingNonPrintingRegex, "");
|
|
363
|
+
}
|
|
364
|
+
function isZeroWidthCluster(segment) {
|
|
365
|
+
return zeroWidthClusterRegex.test(segment);
|
|
366
|
+
}
|
|
367
|
+
function trailingHalfwidthWidth(segment, eastAsianWidthOptions) {
|
|
368
|
+
let extra = 0;
|
|
369
|
+
if (segment.length > 1) {
|
|
370
|
+
for (const char of segment.slice(1)) {
|
|
371
|
+
if (char >= "" && char <= "") {
|
|
372
|
+
extra += eastAsianWidth(char.codePointAt(0), eastAsianWidthOptions);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return extra;
|
|
377
|
+
}
|
|
378
|
+
function stringWidth(input, options = {}) {
|
|
379
|
+
if (typeof input !== "string" || input.length === 0) {
|
|
380
|
+
return 0;
|
|
381
|
+
}
|
|
382
|
+
const {
|
|
383
|
+
ambiguousIsNarrow = true,
|
|
384
|
+
countAnsiEscapeCodes = false
|
|
385
|
+
} = options;
|
|
386
|
+
let string = input;
|
|
387
|
+
if (!countAnsiEscapeCodes) {
|
|
388
|
+
string = stripAnsi(string);
|
|
389
|
+
}
|
|
390
|
+
if (string.length === 0) {
|
|
391
|
+
return 0;
|
|
392
|
+
}
|
|
393
|
+
let width = 0;
|
|
394
|
+
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
395
|
+
for (const { segment } of segmenter.segment(string)) {
|
|
396
|
+
if (isZeroWidthCluster(segment)) {
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
if (rgiEmojiRegex.test(segment)) {
|
|
400
|
+
width += 2;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
const codePoint = baseVisible(segment).codePointAt(0);
|
|
404
|
+
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
405
|
+
width += trailingHalfwidthWidth(segment, eastAsianWidthOptions);
|
|
406
|
+
}
|
|
407
|
+
return width;
|
|
408
|
+
}
|
|
409
|
+
function getIndexOfNearestSpace(string, wantedIndex, shouldSearchRight) {
|
|
410
|
+
if (string.charAt(wantedIndex) === " ") {
|
|
411
|
+
return wantedIndex;
|
|
412
|
+
}
|
|
413
|
+
const direction = shouldSearchRight ? 1 : -1;
|
|
414
|
+
for (let index = 0; index <= 3; index++) {
|
|
415
|
+
const finalIndex = wantedIndex + index * direction;
|
|
416
|
+
if (string.charAt(finalIndex) === " ") {
|
|
417
|
+
return finalIndex;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return wantedIndex;
|
|
421
|
+
}
|
|
422
|
+
function cliTruncate(text, columns, options = {}) {
|
|
423
|
+
const {
|
|
424
|
+
position = "end",
|
|
425
|
+
space = false,
|
|
426
|
+
preferTruncationOnSpace = false
|
|
427
|
+
} = options;
|
|
428
|
+
let { truncationCharacter = "…" } = options;
|
|
429
|
+
if (typeof text !== "string") {
|
|
430
|
+
throw new TypeError(`Expected \`input\` to be a string, got ${typeof text}`);
|
|
431
|
+
}
|
|
432
|
+
if (typeof columns !== "number") {
|
|
433
|
+
throw new TypeError(`Expected \`columns\` to be a number, got ${typeof columns}`);
|
|
434
|
+
}
|
|
435
|
+
if (columns < 1) {
|
|
436
|
+
return "";
|
|
437
|
+
}
|
|
438
|
+
const length = stringWidth(text);
|
|
439
|
+
if (length <= columns) {
|
|
440
|
+
return text;
|
|
441
|
+
}
|
|
442
|
+
if (columns === 1) {
|
|
443
|
+
return truncationCharacter;
|
|
444
|
+
}
|
|
445
|
+
const ANSI = {
|
|
446
|
+
ESC: 27,
|
|
447
|
+
LEFT_BRACKET: 91,
|
|
448
|
+
LETTER_M: 109
|
|
449
|
+
};
|
|
450
|
+
const isSgrParameter = (code) => code >= 48 && code <= 57 || code === 59;
|
|
451
|
+
function leadingSgrSpanEndIndex(string) {
|
|
452
|
+
let index = 0;
|
|
453
|
+
while (index + 2 < string.length && string.codePointAt(index) === ANSI.ESC && string.codePointAt(index + 1) === ANSI.LEFT_BRACKET) {
|
|
454
|
+
let j = index + 2;
|
|
455
|
+
while (j < string.length && isSgrParameter(string.codePointAt(j))) {
|
|
456
|
+
j++;
|
|
457
|
+
}
|
|
458
|
+
if (j < string.length && string.codePointAt(j) === ANSI.LETTER_M) {
|
|
459
|
+
index = j + 1;
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
return index;
|
|
465
|
+
}
|
|
466
|
+
function trailingSgrSpanStartIndex(string) {
|
|
467
|
+
let start = string.length;
|
|
468
|
+
while (start > 1 && string.codePointAt(start - 1) === ANSI.LETTER_M) {
|
|
469
|
+
let j = start - 2;
|
|
470
|
+
while (j >= 0 && isSgrParameter(string.codePointAt(j))) {
|
|
471
|
+
j--;
|
|
472
|
+
}
|
|
473
|
+
if (j >= 1 && string.codePointAt(j - 1) === ANSI.ESC && string.codePointAt(j) === ANSI.LEFT_BRACKET) {
|
|
474
|
+
start = j - 1;
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
return start;
|
|
480
|
+
}
|
|
481
|
+
function appendWithInheritedStyleFromEnd(visible, suffix) {
|
|
482
|
+
const start = trailingSgrSpanStartIndex(visible);
|
|
483
|
+
if (start === visible.length) {
|
|
484
|
+
return visible + suffix;
|
|
485
|
+
}
|
|
486
|
+
return visible.slice(0, start) + suffix + visible.slice(start);
|
|
487
|
+
}
|
|
488
|
+
function prependWithInheritedStyleFromStart(prefix, visible) {
|
|
489
|
+
const end = leadingSgrSpanEndIndex(visible);
|
|
490
|
+
if (end === 0) {
|
|
491
|
+
return prefix + visible;
|
|
492
|
+
}
|
|
493
|
+
return visible.slice(0, end) + prefix + visible.slice(end);
|
|
494
|
+
}
|
|
495
|
+
if (position === "start") {
|
|
496
|
+
if (preferTruncationOnSpace) {
|
|
497
|
+
const nearestSpace = getIndexOfNearestSpace(text, length - columns + 1, true);
|
|
498
|
+
const right2 = sliceAnsi(text, nearestSpace, length).trim();
|
|
499
|
+
return prependWithInheritedStyleFromStart(truncationCharacter, right2);
|
|
500
|
+
}
|
|
501
|
+
if (space) {
|
|
502
|
+
truncationCharacter += " ";
|
|
503
|
+
}
|
|
504
|
+
const right = sliceAnsi(text, length - columns + stringWidth(truncationCharacter), length);
|
|
505
|
+
return prependWithInheritedStyleFromStart(truncationCharacter, right);
|
|
506
|
+
}
|
|
507
|
+
if (position === "middle") {
|
|
508
|
+
if (space) {
|
|
509
|
+
truncationCharacter = ` ${truncationCharacter} `;
|
|
510
|
+
}
|
|
511
|
+
const half = Math.floor(columns / 2);
|
|
512
|
+
if (preferTruncationOnSpace) {
|
|
513
|
+
const spaceNearFirstBreakPoint = getIndexOfNearestSpace(text, half);
|
|
514
|
+
const spaceNearSecondBreakPoint = getIndexOfNearestSpace(text, length - (columns - half) + 1, true);
|
|
515
|
+
return sliceAnsi(text, 0, spaceNearFirstBreakPoint) + truncationCharacter + sliceAnsi(text, spaceNearSecondBreakPoint, length).trim();
|
|
516
|
+
}
|
|
517
|
+
return sliceAnsi(text, 0, half) + truncationCharacter + sliceAnsi(text, length - (columns - half) + stringWidth(truncationCharacter), length);
|
|
518
|
+
}
|
|
519
|
+
if (position === "end") {
|
|
520
|
+
if (preferTruncationOnSpace) {
|
|
521
|
+
const nearestSpace = getIndexOfNearestSpace(text, columns - 1);
|
|
522
|
+
const left2 = sliceAnsi(text, 0, nearestSpace);
|
|
523
|
+
return appendWithInheritedStyleFromEnd(left2, truncationCharacter);
|
|
524
|
+
}
|
|
525
|
+
if (space) {
|
|
526
|
+
truncationCharacter = ` ${truncationCharacter}`;
|
|
527
|
+
}
|
|
528
|
+
const left = sliceAnsi(text, 0, columns - stringWidth(truncationCharacter));
|
|
529
|
+
return appendWithInheritedStyleFromEnd(left, truncationCharacter);
|
|
530
|
+
}
|
|
531
|
+
throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${position}`);
|
|
532
|
+
}
|
|
533
|
+
const SORT_OPTIONS = [
|
|
534
|
+
{ id: "updated-desc", label: "Updated (newest first)", requiresQuery: false },
|
|
535
|
+
{ id: "updated-asc", label: "Updated (oldest first)", requiresQuery: false },
|
|
536
|
+
{ id: "created-desc", label: "Created (newest first)", requiresQuery: false },
|
|
537
|
+
{ id: "created-asc", label: "Created (oldest first)", requiresQuery: false },
|
|
538
|
+
{ id: "published-desc", label: "Published (newest first)", requiresQuery: false },
|
|
539
|
+
{ id: "published-asc", label: "Published (oldest first)", requiresQuery: false },
|
|
540
|
+
{ id: "relevance", label: "Relevance", requiresQuery: true }
|
|
541
|
+
];
|
|
542
|
+
function getSortShortLabel(sortOption) {
|
|
543
|
+
switch (sortOption) {
|
|
544
|
+
case "updated-desc":
|
|
545
|
+
return "Updated ↓";
|
|
546
|
+
case "updated-asc":
|
|
547
|
+
return "Updated ↑";
|
|
548
|
+
case "created-desc":
|
|
549
|
+
return "Created ↓";
|
|
550
|
+
case "created-asc":
|
|
551
|
+
return "Created ↑";
|
|
552
|
+
case "published-desc":
|
|
553
|
+
return "Published ↓";
|
|
554
|
+
case "published-asc":
|
|
555
|
+
return "Published ↑";
|
|
556
|
+
case "relevance":
|
|
557
|
+
return "Relevance";
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
function createDateComparator(getDate, descending) {
|
|
561
|
+
return (a, b) => {
|
|
562
|
+
const dateA = getDate(a)?.getTime() ?? 0;
|
|
563
|
+
const dateB = getDate(b)?.getTime() ?? 0;
|
|
564
|
+
return descending ? dateB - dateA : dateA - dateB;
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
function sortChoices(choices, sortOption) {
|
|
568
|
+
if (sortOption === "relevance") return [...choices];
|
|
569
|
+
const sorted = [...choices];
|
|
570
|
+
const comparators = {
|
|
571
|
+
"updated-desc": createDateComparator((c) => c.updatedDate, true),
|
|
572
|
+
"updated-asc": createDateComparator((c) => c.updatedDate, false),
|
|
573
|
+
"created-desc": createDateComparator((c) => c.createdDate, true),
|
|
574
|
+
"created-asc": createDateComparator((c) => c.createdDate, false),
|
|
575
|
+
"published-desc": createDateComparator((c) => c.publishedDate, true),
|
|
576
|
+
"published-asc": createDateComparator((c) => c.publishedDate, false)
|
|
577
|
+
};
|
|
578
|
+
return sorted.sort(comparators[sortOption]);
|
|
579
|
+
}
|
|
580
|
+
function defaultFilter(query, choices) {
|
|
581
|
+
if (!query.trim()) return choices;
|
|
582
|
+
const lowerQuery = query.toLowerCase();
|
|
583
|
+
return choices.filter(
|
|
584
|
+
(choice) => choice.title.toLowerCase().includes(lowerQuery) || choice.subtitle?.toLowerCase().includes(lowerQuery) || choice.meta?.toLowerCase().includes(lowerQuery)
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
function truncate(text, maxWidth) {
|
|
588
|
+
return cliTruncate(text, maxWidth, { position: "end" });
|
|
589
|
+
}
|
|
590
|
+
function getNavigationDelta(key, input, visibleCount, maxIndex) {
|
|
591
|
+
if (key.upArrow) return -1;
|
|
592
|
+
if (key.downArrow) return 1;
|
|
593
|
+
if (key.pageUp) return -visibleCount;
|
|
594
|
+
if (key.pageDown) return visibleCount;
|
|
595
|
+
if (key.ctrl && input === "a") return -maxIndex - 1;
|
|
596
|
+
if (key.ctrl && input === "e") return maxIndex + 1;
|
|
597
|
+
return null;
|
|
598
|
+
}
|
|
599
|
+
function parseKeyAction(input, key, visibleCount, maxIndex) {
|
|
600
|
+
if (key.escape) return { type: "cancel" };
|
|
601
|
+
if (key.return) return { type: "submit" };
|
|
602
|
+
const navDelta = getNavigationDelta(key, input, visibleCount, maxIndex);
|
|
603
|
+
if (navDelta !== null) return { type: "navigate", delta: navDelta };
|
|
604
|
+
if (key.ctrl && input === "s") return { type: "sort" };
|
|
605
|
+
if (key.tab) return { type: "toggle" };
|
|
606
|
+
if (key.backspace || key.delete) return { type: "backspace" };
|
|
607
|
+
if (input && !key.ctrl && !key.meta) return { type: "input", char: input };
|
|
608
|
+
return { type: "none" };
|
|
609
|
+
}
|
|
610
|
+
function ChoiceItem({
|
|
611
|
+
choice,
|
|
612
|
+
isSelected,
|
|
613
|
+
isFocused,
|
|
614
|
+
contentWidth
|
|
615
|
+
}) {
|
|
616
|
+
const indent = " ";
|
|
617
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { flexDirection: "column", paddingY: 0, children: [
|
|
618
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { flexDirection: "row", children: [
|
|
619
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { width: 2, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { color: "cyan", children: isFocused ? "❯" : " " }) }),
|
|
620
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { width: 2, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { color: isSelected ? "green" : "gray", children: isSelected ? "◉" : "○" }) }),
|
|
621
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { width: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { children: " " }) }),
|
|
622
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: isFocused ? /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { color: "cyan", bold: true, children: truncate(choice.title, contentWidth) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { color: "blue", children: truncate(choice.title, contentWidth) }) })
|
|
623
|
+
] }),
|
|
624
|
+
choice.subtitle && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { dimColor: true, children: [
|
|
625
|
+
indent,
|
|
626
|
+
truncate(choice.subtitle, contentWidth)
|
|
627
|
+
] }) }),
|
|
628
|
+
choice.meta && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { dimColor: true, children: [
|
|
629
|
+
indent,
|
|
630
|
+
truncate(choice.meta, contentWidth)
|
|
631
|
+
] }) })
|
|
632
|
+
] });
|
|
633
|
+
}
|
|
634
|
+
function ScrollIndicator({
|
|
635
|
+
direction,
|
|
636
|
+
count,
|
|
637
|
+
visible
|
|
638
|
+
}) {
|
|
639
|
+
const arrow = direction === "up" ? "↑" : "↓";
|
|
640
|
+
const label = direction === "up" ? "more above" : "more below";
|
|
641
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { height: 1, children: visible && count > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { dimColor: true, children: [
|
|
642
|
+
" ",
|
|
643
|
+
arrow,
|
|
644
|
+
" ",
|
|
645
|
+
count,
|
|
646
|
+
" ",
|
|
647
|
+
label
|
|
648
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { children: " " }) });
|
|
649
|
+
}
|
|
650
|
+
function ChoiceList({
|
|
651
|
+
choices,
|
|
652
|
+
selectedIds,
|
|
653
|
+
focusIndex,
|
|
654
|
+
scrollOffset,
|
|
655
|
+
contentWidth
|
|
656
|
+
}) {
|
|
657
|
+
if (choices.length === 0) {
|
|
658
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { dimColor: true, children: "No results found" }) });
|
|
659
|
+
}
|
|
660
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { flexDirection: "column", children: choices.map((choice, visibleIndex) => {
|
|
661
|
+
const actualIndex = scrollOffset + visibleIndex;
|
|
662
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
663
|
+
ChoiceItem,
|
|
664
|
+
{
|
|
665
|
+
choice,
|
|
666
|
+
isSelected: selectedIds.has(choice.id),
|
|
667
|
+
isFocused: actualIndex === focusIndex,
|
|
668
|
+
contentWidth
|
|
669
|
+
}
|
|
670
|
+
) }, choice.id);
|
|
671
|
+
}) });
|
|
672
|
+
}
|
|
673
|
+
function SortMenu({
|
|
674
|
+
options,
|
|
675
|
+
focusIndex,
|
|
676
|
+
currentSort
|
|
677
|
+
}) {
|
|
678
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
679
|
+
Box,
|
|
680
|
+
{
|
|
681
|
+
flexDirection: "column",
|
|
682
|
+
marginBottom: 1,
|
|
683
|
+
paddingX: 1,
|
|
684
|
+
borderStyle: "round",
|
|
685
|
+
borderColor: "yellow",
|
|
686
|
+
children: [
|
|
687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { bold: true, color: "yellow", children: "Sort by:" }) }),
|
|
688
|
+
options.map((opt, index) => {
|
|
689
|
+
const isFocused = index === focusIndex;
|
|
690
|
+
const isCurrent = opt.id === currentSort;
|
|
691
|
+
const checkMark = isCurrent ? " ✓" : "";
|
|
692
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: isFocused ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { color: "cyan", children: [
|
|
693
|
+
"❯ ",
|
|
694
|
+
opt.label,
|
|
695
|
+
checkMark
|
|
696
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { children: [
|
|
697
|
+
" ",
|
|
698
|
+
opt.label,
|
|
699
|
+
checkMark
|
|
700
|
+
] }) }, opt.id);
|
|
701
|
+
}),
|
|
702
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { dimColor: true, children: "↑↓:select Enter:confirm Esc:cancel" }) })
|
|
703
|
+
]
|
|
704
|
+
}
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
function SearchableMultiSelect({
|
|
708
|
+
choices,
|
|
709
|
+
filterFn = defaultFilter,
|
|
710
|
+
visibleCount: visibleCountProp,
|
|
711
|
+
onSubmit,
|
|
712
|
+
onCancel,
|
|
713
|
+
placeholder = "Type to search...",
|
|
714
|
+
header,
|
|
715
|
+
footer,
|
|
716
|
+
defaultSort = "updated-desc"
|
|
717
|
+
}) {
|
|
718
|
+
const [query, setQuery] = useState("");
|
|
719
|
+
const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
|
|
720
|
+
const [focusIndex, setFocusIndex] = useState(0);
|
|
721
|
+
const [scrollOffset, setScrollOffset] = useState(0);
|
|
722
|
+
const [sortOption, setSortOption] = useState(defaultSort);
|
|
723
|
+
const [showSortMenu, setShowSortMenu] = useState(false);
|
|
724
|
+
const [sortMenuIndex, setSortMenuIndex] = useState(0);
|
|
725
|
+
const { isFocused } = useFocus({ autoFocus: true });
|
|
726
|
+
const { stdout } = useStdout();
|
|
727
|
+
const terminalWidth = stdout?.columns ?? 80;
|
|
728
|
+
const terminalHeight = stdout?.rows ?? 24;
|
|
729
|
+
const contentWidth = terminalWidth - 8;
|
|
730
|
+
const itemHeight = 3;
|
|
731
|
+
const reservedLines = 10;
|
|
732
|
+
const calculatedVisibleCount = Math.max(
|
|
733
|
+
1,
|
|
734
|
+
Math.floor((terminalHeight - reservedLines) / itemHeight)
|
|
735
|
+
);
|
|
736
|
+
const visibleCount = visibleCountProp ?? calculatedVisibleCount;
|
|
737
|
+
const filteredChoices = useMemo(() => filterFn(query, choices), [query, choices, filterFn]);
|
|
738
|
+
const availableSortOptions = useMemo(
|
|
739
|
+
() => SORT_OPTIONS.filter((opt) => !opt.requiresQuery || query.trim().length > 0),
|
|
740
|
+
[query]
|
|
741
|
+
);
|
|
742
|
+
const sortedChoices = useMemo(
|
|
743
|
+
() => sortOption === "relevance" ? filteredChoices : sortChoices(filteredChoices, sortOption),
|
|
744
|
+
[filteredChoices, sortOption]
|
|
745
|
+
);
|
|
746
|
+
const maxIndex = sortedChoices.length - 1;
|
|
747
|
+
useEffect(() => {
|
|
748
|
+
setFocusIndex(0);
|
|
749
|
+
setScrollOffset(0);
|
|
750
|
+
}, [query]);
|
|
751
|
+
useEffect(() => {
|
|
752
|
+
if (focusIndex < scrollOffset) {
|
|
753
|
+
setScrollOffset(focusIndex);
|
|
754
|
+
} else if (focusIndex >= scrollOffset + visibleCount) {
|
|
755
|
+
setScrollOffset(focusIndex - visibleCount + 1);
|
|
756
|
+
}
|
|
757
|
+
}, [focusIndex, scrollOffset, visibleCount]);
|
|
758
|
+
const visibleChoices = useMemo(
|
|
759
|
+
() => sortedChoices.slice(scrollOffset, scrollOffset + visibleCount),
|
|
760
|
+
[sortedChoices, scrollOffset, visibleCount]
|
|
761
|
+
);
|
|
762
|
+
const toggleSelection = useCallback(() => {
|
|
763
|
+
const currentChoice = sortedChoices[focusIndex];
|
|
764
|
+
if (!currentChoice) return;
|
|
765
|
+
setSelectedIds((prev) => {
|
|
766
|
+
const newSet = new Set(prev);
|
|
767
|
+
if (newSet.has(currentChoice.id)) {
|
|
768
|
+
newSet.delete(currentChoice.id);
|
|
769
|
+
} else {
|
|
770
|
+
newSet.add(currentChoice.id);
|
|
771
|
+
}
|
|
772
|
+
return newSet;
|
|
773
|
+
});
|
|
774
|
+
}, [sortedChoices, focusIndex]);
|
|
775
|
+
useInput(
|
|
776
|
+
(_input, key) => {
|
|
777
|
+
if (key.escape) {
|
|
778
|
+
setShowSortMenu(false);
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
if (key.return) {
|
|
782
|
+
const selected = availableSortOptions[sortMenuIndex];
|
|
783
|
+
if (selected) {
|
|
784
|
+
setSortOption(selected.id);
|
|
785
|
+
setFocusIndex(0);
|
|
786
|
+
setScrollOffset(0);
|
|
787
|
+
}
|
|
788
|
+
setShowSortMenu(false);
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (key.upArrow) {
|
|
792
|
+
setSortMenuIndex((prev) => Math.max(0, prev - 1));
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
if (key.downArrow) {
|
|
796
|
+
setSortMenuIndex((prev) => Math.min(availableSortOptions.length - 1, prev + 1));
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
},
|
|
800
|
+
{ isActive: isFocused && showSortMenu }
|
|
801
|
+
);
|
|
802
|
+
useInput(
|
|
803
|
+
(input, key) => {
|
|
804
|
+
const action = parseKeyAction(input, key, visibleCount, maxIndex);
|
|
805
|
+
switch (action.type) {
|
|
806
|
+
case "cancel":
|
|
807
|
+
onCancel();
|
|
808
|
+
break;
|
|
809
|
+
case "submit":
|
|
810
|
+
onSubmit(choices.filter((c) => selectedIds.has(c.id)));
|
|
811
|
+
break;
|
|
812
|
+
case "navigate":
|
|
813
|
+
setFocusIndex((prev) => Math.max(0, Math.min(maxIndex, prev + action.delta)));
|
|
814
|
+
break;
|
|
815
|
+
case "toggle":
|
|
816
|
+
toggleSelection();
|
|
817
|
+
break;
|
|
818
|
+
case "backspace":
|
|
819
|
+
setQuery((prev) => prev.slice(0, -1));
|
|
820
|
+
break;
|
|
821
|
+
case "input":
|
|
822
|
+
setQuery((prev) => prev + action.char);
|
|
823
|
+
break;
|
|
824
|
+
case "sort":
|
|
825
|
+
setSortMenuIndex(availableSortOptions.findIndex((o) => o.id === sortOption));
|
|
826
|
+
setShowSortMenu(true);
|
|
827
|
+
break;
|
|
828
|
+
}
|
|
829
|
+
},
|
|
830
|
+
{ isActive: isFocused && !showSortMenu }
|
|
831
|
+
);
|
|
832
|
+
const totalItems = sortedChoices.length;
|
|
833
|
+
const showScrollIndicator = totalItems > visibleCount;
|
|
834
|
+
const footerText = footer ?? (showScrollIndicator ? `↑↓:move Tab:select ^S:sort Enter:confirm (${focusIndex + 1}/${totalItems})` : "↑↓:move Tab:select ^S:sort Enter:confirm Esc:cancel");
|
|
835
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
836
|
+
header && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { bold: true, color: "cyan", children: header }) }),
|
|
837
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { marginBottom: 1, paddingX: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Text, { color: "green", children: "❯ " }),
|
|
839
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Text, { children: query || /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { dimColor: true, children: placeholder }) }),
|
|
840
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Text, { color: "gray", children: "▎" })
|
|
841
|
+
] }),
|
|
842
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { marginBottom: 1, paddingX: 1, justifyContent: "space-between", children: [
|
|
843
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: selectedIds.size > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { color: "yellow", children: [
|
|
844
|
+
selectedIds.size,
|
|
845
|
+
" selected / ",
|
|
846
|
+
totalItems,
|
|
847
|
+
" results"
|
|
848
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { dimColor: true, children: [
|
|
849
|
+
totalItems,
|
|
850
|
+
" results"
|
|
851
|
+
] }) }),
|
|
852
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Text, { dimColor: true, children: [
|
|
853
|
+
"Sort: ",
|
|
854
|
+
getSortShortLabel(sortOption)
|
|
855
|
+
] }) })
|
|
856
|
+
] }),
|
|
857
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { flexDirection: "column", height: visibleCount * itemHeight + 2, children: showSortMenu ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
858
|
+
SortMenu,
|
|
859
|
+
{
|
|
860
|
+
options: availableSortOptions,
|
|
861
|
+
focusIndex: sortMenuIndex,
|
|
862
|
+
currentSort: sortOption
|
|
863
|
+
}
|
|
864
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
865
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollIndicator, { direction: "up", count: scrollOffset, visible: showScrollIndicator }),
|
|
866
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
867
|
+
ChoiceList,
|
|
868
|
+
{
|
|
869
|
+
choices: visibleChoices,
|
|
870
|
+
selectedIds,
|
|
871
|
+
focusIndex,
|
|
872
|
+
scrollOffset,
|
|
873
|
+
contentWidth
|
|
874
|
+
}
|
|
875
|
+
),
|
|
876
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
877
|
+
ScrollIndicator,
|
|
878
|
+
{
|
|
879
|
+
direction: "down",
|
|
880
|
+
count: totalItems - scrollOffset - visibleCount,
|
|
881
|
+
visible: showScrollIndicator
|
|
882
|
+
}
|
|
883
|
+
)
|
|
884
|
+
] }) }),
|
|
885
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { dimColor: true, children: footerText }) })
|
|
886
|
+
] });
|
|
887
|
+
}
|
|
888
|
+
function formatSingleAuthor(author) {
|
|
889
|
+
if (author.literal) {
|
|
890
|
+
return author.literal;
|
|
891
|
+
}
|
|
892
|
+
if (author.family) {
|
|
893
|
+
if (author.given) {
|
|
894
|
+
const initial = author.given.charAt(0).toUpperCase();
|
|
895
|
+
return `${author.family}, ${initial}.`;
|
|
896
|
+
}
|
|
897
|
+
return author.family;
|
|
898
|
+
}
|
|
899
|
+
return "";
|
|
900
|
+
}
|
|
901
|
+
function formatAuthors(authors) {
|
|
902
|
+
if (!authors || authors.length === 0) {
|
|
903
|
+
return "";
|
|
904
|
+
}
|
|
905
|
+
if (authors.length > 3) {
|
|
906
|
+
const first = authors[0];
|
|
907
|
+
if (!first) {
|
|
908
|
+
return "";
|
|
909
|
+
}
|
|
910
|
+
return `${formatSingleAuthor(first)}, et al.`;
|
|
911
|
+
}
|
|
912
|
+
const formatted = authors.map(formatSingleAuthor);
|
|
913
|
+
if (formatted.length === 1) {
|
|
914
|
+
return formatted[0] ?? "";
|
|
915
|
+
}
|
|
916
|
+
const allButLast = formatted.slice(0, -1).join(", ");
|
|
917
|
+
const last = formatted[formatted.length - 1] ?? "";
|
|
918
|
+
return `${allButLast}, & ${last}`;
|
|
919
|
+
}
|
|
920
|
+
export {
|
|
921
|
+
SearchableMultiSelect as S,
|
|
922
|
+
formatAuthors as f
|
|
923
|
+
};
|
|
924
|
+
//# sourceMappingURL=format-BPeCbpFG.js.map
|