Skip to content

Commit

Permalink
Auto merge of #6010 - ehuss:winsize, r=alexcrichton
Browse files Browse the repository at this point in the history
Get window size on more Windows terminals.

This is an alternate approach to determining the window size that works on more Windows terminals.

Terminals with accurate width detection: Normal Windows console, cmder, ConEmu, VS Code, Hyper, etc.

mintty-based terminals will always be 60 characters wide. Cygwin in a command console is ok, but
running under x-windows will also always be 60.

Tested on Windows 8 and Windows 10.

Closes #5124.
  • Loading branch information
bors committed Sep 12, 2018
2 parents 21cddb7 + 5b139d1 commit c514b94
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions src/cargo/core/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,18 +359,51 @@ mod imp {
extern crate winapi;

use std::mem;
use std::ptr;
use self::winapi::um::fileapi::*;
use self::winapi::um::handleapi::*;
use self::winapi::um::processenv::*;
use self::winapi::um::winbase::*;
use self::winapi::um::wincon::*;
use self::winapi::um::winnt::*;

pub fn stderr_width() -> Option<usize> {
unsafe {
let stdout = GetStdHandle(STD_ERROR_HANDLE);
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem::zeroed();
if GetConsoleScreenBufferInfo(stdout, &mut csbi) == 0 {
if GetConsoleScreenBufferInfo(stdout, &mut csbi) != 0 {
return Some((csbi.srWindow.Right - csbi.srWindow.Left) as usize)
}

// On mintty/msys/cygwin based terminals, the above fails with
// INVALID_HANDLE_VALUE. Use an alternate method which works
// in that case as well.
let h = CreateFileA("CONOUT$\0".as_ptr() as *const CHAR,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
ptr::null_mut(),
OPEN_EXISTING,
0,
ptr::null_mut()
);
if h == INVALID_HANDLE_VALUE {
return None;
}
Some((csbi.srWindow.Right - csbi.srWindow.Left) as usize)

let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem::zeroed();
let rc = GetConsoleScreenBufferInfo(h, &mut csbi);
CloseHandle(h);
if rc != 0 {
let width = (csbi.srWindow.Right - csbi.srWindow.Left) as usize;
// Some terminals, such as mintty, always return 79 instead of
// the actual width. In that case, use a conservative value.
if width == 79 {
return Some(60);
} else {
return Some(width);
}
}
return None;
}
}
}

0 comments on commit c514b94

Please sign in to comment.