lsd/src/display.rs

117 lines
3.1 KiB
Rust
Raw Normal View History

use flags::Flags;
2018-12-13 12:33:49 +05:30
use std::io::Write;
2018-12-02 17:22:51 +01:00
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
use terminal_size::terminal_size;
const EDGE: &str = "├──";
const LINE: &str = "";
const CORNER: &str = "└──";
2018-12-04 14:54:56 +01:00
pub struct Display {
flags: Flags,
2018-12-02 17:22:51 +01:00
}
impl Display {
pub fn new(flags: Flags) -> Display {
Display { flags }
2018-12-02 17:22:51 +01:00
}
pub fn print_outputs(&self, outputs: Vec<String>) {
if self.flags.display_long || self.flags.display_online {
2018-12-02 17:22:51 +01:00
self.print_one_per_line(&outputs);
} else {
self.print_grid(outputs);
}
}
fn print_grid(&self, outputs: Vec<String>) {
let term_width = match terminal_size() {
Some((w, _)) => w.0 as usize,
None => panic!("failed to retrieve terminal size"),
};
let mut grid = Grid::new(GridOptions {
filling: Filling::Spaces(2),
2018-12-07 19:44:26 +01:00
direction: Direction::TopToBottom,
2018-12-02 17:22:51 +01:00
});
for output in outputs {
grid.add(Cell {
width: self.get_visible_width(&output),
contents: output,
});
}
2018-12-05 04:44:01 +01:00
if let Some(gridded_output) = grid.fit_into_width(term_width) {
print!("{}", gridded_output);
2018-12-13 12:33:49 +05:30
std::io::stdout()
.flush()
.ok()
.expect("Could not flush stdout");
2018-12-05 04:44:01 +01:00
} else {
//does not fit into grid, usually because (some) filename(s)
//are longer or almost as long as term_width
//print line by line instead!
let lined_output = grid.fit_into_columns(1);
print!("{}", lined_output);
2018-12-13 12:33:49 +05:30
std::io::stdout()
.flush()
.ok()
.expect("Could not flush stdout");
2018-12-05 04:44:01 +01:00
}
2018-12-02 17:22:51 +01:00
}
2018-12-04 14:54:56 +01:00
pub fn print_tree_row(&self, output: String, depth: usize, last: bool) {
let mut res = String::new();
for _ in 0..depth {
res += LINE;
}
if last {
res += EDGE;
} else {
res += CORNER;
}
res += " ";
res += &output;
println!("{}", res);
}
2018-12-02 18:12:53 +01:00
fn print_one_per_line(&self, outputs: &[String]) {
2018-12-02 18:16:02 +01:00
let mut res = String::new();
2018-12-02 17:22:51 +01:00
for output in outputs {
2018-12-02 18:16:02 +01:00
res += output;
res += "\n";
2018-12-02 17:22:51 +01:00
}
2018-12-02 18:16:02 +01:00
print!("{}", res);
2018-12-13 12:33:49 +05:30
std::io::stdout()
.flush()
.ok()
.expect("Could not flush stdout");
2018-12-02 17:22:51 +01:00
}
2018-12-02 18:12:53 +01:00
fn get_visible_width(&self, input: &str) -> usize {
2018-12-02 17:22:51 +01:00
let mut nb_invisible_char = 0;
for (idx, _) in input.match_indices("[38;5;") {
let color_code = input.chars().skip(idx + 6);
let mut code_size = 0;
color_code
.skip_while(|x| {
code_size += 1;
char::is_numeric(*x)
2018-12-12 11:17:32 +01:00
})
.count();
2018-12-02 17:22:51 +01:00
nb_invisible_char += 6 + code_size; /* "[38;5;" + color number + "m" */
}
nb_invisible_char += 3; /* "[0m" */
input.chars().count() - nb_invisible_char
}
}