summaryrefslogtreecommitdiffstats
path: root/src/term.rs
diff options
context:
space:
mode:
authorBen S <ogham@bsago.me>2014-07-22 15:41:20 +0100
committerBen S <ogham@bsago.me>2014-07-22 15:41:20 +0100
commitcf3e32c9c166c16aa57a3ce2c0eff34796c5cd0a (patch)
treee71fa7ecc27a7f367508e9d5bd3f4cdb5a6f5ea2 /src/term.rs
parentb1560edb854d0e0d1f0c37f176f6bce6571d00a5 (diff)
Get terminal width for grid view (resolve #1)
Diffstat (limited to 'src/term.rs')
-rw-r--r--src/term.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/term.rs b/src/term.rs
new file mode 100644
index 0000000..9e88adf
--- /dev/null
+++ b/src/term.rs
@@ -0,0 +1,57 @@
+
+mod c {
+ #![allow(non_camel_case_types)]
+ extern crate libc;
+ pub use self::libc::{
+ c_int,
+ c_ushort,
+ c_ulong,
+ STDOUT_FILENO,
+ };
+ use std::mem::zeroed;
+
+ // Getting the terminal size is done using an ioctl command that
+ // takes the file handle to the terminal (which in our case is
+ // stdout), and populates a structure with the values.
+
+ pub struct winsize {
+ pub ws_row: c_ushort,
+ pub ws_col: c_ushort,
+ }
+
+ // Unfortunately the actual command is not standardised...
+
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
+ static TIOCGWINSZ: c_ulong = 0x5413;
+
+ #[cfg(target_os = "freebsd")]
+ #[cfg(target_os = "macos")]
+ static TIOCGWINSZ: c_ulong = 0x40087468;
+
+ extern {
+ pub fn ioctl(fd: c_int, request: c_ulong, ...) -> c_int;
+ }
+
+ pub fn dimensions() -> winsize {
+ unsafe {
+ let mut window: winsize = zeroed();
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut window as *mut winsize);
+ window
+ }
+ }
+}
+
+pub fn dimensions() -> Option<(uint, uint)> {
+ let w = c::dimensions();
+
+ // If either of the dimensions is 0 then the command failed,
+ // usually because output isn't to a terminal (instead to a file
+ // or pipe or something)
+ if w.ws_col == 0 || w.ws_row == 0 {
+ None
+ }
+ else {
+ Some((w.ws_col as uint, w.ws_row as uint))
+ }
+}