Skip to content

Bottom-row prompt is duplicated when returning from executehostcommand or the buffer editor #1196

Description

@mst-mkt

Platform Linux
Terminal software Ghostty 1.3.1

When control returns to the line editor from an executehostcommand keybinding or the Ctrl+O buffer editor without anything having been printed, and the prompt sits on the bottom row of the screen, the previous prompt position is not re-used: a new prompt is drawn one row below and the old prompt stays on screen. Up to reedline 0.49 (nushell 0.114) the prompt was redrawn in place and nothing visibly changed; starting with 0.50 (nushell 0.115) the duplication occurs.

Once a session has filled the screen, the prompt is always on the bottom row, so every Ctrl+O round-trip through an alternate-screen editor and every keybinding that edits the buffer via commandline edit stacks one more copy of the prompt.

In practice this makes such keybindings unusable: for example, mst-mkt/autopair.nu binds (, ", Backspace and friends to executehostcommand events that edit the buffer, so once the screen is full, ordinary typing triggers the duplication on every keystroke.

Steps to reproduce

With reedline alone (no nushell required; examples/demo.rs already configures vi as the buffer editor):

  1. cargo run --example demo
  2. Press Enter repeatedly until the prompt reaches the bottom row of the terminal
  3. Press Ctrl+O, then quit vi with :q

With nushell 0.115, add a keybinding that only edits the buffer and prints nothing (F5 here):

$env.config.keybindings ++= [{
  name: repro
  modifier: none
  keycode: f5
  mode: [emacs vi_insert]
  event: { send: executehostcommand, cmd: "commandline edit --insert 'x'" }
}]

1..50 | to text | print   # or more, enough to fill your terminal so the prompt reaches the bottom row

Then press F5.

  • Expected: the prompt is redrawn in place, as in reedline 0.49 / nushell 0.114
  • Actual: a new prompt is drawn one row below on every press or Ctrl+O round-trip, and the old prompt lines stay on screen
  • While the prompt is above the bottom row, the same steps only edit the buffer in place; the prompt is not duplicated

Screenshots/Screencaptures

screenrecord

In the recording, F5 is bound to commandline edit --insert '###'. While the prompt is above the bottom row, pressing F5 only inserts ### in place. After the screen is filled by pressing Enter, each F5 press draws a new prompt one row below and the previous prompt lines stay on screen.

Suspected cause

#1133 (the fix for #1130) added the !painter_state.was_flush_at_bottom condition to the existing re-use branch in select_prompt_row (src/painting/painter.rs). When the previous prompt was flush at the bottom row, the branch is no longer taken and a new prompt is started one row below instead:

-if painter_state.previous_prompt_rows_range.contains(&row) {
+if !painter_state.was_flush_at_bottom
+    && painter_state.previous_prompt_rows_range.contains(&row)
+{
     let start_row = *painter_state.previous_prompt_rows_range.start();
     return PromptRowSelector::UseExistingPrompt { start_row };
 }
  • 0.49, which does not have this condition, is unaffected; 0.50, which introduced it, is affected. The condition is unchanged in 0.51.0 (nushell 0.115.1) and on current main (fc19b91), where the bug still reproduces
  • The intent behind Wrong prompt positioning after fzf menus when there's little room left and content get moved upwards #1130 (a host command such as an fzf menu takes over the tty and scrolls content upwards, so the prompt must not be redrawn over the scrolled-up output) is correct, but the condition cannot distinguish a command that printed nothing from one that scrolled the screen, so it also catches the case where the command printed nothing

Environment

  • Reproduced with reedline 0.50.0 (nushell 0.115.0), and with examples/demo.rs on main (fc19b91)
  • Condition verified unchanged in reedline 0.51.0 (nushell 0.115.1)
  • Linux, Ghostty 1.3.1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions