phewsh 0.15.55 → 0.15.56
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/lib/md.js +41 -4
- package/package.json +1 -1
package/lib/md.js
CHANGED
|
@@ -33,6 +33,43 @@ function inlineMd(t, base = '') {
|
|
|
33
33
|
(_, x, u) => `${A.uline}${A.teal}${x}${A.reset}${base} ${A.dim}${A.slate}(${u})${A.reset}${base}`);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// Soft-wrap a rendered line at word boundaries to the terminal width — this is
|
|
37
|
+
// what replaces the terminal's mid-word hard wrap (CSS `text-wrap: pretty`, in
|
|
38
|
+
// spirit). We never break inside a word. `base` is the block's colour SGR,
|
|
39
|
+
// re-emitted at the start of each continuation line so colour survives the
|
|
40
|
+
// break; `hang` is the continuation indent (hanging indent under list/quote
|
|
41
|
+
// markers). No-op when width is unknown (piped output) so redirected text and
|
|
42
|
+
// tests stay raw.
|
|
43
|
+
const ANSI = /\x1b\[[0-9;]*m/g;
|
|
44
|
+
const vis = (s) => s.replace(ANSI, '').length;
|
|
45
|
+
|
|
46
|
+
function softWrap(s, base = '', hang) {
|
|
47
|
+
const width = process.stdout.columns;
|
|
48
|
+
if (!width || width < 24 || vis(s) <= width) return s;
|
|
49
|
+
const lead = s.match(/^ */)[0].length;
|
|
50
|
+
const indent = hang == null ? lead : hang;
|
|
51
|
+
const words = s.slice(lead).split(/ +/);
|
|
52
|
+
const pad = ' '.repeat(indent);
|
|
53
|
+
const out = [];
|
|
54
|
+
let cur = ' '.repeat(lead);
|
|
55
|
+
let len = lead;
|
|
56
|
+
let started = false;
|
|
57
|
+
for (const word of words) {
|
|
58
|
+
const wl = vis(word);
|
|
59
|
+
if (started && len + 1 + wl > width) {
|
|
60
|
+
out.push(cur + A.reset);
|
|
61
|
+
cur = base + pad + word;
|
|
62
|
+
len = indent + wl;
|
|
63
|
+
} else {
|
|
64
|
+
cur += (started ? ' ' : '') + word;
|
|
65
|
+
len += (started ? 1 : 0) + wl;
|
|
66
|
+
started = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
out.push(cur);
|
|
70
|
+
return out.join('\n');
|
|
71
|
+
}
|
|
72
|
+
|
|
36
73
|
// Render one complete line, mutating `state` for block-level context.
|
|
37
74
|
// Body text keeps the default terminal foreground (bright) — only structural
|
|
38
75
|
// elements get colour, so a reply reads as a reply, not as dimmed UI chrome.
|
|
@@ -47,12 +84,12 @@ function renderLine(line, state = {}) {
|
|
|
47
84
|
}
|
|
48
85
|
if (/^#{1,2}\s/.test(line)) return `\n${A.bold}${A.teal}${inlineMd(line.replace(/^#+\s*/, ''), A.teal)}${A.reset}`;
|
|
49
86
|
if (/^#{3,}\s/.test(line)) return `${A.cream}${inlineMd(line.replace(/^#+\s*/, ''), A.cream)}${A.reset}`;
|
|
50
|
-
if (/^\s*[-*]\s/.test(line)) return ` ${A.teal}·${A.reset} ${A.sage}${inlineMd(line.replace(/^\s*[-*]\s*/, ''), A.sage)}${A.reset}
|
|
51
|
-
if (/^\s*\d+\.\s/.test(line)) return ` ${A.sage}${inlineMd(line.trim(), A.sage)}${A.reset}
|
|
52
|
-
if (/^\s*>\s?/.test(line)) return ` ${A.slate}${A.ital}${inlineMd(line.replace(/^\s*>\s?/, ''), A.slate)}${A.italOff}${A.reset}
|
|
87
|
+
if (/^\s*[-*]\s/.test(line)) return softWrap(` ${A.teal}·${A.reset} ${A.sage}${inlineMd(line.replace(/^\s*[-*]\s*/, ''), A.sage)}${A.reset}`, A.sage, 4);
|
|
88
|
+
if (/^\s*\d+\.\s/.test(line)) return softWrap(` ${A.sage}${inlineMd(line.trim(), A.sage)}${A.reset}`, A.sage, 5);
|
|
89
|
+
if (/^\s*>\s?/.test(line)) return softWrap(` ${A.slate}${A.ital}${inlineMd(line.replace(/^\s*>\s?/, ''), A.slate)}${A.italOff}${A.reset}`, A.slate, 4);
|
|
53
90
|
if (/^---+\s*$/.test(line)) return ` ${A.slate}${'─'.repeat(40)}${A.reset}`;
|
|
54
91
|
if (line.trim() === '') return '';
|
|
55
|
-
return inlineMd(line, ''); // body: default foreground, inline styling only
|
|
92
|
+
return softWrap(inlineMd(line, ''), '', 0); // body: default foreground, inline styling only
|
|
56
93
|
}
|
|
57
94
|
|
|
58
95
|
// Line-buffered streaming renderer. Feed raw token text via push(); each time a
|