Repository navigation
Conversation
A long session can only be moved through by line, page or the whole transcript. messages_next/messages_previous exist but are unbound, and they skip any prompt within 10 rows of the viewport top, because they compare against a fixed threshold rather than the row they land on. Assistant parts render without an id the scroll position could be matched against. Bind three levels of navigation by default, all overridable in tui.json: - messages_previous / messages_next (ctrl+up / ctrl+down) stop on every user prompt, now through the same picker as the two below. - messages_landmark_previous / messages_landmark_next (ctrl+shift+up / ctrl+shift+down) stop on prompts, the last text part of each turn (its final response), and question, todowrite and task calls. Edits, reads and shell calls are left out because they are as dense as the blocks themselves. - messages_block_previous / messages_block_next (ctrl+alt+shift+up / ctrl+alt+shift+down) stop on every prompt, text part, reasoning part with content, and tool call. Reasoning without content - an encrypted block or an empty "Thinking" placeholder, which GPT models emit on every step - renders as a bare header and is skipped. Text, reasoning and tool boxes now carry their part id so the session route can find them among the scrollbox children, as it already does for user messages by message id. "Previous" and "next" are relative to the row a navigated block lands on, one below the viewport top, so repeated presses walk block by block; past either end the view goes to the top or back to the bottom. messages_first and messages_last also bind ctrl+home and ctrl+end.
Jumping to the bottom to read new output or type a prompt loses the place a scrolled-up reader was at; the only way back is to scroll and search for it. messages_last (end, ctrl+end) now remembers the block at the top of a scrolled-up viewport and its offset from that edge. The next messages_first (home, ctrl+home) brings that block back to the same row; a second messages_first goes to the top as before. Remembering the renderable rather than a scroll offset keeps the position correct when content above it changes, and avoids part ids, which apply_patch repeats across its per-file boxes. The mark is dropped, and messages_first goes to the top, when: - it was taken in another session; - the view is no longer at the bottom when messages_first runs; - any other navigation command ran in between (page, half page, line, prompt, landmark, block, last user message) or the wheel scrolled the transcript; - its block is no longer rendered, e.g. after a revert. messages_last pressed at the bottom keeps the mark it already holds, so a submitted prompt or new output in between does not lose it. rememberScroll / recallScroll in src/routes/session/navigation.ts hold the rules and are unit-tested.
1 task done
Contributor
|
The following comment was made by an LLM, it may be inaccurate: |
Nowaker
force-pushed
the
tui-home-return
branch
from
October 7, 2026 11:13
78ce706 to
d6096e2
Compare
1 task done
Member
|
This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2. — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note: I'm aware v1 is now the maintenance branch and new features go to v2 only. This PR is here for others who want to use it on v1. I will submit a v2 version once I've migrated my plugin setup to v2.
Issue for this PR
Closes #53629. Builds on #53333: this branch contains that PR's commit too. Review only the last commit, 78ce706 "return to the scrolled-up position on messages_first". It is stacked because it uses #53333's
ctrl+home/ctrl+endbindings and drops its mark from that PR's navigation commands.Type of change
What does this PR do?
messages_last(end,ctrl+end) now remembers where a scrolled-up reader was. The nextmessages_first(home,ctrl+home) brings them back there instead of to the top, and a secondmessages_firstgoes to the top as before. Soendthenhomeis a round trip, andhomehomestill reaches the top.The mark is the renderable at the top of the viewport plus its offset from that edge. Restoring scrolls that renderable back to the same row, so the position stays correct when content above or below it changes. It is a renderable rather than a scroll offset or a part id: offsets drift as content changes, and
apply_patchrepeats its part id across one box per file.The mark is dropped, and
messages_firstgoes to the top, when:messages_firstruns (dragged scrollbar, anything else that moved it);onMouseScrollon the scrollbox);messages_lastpressed while already at the bottom keeps the mark it holds, so new output or a submitted prompt in between doesn't lose it. A view sitting at the bottom is following output, so restoring from there doesn't interact with sticky scroll, and new output arriving afterwards above the restored view is handled by the existing layout code like any other scroll-up.The rules live in
rememberScroll/recallScrollinsrc/routes/session/navigation.ts, generic over the anchor type so they are unit-testable without a renderer. The route keeps onescrollReturnvariable.How did you verify your code works?
test/routes/session/navigation.test.tscovers the state machine: remember on leaving a scrolled-up view, replace on leaving again, keep when already at the bottom, discard across sessions, recall only at the bottom and only in the same session.bun testandbun typecheckpass inpackages/tui.XDG_*dirs and a 28-message imported session, sending keys withtmux send-keys(first viewport row after each key):With the view three rows into a response before
ctrl+end,ctrl+homerestores all 30 captured viewport rows byte for byte. Ondev,homeafterendgoes to the top.Checklist
This PR is AI generated, but under direct supervision and on request of @Nowaker.