fix: keep stream write-head on tip glyph, not next-line col0 (0.9.29)

Appending the scanning caret after trailing newlines parked a lonely
block at the left margin. Overlay the tip character instead and let the
decode crest sweep through the wake.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-29 19:15:01 +08:00
co-authored by Cursor
parent 6d2e106e26
commit 67b9d6683f
2 changed files with 31 additions and 31 deletions
+30 -30
View File
@@ -1051,8 +1051,8 @@ static char *glitch_stream_frontier(const char *src, int spin) {
const int ncaret = g_ascii ? (int)(sizeof(asc_caret) / sizeof(asc_caret[0]))
: (int)(sizeof(uni_caret) / sizeof(uni_caret[0]));
/* Traveling decode head — a soft sine along the wake. */
int wave = spin % (nv + 8);
/* Traveling decode crest — sweeps from older wake toward the tip. */
int wave = (spin * 2) % (nv + 6);
size_t o = 0;
size_t cursor = 0;
@@ -1065,62 +1065,62 @@ static char *glitch_stream_frontier(const char *src, int spin) {
int age = nv - 1 - v; /* 0 = newest (tip) */
unsigned h = glitch_mix((unsigned)spin * 131u + (unsigned)v * 17u +
(unsigned)st * 3u);
int on_wave = (age >= wave - 1 && age <= wave + 2);
int on_wave = (age >= wave - 2 && age <= wave + 1);
if (age <= 2) {
/* Plasma tip: bright cyan decode glyphs. */
if (age == 0) {
/* Write head sits ON the tip glyph (never appended after a newline,
* which would park a lonely block at column 0 of the next row). */
o = glitch_put(out, o, "\033[1;96m");
o = glitch_put(out, o, caret[(unsigned)spin % (unsigned)ncaret]);
o = glitch_put(out, o, "\033[22;39m");
} else if (age <= 3) {
/* Plasma just behind the head. */
const char *g = plasma[(h + (unsigned)spin) % (unsigned)nplasma];
o = glitch_put(out, o, "\033[1;96m");
o = glitch_put(out, o, g);
o = glitch_put(out, o, "\033[22;39m");
} else if (age <= 16) {
/* Wake: mostly ghosting the real glyph; braid with phosphor on the
* wave crest so it reads as a decode sweep, not TV static. */
int dens = 18 - age; /* 15..2 */
int hit = on_wave || (int)(h % 18) < dens / 2;
if (hit && (spin + v) % 3 != 0) {
} else if (age <= 18) {
/* Wake: ghost real text; crest braids phosphor as it sweeps. */
int dens = 20 - age;
int hit = on_wave || (int)(h % 16) < dens / 3;
if (on_wave) {
const char *g = wake[h % (unsigned)nwake];
o = glitch_put(out, o, on_wave ? "\033[96m" : "\033[2;36m");
o = glitch_put(out, o, "\033[1;96m");
o = glitch_put(out, o, g);
o = glitch_put(out, o, "\033[22;39m");
} else if (age <= 6 && (spin + age) % 4 == 0) {
/* Brief bright reveal of the true char — locking in. */
} else if (hit && (spin + v) % 4 != 0) {
const char *g = wake[h % (unsigned)nwake];
o = glitch_put(out, o, "\033[2;36m");
o = glitch_put(out, o, g);
o = glitch_put(out, o, "\033[22;39m");
} else if (age <= 8 && (spin + age) % 5 == 0) {
o = glitch_put(out, o, "\033[1;97m");
memcpy(out + o, src + st, lens[v]);
o += lens[v];
o = glitch_put(out, o, "\033[22;39m");
} else {
/* Dim true glyph — readable under the wake. */
o = glitch_put(out, o, "\033[2m");
memcpy(out + o, src + st, lens[v]);
o += lens[v];
o = glitch_put(out, o, "\033[22m");
}
} else if (age <= 20) {
/* Lock flash: settle with a one-beat bright pulse. */
if ((spin + age) % 5 == 0) {
o = glitch_put(out, o, "\033[1m");
memcpy(out + o, src + st, lens[v]);
o += lens[v];
o = glitch_put(out, o, "\033[22m");
} else {
memcpy(out + o, src + st, lens[v]);
o += lens[v];
}
} else if (age <= 22 && (spin + age) % 6 == 0) {
o = glitch_put(out, o, "\033[1m");
memcpy(out + o, src + st, lens[v]);
o += lens[v];
o = glitch_put(out, o, "\033[22m");
} else {
memcpy(out + o, src + st, lens[v]);
o += lens[v];
}
cursor = st + lens[v];
}
/* Trailing newlines / SGR after the last glyph stay as-is — caret already
* sits on the tip character above, so it tracks the text, not col 0. */
if (cursor < n) {
memcpy(out + o, src + cursor, n - cursor);
o += n - cursor;
}
/* Scanning caret past the tip — the "write head". */
o = glitch_put(out, o, "\033[1;96m");
o = glitch_put(out, o, caret[(unsigned)spin % (unsigned)ncaret]);
o = glitch_put(out, o, "\033[22;39m");
out[o] = 0;
return out;
}