diff --git a/shell-plugin/lib/dispatcher.zsh b/shell-plugin/lib/dispatcher.zsh index c5f13db0e0..53b8a1bbc0 100644 --- a/shell-plugin/lib/dispatcher.zsh +++ b/shell-plugin/lib/dispatcher.zsh @@ -118,11 +118,12 @@ function forge-accept-line() { # Add the original command to history before transformation print -s -- "$original_buffer" - # CRITICAL: Move cursor to end so output doesn't overwrite - # Don't clear BUFFER yet - let _forge_reset do that after action completes - # This keeps buffer state consistent if Ctrl+C is pressed - CURSOR=${#BUFFER} - zle redisplay + # CRITICAL: clear and invalidate the active ZLE prompt before writing output. + # Otherwise RPROMPT/text from the old prompt can remain on wrapped rows and + # the command output can run underneath it, which looks like clipping. + BUFFER="" + CURSOR=0 + zle -I # Handle aliases - convert to their actual agent names case "$user_action" in diff --git a/shell-plugin/lib/helpers.zsh b/shell-plugin/lib/helpers.zsh index 2f038381c6..dfdecfc4b8 100644 --- a/shell-plugin/lib/helpers.zsh +++ b/shell-plugin/lib/helpers.zsh @@ -137,12 +137,20 @@ function _forge_select_model_pair_global() { } function _forge_reset() { - # Clear buffer and reset cursor position BUFFER="" CURSOR=0 - # Force widget redraw and prompt reset + # Output may finish without a trailing newline. If ZLE accepts an empty line + # from that position, RPROMPT can be painted on top of the final output row. + # Move to a clean line before accepting the empty buffer so the next prompt + # is always rendered below Forge output. + print -r -- "" >/dev/tty + + # Do not accept an empty command line here. accept-line asks ZLE to render the + # next prompt from inside the widget; with right prompts (p10k/RPROMPT) that + # repaint can still target the last output row and hide the tail of output. + # Invalidating the display is enough: the widget returns and zsh redraws the + # prompt naturally on the clean line above. zle -I - zle reset-prompt } # Helper function to print messages with consistent formatting based on log level