mepcli 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/highlight.d.ts +6 -0
- package/dist/highlight.js +133 -28
- package/dist/prompts/calculator.d.ts +1 -0
- package/dist/prompts/calculator.js +7 -0
- package/dist/prompts/code.js +46 -31
- package/dist/prompts/curl.d.ts +1 -0
- package/dist/prompts/curl.js +7 -0
- package/dist/prompts/file.d.ts +1 -0
- package/dist/prompts/file.js +7 -5
- package/dist/prompts/form.d.ts +1 -0
- package/dist/prompts/form.js +7 -0
- package/dist/prompts/phone.d.ts +1 -0
- package/dist/prompts/phone.js +7 -0
- package/dist/prompts/snippet.d.ts +1 -0
- package/dist/prompts/snippet.js +7 -0
- package/dist/prompts/text.d.ts +1 -0
- package/dist/prompts/text.js +7 -0
- package/dist/types.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
package/dist/highlight.d.ts
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
1
|
export declare function highlightJson(json: string): string;
|
|
2
|
+
export declare function highlightEnv(env: string): string;
|
|
3
|
+
export declare function highlightToml(toml: string): string;
|
|
4
|
+
export declare function highlightCsv(csv: string): string;
|
|
5
|
+
export declare function highlightShell(script: string): string;
|
|
6
|
+
export declare function highlightProperties(props: string): string;
|
|
7
|
+
export declare function highlight(code: string, language: string): string;
|
package/dist/highlight.js
CHANGED
|
@@ -1,39 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.highlightJson = highlightJson;
|
|
4
|
+
exports.highlightEnv = highlightEnv;
|
|
5
|
+
exports.highlightToml = highlightToml;
|
|
6
|
+
exports.highlightCsv = highlightCsv;
|
|
7
|
+
exports.highlightShell = highlightShell;
|
|
8
|
+
exports.highlightProperties = highlightProperties;
|
|
9
|
+
exports.highlight = highlight;
|
|
4
10
|
const ansi_1 = require("./ansi");
|
|
5
11
|
const theme_1 = require("./theme");
|
|
12
|
+
// --- 1. JSON Highlighter ---
|
|
6
13
|
function highlightJson(json) {
|
|
7
14
|
if (!json)
|
|
8
15
|
return '';
|
|
9
|
-
// Updated Regex for better partial matching and separation
|
|
10
|
-
// 1. Strings (keys or values), allowing unclosed quotes for partial typing
|
|
11
|
-
// 2. Numbers
|
|
12
|
-
// 3. Booleans/Null
|
|
13
|
-
// 4. Punctuation (separated colon from keys logic)
|
|
14
|
-
// Regex explanation:
|
|
15
|
-
// ("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"?) -> Captures strings, optionally unclosed at the end
|
|
16
|
-
// (-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?) -> Captures numbers
|
|
17
|
-
// (true|false|null) -> Captures keywords
|
|
18
|
-
// ([{}[\],:]) -> Captures punctuation
|
|
19
16
|
const tokenRegex = /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"?)|(-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)|(true|false|null)|([{}[\],:])/g;
|
|
20
17
|
let result = '';
|
|
21
18
|
let lastIndex = 0;
|
|
22
19
|
let match;
|
|
23
20
|
while ((match = tokenRegex.exec(json)) !== null) {
|
|
24
|
-
// Add any non-matching text (whitespace/invalid) as-is
|
|
25
21
|
if (match.index > lastIndex) {
|
|
26
22
|
result += json.substring(lastIndex, match.index);
|
|
27
23
|
}
|
|
28
24
|
const token = match[0];
|
|
29
|
-
// 1. Strings (Key or Value determination is context-based, but here we do simple check)
|
|
30
|
-
// Note: In strict JSON, keys are strings followed by :, but since we separated colon,
|
|
31
|
-
// we can't easily distinguish keys just by regex lookahead safely without lookbehind support.
|
|
32
|
-
// However, for visual highlighting, colouring all strings consistently is often acceptable
|
|
33
|
-
// or we can try to peek ahead.
|
|
34
25
|
if (token.startsWith('"')) {
|
|
35
|
-
// Simple heuristic: If the NEXT non-whitespace char is ':', treat as key
|
|
36
26
|
const remaining = json.substring(tokenRegex.lastIndex);
|
|
27
|
+
// Heuristic for keys: followed by optional whitespace and a colon
|
|
37
28
|
if (/^\s*:/.test(remaining)) {
|
|
38
29
|
result += `${theme_1.theme.syntax.key}${token}${ansi_1.ANSI.RESET}`;
|
|
39
30
|
}
|
|
@@ -41,32 +32,146 @@ function highlightJson(json) {
|
|
|
41
32
|
result += `${theme_1.theme.syntax.string}${token}${ansi_1.ANSI.RESET}`;
|
|
42
33
|
}
|
|
43
34
|
}
|
|
44
|
-
// 2. Numbers
|
|
45
35
|
else if (/^-?\d/.test(token)) {
|
|
46
36
|
result += `${theme_1.theme.syntax.number}${token}${ansi_1.ANSI.RESET}`;
|
|
47
37
|
}
|
|
48
|
-
// 3. Booleans/Null
|
|
49
38
|
else if (/^(true|false|null)$/.test(token)) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
else {
|
|
54
|
-
result += `${theme_1.theme.syntax.boolean}${token}${ansi_1.ANSI.RESET}`;
|
|
55
|
-
}
|
|
39
|
+
result += (token === 'null')
|
|
40
|
+
? `${theme_1.theme.syntax.null}${token}${ansi_1.ANSI.RESET}`
|
|
41
|
+
: `${theme_1.theme.syntax.boolean}${token}${ansi_1.ANSI.RESET}`;
|
|
56
42
|
}
|
|
57
|
-
// 4. Punctuation
|
|
58
43
|
else if (/^[{}[\],:]$/.test(token)) {
|
|
59
44
|
result += `${theme_1.theme.syntax.punctuation}${token}${ansi_1.ANSI.RESET}`;
|
|
60
45
|
}
|
|
61
|
-
// Fallback
|
|
62
46
|
else {
|
|
63
47
|
result += token;
|
|
64
48
|
}
|
|
65
49
|
lastIndex = tokenRegex.lastIndex;
|
|
66
50
|
}
|
|
67
|
-
// Append remaining text
|
|
68
51
|
if (lastIndex < json.length) {
|
|
69
52
|
result += json.substring(lastIndex);
|
|
70
53
|
}
|
|
71
54
|
return result;
|
|
72
55
|
}
|
|
56
|
+
// --- 2. ENV Highlighter ---
|
|
57
|
+
function highlightEnv(env) {
|
|
58
|
+
if (!env)
|
|
59
|
+
return '';
|
|
60
|
+
return env.split('\n').map(line => {
|
|
61
|
+
if (line.trim().startsWith('#')) {
|
|
62
|
+
return `${theme_1.theme.muted}${line}${ansi_1.ANSI.RESET}`;
|
|
63
|
+
}
|
|
64
|
+
const match = line.match(/^([^=]+)=(.*)$/);
|
|
65
|
+
if (match) {
|
|
66
|
+
const [, key, value] = match;
|
|
67
|
+
return `${theme_1.theme.syntax.key}${key}${theme_1.theme.syntax.punctuation}=${theme_1.theme.syntax.string}${value}${ansi_1.ANSI.RESET}`;
|
|
68
|
+
}
|
|
69
|
+
return line;
|
|
70
|
+
}).join('\n');
|
|
71
|
+
}
|
|
72
|
+
// --- 3. TOML Highlighter ---
|
|
73
|
+
function highlightToml(toml) {
|
|
74
|
+
if (!toml)
|
|
75
|
+
return '';
|
|
76
|
+
return toml.split('\n').map(line => {
|
|
77
|
+
const trimmed = line.trim();
|
|
78
|
+
if (trimmed.startsWith('#')) {
|
|
79
|
+
return `${theme_1.theme.muted}${line}${ansi_1.ANSI.RESET}`;
|
|
80
|
+
}
|
|
81
|
+
// [section]
|
|
82
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
83
|
+
return `${theme_1.theme.syntax.key}${line}${ansi_1.ANSI.RESET}`;
|
|
84
|
+
}
|
|
85
|
+
// Key = Value
|
|
86
|
+
const match = line.match(/^(\s*[\w\d_-]+)(\s*=)/);
|
|
87
|
+
if (match) {
|
|
88
|
+
const fullMatch = match[0];
|
|
89
|
+
const keyPart = match[1];
|
|
90
|
+
const eqPart = match[2];
|
|
91
|
+
const rest = line.substring(fullMatch.length);
|
|
92
|
+
return `${theme_1.theme.syntax.key}${keyPart}${ansi_1.ANSI.RESET}${theme_1.theme.syntax.punctuation}${eqPart}${theme_1.theme.syntax.string}${rest}${ansi_1.ANSI.RESET}`;
|
|
93
|
+
}
|
|
94
|
+
return line;
|
|
95
|
+
}).join('\n');
|
|
96
|
+
}
|
|
97
|
+
// --- 4. CSV Highlighter ---
|
|
98
|
+
function highlightCsv(csv) {
|
|
99
|
+
if (!csv)
|
|
100
|
+
return '';
|
|
101
|
+
// Cycle through colors to differentiate columns
|
|
102
|
+
const colors = [theme_1.theme.syntax.string, theme_1.theme.syntax.key, theme_1.theme.syntax.number, theme_1.theme.syntax.boolean];
|
|
103
|
+
return csv.split('\n').map(line => {
|
|
104
|
+
if (!line.trim())
|
|
105
|
+
return line;
|
|
106
|
+
// Split by comma, ignoring commas inside double quotes
|
|
107
|
+
// Regex explanation: Match comma only if followed by an even number of quotes (or 0) until end of line
|
|
108
|
+
const parts = line.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
|
|
109
|
+
return parts.map((part, index) => {
|
|
110
|
+
const color = colors[index % colors.length];
|
|
111
|
+
return `${color}${part}${ansi_1.ANSI.RESET}`;
|
|
112
|
+
}).join(`${theme_1.theme.syntax.punctuation},${ansi_1.ANSI.RESET}`);
|
|
113
|
+
}).join('\n');
|
|
114
|
+
}
|
|
115
|
+
// --- 5. Shell/Bash Highlighter ---
|
|
116
|
+
function highlightShell(script) {
|
|
117
|
+
if (!script)
|
|
118
|
+
return '';
|
|
119
|
+
// Simple replacements for common shell patterns
|
|
120
|
+
// 1. Comments
|
|
121
|
+
// 2. Keywords
|
|
122
|
+
// 3. Variables
|
|
123
|
+
const keywords = /\b(if|then|else|elif|fi|for|in|do|done|while|case|esac|return|exit|export|source|echo|printf)\b/g;
|
|
124
|
+
return script.split('\n').map(line => {
|
|
125
|
+
if (line.trim().startsWith('#')) {
|
|
126
|
+
return `${theme_1.theme.muted}${line}${ansi_1.ANSI.RESET}`;
|
|
127
|
+
}
|
|
128
|
+
// Temporarily hide strings properly is hard with regex replace,
|
|
129
|
+
// so we just do best-effort highlights for keywords and vars outside of checking quote context.
|
|
130
|
+
const processed = line
|
|
131
|
+
.replace(keywords, match => `${theme_1.theme.syntax.boolean}${match}${ansi_1.ANSI.RESET}`)
|
|
132
|
+
.replace(/(\$[\w\d_]+|\$\{[^}]+\})/g, match => `${theme_1.theme.syntax.key}${match}${ansi_1.ANSI.RESET}`)
|
|
133
|
+
.replace(/(\s|^)(-{1,2}[a-zA-Z0-9_-]+)/g, (_match, prefix, flag) => `${prefix}${theme_1.theme.syntax.number}${flag}${ansi_1.ANSI.RESET}`);
|
|
134
|
+
return processed;
|
|
135
|
+
}).join('\n');
|
|
136
|
+
}
|
|
137
|
+
// --- 6. Properties Highlighter ---
|
|
138
|
+
function highlightProperties(props) {
|
|
139
|
+
if (!props)
|
|
140
|
+
return '';
|
|
141
|
+
return props.split('\n').map(line => {
|
|
142
|
+
const trimmed = line.trim();
|
|
143
|
+
// Supports # or ! for comments
|
|
144
|
+
if (trimmed.startsWith('#') || trimmed.startsWith('!')) {
|
|
145
|
+
return `${theme_1.theme.muted}${line}${ansi_1.ANSI.RESET}`;
|
|
146
|
+
}
|
|
147
|
+
// Keys can be separated by = or :
|
|
148
|
+
const match = line.match(/^([^=:]+)([=:])(.*)$/);
|
|
149
|
+
if (match) {
|
|
150
|
+
const [, key, sep, value] = match;
|
|
151
|
+
return `${theme_1.theme.syntax.key}${key}${theme_1.theme.syntax.punctuation}${sep}${theme_1.theme.syntax.string}${value}${ansi_1.ANSI.RESET}`;
|
|
152
|
+
}
|
|
153
|
+
return line;
|
|
154
|
+
}).join('\n');
|
|
155
|
+
}
|
|
156
|
+
// --- Main Mapping ---
|
|
157
|
+
const highlighters = {
|
|
158
|
+
'json': highlightJson,
|
|
159
|
+
'env': highlightEnv,
|
|
160
|
+
'toml': highlightToml,
|
|
161
|
+
'csv': highlightCsv,
|
|
162
|
+
'sh': highlightShell,
|
|
163
|
+
'bash': highlightShell,
|
|
164
|
+
'zsh': highlightShell,
|
|
165
|
+
'properties': highlightProperties,
|
|
166
|
+
'props': highlightProperties,
|
|
167
|
+
'conf': highlightProperties // loose convention
|
|
168
|
+
};
|
|
169
|
+
function highlight(code, language) {
|
|
170
|
+
const lang = language.toLowerCase();
|
|
171
|
+
const highlightFunc = highlighters[lang];
|
|
172
|
+
if (highlightFunc) {
|
|
173
|
+
return highlightFunc(code);
|
|
174
|
+
}
|
|
175
|
+
// Fallback: If no highlighter found, return original code
|
|
176
|
+
return code;
|
|
177
|
+
}
|
|
@@ -12,5 +12,6 @@ export declare class CalculatorPrompt extends Prompt<number, CalculatorOptions>
|
|
|
12
12
|
private evaluate;
|
|
13
13
|
protected render(firstRender: boolean): void;
|
|
14
14
|
private getVisualCursorPosition;
|
|
15
|
+
protected cleanup(): void;
|
|
15
16
|
protected handleInput(char: string): void;
|
|
16
17
|
}
|
|
@@ -147,6 +147,13 @@ class CalculatorPrompt extends base_1.Prompt {
|
|
|
147
147
|
}
|
|
148
148
|
return width;
|
|
149
149
|
}
|
|
150
|
+
cleanup() {
|
|
151
|
+
if (this.lastLinesUp > 0) {
|
|
152
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
153
|
+
this.lastLinesUp = 0;
|
|
154
|
+
}
|
|
155
|
+
super.cleanup();
|
|
156
|
+
}
|
|
150
157
|
handleInput(char) {
|
|
151
158
|
// Enter
|
|
152
159
|
if (char === '\r' || char === '\n') {
|
package/dist/prompts/code.js
CHANGED
|
@@ -5,6 +5,7 @@ const ansi_1 = require("../ansi");
|
|
|
5
5
|
const base_1 = require("../base");
|
|
6
6
|
const theme_1 = require("../theme");
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
|
+
const highlight_1 = require("../highlight");
|
|
8
9
|
class CodePrompt extends base_1.Prompt {
|
|
9
10
|
constructor(options) {
|
|
10
11
|
super(options);
|
|
@@ -76,44 +77,58 @@ class CodePrompt extends base_1.Prompt {
|
|
|
76
77
|
let highlighted = '';
|
|
77
78
|
const shouldHighlight = this.options.highlight !== false;
|
|
78
79
|
if (shouldHighlight) {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
let
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
80
|
+
const lang = this.options.language || 'json';
|
|
81
|
+
const highlightedText = (0, highlight_1.highlight)(fullRawText, lang);
|
|
82
|
+
let visibleIdx = 0;
|
|
83
|
+
let activeColor = ''; // Tracks the last set color
|
|
84
|
+
for (let i = 0; i < highlightedText.length; i++) {
|
|
85
|
+
const char = highlightedText[i];
|
|
86
|
+
if (char === '\x1b') {
|
|
87
|
+
// Start of ANSI sequence
|
|
88
|
+
let sequence = char;
|
|
89
|
+
i++;
|
|
90
|
+
while (i < highlightedText.length && highlightedText[i] !== 'm') {
|
|
91
|
+
sequence += highlightedText[i];
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
if (i < highlightedText.length)
|
|
95
|
+
sequence += 'm'; // Append terminator
|
|
96
|
+
// Interpret sequence (naive)
|
|
97
|
+
if (sequence === ansi_1.ANSI.RESET || sequence === '\x1b[0m') {
|
|
98
|
+
activeColor = '';
|
|
94
99
|
}
|
|
95
100
|
else {
|
|
96
|
-
|
|
101
|
+
// Assuming it's a color code.
|
|
102
|
+
activeColor = sequence;
|
|
97
103
|
}
|
|
104
|
+
// If we are INSIDE the active range, and we encounter a color change/reset,
|
|
105
|
+
// we must ensure UNDERLINE is kept/restored.
|
|
106
|
+
if (visibleIdx >= activeVarStart && visibleIdx < activeVarEnd) {
|
|
107
|
+
// Output the sequence (e.g. a color change)
|
|
108
|
+
highlighted += sequence;
|
|
109
|
+
// Then re-assert underline
|
|
110
|
+
highlighted += ansi_1.ANSI.UNDERLINE;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
highlighted += sequence;
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
98
116
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
else if (/^(true|false|null)$/.test(tokenText)) {
|
|
103
|
-
color = (tokenText === 'null')
|
|
104
|
-
? (theme_1.theme.syntax?.null || ansi_1.ANSI.FG_RED)
|
|
105
|
-
: (theme_1.theme.syntax?.boolean || ansi_1.ANSI.FG_MAGENTA);
|
|
117
|
+
// Normal char
|
|
118
|
+
if (visibleIdx === activeVarStart) {
|
|
119
|
+
highlighted += `${theme_1.theme.main}${ansi_1.ANSI.UNDERLINE}`;
|
|
106
120
|
}
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
highlighted += char;
|
|
122
|
+
visibleIdx++;
|
|
123
|
+
if (visibleIdx === activeVarEnd) {
|
|
124
|
+
highlighted += ansi_1.ANSI.RESET;
|
|
125
|
+
// Restore previous color if any
|
|
126
|
+
if (activeColor) {
|
|
127
|
+
highlighted += activeColor;
|
|
128
|
+
}
|
|
109
129
|
}
|
|
110
|
-
this.appendSegment(tokenText, tokenStart, activeVarStart, activeVarEnd, color, (s) => highlighted += s);
|
|
111
|
-
lastIndex = jsonTokenRegex.lastIndex;
|
|
112
|
-
}
|
|
113
|
-
if (lastIndex < fullRawText.length) {
|
|
114
|
-
const tail = fullRawText.substring(lastIndex);
|
|
115
|
-
this.appendSegment(tail, lastIndex, activeVarStart, activeVarEnd, ansi_1.ANSI.FG_WHITE, (s) => highlighted += s);
|
|
116
130
|
}
|
|
131
|
+
highlighted += ansi_1.ANSI.RESET;
|
|
117
132
|
}
|
|
118
133
|
else {
|
|
119
134
|
this.appendSegment(fullRawText, 0, activeVarStart, activeVarEnd, ansi_1.ANSI.RESET, (s) => highlighted += s);
|
package/dist/prompts/curl.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare class CurlPrompt extends Prompt<CurlResult, CurlOptions> {
|
|
|
31
31
|
private shellEscapeDoubleQuoted;
|
|
32
32
|
private generateCommand;
|
|
33
33
|
protected render(firstRender: boolean): void;
|
|
34
|
+
protected cleanup(): void;
|
|
34
35
|
protected handleInput(char: string, _buffer: Buffer): void;
|
|
35
36
|
private cycleSection;
|
|
36
37
|
private editHeaders;
|
package/dist/prompts/curl.js
CHANGED
|
@@ -155,6 +155,13 @@ class CurlPrompt extends base_1.Prompt {
|
|
|
155
155
|
this.print(ansi_1.ANSI.HIDE_CURSOR);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
+
cleanup() {
|
|
159
|
+
if (this.lastLinesUp > 0) {
|
|
160
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
161
|
+
this.lastLinesUp = 0;
|
|
162
|
+
}
|
|
163
|
+
super.cleanup();
|
|
164
|
+
}
|
|
158
165
|
handleInput(char, _buffer) {
|
|
159
166
|
// Navigation
|
|
160
167
|
if (char === '\t') {
|
package/dist/prompts/file.d.ts
CHANGED
package/dist/prompts/file.js
CHANGED
|
@@ -147,6 +147,13 @@ class FilePrompt extends base_1.Prompt {
|
|
|
147
147
|
this.print(`\x1b[${targetCol}C`);
|
|
148
148
|
this.print(ansi_1.ANSI.SHOW_CURSOR);
|
|
149
149
|
}
|
|
150
|
+
cleanup() {
|
|
151
|
+
if (this.lastLinesUp > 0) {
|
|
152
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
153
|
+
this.lastLinesUp = 0;
|
|
154
|
+
}
|
|
155
|
+
super.cleanup();
|
|
156
|
+
}
|
|
150
157
|
handleInput(char) {
|
|
151
158
|
if (char === '\t') {
|
|
152
159
|
if (this.suggestions.length > 0) {
|
|
@@ -166,11 +173,6 @@ class FilePrompt extends base_1.Prompt {
|
|
|
166
173
|
return;
|
|
167
174
|
}
|
|
168
175
|
if (char === '\r' || char === '\n') {
|
|
169
|
-
// Move cursor to the bottom to ensure clean exit UI
|
|
170
|
-
if (this.lastLinesUp > 0) {
|
|
171
|
-
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
172
|
-
this.lastLinesUp = 0;
|
|
173
|
-
}
|
|
174
176
|
this.submit(this.input);
|
|
175
177
|
return;
|
|
176
178
|
}
|
package/dist/prompts/form.d.ts
CHANGED
package/dist/prompts/form.js
CHANGED
|
@@ -196,6 +196,13 @@ class FormPrompt extends base_1.Prompt {
|
|
|
196
196
|
this.render(false);
|
|
197
197
|
return true;
|
|
198
198
|
}
|
|
199
|
+
cleanup() {
|
|
200
|
+
if (this.lastLinesUp > 0) {
|
|
201
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
202
|
+
this.lastLinesUp = 0;
|
|
203
|
+
}
|
|
204
|
+
super.cleanup();
|
|
205
|
+
}
|
|
199
206
|
async submitForm() {
|
|
200
207
|
this.globalError = '';
|
|
201
208
|
// Validate all fields
|
package/dist/prompts/phone.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export declare class PhonePrompt extends Prompt<string, PhoneOptions> {
|
|
|
30
30
|
*/
|
|
31
31
|
private renderFormattedNumber;
|
|
32
32
|
protected render(firstRender: boolean): void;
|
|
33
|
+
protected cleanup(): void;
|
|
33
34
|
protected handleInput(char: string): void;
|
|
34
35
|
private filterCountries;
|
|
35
36
|
private cycleCountry;
|
package/dist/prompts/phone.js
CHANGED
|
@@ -206,6 +206,13 @@ class PhonePrompt extends base_1.Prompt {
|
|
|
206
206
|
}
|
|
207
207
|
this.print(ansi_1.ANSI.SHOW_CURSOR);
|
|
208
208
|
}
|
|
209
|
+
cleanup() {
|
|
210
|
+
if (this.lastLinesUp > 0) {
|
|
211
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
212
|
+
this.lastLinesUp = 0;
|
|
213
|
+
}
|
|
214
|
+
super.cleanup();
|
|
215
|
+
}
|
|
209
216
|
handleInput(char) {
|
|
210
217
|
// Handle common keys
|
|
211
218
|
if (char === '\r' || char === '\n') {
|
|
@@ -11,6 +11,7 @@ export declare class SnippetPrompt extends Prompt<string, SnippetOptions> {
|
|
|
11
11
|
constructor(options: SnippetOptions);
|
|
12
12
|
private parseTemplate;
|
|
13
13
|
protected render(firstRender: boolean): void;
|
|
14
|
+
protected cleanup(): void;
|
|
14
15
|
protected handleInput(char: string, _key: Buffer): void;
|
|
15
16
|
protected handleMouse(event: MouseEvent): void;
|
|
16
17
|
private moveFocus;
|
package/dist/prompts/snippet.js
CHANGED
|
@@ -114,6 +114,13 @@ class SnippetPrompt extends base_1.Prompt {
|
|
|
114
114
|
this.print(`\x1b[${cursorVisualIndex}C`);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
+
cleanup() {
|
|
118
|
+
if (this.lastLinesUp > 0) {
|
|
119
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
120
|
+
this.lastLinesUp = 0;
|
|
121
|
+
}
|
|
122
|
+
super.cleanup();
|
|
123
|
+
}
|
|
117
124
|
handleInput(char, _key) {
|
|
118
125
|
// Navigation: Tab / Shift+Tab
|
|
119
126
|
if (char === '\u001b[Z') {
|
package/dist/prompts/text.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare class TextPrompt<O extends TextOptions = TextOptions> extends Pro
|
|
|
11
11
|
private triggerSuggest;
|
|
12
12
|
protected render(firstRender: boolean): void;
|
|
13
13
|
private getSegmentWidth;
|
|
14
|
+
protected cleanup(): void;
|
|
14
15
|
protected handleInput(char: string): void;
|
|
15
16
|
private validateAndSubmit;
|
|
16
17
|
}
|
package/dist/prompts/text.js
CHANGED
|
@@ -179,6 +179,13 @@ class TextPrompt extends base_1.Prompt {
|
|
|
179
179
|
getSegmentWidth(seg) {
|
|
180
180
|
return (0, utils_1.stringWidth)(seg);
|
|
181
181
|
}
|
|
182
|
+
cleanup() {
|
|
183
|
+
if (this.lastLinesUp > 0) {
|
|
184
|
+
this.print(`\x1b[${this.lastLinesUp}B`);
|
|
185
|
+
this.lastLinesUp = 0;
|
|
186
|
+
}
|
|
187
|
+
super.cleanup();
|
|
188
|
+
}
|
|
182
189
|
handleInput(char) {
|
|
183
190
|
// Tab (Accept Suggestion)
|
|
184
191
|
if (char === '\t') {
|
package/dist/types.d.ts
CHANGED
|
@@ -190,7 +190,7 @@ export interface WaitOptions extends BaseOptions {
|
|
|
190
190
|
}
|
|
191
191
|
export interface CodeOptions extends BaseOptions {
|
|
192
192
|
template: string;
|
|
193
|
-
language?: 'json';
|
|
193
|
+
language?: 'json' | 'env' | 'toml' | 'csv' | 'sh' | 'bash' | 'zsh' | 'properties' | 'props' | 'conf';
|
|
194
194
|
/**
|
|
195
195
|
* Enable syntax highlighting (Experimental).
|
|
196
196
|
* @default true
|
package/dist/utils.js
CHANGED
|
@@ -20,7 +20,7 @@ function detectCapabilities() {
|
|
|
20
20
|
// Check if it is a TTY
|
|
21
21
|
const isTTY = process.stdout.isTTY;
|
|
22
22
|
const isWindows = process.platform === 'win32';
|
|
23
|
-
//
|
|
23
|
+
// Better Unicode detection logic
|
|
24
24
|
const isUnicodeSupported = () => {
|
|
25
25
|
// 1. Windows: Check specific environmental variables
|
|
26
26
|
if (isWindows) {
|