diff --git a/src/reader.cpp b/src/reader.cpp index 1a29e8f87..b54af88c4 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -3581,7 +3581,11 @@ maybe_t reader_data_t::readline(int nchars_or_0) { repaint_if_needed(); } - ignore_result(write(STDOUT_FILENO, "\n", 1)); + // Emit a newline so that the output is on the line after the command. + // But do not emit a newline if the cursor has wrapped onto a new line all its own - see #6826. + if (!screen.cursor_is_wrapped_to_own_line()) { + ignore_result(write(STDOUT_FILENO, "\n", 1)); + } // Ensure we have no pager contents when we exit. if (!pager.empty()) { diff --git a/src/screen.cpp b/src/screen.cpp index 72d66fef3..821831500 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -1222,3 +1222,10 @@ void screen_force_clear_to_end() { } screen_t::screen_t() : outp_(outputter_t::stdoutput()) {} + +bool screen_t::cursor_is_wrapped_to_own_line() const { + // Note == comparison against the line count is correct: we do not create a line just for the + // cursor. If there is a line containing the cursor, then it means that line has contents and we + // should return false. + return actual.cursor.x == 0 && static_cast(actual.cursor.y) == actual.line_count(); +} diff --git a/src/screen.h b/src/screen.h index ba750cf3a..612827241 100644 --- a/src/screen.h +++ b/src/screen.h @@ -154,6 +154,10 @@ class screen_t { /// \return the outputter for this screen. outputter_t &outp() { return outp_; } + + /// \return whether we believe the cursor is wrapped onto the last line, and that line is + /// otherwise empty. This includes both soft and hard wrapping. + bool cursor_is_wrapped_to_own_line() const; }; /// This is the main function for the screen putput library. It is used to define the desired