Skip to content

fix: emit scroll commands before glyphs in CLI mode (#2577)#2918

Open
deths74r wants to merge 1 commit intodankamongmen:masterfrom
deths74r:fix/cli-scroll-phase-ordering
Open

fix: emit scroll commands before glyphs in CLI mode (#2577)#2918
deths74r wants to merge 1 commit intodankamongmen:masterfrom
deths74r:fix/cli-scroll-phase-ordering

Conversation

@deths74r
Copy link
Copy Markdown

Summary

Fixes #2577 (disappearing strings in CLI mode).

In notcurses_rasterize_inner(), rasterize_core(phase=0) was emitting all damaged glyph cells before rasterize_scrolls() emitted terminal scroll commands. This caused the subsequent scroll to shift just-written characters up by one row, desyncing lastframe from the actual terminal state. On the next render, those cells would be incorrectly skipped because lastframe thought they were already displayed.

This manifested as intermittent "disappearing strings" in CLI mode — the first character of output would vanish after a scroll event.

Changes

  1. Move rasterize_scrolls() before rasterize_core(phase=0) so the terminal scrolls first and glyphs land at their correct final positions.

  2. Uncomment the logendy adjustment in rasterize_scrolls() which was disabled with a FIXME probably need this to take place at the end of cycle... note. This ensures the logical end-of-output cursor position is updated after scrolls, preventing stale cursor parking and goto_location() elision bugs.

How to reproduce

// Minimal repro: CLI mode, write styled text, render, read input, loop
struct notcurses_options opts = { .flags = NCOPTION_CLI_MODE };
struct notcurses* nc = notcurses_init(&opts, NULL);
struct ncplane* n = notcurses_stdplane(nc);
for(int i = 0; i < 20; i++){
    ncplane_set_fg_rgb(n, 0x00ff00);
    ncplane_putstr(n, "round N> ");
    ncplane_set_fg_default(n);
    notcurses_render(nc);
    // ... read input, write response text with per-token renders ...
}

After enough rounds to trigger terminal scrolling, the first character of the prompt or response text disappears intermittently.

Testing

Tested with a CLI-mode application (Vessel AI coding assistant) that writes styled prompts and streams LLM responses token-by-token with per-token renders. Before the fix, first-character clipping occurred intermittently after scrolling. After the fix, no clipping observed across extended sessions.

In notcurses_rasterize_inner(), rasterize_core(phase=0) was emitting
all damaged glyph cells BEFORE rasterize_scrolls() emitted terminal
scroll commands. This caused the subsequent scroll to shift just-written
characters up, desyncing lastframe from the actual terminal state.
On the next render, those cells would be incorrectly skipped.

This manifested as intermittent "disappearing strings" in CLI mode --
the first character of output would vanish after scrolling.

Fix: move rasterize_scrolls() before rasterize_core(phase=0) so the
terminal scrolls first and glyphs land at their correct positions.

Also uncomment the logendy adjustment in rasterize_scrolls() which
was disabled with a FIXME note. This ensures the logical end-of-output
cursor position is updated after scrolls, preventing stale cursor
parking and goto_location() elision bugs.

Fixes dankamongmen#2577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

disappearing strings in CLI mode

1 participant