mirror of
https://github.com/lsd-rs/lsd
synced 2024-11-10 14:24:27 +00:00
Handle the --tree option
This commit is contained in:
parent
10e24e9854
commit
b60bab1bdd
6 changed files with 71 additions and 11 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -47,7 +47,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "lsd"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1-pre"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -45,5 +45,5 @@ Result from `hyperfine --warmup 10 'lsd -la /etc/*' 'colorls -la /etc/*' --expor
|
|||
- [x] Handle the `-a` option
|
||||
- [x] Add icons before the files names
|
||||
- [x] Handle all the file types (block/char/pipe/etc)
|
||||
- [ ] Handle the tree (`--tree`) output option
|
||||
- [x] Handle the tree (`--tree`) output option
|
||||
- [ ] Handle the json (`--json`) output option
|
||||
|
|
|
@ -23,6 +23,10 @@ impl IntoIterator for Batch {
|
|||
}
|
||||
|
||||
impl Batch {
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn sort(&mut self) {
|
||||
self.0.sort_unstable_by(sort_by_meta);
|
||||
}
|
||||
|
|
48
src/core.rs
48
src/core.rs
|
@ -6,16 +6,22 @@ use Options;
|
|||
|
||||
pub struct Core<'a> {
|
||||
options: &'a Options,
|
||||
display: Display<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Core<'a> {
|
||||
pub fn new(options: &'a Options) -> Core<'a> {
|
||||
Core { options }
|
||||
Core {
|
||||
options,
|
||||
display: Display::new(options),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, paths: Vec<PathBuf>) {
|
||||
let display = Display::new(self.options);
|
||||
pub fn run(self, paths: Vec<PathBuf>) {
|
||||
self.run_inner(paths, 0);
|
||||
}
|
||||
|
||||
fn run_inner(&self, paths: Vec<PathBuf>, depth: usize) {
|
||||
let mut dirs = Vec::new();
|
||||
let mut files = Vec::new();
|
||||
|
||||
|
@ -29,23 +35,27 @@ impl<'a> Core<'a> {
|
|||
|
||||
let print_folder_name: bool = dirs.len() + files.len() > 1;
|
||||
|
||||
if !files.is_empty() {
|
||||
if !files.is_empty() && !self.options.display_tree {
|
||||
let mut file_batch = Batch::from(files);
|
||||
file_batch.sort();
|
||||
display.print_outputs(self.get_batch_outputs(&file_batch));
|
||||
self.display
|
||||
.print_outputs(self.get_batch_outputs(&file_batch));
|
||||
}
|
||||
|
||||
dirs.sort_unstable();
|
||||
|
||||
for dir in dirs {
|
||||
if let Some(folder_batch) = self.list_folder_content(dir.as_path()) {
|
||||
if print_folder_name || self.options.recursive {
|
||||
if (print_folder_name || self.options.recursive) && !self.options.display_tree {
|
||||
println!("\n{}:", dir.display())
|
||||
}
|
||||
|
||||
display.print_outputs(self.get_batch_outputs(&folder_batch));
|
||||
if self.options.display_tree {
|
||||
self.display_as_tree(folder_batch, depth);
|
||||
} else if self.options.recursive {
|
||||
self.display
|
||||
.print_outputs(self.get_batch_outputs(&folder_batch));
|
||||
|
||||
if self.options.recursive {
|
||||
let folder_dirs = folder_batch
|
||||
.into_iter()
|
||||
.filter_map(|x| {
|
||||
|
@ -56,12 +66,32 @@ impl<'a> Core<'a> {
|
|||
}
|
||||
}).collect();
|
||||
|
||||
self.run(folder_dirs);
|
||||
self.run_inner(folder_dirs, depth);
|
||||
} else {
|
||||
self.display
|
||||
.print_outputs(self.get_batch_outputs(&folder_batch));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_as_tree(&self, batch: Batch, depth: usize) {
|
||||
let last_idx = batch.len();
|
||||
|
||||
for (idx, elem) in batch.into_iter().enumerate() {
|
||||
let last = !(idx + 1 == last_idx);
|
||||
|
||||
if elem.file_type == FileType::Directory {
|
||||
self.display
|
||||
.print_tree_row(elem.name.render().to_string(), depth, last);
|
||||
self.run_inner(vec![elem.path], depth + 1);
|
||||
} else {
|
||||
self.display
|
||||
.print_tree_row(elem.name.render().to_string(), depth, last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_batch_outputs<'b>(&self, batch: &'b Batch) -> Vec<String> {
|
||||
if self.options.display_long {
|
||||
batch.get_long_output()
|
||||
|
|
|
@ -2,6 +2,10 @@ use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
|||
use terminal_size::terminal_size;
|
||||
use Options;
|
||||
|
||||
const EDGE: &'static str = "├──";
|
||||
const LINE: &'static str = "│ ";
|
||||
const CORNER: &'static str = "└──";
|
||||
|
||||
pub struct Display<'a> {
|
||||
options: &'a Options,
|
||||
}
|
||||
|
@ -44,6 +48,25 @@ impl<'a> Display<'a> {
|
|||
);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn print_one_per_line(&self, outputs: &[String]) {
|
||||
let mut res = String::new();
|
||||
for output in outputs {
|
||||
|
|
|
@ -23,6 +23,7 @@ pub struct Options {
|
|||
pub display_all: bool,
|
||||
pub display_long: bool,
|
||||
pub display_online: bool,
|
||||
pub display_tree: bool,
|
||||
pub recursive: bool,
|
||||
}
|
||||
|
||||
|
@ -34,12 +35,14 @@ fn main() {
|
|||
.arg(Arg::with_name("long").short("l").long("long"))
|
||||
.arg(Arg::with_name("oneline").short("1").long("oneline"))
|
||||
.arg(Arg::with_name("recursive").short("R").long("recursive"))
|
||||
.arg(Arg::with_name("tree").long("tree"))
|
||||
.get_matches();
|
||||
|
||||
let options = Options {
|
||||
display_all: matches.is_present("all"),
|
||||
display_long: matches.is_present("long"),
|
||||
display_online: matches.is_present("oneline"),
|
||||
display_tree: matches.is_present("tree"),
|
||||
recursive: matches.is_present("recursive"),
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue