Add a tput based computation of terminal size (#283)
This commit is contained in:
parent
3e82d6ae1c
commit
c23a6ddf38
@ -1,6 +1,6 @@
|
|||||||
//! UNIX related logic for terminal manipulation.
|
//! UNIX related logic for terminal manipulation.
|
||||||
|
|
||||||
use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ};
|
use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ};
|
||||||
|
use std::process;
|
||||||
|
|
||||||
use crate::utils::sys::unix::wrap_with_result;
|
use crate::utils::sys::unix::wrap_with_result;
|
||||||
use crate::utils::Result;
|
use crate::utils::Result;
|
||||||
@ -10,6 +10,39 @@ pub fn exit() {
|
|||||||
::std::process::exit(0);
|
::std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// execute tput with the given argument and parse
|
||||||
|
/// the output as a u16.
|
||||||
|
///
|
||||||
|
/// The arg should be "cols" or "lines"
|
||||||
|
fn tput_value(arg: &str) -> Option<u16> {
|
||||||
|
match process::Command::new("tput").arg(arg).output() {
|
||||||
|
Ok(process::Output { stdout, .. }) => {
|
||||||
|
let value = stdout
|
||||||
|
.iter()
|
||||||
|
.map(|&b| b as u16)
|
||||||
|
.take_while(|&b| b >= 48 && b <= 58)
|
||||||
|
.fold(0, |v, b| v * 10 + (b - 48));
|
||||||
|
if value > 0 {
|
||||||
|
Some(value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return the size of the screen as determined by tput
|
||||||
|
///
|
||||||
|
/// This alternate way of computing the size is useful
|
||||||
|
/// when in a subshell.
|
||||||
|
fn tput_size() -> Option<(u16, u16)> {
|
||||||
|
match (tput_value("cols"), tput_value("lines")) {
|
||||||
|
(Some(w), Some(h)) => Some((w, h)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the terminal size `(columns, rows)`.
|
/// Returns the terminal size `(columns, rows)`.
|
||||||
///
|
///
|
||||||
/// The top left cell is represented `1,1`.
|
/// The top left cell is represented `1,1`.
|
||||||
@ -26,6 +59,6 @@ pub fn size() -> Result<(u16, u16)> {
|
|||||||
{
|
{
|
||||||
return Ok((size.ws_col, size.ws_row));
|
return Ok((size.ws_col, size.ws_row));
|
||||||
} else {
|
} else {
|
||||||
Err(std::io::Error::last_os_error().into())
|
tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user