id: NVIM-ISSUE-INA9RX_F
type: issue
title: Transcript force-scrolls to bottom on every write
specs:
NVIM-SPEC-GMWDCMJZ
Transcript force-scrolls to bottom on every write
Symptom
In a grown transcript, scrolling is erratic: the view jumps on every new streamed delta, navigation away from the bottom does not hold, and expanding a tool entry appears broken.
Transcript navigation requires moving between entries "with ordinary motions"; the cursor cannot be held off the last line while a run streams.
Follow mode is "optional and disabled unless selected", yet the transcript force-follows unconditionally.
Entry collapse/expand is defeated because the expanded entry is scrolled out of view and the toggle acts on the wrong line.
Evidence
lua/bugabinga/pivi/transcript.lua — follow_windows forces the cursor to the last line in every window showing the buffer, and is called unconditionally after append, line, and replace:
local follow_windows = function( bufnr )
local last = vim.api.nvim_buf_line_count( bufnr )
for _, win in ipairs( vim.api.nvim_list_wins() ) do
if vim.api.nvim_win_get_buf( win ) == bufnr then
pcall( vim.api.nvim_win_set_cursor, win, { last, 0, } )
end
end
end
No guard checks whether a window is already tailing the bottom, so any user navigation is overwritten by the next streamed delta.
Expand breakage follows from the same force: fold.toggle reads nvim_win_get_cursor( 0 )[1] to pick the entry, but follow_windows has already yanked the cursor to the last line, so <Plug>(pivi-toggle-entry) toggles the final entry rather than the one under the reader; and fold.apply's normal! zX recompute runs against a view scrolled to the bottom.
sequenceDiagram
participant User
participant session
participant transcript
participant window as transcript window
participant fold
User->>window: move cursor up / expand entry
session->>transcript: append streamed delta
transcript->>window: follow_windows -> cursor = last line
window-->>User: view jumps to bottom
User->>fold: toggle entry at cursor
fold->>window: reads cursor (already at last line)
window-->>User: wrong entry toggled, scrolled away
Expected
Auto-follow only when the window is already at the transcript tail; otherwise leave cursor and view untouched.
User navigation holds across streamed writes.
Expanding or collapsing acts on the entry the reader is on and keeps it in view.
Reproduction
Start a session and submit a prompt that produces a long streamed answer with tool calls.
While it streams, move the cursor up or expand a collapsed tool entry.
Observe the view snap back to the bottom on the next delta and the toggled entry change or scroll away.
---
id: NVIM-ISSUE-INA9RX_F
type: issue
title: Transcript force-scrolls to bottom on every write
specs:
- NVIM-SPEC-GMWDCMJZ
---
# Transcript force-scrolls to bottom on every write
## Symptom
In a grown transcript, scrolling is erratic: the view jumps on every new streamed delta, navigation away from the bottom does not hold, and expanding a tool entry appears broken.
## Impact
Violates transcript behavior of [NVIM-SPEC-GMWDCMJZ](../../specs/NVIM-SPEC-GMWDCMJZ-pivi-native-neovim-integration/index.md):
- Transcript navigation requires moving between entries "with ordinary motions"; the cursor cannot be held off the last line while a run streams.
- Follow mode is "optional and disabled unless selected", yet the transcript force-follows unconditionally.
- Entry collapse/expand is defeated because the expanded entry is scrolled out of view and the toggle acts on the wrong line.
## Evidence
`lua/bugabinga/pivi/transcript.lua` — `follow_windows` forces the cursor to the last line in every window showing the buffer, and is called unconditionally after `append`, `line`, and `replace`:
```
local follow_windows = function( bufnr )
local last = vim.api.nvim_buf_line_count( bufnr )
for _, win in ipairs( vim.api.nvim_list_wins() ) do
if vim.api.nvim_win_get_buf( win ) == bufnr then
pcall( vim.api.nvim_win_set_cursor, win, { last, 0, } )
end
end
end
```
No guard checks whether a window is already tailing the bottom, so any user navigation is overwritten by the next streamed delta.
Expand breakage follows from the same force: `fold.toggle` reads `nvim_win_get_cursor( 0 )[1]` to pick the entry, but `follow_windows` has already yanked the cursor to the last line, so `<Plug>(pivi-toggle-entry)` toggles the final entry rather than the one under the reader; and `fold.apply`'s `normal! zX` recompute runs against a view scrolled to the bottom.
```mermaid
sequenceDiagram
participant User
participant session
participant transcript
participant window as transcript window
participant fold
User->>window: move cursor up / expand entry
session->>transcript: append streamed delta
transcript->>window: follow_windows -> cursor = last line
window-->>User: view jumps to bottom
User->>fold: toggle entry at cursor
fold->>window: reads cursor (already at last line)
window-->>User: wrong entry toggled, scrolled away
```
## Expected
- Auto-follow only when the window is already at the transcript tail; otherwise leave cursor and view untouched.
- User navigation holds across streamed writes.
- Expanding or collapsing acts on the entry the reader is on and keeps it in view.
## Reproduction
1. Start a session and submit a prompt that produces a long streamed answer with tool calls.
2. While it streams, move the cursor up or expand a collapsed tool entry.
3. Observe the view snap back to the bottom on the next delta and the toggled entry change or scroll away.