-
Notifications
You must be signed in to change notification settings - Fork 393
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add terminal width fallback via stty if on Windows/MSYS2
Also new workarounds.rs file, and DELTA_NO_WORKAROUNDS env var to disable these.
- Loading branch information
Showing
3 changed files
with
63 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ pub mod process; | |
pub mod regex_replacement; | ||
pub mod round_char_boundary; | ||
pub mod syntect; | ||
pub mod workarounds; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// env var which should disable workarounds | ||
const NO_WORKAROUNDS: &str = "DELTA_NO_WORKAROUNDS"; | ||
|
||
// Work around a bug in the 'console' crate: On Windows it can not determine the width of | ||
// an MSYS2 / MINGW64 terminal (e.g. from Git-Bash) correctly. | ||
// Instead use the usually included stty util from the MSYS2 distribution. | ||
#[cfg(target_os = "windows")] | ||
pub fn windows_msys2_width_fix(height_width: (u16, u16), term_stdout: &console::Term) -> usize { | ||
fn guess_real_width(current_width: u16, term_stdout: &console::Term) -> Option<u16> { | ||
use std::process::{Command, Stdio}; | ||
|
||
let term_var = std::env::var("TERM").ok()?; | ||
// More checks before actually calling stty. | ||
if term_var.starts_with("xterm") | ||
&& term_stdout.is_term() | ||
&& term_stdout.features().is_msys_tty() | ||
{ | ||
if std::env::var(NO_WORKAROUNDS).is_ok() { | ||
return Some(current_width); | ||
} | ||
|
||
// stderr/2 is passed to the Command below. | ||
let pseudo_term = "/dev/fd/2"; | ||
|
||
// Read width via stty helper program (e.g. "C:\Program Files\Git\usr\bin\stty.exe") | ||
// which gets both the MSYS2 and cmd.exe width right. | ||
let result = Command::new("stty") | ||
.stderr(Stdio::inherit()) | ||
.arg("-F") | ||
.arg(pseudo_term) | ||
.arg("size") | ||
.output() | ||
.ok()?; | ||
|
||
if result.status.success() { | ||
let size = std::str::from_utf8(&result.stdout).ok()?; | ||
let mut it = size.split_whitespace(); | ||
let _height = it.next()?; | ||
return it.next().map(|width| width.parse().ok())?; | ||
} | ||
} | ||
None | ||
} | ||
|
||
// Calling an external binary is slow, so make sure this is actually necessary. | ||
// The fallback values of 25 lines by 80 columns (sometimes zero indexed) are a good | ||
// indicator. | ||
let (height, width) = height_width; | ||
match (height, width) { | ||
(24..=25, 79..=80) => guess_real_width(width, term_stdout).unwrap_or(width), | ||
_ => width, | ||
} | ||
.into() | ||
} | ||
|
||
#[cfg(not(target_os = "windows"))] | ||
pub fn windows_msys2_width_fix(height_width: (u16, u16), _: &console::Term) -> usize { | ||
let _ = NO_WORKAROUNDS; | ||
height_width.1.into() | ||
} |