mepcli 0.6.1 → 1.0.0-beta.2
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/LICENSE +21 -21
- package/README.md +512 -326
- package/dist/ansi.d.ts +8 -0
- package/dist/ansi.js +8 -0
- package/dist/base.d.ts +21 -0
- package/dist/base.js +57 -0
- package/dist/core.d.ts +48 -1
- package/dist/core.js +156 -0
- package/dist/data/licenses.d.ts +2 -0
- package/dist/data/licenses.js +109 -0
- package/dist/highlight.js +58 -26
- package/dist/index.d.ts +36 -0
- package/dist/index.js +36 -0
- package/dist/input.js +0 -3
- package/dist/prompts/box.d.ts +21 -0
- package/dist/prompts/box.js +192 -0
- package/dist/prompts/breadcrumb.d.ts +22 -0
- package/dist/prompts/breadcrumb.js +302 -0
- package/dist/prompts/byte.d.ts +13 -0
- package/dist/prompts/byte.js +159 -0
- package/dist/prompts/calculator.d.ts +16 -0
- package/dist/prompts/calculator.js +213 -0
- package/dist/prompts/calendar.js +0 -5
- package/dist/prompts/code.d.ts +2 -0
- package/dist/prompts/code.js +104 -70
- package/dist/prompts/connection-string.d.ts +18 -0
- package/dist/prompts/connection-string.js +97 -0
- package/dist/prompts/curl.d.ts +39 -0
- package/dist/prompts/curl.js +285 -0
- package/dist/prompts/data-inspector.d.ts +22 -0
- package/dist/prompts/data-inspector.js +256 -0
- package/dist/prompts/dependency.d.ts +16 -0
- package/dist/prompts/dependency.js +265 -0
- package/dist/prompts/dial.d.ts +10 -0
- package/dist/prompts/dial.js +110 -0
- package/dist/prompts/diff.d.ts +10 -0
- package/dist/prompts/diff.js +101 -0
- package/dist/prompts/draw.d.ts +20 -0
- package/dist/prompts/draw.js +188 -0
- package/dist/prompts/editor.js +0 -4
- package/dist/prompts/emoji.d.ts +18 -0
- package/dist/prompts/emoji.js +228 -0
- package/dist/prompts/exec.d.ts +13 -0
- package/dist/prompts/exec.js +83 -0
- package/dist/prompts/fuzzy.d.ts +12 -0
- package/dist/prompts/fuzzy.js +136 -0
- package/dist/prompts/gauge.d.ts +21 -0
- package/dist/prompts/gauge.js +130 -0
- package/dist/prompts/heatmap.d.ts +13 -0
- package/dist/prompts/heatmap.js +141 -0
- package/dist/prompts/ip.d.ts +11 -0
- package/dist/prompts/ip.js +118 -0
- package/dist/prompts/kanban.d.ts +17 -0
- package/dist/prompts/kanban.js +228 -0
- package/dist/prompts/keypress.js +0 -2
- package/dist/prompts/license.d.ts +9 -0
- package/dist/prompts/license.js +105 -0
- package/dist/prompts/map.d.ts +15 -0
- package/dist/prompts/map.js +199 -0
- package/dist/prompts/match.d.ts +19 -0
- package/dist/prompts/match.js +275 -0
- package/dist/prompts/miller.d.ts +15 -0
- package/dist/prompts/miller.js +221 -0
- package/dist/prompts/multi-column-select.d.ts +10 -0
- package/dist/prompts/multi-column-select.js +166 -0
- package/dist/prompts/number.js +0 -2
- package/dist/prompts/otp.d.ts +10 -0
- package/dist/prompts/otp.js +91 -0
- package/dist/prompts/pattern.d.ts +22 -0
- package/dist/prompts/pattern.js +249 -0
- package/dist/prompts/quiz-select.d.ts +10 -0
- package/dist/prompts/quiz-select.js +104 -0
- package/dist/prompts/quiz-text.d.ts +11 -0
- package/dist/prompts/quiz-text.js +82 -0
- package/dist/prompts/regex.d.ts +13 -0
- package/dist/prompts/regex.js +131 -0
- package/dist/prompts/region.d.ts +11 -0
- package/dist/prompts/region.js +164 -0
- package/dist/prompts/schedule.d.ts +18 -0
- package/dist/prompts/schedule.js +221 -0
- package/dist/prompts/scroll.d.ts +13 -0
- package/dist/prompts/scroll.js +152 -0
- package/dist/prompts/seat.d.ts +17 -0
- package/dist/prompts/seat.js +165 -0
- package/dist/prompts/select-range.d.ts +8 -0
- package/dist/prompts/select-range.js +136 -0
- package/dist/prompts/select.d.ts +9 -9
- package/dist/prompts/semver.d.ts +6 -0
- package/dist/prompts/semver.js +32 -0
- package/dist/prompts/shortcut.d.ts +9 -0
- package/dist/prompts/shortcut.js +135 -0
- package/dist/prompts/slot.d.ts +16 -0
- package/dist/prompts/slot.js +107 -0
- package/dist/prompts/snippet.js +0 -3
- package/dist/prompts/sort-grid.d.ts +16 -0
- package/dist/prompts/sort-grid.js +146 -0
- package/dist/prompts/sort.js +0 -1
- package/dist/prompts/spreadsheet.d.ts +21 -0
- package/dist/prompts/spreadsheet.js +239 -0
- package/dist/prompts/text.d.ts +9 -7
- package/dist/prompts/text.js +52 -0
- package/dist/prompts/time.d.ts +12 -0
- package/dist/prompts/time.js +202 -0
- package/dist/prompts/tree-select.d.ts +0 -1
- package/dist/prompts/tree-select.js +1 -5
- package/dist/symbols.d.ts +12 -0
- package/dist/symbols.js +14 -2
- package/dist/theme.js +10 -1
- package/dist/types.d.ts +264 -1
- package/dist/utils.d.ts +53 -0
- package/dist/utils.js +252 -0
- package/package.json +51 -47
- package/example.ts +0 -390
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ShortcutPrompt = void 0;
|
|
4
|
+
const base_1 = require("../base");
|
|
5
|
+
const ansi_1 = require("../ansi");
|
|
6
|
+
const theme_1 = require("../theme");
|
|
7
|
+
class ShortcutPrompt extends base_1.Prompt {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super(options);
|
|
10
|
+
this.currentKey = options.initial;
|
|
11
|
+
}
|
|
12
|
+
render(_firstRender) {
|
|
13
|
+
let text = `${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET} `;
|
|
14
|
+
if (this.currentKey) {
|
|
15
|
+
const parts = [];
|
|
16
|
+
if (this.currentKey.ctrl)
|
|
17
|
+
parts.push(`${ansi_1.ANSI.REVERSE} Ctrl ${ansi_1.ANSI.RESET}`);
|
|
18
|
+
if (this.currentKey.meta)
|
|
19
|
+
parts.push(`${ansi_1.ANSI.REVERSE} Alt ${ansi_1.ANSI.RESET}`);
|
|
20
|
+
if (this.currentKey.shift)
|
|
21
|
+
parts.push(`${ansi_1.ANSI.REVERSE} Shift ${ansi_1.ANSI.RESET}`);
|
|
22
|
+
if (this.currentKey.name) {
|
|
23
|
+
parts.push(`${ansi_1.ANSI.FG_CYAN}[${this.currentKey.name}]${ansi_1.ANSI.RESET}`);
|
|
24
|
+
}
|
|
25
|
+
text += parts.join(' + ');
|
|
26
|
+
text += ` ${theme_1.theme.muted}(Press Enter to confirm)${ansi_1.ANSI.RESET}`;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
text += `${theme_1.theme.muted}Press any key combination...${ansi_1.ANSI.RESET}`;
|
|
30
|
+
}
|
|
31
|
+
this.renderFrame(text);
|
|
32
|
+
}
|
|
33
|
+
handleInput(char, buffer) {
|
|
34
|
+
const raw = buffer.toString();
|
|
35
|
+
// Enter to confirm
|
|
36
|
+
if (char === '\r' || char === '\n') {
|
|
37
|
+
if (this.currentKey) {
|
|
38
|
+
this.submit(this.currentKey);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Parse the key
|
|
43
|
+
const parsed = this.parseKey(char, raw);
|
|
44
|
+
if (parsed) {
|
|
45
|
+
this.currentKey = parsed;
|
|
46
|
+
this.render(false);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
parseKey(char, raw) {
|
|
50
|
+
let name = '';
|
|
51
|
+
let ctrl = false;
|
|
52
|
+
let meta = false;
|
|
53
|
+
let shift = false;
|
|
54
|
+
const code = raw.charCodeAt(0);
|
|
55
|
+
// Control Keys (1-26, except Backspace, Tab, Enter, Esc)
|
|
56
|
+
if (code >= 1 && code <= 26) {
|
|
57
|
+
// Exclude special control codes
|
|
58
|
+
if (char === '\t') { // Ctrl+I
|
|
59
|
+
name = 'Tab';
|
|
60
|
+
}
|
|
61
|
+
else if (char === '\n' || char === '\r') { // Ctrl+J / Ctrl+M
|
|
62
|
+
name = 'Enter';
|
|
63
|
+
}
|
|
64
|
+
else if (char === '\b') { // Ctrl+H
|
|
65
|
+
name = 'Backspace';
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
ctrl = true;
|
|
69
|
+
name = String.fromCharCode(code + 64); // 1 -> 'A'
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (code === 27) { // Escape
|
|
73
|
+
if (raw.length === 1) {
|
|
74
|
+
name = 'Escape';
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Sequence starting with ESC
|
|
78
|
+
meta = true; // Assume Alt for ESC+Char
|
|
79
|
+
if (raw.length === 2) {
|
|
80
|
+
// Alt + Char
|
|
81
|
+
name = raw[1].toUpperCase();
|
|
82
|
+
// Check shift for Alt+Shift+Char logic?
|
|
83
|
+
if (raw[1] >= 'A' && raw[1] <= 'Z')
|
|
84
|
+
shift = true;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// CSI sequences
|
|
88
|
+
meta = false; // Usually these are navigation
|
|
89
|
+
if (raw === '\u001b[A')
|
|
90
|
+
name = 'Up';
|
|
91
|
+
else if (raw === '\u001b[B')
|
|
92
|
+
name = 'Down';
|
|
93
|
+
else if (raw === '\u001b[C')
|
|
94
|
+
name = 'Right';
|
|
95
|
+
else if (raw === '\u001b[D')
|
|
96
|
+
name = 'Left';
|
|
97
|
+
else if (raw === '\u001b[H')
|
|
98
|
+
name = 'Home';
|
|
99
|
+
else if (raw === '\u001b[F')
|
|
100
|
+
name = 'End';
|
|
101
|
+
else if (raw === '\u001b[3~')
|
|
102
|
+
name = 'Delete';
|
|
103
|
+
else if (raw === '\u001b[Z') {
|
|
104
|
+
name = 'Tab';
|
|
105
|
+
shift = true;
|
|
106
|
+
} // Shift+Tab
|
|
107
|
+
else {
|
|
108
|
+
name = 'Unknown';
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (code === 127) {
|
|
114
|
+
name = 'Backspace';
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// Regular char
|
|
118
|
+
name = char.toUpperCase();
|
|
119
|
+
if (char >= 'A' && char <= 'Z')
|
|
120
|
+
shift = true;
|
|
121
|
+
if (char === ' ')
|
|
122
|
+
name = 'Space';
|
|
123
|
+
// Special Symbols map?
|
|
124
|
+
// Keep it simple for now.
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
name,
|
|
128
|
+
ctrl,
|
|
129
|
+
shift,
|
|
130
|
+
meta,
|
|
131
|
+
sequence: raw
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.ShortcutPrompt = ShortcutPrompt;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Prompt } from '../base';
|
|
2
|
+
import { SlotOptions } from '../types';
|
|
3
|
+
export declare class SlotPrompt extends Prompt<string, SlotOptions> {
|
|
4
|
+
private selectedIndex;
|
|
5
|
+
private isSpinning;
|
|
6
|
+
private isStopping;
|
|
7
|
+
private spinSpeed;
|
|
8
|
+
private spinTimer?;
|
|
9
|
+
private rows;
|
|
10
|
+
constructor(options: SlotOptions);
|
|
11
|
+
private spin;
|
|
12
|
+
private finish;
|
|
13
|
+
protected handleInput(char: string, _key: Buffer): void;
|
|
14
|
+
protected render(_firstRender: boolean): void;
|
|
15
|
+
protected cleanup(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SlotPrompt = void 0;
|
|
4
|
+
const ansi_1 = require("../ansi");
|
|
5
|
+
const base_1 = require("../base");
|
|
6
|
+
const theme_1 = require("../theme");
|
|
7
|
+
const symbols_1 = require("../symbols");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
class SlotPrompt extends base_1.Prompt {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
super(options);
|
|
12
|
+
this.isSpinning = false;
|
|
13
|
+
this.isStopping = false;
|
|
14
|
+
this.spinSpeed = 50; // Initial speed (ms)
|
|
15
|
+
this.rows = options.rows || 3;
|
|
16
|
+
// Ensure rows is odd to have a center
|
|
17
|
+
if (this.rows % 2 === 0)
|
|
18
|
+
this.rows++;
|
|
19
|
+
this.selectedIndex = options.initial || 0;
|
|
20
|
+
}
|
|
21
|
+
spin() {
|
|
22
|
+
if (!this.isSpinning)
|
|
23
|
+
return;
|
|
24
|
+
this.selectedIndex = (this.selectedIndex + 1) % this.options.choices.length;
|
|
25
|
+
this.render(false);
|
|
26
|
+
if (this.isStopping) {
|
|
27
|
+
// Deceleration physics
|
|
28
|
+
this.spinSpeed = Math.floor(this.spinSpeed * 1.1);
|
|
29
|
+
if (this.spinSpeed > 400) {
|
|
30
|
+
this.isSpinning = false;
|
|
31
|
+
this.finish();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.spinTimer = setTimeout(() => this.spin(), this.spinSpeed);
|
|
36
|
+
}
|
|
37
|
+
finish() {
|
|
38
|
+
if (this.spinTimer)
|
|
39
|
+
clearTimeout(this.spinTimer);
|
|
40
|
+
this.submit(this.options.choices[this.selectedIndex]);
|
|
41
|
+
}
|
|
42
|
+
handleInput(char, _key) {
|
|
43
|
+
if (char === ' ' || char === '\r' || char === '\n') {
|
|
44
|
+
if (!this.isSpinning) {
|
|
45
|
+
// Start spinning
|
|
46
|
+
this.isSpinning = true;
|
|
47
|
+
this.isStopping = false;
|
|
48
|
+
this.spinSpeed = 50; // Reset speed
|
|
49
|
+
this.spin();
|
|
50
|
+
}
|
|
51
|
+
else if (!this.isStopping) {
|
|
52
|
+
// Initiate stop sequence
|
|
53
|
+
this.isStopping = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
render(_firstRender) {
|
|
58
|
+
let output = '';
|
|
59
|
+
// Header
|
|
60
|
+
output += `${theme_1.theme.success}?${ansi_1.ANSI.RESET} ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
|
|
61
|
+
// Calculate dynamic width
|
|
62
|
+
const maxLen = Math.max(...this.options.choices.map(c => (0, utils_1.stringWidth)(c)));
|
|
63
|
+
const boxWidth = Math.max(20, maxLen + 6);
|
|
64
|
+
const border = symbols_1.symbols.line.repeat(boxWidth - 2);
|
|
65
|
+
output += `┌${border}┐\n`;
|
|
66
|
+
const centerRow = Math.floor(this.rows / 2);
|
|
67
|
+
for (let i = 0; i < this.rows; i++) {
|
|
68
|
+
const offset = i - centerRow;
|
|
69
|
+
let index = (this.selectedIndex + offset) % this.options.choices.length;
|
|
70
|
+
if (index < 0)
|
|
71
|
+
index += this.options.choices.length;
|
|
72
|
+
const item = this.options.choices[index];
|
|
73
|
+
const content = this.truncate(item, boxWidth - 4);
|
|
74
|
+
const contentWidth = (0, utils_1.stringWidth)(content);
|
|
75
|
+
const padding = boxWidth - 4 - contentWidth;
|
|
76
|
+
const leftPad = ' '.repeat(Math.floor(padding / 2));
|
|
77
|
+
const rightPad = ' '.repeat(Math.ceil(padding / 2));
|
|
78
|
+
const lineContent = `${leftPad}${content}${rightPad}`;
|
|
79
|
+
if (i === centerRow) {
|
|
80
|
+
// Highlight
|
|
81
|
+
output += `│ ${theme_1.theme.main}${ansi_1.ANSI.REVERSE} ${lineContent} ${ansi_1.ANSI.RESET} │ ${theme_1.theme.main}◄${ansi_1.ANSI.RESET}\n`;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
output += `│ ${lineContent} │\n`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
output += `└${border}┘`;
|
|
88
|
+
// Instructions
|
|
89
|
+
if (!this.isSpinning) {
|
|
90
|
+
output += `\n${theme_1.theme.muted}(Press Space/Enter to Spin)${ansi_1.ANSI.RESET}`;
|
|
91
|
+
}
|
|
92
|
+
else if (this.isStopping) {
|
|
93
|
+
output += `\n${theme_1.theme.muted}(Stopping...)${ansi_1.ANSI.RESET}`;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
output += `\n${theme_1.theme.muted}(Press Space/Enter to Stop)${ansi_1.ANSI.RESET}`;
|
|
97
|
+
}
|
|
98
|
+
this.renderFrame(output);
|
|
99
|
+
}
|
|
100
|
+
// Override cleanup to ensure timer is cleared if user Ctrl+C
|
|
101
|
+
cleanup() {
|
|
102
|
+
if (this.spinTimer)
|
|
103
|
+
clearTimeout(this.spinTimer);
|
|
104
|
+
super.cleanup();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.SlotPrompt = SlotPrompt;
|
package/dist/prompts/snippet.js
CHANGED
|
@@ -59,9 +59,6 @@ class SnippetPrompt extends base_1.Prompt {
|
|
|
59
59
|
// Prefix/Message
|
|
60
60
|
const prefix = `${theme_1.theme.success}? ${ansi_1.ANSI.BOLD}${theme_1.theme.title}${this.options.message || 'Fill snippet'}${ansi_1.ANSI.RESET}\n`;
|
|
61
61
|
output += prefix;
|
|
62
|
-
// cursorVisualIndex should start after prefix?
|
|
63
|
-
// Actually renderFrame handles newlines.
|
|
64
|
-
// We will construct the snippet line.
|
|
65
62
|
let snippetLine = '';
|
|
66
63
|
this.tokens.forEach((token, index) => {
|
|
67
64
|
if (token.type === 'static') {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Prompt } from '../base';
|
|
2
|
+
import { SortGridOptions, MouseEvent } from '../types';
|
|
3
|
+
export declare class SortGridPrompt extends Prompt<string[][], SortGridOptions> {
|
|
4
|
+
protected cursorX: number;
|
|
5
|
+
protected cursorY: number;
|
|
6
|
+
protected grabbedX: number | null;
|
|
7
|
+
protected grabbedY: number | null;
|
|
8
|
+
private gridData;
|
|
9
|
+
private columnWidths;
|
|
10
|
+
constructor(options: SortGridOptions);
|
|
11
|
+
private calculateLayout;
|
|
12
|
+
protected render(_firstRender: boolean): void;
|
|
13
|
+
protected handleInput(char: string, _key: Buffer): void;
|
|
14
|
+
protected handleMouse(event: MouseEvent): void;
|
|
15
|
+
protected move(direction: 'up' | 'down' | 'left' | 'right'): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SortGridPrompt = void 0;
|
|
4
|
+
const ansi_1 = require("../ansi");
|
|
5
|
+
const base_1 = require("../base");
|
|
6
|
+
const theme_1 = require("../theme");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
class SortGridPrompt extends base_1.Prompt {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
super(options);
|
|
11
|
+
this.cursorX = 0;
|
|
12
|
+
this.cursorY = 0;
|
|
13
|
+
this.grabbedX = null;
|
|
14
|
+
this.grabbedY = null;
|
|
15
|
+
this.columnWidths = [];
|
|
16
|
+
// Deep copy grid data
|
|
17
|
+
this.gridData = options.data.map(row => [...row]);
|
|
18
|
+
this.calculateLayout();
|
|
19
|
+
}
|
|
20
|
+
calculateLayout() {
|
|
21
|
+
const rows = this.gridData.length;
|
|
22
|
+
if (rows === 0)
|
|
23
|
+
return;
|
|
24
|
+
// Assume consistent column count, use max found if ragged
|
|
25
|
+
const cols = this.gridData.reduce((max, row) => Math.max(max, row.length), 0);
|
|
26
|
+
this.columnWidths = new Array(cols).fill(0);
|
|
27
|
+
for (let r = 0; r < rows; r++) {
|
|
28
|
+
for (let c = 0; c < this.gridData[r].length; c++) {
|
|
29
|
+
const cell = this.gridData[r][c] || '';
|
|
30
|
+
this.columnWidths[c] = Math.max(this.columnWidths[c], (0, utils_1.stringWidth)(cell) + 2); // +2 padding
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
render(_firstRender) {
|
|
35
|
+
this.calculateLayout();
|
|
36
|
+
let output = `${theme_1.theme.title}${this.options.message}${ansi_1.ANSI.RESET}\n`;
|
|
37
|
+
this.gridData.forEach((row, r) => {
|
|
38
|
+
const rowStr = row.map((cell, c) => {
|
|
39
|
+
const width = this.columnWidths[c] || (0, utils_1.stringWidth)(cell) + 2;
|
|
40
|
+
const content = cell || '';
|
|
41
|
+
// Padding
|
|
42
|
+
const padding = Math.max(0, width - (0, utils_1.stringWidth)(content));
|
|
43
|
+
const leftPad = Math.floor(padding / 2);
|
|
44
|
+
const rightPad = padding - leftPad;
|
|
45
|
+
let cellStr = ' '.repeat(leftPad) + content + ' '.repeat(rightPad);
|
|
46
|
+
// Styling
|
|
47
|
+
const isFocused = (r === this.cursorY && c === this.cursorX);
|
|
48
|
+
const isGrabbed = (r === this.grabbedY && c === this.grabbedX);
|
|
49
|
+
if (isGrabbed) {
|
|
50
|
+
// Grabbed item style
|
|
51
|
+
cellStr = `${ansi_1.ANSI.BG_RED}${ansi_1.ANSI.FG_WHITE}${cellStr}${ansi_1.ANSI.RESET}`;
|
|
52
|
+
}
|
|
53
|
+
else if (isFocused) {
|
|
54
|
+
// Focused item style
|
|
55
|
+
cellStr = `${ansi_1.ANSI.REVERSE}${cellStr}${ansi_1.ANSI.RESET}`;
|
|
56
|
+
}
|
|
57
|
+
return cellStr;
|
|
58
|
+
}).join(' '); // Space between columns
|
|
59
|
+
output += rowStr + '\n';
|
|
60
|
+
});
|
|
61
|
+
output += `${theme_1.theme.muted}Arrows to move, Space to grab/drop, Enter to submit${ansi_1.ANSI.RESET}`;
|
|
62
|
+
this.renderFrame(output);
|
|
63
|
+
}
|
|
64
|
+
handleInput(char, _key) {
|
|
65
|
+
if (char === '\r' || char === '\n') {
|
|
66
|
+
if (this.grabbedX !== null) {
|
|
67
|
+
this.grabbedX = null;
|
|
68
|
+
this.grabbedY = null;
|
|
69
|
+
}
|
|
70
|
+
this.submit(this.gridData);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (char === ' ') {
|
|
74
|
+
if (this.grabbedX === null) {
|
|
75
|
+
// Grab
|
|
76
|
+
this.grabbedX = this.cursorX;
|
|
77
|
+
this.grabbedY = this.cursorY;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Drop
|
|
81
|
+
this.grabbedX = null;
|
|
82
|
+
this.grabbedY = null;
|
|
83
|
+
}
|
|
84
|
+
this.render(false);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const isUp = this.isUp(char);
|
|
88
|
+
const isDown = this.isDown(char);
|
|
89
|
+
const isLeft = this.isLeft(char);
|
|
90
|
+
const isRight = this.isRight(char);
|
|
91
|
+
const isTab = char === '\t';
|
|
92
|
+
const isShiftTab = char === '\u001b[Z';
|
|
93
|
+
if (isUp)
|
|
94
|
+
this.move('up');
|
|
95
|
+
if (isDown)
|
|
96
|
+
this.move('down');
|
|
97
|
+
if (isLeft || isShiftTab)
|
|
98
|
+
this.move('left');
|
|
99
|
+
if (isRight || isTab)
|
|
100
|
+
this.move('right');
|
|
101
|
+
}
|
|
102
|
+
handleMouse(event) {
|
|
103
|
+
if (event.scroll === 'up') {
|
|
104
|
+
this.move('up');
|
|
105
|
+
}
|
|
106
|
+
else if (event.scroll === 'down') {
|
|
107
|
+
this.move('down');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
move(direction) {
|
|
111
|
+
if (this.gridData.length === 0)
|
|
112
|
+
return;
|
|
113
|
+
const oldX = this.cursorX;
|
|
114
|
+
const oldY = this.cursorY;
|
|
115
|
+
if (direction === 'up')
|
|
116
|
+
this.cursorY = Math.max(0, this.cursorY - 1);
|
|
117
|
+
if (direction === 'down')
|
|
118
|
+
this.cursorY = Math.min(this.gridData.length - 1, this.cursorY + 1);
|
|
119
|
+
// Clamp cursorX if we moved to a shorter row
|
|
120
|
+
if (this.gridData.length > 0) {
|
|
121
|
+
const rowLen = this.gridData[this.cursorY] ? this.gridData[this.cursorY].length : 0;
|
|
122
|
+
if (this.cursorX >= rowLen)
|
|
123
|
+
this.cursorX = Math.max(0, rowLen - 1);
|
|
124
|
+
}
|
|
125
|
+
if (direction === 'left')
|
|
126
|
+
this.cursorX = Math.max(0, this.cursorX - 1);
|
|
127
|
+
if (direction === 'right') {
|
|
128
|
+
const rowLen = this.gridData.length > 0 && this.gridData[this.cursorY] ? this.gridData[this.cursorY].length : 0;
|
|
129
|
+
this.cursorX = Math.min(rowLen - 1, this.cursorX + 1);
|
|
130
|
+
}
|
|
131
|
+
// If Grabbed, swap content
|
|
132
|
+
if (this.grabbedX !== null) {
|
|
133
|
+
// If we moved
|
|
134
|
+
if (oldX !== this.cursorX || oldY !== this.cursorY) {
|
|
135
|
+
const valA = this.gridData[oldY][oldX];
|
|
136
|
+
const valB = this.gridData[this.cursorY][this.cursorX];
|
|
137
|
+
this.gridData[oldY][oldX] = valB;
|
|
138
|
+
this.gridData[this.cursorY][this.cursorX] = valA;
|
|
139
|
+
this.grabbedX = this.cursorX;
|
|
140
|
+
this.grabbedY = this.cursorY;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
this.render(false);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.SortGridPrompt = SortGridPrompt;
|
package/dist/prompts/sort.js
CHANGED
|
@@ -58,7 +58,6 @@ class SortPrompt extends base_1.Prompt {
|
|
|
58
58
|
else if (isSelected) {
|
|
59
59
|
content = `${theme_1.theme.main}${content}${ansi_1.ANSI.RESET}`;
|
|
60
60
|
}
|
|
61
|
-
// Index indicator? Maybe not needed, minimalist.
|
|
62
61
|
output += `${prefix}${content}`;
|
|
63
62
|
});
|
|
64
63
|
this.renderFrame(output);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Prompt } from '../base';
|
|
2
|
+
import { SpreadsheetOptions, MouseEvent } from '../types';
|
|
3
|
+
export declare class SpreadsheetPrompt extends Prompt<Record<string, any>[], SpreadsheetOptions> {
|
|
4
|
+
private cursorRow;
|
|
5
|
+
private cursorCol;
|
|
6
|
+
private scrollRow;
|
|
7
|
+
private scrollCol;
|
|
8
|
+
private editMode;
|
|
9
|
+
private tempValue;
|
|
10
|
+
private colWidths;
|
|
11
|
+
private viewportHeight;
|
|
12
|
+
constructor(options: SpreadsheetOptions);
|
|
13
|
+
private calculateColWidths;
|
|
14
|
+
protected render(_firstRender: boolean): void;
|
|
15
|
+
private pad;
|
|
16
|
+
protected handleInput(char: string, _key: Buffer): void;
|
|
17
|
+
private handleNavInput;
|
|
18
|
+
private startEditing;
|
|
19
|
+
private handleEditInput;
|
|
20
|
+
protected handleMouse(event: MouseEvent): void;
|
|
21
|
+
}
|