[gjs/ewlsh/nova-repl] WIP - use cliffy for ANSI and keypress parsing
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/ewlsh/nova-repl] WIP - use cliffy for ANSI and keypress parsing
- Date: Wed, 1 Sep 2021 05:36:03 +0000 (UTC)
commit 2b63a596ba6d2b9bf8d8ca41e249e46480d39746
Author: Evan Welsh <contact evanwelsh com>
Date: Tue Aug 31 22:35:56 2021 -0700
WIP - use cliffy for ANSI and keypress parsing
cliffy/bundle.sh | 4 +
cliffy/lib.js | 4 +
cliffy/transform.js | 14 +
js.gresource.xml | 3 +
modules/esm/_cliffy.js | 6047 +++++----------------------------------
modules/esm/_denoCompatLayer.js | 102 +
modules/esm/repl.js | 473 ++-
7 files changed, 967 insertions(+), 5680 deletions(-)
---
diff --git a/cliffy/bundle.sh b/cliffy/bundle.sh
new file mode 100755
index 00000000..3de97ca4
--- /dev/null
+++ b/cliffy/bundle.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+deno bundle --unstable ./cliffy/lib.js ./modules/esm/_cliffy.js
+gjs -m ./cliffy/transform.js ./modules/esm/_cliffy.js
\ No newline at end of file
diff --git a/cliffy/lib.js b/cliffy/lib.js
new file mode 100644
index 00000000..c0819522
--- /dev/null
+++ b/cliffy/lib.js
@@ -0,0 +1,4 @@
+export * as AnsiColors from 'https://deno.land/std@0.104.0/fmt/colors.ts';
+export * as Ansi from 'https://deno.land/x/cliffy@v0.19.5/ansi/mod.ts';
+export * as Keycode from 'https://deno.land/x/cliffy@v0.19.5/keycode/mod.ts';
+export { Figures } from 'https://deno.land/x/cliffy@v0.19.5/prompt/figures.ts';
\ No newline at end of file
diff --git a/cliffy/transform.js b/cliffy/transform.js
new file mode 100644
index 00000000..4183fe47
--- /dev/null
+++ b/cliffy/transform.js
@@ -0,0 +1,14 @@
+import System from 'system';
+import Gio from 'gi://Gio';
+const file = Gio.File.new_for_commandline_arg(System.programArgs[0]);
+const [, contents] = file.load_contents(null);
+let source = new TextDecoder().decode(contents);
+source =
+`
+import * as Deno from './_denoCompatLayer.js';
+${source.replace(/\#/g, '$').replace('const { Deno: Deno1 } = globalThis;', 'const Deno1 = Deno;')}
+`
+
+file.replace_contents(new TextEncoder().encode(source), null, false, 0, null);
+
+console.log('Transformed.');
\ No newline at end of file
diff --git a/js.gresource.xml b/js.gresource.xml
index 46515458..a5f564fa 100644
--- a/js.gresource.xml
+++ b/js.gresource.xml
@@ -21,6 +21,9 @@
<file>modules/esm/repl.js</file>
<file>modules/esm/system.js</file>
+ <file>modules/esm/_denoCompatLayer.js</file>
+ <file>modules/esm/_cliffy.js</file>
+
<!-- Script-based Modules -->
<file>modules/script/_bootstrap/debugger.js</file>
<file>modules/script/_bootstrap/default.js</file>
diff --git a/modules/esm/_cliffy.js b/modules/esm/_cliffy.js
index 78868d82..30e613c7 100644
--- a/modules/esm/_cliffy.js
+++ b/modules/esm/_cliffy.js
@@ -1,313 +1,6 @@
-const base64abc = [
- "A",
- "B",
- "C",
- "D",
- "E",
- "F",
- "G",
- "H",
- "I",
- "J",
- "K",
- "L",
- "M",
- "N",
- "O",
- "P",
- "Q",
- "R",
- "S",
- "T",
- "U",
- "V",
- "W",
- "X",
- "Y",
- "Z",
- "a",
- "b",
- "c",
- "d",
- "e",
- "f",
- "g",
- "h",
- "i",
- "j",
- "k",
- "l",
- "m",
- "n",
- "o",
- "p",
- "q",
- "r",
- "s",
- "t",
- "u",
- "v",
- "w",
- "x",
- "y",
- "z",
- "0",
- "1",
- "2",
- "3",
- "4",
- "5",
- "6",
- "7",
- "8",
- "9",
- "+",
- "/"
-];
-function encode(data) {
- const uint8 = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ?
data : new Uint8Array(data);
- let result = "", i;
- const l = uint8.length;
- for(i = 2; i < l; i += 3){
- result += base64abc[uint8[i - 2] >> 2];
- result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4];
- result += base64abc[(uint8[i - 1] & 15) << 2 | uint8[i] >> 6];
- result += base64abc[uint8[i] & 63];
- }
- if (i === l + 1) {
- result += base64abc[uint8[i - 2] >> 2];
- result += base64abc[(uint8[i - 2] & 3) << 4];
- result += "==";
- }
- if (i === l) {
- result += base64abc[uint8[i - 2] >> 2];
- result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4];
- result += base64abc[(uint8[i - 1] & 15) << 2];
- result += "=";
- }
- return result;
-}
-const ESC = "\x1B";
-const CSI = `${ESC}[`;
-const OSC = `${ESC}]`;
-const SEP = ";";
-const bel1 = "\u0007";
-const cursorPosition1 = `${CSI}6n`;
-function cursorTo1(x, y) {
- if (typeof y !== "number") {
- return `${CSI}${x}G`;
- }
- return `${CSI}${y};${x}H`;
-}
-function cursorMove1(x, y) {
- let ret = "";
- if (x < 0) {
- ret += `${CSI}${-x}D`;
- } else if (x > 0) {
- ret += `${CSI}${x}C`;
- }
- if (y < 0) {
- ret += `${CSI}${-y}A`;
- } else if (y > 0) {
- ret += `${CSI}${y}B`;
- }
- return ret;
-}
-function cursorUp1(count = 1) {
- return `${CSI}${count}A`;
-}
-function cursorDown1(count = 1) {
- return `${CSI}${count}B`;
-}
-function cursorForward1(count = 1) {
- return `${CSI}${count}C`;
-}
-function cursorBackward1(count = 1) {
- return `${CSI}${count}D`;
-}
-function cursorNextLine1(count = 1) {
- return `${CSI}E`.repeat(count);
-}
-function cursorPrevLine1(count = 1) {
- return `${CSI}F`.repeat(count);
-}
-const cursorLeft1 = `${CSI}G`;
-const cursorHide1 = `${CSI}?25l`;
-const cursorShow1 = `${CSI}?25h`;
-const cursorSave1 = `${ESC}7`;
-const cursorRestore1 = `${ESC}8`;
-function scrollUp1(count = 1) {
- return `${CSI}S`.repeat(count);
-}
-function scrollDown1(count = 1) {
- return `${CSI}T`.repeat(count);
-}
-const eraseScreen1 = `${CSI}2J`;
-function eraseUp1(count = 1) {
- return `${CSI}1J`.repeat(count);
-}
-function eraseDown1(count = 1) {
- return `${CSI}0J`.repeat(count);
-}
-const eraseLine1 = `${CSI}2K`;
-const eraseLineEnd1 = `${CSI}0K`;
-const eraseLineStart1 = `${CSI}1K`;
-function eraseLines1(count) {
- let clear = "";
- for(let i = 0; i < count; i++){
- clear += eraseLine1 + (i < count - 1 ? cursorUp1() : "");
- }
- clear += cursorLeft1;
- return clear;
-}
-const clearScreen1 = "\u001Bc";
-const clearTerminal1 = Deno.build.os === "windows" ? `${eraseScreen1}${CSI}0f` :
`${eraseScreen1}${CSI}3J${CSI}H`;
-function link1(text, url) {
- return [
- OSC,
- "8",
- SEP,
- SEP,
- url,
- bel1,
- text,
- OSC,
- "8",
- SEP,
- SEP,
- bel1,
- ].join("");
-}
-function image1(buffer, options) {
- let ret = `${OSC}1337;File=inline=1`;
- if (options?.width) {
- ret += `;width=${options.width}`;
- }
- if (options?.height) {
- ret += `;height=${options.height}`;
- }
- if (options?.preserveAspectRatio === false) {
- ret += ";preserveAspectRatio=0";
- }
- return ret + ":" + encode(buffer) + bel1;
-}
-export { bel1 as bel };
-export { cursorPosition1 as cursorPosition };
-export { cursorTo1 as cursorTo };
-export { cursorMove1 as cursorMove };
-export { cursorUp1 as cursorUp };
-export { cursorDown1 as cursorDown };
-export { cursorForward1 as cursorForward };
-export { cursorBackward1 as cursorBackward };
-export { cursorNextLine1 as cursorNextLine };
-export { cursorPrevLine1 as cursorPrevLine };
-export { cursorLeft1 as cursorLeft };
-export { cursorHide1 as cursorHide };
-export { cursorShow1 as cursorShow };
-export { cursorSave1 as cursorSave };
-export { cursorRestore1 as cursorRestore };
-export { scrollUp1 as scrollUp };
-export { scrollDown1 as scrollDown };
-export { eraseScreen1 as eraseScreen };
-export { eraseUp1 as eraseUp };
-export { eraseDown1 as eraseDown };
-export { eraseLine1 as eraseLine };
-export { eraseLineEnd1 as eraseLineEnd };
-export { eraseLineStart1 as eraseLineStart };
-export { eraseLines1 as eraseLines };
-export { clearScreen1 as clearScreen };
-export { clearTerminal1 as clearTerminal };
-export { link1 as link };
-export { image1 as image };
-const mod = function() {
- return {
- bel: bel1,
- cursorPosition: cursorPosition1,
- cursorTo: cursorTo1,
- cursorMove: cursorMove1,
- cursorUp: cursorUp1,
- cursorDown: cursorDown1,
- cursorForward: cursorForward1,
- cursorBackward: cursorBackward1,
- cursorNextLine: cursorNextLine1,
- cursorPrevLine: cursorPrevLine1,
- cursorLeft: cursorLeft1,
- cursorHide: cursorHide1,
- cursorShow: cursorShow1,
- cursorSave: cursorSave1,
- cursorRestore: cursorRestore1,
- scrollUp: scrollUp1,
- scrollDown: scrollDown1,
- eraseScreen: eraseScreen1,
- eraseUp: eraseUp1,
- eraseDown: eraseDown1,
- eraseLine: eraseLine1,
- eraseLineEnd: eraseLineEnd1,
- eraseLineStart: eraseLineStart1,
- eraseLines: eraseLines1,
- clearScreen: clearScreen1,
- clearTerminal: clearTerminal1,
- link: link1,
- image: image1
- };
-}();
-const ansi1 = factory1();
-function factory1() {
- let result = [];
- let stack = [];
- const ansi1 = function(...args) {
- if (this) {
- if (args.length) {
- update(args);
- return this;
- }
- return this.toString();
- }
- return factory1();
- };
- ansi1.text = function(text) {
- stack.push([
- text,
- []
- ]);
- return this;
- };
- ansi1.toString = function() {
- update();
- const str = result.join("");
- result = [];
- return str;
- };
- ansi1.toBuffer = function() {
- return new TextEncoder().encode(this.toString());
- };
- const methodList = Object.entries(mod);
- for (const [name, method] of methodList){
- Object.defineProperty(ansi1, name, {
- get () {
- stack.push([
- method,
- []
- ]);
- return this;
- }
- });
- }
- return ansi1;
- function update(args) {
- if (!stack.length) {
- return;
- }
- if (args) {
- stack[stack.length - 1][1] = args;
- }
- result.push(...stack.map(([prop, args1])=>typeof prop === "string" ? prop : prop.call(ansi1,
...args1)
- ));
- stack = [];
- }
-}
-export { ansi1 as ansi };
-const { Deno: Deno1 } = globalThis;
+
+import * as Deno from './_denoCompatLayer.js';
+const Deno1 = Deno;
const noColor = typeof Deno1?.noColor === "boolean" ? Deno1.noColor : true;
let enabled = !noColor;
function setColorEnabled(value) {
@@ -326,86 +19,86 @@ function code(open, close) {
regexp: new RegExp(`\\x1b\\[${close}m`, "g")
};
}
-function run1(str, code1) {
+function run(str, code1) {
return enabled ? `${code1.open}${str.replace(code1.regexp, code1.open)}${code1.close}` : str;
}
function reset(str) {
- return run1(str, code([
+ return run(str, code([
0
], 0));
}
function bold(str) {
- return run1(str, code([
+ return run(str, code([
1
], 22));
}
function dim(str) {
- return run1(str, code([
+ return run(str, code([
2
], 22));
}
function italic(str) {
- return run1(str, code([
+ return run(str, code([
3
], 23));
}
function underline(str) {
- return run1(str, code([
+ return run(str, code([
4
], 24));
}
function inverse(str) {
- return run1(str, code([
+ return run(str, code([
7
], 27));
}
-function hidden1(str) {
- return run1(str, code([
+function hidden(str) {
+ return run(str, code([
8
], 28));
}
function strikethrough(str) {
- return run1(str, code([
+ return run(str, code([
9
], 29));
}
function black(str) {
- return run1(str, code([
+ return run(str, code([
30
], 39));
}
function red(str) {
- return run1(str, code([
+ return run(str, code([
31
], 39));
}
function green(str) {
- return run1(str, code([
+ return run(str, code([
32
], 39));
}
function yellow(str) {
- return run1(str, code([
+ return run(str, code([
33
], 39));
}
function blue(str) {
- return run1(str, code([
+ return run(str, code([
34
], 39));
}
function magenta(str) {
- return run1(str, code([
+ return run(str, code([
35
], 39));
}
function cyan(str) {
- return run1(str, code([
+ return run(str, code([
36
], 39));
}
function white(str) {
- return run1(str, code([
+ return run(str, code([
37
], 39));
}
@@ -413,122 +106,122 @@ function gray(str) {
return brightBlack(str);
}
function brightBlack(str) {
- return run1(str, code([
+ return run(str, code([
90
], 39));
}
function brightRed(str) {
- return run1(str, code([
+ return run(str, code([
91
], 39));
}
function brightGreen(str) {
- return run1(str, code([
+ return run(str, code([
92
], 39));
}
function brightYellow(str) {
- return run1(str, code([
+ return run(str, code([
93
], 39));
}
function brightBlue(str) {
- return run1(str, code([
+ return run(str, code([
94
], 39));
}
function brightMagenta(str) {
- return run1(str, code([
+ return run(str, code([
95
], 39));
}
function brightCyan(str) {
- return run1(str, code([
+ return run(str, code([
96
], 39));
}
function brightWhite(str) {
- return run1(str, code([
+ return run(str, code([
97
], 39));
}
function bgBlack(str) {
- return run1(str, code([
+ return run(str, code([
40
], 49));
}
function bgRed(str) {
- return run1(str, code([
+ return run(str, code([
41
], 49));
}
function bgGreen(str) {
- return run1(str, code([
+ return run(str, code([
42
], 49));
}
function bgYellow(str) {
- return run1(str, code([
+ return run(str, code([
43
], 49));
}
function bgBlue(str) {
- return run1(str, code([
+ return run(str, code([
44
], 49));
}
function bgMagenta(str) {
- return run1(str, code([
+ return run(str, code([
45
], 49));
}
function bgCyan(str) {
- return run1(str, code([
+ return run(str, code([
46
], 49));
}
function bgWhite(str) {
- return run1(str, code([
+ return run(str, code([
47
], 49));
}
function bgBrightBlack(str) {
- return run1(str, code([
+ return run(str, code([
100
], 49));
}
function bgBrightRed(str) {
- return run1(str, code([
+ return run(str, code([
101
], 49));
}
function bgBrightGreen(str) {
- return run1(str, code([
+ return run(str, code([
102
], 49));
}
function bgBrightYellow(str) {
- return run1(str, code([
+ return run(str, code([
103
], 49));
}
function bgBrightBlue(str) {
- return run1(str, code([
+ return run(str, code([
104
], 49));
}
function bgBrightMagenta(str) {
- return run1(str, code([
+ return run(str, code([
105
], 49));
}
function bgBrightCyan(str) {
- return run1(str, code([
+ return run(str, code([
106
], 49));
}
function bgBrightWhite(str) {
- return run1(str, code([
+ return run(str, code([
107
], 49));
}
@@ -536,14 +229,14 @@ function clampAndTruncate(n, max = 255, min = 0) {
return Math.trunc(Math.max(Math.min(n, max), min));
}
function rgb8(str, color) {
- return run1(str, code([
+ return run(str, code([
38,
5,
clampAndTruncate(color)
], 39));
}
function bgRgb8(str, color) {
- return run1(str, code([
+ return run(str, code([
48,
5,
clampAndTruncate(color)
@@ -551,7 +244,7 @@ function bgRgb8(str, color) {
}
function rgb24(str, color) {
if (typeof color === "number") {
- return run1(str, code([
+ return run(str, code([
38,
2,
color >> 16 & 255,
@@ -559,7 +252,7 @@ function rgb24(str, color) {
color & 255
], 39));
}
- return run1(str, code([
+ return run(str, code([
38,
2,
clampAndTruncate(color.r),
@@ -569,7 +262,7 @@ function rgb24(str, color) {
}
function bgRgb24(str, color) {
if (typeof color === "number") {
- return run1(str, code([
+ return run(str, code([
48,
2,
color >> 16 & 255,
@@ -577,7 +270,7 @@ function bgRgb24(str, color) {
color & 255
], 49));
}
- return run1(str, code([
+ return run(str, code([
48,
2,
clampAndTruncate(color.r),
@@ -586,13 +279,13 @@ function bgRgb24(str, color) {
], 49));
}
const ANSI_PATTERN = new RegExp([
- "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
+ "[\\u001B\\u009B][[\\]()$;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/$&.:=?%@~_]*)*)?\\u0007)",
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
].join("|"), "g");
function stripColor(string) {
return string.replace(ANSI_PATTERN, "");
}
-const mod1 = function() {
+const mod = function() {
return {
setColorEnabled: setColorEnabled,
getColorEnabled: getColorEnabled,
@@ -602,7 +295,7 @@ const mod1 = function() {
italic: italic,
underline: underline,
inverse: inverse,
- hidden: hidden1,
+ hidden: hidden,
strikethrough: strikethrough,
black: black,
red: red,
@@ -644,56 +337,334 @@ const mod1 = function() {
stripColor: stripColor
};
}();
-const proto = Object.create(null);
-const methodNames = Object.keys(mod1);
-for (const name18 of methodNames){
- if (name18 === "setColorEnabled" || name18 === "getColorEnabled") {
- continue;
- }
- Object.defineProperty(proto, name18, {
- get () {
- return factory2([
- ...this._stack,
- name18
- ]);
- }
- });
-}
-const colors1 = factory2();
-function factory2(stack = []) {
- const colors1 = function(str, ...args) {
- if (str) {
- const lastIndex = stack.length - 1;
- return stack.reduce((str1, name1, index)=>index === lastIndex ? mod1[name1](str1, ...args) :
mod1[name1](str1)
- , str);
- }
- const tmp = stack.slice();
- stack = [];
- return factory2(tmp);
- };
- Object.setPrototypeOf(colors1, proto);
- colors1._stack = stack;
- return colors1;
-}
-export { colors1 as colors };
-function getCursorPosition1({ stdin =Deno.stdin , stdout =Deno.stdout } = {
-}) {
- const data = new Uint8Array(8);
- Deno.setRaw(stdin.rid, true);
- stdout.writeSync(new TextEncoder().encode(cursorPosition1));
- stdin.readSync(data);
- Deno.setRaw(stdin.rid, false);
- const [y, x] = new TextDecoder().decode(data).match(/\[(\d+);(\d+)R/)?.slice(1, 3).map(Number) ?? [
- 0,
- 0
- ];
- return {
- x,
- y
- };
+const base64abc = [
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "+",
+ "/"
+];
+function encode(data) {
+ const uint8 = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ?
data : new Uint8Array(data);
+ let result = "", i;
+ const l = uint8.length;
+ for(i = 2; i < l; i += 3){
+ result += base64abc[uint8[i - 2] >> 2];
+ result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4];
+ result += base64abc[(uint8[i - 1] & 15) << 2 | uint8[i] >> 6];
+ result += base64abc[uint8[i] & 63];
+ }
+ if (i === l + 1) {
+ result += base64abc[uint8[i - 2] >> 2];
+ result += base64abc[(uint8[i - 2] & 3) << 4];
+ result += "==";
+ }
+ if (i === l) {
+ result += base64abc[uint8[i - 2] >> 2];
+ result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4];
+ result += base64abc[(uint8[i - 1] & 15) << 2];
+ result += "=";
+ }
+ return result;
+}
+const ESC = "\x1B";
+const CSI = `${ESC}[`;
+const OSC = `${ESC}]`;
+const SEP = ";";
+const bel = "\u0007";
+const cursorPosition = `${CSI}6n`;
+function cursorTo(x, y) {
+ if (typeof y !== "number") {
+ return `${CSI}${x}G`;
+ }
+ return `${CSI}${y};${x}H`;
+}
+function cursorMove(x, y) {
+ let ret = "";
+ if (x < 0) {
+ ret += `${CSI}${-x}D`;
+ } else if (x > 0) {
+ ret += `${CSI}${x}C`;
+ }
+ if (y < 0) {
+ ret += `${CSI}${-y}A`;
+ } else if (y > 0) {
+ ret += `${CSI}${y}B`;
+ }
+ return ret;
+}
+function cursorUp(count = 1) {
+ return `${CSI}${count}A`;
+}
+function cursorDown(count = 1) {
+ return `${CSI}${count}B`;
+}
+function cursorForward(count = 1) {
+ return `${CSI}${count}C`;
+}
+function cursorBackward(count = 1) {
+ return `${CSI}${count}D`;
+}
+function cursorNextLine(count = 1) {
+ return `${CSI}E`.repeat(count);
+}
+function cursorPrevLine(count = 1) {
+ return `${CSI}F`.repeat(count);
+}
+const cursorLeft = `${CSI}G`;
+const cursorHide = `${CSI}?25l`;
+const cursorShow = `${CSI}?25h`;
+const cursorSave = `${ESC}7`;
+const cursorRestore = `${ESC}8`;
+function scrollUp(count = 1) {
+ return `${CSI}S`.repeat(count);
+}
+function scrollDown(count = 1) {
+ return `${CSI}T`.repeat(count);
+}
+const eraseScreen = `${CSI}2J`;
+function eraseUp(count = 1) {
+ return `${CSI}1J`.repeat(count);
}
-export { getCursorPosition1 as getCursorPosition };
-const tty1 = factory3();
+function eraseDown(count = 1) {
+ return `${CSI}0J`.repeat(count);
+}
+const eraseLine = `${CSI}2K`;
+const eraseLineEnd = `${CSI}0K`;
+const eraseLineStart = `${CSI}1K`;
+function eraseLines(count) {
+ let clear = "";
+ for(let i = 0; i < count; i++){
+ clear += eraseLine + (i < count - 1 ? cursorUp() : "");
+ }
+ clear += cursorLeft;
+ return clear;
+}
+const clearScreen = "\u001Bc";
+const clearTerminal = Deno.build.os === "windows" ? `${eraseScreen}${CSI}0f` :
`${eraseScreen}${CSI}3J${CSI}H`;
+function link(text, url) {
+ return [
+ OSC,
+ "8",
+ SEP,
+ SEP,
+ url,
+ bel,
+ text,
+ OSC,
+ "8",
+ SEP,
+ SEP,
+ bel,
+ ].join("");
+}
+function image(buffer, options) {
+ let ret = `${OSC}1337;File=inline=1`;
+ if (options?.width) {
+ ret += `;width=${options.width}`;
+ }
+ if (options?.height) {
+ ret += `;height=${options.height}`;
+ }
+ if (options?.preserveAspectRatio === false) {
+ ret += ";preserveAspectRatio=0";
+ }
+ return ret + ":" + encode(buffer) + bel;
+}
+const mod1 = function() {
+ return {
+ bel: bel,
+ cursorPosition: cursorPosition,
+ cursorTo: cursorTo,
+ cursorMove: cursorMove,
+ cursorUp: cursorUp,
+ cursorDown: cursorDown,
+ cursorForward: cursorForward,
+ cursorBackward: cursorBackward,
+ cursorNextLine: cursorNextLine,
+ cursorPrevLine: cursorPrevLine,
+ cursorLeft: cursorLeft,
+ cursorHide: cursorHide,
+ cursorShow: cursorShow,
+ cursorSave: cursorSave,
+ cursorRestore: cursorRestore,
+ scrollUp: scrollUp,
+ scrollDown: scrollDown,
+ eraseScreen: eraseScreen,
+ eraseUp: eraseUp,
+ eraseDown: eraseDown,
+ eraseLine: eraseLine,
+ eraseLineEnd: eraseLineEnd,
+ eraseLineStart: eraseLineStart,
+ eraseLines: eraseLines,
+ clearScreen: clearScreen,
+ clearTerminal: clearTerminal,
+ link: link,
+ image: image
+ };
+}();
+const ansi = factory1();
+function factory1() {
+ let result = [];
+ let stack = [];
+ const ansi1 = function(...args) {
+ if (this) {
+ if (args.length) {
+ update(args);
+ return this;
+ }
+ return this.toString();
+ }
+ return factory1();
+ };
+ ansi1.text = function(text) {
+ stack.push([
+ text,
+ []
+ ]);
+ return this;
+ };
+ ansi1.toString = function() {
+ update();
+ const str = result.join("");
+ result = [];
+ return str;
+ };
+ ansi1.toBuffer = function() {
+ return new TextEncoder().encode(this.toString());
+ };
+ const methodList = Object.entries(mod1);
+ for (const [name, method] of methodList){
+ Object.defineProperty(ansi1, name, {
+ get () {
+ stack.push([
+ method,
+ []
+ ]);
+ return this;
+ }
+ });
+ }
+ return ansi1;
+ function update(args) {
+ if (!stack.length) {
+ return;
+ }
+ if (args) {
+ stack[stack.length - 1][1] = args;
+ }
+ result.push(...stack.map(([prop, args1])=>typeof prop === "string" ? prop : prop.call(ansi1,
...args1)
+ ));
+ stack = [];
+ }
+}
+const proto = Object.create(null);
+const methodNames = Object.keys(mod);
+for (const name of methodNames){
+ if (name === "setColorEnabled" || name === "getColorEnabled") {
+ continue;
+ }
+ Object.defineProperty(proto, name, {
+ get () {
+ return factory2([
+ ...this._stack,
+ name
+ ]);
+ }
+ });
+}
+const colors = factory2();
+function factory2(stack = []) {
+ const colors1 = function(str, ...args) {
+ if (str) {
+ const lastIndex = stack.length - 1;
+ return stack.reduce((str1, name1, index)=>index === lastIndex ? mod[name1](str1, ...args) :
mod[name1](str1)
+ , str);
+ }
+ const tmp = stack.slice();
+ stack = [];
+ return factory2(tmp);
+ };
+ Object.setPrototypeOf(colors1, proto);
+ colors1._stack = stack;
+ return colors1;
+}
+function getCursorPosition({ stdin =Deno.stdin , stdout =Deno.stdout } = {
+}) {
+ const data = new Uint8Array(8);
+ Deno.setRaw(stdin.rid, true);
+ stdout.writeSync(new TextEncoder().encode(cursorPosition));
+ stdin.readSync(data);
+ Deno.setRaw(stdin.rid, false);
+ const [y, x] = new TextDecoder().decode(data).match(/\[(\d+);(\d+)R/)?.slice(1, 3).map(Number) ?? [
+ 0,
+ 0
+ ];
+ return {
+ x,
+ y
+ };
+}
+const tty = factory3();
function factory3(options) {
let result = "";
let stack = [];
@@ -716,12 +687,12 @@ function factory3(options) {
stdout.writeSync(new TextEncoder().encode(result));
return this;
};
- tty1.getCursorPosition = ()=>getCursorPosition1({
+ tty1.getCursorPosition = ()=>getCursorPosition({
stdout,
stdin
})
;
- const methodList = Object.entries(mod);
+ const methodList = Object.entries(mod1);
for (const [name1, method] of methodList){
if (name1 === "cursorPosition") {
continue;
@@ -749,5007 +720,297 @@ function factory3(options) {
stack = [];
}
}
-export { tty1 as tty };
-function distance(a, b) {
- if (a.length == 0) {
- return b.length;
- }
- if (b.length == 0) {
- return a.length;
- }
- const matrix = [];
- for(let i = 0; i <= b.length; i++){
- matrix[i] = [
- i
- ];
- }
- for(let j = 0; j <= a.length; j++){
- matrix[0][j] = j;
- }
- for(let i1 = 1; i1 <= b.length; i1++){
- for(let j1 = 1; j1 <= a.length; j1++){
- if (b.charAt(i1 - 1) == a.charAt(j1 - 1)) {
- matrix[i1][j1] = matrix[i1 - 1][j1 - 1];
- } else {
- matrix[i1][j1] = Math.min(matrix[i1 - 1][j1 - 1] + 1, Math.min(matrix[i1][j1 - 1] + 1,
matrix[i1 - 1][j1] + 1));
- }
- }
- }
- return matrix[b.length][a.length];
-}
-function paramCaseToCamelCase(str) {
- return str.replace(/-([a-z])/g, (g)=>g[1].toUpperCase()
- );
-}
-function underscoreToCamelCase(str) {
- return str.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase().replace(/_([a-z])/g, (g)=>g[1].toUpperCase()
- );
-}
-function getOption(flags, name1) {
- while(name1[0] === "-"){
- name1 = name1.slice(1);
- }
- for (const flag of flags){
- if (isOption(flag, name1)) {
- return flag;
- }
- }
- return;
-}
-function didYouMeanOption(option, options) {
- const optionNames = options.map((option1)=>[
- option1.name,
- ...option1.aliases ?? []
- ]
- ).flat().map((option1)=>getFlag(option1)
- );
- return didYouMean(" Did you mean option", getFlag(option), optionNames);
-}
-function didYouMeanType(type, types) {
- return didYouMean(" Did you mean type", type, types);
-}
-function didYouMean(message, type, types) {
- const match = closest(type, types);
- return match ? `${message} "${match}"?` : "";
-}
-function getFlag(name1) {
- if (name1.startsWith("-")) {
- return name1;
- }
- if (name1.length > 1) {
- return `--${name1}`;
- }
- return `-${name1}`;
-}
-function isOption(option, name1) {
- return option.name === name1 || option.aliases && option.aliases.indexOf(name1) !== -1;
-}
-function closest(str, arr) {
- let minDistance = Infinity;
- let minIndex = 0;
- for(let i = 0; i < arr.length; i++){
- const dist = distance(str, arr[i]);
- if (dist < minDistance) {
- minDistance = dist;
- minIndex = i;
- }
- }
- return arr[minIndex];
-}
-function getDefaultValue(option) {
- return typeof option.default === "function" ? option.default() : option.default;
-}
-class FlagsError extends Error {
- constructor(message){
- super(message);
- Object.setPrototypeOf(this, FlagsError.prototype);
- }
-}
-class UnknownRequiredOption extends FlagsError {
- constructor(option10, options4){
- super(`Unknown required option "${getFlag(option10)}".${didYouMeanOption(option10, options4)}`);
- Object.setPrototypeOf(this, UnknownRequiredOption.prototype);
- }
-}
-class UnknownConflictingOption extends FlagsError {
- constructor(option1, options1){
- super(`Unknown conflicting option "${getFlag(option1)}".${didYouMeanOption(option1, options1)}`);
- Object.setPrototypeOf(this, UnknownConflictingOption.prototype);
- }
-}
-class UnknownType extends FlagsError {
- constructor(type2, types1){
- super(`Unknown type "${type2}".${didYouMeanType(type2, types1)}`);
- Object.setPrototypeOf(this, UnknownType.prototype);
- }
-}
-class ValidationError2 extends FlagsError {
- constructor(message1){
- super(message1);
- Object.setPrototypeOf(this, ValidationError2.prototype);
- }
-}
-class DuplicateOption extends ValidationError2 {
- constructor(name1){
- super(`Option "${getFlag(name1).replace(/^--no-/, "--")}" can only occur once, but was found several
times.`);
- Object.setPrototypeOf(this, DuplicateOption.prototype);
- }
-}
-class InvalidOption extends ValidationError2 {
- constructor(option2, options2){
- super(`Invalid option "${getFlag(option2)}".${didYouMeanOption(option2, options2)}`);
- Object.setPrototypeOf(this, InvalidOption.prototype);
- }
-}
-class UnknownOption extends ValidationError2 {
- constructor(option3, options3){
- super(`Unknown option "${getFlag(option3)}".${didYouMeanOption(option3, options3)}`);
- Object.setPrototypeOf(this, UnknownOption.prototype);
- }
-}
-class MissingOptionValue extends ValidationError2 {
- constructor(option4){
- super(`Missing value for option "${getFlag(option4)}".`);
- Object.setPrototypeOf(this, MissingOptionValue.prototype);
- }
-}
-class InvalidOptionValue extends ValidationError2 {
- constructor(option5, expected, value2){
- super(`Option "${getFlag(option5)}" must be of type "${expected}", but got "${value2}".`);
- Object.setPrototypeOf(this, InvalidOptionValue.prototype);
- }
-}
-class OptionNotCombinable extends ValidationError2 {
- constructor(option6){
- super(`Option "${getFlag(option6)}" cannot be combined with other options.`);
- Object.setPrototypeOf(this, OptionNotCombinable.prototype);
- }
-}
-class ConflictingOption extends ValidationError2 {
- constructor(option7, conflictingOption){
- super(`Option "${getFlag(option7)}" conflicts with option "${getFlag(conflictingOption)}".`);
- Object.setPrototypeOf(this, ConflictingOption.prototype);
- }
-}
-class DependingOption extends ValidationError2 {
- constructor(option8, dependingOption){
- super(`Option "${getFlag(option8)}" depends on option "${getFlag(dependingOption)}".`);
- Object.setPrototypeOf(this, DependingOption.prototype);
- }
-}
-class MissingRequiredOption extends ValidationError2 {
- constructor(option9){
- super(`Missing required option "${getFlag(option9)}".`);
- Object.setPrototypeOf(this, MissingRequiredOption.prototype);
- }
-}
-class RequiredArgumentFollowsOptionalArgument extends ValidationError2 {
- constructor(arg3){
- super(`An required argument cannot follow an optional argument, but "${arg3}" is defined as
required.`);
- Object.setPrototypeOf(this, RequiredArgumentFollowsOptionalArgument.prototype);
- }
-}
-class ArgumentFollowsVariadicArgument extends ValidationError2 {
- constructor(arg1){
- super(`An argument cannot follow an variadic argument, but got "${arg1}".`);
- Object.setPrototypeOf(this, ArgumentFollowsVariadicArgument.prototype);
- }
-}
-class NoArguments extends ValidationError2 {
- constructor(){
- super(`No arguments.`);
- Object.setPrototypeOf(this, NoArguments.prototype);
- }
-}
-class InvalidTypeError extends ValidationError2 {
- constructor({ label: label1 , name: name2 , value: value1 , type: type1 }, expected1){
- super(`${label1} "${name2}" must be of type "${type1}", but got "${value1}".` + (expected1 ? `
Expected values: ${expected1.map((value2)=>`"${value2}"`
- ).join(", ")}` : ""));
- Object.setPrototypeOf(this, MissingOptionValue.prototype);
- }
-}
-var OptionType1;
-(function(OptionType1) {
- OptionType1["STRING"] = "string";
- OptionType1["NUMBER"] = "number";
- OptionType1["INTEGER"] = "integer";
- OptionType1["BOOLEAN"] = "boolean";
-})(OptionType1 || (OptionType1 = {
-}));
-function didYouMeanCommand(command, commands, excludes = []) {
- const commandNames = commands.map((command1)=>command1.getName()
- ).filter((command1)=>!excludes.includes(command1)
- );
- return didYouMean(" Did you mean command", command, commandNames);
-}
-const ARGUMENT_REGEX = /^[<\[].+[\]>]$/;
-const ARGUMENT_DETAILS_REGEX = /[<\[:>\]]/;
-function splitArguments(args) {
- const parts = args.trim().split(/[, =] */g);
- const typeParts = [];
- while(parts[parts.length - 1] && ARGUMENT_REGEX.test(parts[parts.length - 1])){
- typeParts.unshift(parts.pop());
- }
- const typeDefinition = typeParts.join(" ");
+const mod2 = function() {
return {
- flags: parts,
- typeDefinition
+ ansi,
+ bel,
+ cursorPosition,
+ cursorTo,
+ cursorMove,
+ cursorUp,
+ cursorDown,
+ cursorForward,
+ cursorBackward,
+ cursorNextLine,
+ cursorPrevLine,
+ cursorLeft,
+ cursorHide,
+ cursorShow,
+ cursorSave,
+ cursorRestore,
+ scrollUp,
+ scrollDown,
+ eraseScreen,
+ eraseUp,
+ eraseDown,
+ eraseLine,
+ eraseLineEnd,
+ eraseLineStart,
+ eraseLines,
+ clearScreen,
+ clearTerminal,
+ link,
+ image,
+ colors,
+ getCursorPosition,
+ tty,
+ mod: mod1
};
-}
-function parseArgumentsDefinition(argsDefinition) {
- const argumentDetails = [];
- let hasOptional = false;
- let hasVariadic = false;
- const parts = argsDefinition.split(/ +/);
- for (const arg2 of parts){
- if (hasVariadic) {
- throw new ArgumentFollowsVariadicArgument(arg2);
- }
- const parts1 = arg2.split(ARGUMENT_DETAILS_REGEX);
- const type2 = parts1[2] || OptionType1.STRING;
- const details = {
- optionalValue: arg2[0] !== "<",
- name: parts1[1],
- action: parts1[3] || type2,
- variadic: false,
- list: type2 ? arg2.indexOf(type2 + "[]") !== -1 : false,
- type: type2
- };
- if (!details.optionalValue && hasOptional) {
- throw new RequiredArgumentFollowsOptionalArgument(details.name);
- }
- if (arg2[0] === "[") {
- hasOptional = true;
- }
- if (details.name.length > 3) {
- const istVariadicLeft = details.name.slice(0, 3) === "...";
- const istVariadicRight = details.name.slice(-3) === "...";
- hasVariadic = details.variadic = istVariadicLeft || istVariadicRight;
- if (istVariadicLeft) {
- details.name = details.name.slice(3);
- } else if (istVariadicRight) {
- details.name = details.name.slice(0, -3);
- }
- }
- if (details.name) {
- argumentDetails.push(details);
- }
- }
- return argumentDetails;
-}
-class CommandError extends Error {
- constructor(message2){
- super(message2);
- Object.setPrototypeOf(this, CommandError.prototype);
- }
-}
-class ValidationError1 extends CommandError {
- exitCode;
- constructor(message3, { exitCode } = {
- }){
- super(message3);
- Object.setPrototypeOf(this, ValidationError1.prototype);
- this.exitCode = exitCode ?? 1;
- }
-}
-class DuplicateOptionName extends CommandError {
- constructor(name3){
- super(`Option with name "${getFlag(name3)}" already exists.`);
- Object.setPrototypeOf(this, DuplicateOptionName.prototype);
- }
-}
-class MissingCommandName extends CommandError {
- constructor(){
- super("Missing command name.");
- Object.setPrototypeOf(this, MissingCommandName.prototype);
- }
-}
-class DuplicateCommandName extends CommandError {
- constructor(name4){
- super(`Duplicate command name "${name4}".`);
- Object.setPrototypeOf(this, DuplicateCommandName.prototype);
- }
-}
-class DuplicateCommandAlias extends CommandError {
- constructor(alias1){
- super(`Duplicate command alias "${alias1}".`);
- Object.setPrototypeOf(this, DuplicateCommandAlias.prototype);
- }
-}
-class CommandNotFound extends CommandError {
- constructor(name5, commands4, excluded){
- super(`Unknown command "${name5}".${didYouMeanCommand(name5, commands4, excluded)}`);
- Object.setPrototypeOf(this, UnknownCommand.prototype);
- }
-}
-class DuplicateType extends CommandError {
- constructor(name6){
- super(`Type with name "${name6}" already exists.`);
- Object.setPrototypeOf(this, DuplicateType.prototype);
- }
-}
-class DuplicateCompletion extends CommandError {
- constructor(name7){
- super(`Completion with name "${name7}" already exists.`);
- Object.setPrototypeOf(this, DuplicateCompletion.prototype);
- }
-}
-class DuplicateExample extends CommandError {
- constructor(name8){
- super(`Example with name "${name8}" already exists.`);
- Object.setPrototypeOf(this, DuplicateExample.prototype);
- }
-}
-class DuplicateEnvironmentVariable extends CommandError {
- constructor(name9){
- super(`Environment variable with name "${name9}" already exists.`);
- Object.setPrototypeOf(this, DuplicateEnvironmentVariable.prototype);
- }
-}
-class MissingRequiredEnvVar extends ValidationError1 {
- constructor(envVar){
- super(`Missing required environment variable "${envVar.names[0]}".`);
- Object.setPrototypeOf(this, MissingRequiredEnvVar.prototype);
- }
-}
-class EnvironmentVariableSingleValue extends CommandError {
- constructor(name10){
- super(`An environment variable can only have one value, but "${name10}" has more than one.`);
- Object.setPrototypeOf(this, EnvironmentVariableSingleValue.prototype);
- }
-}
-class EnvironmentVariableOptionalValue extends CommandError {
- constructor(name11){
- super(`An environment variable cannot have an optional value, but "${name11}" is defined as
optional.`);
- Object.setPrototypeOf(this, EnvironmentVariableOptionalValue.prototype);
- }
-}
-class EnvironmentVariableVariadicValue extends CommandError {
- constructor(name12){
- super(`An environment variable cannot have an variadic value, but "${name12}" is defined as
variadic.`);
- Object.setPrototypeOf(this, EnvironmentVariableVariadicValue.prototype);
- }
-}
-class DefaultCommandNotFound extends CommandError {
- constructor(name13, commands1){
- super(`Default command "${name13}" not found.${didYouMeanCommand(name13, commands1)}`);
- Object.setPrototypeOf(this, DefaultCommandNotFound.prototype);
- }
-}
-class CommandExecutableNotFound extends CommandError {
- constructor(name14){
- super(`Command executable not found: ${name14}`);
- Object.setPrototypeOf(this, CommandExecutableNotFound.prototype);
- }
-}
-class UnknownCompletionCommand extends CommandError {
- constructor(name15, commands2){
- super(`Auto-completion failed. Unknown command "${name15}".${didYouMeanCommand(name15, commands2)}`);
- Object.setPrototypeOf(this, UnknownCompletionCommand.prototype);
- }
-}
-class UnknownCommand extends ValidationError1 {
- constructor(name16, commands3, excluded1){
- super(`Unknown command "${name16}".${didYouMeanCommand(name16, commands3, excluded1)}`);
- Object.setPrototypeOf(this, UnknownCommand.prototype);
- }
-}
-class NoArgumentsAllowed extends ValidationError1 {
- constructor(name17){
- super(`No arguments allowed for command "${name17}".`);
- Object.setPrototypeOf(this, NoArgumentsAllowed.prototype);
- }
-}
-class MissingArguments extends ValidationError1 {
- constructor(args2){
- super("Missing argument(s): " + args2.join(", "));
- Object.setPrototypeOf(this, MissingArguments.prototype);
- }
-}
-class MissingArgument extends ValidationError1 {
- constructor(arg2){
- super(`Missing argument "${arg2}".`);
- Object.setPrototypeOf(this, MissingArgument.prototype);
- }
-}
-class TooManyArguments extends ValidationError1 {
- constructor(args1){
- super(`Too many arguments: ${args1.join(" ")}`);
- Object.setPrototypeOf(this, TooManyArguments.prototype);
- }
-}
-const __boolean = (type2)=>{
- if (~[
- "1",
- "true"
- ].indexOf(type2.value)) {
- return true;
- }
- if (~[
- "0",
- "false"
- ].indexOf(type2.value)) {
- return false;
- }
- throw new InvalidTypeError(type2);
-};
-const number1 = (type2)=>{
- const value2 = Number(type2.value);
- if (Number.isFinite(value2)) {
- return value2;
- }
- throw new InvalidTypeError(type2);
+}();
+const KeyMap = {
+ "[P": "f1",
+ "[Q": "f2",
+ "[R": "f3",
+ "[S": "f4",
+ "OP": "f1",
+ "OQ": "f2",
+ "OR": "f3",
+ "OS": "f4",
+ "[11~": "f1",
+ "[12~": "f2",
+ "[13~": "f3",
+ "[14~": "f4",
+ "[[A": "f1",
+ "[[B": "f2",
+ "[[C": "f3",
+ "[[D": "f4",
+ "[[E": "f5",
+ "[15~": "f5",
+ "[17~": "f6",
+ "[18~": "f7",
+ "[19~": "f8",
+ "[20~": "f9",
+ "[21~": "f10",
+ "[23~": "f11",
+ "[24~": "f12",
+ "[A": "up",
+ "[B": "down",
+ "[C": "right",
+ "[D": "left",
+ "[E": "clear",
+ "[F": "end",
+ "[H": "home",
+ "OA": "up",
+ "OB": "down",
+ "OC": "right",
+ "OD": "left",
+ "OE": "clear",
+ "OF": "end",
+ "OH": "home",
+ "[1~": "home",
+ "[2~": "insert",
+ "[3~": "delete",
+ "[4~": "end",
+ "[5~": "pageup",
+ "[6~": "pagedown",
+ "[[5~": "pageup",
+ "[[6~": "pagedown",
+ "[7~": "home",
+ "[8~": "end"
};
-const string1 = ({ value: value2 })=>{
- return value2;
+const KeyMapShift = {
+ "[a": "up",
+ "[b": "down",
+ "[c": "right",
+ "[d": "left",
+ "[e": "clear",
+ "[2$": "insert",
+ "[3$": "delete",
+ "[5$": "pageup",
+ "[6$": "pagedown",
+ "[7$": "home",
+ "[8$": "end",
+ "[Z": "tab"
};
-function validateFlags1(flags, values, _knownFlaks, allowEmpty, optionNames = {
-}) {
- const defaultValues = {
- };
- for (const option10 of flags){
- let name18;
- let defaultValue = undefined;
- if (option10.name.startsWith("no-")) {
- const propName = option10.name.replace(/^no-/, "");
- if (propName in values) {
- continue;
- }
- const positiveOption = getOption(flags, propName);
- if (positiveOption) {
- continue;
- }
- name18 = paramCaseToCamelCase(propName);
- defaultValue = true;
- }
- if (!name18) {
- name18 = paramCaseToCamelCase(option10.name);
- }
- if (!(name18 in optionNames)) {
- optionNames[name18] = option10.name;
- }
- const hasDefaultValue = typeof values[name18] === "undefined" && (typeof option10.default !==
"undefined" || typeof defaultValue !== "undefined");
- if (hasDefaultValue) {
- values[name18] = getDefaultValue(option10) ?? defaultValue;
- defaultValues[option10.name] = true;
- if (typeof option10.value === "function") {
- values[name18] = option10.value(values[name18]);
- }
- }
- }
- const keys = Object.keys(values);
- if (keys.length === 0 && allowEmpty) {
- return;
- }
- const options4 = keys.map((name18)=>({
- name: name18,
- option: getOption(flags, optionNames[name18])
- })
- );
- for (const { name: name18 , option: option11 } of options4){
- if (!option11) {
- throw new UnknownOption(name18, flags);
- }
- if (option11.standalone) {
- if (keys.length > 1) {
- if (options4.every(({ option: opt })=>opt && (option11 === opt || defaultValues[opt.name])
- )) {
- return;
- }
- throw new OptionNotCombinable(option11.name);
- }
- return;
- }
- option11.conflicts?.forEach((flag)=>{
- if (isset(flag, values)) {
- throw new ConflictingOption(option11.name, flag);
- }
- });
- option11.depends?.forEach((flag)=>{
- if (!isset(flag, values) && !defaultValues[option11.name]) {
- throw new DependingOption(option11.name, flag);
- }
- });
- const isArray = (option11.args?.length || 0) > 1;
- option11.args?.forEach((arg3, i)=>{
- if (arg3.requiredValue && (typeof values[name18] === "undefined" || isArray && typeof
values[name18][i] === "undefined")) {
- throw new MissingOptionValue(option11.name);
- }
- });
- }
- for (const option12 of flags){
- if (option12.required && !(paramCaseToCamelCase(option12.name) in values)) {
- if ((!option12.conflicts || !option12.conflicts.find((flag)=>!!values[flag]
- )) && !options4.find((opt)=>opt.option?.conflicts?.find((flag)=>flag === option12.name
- )
- )) {
- throw new MissingRequiredOption(option12.name);
- }
- }
- }
- if (keys.length === 0 && !allowEmpty) {
- throw new NoArguments();
- }
-}
-function isset(flag, values) {
- const name18 = paramCaseToCamelCase(flag);
- return typeof values[name18] !== "undefined";
-}
-const integer = (type2)=>{
- const value2 = Number(type2.value);
- if (Number.isInteger(value2)) {
- return value2;
- }
- throw new InvalidTypeError(type2);
+const KeyMapCtrl = {
+ "Oa": "up",
+ "Ob": "down",
+ "Oc": "right",
+ "Od": "left",
+ "Oe": "clear",
+ "[2^": "insert",
+ "[3^": "delete",
+ "[5^": "pageup",
+ "[6^": "pagedown",
+ "[7^": "home",
+ "[8^": "end"
};
-const Types = {
- [OptionType1.STRING]: string1,
- [OptionType1.NUMBER]: number1,
- [OptionType1.INTEGER]: integer,
- [OptionType1.BOOLEAN]: __boolean
+const SpecialKeyMap = {
+ "\r": "return",
+ "\n": "enter",
+ "\t": "tab",
+ "\b": "backspace",
+ "\x7f": "backspace",
+ "\x1b": "escape",
+ " ": "space"
};
-function parseFlags1(args2, opts = {
-}) {
- args2 = args2.slice();
- !opts.flags && (opts.flags = []);
- let inLiteral = false;
- let negate = false;
- const flags = {
- };
- const optionNames = {
- };
- let literal = [];
- let unknown = [];
- let stopEarly = null;
- opts.flags.forEach((opt)=>{
- opt.depends?.forEach((flag)=>{
- if (!opts.flags || !getOption(opts.flags, flag)) {
- throw new UnknownRequiredOption(flag, opts.flags ?? []);
- }
- });
- opt.conflicts?.forEach((flag)=>{
- if (!opts.flags || !getOption(opts.flags, flag)) {
- throw new UnknownConflictingOption(flag, opts.flags ?? []);
- }
- });
- });
- for(let argsIndex = 0; argsIndex < args2.length; argsIndex++){
- let option10;
- let optionArgs;
- let current = args2[argsIndex];
- let currentValue;
- if (inLiteral) {
- literal.push(current);
- continue;
- }
- if (current === "--") {
- inLiteral = true;
- continue;
- }
- const isFlag = current.length > 1 && current[0] === "-";
- const next = ()=>currentValue ?? args2[argsIndex + 1]
- ;
- if (isFlag) {
- const isShort = current[1] !== "-";
- const isLong = isShort ? false : current.length > 3 && current[2] !== "-";
- if (!isShort && !isLong) {
- throw new InvalidOption(current, opts.flags);
- }
- const equalSignIndex = current.indexOf("=");
- if (equalSignIndex > -1) {
- currentValue = current.slice(equalSignIndex + 1) || undefined;
- current = current.slice(0, equalSignIndex);
- }
- if (isShort && current.length > 2 && current[2] !== ".") {
- args2.splice(argsIndex, 1, ...splitFlags(current));
- current = args2[argsIndex];
- } else if (isLong && current.startsWith("--no-")) {
- negate = true;
- }
- option10 = getOption(opts.flags, current);
- if (!option10) {
- if (opts.flags.length) {
- throw new UnknownOption(current, opts.flags);
- }
- option10 = {
- name: current.replace(/^-+/, ""),
- optionalValue: true,
- type: OptionType1.STRING
- };
- }
- const positiveName = negate ? option10.name.replace(/^no-?/, "") : option10.name;
- const propName = paramCaseToCamelCase(positiveName);
- if (typeof flags[propName] !== "undefined") {
- if (!opts.flags.length) {
- option10.collect = true;
- } else if (!option10.collect) {
- throw new DuplicateOption(current);
- }
- }
- optionArgs = option10.args?.length ? option10.args : [
- {
- type: option10.type,
- requiredValue: option10.requiredValue,
- optionalValue: option10.optionalValue,
- variadic: option10.variadic,
- list: option10.list,
- separator: option10.separator
- }
- ];
- let optionArgsIndex = 0;
- let inOptionalArg = false;
- const previous = flags[propName];
- parseNext(option10, optionArgs);
- if (typeof flags[propName] === "undefined") {
- if (optionArgs[optionArgsIndex].requiredValue) {
- throw new MissingOptionValue(option10.name);
- } else if (typeof option10.default !== "undefined") {
- flags[propName] = getDefaultValue(option10);
- } else {
- flags[propName] = true;
- }
- }
- if (option10.value) {
- flags[propName] = option10.value(flags[propName], previous);
- } else if (option10.collect) {
- const value2 = typeof previous !== "undefined" ? Array.isArray(previous) ? previous : [
- previous
- ] : [];
- value2.push(flags[propName]);
- flags[propName] = value2;
- }
- optionNames[propName] = option10.name;
- opts.option?.(option10, flags[propName]);
- function parseNext(option11, optionArgs1) {
- const arg3 = optionArgs1[optionArgsIndex];
- if (!arg3) {
- const flag = next();
- throw new UnknownOption(flag, opts.flags ?? []);
- }
- if (!arg3.type) {
- arg3.type = OptionType1.BOOLEAN;
- }
- if (option11.args?.length) {
- if ((typeof arg3.optionalValue === "undefined" || arg3.optionalValue === false) &&
typeof arg3.requiredValue === "undefined") {
- arg3.requiredValue = true;
- }
- } else {
- if (arg3.type !== OptionType1.BOOLEAN && (typeof arg3.optionalValue === "undefined" ||
arg3.optionalValue === false) && typeof arg3.requiredValue === "undefined") {
- arg3.requiredValue = true;
- }
- }
- if (arg3.requiredValue) {
- if (inOptionalArg) {
- throw new RequiredArgumentFollowsOptionalArgument(option11.name);
- }
- } else {
- inOptionalArg = true;
- }
- if (negate) {
- flags[propName] = false;
- return;
- }
- let result;
- let increase = false;
- if (arg3.list && hasNext(arg3)) {
- const parsed = next().split(arg3.separator || ",").map((nextValue)=>{
- const value2 = parseValue(option11, arg3, nextValue);
- if (typeof value2 === "undefined") {
- throw new InvalidOptionValue(option11.name, arg3.type ?? "?", nextValue);
- }
- return value2;
- });
- if (parsed?.length) {
- result = parsed;
- }
- } else {
- if (hasNext(arg3)) {
- result = parseValue(option11, arg3, next());
- } else if (arg3.optionalValue && arg3.type === OptionType1.BOOLEAN) {
- result = true;
- }
- }
- if (increase && typeof currentValue === "undefined") {
- argsIndex++;
- if (!arg3.variadic) {
- optionArgsIndex++;
- } else if (optionArgs1[optionArgsIndex + 1]) {
- throw new ArgumentFollowsVariadicArgument(next());
- }
- }
- if (typeof result !== "undefined" && (optionArgs1.length > 1 || arg3.variadic)) {
- if (!flags[propName]) {
- flags[propName] = [];
- }
- flags[propName].push(result);
- if (hasNext(arg3)) {
- parseNext(option11, optionArgs1);
- }
- } else {
- flags[propName] = result;
- }
- function hasNext(arg4) {
- const nextValue = currentValue ?? args2[argsIndex + 1];
- if (!currentValue && !nextValue) {
- return false;
- }
- if (arg4.requiredValue) {
- return true;
- }
- if (arg4.optionalValue || arg4.variadic) {
- return nextValue[0] !== "-" || arg4.type === OptionType1.NUMBER &&
!isNaN(Number(nextValue));
- }
- return false;
- }
- function parseValue(option12, arg4, value2) {
- const type2 = arg4.type || OptionType1.STRING;
- const result1 = opts.parse ? opts.parse({
- label: "Option",
- type: type2,
- name: `--${option12.name}`,
- value: value2
- }) : parseFlagValue(option12, arg4, value2);
- if (typeof result1 !== "undefined") {
- increase = true;
- }
- return result1;
- }
- }
- } else {
- if (opts.stopEarly) {
- stopEarly = current;
- break;
- }
- unknown.push(current);
- }
- }
- if (stopEarly) {
- const stopEarlyArgIndex = args2.indexOf(stopEarly);
- if (stopEarlyArgIndex !== -1) {
- const doubleDashIndex = args2.indexOf("--");
- unknown = args2.slice(stopEarlyArgIndex, doubleDashIndex === -1 ? undefined : doubleDashIndex);
- if (doubleDashIndex !== -1) {
- literal = args2.slice(doubleDashIndex + 1);
- }
- }
- }
- if (opts.flags?.length) {
- validateFlags1(opts.flags, flags, opts.knownFlaks, opts.allowEmpty, optionNames);
- }
- const result = Object.keys(flags).reduce((result1, key)=>{
- if (~key.indexOf(".")) {
- key.split(".").reduce((result2, subKey, index, parts)=>{
- if (index === parts.length - 1) {
- result2[subKey] = flags[key];
- } else {
- result2[subKey] = result2[subKey] ?? {
- };
- }
- return result2[subKey];
- }, result1);
- } else {
- result1[key] = flags[key];
- }
- return result1;
- }, {
- });
- return {
- flags: result,
- unknown,
- literal
- };
-}
-function splitFlags(flag) {
- const normalized = [];
- const flags = flag.slice(1).split("");
- if (isNaN(Number(flag[flag.length - 1]))) {
- flags.forEach((val)=>normalized.push(`-${val}`)
- );
- } else {
- normalized.push(`-${flags.shift()}`);
- if (flags.length) {
- normalized.push(flags.join(""));
- }
- }
- return normalized;
-}
-function parseFlagValue(option10, arg3, value2) {
- const type2 = arg3.type || OptionType1.STRING;
- const parseType = Types[type2];
- if (!parseType) {
- throw new UnknownType(type2, Object.keys(Types));
- }
- return parseType({
- label: "Option",
- type: type2,
- name: `--${option10.name}`,
- value: value2
- });
-}
-class Type1 {
-}
-export { Type1 as Type };
-class BooleanType1 extends Type1 {
- parse(type) {
- return __boolean(type);
- }
- complete() {
- return [
- "true",
- "false"
- ];
- }
-}
-export { BooleanType1 as BooleanType };
-class NumberType1 extends Type1 {
- parse(type) {
- return number1(type);
- }
-}
-export { NumberType1 as NumberType };
-class StringType1 extends Type1 {
- parse(type) {
- return string1(type);
- }
-}
-export { StringType1 as StringType };
-const border = {
- top: "─",
- topMid: "┬",
- topLeft: "┌",
- topRight: "┐",
- bottom: "─",
- bottomMid: "┴",
- bottomLeft: "└",
- bottomRight: "┘",
- left: "│",
- leftMid: "├",
- mid: "─",
- midMid: "┼",
- right: "│",
- rightMid: "┤",
- middle: "│"
-};
-class Cell1 {
- value;
- options = {
- };
- get length() {
- return this.toString().length;
- }
- static from(value) {
- const cell = new this(value);
- if (value instanceof Cell1) {
- cell.options = {
- ...value.options
- };
- }
- return cell;
- }
- constructor(value3){
- this.value = value3;
- }
- toString() {
- return this.value.toString();
- }
- setValue(value) {
- this.value = value;
- return this;
- }
- clone(value) {
- const cell = new Cell1(value ?? this);
- cell.options = {
- ...this.options
- };
- return cell;
- }
- border(enable, override = true) {
- if (override || typeof this.options.border === "undefined") {
- this.options.border = enable;
- }
- return this;
- }
- colSpan(span, override = true) {
- if (override || typeof this.options.colSpan === "undefined") {
- this.options.colSpan = span;
- }
- return this;
- }
- rowSpan(span, override = true) {
- if (override || typeof this.options.rowSpan === "undefined") {
- this.options.rowSpan = span;
- }
- return this;
- }
- align(direction, override = true) {
- if (override || typeof this.options.align === "undefined") {
- this.options.align = direction;
- }
- return this;
- }
- getBorder() {
- return this.options.border === true;
- }
- getColSpan() {
- return typeof this.options.colSpan === "number" && this.options.colSpan > 0 ? this.options.colSpan :
1;
- }
- getRowSpan() {
- return typeof this.options.rowSpan === "number" && this.options.rowSpan > 0 ? this.options.rowSpan :
1;
- }
- getAlign() {
- return this.options.align ?? "left";
- }
-}
-export { Cell1 as Cell };
-class Row1 extends Array {
- options = {
- };
- static from(cells) {
- const row = new this(...cells);
- if (cells instanceof Row1) {
- row.options = {
- ...cells.options
- };
- }
- return row;
- }
- clone() {
- const row = new Row1(...this.map((cell)=>cell instanceof Cell1 ? cell.clone() : cell
- ));
- row.options = {
- ...this.options
- };
- return row;
- }
- border(enable, override = true) {
- if (override || typeof this.options.border === "undefined") {
- this.options.border = enable;
- }
- return this;
- }
- align(direction, override = true) {
- if (override || typeof this.options.align === "undefined") {
- this.options.align = direction;
- }
- return this;
- }
- getBorder() {
- return this.options.border === true;
- }
- hasBorder() {
- return this.getBorder() || this.some((cell)=>cell instanceof Cell1 && cell.getBorder()
- );
- }
- getAlign() {
- return this.options.align ?? "left";
- }
-}
-export { Row1 as Row };
-function consumeWords(length, content) {
- let consumed = "";
- const words = content.split(/ /g);
- for(let i = 0; i < words.length; i++){
- let word = words[i];
- const hasLineBreak = word.indexOf("\n") !== -1;
- if (hasLineBreak) {
- word = word.split("\n").shift();
- }
- if (consumed) {
- const nextLength = stripColor(word).length;
- const consumedLength = stripColor(consumed).length;
- if (consumedLength + nextLength >= length) {
- break;
- }
- }
- consumed += (i > 0 ? " " : "") + word;
- if (hasLineBreak) {
- break;
- }
- }
- return consumed;
-}
-function longest(index, rows, maxWidth) {
- return Math.max(...rows.map((row)=>(row[index] instanceof Cell1 && row[index].getColSpan() > 1 ? "" :
row[index]?.toString() || "").split("\n").map((r)=>{
- const str = typeof maxWidth === "undefined" ? r : consumeWords(maxWidth, r);
- return stripColor(str).length || 0;
- })
- ).flat());
-}
-class TableLayout {
- table;
- options;
- constructor(table, options5){
- this.table = table;
- this.options = options5;
- }
- toString() {
- const opts = this.createLayout();
- return opts.rows.length ? this.renderRows(opts) : "";
- }
- createLayout() {
- Object.keys(this.options.chars).forEach((key)=>{
- if (typeof this.options.chars[key] !== "string") {
- this.options.chars[key] = "";
- }
- });
- const hasBodyBorder = this.table.getBorder() || this.table.hasBodyBorder();
- const hasHeaderBorder = this.table.hasHeaderBorder();
- const hasBorder = hasHeaderBorder || hasBodyBorder;
- const header = this.table.getHeader();
- const rows = this.spanRows(header ? [
- header,
- ...this.table
- ] : this.table.slice());
- const columns = Math.max(...rows.map((row)=>row.length
- ));
- for (const row of rows){
- const length = row.length;
- if (length < columns) {
- const diff = columns - length;
- for(let i = 0; i < diff; i++){
- row.push(this.createCell(null, row));
- }
- }
- }
- const padding = [];
- const width = [];
- for(let colIndex = 0; colIndex < columns; colIndex++){
- const minColWidth = Array.isArray(this.options.minColWidth) ? this.options.minColWidth[colIndex]
: this.options.minColWidth;
- const maxColWidth = Array.isArray(this.options.maxColWidth) ? this.options.maxColWidth[colIndex]
: this.options.maxColWidth;
- const colWidth = longest(colIndex, rows, maxColWidth);
- width[colIndex] = Math.min(maxColWidth, Math.max(minColWidth, colWidth));
- padding[colIndex] = Array.isArray(this.options.padding) ? this.options.padding[colIndex] :
this.options.padding;
- }
- return {
- padding,
- width,
- rows,
- columns,
- hasBorder,
- hasBodyBorder,
- hasHeaderBorder
- };
- }
- spanRows(_rows, rowIndex = 0, colIndex = 0, rowSpan = [], colSpan = 1) {
- const rows = _rows;
- if (rowIndex >= rows.length && rowSpan.every((span)=>span === 1
- )) {
- return rows;
- } else if (rows[rowIndex] && colIndex >= rows[rowIndex].length && colIndex >= rowSpan.length &&
colSpan === 1) {
- return this.spanRows(rows, ++rowIndex, 0, rowSpan, 1);
- }
- if (colSpan > 1) {
- colSpan--;
- rowSpan[colIndex] = rowSpan[colIndex - 1];
- rows[rowIndex].splice(colIndex - 1, 0, rows[rowIndex][colIndex - 1]);
- return this.spanRows(rows, rowIndex, ++colIndex, rowSpan, colSpan);
- }
- if (colIndex === 0) {
- rows[rowIndex] = this.createRow(rows[rowIndex] || []);
- }
- if (rowSpan[colIndex] > 1) {
- rowSpan[colIndex]--;
- rows[rowIndex].splice(colIndex, 0, rows[rowIndex - 1][colIndex]);
- return this.spanRows(rows, rowIndex, ++colIndex, rowSpan, colSpan);
- }
- rows[rowIndex][colIndex] = this.createCell(rows[rowIndex][colIndex] || null, rows[rowIndex]);
- colSpan = rows[rowIndex][colIndex].getColSpan();
- rowSpan[colIndex] = rows[rowIndex][colIndex].getRowSpan();
- return this.spanRows(rows, rowIndex, ++colIndex, rowSpan, colSpan);
- }
- createRow(row) {
- return Row1.from(row).border(this.table.getBorder(), false).align(this.table.getAlign(), false);
- }
- createCell(cell, row) {
- return Cell1.from(cell ?? "").border(row.getBorder(), false).align(row.getAlign(), false);
- }
- renderRows(opts) {
- let result = "";
- const rowSpan = new Array(opts.columns).fill(1);
- for(let rowIndex = 0; rowIndex < opts.rows.length; rowIndex++){
- result += this.renderRow(rowSpan, rowIndex, opts);
- }
- return result.slice(0, -1);
- }
- renderRow(rowSpan, rowIndex, opts, isMultiline) {
- const row = opts.rows[rowIndex];
- const prevRow = opts.rows[rowIndex - 1];
- const nextRow = opts.rows[rowIndex + 1];
- let result = "";
- let colSpan = 1;
- if (!isMultiline && rowIndex === 0 && row.hasBorder()) {
- result += this.renderBorderRow(undefined, row, rowSpan, opts);
- }
- let isMultilineRow = false;
- result += " ".repeat(this.options.indent || 0);
- for(let colIndex = 0; colIndex < opts.columns; colIndex++){
- if (colSpan > 1) {
- colSpan--;
- rowSpan[colIndex] = rowSpan[colIndex - 1];
- continue;
- }
- result += this.renderCell(colIndex, row, opts);
- if (rowSpan[colIndex] > 1) {
- if (!isMultiline) {
- rowSpan[colIndex]--;
- }
- } else if (!prevRow || prevRow[colIndex] !== row[colIndex]) {
- rowSpan[colIndex] = row[colIndex].getRowSpan();
- }
- colSpan = row[colIndex].getColSpan();
- if (rowSpan[colIndex] === 1 && row[colIndex].length) {
- isMultilineRow = true;
- }
- }
- if (opts.columns > 0) {
- if (row[opts.columns - 1].getBorder()) {
- result += this.options.chars.right;
- } else if (opts.hasBorder) {
- result += " ";
- }
- }
- result += "\n";
- if (isMultilineRow) {
- return result + this.renderRow(rowSpan, rowIndex, opts, isMultilineRow);
- }
- if (rowIndex === 0 && opts.hasHeaderBorder || rowIndex < opts.rows.length - 1 && opts.hasBodyBorder)
{
- result += this.renderBorderRow(row, nextRow, rowSpan, opts);
- }
- if (rowIndex === opts.rows.length - 1 && row.hasBorder()) {
- result += this.renderBorderRow(row, undefined, rowSpan, opts);
- }
- return result;
- }
- renderCell(colIndex, row, opts, noBorder) {
- let result = "";
- const prevCell = row[colIndex - 1];
- const cell = row[colIndex];
- if (!noBorder) {
- if (colIndex === 0) {
- if (cell.getBorder()) {
- result += this.options.chars.left;
- } else if (opts.hasBorder) {
- result += " ";
- }
- } else {
- if (cell.getBorder() || prevCell?.getBorder()) {
- result += this.options.chars.middle;
- } else if (opts.hasBorder) {
- result += " ";
- }
- }
- }
- let maxLength = opts.width[colIndex];
- const colSpan = cell.getColSpan();
- if (colSpan > 1) {
- for(let o = 1; o < colSpan; o++){
- maxLength += opts.width[colIndex + o] + opts.padding[colIndex + o];
- if (opts.hasBorder) {
- maxLength += opts.padding[colIndex + o] + 1;
- }
- }
- }
- const { current , next } = this.renderCellValue(cell, maxLength);
- row[colIndex].setValue(next);
- if (opts.hasBorder) {
- result += " ".repeat(opts.padding[colIndex]);
- }
- result += current;
- if (opts.hasBorder || colIndex < opts.columns - 1) {
- result += " ".repeat(opts.padding[colIndex]);
- }
- return result;
- }
- renderCellValue(cell, maxLength) {
- const length = Math.min(maxLength, stripColor(cell.toString()).length);
- let words = consumeWords(length, cell.toString());
- const breakWord = stripColor(words).length > length;
- if (breakWord) {
- words = words.slice(0, length);
- }
- const next = cell.toString().slice(words.length + (breakWord ? 0 : 1));
- const fillLength = maxLength - stripColor(words).length;
- const align = cell.getAlign();
- let current;
- if (fillLength === 0) {
- current = words;
- } else if (align === "left") {
- current = words + " ".repeat(fillLength);
- } else if (align === "center") {
- current = " ".repeat(Math.floor(fillLength / 2)) + words + " ".repeat(Math.ceil(fillLength / 2));
- } else if (align === "right") {
- current = " ".repeat(fillLength) + words;
- } else {
- throw new Error("Unknown direction: " + align);
- }
- return {
- current,
- next: cell.clone(next)
- };
- }
- renderBorderRow(prevRow, nextRow, rowSpan, opts) {
- let result = "";
- let colSpan = 1;
- for(let colIndex = 0; colIndex < opts.columns; colIndex++){
- if (rowSpan[colIndex] > 1) {
- if (!nextRow) {
- throw new Error("invalid layout");
- }
- if (colSpan > 1) {
- colSpan--;
- continue;
- }
- }
- result += this.renderBorderCell(colIndex, prevRow, nextRow, rowSpan, opts);
- colSpan = nextRow?.[colIndex].getColSpan() ?? 1;
- }
- return result.length ? " ".repeat(this.options.indent) + result + "\n" : "";
- }
- renderBorderCell(colIndex, prevRow, nextRow, rowSpan, opts) {
- const a1 = prevRow?.[colIndex - 1];
- const a2 = nextRow?.[colIndex - 1];
- const b1 = prevRow?.[colIndex];
- const b2 = nextRow?.[colIndex];
- const a1Border = !!a1?.getBorder();
- const a2Border = !!a2?.getBorder();
- const b1Border = !!b1?.getBorder();
- const b2Border = !!b2?.getBorder();
- const hasColSpan = (cell)=>(cell?.getColSpan() ?? 1) > 1
- ;
- const hasRowSpan = (cell)=>(cell?.getRowSpan() ?? 1) > 1
- ;
- let result = "";
- if (colIndex === 0) {
- if (rowSpan[colIndex] > 1) {
- if (b1Border) {
- result += this.options.chars.left;
- } else {
- result += " ";
- }
- } else if (b1Border && b2Border) {
- result += this.options.chars.leftMid;
- } else if (b1Border) {
- result += this.options.chars.bottomLeft;
- } else if (b2Border) {
- result += this.options.chars.topLeft;
- } else {
- result += " ";
- }
- } else if (colIndex < opts.columns) {
- if (a1Border && b2Border || b1Border && a2Border) {
- const a1ColSpan = hasColSpan(a1);
- const a2ColSpan = hasColSpan(a2);
- const b1ColSpan = hasColSpan(b1);
- const b2ColSpan = hasColSpan(b2);
- const a1RowSpan = hasRowSpan(a1);
- const a2RowSpan = hasRowSpan(a2);
- const b1RowSpan = hasRowSpan(b1);
- const b2RowSpan = hasRowSpan(b2);
- const hasAllBorder = a1Border && b2Border && b1Border && a2Border;
- const hasAllRowSpan = a1RowSpan && b1RowSpan && a2RowSpan && b2RowSpan;
- const hasAllColSpan = a1ColSpan && b1ColSpan && a2ColSpan && b2ColSpan;
- if (hasAllRowSpan && hasAllBorder) {
- result += this.options.chars.middle;
- } else if (hasAllColSpan && hasAllBorder && a1 === b1 && a2 === b2) {
- result += this.options.chars.mid;
- } else if (a1ColSpan && b1ColSpan && a1 === b1) {
- result += this.options.chars.topMid;
- } else if (a2ColSpan && b2ColSpan && a2 === b2) {
- result += this.options.chars.bottomMid;
- } else if (a1RowSpan && a2RowSpan && a1 === a2) {
- result += this.options.chars.leftMid;
- } else if (b1RowSpan && b2RowSpan && b1 === b2) {
- result += this.options.chars.rightMid;
- } else {
- result += this.options.chars.midMid;
- }
- } else if (a1Border && b1Border) {
- if (hasColSpan(a1) && hasColSpan(b1) && a1 === b1) {
- result += this.options.chars.bottom;
- } else {
- result += this.options.chars.bottomMid;
- }
- } else if (b1Border && b2Border) {
- if (rowSpan[colIndex] > 1) {
- result += this.options.chars.left;
- } else {
- result += this.options.chars.leftMid;
- }
- } else if (b2Border && a2Border) {
- if (hasColSpan(a2) && hasColSpan(b2) && a2 === b2) {
- result += this.options.chars.top;
- } else {
- result += this.options.chars.topMid;
- }
- } else if (a1Border && a2Border) {
- if (hasRowSpan(a1) && a1 === a2) {
- result += this.options.chars.right;
- } else {
- result += this.options.chars.rightMid;
- }
- } else if (a1Border) {
- result += this.options.chars.bottomRight;
- } else if (b1Border) {
- result += this.options.chars.bottomLeft;
- } else if (a2Border) {
- result += this.options.chars.topRight;
- } else if (b2Border) {
- result += this.options.chars.topLeft;
- } else {
- result += " ";
- }
- }
- const length = opts.padding[colIndex] + opts.width[colIndex] + opts.padding[colIndex];
- if (rowSpan[colIndex] > 1 && nextRow) {
- result += this.renderCell(colIndex, nextRow, opts, true);
- if (nextRow[colIndex] === nextRow[nextRow.length - 1]) {
- if (b1Border) {
- result += this.options.chars.right;
- } else {
- result += " ";
- }
- return result;
- }
- } else if (b1Border && b2Border) {
- result += this.options.chars.mid.repeat(length);
- } else if (b1Border) {
- result += this.options.chars.bottom.repeat(length);
- } else if (b2Border) {
- result += this.options.chars.top.repeat(length);
- } else {
- result += " ".repeat(length);
- }
- if (colIndex === opts.columns - 1) {
- if (b1Border && b2Border) {
- result += this.options.chars.rightMid;
- } else if (b1Border) {
- result += this.options.chars.bottomRight;
- } else if (b2Border) {
- result += this.options.chars.topRight;
- } else {
- result += " ";
- }
- }
- return result;
- }
-}
-class Table1 extends Array {
- static _chars = {
- ...border
- };
- options = {
- indent: 0,
- border: false,
- maxColWidth: Infinity,
- minColWidth: 0,
- padding: 1,
- chars: {
- ...Table1._chars
- }
- };
- headerRow;
- static from(rows) {
- const table1 = new this(...rows);
- if (rows instanceof Table1) {
- table1.options = {
- ...rows.options
- };
- table1.headerRow = rows.headerRow ? Row1.from(rows.headerRow) : undefined;
- }
- return table1;
- }
- static fromJson(rows) {
- return new this().fromJson(rows);
- }
- static chars(chars) {
- Object.assign(this._chars, chars);
- return this;
- }
- static render(rows) {
- Table1.from(rows).render();
- }
- fromJson(rows) {
- this.header(Object.keys(rows[0]));
- this.body(rows.map((row)=>Object.values(row)
- ));
- return this;
- }
- header(header) {
- this.headerRow = header instanceof Row1 ? header : Row1.from(header);
- return this;
- }
- body(rows) {
- this.length = 0;
- this.push(...rows);
- return this;
- }
- clone() {
- const table1 = new Table1(...this.map((row)=>row instanceof Row1 ? row.clone() :
Row1.from(row).clone()
- ));
- table1.options = {
- ...this.options
- };
- table1.headerRow = this.headerRow?.clone();
- return table1;
- }
- toString() {
- return new TableLayout(this, this.options).toString();
- }
- render() {
- console.log(this.toString());
- return this;
- }
- maxColWidth(width, override = true) {
- if (override || typeof this.options.maxColWidth === "undefined") {
- this.options.maxColWidth = width;
- }
- return this;
- }
- minColWidth(width, override = true) {
- if (override || typeof this.options.minColWidth === "undefined") {
- this.options.minColWidth = width;
- }
- return this;
- }
- indent(width, override = true) {
- if (override || typeof this.options.indent === "undefined") {
- this.options.indent = width;
- }
- return this;
- }
- padding(padding, override = true) {
- if (override || typeof this.options.padding === "undefined") {
- this.options.padding = padding;
- }
- return this;
- }
- border(enable, override = true) {
- if (override || typeof this.options.border === "undefined") {
- this.options.border = enable;
- }
- return this;
- }
- align(direction, override = true) {
- if (override || typeof this.options.align === "undefined") {
- this.options.align = direction;
- }
- return this;
- }
- chars(chars) {
- Object.assign(this.options.chars, chars);
- return this;
- }
- getHeader() {
- return this.headerRow;
- }
- getBody() {
- return [
- ...this
- ];
- }
- getMaxColWidth() {
- return this.options.maxColWidth;
- }
- getMinColWidth() {
- return this.options.minColWidth;
- }
- getIndent() {
- return this.options.indent;
- }
- getPadding() {
- return this.options.padding;
- }
- getBorder() {
- return this.options.border === true;
- }
- hasHeaderBorder() {
- const hasBorder = this.headerRow?.hasBorder();
- return hasBorder === true || this.getBorder() && hasBorder !== false;
- }
- hasBodyBorder() {
- return this.getBorder() || this.some((row)=>row instanceof Row1 ? row.hasBorder() :
row.some((cell)=>cell instanceof Cell1 ? cell.getBorder : false
- )
- );
- }
- hasBorder() {
- return this.hasHeaderBorder() || this.hasBodyBorder();
- }
- getAlign() {
- return this.options.align ?? "left";
- }
-}
-export { Table1 as Table };
-class HelpGenerator {
- cmd;
- indent = 2;
- options;
- static generate(cmd, options) {
- return new HelpGenerator(cmd, options).generate();
- }
- constructor(cmd1, options6 = {
- }){
- this.cmd = cmd1;
- this.options = {
- types: false,
- hints: true,
- colors: true,
- ...options6
- };
- }
- generate() {
- const areColorsEnabled = getColorEnabled();
- setColorEnabled(this.options.colors);
- const result = this.generateHeader() + this.generateDescription() + this.generateOptions() +
this.generateCommands() + this.generateEnvironmentVariables() + this.generateExamples();
- setColorEnabled(areColorsEnabled);
- return result;
- }
- generateHeader() {
- const rows = [
- [
- bold("Usage:"),
- magenta(`${this.cmd.getPath()}${this.cmd.getArgsDefinition() ? " " +
this.cmd.getArgsDefinition() : ""}`),
- ],
- ];
- const version = this.cmd.getVersion();
- if (version) {
- rows.push([
- bold("Version:"),
- yellow(`${this.cmd.getVersion()}`)
- ]);
- }
- return "\n" + Table1.from(rows).indent(this.indent).padding(1).toString() + "\n";
- }
- generateDescription() {
- if (!this.cmd.getDescription()) {
- return "";
- }
- return this.label("Description") + Table1.from([
- [
- this.cmd.getDescription()
- ],
- ]).indent(this.indent * 2).maxColWidth(140).padding(1).toString() + "\n";
- }
- generateOptions() {
- const options7 = this.cmd.getOptions(false);
- if (!options7.length) {
- return "";
- }
- const hasTypeDefinitions = !!options7.find((option10)=>!!option10.typeDefinition
- );
- if (hasTypeDefinitions) {
- return this.label("Options") + Table1.from([
- ...options7.map((option10)=>[
- option10.flags.map((flag)=>blue(flag)
- ).join(", "),
- highlightArguments(option10.typeDefinition || "", this.options.types),
- red(bold("-")) + " " + option10.description.split("\n").shift(),
- this.generateHints(option10),
- ]
- ),
- ]).padding([
- 2,
- 2,
- 2
- ]).indent(this.indent * 2).maxColWidth([
- 60,
- 60,
- 80,
- 60
- ]).toString() + "\n";
- }
- return this.label("Options") + Table1.from([
- ...options7.map((option10)=>[
- option10.flags.map((flag)=>blue(flag)
- ).join(", "),
- red(bold("-")) + " " + option10.description.split("\n").shift(),
- this.generateHints(option10),
- ]
- ),
- ]).padding([
- 2,
- 2
- ]).indent(this.indent * 2).maxColWidth([
- 60,
- 80,
- 60
- ]).toString() + "\n";
- }
- generateCommands() {
- const commands4 = this.cmd.getCommands(false);
- if (!commands4.length) {
- return "";
- }
- const hasTypeDefinitions = !!commands4.find((command)=>!!command.getArgsDefinition()
- );
- if (hasTypeDefinitions) {
- return this.label("Commands") + Table1.from([
- ...commands4.map((command)=>[
- [
- command.getName(),
- ...command.getAliases()
- ].map((name18)=>blue(name18)
- ).join(", "),
- highlightArguments(command.getArgsDefinition() || "", this.options.types),
- red(bold("-")) + " " + command.getDescription().split("\n").shift(),
- ]
- ),
- ]).padding([
- 2,
- 2,
- 2
- ]).indent(this.indent * 2).toString() + "\n";
- }
- return this.label("Commands") + Table1.from([
- ...commands4.map((command)=>[
- [
- command.getName(),
- ...command.getAliases()
- ].map((name18)=>blue(name18)
- ).join(", "),
- red(bold("-")) + " " + command.getDescription().split("\n").shift(),
- ]
- ),
- ]).padding([
- 2,
- 2
- ]).indent(this.indent * 2).toString() + "\n";
- }
- generateEnvironmentVariables() {
- const envVars = this.cmd.getEnvVars(false);
- if (!envVars.length) {
- return "";
- }
- return this.label("Environment variables") + Table1.from([
- ...envVars.map((envVar1)=>[
- envVar1.names.map((name18)=>blue(name18)
- ).join(", "),
- highlightArgumentDetails(envVar1.details, this.options.types),
- `${red(bold("-"))} ${envVar1.description}`,
- ]
- ),
- ]).padding(2).indent(this.indent * 2).toString() + "\n";
- }
- generateExamples() {
- const examples = this.cmd.getExamples();
- if (!examples.length) {
- return "";
- }
- return this.label("Examples") + Table1.from(examples.map((example)=>[
- dim(bold(`${capitalize(example.name)}:`)),
- example.description,
- ]
- )).padding(1).indent(this.indent * 2).maxColWidth(150).toString() + "\n";
- }
- generateHints(option) {
- if (!this.options.hints) {
- return "";
- }
- const hints = [];
- option.required && hints.push(yellow(`required`));
- typeof option.default !== "undefined" && hints.push(bold(`Default: `) + inspect(option.default,
this.options.colors));
- option.depends?.length && hints.push(yellow(bold(`Depends: `)) +
italic(option.depends.map(getFlag).join(", ")));
- option.conflicts?.length && hints.push(red(bold(`Conflicts: `)) +
italic(option.conflicts.map(getFlag).join(", ")));
- const type3 = this.cmd.getType(option.args[0]?.type)?.handler;
- if (type3 instanceof Type1) {
- const possibleValues = type3.values?.(this.cmd, this.cmd.getParent());
- if (possibleValues?.length) {
- hints.push(bold(`Values: `) + possibleValues.map((value4)=>inspect(value4,
this.options.colors)
- ).join(", "));
- }
- }
- if (hints.length) {
- return `(${hints.join(", ")})`;
- }
- return "";
- }
- label(label) {
- return "\n" + " ".repeat(this.indent) + bold(`${label}:`) + "\n\n";
- }
-}
-function capitalize(string1) {
- return (string1?.charAt(0).toUpperCase() + string1.slice(1)) ?? "";
-}
-function inspect(value4, colors2) {
- return Deno.inspect(value4, {
- depth: 1,
- colors: colors2,
- trailingComma: false
- });
-}
-function highlightArguments(argsDefinition, types1 = true) {
- if (!argsDefinition) {
- return "";
- }
- return parseArgumentsDefinition(argsDefinition).map((arg3)=>highlightArgumentDetails(arg3, types1)
- ).join(" ");
-}
-function highlightArgumentDetails(arg3, types1 = true) {
- let str = "";
- str += yellow(arg3.optionalValue ? "[" : "<");
- let name18 = "";
- name18 += arg3.name;
- if (arg3.variadic) {
- name18 += "...";
- }
- name18 = magenta(name18);
- str += name18;
- if (types1) {
- str += yellow(":");
- str += red(arg3.type);
- }
- if (arg3.list) {
- str += green("[]");
- }
- str += yellow(arg3.optionalValue ? "]" : ">");
- return str;
-}
-class IntegerType extends Type1 {
- parse(type) {
- return integer(type);
- }
-}
-class Command1 {
- types = new Map();
- rawArgs = [];
- literalArgs = [];
- _name = "COMMAND";
- _parent;
- _globalParent;
- ver;
- desc = "";
- fn;
- options = [];
- commands = new Map();
- examples = [];
- envVars = [];
- aliases = [];
- completions = new Map();
- cmd = this;
- argsDefinition;
- isExecutable = false;
- throwOnError = false;
- _allowEmpty = true;
- _stopEarly = false;
- defaultCommand;
- _useRawArgs = false;
- args = [];
- isHidden = false;
- isGlobal = false;
- hasDefaults = false;
- _versionOption;
- _helpOption;
- _help;
- exitOnHelp;
- versionOption(flags, desc, opts) {
- this._versionOption = flags === false ? flags : {
- flags,
- desc,
- opts: typeof opts === "function" ? {
- action: opts
- } : opts
- };
- return this;
- }
- helpOption(flags, desc, opts) {
- this._helpOption = flags === false ? flags : {
- flags,
- desc,
- opts: typeof opts === "function" ? {
- action: opts
- } : opts
- };
- return this;
- }
- command(nameAndArguments, cmdOrDescription, override) {
- const result = splitArguments(nameAndArguments);
- const name18 = result.flags.shift();
- const aliases = result.flags;
- if (!name18) {
- throw new MissingCommandName();
- }
- if (this.getBaseCommand(name18, true)) {
- if (!override) {
- throw new DuplicateCommandName(name18);
- }
- this.removeCommand(name18);
- }
- let description;
- let cmd2;
- if (typeof cmdOrDescription === "string") {
- description = cmdOrDescription;
- }
- if (cmdOrDescription instanceof Command1) {
- cmd2 = cmdOrDescription.reset();
- } else {
- cmd2 = new Command1();
- }
- cmd2._name = name18;
- cmd2._parent = this;
- if (description) {
- cmd2.description(description);
- }
- if (result.typeDefinition) {
- cmd2.arguments(result.typeDefinition);
- }
- aliases.forEach((alias1)=>cmd2.alias(alias1)
- );
- this.commands.set(name18, cmd2);
- this.select(name18);
- return this;
- }
- alias(alias) {
- if (this.cmd._name === alias || this.cmd.aliases.includes(alias)) {
- throw new DuplicateCommandAlias(alias);
- }
- this.cmd.aliases.push(alias);
- return this;
- }
- reset() {
- this.cmd = this;
- return this;
- }
- select(name) {
- const cmd2 = this.getBaseCommand(name, true);
- if (!cmd2) {
- throw new CommandNotFound(name, this.getBaseCommands(true));
- }
- this.cmd = cmd2;
- return this;
- }
- name(name) {
- this.cmd._name = name;
- return this;
- }
- version(version) {
- if (typeof version === "string") {
- this.cmd.ver = ()=>version
- ;
- } else if (typeof version === "function") {
- this.cmd.ver = version;
- }
- return this;
- }
- help(help) {
- if (typeof help === "string") {
- this.cmd._help = ()=>help
- ;
- } else if (typeof help === "function") {
- this.cmd._help = help;
- } else {
- this.cmd.exitOnHelp = help.exit;
- this.cmd._help = (cmd2)=>HelpGenerator.generate(cmd2, help)
- ;
- }
- return this;
- }
- description(description) {
- this.cmd.desc = description;
- return this;
- }
- hidden() {
- this.cmd.isHidden = true;
- return this;
- }
- global() {
- this.cmd.isGlobal = true;
- return this;
- }
- executable() {
- this.cmd.isExecutable = true;
- return this;
- }
- arguments(args) {
- this.cmd.argsDefinition = args;
- return this;
- }
- action(fn) {
- this.cmd.fn = fn;
- return this;
- }
- allowEmpty(allowEmpty = true) {
- this.cmd._allowEmpty = allowEmpty;
- return this;
- }
- stopEarly(stopEarly = true) {
- this.cmd._stopEarly = stopEarly;
- return this;
- }
- useRawArgs(useRawArgs = true) {
- this.cmd._useRawArgs = useRawArgs;
- return this;
- }
- default(name) {
- this.cmd.defaultCommand = name;
- return this;
- }
- globalType(name, type, options) {
- return this.type(name, type, {
- ...options,
- global: true
- });
- }
- type(name, handler, options) {
- if (this.cmd.types.get(name) && !options?.override) {
- throw new DuplicateType(name);
- }
- this.cmd.types.set(name, {
- ...options,
- name,
- handler
- });
- if (handler instanceof Type1 && (typeof handler.complete !== "undefined" || typeof handler.values
!== "undefined")) {
- const completeHandler = (cmd2, parent)=>handler.complete?.(cmd2, parent) || []
- ;
- this.complete(name, completeHandler, options);
- }
- return this;
- }
- globalComplete(name, complete, options) {
- return this.complete(name, complete, {
- ...options,
- global: true
- });
- }
- complete(name, complete, options) {
- if (this.cmd.completions.has(name) && !options?.override) {
- throw new DuplicateCompletion(name);
- }
- this.cmd.completions.set(name, {
- name,
- complete,
- ...options
- });
- return this;
- }
- throwErrors() {
- this.cmd.throwOnError = true;
- return this;
- }
- shouldThrowErrors() {
- return this.cmd.throwOnError || !!this.cmd._parent?.shouldThrowErrors();
- }
- shouldExitOnHelp() {
- return this.cmd.exitOnHelp ?? (this.cmd._parent?.shouldExitOnHelp() ?? true);
- }
- globalOption(flags, desc, opts) {
- if (typeof opts === "function") {
- return this.option(flags, desc, {
- value: opts,
- global: true
- });
- }
- return this.option(flags, desc, {
- ...opts,
- global: true
- });
- }
- option(flags, desc, opts) {
- if (typeof opts === "function") {
- return this.option(flags, desc, {
- value: opts
- });
- }
- const result = splitArguments(flags);
- const args3 = result.typeDefinition ? parseArgumentsDefinition(result.typeDefinition) : [];
- const option11 = {
- ...opts,
- name: "",
- description: desc,
- args: args3,
- flags: result.flags,
- typeDefinition: result.typeDefinition
- };
- if (option11.separator) {
- for (const arg3 of args3){
- if (arg3.list) {
- arg3.separator = option11.separator;
- }
- }
- }
- for (const part of option11.flags){
- const arg3 = part.trim();
- const isLong = /^--/.test(arg3);
- const name19 = isLong ? arg3.slice(2) : arg3.slice(1);
- if (this.cmd.getBaseOption(name19, true)) {
- if (opts?.override) {
- this.removeOption(name19);
- } else {
- throw new DuplicateOptionName(name19);
- }
- }
- if (!option11.name && isLong) {
- option11.name = name19;
- } else if (!option11.aliases) {
- option11.aliases = [
- name19
- ];
- } else {
- option11.aliases.push(name19);
- }
- }
- if (option11.prepend) {
- this.cmd.options.unshift(option11);
- } else {
- this.cmd.options.push(option11);
- }
- return this;
- }
- example(name, description) {
- if (this.cmd.hasExample(name)) {
- throw new DuplicateExample(name);
- }
- this.cmd.examples.push({
- name,
- description
- });
- return this;
- }
- globalEnv(name, description, options) {
- return this.env(name, description, {
- ...options,
- global: true
- });
- }
- env(name, description, options) {
- const result = splitArguments(name);
- if (!result.typeDefinition) {
- result.typeDefinition = "<value:boolean>";
- }
- if (result.flags.some((envName)=>this.cmd.getBaseEnvVar(envName, true)
- )) {
- throw new DuplicateEnvironmentVariable(name);
- }
- const details = parseArgumentsDefinition(result.typeDefinition);
- if (details.length > 1) {
- throw new EnvironmentVariableSingleValue(name);
- } else if (details.length && details[0].optionalValue) {
- throw new EnvironmentVariableOptionalValue(name);
- } else if (details.length && details[0].variadic) {
- throw new EnvironmentVariableVariadicValue(name);
- }
- this.cmd.envVars.push({
- name: result.flags[0],
- names: result.flags,
- description,
- type: details[0].type,
- details: details.shift(),
- ...options
- });
- return this;
- }
- async parse(args = Deno.args) {
- try {
- this.reset();
- this.registerDefaults();
- this.rawArgs = args;
- if (args.length > 0) {
- const subCommand = this.getCommand(args[0], true);
- if (subCommand) {
- subCommand._globalParent = this;
- return subCommand.parse(this.rawArgs.slice(1));
- }
- }
- if (this.isExecutable) {
- await this.executeExecutable(this.rawArgs);
- return {
- options: {
- },
- args: [],
- cmd: this,
- literal: []
- };
- } else if (this._useRawArgs) {
- const env = await this.parseEnvVars();
- return await this.execute(env, ...this.rawArgs);
- } else {
- const { action , flags , unknown , literal } = this.parseFlags(this.rawArgs);
- this.literalArgs = literal;
- const env = await this.parseEnvVars();
- const options7 = {
- ...env,
- ...flags
- };
- const params = this.parseArguments(unknown, options7);
- if (action) {
- await action.call(this, options7, ...params);
- return {
- options: options7,
- args: params,
- cmd: this,
- literal: this.literalArgs
- };
- }
- return await this.execute(options7, ...params);
- }
- } catch (error) {
- throw this.error(error);
- }
- }
- registerDefaults() {
- if (this.hasDefaults || this.getParent()) {
- return this;
- }
- this.hasDefaults = true;
- this.reset();
- !this.types.has("string") && this.type("string", new StringType1(), {
- global: true
- });
- !this.types.has("number") && this.type("number", new NumberType1(), {
- global: true
- });
- !this.types.has("integer") && this.type("integer", new IntegerType(), {
- global: true
- });
- !this.types.has("boolean") && this.type("boolean", new BooleanType1(), {
- global: true
- });
- if (!this._help) {
- this.help({
- hints: true,
- types: false
- });
- }
- if (this._versionOption !== false && (this._versionOption || this.ver)) {
- this.option(this._versionOption?.flags || "-V, --version", this._versionOption?.desc || "Show
the version number for this program.", {
- standalone: true,
- prepend: true,
- action: function() {
- this.showVersion();
- if (this.shouldExitOnHelp()) {
- Deno.exit(0);
- }
- },
- ...this._versionOption?.opts ?? {
- }
- });
- }
- if (this._helpOption !== false) {
- this.option(this._helpOption?.flags || "-h, --help", this._helpOption?.desc || "Show this
help.", {
- standalone: true,
- global: true,
- prepend: true,
- action: function() {
- this.showHelp();
- if (this.shouldExitOnHelp()) {
- Deno.exit(0);
- }
- },
- ...this._helpOption?.opts ?? {
- }
- });
- }
- return this;
- }
- async execute(options, ...args) {
- if (this.fn) {
- await this.fn(options, ...args);
- } else if (this.defaultCommand) {
- const cmd2 = this.getCommand(this.defaultCommand, true);
- if (!cmd2) {
- throw new DefaultCommandNotFound(this.defaultCommand, this.getCommands());
- }
- cmd2._globalParent = this;
- await cmd2.execute(options, ...args);
- }
- return {
- options,
- args,
- cmd: this,
- literal: this.literalArgs
- };
- }
- async executeExecutable(args) {
- const command = this.getPath().replace(/\s+/g, "-");
- await Deno.permissions.request({
- name: "run",
- command
- });
- try {
- const process = Deno.run({
- cmd: [
- command,
- ...args
- ]
- });
- const status = await process.status();
- if (!status.success) {
- Deno.exit(status.code);
- }
- } catch (error) {
- if (error instanceof Deno.errors.NotFound) {
- throw new CommandExecutableNotFound(command);
- }
- throw error;
- }
- }
- parseFlags(args) {
- try {
- let action;
- const result = parseFlags1(args, {
- stopEarly: this._stopEarly,
- allowEmpty: this._allowEmpty,
- flags: this.getOptions(true),
- parse: (type3)=>this.parseType(type3)
- ,
- option: (option11)=>{
- if (!action && option11.action) {
- action = option11.action;
- }
- }
- });
- return {
- ...result,
- action
- };
- } catch (error) {
- if (error instanceof ValidationError2) {
- throw new ValidationError1(error.message);
- }
- throw error;
- }
- }
- parseType(type) {
- const typeSettings = this.getType(type.type);
- if (!typeSettings) {
- throw new UnknownType(type.type, this.getTypes().map((type3)=>type3.name
- ));
- }
- return typeSettings.handler instanceof Type1 ? typeSettings.handler.parse(type) :
typeSettings.handler(type);
- }
- async parseEnvVars() {
- const envVars = this.getEnvVars(true);
- const result = {
- };
- if (!envVars.length) {
- return result;
- }
- const hasEnvPermissions = (await Deno.permissions.query({
- name: "env"
- })).state === "granted";
- for (const env of envVars){
- const name19 = hasEnvPermissions && env.names.find((name20)=>!!Deno.env.get(name20)
- );
- if (name19) {
- const propertyName = underscoreToCamelCase(env.prefix ? env.names[0].replace(new
RegExp(`^${env.prefix}`), "") : env.names[0]);
- result[propertyName] = this.parseType({
- label: "Environment variable",
- type: env.type,
- name: name19,
- value: Deno.env.get(name19) ?? ""
- });
- } else if (env.required) {
- throw new MissingRequiredEnvVar(env);
- }
- }
- return result;
- }
- parseArguments(args, flags) {
- const params = [];
- args = args.slice(0);
- if (!this.hasArguments()) {
- if (args.length) {
- if (this.hasCommands(true)) {
- throw new UnknownCommand(args[0], this.getCommands());
- } else {
- throw new NoArgumentsAllowed(this.getPath());
- }
- }
- } else {
- if (!args.length) {
- const required = this.getArguments().filter((expectedArg)=>!expectedArg.optionalValue
- ).map((expectedArg)=>expectedArg.name
- );
- if (required.length) {
- const flagNames = Object.keys(flags);
- const hasStandaloneOption = !!flagNames.find((name19)=>this.getOption(name19,
true)?.standalone
- );
- if (!hasStandaloneOption) {
- throw new MissingArguments(required);
- }
- }
- } else {
- for (const expectedArg of this.getArguments()){
- if (!args.length) {
- if (expectedArg.optionalValue) {
- break;
- }
- throw new MissingArgument(`Missing argument: ${expectedArg.name}`);
- }
- let arg3;
- if (expectedArg.variadic) {
- arg3 = args.splice(0, args.length).map((value4)=>this.parseType({
- label: "Argument",
- type: expectedArg.type,
- name: expectedArg.name,
- value: value4
- })
- );
- } else {
- arg3 = this.parseType({
- label: "Argument",
- type: expectedArg.type,
- name: expectedArg.name,
- value: args.shift()
- });
- }
- if (arg3) {
- params.push(arg3);
- }
- }
- if (args.length) {
- throw new TooManyArguments(args);
- }
- }
- }
- return params;
- }
- error(error) {
- if (this.shouldThrowErrors() || !(error instanceof ValidationError1)) {
- return error;
- }
- this.showHelp();
- Deno.stderr.writeSync(new TextEncoder().encode(red(` ${bold("error")}: ${error.message}\n`) +
"\n"));
- Deno.exit(error instanceof ValidationError1 ? error.exitCode : 1);
- }
- getName() {
- return this._name;
- }
- getParent() {
- return this._parent;
- }
- getGlobalParent() {
- return this._globalParent;
- }
- getMainCommand() {
- return this._parent?.getMainCommand() ?? this;
- }
- getAliases() {
- return this.aliases;
- }
- getPath() {
- return this._parent ? this._parent.getPath() + " " + this._name : this._name;
- }
- getArgsDefinition() {
- return this.argsDefinition;
- }
- getArgument(name) {
- return this.getArguments().find((arg3)=>arg3.name === name
- );
- }
- getArguments() {
- if (!this.args.length && this.argsDefinition) {
- this.args = parseArgumentsDefinition(this.argsDefinition);
- }
- return this.args;
- }
- hasArguments() {
- return !!this.argsDefinition;
- }
- getVersion() {
- return this.getVersionHandler()?.call(this, this);
- }
- getVersionHandler() {
- return this.ver ?? this._parent?.getVersionHandler();
- }
- getDescription() {
- return typeof this.desc === "function" ? this.desc = this.desc() : this.desc;
- }
- getShortDescription() {
- return this.getDescription().trim().split("\n").shift();
- }
- getRawArgs() {
- return this.rawArgs;
- }
- getLiteralArgs() {
- return this.literalArgs;
- }
- showVersion() {
- console.log(this.getVersion());
- }
- showHelp() {
- console.log(this.getHelp());
- }
- getHelp() {
- this.registerDefaults();
- return this.getHelpHandler().call(this, this);
- }
- getHelpHandler() {
- return this._help ?? this._parent?.getHelpHandler();
- }
- hasOptions(hidden) {
- return this.getOptions(hidden).length > 0;
- }
- getOptions(hidden) {
- return this.getGlobalOptions(hidden).concat(this.getBaseOptions(hidden));
- }
- getBaseOptions(hidden) {
- if (!this.options.length) {
- return [];
- }
- return hidden ? this.options.slice(0) : this.options.filter((opt)=>!opt.hidden
- );
- }
- getGlobalOptions(hidden) {
- const getOptions = (cmd2, options7 = [], names = [])=>{
- if (cmd2) {
- if (cmd2.options.length) {
- cmd2.options.forEach((option11)=>{
- if (option11.global && !this.options.find((opt)=>opt.name === option11.name
- ) && names.indexOf(option11.name) === -1 && (hidden || !option11.hidden)) {
- names.push(option11.name);
- options7.push(option11);
- }
- });
- }
- return getOptions(cmd2._parent, options7, names);
- }
- return options7;
- };
- return getOptions(this._parent);
- }
- hasOption(name, hidden) {
- return !!this.getOption(name, hidden);
- }
- getOption(name, hidden) {
- return this.getBaseOption(name, hidden) ?? this.getGlobalOption(name, hidden);
- }
- getBaseOption(name, hidden) {
- const option11 = this.options.find((option12)=>option12.name === name
- );
- return option11 && (hidden || !option11.hidden) ? option11 : undefined;
- }
- getGlobalOption(name, hidden) {
- if (!this._parent) {
- return;
- }
- const option11 = this._parent.getBaseOption(name, hidden);
- if (!option11 || !option11.global) {
- return this._parent.getGlobalOption(name, hidden);
- }
- return option11;
- }
- removeOption(name) {
- const index = this.options.findIndex((option11)=>option11.name === name
- );
- if (index === -1) {
- return;
- }
- return this.options.splice(index, 1)[0];
- }
- hasCommands(hidden) {
- return this.getCommands(hidden).length > 0;
- }
- getCommands(hidden) {
- return this.getGlobalCommands(hidden).concat(this.getBaseCommands(hidden));
- }
- getBaseCommands(hidden) {
- const commands5 = Array.from(this.commands.values());
- return hidden ? commands5 : commands5.filter((cmd2)=>!cmd2.isHidden
- );
- }
- getGlobalCommands(hidden) {
- const getCommands = (cmd2, commands5 = [], names = [])=>{
- if (cmd2) {
- if (cmd2.commands.size) {
- cmd2.commands.forEach((cmd3)=>{
- if (cmd3.isGlobal && this !== cmd3 && !this.commands.has(cmd3._name) &&
names.indexOf(cmd3._name) === -1 && (hidden || !cmd3.isHidden)) {
- names.push(cmd3._name);
- commands5.push(cmd3);
- }
- });
- }
- return getCommands(cmd2._parent, commands5, names);
- }
- return commands5;
- };
- return getCommands(this._parent);
- }
- hasCommand(name, hidden) {
- return !!this.getCommand(name, hidden);
- }
- getCommand(name, hidden) {
- return this.getBaseCommand(name, hidden) ?? this.getGlobalCommand(name, hidden);
- }
- getBaseCommand(name, hidden) {
- for (const cmd2 of this.commands.values()){
- if (cmd2._name === name || cmd2.aliases.includes(name)) {
- return cmd2 && (hidden || !cmd2.isHidden) ? cmd2 : undefined;
- }
- }
- }
- getGlobalCommand(name, hidden) {
- if (!this._parent) {
- return;
- }
- const cmd2 = this._parent.getBaseCommand(name, hidden);
- if (!cmd2?.isGlobal) {
- return this._parent.getGlobalCommand(name, hidden);
- }
- return cmd2;
- }
- removeCommand(name) {
- const command = this.getBaseCommand(name, true);
- if (command) {
- this.commands.delete(command._name);
- }
- return command;
- }
- getTypes() {
- return this.getGlobalTypes().concat(this.getBaseTypes());
- }
- getBaseTypes() {
- return Array.from(this.types.values());
- }
- getGlobalTypes() {
- const getTypes = (cmd2, types2 = [], names = [])=>{
- if (cmd2) {
- if (cmd2.types.size) {
- cmd2.types.forEach((type3)=>{
- if (type3.global && !this.types.has(type3.name) && names.indexOf(type3.name) === -1)
{
- names.push(type3.name);
- types2.push(type3);
- }
- });
- }
- return getTypes(cmd2._parent, types2, names);
- }
- return types2;
- };
- return getTypes(this._parent);
- }
- getType(name) {
- return this.getBaseType(name) ?? this.getGlobalType(name);
- }
- getBaseType(name) {
- return this.types.get(name);
- }
- getGlobalType(name) {
- if (!this._parent) {
- return;
- }
- const cmd2 = this._parent.getBaseType(name);
- if (!cmd2?.global) {
- return this._parent.getGlobalType(name);
- }
- return cmd2;
- }
- getCompletions() {
- return this.getGlobalCompletions().concat(this.getBaseCompletions());
- }
- getBaseCompletions() {
- return Array.from(this.completions.values());
- }
- getGlobalCompletions() {
- const getCompletions = (cmd2, completions = [], names = [])=>{
- if (cmd2) {
- if (cmd2.completions.size) {
- cmd2.completions.forEach((completion)=>{
- if (completion.global && !this.completions.has(completion.name) &&
names.indexOf(completion.name) === -1) {
- names.push(completion.name);
- completions.push(completion);
- }
- });
- }
- return getCompletions(cmd2._parent, completions, names);
- }
- return completions;
- };
- return getCompletions(this._parent);
- }
- getCompletion(name) {
- return this.getBaseCompletion(name) ?? this.getGlobalCompletion(name);
- }
- getBaseCompletion(name) {
- return this.completions.get(name);
- }
- getGlobalCompletion(name) {
- if (!this._parent) {
- return;
- }
- const completion = this._parent.getBaseCompletion(name);
- if (!completion?.global) {
- return this._parent.getGlobalCompletion(name);
- }
- return completion;
- }
- hasEnvVars(hidden) {
- return this.getEnvVars(hidden).length > 0;
- }
- getEnvVars(hidden) {
- return this.getGlobalEnvVars(hidden).concat(this.getBaseEnvVars(hidden));
- }
- getBaseEnvVars(hidden) {
- if (!this.envVars.length) {
- return [];
- }
- return hidden ? this.envVars.slice(0) : this.envVars.filter((env)=>!env.hidden
- );
- }
- getGlobalEnvVars(hidden) {
- const getEnvVars = (cmd2, envVars = [], names = [])=>{
- if (cmd2) {
- if (cmd2.envVars.length) {
- cmd2.envVars.forEach((envVar1)=>{
- if (envVar1.global && !this.envVars.find((env)=>env.names[0] === envVar1.names[0]
- ) && names.indexOf(envVar1.names[0]) === -1 && (hidden || !envVar1.hidden)) {
- names.push(envVar1.names[0]);
- envVars.push(envVar1);
- }
- });
- }
- return getEnvVars(cmd2._parent, envVars, names);
- }
- return envVars;
- };
- return getEnvVars(this._parent);
- }
- hasEnvVar(name, hidden) {
- return !!this.getEnvVar(name, hidden);
- }
- getEnvVar(name, hidden) {
- return this.getBaseEnvVar(name, hidden) ?? this.getGlobalEnvVar(name, hidden);
- }
- getBaseEnvVar(name, hidden) {
- const envVar1 = this.envVars.find((env)=>env.names.indexOf(name) !== -1
- );
- return envVar1 && (hidden || !envVar1.hidden) ? envVar1 : undefined;
- }
- getGlobalEnvVar(name, hidden) {
- if (!this._parent) {
- return;
- }
- const envVar1 = this._parent.getBaseEnvVar(name, hidden);
- if (!envVar1?.global) {
- return this._parent.getGlobalEnvVar(name, hidden);
- }
- return envVar1;
- }
- hasExamples() {
- return this.examples.length > 0;
- }
- getExamples() {
- return this.examples;
- }
- hasExample(name) {
- return !!this.getExample(name);
- }
- getExample(name) {
- return this.examples.find((example)=>example.name === name
- );
- }
-}
-export { Command1 as Command };
-class BashCompletionsGenerator {
- cmd;
- static generate(cmd) {
- return new BashCompletionsGenerator(cmd).generate();
- }
- constructor(cmd2){
- this.cmd = cmd2;
- }
- generate() {
- const path = this.cmd.getPath();
- const version = this.cmd.getVersion() ? ` v${this.cmd.getVersion()}` : "";
- return `#!/usr/bin/env bash\n# bash completion support for
${path}${version}\n\n_${replaceSpecialChars1(path)}() {\n local word cur prev\n local -a opts\n
COMPREPLY=()\n cur="\${COMP_WORDS[COMP_CWORD]}"\n prev="\${COMP_WORDS[COMP_CWORD-1]}"\n cmd="_"\n
opts=()\n\n _${replaceSpecialChars1(this.cmd.getName())}_complete() {\n local action="$1"; shift\n
mapfile -t values < <( ${this.cmd.getName()} completions complete "\${action}" "\${@}" )\n for i in
"\${values[@]}"; do\n opts+=("$i")\n done\n }\n\n ${this.generateCompletions(this.cmd).trim()}\n\n
for word in "\${COMP_WORDS[@]}"; do\n case "\${word}" in\n -*) ;;\n *)\n
cmd_tmp="\${cmd}_\${word//[^[:alnum:]]/_}"\n if type "\${cmd_tmp}" &>/dev/null; then\n
cmd="\${cmd_tmp}"\n fi\n esac\n done\n\n \${cmd}\n\n if [[ \${#opts[@]} -eq 0 ]]; then\n #
shellcheck disable=SC2207\n COMPREPLY=($(compgen -f "\${cur}"))\n return 0\n fi\n\n local values\n
values="$( printf "\\n%s" "\${opts[@]}" )"\n local IFS=$'\\n'\n # shellcheck disable=SC2207\n local
result=($(compgen -W "\${values[@]}" -- "\${cur}"))\n if [[ \${#result[@]} -eq 0 ]]; then\n # shellcheck
disable=SC2207\n COMPREPLY=($(compgen -f "\${cur}"))\n else\n # shellcheck disable=SC2207\n
COMPREPLY=($(printf '%q\\n' "\${result[@]}"))\n fi\n\n return 0\n}\n\ncomplete -F
_${replaceSpecialChars1(path)} -o bashdefault -o default ${path}`;
- }
- generateCompletions(command, path = "", index = 1) {
- path = (path ? path + " " : "") + command.getName();
- const commandCompletions = this.generateCommandCompletions(command, path, index);
- const childCommandCompletions = command.getCommands(false).filter((subCommand)=>subCommand !==
command
- ).map((subCommand)=>this.generateCompletions(subCommand, path, index + 1)
- ).join("");
- return `${commandCompletions}\n\n${childCommandCompletions}`;
- }
- generateCommandCompletions(command, path, index) {
- const flags = this.getFlags(command);
- const childCommandNames = command.getCommands(false).map((childCommand)=>childCommand.getName()
- );
- const completionsPath = ~path.indexOf(" ") ? " " + path.split(" ").slice(1).join(" ") : "";
- const optionArguments = this.generateOptionArguments(command, completionsPath);
- const completionsCmd = this.generateCommandCompletionsCommand(command.getArguments(),
completionsPath);
- return ` __${replaceSpecialChars1(path)}() {\n opts=(${[
- ...flags,
- ...childCommandNames
- ].join(" ")})\n ${completionsCmd}\n if [[ \${cur} == -* || \${COMP_CWORD} -eq ${index} ]] ;
then\n return 0\n fi\n ${optionArguments}\n }`;
- }
- getFlags(command) {
- return command.getOptions(false).map((option11)=>option11.flags
- ).flat();
- }
- generateOptionArguments(command, completionsPath) {
- let opts = "";
- const options7 = command.getOptions(false);
- if (options7.length) {
- opts += 'case "${prev}" in';
- for (const option11 of options7){
- const flags = option11.flags.map((flag)=>flag.trim()
- ).join("|");
- const completionsCmd = this.generateOptionCompletionsCommand(option11.args, completionsPath,
{
- standalone: option11.standalone
- });
- opts += `\n ${flags}) ${completionsCmd} ;;`;
- }
- opts += "\n esac";
- }
- return opts;
- }
- generateCommandCompletionsCommand(args, path) {
- if (args.length) {
- return `_${replaceSpecialChars1(this.cmd.getName())}_complete ${args[0].action}${path}`;
- }
- return "";
- }
- generateOptionCompletionsCommand(args, path, opts) {
- if (args.length) {
- return `opts=(); _${replaceSpecialChars1(this.cmd.getName())}_complete ${args[0].action}${path}`;
- }
- if (opts?.standalone) {
- return "opts=()";
- }
- return "";
- }
-}
-function replaceSpecialChars1(str) {
- return str.replace(/[^a-zA-Z0-9]/g, "_");
-}
-class BashCompletionsCommand extends Command1 {
- #cmd;
- constructor(cmd3){
- super();
- this.#cmd = cmd3;
- this.description(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- return `Generate shell completions for bash.\n\nTo enable bash completions for this program add
following line to your ${dim(italic("~/.bashrc"))}:\n\n ${dim(italic(`source <(${baseCmd.getPath()}
completions bash)`))}`;
- }).action(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- console.log(BashCompletionsGenerator.generate(baseCmd));
- });
- }
-}
-class CompleteCommand extends Command1 {
- constructor(cmd4){
- super();
- this.description("Get completions for given action from given command.").arguments("<action:string>
[command...:string]").action(async (_, action, commandNames)=>{
- let parent;
- const completeCommand = commandNames?.reduce((cmd5, name19)=>{
- parent = cmd5;
- const childCmd = cmd5.getCommand(name19, false);
- if (!childCmd) {
- throw new UnknownCompletionCommand(name19, cmd5.getCommands());
- }
- return childCmd;
- }, cmd4 || this.getMainCommand()) ?? (cmd4 || this.getMainCommand());
- const completion = completeCommand.getCompletion(action);
- const result = await completion?.complete(completeCommand, parent) ?? [];
- if (result?.length) {
- Deno.stdout.writeSync(new TextEncoder().encode(result.join("\n")));
- }
- }).reset();
- }
-}
-class FishCompletionsGenerator {
- cmd;
- static generate(cmd) {
- return new FishCompletionsGenerator(cmd).generate();
- }
- constructor(cmd5){
- this.cmd = cmd5;
- }
- generate() {
- const path = this.cmd.getPath();
- const version = this.cmd.getVersion() ? ` v${this.cmd.getVersion()}` : "";
- return `#!/usr/bin/env fish\n# fish completion support for ${path}${version}\n\nfunction
__fish_${replaceSpecialChars2(this.cmd.getName())}_using_command\n set cmds
${getCommandFnNames(this.cmd).join(" ")}\n set words (commandline -opc)\n set cmd "_"\n for word in
$words\n switch $word\n case '-*'\n continue\n case '*'\n set word (string replace
-r -a '\\W' '_' $word)\n set cmd_tmp $cmd"_$word"\n if contains $cmd_tmp $cmds\n set
cmd $cmd_tmp\n end\n end\n end\n if [ "$cmd" = "$argv[1]" ]\n return 0\n end\n return
1\nend\n\n${this.generateCompletions(this.cmd).trim()}`;
- }
- generateCompletions(command) {
- const parent = command.getParent();
- let result = ``;
- if (parent) {
- result += "\n" + this.complete(parent, {
- description: command.getShortDescription(),
- arguments: command.getName()
- });
- }
- const commandArgs = command.getArguments();
- if (commandArgs.length) {
- result += "\n" + this.complete(command, {
- arguments: commandArgs.length ? this.getCompletionCommand(commandArgs[0].action + " " +
getCompletionsPath(command)) : undefined
- });
- }
- for (const option11 of command.getOptions(false)){
- result += "\n" + this.completeOption(command, option11);
- }
- for (const subCommand of command.getCommands(false)){
- result += this.generateCompletions(subCommand);
- }
- return result;
- }
- completeOption(command, option) {
- const shortOption = option.flags.find((flag)=>flag.length === 2
- )?.replace(/^(-)+/, "");
- const longOption = option.flags.find((flag)=>flag.length > 2
- )?.replace(/^(-)+/, "");
- return this.complete(command, {
- description: option.description,
- shortOption: shortOption,
- longOption: longOption,
- required: true,
- standalone: option.standalone,
- arguments: option.args.length ? this.getCompletionCommand(option.args[0].action + " " +
getCompletionsPath(command)) : undefined
- });
- }
- complete(command, options) {
- const cmd6 = [
- "complete"
- ];
- cmd6.push("-c", this.cmd.getName());
- cmd6.push("-n", `'__fish_${replaceSpecialChars2(this.cmd.getName())}_using_command
__${replaceSpecialChars2(command.getPath())}'`);
- options.shortOption && cmd6.push("-s", options.shortOption);
- options.longOption && cmd6.push("-l", options.longOption);
- options.standalone && cmd6.push("-x");
- cmd6.push("-k");
- cmd6.push("-f");
- if (options.arguments) {
- options.required && cmd6.push("-r");
- cmd6.push("-a", options.arguments);
- }
- options.description && cmd6.push("-d", `'${options.description}'`);
- return cmd6.join(" ");
- }
- getCompletionCommand(cmd) {
- return `'(${this.cmd.getName()} completions complete ${cmd.trim()})'`;
- }
-}
-function getCommandFnNames(cmd6, cmds = []) {
- cmds.push(`__${replaceSpecialChars2(cmd6.getPath())}`);
- cmd6.getCommands(false).forEach((command)=>{
- getCommandFnNames(command, cmds);
- });
- return cmds;
-}
-function getCompletionsPath(command) {
- return command.getPath().split(" ").slice(1).join(" ");
-}
-function replaceSpecialChars2(str) {
- return str.replace(/[^a-zA-Z0-9]/g, "_");
-}
-class FishCompletionsCommand extends Command1 {
- #cmd;
- constructor(cmd6){
- super();
- this.#cmd = cmd6;
- this.description(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- return `Generate shell completions for fish.\n\nTo enable fish completions for this program add
following line to your ${dim(italic("~/.config/fish/config.fish"))}:\n\n ${dim(italic(`source
(${baseCmd.getPath()} completions fish | psub)`))}`;
- }).action(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- console.log(FishCompletionsGenerator.generate(baseCmd));
- });
- }
-}
-class ZshCompletionsGenerator {
- cmd;
- actions = new Map();
- static generate(cmd) {
- return new ZshCompletionsGenerator(cmd).generate();
- }
- constructor(cmd7){
- this.cmd = cmd7;
- }
- generate() {
- const path = this.cmd.getPath();
- const name19 = this.cmd.getName();
- const version = this.cmd.getVersion() ? ` v${this.cmd.getVersion()}` : "";
- return `#!/usr/bin/env zsh\n# zsh completion support for ${path}${version}\n\nautoload -U
is-at-least\n\n# shellcheck disable=SC2154\n(( $+functions[__${replaceSpecialChars3(name19)}_complete] ))
||\nfunction __${replaceSpecialChars3(name19)}_complete {\n local name="$1"; shift\n local action="$1";
shift\n integer ret=1\n local -a values\n local expl lines\n _tags "$name"\n while _tags; do\n if
_requested "$name"; then\n # shellcheck disable=SC2034\n lines="$(${name19} completions complete
"\${action}" "\${@}")"\n values=("\${(ps:\\n:)lines}")\n if (( \${#values[@]} )); then\n
while _next_label "$name" expl "$action"; do\n compadd -S '' "\${expl[@]}" "\${values[@]}"\n
done\n fi\n fi\n done\n}\n\n${this.generateCompletions(this.cmd).trim()}\n\n#
_${replaceSpecialChars3(path)} "\${@}"\n\ncompdef _${replaceSpecialChars3(path)} ${path}`;
- }
- generateCompletions(command, path = "") {
- if (!command.hasCommands(false) && !command.hasOptions(false) && !command.hasArguments()) {
- return "";
- }
- path = (path ? path + " " : "") + command.getName();
- return `# shellcheck disable=SC2154\n(( $+functions[_${replaceSpecialChars3(path)}] )) ||\nfunction
_${replaceSpecialChars3(path)}() {` + (!command.getParent() ? `\n local state` : "") +
this.generateCommandCompletions(command, path) + this.generateSubCommandCompletions(command, path) +
this.generateArgumentCompletions(command, path) + this.generateActions(command) + `\n}\n\n` +
command.getCommands(false).filter((subCommand)=>subCommand !== command
- ).map((subCommand)=>this.generateCompletions(subCommand, path)
- ).join("");
- }
- generateCommandCompletions(command, path) {
- const commands5 = command.getCommands(false);
- let completions =
commands5.map((subCommand)=>`'${subCommand.getName()}:${subCommand.getShortDescription()}'`
- ).join("\n ");
- if (completions) {
- completions = `\n local -a commands\n # shellcheck disable=SC2034\n commands=(\n
${completions}\n )\n _describe 'command' commands`;
- }
- if (command.hasArguments()) {
- const completionsPath = path.split(" ").slice(1).join(" ");
- const arg3 = command.getArguments()[0];
- const action = this.addAction(arg3, completionsPath);
- if (action && command.getCompletion(arg3.action)) {
- completions += `\n __${replaceSpecialChars3(this.cmd.getName())}_complete
${action.arg.name} ${action.arg.action} ${action.cmd}`;
- }
- }
- if (completions) {
- completions = `\n\n function _commands() {${completions}\n }`;
- }
- return completions;
- }
- generateSubCommandCompletions(command, path) {
- if (command.hasCommands(false)) {
- const actions = command.getCommands(false).map((command)=>`${command.getName()})
_${replaceSpecialChars3(path + " " + command.getName())} ;;`
- ).join("\n ");
- return `\n\n function _command_args() {\n case "\${words[1]}" in\n ${actions}\n
esac\n }`;
- }
- return "";
- }
- generateArgumentCompletions(command, path) {
- this.actions.clear();
- const options7 = this.generateOptions(command, path);
- let argIndex = 0;
- let argsCommand = "\n\n _arguments -w -s -S -C";
- if (command.hasOptions()) {
- argsCommand += ` \\\n ${options7.join(" \\\n ")}`;
- }
- if (command.hasCommands(false) ||
command.getArguments().filter((arg3)=>command.getCompletion(arg3.action)
- ).length) {
- argsCommand += ` \\\n '${++argIndex}: :_commands'`;
- }
- if (command.hasArguments() || command.hasCommands(false)) {
- const args3 = [];
- for (const arg3 of command.getArguments().slice(1)){
- const completionsPath = path.split(" ").slice(1).join(" ");
- const action = this.addAction(arg3, completionsPath);
- args3.push(`${++argIndex}${arg3.optionalValue ? "::" : ":"}${action.name}`);
- }
- argsCommand += args3.map((arg4)=>`\\\n '${arg4}'`
- ).join("");
- if (command.hasCommands(false)) {
- argsCommand += ` \\\n '*:: :->command_args'`;
- }
- }
- return argsCommand;
- }
- generateOptions(command, path) {
- const options7 = [];
- const cmdArgs = path.split(" ");
- const _baseName = cmdArgs.shift();
- const completionsPath = cmdArgs.join(" ");
- const excludedFlags = command.getOptions(false).map((option11)=>option11.standalone ? option11.flags
: false
- ).flat().filter((flag)=>typeof flag === "string"
- );
- for (const option11 of command.getOptions(false)){
- options7.push(this.generateOption(option11, completionsPath, excludedFlags));
- }
- return options7;
- }
- generateOption(option, completionsPath, excludedOptions) {
- const flags = option.flags;
- let excludedFlags = option.conflicts?.length ? [
- ...excludedOptions,
- ...option.conflicts.map((opt)=>"--" + opt.replace(/^--/, "")
- ),
- ] : excludedOptions;
- excludedFlags = option.collect ? excludedFlags : [
- ...excludedFlags,
- ...flags,
- ];
- let args3 = "";
- for (const arg3 of option.args){
- const action = this.addAction(arg3, completionsPath);
- if (arg3.variadic) {
- args3 += `${arg3.optionalValue ? "::" : ":"}${arg3.name}:->${action.name}`;
- } else {
- args3 += `${arg3.optionalValue ? "::" : ":"}${arg3.name}:->${action.name}`;
- }
- }
- let description = option.description.trim().split("\n").shift();
- description = description.replace(/\[/g, "\\[").replace(/]/g, "\\]").replace(/"/g,
'\\"').replace(/'/g, "'\"'\"'");
- const collect = option.collect ? "*" : "";
- if (option.standalone) {
- return `'(- *)'{${collect}${flags}}'[${description}]${args3}'`;
- } else {
- const excluded2 = excludedFlags.length ? `'(${excludedFlags.join(" ")})'` : "";
- if (collect || flags.length > 1) {
- return `${excluded2}{${collect}${flags}}'[${description}]${args3}'`;
- } else {
- return `${excluded2}${flags}'[${description}]${args3}'`;
- }
- }
- }
- addAction(arg, cmd) {
- const action = `${arg.name}-${arg.action}`;
- if (!this.actions.has(action)) {
- this.actions.set(action, {
- arg: arg,
- label: `${arg.name}: ${arg.action}`,
- name: action,
- cmd
- });
- }
- return this.actions.get(action);
- }
- generateActions(command) {
- let actions = [];
- if (this.actions.size) {
- actions = Array.from(this.actions).map(([name19, action])=>`${name19})
__${replaceSpecialChars3(this.cmd.getName())}_complete ${action.arg.name} ${action.arg.action} ${action.cmd}
;;`
- );
- }
- if (command.hasCommands(false)) {
- actions.unshift(`command_args) _command_args ;;`);
- }
- if (actions.length) {
- return `\n\n case "$state" in\n ${actions.join("\n ")}\n esac`;
- }
- return "";
- }
-}
-function replaceSpecialChars3(str) {
- return str.replace(/[^a-zA-Z0-9]/g, "_");
-}
-class ZshCompletionsCommand extends Command1 {
- #cmd;
- constructor(cmd8){
- super();
- this.#cmd = cmd8;
- this.description(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- return `Generate shell completions for zsh.\n\nTo enable zsh completions for this program add
following line to your ${dim(italic("~/.zshrc"))}:\n\n ${dim(italic(`source <(${baseCmd.getPath()}
completions zsh)`))}`;
- }).action(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- console.log(ZshCompletionsGenerator.generate(baseCmd));
- });
- }
-}
-class CompletionsCommand1 extends Command1 {
- #cmd;
- constructor(cmd9){
- super();
- this.#cmd = cmd9;
- this.description(()=>{
- const baseCmd = this.#cmd || this.getMainCommand();
- return `Generate shell completions.\n\nTo enable shell completions for this program add the
following line to your ${dim(italic("~/.bashrc"))} or similar:\n\n ${dim(italic(`source
<(${baseCmd.getPath()} completions [shell])`))}\n\n For more information run
${dim(italic(`${baseCmd.getPath()} completions [shell] --help`))}\n`;
- }).action(()=>this.showHelp()
- ).command("bash", new BashCompletionsCommand(this.#cmd)).command("fish", new
FishCompletionsCommand(this.#cmd)).command("zsh", new ZshCompletionsCommand(this.#cmd)).command("complete",
new CompleteCommand(this.#cmd).hidden()).reset();
- }
-}
-export { CompletionsCommand1 as CompletionsCommand };
-class CommandType extends StringType1 {
- complete(_cmd, parent) {
- return parent?.getCommands(false).map((cmd10)=>cmd10.getName()
- ) || [];
- }
-}
-class HelpCommand1 extends Command1 {
- constructor(cmd10){
- super();
- this.type("command", new CommandType()).arguments("[command:command]").description("Show this help
or the help of a sub-command.").action((_, name19)=>{
- if (!cmd10) {
- cmd10 = name19 ? this.getGlobalParent()?.getBaseCommand(name19) : this.getGlobalParent();
- }
- if (!cmd10) {
- const cmds = this.getGlobalParent()?.getCommands();
- throw new UnknownCommand(name19 ?? "", cmds ?? [], [
- this.getName(),
- ...this.getAliases(),
- ]);
- }
- cmd10.showHelp();
- Deno.exit(0);
- });
- }
-}
-export { HelpCommand1 as HelpCommand };
-class ActionListType1 extends StringType1 {
- cmd;
- constructor(cmd11){
- super();
- this.cmd = cmd11;
- }
- complete() {
- return this.cmd.getCompletions().map((type3)=>type3.name
- ).filter((value4, index, self)=>self.indexOf(value4) === index
- );
- }
-}
-export { ActionListType1 as ActionListType };
-class ChildCommandType1 extends StringType1 {
- #cmd;
- constructor(cmd12){
- super();
- this.#cmd = cmd12;
- }
- complete(cmd) {
- return (this.#cmd ?? cmd)?.getCommands(false).map((cmd13)=>cmd13.getName()
- ) || [];
- }
-}
-export { ChildCommandType1 as ChildCommandType };
-class EnumType1 extends Type1 {
- allowedValues;
- constructor(values){
- super();
- this.allowedValues = values;
- }
- parse(type) {
- for (const value4 of this.allowedValues){
- if (value4.toString() === type.value) {
- return value4;
- }
- }
- throw new InvalidTypeError(type, this.allowedValues.slice());
- }
- values() {
- return this.allowedValues.slice();
- }
- complete() {
- return this.values();
- }
-}
-export { EnumType1 as EnumType };
-export { ValidationError1 as ValidationError };
-const KeyMap1 = {
- "[P": "f1",
- "[Q": "f2",
- "[R": "f3",
- "[S": "f4",
- "OP": "f1",
- "OQ": "f2",
- "OR": "f3",
- "OS": "f4",
- "[11~": "f1",
- "[12~": "f2",
- "[13~": "f3",
- "[14~": "f4",
- "[[A": "f1",
- "[[B": "f2",
- "[[C": "f3",
- "[[D": "f4",
- "[[E": "f5",
- "[15~": "f5",
- "[17~": "f6",
- "[18~": "f7",
- "[19~": "f8",
- "[20~": "f9",
- "[21~": "f10",
- "[23~": "f11",
- "[24~": "f12",
- "[A": "up",
- "[B": "down",
- "[C": "right",
- "[D": "left",
- "[E": "clear",
- "[F": "end",
- "[H": "home",
- "OA": "up",
- "OB": "down",
- "OC": "right",
- "OD": "left",
- "OE": "clear",
- "OF": "end",
- "OH": "home",
- "[1~": "home",
- "[2~": "insert",
- "[3~": "delete",
- "[4~": "end",
- "[5~": "pageup",
- "[6~": "pagedown",
- "[[5~": "pageup",
- "[[6~": "pagedown",
- "[7~": "home",
- "[8~": "end"
-};
-const KeyMapShift1 = {
- "[a": "up",
- "[b": "down",
- "[c": "right",
- "[d": "left",
- "[e": "clear",
- "[2$": "insert",
- "[3$": "delete",
- "[5$": "pageup",
- "[6$": "pagedown",
- "[7$": "home",
- "[8$": "end",
- "[Z": "tab"
-};
-const KeyMapCtrl1 = {
- "Oa": "up",
- "Ob": "down",
- "Oc": "right",
- "Od": "left",
- "Oe": "clear",
- "[2^": "insert",
- "[3^": "delete",
- "[5^": "pageup",
- "[6^": "pagedown",
- "[7^": "home",
- "[8^": "end"
-};
-const SpecialKeyMap1 = {
- "\r": "return",
- "\n": "enter",
- "\t": "tab",
- "\b": "backspace",
- "\x7f": "backspace",
- "\x1b": "escape",
- " ": "space"
-};
-export { KeyMap1 as KeyMap };
-export { KeyMapShift1 as KeyMapShift };
-export { KeyMapCtrl1 as KeyMapCtrl };
-export { SpecialKeyMap1 as SpecialKeyMap };
-const kEscape = "\x1b";
-function parse1(data) {
- let index = -1;
- const keys = [];
- const input = data instanceof Uint8Array ? new TextDecoder().decode(data) : data;
- const hasNext = ()=>input.length - 1 >= index + 1
- ;
- const next = ()=>input[++index]
- ;
- parseNext();
- return keys;
- function parseNext() {
- let ch = next();
- let s = ch;
- let escaped = false;
- const key = {
- name: undefined,
- sequence: undefined,
- code: undefined,
- ctrl: false,
- meta: false,
- shift: false
- };
- if (ch === kEscape && hasNext()) {
- escaped = true;
- s += ch = next();
- if (ch === kEscape) {
- s += ch = next();
- }
- }
- if (escaped && (ch === "O" || ch === "[")) {
- let code1 = ch;
- let modifier = 0;
- if (ch === "O") {
- s += ch = next();
- if (ch >= "0" && ch <= "9") {
- modifier = (Number(ch) >> 0) - 1;
- s += ch = next();
- }
- code1 += ch;
- } else if (ch === "[") {
- s += ch = next();
- if (ch === "[") {
- code1 += ch;
- s += ch = next();
- }
- const cmdStart = s.length - 1;
- if (ch >= "0" && ch <= "9") {
- s += ch = next();
- if (ch >= "0" && ch <= "9") {
- s += ch = next();
- }
- }
- if (ch === ";") {
- s += ch = next();
- if (ch >= "0" && ch <= "9") {
- s += next();
- }
- }
- const cmd13 = s.slice(cmdStart);
- let match;
- if (match = cmd13.match(/^(\d\d?)(;(\d))?([~^$])$/)) {
- code1 += match[1] + match[4];
- modifier = (Number(match[3]) || 1) - 1;
- } else if (match = cmd13.match(/^((\d;)?(\d))?([A-Za-z])$/)) {
- code1 += match[4];
- modifier = (Number(match[3]) || 1) - 1;
- } else {
- code1 += cmd13;
- }
- }
- key.ctrl = !!(modifier & 4);
- key.meta = !!(modifier & 10);
- key.shift = !!(modifier & 1);
- key.code = code1;
- if (code1 in KeyMap1) {
- key.name = KeyMap1[code1];
- } else if (code1 in KeyMapShift1) {
- key.name = KeyMapShift1[code1];
- key.shift = true;
- } else if (code1 in KeyMapCtrl1) {
- key.name = KeyMapCtrl1[code1];
- key.ctrl = true;
- } else {
- key.name = "undefined";
- }
- } else if (ch in SpecialKeyMap1) {
- key.name = SpecialKeyMap1[ch];
- key.meta = escaped;
- } else if (!escaped && ch <= "\x1a") {
- key.name = String.fromCharCode(ch.charCodeAt(0) + "a".charCodeAt(0) - 1);
- key.ctrl = true;
- } else if (/^[0-9A-Za-z]$/.test(ch)) {
- key.name = ch.toLowerCase();
- key.shift = /^[A-Z]$/.test(ch);
- key.meta = escaped;
- } else if (escaped) {
- key.name = ch.length ? undefined : "escape";
- key.meta = true;
- }
- key.sequence = s;
- if (s.length !== 0 && (key.name !== undefined || escaped)) {
- keys.push(key);
- } else if (charLengthAt(s, 0) === s.length) {
- keys.push(key);
- } else {
- throw new Error("Unrecognized or broken escape sequence");
- }
- if (hasNext()) {
- parseNext();
- }
- }
-}
-function charLengthAt(str, i) {
- const pos = str.codePointAt(i);
- if (typeof pos === "undefined") {
- return 1;
- }
- return pos >= 65536 ? 2 : 1;
-}
-export { parse1 as parse };
-const main = {
- ARROW_UP: "↑",
- ARROW_DOWN: "↓",
- ARROW_LEFT: "←",
- ARROW_RIGHT: "→",
- ARROW_UP_LEFT: "↖",
- ARROW_UP_RIGHT: "↗",
- ARROW_DOWN_RIGHT: "↘",
- ARROW_DOWN_LEFT: "↙",
- RADIO_ON: "◉",
- RADIO_OFF: "◯",
- TICK: "✔",
- CROSS: "✘",
- ELLIPSIS: "…",
- POINTER_SMALL: "›",
- LINE: "─",
- POINTER: "❯",
- INFO: "ℹ",
- TAB_LEFT: "⇤",
- TAB_RIGHT: "⇥",
- ESCAPE: "⎋",
- BACKSPACE: "⌫",
- PAGE_UP: "⇞",
- PAGE_DOWN: "⇟",
- ENTER: "↵",
- SEARCH: "⌕"
-};
-const win = {
- ...main,
- RADIO_ON: "(*)",
- RADIO_OFF: "( )",
- TICK: "√",
- CROSS: "×",
- POINTER_SMALL: "»"
-};
-const Figures1 = Deno.build.os === "windows" ? win : main;
-const keyMap = {
- up: "ARROW_UP",
- down: "ARROW_DOWN",
- pageup: "PAGE_UP",
- pagedown: "PAGE_DOWN",
- tab: "TAB_RIGHT",
- enter: "ENTER",
- return: "ENTER"
-};
-function getFiguresByKeys1(keys) {
- const figures = [];
- for (const key of keys){
- const figure = Figures1[keyMap[key]] ?? key;
- if (!figures.includes(figure)) {
- figures.push(figure);
- }
- }
- return figures;
-}
-export { Figures1 as Figures };
-export { getFiguresByKeys1 as getFiguresByKeys };
-class GenericPrompt1 {
- static injectedValue;
- settings;
- tty = tty1;
- indent;
- cursor = {
- x: 0,
- y: 0
- };
- #value;
- #lastError;
- #isFirstRun = true;
- static inject(value) {
- GenericPrompt1.injectedValue = value;
- }
- constructor(settings){
- this.settings = {
- ...settings,
- keys: {
- submit: [
- "enter",
- "return"
- ],
- ...settings.keys ?? {
- }
- }
- };
- this.indent = this.settings.indent ?? " ";
- }
- async prompt() {
- try {
- return await this.#execute();
- } finally{
- this.tty.cursorShow();
- }
- }
- clear() {
- this.tty.cursorLeft.eraseDown();
- }
- #execute = async ()=>{
- if (typeof GenericPrompt1.injectedValue !== "undefined" && this.#lastError) {
- throw new Error(await this.error());
- }
- await this.render();
- this.#lastError = undefined;
- if (!await this.read()) {
- return this.#execute();
- }
- if (typeof this.#value === "undefined") {
- throw new Error("internal error: failed to read value");
- }
- this.clear();
- const successMessage = this.success(this.#value);
- if (successMessage) {
- console.log(successMessage);
- }
- GenericPrompt1.injectedValue = undefined;
- this.tty.cursorShow();
- return this.#value;
- };
- async render() {
- const result = await Promise.all([
- this.message(),
- this.body?.(),
- this.footer(),
- ]);
- const content = result.filter(Boolean).join("\n");
- const y = content.split("\n").length - this.cursor.y - 1;
- if (!this.#isFirstRun || this.#lastError) {
- this.clear();
- }
- this.#isFirstRun = false;
- if (Deno.build.os === "windows") {
- console.log(content);
- this.tty.cursorUp();
- } else {
- Deno.stdout.writeSync(new TextEncoder().encode(content));
- }
- if (y) {
- this.tty.cursorUp(y);
- }
- this.tty.cursorTo(this.cursor.x);
- }
- async read() {
- if (typeof GenericPrompt1.injectedValue !== "undefined") {
- const value4 = GenericPrompt1.injectedValue;
- await this.#validateValue(value4);
- } else {
- const events = await this.#readKey();
- if (!events.length) {
- return false;
- }
- for (const event of events){
- await this.handleEvent(event);
- }
- }
- return typeof this.#value !== "undefined";
- }
- submit() {
- return this.#validateValue(this.getValue());
- }
- message() {
- return `${this.settings.indent}${this.settings.prefix}` + bold(this.settings.message) +
this.defaults();
- }
- defaults() {
- let defaultMessage = "";
- if (typeof this.settings.default !== "undefined") {
- defaultMessage += dim(` (${this.format(this.settings.default)})`);
- }
- return defaultMessage;
- }
- success(value) {
- return `${this.settings.indent}${this.settings.prefix}` + bold(this.settings.message) +
this.defaults() + " " + this.settings.pointer + " " + green(this.format(value));
- }
- footer() {
- return this.error() ?? this.hint();
- }
- error() {
- return this.#lastError ? this.settings.indent + red(bold(`${Figures1.CROSS} `) + this.#lastError) :
undefined;
- }
- hint() {
- return this.settings.hint ? this.settings.indent + italic(blue(dim(`${Figures1.POINTER} `) +
this.settings.hint)) : undefined;
- }
- async handleEvent(event) {
- switch(true){
- case event.name === "c" && event.ctrl:
- this.clear();
- this.tty.cursorShow();
- Deno.exit(130);
- return;
- case this.isKey(this.settings.keys, "submit", event):
- await this.submit();
- break;
- }
- }
- #readKey = async ()=>{
- const data = await this.#readChar();
- return data.length ? parse1(data) : [];
- };
- #readChar = async ()=>{
- const buffer = new Uint8Array(8);
- const isTty = Deno.isatty(Deno.stdin.rid);
- if (isTty) {
- Deno.setRaw(Deno.stdin.rid, true, {
- cbreak: this.settings.cbreak === true
- });
- }
- const nread = await Deno.stdin.read(buffer);
- if (isTty) {
- Deno.setRaw(Deno.stdin.rid, false);
- }
- if (nread === null) {
- return buffer;
- }
- return buffer.subarray(0, nread);
- };
- #transformValue = (value4)=>{
- return this.settings.transform ? this.settings.transform(value4) : this.transform(value4);
- };
- #validateValue = async (value4)=>{
- if (!value4 && typeof this.settings.default !== "undefined") {
- this.#value = this.settings.default;
- return;
- }
- this.#value = undefined;
- this.#lastError = undefined;
- const validation = await (this.settings.validate ? this.settings.validate(value4) :
this.validate(value4));
- if (validation === false) {
- this.#lastError = `Invalid answer.`;
- } else if (typeof validation === "string") {
- this.#lastError = validation;
- } else {
- this.#value = this.#transformValue(value4);
- }
- };
- isKey(keys, name, event) {
- const keyNames = keys?.[name];
- return typeof keyNames !== "undefined" && (typeof event.name !== "undefined" &&
keyNames.indexOf(event.name) !== -1 || typeof event.sequence !== "undefined" &&
keyNames.indexOf(event.sequence) !== -1);
- }
-}
-export { GenericPrompt1 as GenericPrompt };
-class GenericInput1 extends GenericPrompt1 {
- inputValue = "";
- inputIndex = 0;
- constructor(settings1){
- super({
- ...settings1,
- keys: {
- moveCursorLeft: [
- "left"
- ],
- moveCursorRight: [
- "right"
- ],
- deleteCharLeft: [
- "backspace"
- ],
- deleteCharRight: [
- "delete"
- ],
- ...settings1.keys ?? {
- }
- }
- });
- }
- getCurrentInputValue() {
- return this.inputValue;
- }
- message() {
- const message4 = super.message() + " " + this.settings.pointer + " ";
- this.cursor.x = stripColor(message4).length + this.inputIndex + 1;
- return message4 + this.input();
- }
- input() {
- return underline(this.inputValue);
- }
- highlight(value, color1 = dim, color2 = blue) {
- value = value.toString();
- const inputLowerCase = this.getCurrentInputValue().toLowerCase();
- const valueLowerCase = value.toLowerCase();
- const index = valueLowerCase.indexOf(inputLowerCase);
- const matched = value.slice(index, index + inputLowerCase.length);
- return index >= 0 ? color1(value.slice(0, index)) + color2(matched) + color1(value.slice(index +
inputLowerCase.length)) : value;
- }
- async handleEvent(event) {
- switch(true){
- case event.name === "c" && event.ctrl:
- this.clear();
- this.tty.cursorShow();
- Deno.exit(130);
- return;
- case this.isKey(this.settings.keys, "moveCursorLeft", event):
- this.moveCursorLeft();
- break;
- case this.isKey(this.settings.keys, "moveCursorRight", event):
- this.moveCursorRight();
- break;
- case this.isKey(this.settings.keys, "deleteCharRight", event):
- this.deleteCharRight();
- break;
- case this.isKey(this.settings.keys, "deleteCharLeft", event):
- this.deleteChar();
- break;
- case this.isKey(this.settings.keys, "submit", event):
- await this.submit();
- break;
- default:
- if (event.sequence && !event.meta && !event.ctrl) {
- this.addChar(event.sequence);
- }
- }
- }
- addChar(__char) {
- this.inputValue = this.inputValue.slice(0, this.inputIndex) + __char +
this.inputValue.slice(this.inputIndex);
- this.inputIndex++;
- }
- moveCursorLeft() {
- if (this.inputIndex > 0) {
- this.inputIndex--;
- }
- }
- moveCursorRight() {
- if (this.inputIndex < this.inputValue.length) {
- this.inputIndex++;
- }
- }
- deleteChar() {
- if (this.inputIndex > 0) {
- this.inputIndex--;
- this.deleteCharRight();
- }
- }
- deleteCharRight() {
- if (this.inputIndex < this.inputValue.length) {
- this.inputValue = this.inputValue.slice(0, this.inputIndex) +
this.inputValue.slice(this.inputIndex + 1);
- }
- }
-}
-export { GenericInput1 as GenericInput };
-class GenericList1 extends GenericInput1 {
- options = this.settings.options;
- listIndex = this.getListIndex();
- listOffset = this.getPageOffset(this.listIndex);
- static separator(label = "------------") {
- return {
- value: label,
- disabled: true
- };
- }
- static mapOption(option) {
- return {
- value: option.value,
- name: typeof option.name === "undefined" ? option.value : option.name,
- disabled: !!option.disabled
- };
- }
- constructor(settings2){
- super({
- ...settings2,
- keys: {
- previous: settings2.search ? [
- "up"
- ] : [
- "up",
- "u",
- "8"
- ],
- next: settings2.search ? [
- "down"
- ] : [
- "down",
- "d",
- "2"
- ],
- previousPage: [
- "pageup"
- ],
- nextPage: [
- "pagedown"
- ],
- ...settings2.keys ?? {
- }
- }
- });
- }
- match() {
- const input = this.getCurrentInputValue().toLowerCase();
- if (!input.length) {
- this.options = this.settings.options.slice();
- } else {
- this.options = this.settings.options.filter((option11)=>match(option11.name) || option11.name
!== option11.value && match(option11.value)
- ).sort((a, b)=>distance(a.name, input) - distance(b.name, input)
- );
- }
- this.listIndex = Math.max(0, Math.min(this.options.length - 1, this.listIndex));
- this.listOffset = Math.max(0, Math.min(this.options.length - this.getListHeight(), this.listOffset));
- function match(value4) {
- return stripColor(value4).toLowerCase().includes(input);
- }
- }
- message() {
- let message4 = `${this.settings.indent}${this.settings.prefix}` + bold(this.settings.message) +
this.defaults();
- if (this.settings.search) {
- message4 += " " + this.settings.searchLabel + " ";
- }
- this.cursor.x = stripColor(message4).length + this.inputIndex + 1;
- return message4 + this.input();
- }
- body() {
- return this.getList() + this.getInfo();
- }
- getInfo() {
- if (!this.settings.info) {
- return "";
- }
- const selected = this.listIndex + 1;
- const actions = [
- [
- "Next",
- getFiguresByKeys1(this.settings.keys?.next ?? [])
- ],
- [
- "Previous",
- getFiguresByKeys1(this.settings.keys?.previous ?? [])
- ],
- [
- "Next Page",
- getFiguresByKeys1(this.settings.keys?.nextPage ?? [])
- ],
- [
- "Previous Page",
- getFiguresByKeys1(this.settings.keys?.previousPage ?? []),
- ],
- [
- "Submit",
- getFiguresByKeys1(this.settings.keys?.submit ?? [])
- ],
- ];
- return "\n" + this.settings.indent + blue(Figures1.INFO) + bold(` ${selected}/${this.options.length}
`) + actions.map((cur)=>`${cur[0]}: ${bold(cur[1].join(", "))}`
- ).join(", ");
- }
- getList() {
- const list = [];
- const height = this.getListHeight();
- for(let i = this.listOffset; i < this.listOffset + height; i++){
- list.push(this.getListItem(this.options[i], this.listIndex === i));
- }
- if (!list.length) {
- list.push(this.settings.indent + dim(" No matches..."));
- }
- return list.join("\n");
- }
- getListHeight() {
- return Math.min(this.options.length, this.settings.maxRows || this.options.length);
- }
- getListIndex(value) {
- return typeof value === "undefined" ? this.options.findIndex((item)=>!item.disabled
- ) || 0 : this.options.findIndex((item)=>item.value === value
- ) || 0;
- }
- getPageOffset(index) {
- if (index === 0) {
- return 0;
- }
- const height = this.getListHeight();
- return Math.floor(index / height) * height;
- }
- getOptionByValue(value) {
- return this.options.find((option11)=>option11.value === value
- );
- }
- read() {
- if (!this.settings.search) {
- this.tty.cursorHide();
- }
- return super.read();
- }
- async handleEvent(event) {
- switch(true){
- case this.isKey(this.settings.keys, "previous", event):
- this.selectPrevious();
- break;
- case this.isKey(this.settings.keys, "next", event):
- this.selectNext();
- break;
- case this.isKey(this.settings.keys, "nextPage", event):
- this.selectNextPage();
- break;
- case this.isKey(this.settings.keys, "previousPage", event):
- this.selectPreviousPage();
- break;
- default:
- await super.handleEvent(event);
- }
- }
- moveCursorLeft() {
- if (this.settings.search) {
- super.moveCursorLeft();
- }
- }
- moveCursorRight() {
- if (this.settings.search) {
- super.moveCursorRight();
- }
- }
- deleteChar() {
- if (this.settings.search) {
- super.deleteChar();
- }
- }
- deleteCharRight() {
- if (this.settings.search) {
- super.deleteCharRight();
- this.match();
- }
- }
- addChar(__char) {
- if (this.settings.search) {
- super.addChar(__char);
- this.match();
- }
- }
- selectPrevious() {
- if (this.options.length < 2) {
- return;
- }
- if (this.listIndex > 0) {
- this.listIndex--;
- if (this.listIndex < this.listOffset) {
- this.listOffset--;
- }
- if (this.options[this.listIndex].disabled) {
- this.selectPrevious();
- }
- } else {
- this.listIndex = this.options.length - 1;
- this.listOffset = this.options.length - this.getListHeight();
- if (this.options[this.listIndex].disabled) {
- this.selectPrevious();
- }
- }
- }
- selectNext() {
- if (this.options.length < 2) {
- return;
- }
- if (this.listIndex < this.options.length - 1) {
- this.listIndex++;
- if (this.listIndex >= this.listOffset + this.getListHeight()) {
- this.listOffset++;
- }
- if (this.options[this.listIndex].disabled) {
- this.selectNext();
- }
- } else {
- this.listIndex = this.listOffset = 0;
- if (this.options[this.listIndex].disabled) {
- this.selectNext();
- }
- }
- }
- selectPreviousPage() {
- if (this.options?.length) {
- const height = this.getListHeight();
- if (this.listOffset >= height) {
- this.listIndex -= height;
- this.listOffset -= height;
- } else if (this.listOffset > 0) {
- this.listIndex -= this.listOffset;
- this.listOffset = 0;
- }
- }
- }
- selectNextPage() {
- if (this.options?.length) {
- const height = this.getListHeight();
- if (this.listOffset + height + height < this.options.length) {
- this.listIndex += height;
- this.listOffset += height;
- } else if (this.listOffset + height < this.options.length) {
- const offset = this.options.length - height;
- this.listIndex += offset - this.listOffset;
- this.listOffset = offset;
- }
- }
- }
-}
-export { GenericList1 as GenericList };
-class Checkbox1 extends GenericList1 {
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- static prompt(options) {
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- listPointer: blue(Figures1.POINTER),
- maxRows: 10,
- searchLabel: blue(Figures1.SEARCH),
- minOptions: 0,
- maxOptions: Infinity,
- check: green(Figures1.TICK),
- uncheck: red(Figures1.CROSS),
- ...options,
- keys: {
- check: [
- "space"
- ],
- ...options.keys ?? {
- }
- },
- options: Checkbox1.mapOptions(options)
- }).prompt();
- }
- static separator(label) {
- return {
- ...super.separator(label),
- icon: false
+const kEscape = "\x1b";
+function parse(data) {
+ let index = -1;
+ const keys = [];
+ const input = data instanceof Uint8Array ? new TextDecoder().decode(data) : data;
+ const hasNext = ()=>input.length - 1 >= index + 1
+ ;
+ const next = ()=>input[++index]
+ ;
+ parseNext();
+ return keys;
+ function parseNext() {
+ let ch = next();
+ let s = ch;
+ let escaped = false;
+ const key = {
+ name: undefined,
+ sequence: undefined,
+ code: undefined,
+ ctrl: false,
+ meta: false,
+ shift: false
};
- }
- static mapOptions(options) {
- return options.options.map((item)=>typeof item === "string" ? {
- value: item
- } : item
- ).map((item)=>({
- ...this.mapOption(item),
- checked: typeof item.checked === "undefined" && options.default &&
options.default.indexOf(item.value) !== -1 ? true : !!item.checked,
- icon: typeof item.icon === "undefined" ? true : item.icon
- })
- );
- }
- getListItem(item, isSelected) {
- let line = this.settings.indent;
- line += isSelected ? this.settings.listPointer + " " : " ";
- if (item.icon) {
- let check = item.checked ? this.settings.check + " " : this.settings.uncheck + " ";
- if (item.disabled) {
- check = dim(check);
- }
- line += check;
- } else {
- line += " ";
- }
- line += `${isSelected ? this.highlight(item.name, (val)=>val
- ) : this.highlight(item.name)}`;
- return line;
- }
- getValue() {
- return this.settings.options.filter((item)=>item.checked
- ).map((item)=>item.value
- );
- }
- async handleEvent(event) {
- switch(true){
- case this.isKey(this.settings.keys, "check", event):
- this.checkValue();
- break;
- default:
- await super.handleEvent(event);
- }
- }
- checkValue() {
- const item = this.options[this.listIndex];
- item.checked = !item.checked;
- }
- validate(value) {
- const isValidValue = Array.isArray(value) && value.every((val)=>typeof val === "string" &&
val.length > 0 && this.settings.options.findIndex((option11)=>option11.value === val
- ) !== -1
- );
- if (!isValidValue) {
- return false;
- }
- if (value.length < this.settings.minOptions) {
- return `The minimum number of options is ${this.settings.minOptions} but got ${value.length}.`;
- }
- if (value.length > this.settings.maxOptions) {
- return `The maximum number of options is ${this.settings.maxOptions} but got ${value.length}.`;
- }
- return true;
- }
- transform(value) {
- return value.map((val)=>val.trim()
- );
- }
- format(value) {
- return value.map((val)=>this.getOptionByValue(val)?.name ?? val
- ).join(", ");
- }
-}
-export { Checkbox1 as Checkbox };
-class GenericSuggestions extends GenericInput1 {
- suggestionsIndex = -1;
- suggestionsOffset = 0;
- suggestions = [];
- constructor(settings3){
- super({
- ...settings3,
- keys: {
- complete: [
- "tab"
- ],
- next: [
- "up"
- ],
- previous: [
- "down"
- ],
- nextPage: [
- "pageup"
- ],
- previousPage: [
- "pagedown"
- ],
- ...settings3.keys ?? {
- }
- }
- });
- const suggestions1 = this.loadSuggestions();
- if (suggestions1.length || this.settings.suggestions) {
- this.settings.suggestions = [
- ...suggestions1,
- ...this.settings.suggestions ?? [],
- ].filter(uniqueSuggestions);
- }
- }
- get localStorage() {
- if (this.settings.id && "localStorage" in window) {
- try {
- return window.localStorage;
- } catch (_) {
- }
- }
- return null;
- }
- loadSuggestions() {
- if (this.settings.id) {
- const json = this.localStorage?.getItem(this.settings.id);
- const suggestions1 = json ? JSON.parse(json) : [];
- if (!Array.isArray(suggestions1)) {
- return [];
- }
- return suggestions1;
- }
- return [];
- }
- saveSuggestions(...suggestions) {
- if (this.settings.id) {
- this.localStorage?.setItem(this.settings.id, JSON.stringify([
- ...suggestions,
- ...this.loadSuggestions(),
- ].filter(uniqueSuggestions)));
- }
- }
- render() {
- this.match();
- return super.render();
- }
- match() {
- if (!this.settings.suggestions?.length) {
- return;
- }
- const input = this.getCurrentInputValue().toLowerCase();
- if (!input.length) {
- this.suggestions = this.settings.suggestions.slice();
- } else {
- this.suggestions =
this.settings.suggestions.filter((value4)=>stripColor(value4.toString()).toLowerCase().startsWith(input)
- ).sort((a, b)=>distance((a || a).toString(), input) - distance((b || b).toString(), input)
- );
- }
- this.suggestionsIndex = Math.max(this.getCurrentInputValue().trim().length === 0 ? -1 : 0,
Math.min(this.suggestions.length - 1, this.suggestionsIndex));
- this.suggestionsOffset = Math.max(0, Math.min(this.suggestions.length - this.getListHeight(),
this.suggestionsOffset));
- }
- input() {
- return super.input() + dim(this.getSuggestion());
- }
- getSuggestion() {
- return
this.suggestions[this.suggestionsIndex]?.toString().substr(this.getCurrentInputValue().length) ?? "";
- }
- body() {
- return this.getList() + this.getInfo();
- }
- getInfo() {
- if (!this.settings.info) {
- return "";
- }
- const selected = this.suggestionsIndex + 1;
- const matched = this.suggestions.length;
- const actions = [];
- if (this.settings.suggestions?.length) {
- if (this.settings.list) {
- actions.push([
- "Next",
- getFiguresByKeys1(this.settings.keys?.next ?? [])
- ], [
- "Previous",
- getFiguresByKeys1(this.settings.keys?.previous ?? [])
- ], [
- "Next Page",
- getFiguresByKeys1(this.settings.keys?.nextPage ?? [])
- ], [
- "Previous Page",
- getFiguresByKeys1(this.settings.keys?.previousPage ?? []),
- ]);
- } else {
- actions.push([
- "Next",
- getFiguresByKeys1(this.settings.keys?.next ?? [])
- ], [
- "Previous",
- getFiguresByKeys1(this.settings.keys?.previous ?? [])
- ]);
- }
- actions.push([
- "Complete",
- getFiguresByKeys1(this.settings.keys?.complete ?? [])
- ]);
- }
- actions.push([
- "Submit",
- getFiguresByKeys1(this.settings.keys?.submit ?? [])
- ]);
- let info = this.settings.indent;
- if (this.settings.suggestions?.length) {
- info += blue(Figures1.INFO) + bold(` ${selected}/${matched} `);
- }
- info += actions.map((cur)=>`${cur[0]}: ${bold(cur[1].join(" "))}`
- ).join(", ");
- return info;
- }
- getList() {
- if (!this.settings.suggestions?.length || !this.settings.list) {
- return "";
- }
- const list = [];
- const height = this.getListHeight();
- for(let i = this.suggestionsOffset; i < this.suggestionsOffset + height; i++){
- list.push(this.getListItem(this.suggestions[i], this.suggestionsIndex === i));
- }
- if (list.length && this.settings.info) {
- list.push("");
- }
- return list.join("\n");
- }
- getListItem(value, isSelected) {
- let line = this.settings.indent ?? "";
- line += isSelected ? `${this.settings.listPointer} ` : " ";
- if (isSelected) {
- line += underline(this.highlight(value));
- } else {
- line += this.highlight(value);
- }
- return line;
- }
- getListHeight(suggestions = this.suggestions) {
- return Math.min(suggestions.length, this.settings.maxRows || suggestions.length);
- }
- async handleEvent(event) {
- switch(true){
- case this.isKey(this.settings.keys, "next", event):
- if (this.settings.list) {
- this.selectPreviousSuggestion();
- } else {
- this.selectNextSuggestion();
- }
- break;
- case this.isKey(this.settings.keys, "previous", event):
- if (this.settings.list) {
- this.selectNextSuggestion();
- } else {
- this.selectPreviousSuggestion();
- }
- break;
- case this.isKey(this.settings.keys, "nextPage", event):
- if (this.settings.list) {
- this.selectPreviousSuggestionsPage();
- } else {
- this.selectNextSuggestionsPage();
- }
- break;
- case this.isKey(this.settings.keys, "previousPage", event):
- if (this.settings.list) {
- this.selectNextSuggestionsPage();
- } else {
- this.selectPreviousSuggestionsPage();
- }
- break;
- case this.isKey(this.settings.keys, "complete", event):
- this.complete();
- break;
- case this.isKey(this.settings.keys, "moveCursorRight", event):
- if (this.inputIndex < this.inputValue.length) {
- this.moveCursorRight();
- } else {
- this.complete();
- }
- break;
- default:
- await super.handleEvent(event);
- }
- }
- deleteCharRight() {
- if (this.inputIndex < this.inputValue.length) {
- super.deleteCharRight();
- if (!this.getCurrentInputValue().length) {
- this.suggestionsIndex = -1;
- this.suggestionsOffset = 0;
- }
- }
- }
- complete() {
- if (this.suggestions.length && this.suggestions[this.suggestionsIndex]) {
- this.inputValue = this.suggestions[this.suggestionsIndex].toString();
- this.inputIndex = this.inputValue.length;
- this.suggestionsIndex = 0;
- this.suggestionsOffset = 0;
- }
- }
- selectPreviousSuggestion() {
- if (this.suggestions?.length) {
- if (this.suggestionsIndex > -1) {
- this.suggestionsIndex--;
- if (this.suggestionsIndex < this.suggestionsOffset) {
- this.suggestionsOffset--;
- }
- }
- }
- }
- selectNextSuggestion() {
- if (this.suggestions?.length) {
- if (this.suggestionsIndex < this.suggestions.length - 1) {
- this.suggestionsIndex++;
- if (this.suggestionsIndex >= this.suggestionsOffset + this.getListHeight()) {
- this.suggestionsOffset++;
- }
- }
- }
- }
- selectPreviousSuggestionsPage() {
- if (this.suggestions?.length) {
- const height = this.getListHeight();
- if (this.suggestionsOffset >= height) {
- this.suggestionsIndex -= height;
- this.suggestionsOffset -= height;
- } else if (this.suggestionsOffset > 0) {
- this.suggestionsIndex -= this.suggestionsOffset;
- this.suggestionsOffset = 0;
- }
- }
- }
- selectNextSuggestionsPage() {
- if (this.suggestions?.length) {
- const height = this.getListHeight();
- if (this.suggestionsOffset + height + height < this.suggestions.length) {
- this.suggestionsIndex += height;
- this.suggestionsOffset += height;
- } else if (this.suggestionsOffset + height < this.suggestions.length) {
- const offset = this.suggestions.length - height;
- this.suggestionsIndex += offset - this.suggestionsOffset;
- this.suggestionsOffset = offset;
+ if (ch === kEscape && hasNext()) {
+ escaped = true;
+ s += ch = next();
+ if (ch === kEscape) {
+ s += ch = next();
}
}
- }
-}
-function uniqueSuggestions(value4, index, self) {
- return typeof value4 !== "undefined" && value4 !== "" && self.indexOf(value4) === index;
-}
-class Confirm1 extends GenericSuggestions {
- static prompt(options) {
- if (typeof options === "string") {
- options = {
- message: options
- };
- }
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- listPointer: blue(Figures1.POINTER),
- maxRows: 8,
- active: "Yes",
- inactive: "No",
- ...options,
- suggestions: [
- options.active ?? "Yes",
- options.inactive ?? "No",
- ],
- list: false,
- info: false
- }).prompt();
- }
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- defaults() {
- let defaultMessage = "";
- if (this.settings.default === true) {
- defaultMessage += this.settings.active[0].toUpperCase() + "/" +
this.settings.inactive[0].toLowerCase();
- } else if (this.settings.default === false) {
- defaultMessage += this.settings.active[0].toLowerCase() + "/" +
this.settings.inactive[0].toUpperCase();
- } else {
- defaultMessage += this.settings.active[0].toLowerCase() + "/" +
this.settings.inactive[0].toLowerCase();
- }
- return defaultMessage ? dim(` (${defaultMessage})`) : "";
- }
- success(value) {
- this.saveSuggestions(this.format(value));
- return super.success(value);
- }
- getValue() {
- return this.inputValue;
- }
- validate(value) {
- return typeof value === "string" && [
- this.settings.active[0].toLowerCase(),
- this.settings.active.toLowerCase(),
- this.settings.inactive[0].toLowerCase(),
- this.settings.inactive.toLowerCase(),
- ].indexOf(value.toLowerCase()) !== -1;
- }
- transform(value) {
- switch(value.toLowerCase()){
- case this.settings.active[0].toLowerCase():
- case this.settings.active.toLowerCase():
- return true;
- case this.settings.inactive[0].toLowerCase():
- case this.settings.inactive.toLowerCase():
- return false;
- }
- return;
- }
- format(value) {
- return value ? this.settings.active : this.settings.inactive;
- }
-}
-export { Confirm1 as Confirm };
-class Input1 extends GenericSuggestions {
- static prompt(options) {
- if (typeof options === "string") {
- options = {
- message: options
- };
- }
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- listPointer: blue(Figures1.POINTER),
- maxRows: 8,
- minLength: 0,
- maxLength: Infinity,
- ...options
- }).prompt();
- }
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- success(value) {
- this.saveSuggestions(value);
- return super.success(value);
- }
- getValue() {
- return this.inputValue;
- }
- validate(value) {
- if (typeof value !== "string") {
- return false;
- }
- if (value.length < this.settings.minLength) {
- return `Value must be longer then ${this.settings.minLength} but has a length of
${value.length}.`;
- }
- if (value.length > this.settings.maxLength) {
- return `Value can't be longer then ${this.settings.maxLength} but has a length of
${value.length}.`;
- }
- return true;
- }
- transform(value) {
- return value.trim();
- }
- format(value) {
- return value;
- }
-}
-export { Input1 as Input };
-class List1 extends GenericSuggestions {
- static prompt(options) {
- if (typeof options === "string") {
- options = {
- message: options
- };
- }
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- listPointer: blue(Figures1.POINTER),
- maxRows: 8,
- separator: ",",
- minLength: 0,
- maxLength: Infinity,
- minTags: 0,
- maxTags: Infinity,
- ...options
- }).prompt();
- }
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- input() {
- const oldInput = this.inputValue;
- const tags = this.getTags(oldInput);
- const separator = this.settings.separator + " ";
- this.inputValue = tags.join(separator);
- const diff = oldInput.length - this.inputValue.length;
- this.inputIndex -= diff;
- this.cursor.x -= diff;
- return tags.map((val)=>underline(val)
- ).join(separator) + dim(this.getSuggestion());
- }
- getTags(value = this.inputValue) {
- return value.trim().split(this.regexp());
- }
- regexp() {
- return new RegExp(this.settings.separator === " " ? ` +` : ` *${this.settings.separator} *`);
- }
- success(value) {
- this.saveSuggestions(...value);
- return super.success(value);
- }
- getValue() {
- return this.inputValue.replace(/,+\s*$/, "");
- }
- getCurrentInputValue() {
- return this.getTags().pop() ?? "";
- }
- addChar(__char) {
- switch(__char){
- case this.settings.separator:
- if (this.inputValue.length && this.inputValue.trim().slice(-1) !== this.settings.separator) {
- super.addChar(__char);
+ if (escaped && (ch === "O" || ch === "[")) {
+ let code1 = ch;
+ let modifier = 0;
+ if (ch === "O") {
+ s += ch = next();
+ if (ch >= "0" && ch <= "9") {
+ modifier = (Number(ch) >> 0) - 1;
+ s += ch = next();
}
- this.suggestionsIndex = -1;
- this.suggestionsOffset = 0;
- break;
- default:
- super.addChar(__char);
- }
- }
- deleteChar() {
- if (this.inputValue[this.inputIndex - 1] === " ") {
- super.deleteChar();
- }
- super.deleteChar();
- }
- complete() {
- if (this.suggestions.length && this.suggestions[this.suggestionsIndex]) {
- const tags = this.getTags().slice(0, -1);
- tags.push(this.suggestions[this.suggestionsIndex].toString());
- this.inputValue = tags.join(this.settings.separator + " ");
- this.inputIndex = this.inputValue.length;
- this.suggestionsIndex = 0;
- this.suggestionsOffset = 0;
- }
- }
- validate(value) {
- if (typeof value !== "string") {
- return false;
- }
- const values1 = this.transform(value);
- for (const val of values1){
- if (val.length < this.settings.minLength) {
- return `Value must be longer then ${this.settings.minLength} but has a length of
${val.length}.`;
- }
- if (val.length > this.settings.maxLength) {
- return `Value can't be longer then ${this.settings.maxLength} but has a length of
${val.length}.`;
- }
- }
- if (values1.length < this.settings.minTags) {
- return `The minimum number of tags is ${this.settings.minTags} but got ${values1.length}.`;
- }
- if (values1.length > this.settings.maxTags) {
- return `The maximum number of tags is ${this.settings.maxTags} but got ${values1.length}.`;
- }
- return true;
- }
- transform(value) {
- return this.getTags(value).filter((val)=>val !== ""
- );
- }
- format(value) {
- return value.join(`, `);
- }
-}
-export { List1 as List };
-function parseNumber(value4) {
- return Number(value4);
-}
-class Number1 extends GenericSuggestions {
- static prompt(options) {
- if (typeof options === "string") {
- options = {
- message: options
- };
- }
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- listPointer: blue(Figures1.POINTER),
- maxRows: 8,
- min: -Infinity,
- max: Infinity,
- float: false,
- round: 2,
- ...options,
- keys: {
- increaseValue: [
- "up",
- "u",
- "+"
- ],
- decreaseValue: [
- "down",
- "d",
- "-"
- ],
- ...options.keys ?? {
+ code1 += ch;
+ } else if (ch === "[") {
+ s += ch = next();
+ if (ch === "[") {
+ code1 += ch;
+ s += ch = next();
}
- }
- }).prompt();
- }
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- success(value) {
- this.saveSuggestions(value);
- return super.success(value);
- }
- async handleEvent(event) {
- switch(true){
- case this.settings.suggestions && this.isKey(this.settings.keys, "next", event):
- if (this.settings.list) {
- this.selectPreviousSuggestion();
- } else {
- this.selectNextSuggestion();
+ const cmdStart = s.length - 1;
+ if (ch >= "0" && ch <= "9") {
+ s += ch = next();
+ if (ch >= "0" && ch <= "9") {
+ s += ch = next();
+ }
}
- break;
- case this.settings.suggestions && this.isKey(this.settings.keys, "previous", event):
- if (this.settings.list) {
- this.selectNextSuggestion();
- } else {
- this.selectPreviousSuggestion();
+ if (ch === ";") {
+ s += ch = next();
+ if (ch >= "0" && ch <= "9") {
+ s += next();
+ }
}
- break;
- case this.isKey(this.settings.keys, "increaseValue", event):
- this.increaseValue();
- break;
- case this.isKey(this.settings.keys, "decreaseValue", event):
- this.decreaseValue();
- break;
- default:
- await super.handleEvent(event);
- }
- }
- increaseValue() {
- this.manipulateIndex(false);
- }
- decreaseValue() {
- this.manipulateIndex(true);
- }
- manipulateIndex(decrease) {
- if (this.inputValue[this.inputIndex] === "-") {
- this.inputIndex++;
- }
- if (this.inputValue.length && this.inputIndex > this.inputValue.length - 1) {
- this.inputIndex--;
- }
- const decimalIndex = this.inputValue.indexOf(".");
- const [abs, dec] = this.inputValue.split(".");
- if (dec && this.inputIndex === decimalIndex) {
- this.inputIndex--;
- }
- const inDecimal = decimalIndex !== -1 && this.inputIndex > decimalIndex;
- let value4 = (inDecimal ? dec : abs) || "0";
- const oldLength = this.inputValue.length;
- const index = inDecimal ? this.inputIndex - decimalIndex - 1 : this.inputIndex;
- const increaseValue = Math.pow(10, value4.length - index - 1);
- value4 = (parseInt(value4) + (decrease ? -increaseValue : increaseValue)).toString();
- this.inputValue = !dec ? value4 : this.inputIndex > decimalIndex ? abs + "." + value4 : value4 + "."
+ dec;
- if (this.inputValue.length > oldLength) {
- this.inputIndex++;
- } else if (this.inputValue.length < oldLength && this.inputValue[this.inputIndex - 1] !== "-") {
- this.inputIndex--;
- }
- this.inputIndex = Math.max(0, Math.min(this.inputIndex, this.inputValue.length - 1));
- }
- addChar(__char) {
- if (isNumeric(__char)) {
- super.addChar(__char);
- } else if (this.settings.float && __char === "." && this.inputValue.indexOf(".") === -1 &&
(this.inputValue[0] === "-" ? this.inputIndex > 1 : this.inputIndex > 0)) {
- super.addChar(__char);
- }
- }
- validate(value) {
- if (!isNumeric(value)) {
- return false;
- }
- const val = parseFloat(value);
- if (val > this.settings.max) {
- return `Value must be lower or equal than ${this.settings.max}`;
- }
- if (val < this.settings.min) {
- return `Value must be greater or equal than ${this.settings.min}`;
- }
- return true;
- }
- transform(value) {
- const val = parseFloat(value);
- if (this.settings.float) {
- return parseFloat(val.toFixed(this.settings.round));
- }
- return val;
- }
- format(value) {
- return value.toString();
- }
- getValue() {
- return this.inputValue;
- }
-}
-function isNumeric(value4) {
- return typeof value4 === "number" || !!value4 && !isNaN(parseNumber(value4));
-}
-export { Number1 as Number };
-class Secret1 extends GenericInput1 {
- static prompt(options) {
- if (typeof options === "string") {
- options = {
- message: options
- };
- }
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- label: "Password",
- hidden: false,
- minLength: 0,
- maxLength: Infinity,
- ...options
- }).prompt();
- }
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- input() {
- return underline(this.settings.hidden ? "" : "*".repeat(this.inputValue.length));
- }
- read() {
- if (this.settings.hidden) {
- this.tty.cursorHide();
- }
- return super.read();
- }
- validate(value) {
- if (typeof value !== "string") {
- return false;
- }
- if (value.length < this.settings.minLength) {
- return `${this.settings.label} must be longer then ${this.settings.minLength} but has a length
of ${value.length}.`;
- }
- if (value.length > this.settings.maxLength) {
- return `${this.settings.label} can't be longer then ${this.settings.maxLength} but has a length
of ${value.length}.`;
- }
- return true;
- }
- transform(value) {
- return value;
- }
- format(value) {
- return this.settings.hidden ? "*".repeat(8) : "*".repeat(value.length);
- }
- getValue() {
- return this.inputValue;
- }
-}
-export { Secret1 as Secret };
-class Select1 extends GenericList1 {
- listIndex = this.getListIndex(this.settings.default);
- static inject(value) {
- GenericPrompt1.inject(value);
- }
- static prompt(options) {
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- listPointer: blue(Figures1.POINTER),
- maxRows: 10,
- searchLabel: blue(Figures1.SEARCH),
- ...options,
- options: Select1.mapOptions(options)
- }).prompt();
- }
- static mapOptions(options) {
- return options.options.map((item)=>typeof item === "string" ? {
- value: item
- } : item
- ).map((item)=>this.mapOption(item)
- );
- }
- input() {
- return underline(blue(this.inputValue));
- }
- getListItem(item, isSelected) {
- let line = this.settings.indent;
- line += isSelected ? `${this.settings.listPointer} ` : " ";
- line += `${isSelected ? this.highlight(item.name, (val)=>val
- ) : this.highlight(item.name)}`;
- return line;
- }
- getValue() {
- return this.options[this.listIndex]?.value ?? this.settings.default;
- }
- validate(value) {
- return typeof value === "string" && value.length > 0 &&
this.options.findIndex((option11)=>option11.value === value
- ) !== -1;
- }
- transform(value) {
- return value.trim();
- }
- format(value) {
- return this.getOptionByValue(value)?.name ?? value;
- }
-}
-export { Select1 as Select };
-class Toggle1 extends GenericPrompt1 {
- status = typeof this.settings.default !== "undefined" ? this.format(this.settings.default) : "";
- static prompt(options) {
- if (typeof options === "string") {
- options = {
- message: options
- };
- }
- return new this({
- pointer: blue(Figures1.POINTER_SMALL),
- prefix: yellow("? "),
- indent: " ",
- active: "Yes",
- inactive: "No",
- ...options,
- keys: {
- active: [
- "right",
- "y",
- "j",
- "s",
- "o"
- ],
- inactive: [
- "left",
- "n"
- ],
- ...options.keys ?? {
+ const cmd = s.slice(cmdStart);
+ let match;
+ if (match = cmd.match(/^(\d\d?)(;(\d))?([~^$])$/)) {
+ code1 += match[1] + match[4];
+ modifier = (Number(match[3]) || 1) - 1;
+ } else if (match = cmd.match(/^((\d;)?(\d))?([A-Za-z])$/)) {
+ code1 += match[4];
+ modifier = (Number(match[3]) || 1) - 1;
+ } else {
+ code1 += cmd;
}
}
- }).prompt();
- }
- message() {
- let message4 = super.message() + " " + this.settings.pointer + " ";
- if (this.status === this.settings.active) {
- message4 += dim(this.settings.inactive + " / ") + underline(this.settings.active);
- } else if (this.status === this.settings.inactive) {
- message4 += underline(this.settings.inactive) + dim(" / " + this.settings.active);
- } else {
- message4 += dim(this.settings.inactive + " / " + this.settings.active);
- }
- return message4;
- }
- read() {
- this.tty.cursorHide();
- return super.read();
- }
- async handleEvent(event) {
- switch(true){
- case event.sequence === this.settings.inactive[0].toLowerCase():
- case this.isKey(this.settings.keys, "inactive", event):
- this.selectInactive();
- break;
- case event.sequence === this.settings.active[0].toLowerCase():
- case this.isKey(this.settings.keys, "active", event):
- this.selectActive();
- break;
- default:
- await super.handleEvent(event);
- }
- }
- selectActive() {
- this.status = this.settings.active;
- }
- selectInactive() {
- this.status = this.settings.inactive;
- }
- validate(value) {
- return [
- this.settings.active,
- this.settings.inactive
- ].indexOf(value) !== -1;
- }
- transform(value) {
- switch(value){
- case this.settings.active:
- return true;
- case this.settings.inactive:
- return false;
- }
- }
- format(value) {
- return value ? this.settings.active : this.settings.inactive;
- }
- getValue() {
- return this.status;
- }
-}
-export { Toggle1 as Toggle };
-function prompt1(prompts, options7) {
- return new PromptList(prompts, options7).run(options7?.initial);
-}
-let injected = {
-};
-function inject1(values1) {
- injected = values1;
-}
-class PromptList {
- prompts;
- options;
- result = {
- };
- index = -1;
- names;
- isInBeforeHook = false;
- get prompt() {
- return this.prompts[this.index];
- }
- constructor(prompts, options7){
- this.prompts = prompts;
- this.options = options7;
- this.names = this.prompts.map((prompt1)=>prompt1.name
- );
- }
- async run(name) {
- this.index = -1;
- this.result = {
- };
- this.isInBeforeHook = false;
- await this.next(name);
- return this.result;
- }
- async next(name) {
- if (this.updateIndex(name)) {
- await this.runBeforeHook(async ()=>{
- this.isInBeforeHook = false;
- await this.runPrompt();
- await this.runAfterHook();
- });
- }
- }
- updateIndex(name) {
- if (name && typeof name === "string") {
- this.index = this.names.indexOf(name);
- if (this.index === -1) {
- throw new Error(`Invalid prompt name: ${name}, allowed prompt names: ${this.names.join(",
")}`);
- }
- } else if (typeof name === "number") {
- if (name < 0 || name > this.names.length) {
- throw new Error(`Invalid prompt index: ${name}, prompt length: ${this.names.length}`);
- }
- this.index = name;
- } else if (name === true && !this.isInBeforeHook) {
- this.index++;
- if (this.index < this.names.length - 1) {
- this.index++;
+ key.ctrl = !!(modifier & 4);
+ key.meta = !!(modifier & 10);
+ key.shift = !!(modifier & 1);
+ key.code = code1;
+ if (code1 in KeyMap) {
+ key.name = KeyMap[code1];
+ } else if (code1 in KeyMapShift) {
+ key.name = KeyMapShift[code1];
+ key.shift = true;
+ } else if (code1 in KeyMapCtrl) {
+ key.name = KeyMapCtrl[code1];
+ key.ctrl = true;
+ } else {
+ key.name = "undefined";
}
- } else {
- this.index++;
+ } else if (ch in SpecialKeyMap) {
+ key.name = SpecialKeyMap[ch];
+ key.meta = escaped;
+ } else if (!escaped && ch <= "\x1a") {
+ key.name = String.fromCharCode(ch.charCodeAt(0) + "a".charCodeAt(0) - 1);
+ key.ctrl = true;
+ } else if (/^[0-9A-Za-z]$/.test(ch)) {
+ key.name = ch.toLowerCase();
+ key.shift = /^[A-Z]$/.test(ch);
+ key.meta = escaped;
+ } else if (escaped) {
+ key.name = ch.length ? undefined : "escape";
+ key.meta = true;
}
- this.isInBeforeHook = false;
- if (this.index < this.names.length) {
- return true;
- } else if (this.index === this.names.length) {
- return false;
+ key.sequence = s;
+ if (s.length !== 0 && (key.name !== undefined || escaped)) {
+ keys.push(key);
+ } else if (charLengthAt(s, 0) === s.length) {
+ keys.push(key);
} else {
- throw new Error("next() called multiple times");
- }
- }
- async runBeforeHook(run) {
- this.isInBeforeHook = true;
- const next = async (name19)=>{
- if (name19 || typeof name19 === "number") {
- return this.next(name19);
- }
- await run();
- };
- if (this.options?.before) {
- await this.options.before(this.prompt.name, this.result, async (name19)=>{
- if (name19 || typeof name19 === "number") {
- return this.next(name19);
- } else if (this.prompt.before) {
- await this.prompt.before(this.result, next);
- } else {
- await run();
- }
- });
- return;
- } else if (this.prompt.before) {
- await this.prompt.before(this.result, next);
- return;
- }
- await run();
- }
- async runPrompt() {
- const prompt1 = this.prompt.type;
- if (typeof injected[this.prompt.name] !== "undefined") {
- if (prompt1.inject) {
- prompt1.inject(injected[this.prompt.name]);
- } else {
- GenericPrompt1.inject(injected[this.prompt.name]);
- }
+ throw new Error("Unrecognized or broken escape sequence");
}
- try {
- this.result[this.prompt.name] = await prompt1.prompt({
- cbreak: this.options?.cbreak,
- ...this.prompt
- });
- } finally{
- tty1.cursorShow();
+ if (hasNext()) {
+ parseNext();
}
}
- async runAfterHook() {
- if (this.options?.after) {
- await this.options.after(this.prompt.name, this.result, async (name19)=>{
- if (name19) {
- return this.next(name19);
- } else if (this.prompt.after) {
- await this.prompt.after(this.result, (name20)=>this.next(name20)
- );
- } else {
- await this.next();
- }
- });
- } else if (this.prompt.after) {
- await this.prompt.after(this.result, (name19)=>this.next(name19)
- );
- } else {
- await this.next();
- }
+}
+function charLengthAt(str, i) {
+ const pos = str.codePointAt(i);
+ if (typeof pos === "undefined") {
+ return 1;
}
+ return pos >= 65536 ? 2 : 1;
}
-export { prompt1 as prompt };
-export { inject1 as inject };
-export { __boolean as boolean, number1 as number, OptionType1 as OptionType, parseFlags1 as parseFlags,
string1 as string, validateFlags1 as validateFlags };
\ No newline at end of file
+const mod3 = function() {
+ return {
+ parse,
+ KeyMap,
+ KeyMapShift,
+ KeyMapCtrl,
+ SpecialKeyMap
+ };
+}();
+const main = {
+ ARROW_UP: "↑",
+ ARROW_DOWN: "↓",
+ ARROW_LEFT: "←",
+ ARROW_RIGHT: "→",
+ ARROW_UP_LEFT: "↖",
+ ARROW_UP_RIGHT: "↗",
+ ARROW_DOWN_RIGHT: "↘",
+ ARROW_DOWN_LEFT: "↙",
+ RADIO_ON: "◉",
+ RADIO_OFF: "◯",
+ TICK: "✔",
+ CROSS: "✘",
+ ELLIPSIS: "…",
+ POINTER_SMALL: "›",
+ LINE: "─",
+ POINTER: "❯",
+ INFO: "ℹ",
+ TAB_LEFT: "⇤",
+ TAB_RIGHT: "⇥",
+ ESCAPE: "⎋",
+ BACKSPACE: "⌫",
+ PAGE_UP: "⇞",
+ PAGE_DOWN: "⇟",
+ ENTER: "↵",
+ SEARCH: "⌕"
+};
+const win = {
+ ...main,
+ RADIO_ON: "(*)",
+ RADIO_OFF: "( )",
+ TICK: "√",
+ CROSS: "×",
+ POINTER_SMALL: "»"
+};
+const Figures1 = Deno.build.os === "windows" ? win : main;
+export { Figures1 as Figures };
+export { mod as AnsiColors };
+export { mod2 as Ansi };
+export { mod3 as Keycode };
+
diff --git a/modules/esm/_denoCompatLayer.js b/modules/esm/_denoCompatLayer.js
new file mode 100644
index 00000000..fd9dc47e
--- /dev/null
+++ b/modules/esm/_denoCompatLayer.js
@@ -0,0 +1,102 @@
+import GLib from 'gi://GLib';
+import Gio from 'gi://Gio';
+
+export { exit } from 'system';
+
+class Stream {
+ constructor(rid) {
+ this.rid = rid;
+ }
+}
+
+class OutputStream extends Stream {
+ constructor(rid) {
+ super(rid);
+ this._stream = Gio.UnixOutputStream.new(this.rid, false);
+ }
+
+ flush() {
+ const cancellable = new Gio.Cancellable();
+
+ this._stream.flush(cancellable);
+ }
+
+ /**
+ * @param {Uint8Array} buffer
+ */
+ writeSync(buffer) {
+ const cancellable = new Gio.Cancellable();
+
+ this._stream.write_bytes(buffer, cancellable);
+ }
+}
+
+class InputStream extends Stream {
+ constructor(rid) {
+ super(rid);
+ this._stream = Gio.UnixInputStream.new(this.rid, false);
+ }
+
+ /**
+ * @param {Uint8Array} buffer
+ */
+ async read(buffer) {
+ const gbytes = await new Promise((resolve, reject) => {
+ const cancellable = new Gio.Cancellable();
+ this._stream.read_bytes_async(buffer.length, 0, cancellable, (_, result) => {
+ try {
+ const gbytes = this._stream.read_bytes_finish(result);
+ resolve(gbytes.toArray());
+ } catch (error) {
+ reject(error);
+ }
+ });
+ });
+
+ gbytes.slice(0, buffer.length).forEach((v, i) => {
+ buffer[i] = v;
+ });
+
+ return gbytes.length;
+ }
+
+}
+
+export const stdin = new InputStream(0);
+export const stdout = new OutputStream(1);
+export const stderr = new OutputStream(2);
+
+
+export const errors = {
+ NotFound: Error,
+};
+
+export const build = {
+
+};
+Object.defineProperty(build, 'os', {
+ get() {
+ const name = GLib.get_os_info('NAME').toLowerCase();
+
+ if (name === 'macos')
+ return 'darwin';
+
+
+ if (name === 'windows')
+ return 'windows';
+
+ // Linux distributions all have differing names...
+ return 'linux';
+ }
+});
+
+export const noColor = !GLib.log_writer_supports_color(stdout.rid);
+
+export function isatty() {
+ // TODO
+ true;
+}
+
+export function setRaw() {
+ // TODO
+}
\ No newline at end of file
diff --git a/modules/esm/repl.js b/modules/esm/repl.js
index 3cd0a828..98977825 100644
--- a/modules/esm/repl.js
+++ b/modules/esm/repl.js
@@ -1,11 +1,12 @@
import Gio from 'gi://Gio';
-const Console = import.meta.importSync('_consoleNative');
+import { Ansi, AnsiColors, Keycode, Figures } from '_cliffy';
+
+const stdin = Gio.UnixInputStream.new(0, false);
+const stdout = Gio.UnixOutputStream.new(1, false);
+const stderr = Gio.UnixOutputStream.new(2, false);
-/**
- * @type {(letter: string) => number}
- */
-const codeOf = (letter) => letter.charCodeAt(0);
+const Console = import.meta.importSync('_consoleNative');
function toString(value) {
if (typeof value === 'function') {
@@ -20,347 +21,242 @@ function toString(value) {
return `${value}`;
}
-/**
- * @enum {string}
- */
-const KeyCodeStrings = {
- /**
- * Enter
- */
- ENTER: '\x0d',
- /**
- * \n (newline)
- */
- LF: '\n',
- /**
- * Escape
- */
- ESCAPE: '\x1b',
- /**
- * Delete
- */
- DELETE: '\x7f',
- /**
- * Backspace
- */
- BACKSPACE: '\x08',
- /**
- * [
- */
- BRACKET_LEFT: '[',
-};
+AnsiColors.setColorEnabled(true);
-/**
- * @enum {number}
- */
-const KeyCode = {
- /**
- * Enter
- */
- ENTER: 13,
- /**
- * \n (newline)
- */
- LF: codeOf('\n'),
- /**
- * Escape
- */
- ESCAPE: 27,
- /**
- * Delete
- */
- DELETE: 127,
+class ReplInput {
+ constructor() {
+ this.$promptPrefix = 'gjs';
+ this.$promptPointer = Figures.POINTER_SMALL;
+ this.$promptLength = `${this.$promptPrefix} ${this.$promptPointer} `.length;
+ this.$prompt = `${Ansi.colors.yellow(this.$promptPrefix)} ${this.$promptPointer} `;
+
+ this.history = [];
+ this.inputChars = [];
+ this.inputIndex = 0;
+ }
+
/**
- * Backspace
+ * @returns {readonly string[]}
*/
- BACKSPACE: 8,
+ getValue() {
+ if (this.historyIndex > -1) {
+ return this.history[this.historyIndex].join('');
+ }
+ return this.inputChars.join('');
+ }
+
/**
- * [
+ * @returns {string[]}
*/
- BRACKET_LEFT: codeOf('['),
-};
-
-const CSI = `${KeyCodeStrings.ESCAPE}[`;
-
-/**
- * @enum {string}
- */
-const ANSICodeStrings = {
- ARROW_UP: 'A',
- ARROW_DOWN: 'B',
- CURSOR_FORWARD: 'C',
- CURSOR_BACKWARD: 'D',
- CURSOR_MOVE_ABSOLUTE: 'H',
-};
-
-/**
- * @enum {number}
- */
-const ANSICodes = {
- ARROW_UP: codeOf(ANSICodeStrings.ARROW_UP),
- ARROW_DOWN: codeOf(ANSICodeStrings.ARROW_DOWN),
- CURSOR_FORWARD: codeOf(ANSICodeStrings.CURSOR_FORWARD),
- CURSOR_BACKWARD: codeOf(ANSICodeStrings.CURSOR_BACKWARD),
-};
-
-export class Repl {
- constructor(prompt = 'gjs>') {
- if (!('UnixInputStream' in Gio))
- throw new Error('Repl can only be used on systems with Gio Unix');
-
- const stdin = Gio.UnixInputStream.new(0, false);
- const stdout = Gio.UnixOutputStream.new(1, false);
-
- this._stdin = stdin;
- this._stdout = stdout;
-
- this._mainloop = null;
-
- this._keyBuffer = [];
- this._commandHistory = [];
- this._commandHistoryIndex = -1;
- this._cursorColumn = 0;
- this._escapeSequence = 0;
-
- this.prompt = `${prompt} `;
+ getEditableValue() {
+ if (this.historyIndex > -1) {
+ return this.history[this.historyIndex];
+ }
+ return this.inputChars;
}
- get size() {
- const { width, height } = Console.get_size();
- return {
- rows: height,
- columns: width,
- };
+ validate(input) {
+ return true;
}
- toHistory(index) {
- let newcmd = this._commandHistory[index];
- if (newcmd) {
- this._keyBuffer = [...new TextEncoder().encode(newcmd)];
-
- // Snap to the new length
- this._cursorColumn = Math.min(newcmd.length, this._cursorColumn);
- }
-
- this.writeCurrentLine(true);
+ clear() {
+ this.writeSync(Ansi.cursorLeft);
+ this.writeSync(Ansi.eraseLine);
}
historyUp() {
- if (this._commandHistory.length === 0) return;
-
- if (this._commandHistoryIndex === -1) {
- this._savedKeyBuffer = this._keyBuffer;
- }
-
- if (this._commandHistoryIndex < this._commandHistory.length - 1)
- this._commandHistoryIndex++;
-
- this.toHistory(this._commandHistoryIndex);
+ if (this.historyIndex < this.history.length - 1)
+ this.historyIndex++;
}
historyDown() {
- if (this._commandHistoryIndex < 0) return;
-
- // If we're at the last command, reset to the saved buffer
- if (this._commandHistoryIndex == 0) {
- // Only reset if a saved buffer exists
- // (can be cleared by running a command from history)
- if (this._savedKeyBuffer) {
- this._keyBuffer = this._savedKeyBuffer;
- this._savedKeyBuffer = null;
- this._commandHistoryIndex = -1;
-
- this.writeCurrentLine(true);
- }
+ if (this.historyIndex >= 0)
+ this.historyIndex--;
+ }
- return;
- }
+ moveCursorToBeginning() {
+ this.inputIndex = 0;
+ }
- this._commandHistoryIndex--;
- this.toHistory(this._commandHistoryIndex);
+ moveCursorToEnd() {
+ this.inputIndex = this.getValue().length;
}
- cursorForward() {
- if (this._cursorColumn < this._keyBuffer.length) {
- this._cursorColumn++;
- this.writeANSI(ANSICodeStrings.CURSOR_FORWARD);
- }
+ moveCursorLeft() {
+ if (this.inputIndex > 0)
+ this.inputIndex--;
}
- cursorBackward() {
- if (this._cursorColumn > 0) {
- this._cursorColumn--;
- this.writeANSI(ANSICodeStrings.CURSOR_BACKWARD);
- }
+ moveCursorRight() {
+ if (this.inputIndex < this.getValue().length)
+ this.inputIndex++;
}
- delete() {
- if (this._cursorColumn > 0) {
- this._keyBuffer.splice(this._cursorColumn - 1, 1);
- this._cursorColumn--;
- }
+ addChar(char) {
+ this.inputChars.splice(this.inputIndex, 0, char);
- this.writeCurrentLine();
+ this.inputIndex++;
}
- dumpCommandBuffer() {
- const cmd = new TextDecoder().decode(new Uint8Array(this._keyBuffer));
-
- this._keyBuffer = [];
- this._savedKeyBuffer = null;
- this._cursorColumn = 0;
+ deleteChar() {
+ const editableValue = this.getEditableValue();
+ if (this.inputIndex > 0 && editableValue.length > 0)
+ editableValue.splice(this.inputIndex - 1, 1);
- return cmd;
+ this.moveCursorLeft();
}
- addHistory(cmd) {
- this._commandHistory.unshift(cmd);
- // Reset the history index
- this._commandHistoryIndex = -1;
+ processLine() {
+ const value = this.getValue();
+ this.writeSync('\n');
+ this.flush();
+ this.history.unshift(value.split(''));
+ this.historyIndex = -1;
+ this.inputChars = [];
+ this.inputIndex = 0;
+
+ this._input?.(value);
}
- keypress(code) {
- if (this._escapeSequence == 1) {
- if (code === KeyCode.BRACKET_LEFT) {
- this._escapeSequence = 2;
- return;
- } else {
- this._escapeSequence = 0;
+ handleEvent(key) {
+ if (key.ctrl) {
+ switch (key.name) {
+ case 'a':
+ this.moveCursorToBeginning();
+ return;
+ case 'e':
+ this.moveCursorToEnd();
+ return;
+ case 'b':
+ this.moveCursorLeft();
+ return;
+ case 'f':
+ this.moveCursorRight();
+ return;
}
}
- if (this._escapeSequence == 2) {
- switch (code) {
- case ANSICodes.ARROW_UP:
- this.historyUp();
- break;
- case ANSICodes.ARROW_DOWN:
- this.historyDown();
- break;
- case ANSICodes.CURSOR_FORWARD:
- this.cursorForward();
- break;
- case ANSICodes.CURSOR_BACKWARD:
- this.cursorBackward();
- break;
- default:
- this.write(KeyCodeStrings.ESCAPE);
- }
-
- this._escapeSequence = 0;
-
- return;
- }
- if (code === KeyCode.BACKSPACE || code === KeyCode.DELETE) {
- this.delete();
- } else if (code === KeyCode.ESCAPE) {
- // Start escape sequence...
- this._escapeSequence = 1;
- } else if (code === KeyCode.ENTER || code === KeyCode.LF) {
- const cmd = this.dumpCommandBuffer();
-
- // TODO: Add a hardcoded exit() for now.
- if (cmd.startsWith('exit()')) {
- this.stop();
- this.writeLine();
+ switch (key.name) {
+ case 'up':
+ this.historyUp();
+ return;
+ case 'down':
+ this.historyDown();
+ return;
+ case 'left':
+ this.moveCursorLeft();
+ return;
+ case 'right':
+ this.moveCursorRight();
+ return;
+ case 'backspace':
+ this.deleteChar();
+ return;
+ case 'return':
+ this.processLine();
return;
- }
-
- // Add the command to history before evaluation, in case it errors...
- this.addHistory(cmd);
- // Append a new line for the command's output...
- this.writeLine();
-
- try {
- const result = Console.eval(cmd, this._commandHistory.length + 1);
-
- if (result) {
- // TODO: Integrate with good printer...
- this.writeLine(`${toString(result)}`, false);
- this.write(this.prompt);
- } else {
- this.writeLine(`'undefined'`);
- this.write(this.prompt);
- }
- } catch (err) {
- console.error(err);
- }
- } else {
- this._keyBuffer.splice(this._cursorColumn, 0, code);
- this._cursorColumn++;
-
- this.writeCurrentLine();
}
- }
- /**
- * @param {string} code
- * @param {...number} [counts]
- */
- writeANSI(code, ...counts) {
- this.write(`${CSI}${counts.join(';')}${code}`)
+ this.addChar(key.sequence);
}
- writeCurrentLine(reset = false) {
- const { rows } = this.size;
- // TODO: Convert this to the ANSI enums
- // Reset cursor, clear entire line...
- this.write(`\x1b[2K\x1b[1G${this.prompt}`, false);
-
- if (this._keyBuffer.length > 0) {
- const output = String.fromCharCode(...this._keyBuffer);
- this.write(output, false);
-
- if (reset) {
- this._cursorColumn = output.length;
- }
- } else if (reset) {
- this._cursorColumn = 0;
- }
- const cursor_position = this._cursorColumn + this.prompt.length + 1;
- this.writeANSI(ANSICodeStrings.CURSOR_MOVE_ABSOLUTE, rows + 1, cursor_position);
+ render() {
+ this.writeSync(Ansi.cursorHide);
+ this.clear();
+ const value = this.getValue();
+ this.writeSync(this.$prompt + value);
+ // Ensure the input index isn't longer than the content...
+ this.inputIndex = Math.min(this.inputIndex, value.length);
+ this.writeSync(Ansi.cursorTo(this.$promptLength + this.inputIndex + 1));
+ this.writeSync(Ansi.cursorShow);
+ this.flush();
}
- /**
- * @param {string} output
- * @param {boolean} [flush]
- */
- write(output, flush = true) {
- const cancellable = new Gio.Cancellable();
- const bytes = new TextEncoder().encode(output);
- this._stdout.write_bytes(bytes, cancellable);
- if (flush)
- this._stdout.flush(cancellable);
+ flush() {
+ stdout.flush(null);
}
/**
- * @param {string} output
- * @param {boolean} [flush]
+ * @param {Uint8Array} buffer
*/
- writeLine(output = '', flush = true) {
- this.write(`${output}${KeyCodeStrings.LF}`, flush);
+ writeSync(buffer) {
+ if (typeof buffer === 'string')
+ buffer = new TextEncoder().encode(buffer);
+ stdout.write_bytes(buffer, null);
}
- read(stdin, result) {
+ _read(stdin, result) {
if (result) {
- const gbytes = this._stdin.read_bytes_finish(result);
+ const gbytes = stdin.read_bytes_finish(result);
const bytes = gbytes.toArray();
if (bytes.length > 0) {
- for (const byte of bytes) {
- this.keypress(byte);
+ for (const event of Keycode.parse(bytes)) {
+ this.handleEvent(event);
+ this.render();
}
}
}
- const cancellable = new Gio.Cancellable();
- stdin.read_bytes_async(1, 0, cancellable, this.read.bind(this));
+ this.cancellable = new Gio.Cancellable();
+ stdin.read_bytes_async(8, 0, this.cancellable, this._read.bind(this));
+ }
+
+ stop() {
+ this.cancellable.cancel();
+ }
+
+ read() {
+ this.render();
+ this._read(stdin);
+ }
+
+ prompt(input) {
+ this._input = input;
+ this.read();
+ }
+}
+
+export class Repl {
+ constructor() {
+ if (!('UnixInputStream' in Gio))
+ throw new Error('Repl can only be used on systems with Gio Unix');
+ this.input = new ReplInput();
+ }
+
+ evaluateJs(code) {
+ if (!this.line)
+ this.line = 1;
+ else
+ this.line++;
+
+ try {
+ const result = Console.eval(code, this.line);
+
+ if (result) {
+ // TODO: Integrate with good printer...
+ print(`${toString(result)}`);
+ } else {
+ print(`'undefined'`);
+ }
+ } catch (err) {
+ console.error(err);
+ }
+ }
+
+ startPrompt() {
+ this.input.prompt((input) => {
+ if (input === 'exit()') {
+ this.stop();
+ } else {
+ this.evaluateJs(input);
+ }
+ });
}
run() {
Console.enable_raw_mode();
- this.write(`${this.prompt}`);
- this.read(this._stdin);
+ this.startPrompt();
this.replaceMainLoop(() => {
imports.mainloop.run('repl');
@@ -377,6 +273,9 @@ export class Repl {
}
stop() {
+ this.writeSync('\n');
+ this.flush();
+
const mainloop = this._mainloop;
this._mainloop = null;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]