@nmakarov/cli-toolkit 0.81.0 → 0.84.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.
- package/dist/cli-runner.cjs +85 -27
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +87 -29
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +91 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +87 -29
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +85 -27
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +87 -29
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +83 -27
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +77 -27
- package/dist/screen.js.map +1 -1
- package/package.json +1 -1
package/dist/cli-runner.cjs
CHANGED
|
@@ -634,23 +634,23 @@ function formatKeyBindings(bindings, mode = "long") {
|
|
|
634
634
|
})));
|
|
635
635
|
groups.sort((a, b) => a.order - b.order);
|
|
636
636
|
const items = [];
|
|
637
|
-
groups.forEach((group) => {
|
|
637
|
+
groups.forEach((group, groupIndex) => {
|
|
638
638
|
const bindingWithCustom = resolvedBindings.find(
|
|
639
|
-
(b) => group.keys.includes(b
|
|
639
|
+
(b) => group.keys.includes(formatBindingKey(b)) && typeof b.resolvedCaption !== "string"
|
|
640
640
|
);
|
|
641
641
|
if (bindingWithCustom && bindingWithCustom.resolvedCaption) {
|
|
642
642
|
items.push(bindingWithCustom.resolvedCaption);
|
|
643
643
|
} else {
|
|
644
|
-
|
|
645
|
-
if (mode === "long") {
|
|
646
|
-
items.push(`${keyStr} to ${group.caption}`);
|
|
647
|
-
} else {
|
|
648
|
-
items.push(keyStr);
|
|
649
|
-
}
|
|
644
|
+
items.push(formatFooterHotkey(formatKeys(group.keys), group.caption, mode, `kb-${groupIndex}`));
|
|
650
645
|
}
|
|
651
646
|
});
|
|
652
647
|
return items;
|
|
653
648
|
}
|
|
649
|
+
function formatFooterHotkey(keyStr, caption = "", mode = "long", reactKey = "hotkey") {
|
|
650
|
+
const keyNode = (0, import_react3.createElement)(import_ink3.Text, { key: `${reactKey}-key`, ...FOOTER_HOTKEY_STYLE }, keyStr);
|
|
651
|
+
if (mode !== "long" || !caption) return keyNode;
|
|
652
|
+
return (0, import_react3.createElement)(import_ink3.Text, { key: reactKey, dimColor: true, color: "white" }, keyNode, ` to ${caption}`);
|
|
653
|
+
}
|
|
654
654
|
function formatKeys(keys) {
|
|
655
655
|
const keyMap = {
|
|
656
656
|
escape: "esc",
|
|
@@ -920,7 +920,7 @@ async function showMultiColumnListWithPreviewScreen(config2) {
|
|
|
920
920
|
}
|
|
921
921
|
});
|
|
922
922
|
}
|
|
923
|
-
var import_react3, import_ink3, showMenuScreen, showWordGridScreen;
|
|
923
|
+
var import_react3, import_ink3, FOOTER_HOTKEY_STYLE, showMenuScreen, showWordGridScreen;
|
|
924
924
|
var init_screens = __esm({
|
|
925
925
|
"src/screen/screens.js"() {
|
|
926
926
|
import_react3 = require("react");
|
|
@@ -928,6 +928,7 @@ var init_screens = __esm({
|
|
|
928
928
|
init_components();
|
|
929
929
|
init_list_components();
|
|
930
930
|
init_key_bindings();
|
|
931
|
+
FOOTER_HOTKEY_STYLE = { bold: true, color: "white", dimColor: false };
|
|
931
932
|
showMenuScreen = showListScreen;
|
|
932
933
|
showWordGridScreen = showMultiColumnListScreen;
|
|
933
934
|
}
|
|
@@ -1042,7 +1043,44 @@ var init_follow_scroll = __esm({
|
|
|
1042
1043
|
}
|
|
1043
1044
|
});
|
|
1044
1045
|
|
|
1045
|
-
// src/screen/
|
|
1046
|
+
// src/screen/visible-text.js
|
|
1047
|
+
function stripAnsi(text) {
|
|
1048
|
+
return String(text ?? "").replace(ANSI_RE, "");
|
|
1049
|
+
}
|
|
1050
|
+
function visibleWidth(text) {
|
|
1051
|
+
return [...stripAnsi(text)].length;
|
|
1052
|
+
}
|
|
1053
|
+
function sliceVisible(text, cols) {
|
|
1054
|
+
const w = Math.max(0, Math.floor(Number(cols) || 0));
|
|
1055
|
+
const s = String(text ?? "");
|
|
1056
|
+
if (w === 0) return "";
|
|
1057
|
+
let vis = 0;
|
|
1058
|
+
let out = "";
|
|
1059
|
+
let i = 0;
|
|
1060
|
+
while (i < s.length && vis < w) {
|
|
1061
|
+
ANSI_RE.lastIndex = i;
|
|
1062
|
+
const m = ANSI_RE.exec(s);
|
|
1063
|
+
if (m && m.index === i) {
|
|
1064
|
+
out += m[0];
|
|
1065
|
+
i += m[0].length;
|
|
1066
|
+
continue;
|
|
1067
|
+
}
|
|
1068
|
+
const cp = s.codePointAt(i);
|
|
1069
|
+
const ch = String.fromCodePoint(cp);
|
|
1070
|
+
out += ch;
|
|
1071
|
+
i += ch.length;
|
|
1072
|
+
vis += 1;
|
|
1073
|
+
}
|
|
1074
|
+
return out;
|
|
1075
|
+
}
|
|
1076
|
+
function padEndVisible(text, cols) {
|
|
1077
|
+
const w = Math.max(0, Math.floor(Number(cols) || 0));
|
|
1078
|
+
const s = String(text ?? "");
|
|
1079
|
+
const vis = visibleWidth(s);
|
|
1080
|
+
if (vis === w) return s;
|
|
1081
|
+
if (vis > w) return sliceVisible(s, w);
|
|
1082
|
+
return s + " ".repeat(w - vis);
|
|
1083
|
+
}
|
|
1046
1084
|
function wrapTextLines(text, cols) {
|
|
1047
1085
|
const w = Math.max(1, Math.floor(Number(cols) || 1));
|
|
1048
1086
|
const out = [];
|
|
@@ -1051,20 +1089,28 @@ function wrapTextLines(text, cols) {
|
|
|
1051
1089
|
out.push("");
|
|
1052
1090
|
continue;
|
|
1053
1091
|
}
|
|
1092
|
+
if (visibleWidth(raw) <= w) {
|
|
1093
|
+
out.push(raw);
|
|
1094
|
+
continue;
|
|
1095
|
+
}
|
|
1054
1096
|
let rest = raw;
|
|
1055
|
-
while (rest
|
|
1056
|
-
|
|
1057
|
-
|
|
1097
|
+
while (visibleWidth(rest) > w) {
|
|
1098
|
+
const head = sliceVisible(rest, w);
|
|
1099
|
+
out.push(head);
|
|
1100
|
+
rest = rest.slice(head.length);
|
|
1058
1101
|
}
|
|
1059
1102
|
if (rest.length > 0) out.push(rest);
|
|
1060
1103
|
}
|
|
1061
1104
|
return out;
|
|
1062
1105
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
}
|
|
1106
|
+
var ANSI_RE;
|
|
1107
|
+
var init_visible_text = __esm({
|
|
1108
|
+
"src/screen/visible-text.js"() {
|
|
1109
|
+
ANSI_RE = /\u001b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
// src/screen/scrollable-text.js
|
|
1068
1114
|
function ScrollableText({
|
|
1069
1115
|
ctx,
|
|
1070
1116
|
text = "",
|
|
@@ -1132,14 +1178,17 @@ function ScrollableText({
|
|
|
1132
1178
|
}, [ctx, bindKeys, followBottom]);
|
|
1133
1179
|
const status = allLines.length === 0 ? "empty" : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` + (needsBar ? " \xB7 \u2325\u2191/\u2193 or PgUp/Dn page" : "") + (followBottom && following ? " \xB7 follow" : followBottom ? " \xB7 follow off" : "");
|
|
1134
1180
|
const rowNodes = visible.map((line, i) => {
|
|
1135
|
-
const body = padEndVisible(line, textWidth);
|
|
1136
1181
|
const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? " " : "";
|
|
1137
1182
|
const isThumb = glyph === BAR_THUMB;
|
|
1138
1183
|
return h5(
|
|
1139
|
-
import_ink5.
|
|
1140
|
-
{ key: `L${clamped + i}
|
|
1141
|
-
|
|
1142
|
-
|
|
1184
|
+
import_ink5.Box,
|
|
1185
|
+
{ key: `L${clamped + i}`, flexDirection: "row", width: contentCols, flexShrink: 0 },
|
|
1186
|
+
h5(
|
|
1187
|
+
import_ink5.Box,
|
|
1188
|
+
{ width: textWidth, flexShrink: 0 },
|
|
1189
|
+
h5(import_ink5.Text, { wrap: "truncate" }, padEndVisible(line, textWidth))
|
|
1190
|
+
),
|
|
1191
|
+
showScrollbar ? h5(import_ink5.Box, { width: 1, flexShrink: 0 }, h5(import_ink5.Text, { color: isThumb ? "cyan" : "gray" }, glyph)) : null
|
|
1143
1192
|
);
|
|
1144
1193
|
});
|
|
1145
1194
|
if (bar && visible.length < viewportRows) {
|
|
@@ -1147,10 +1196,10 @@ function ScrollableText({
|
|
|
1147
1196
|
const glyph = bar[i] ?? BAR_TRACK;
|
|
1148
1197
|
rowNodes.push(
|
|
1149
1198
|
h5(
|
|
1150
|
-
import_ink5.
|
|
1151
|
-
{ key: `pad${i}
|
|
1152
|
-
padEndVisible("", textWidth),
|
|
1153
|
-
h5(import_ink5.Text, { color: glyph === BAR_THUMB ? "cyan" : "gray" }, glyph)
|
|
1199
|
+
import_ink5.Box,
|
|
1200
|
+
{ key: `pad${i}`, flexDirection: "row", width: contentCols, flexShrink: 0 },
|
|
1201
|
+
h5(import_ink5.Box, { width: textWidth, flexShrink: 0 }, h5(import_ink5.Text, {}, padEndVisible("", textWidth))),
|
|
1202
|
+
h5(import_ink5.Box, { width: 1, flexShrink: 0 }, h5(import_ink5.Text, { color: glyph === BAR_THUMB ? "cyan" : "gray" }, glyph))
|
|
1154
1203
|
)
|
|
1155
1204
|
);
|
|
1156
1205
|
}
|
|
@@ -1171,7 +1220,9 @@ var init_scrollable_text = __esm({
|
|
|
1171
1220
|
init_components();
|
|
1172
1221
|
init_scrollbar();
|
|
1173
1222
|
init_follow_scroll();
|
|
1223
|
+
init_visible_text();
|
|
1174
1224
|
init_scrollbar();
|
|
1225
|
+
init_visible_text();
|
|
1175
1226
|
h5 = import_react5.createElement;
|
|
1176
1227
|
SCROLL_KEYS = [
|
|
1177
1228
|
{ key: "upArrow", caption: "scroll", action: "scrollUp", order: 0 },
|
|
@@ -1316,6 +1367,7 @@ __export(screen_exports, {
|
|
|
1316
1367
|
BAR_TRACK: () => BAR_TRACK,
|
|
1317
1368
|
Box: () => import_ink6.Box,
|
|
1318
1369
|
Divider: () => Divider,
|
|
1370
|
+
FOOTER_HOTKEY_STYLE: () => FOOTER_HOTKEY_STYLE,
|
|
1319
1371
|
FooterPresets: () => FooterPresets,
|
|
1320
1372
|
GridCell: () => GridCell,
|
|
1321
1373
|
InputField: () => InputField,
|
|
@@ -1341,6 +1393,7 @@ __export(screen_exports, {
|
|
|
1341
1393
|
buildFooter: () => buildFooter,
|
|
1342
1394
|
clampScroll: () => clampScroll,
|
|
1343
1395
|
formatBindingKey: () => formatBindingKey,
|
|
1396
|
+
formatFooterHotkey: () => formatFooterHotkey,
|
|
1344
1397
|
h: () => import_react6.createElement,
|
|
1345
1398
|
isScrolledToBottom: () => isScrolledToBottom,
|
|
1346
1399
|
load: () => load,
|
|
@@ -1348,6 +1401,7 @@ __export(screen_exports, {
|
|
|
1348
1401
|
nextScrollAfterContentChange: () => nextScrollAfterContentChange,
|
|
1349
1402
|
nextScrollAfterUserMove: () => nextScrollAfterUserMove,
|
|
1350
1403
|
organizeFooterMessages: () => organizeFooterMessages,
|
|
1404
|
+
padEndVisible: () => padEndVisible,
|
|
1351
1405
|
scrollbarGlyphs: () => scrollbarGlyphs,
|
|
1352
1406
|
showListScreen: () => showListScreen,
|
|
1353
1407
|
showMenuScreen: () => showMenuScreen,
|
|
@@ -1355,6 +1409,8 @@ __export(screen_exports, {
|
|
|
1355
1409
|
showMultiColumnListWithPreviewScreen: () => showMultiColumnListWithPreviewScreen,
|
|
1356
1410
|
showScreen: () => showScreen,
|
|
1357
1411
|
showWordGridScreen: () => showWordGridScreen,
|
|
1412
|
+
sliceVisible: () => sliceVisible,
|
|
1413
|
+
stripAnsi: () => stripAnsi,
|
|
1358
1414
|
useCallback: () => import_react6.useCallback,
|
|
1359
1415
|
useEffect: () => import_react6.useEffect,
|
|
1360
1416
|
useInput: () => import_ink6.useInput,
|
|
@@ -1362,6 +1418,7 @@ __export(screen_exports, {
|
|
|
1362
1418
|
useMemo: () => import_react6.useMemo,
|
|
1363
1419
|
useRef: () => import_react6.useRef,
|
|
1364
1420
|
useState: () => import_react6.useState,
|
|
1421
|
+
visibleWidth: () => visibleWidth,
|
|
1365
1422
|
wrapTextLines: () => wrapTextLines
|
|
1366
1423
|
});
|
|
1367
1424
|
async function load() {
|
|
@@ -1383,6 +1440,7 @@ var init_screen = __esm({
|
|
|
1383
1440
|
init_components();
|
|
1384
1441
|
init_ui_elements();
|
|
1385
1442
|
init_scrollable_text();
|
|
1443
|
+
init_visible_text();
|
|
1386
1444
|
init_follow_scroll();
|
|
1387
1445
|
init_scrollbar();
|
|
1388
1446
|
init_key_bindings();
|