feat(shell): add fish-style Ctrl-L to clear screen preserving scrollback#1212
feat(shell): add fish-style Ctrl-L to clear screen preserving scrollback#1212jetjinser wants to merge 4 commits intoMoonshotAI:mainfrom
Ctrl-L to clear screen preserving scrollback#1212Conversation
Signed-off-by: Jinser Kafka <aimer@purejs.icu>
Signed-off-by: Jinser Kafka <aimer@purejs.icu>
Signed-off-by: Jinser Kafka <aimer@purejs.icu>
Signed-off-by: Jinser Kafka <aimer@purejs.icu>
| height = output.get_size().rows | ||
| used_lines = window.render_info.content_height | ||
|
|
||
| # calculate scroll to push content to top; guard against negative | ||
| scroll = max(0, height - used_lines) |
There was a problem hiding this comment.
🟡 Incorrect scroll calculation under-pushes content into scrollback with multi-line input
The Ctrl+L handler computes scroll = max(0, height - used_lines) where used_lines is window.render_info.content_height — the line count of the input buffer content, not the total rendered height of the application. This means the number of newlines written decreases as the input grows, resulting in fewer rows being pushed into scrollback.
Detailed explanation and impact
content_height at prompt.py:719 returns ui_content.line_count, which is the number of lines in the text being edited in the input buffer. For a fish-style clear, the goal is to push the entire visible screen into scrollback by writing height newlines (one per terminal row).
With the current formula scroll = max(0, height - used_lines):
- Terminal height 40, empty input (1 line):
scroll = 39— pushes 39 of 40 rows ✓ (close enough) - Terminal height 40, 10-line input:
scroll = 30— only pushes 30 rows, but the app renders ~12+ rows of content. The top ~10 rows of the old screen are not pushed into scrollback and are lost whenrenderer.clear()callserase_screen().
The fix should be to write height newlines unconditionally (or at minimum, use the total rendered height of the application rather than just the input buffer content height):
scroll = output.get_size().rows
output.write("\n" * scroll)Impact: With multi-line input, pressing Ctrl+L fails to preserve the top portion of the visible screen in scrollback history, contradicting the documented fish-style behavior.
| height = output.get_size().rows | |
| used_lines = window.render_info.content_height | |
| # calculate scroll to push content to top; guard against negative | |
| scroll = max(0, height - used_lines) | |
| height = output.get_size().rows | |
| output.write("\n" * height) | |
| output.flush() |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
This code is written intentionally.
Subtracting used_lines is to prevent the current prompt from scrolling up, thus preventing duplicate prompts (both the scrolled-up prompt and the refreshed prompt).
Related Issue
N/A (Minor feature addition matching fish shell behavior)
Description
Pressing
Ctrl+Lnow pushes the current prompt content into the terminal's scrollback buffer (like fish'sscrollback-push)Checklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.