mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-26 22:06:26 +00:00
Get terminal width for grid view (resolve #1)
This commit is contained in:
parent
b1560edb85
commit
cf3e32c9c1
16
src/exa.rs
16
src/exa.rs
@ -2,10 +2,7 @@
|
|||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[phase(plugin)] extern crate regex_macros;
|
#[phase(plugin)] extern crate regex_macros;
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
|
|
||||||
extern crate unicode;
|
extern crate unicode;
|
||||||
use std::char::UnicodeChar;
|
|
||||||
use std::iter::AdditiveIterator;
|
|
||||||
|
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
@ -25,6 +22,7 @@ pub mod filetype;
|
|||||||
pub mod unix;
|
pub mod unix;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
pub mod sort;
|
pub mod sort;
|
||||||
|
pub mod term;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = os::args();
|
let args = os::args();
|
||||||
@ -66,20 +64,12 @@ fn exa(opts: &Options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn width(string: &str) -> uint {
|
|
||||||
string.as_slice().chars()
|
|
||||||
.map(|c| c.width(true))
|
|
||||||
.filter(|o| o.is_some())
|
|
||||||
.map(|o| o.unwrap())
|
|
||||||
.sum()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn grid_view(options: &Options, across: bool, dir: Dir) {
|
fn grid_view(options: &Options, across: bool, dir: Dir) {
|
||||||
let unsorted_files = dir.files();
|
let unsorted_files = dir.files();
|
||||||
let files: Vec<&File> = options.transform_files(&unsorted_files);
|
let files: Vec<&File> = options.transform_files(&unsorted_files);
|
||||||
|
|
||||||
let max_column_length = files.iter().map(|f| width(f.name.as_slice())).max().unwrap();
|
let max_column_length = files.iter().map(|f| f.file_name_width()).max().unwrap();
|
||||||
let console_width = 80;
|
let (console_width, _) = term::dimensions().unwrap_or((80, 24));
|
||||||
let num_columns = (console_width + 1) / (max_column_length + 1);
|
let num_columns = (console_width + 1) / (max_column_length + 1);
|
||||||
let count = files.len();
|
let count = files.len();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::io::{fs, IoResult};
|
use std::io::{fs, IoResult};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use unicode::str::UnicodeStrSlice;
|
||||||
|
|
||||||
use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
|
use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
|
||||||
|
|
||||||
@ -157,6 +158,10 @@ impl<'a> File<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn file_name_width(&self) -> uint {
|
||||||
|
self.name.as_slice().width(false)
|
||||||
|
}
|
||||||
|
|
||||||
fn target_file_name_and_arrow(&self, target_path: Path) -> String {
|
fn target_file_name_and_arrow(&self, target_path: Path) -> String {
|
||||||
let v = target_path.filename().unwrap();
|
let v = target_path.filename().unwrap();
|
||||||
let filename = String::from_utf8_lossy(v).to_string();
|
let filename = String::from_utf8_lossy(v).to_string();
|
||||||
|
57
src/term.rs
Normal file
57
src/term.rs
Normal file
@ -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))
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,7 @@ mod c {
|
|||||||
pub fn getuid() -> libc::c_int;
|
pub fn getuid() -> libc::c_int;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Unix {
|
pub struct Unix {
|
||||||
user_names: HashMap<u32, Option<String>>, // mapping of user IDs to user names
|
user_names: HashMap<u32, Option<String>>, // mapping of user IDs to user names
|
||||||
group_names: HashMap<u32, Option<String>>, // mapping of groups IDs to group names
|
group_names: HashMap<u32, Option<String>>, // mapping of groups IDs to group names
|
||||||
|
Loading…
Reference in New Issue
Block a user