From edb839c803f4b0b991ec8d24a77d48bc5514029d Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Fri, 10 May 2024 16:26:48 -0700 Subject: [PATCH] Improve terminal width detection Ensure the value is always non-zero, and consider $COLUMNS if crossterm does not succeed. Fixes #707 --- CHANGELOG.md | 8 ++++++++ src/options.rs | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6374211d..4ffdb5794d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,14 @@ Difftastic now has a man page, see the `difft.1` file. Fixed a memory leak and substantially improved performance in some cases (up to 2x in testing). +### Command Line Interface + +Fixed a crash when difftastic could not detect the terminal width, +such as inside eshell. + +Difftastic now also considers $COLUMNS when detecting the terminal +width. + ## 0.57 (released 1st April 2024) ### Parsing diff --git a/src/options.rs b/src/options.rs index daa156ee0e..774da35869 100644 --- a/src/options.rs +++ b/src/options.rs @@ -864,7 +864,22 @@ pub(crate) fn parse_args() -> Mode { /// to a sensible default value. fn detect_terminal_width() -> usize { if let Ok((columns, _rows)) = crossterm::terminal::size() { - return columns.into(); + if columns > 0 { + return columns.into(); + } + } + + // If crossterm couldn't detect the terminal width, use the + // shell variable COLUMNS if it's set. This helps with terminals like eshell. + // + // https://github.com/Wilfred/difftastic/issues/707 + // https://stackoverflow.com/a/48016366 + if let Ok(columns_env_val) = std::env::var("COLUMNS") { + if let Ok(columns) = columns_env_val.parse::() { + if columns > 0 { + return columns; + } + } } DEFAULT_TERMINAL_WIDTH