Skip to content

Buffer does not scroll to bottom when made visible after receiving output while hidden #177

Description

@emil-e

Version: 0.17.0


When a ghostel buffer receives output while not displayed in any window, the viewport position is not restored to the bottom when the buffer is made visible again.

Steps to reproduce

  1. Open a ghostel buffer and run a command that produces output after a delay (e.g. sleep 2 && echo done, or any long-running agentic tool)
  2. Switch away from the buffer — via tab-bar, tab-line, switch-to-buffer, or any other mechanism — while the command is running
  3. Switch back once output has arrived

Expected behaviour

The buffer scrolls to the bottom showing the latest output — consistent with how every other terminal emulator behaves and with ghostel's own behaviour when the buffer is visible while output arrives.

Actual behaviour

The buffer shows the position it was at when you left. You have to manually scroll to the bottom to see what arrived while you were away.

Root cause

ghostel--delayed-redraw calls get-buffer-window-list to find windows to anchor. When the buffer is not displayed in any window, all-windows is empty, the dolist is a no-op, and no window positions are touched. However, ghostel--last-anchor-position is set unconditionally after the dolist, so it continues advancing as output arrives.

When the buffer is made visible again, the window's window-start is at the previously saved position — now well behind the advanced anchor. ghostel--window-anchored-p checks (>= (window-start win) anchor), which fails, so the window is classified as "reading scrollback" and ghostel--restore-scrollback-window runs instead of ghostel--anchor-window.

The heuristic cannot distinguish between "user scrolled up while the buffer was visible" and "this window has a stale window-start because the buffer was hidden when the anchor advanced."

Suggested fix

Hook window-buffer-change-functions to detect when a ghostel buffer gains its first live window (transitions from zero to one or more entries in get-buffer-window-list), and set ghostel--snap-requested at that point. ghostel--window-anchored-p checks ghostel--snap-requested first and short-circuits the window-start comparison, so the newly-visible window would be treated as anchored regardless of where Emacs placed window-start.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions