@readwise/cli 0.3.0 → 0.5.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/README.md +12 -11
- package/dist/config.d.ts +1 -0
- package/dist/index.js +11 -54
- package/dist/tui/app.js +875 -232
- package/dist/tui/term.js +45 -6
- package/package.json +3 -3
- package/src/config.ts +1 -0
- package/src/index.ts +10 -3
- package/src/tui/app.ts +849 -224
- package/src/tui/term.ts +41 -6
package/src/tui/term.ts
CHANGED
|
@@ -22,12 +22,16 @@ export const style = {
|
|
|
22
22
|
|
|
23
23
|
export function enterFullScreen(): void {
|
|
24
24
|
process.stdout.write(`${ESC}[?1049h`); // alternate screen buffer
|
|
25
|
+
process.stdout.write(`${ESC}[?2004h`); // enable bracketed paste mode
|
|
26
|
+
process.stdout.write(`${ESC}[>1u`); // enable kitty keyboard protocol (disambiguate mode)
|
|
25
27
|
process.stdout.write(`${ESC}[?25l`); // hide cursor
|
|
26
28
|
process.stdout.write(`${ESC}[H`); // cursor home
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
export function exitFullScreen(): void {
|
|
30
32
|
process.stdout.write(`${ESC}[?25h`); // show cursor
|
|
33
|
+
process.stdout.write(`${ESC}[<u`); // disable kitty keyboard protocol
|
|
34
|
+
process.stdout.write(`${ESC}[?2004l`); // disable bracketed paste mode
|
|
31
35
|
process.stdout.write(`${ESC}[?1049l`); // restore screen buffer
|
|
32
36
|
}
|
|
33
37
|
|
|
@@ -37,11 +41,12 @@ export function paint(lines: string[]): void {
|
|
|
37
41
|
let out = `${ESC}[H`; // cursor home
|
|
38
42
|
const count = Math.min(lines.length, rows);
|
|
39
43
|
for (let i = 0; i < count; i++) {
|
|
40
|
-
out += lines[i] + `${ESC}[K
|
|
44
|
+
out += lines[i] + `${ESC}[K`; // line content + clear to end of line
|
|
45
|
+
if (i < count - 1) out += "\n";
|
|
41
46
|
}
|
|
42
47
|
// Clear any remaining lines below content
|
|
43
48
|
if (count < rows) {
|
|
44
|
-
out +=
|
|
49
|
+
out += `\n${ESC}[J`; // clear from cursor to end of screen
|
|
45
50
|
}
|
|
46
51
|
process.stdout.write(out);
|
|
47
52
|
}
|
|
@@ -61,6 +66,25 @@ export interface KeyEvent {
|
|
|
61
66
|
|
|
62
67
|
export function parseKey(data: Buffer): KeyEvent {
|
|
63
68
|
const s = data.toString("utf-8");
|
|
69
|
+
|
|
70
|
+
// Bracketed paste: \x1b[200~ ... \x1b[201~
|
|
71
|
+
if (s.startsWith(`${ESC}[200~`)) {
|
|
72
|
+
const content = s.replace(/\x1b\[200~/g, "").replace(/\x1b\[201~/g, "");
|
|
73
|
+
const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
74
|
+
return { raw: normalized, name: "paste", shift: false, ctrl: false };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Alt+Enter (ESC + CR/LF) — reliable newline insertion across all terminals
|
|
78
|
+
if (s === `${ESC}\r` || s === `${ESC}\n`) {
|
|
79
|
+
return { raw: s, name: "return", shift: true, ctrl: false };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Alt+Arrow (word navigation)
|
|
83
|
+
if (s === `${ESC}[1;3D` || s === `${ESC}b`) return { raw: s, name: "wordLeft", shift: false, ctrl: false };
|
|
84
|
+
if (s === `${ESC}[1;3C` || s === `${ESC}f`) return { raw: s, name: "wordRight", shift: false, ctrl: false };
|
|
85
|
+
// Alt+Backspace (word delete)
|
|
86
|
+
if (s === `${ESC}\x7f`) return { raw: s, name: "wordBackspace", shift: false, ctrl: false };
|
|
87
|
+
|
|
64
88
|
const ctrl = s.length === 1 && s.charCodeAt(0) < 32;
|
|
65
89
|
|
|
66
90
|
// Escape sequences
|
|
@@ -73,10 +97,15 @@ export function parseKey(data: Buffer): KeyEvent {
|
|
|
73
97
|
if (s === `${ESC}[Z`) return { raw: s, name: "tab", shift: true, ctrl: false };
|
|
74
98
|
if (s === ESC || s === `${ESC}${ESC}`) return { raw: s, name: "escape", shift: false, ctrl: false };
|
|
75
99
|
|
|
76
|
-
//
|
|
77
|
-
if (s === `${ESC}[13;2u`) return { raw: s, name: "return", shift: true, ctrl: false }; //
|
|
78
|
-
if (s === `${ESC}[27;2;13~`) return { raw: s, name: "return", shift: true, ctrl: false }; // xterm
|
|
79
|
-
if (s === `${ESC}OM`) return { raw: s, name: "return", shift: true, ctrl: false }; // misc
|
|
100
|
+
// Kitty keyboard protocol CSI-u encodings (when disambiguate mode is active)
|
|
101
|
+
if (s === `${ESC}[13;2u`) return { raw: s, name: "return", shift: true, ctrl: false }; // Shift+Enter
|
|
102
|
+
if (s === `${ESC}[27;2;13~`) return { raw: s, name: "return", shift: true, ctrl: false }; // Shift+Enter (xterm)
|
|
103
|
+
if (s === `${ESC}OM`) return { raw: s, name: "return", shift: true, ctrl: false }; // Shift+Enter (misc)
|
|
104
|
+
if (s === `${ESC}[27u`) return { raw: s, name: "escape", shift: false, ctrl: false };
|
|
105
|
+
if (s === `${ESC}[13u`) return { raw: s, name: "return", shift: false, ctrl: false };
|
|
106
|
+
if (s === `${ESC}[9u`) return { raw: s, name: "tab", shift: false, ctrl: false };
|
|
107
|
+
if (s === `${ESC}[9;2u`) return { raw: s, name: "tab", shift: true, ctrl: false };
|
|
108
|
+
if (s === `${ESC}[127u`) return { raw: s, name: "backspace", shift: false, ctrl: false };
|
|
80
109
|
|
|
81
110
|
// Single characters
|
|
82
111
|
if (s === "\r" || s === "\n") return { raw: s, name: "return", shift: false, ctrl: false };
|
|
@@ -89,6 +118,12 @@ export function parseKey(data: Buffer): KeyEvent {
|
|
|
89
118
|
return { raw: s, name: String.fromCharCode(s.charCodeAt(0) + 96), shift: false, ctrl: true };
|
|
90
119
|
}
|
|
91
120
|
|
|
121
|
+
// Multi-character non-escape input = paste (terminal without bracketed paste support)
|
|
122
|
+
if (s.length > 1 && !s.startsWith(ESC)) {
|
|
123
|
+
const normalized = s.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
124
|
+
return { raw: normalized, name: "paste", shift: false, ctrl: false };
|
|
125
|
+
}
|
|
126
|
+
|
|
92
127
|
return { raw: s, name: s, shift: false, ctrl: false };
|
|
93
128
|
}
|
|
94
129
|
|