Skip to content

Commit

Permalink
Use ANSI escape code to clear line
Browse files Browse the repository at this point in the history
This eliminates the trailing spaces that Cargo used to use for clearing
a line of output. Trailing spaces are problematic because they take up
space on the next line when reducing the width of a terminal.
  • Loading branch information
dtolnay committed Oct 28, 2018
1 parent efb7972 commit d534875
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
31 changes: 31 additions & 0 deletions src/cargo/core/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ impl Shell {
self.err.as_write()
}

/// Erase from cursor to end of line.
pub fn err_erase_line(&mut self) {
if let ShellOut::Stream { tty: true, .. } = self.err {
imp::err_erase_line(self);
}
}

/// Shortcut to right-align and color green a status message.
pub fn status<T, U>(&mut self, status: T, message: U) -> CargoResult<()>
where
Expand Down Expand Up @@ -332,6 +339,8 @@ mod imp {

use libc;

use super::Shell;

pub fn stderr_width() -> Option<usize> {
unsafe {
let mut winsize: libc::winsize = mem::zeroed();
Expand All @@ -345,10 +354,19 @@ mod imp {
}
}
}

pub fn err_erase_line(shell: &mut Shell) {
// This is the "EL - Erase in Line" sequence. It clears from the cursor
// to the end of line.
// https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
let _ = shell.err().write_all(b"\x1B[K");
}
}

#[cfg(all(unix, not(any(target_os = "linux", target_os = "macos"))))]
mod imp {
pub(super) use super::default_err_erase_line as err_erase_line;

pub fn stderr_width() -> Option<usize> {
None
}
Expand All @@ -366,6 +384,8 @@ mod imp {
use self::winapi::um::wincon::*;
use self::winapi::um::winnt::*;

pub(super) use super::default_err_erase_line as err_erase_line;

pub fn stderr_width() -> Option<usize> {
unsafe {
let stdout = GetStdHandle(STD_ERROR_HANDLE);
Expand Down Expand Up @@ -408,3 +428,14 @@ mod imp {
}
}
}

#[cfg(any(
all(unix, not(any(target_os = "linux", target_os = "macos"))),
windows,
))]
fn default_err_erase_line(shell: &mut Shell) {
if let Some(max_width) = imp::stderr_width() {
let blank = " ".repeat(max_width);
drop(write!(shell.err(), "{}\r", blank));
}
}
4 changes: 1 addition & 3 deletions src/cargo/util/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,7 @@ impl<'cfg> State<'cfg> {
}

fn clear(&mut self) {
self.try_update_max_width();
let blank = " ".repeat(self.format.max_width);
drop(write!(self.config.shell().err(), "{}\r", blank));
self.config.shell().err_erase_line();
}

fn try_update_max_width(&mut self) {
Expand Down

0 comments on commit d534875

Please sign in to comment.