2019-02-09 10:41:42 +00:00
|
|
|
use crate::color::{self, Colors};
|
|
|
|
use crate::display;
|
2019-05-08 21:20:26 +00:00
|
|
|
use crate::flags::{Display, Flags, IconTheme, Layout, WhenFlag};
|
2019-02-09 10:41:42 +00:00
|
|
|
use crate::icon::{self, Icons};
|
|
|
|
use crate::meta::Meta;
|
|
|
|
use crate::sort;
|
2019-03-26 22:12:21 +00:00
|
|
|
use std::fs;
|
2019-01-20 10:22:14 +00:00
|
|
|
use std::path::PathBuf;
|
2018-12-05 19:32:25 +00:00
|
|
|
use terminal_size::terminal_size;
|
2018-11-16 13:19:07 +00:00
|
|
|
|
2018-12-05 19:54:17 +00:00
|
|
|
pub struct Core {
|
2018-12-08 13:00:42 +00:00
|
|
|
flags: Flags,
|
2018-12-08 18:52:56 +00:00
|
|
|
icons: Icons,
|
2019-01-20 10:22:14 +00:00
|
|
|
//display: Display,
|
2018-12-05 19:12:33 +00:00
|
|
|
colors: Colors,
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-05 19:54:17 +00:00
|
|
|
impl Core {
|
2018-12-13 15:50:47 +00:00
|
|
|
pub fn new(flags: Flags) -> Self {
|
2018-12-05 19:32:25 +00:00
|
|
|
// terminal_size allows us to know if the stdout is a tty or not.
|
2018-12-05 19:54:17 +00:00
|
|
|
let tty_available = terminal_size().is_some();
|
2018-12-05 19:32:25 +00:00
|
|
|
|
2019-05-07 17:57:01 +00:00
|
|
|
// determine color output availability (and initialize color output (for Windows 10))
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
let console_color_ok = true;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
let console_color_ok = ansi_term::enable_ansi_support().is_ok();
|
|
|
|
|
2018-12-08 13:00:42 +00:00
|
|
|
let mut inner_flags = flags;
|
2018-12-05 19:54:17 +00:00
|
|
|
|
2019-05-07 17:57:01 +00:00
|
|
|
let color_theme = match (tty_available && console_color_ok, flags.color) {
|
2019-01-29 17:16:55 +00:00
|
|
|
(_, WhenFlag::Never) | (false, WhenFlag::Auto) => color::Theme::NoColor,
|
|
|
|
_ => color::Theme::Default,
|
2018-12-13 13:51:31 +00:00
|
|
|
};
|
|
|
|
|
2019-01-29 17:16:55 +00:00
|
|
|
let icon_theme = match (tty_available, flags.icon, flags.icon_theme) {
|
|
|
|
(_, WhenFlag::Never, _) | (false, WhenFlag::Auto, _) => icon::Theme::NoIcon,
|
|
|
|
(_, _, IconTheme::Fancy) => icon::Theme::Fancy,
|
|
|
|
(_, _, IconTheme::Unicode) => icon::Theme::Unicode,
|
2018-12-08 13:21:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if !tty_available {
|
2018-12-05 19:54:17 +00:00
|
|
|
// The output is not a tty, this means the command is piped. (ex: lsd -l | less)
|
|
|
|
//
|
|
|
|
// Most of the programs does not handle correctly the ansi colors
|
|
|
|
// or require a raw output (like the `wc` command).
|
2019-03-08 17:28:35 +00:00
|
|
|
inner_flags.layout = Layout::OneLine { long: false };
|
2018-12-05 19:32:25 +00:00
|
|
|
};
|
|
|
|
|
2018-12-13 15:50:47 +00:00
|
|
|
Self {
|
2018-12-08 13:00:42 +00:00
|
|
|
flags,
|
2019-01-20 10:22:14 +00:00
|
|
|
//display: Display::new(inner_flags),
|
2018-12-13 13:51:31 +00:00
|
|
|
colors: Colors::new(color_theme),
|
|
|
|
icons: Icons::new(icon_theme),
|
2018-12-04 13:54:56 +00:00
|
|
|
}
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
pub fn run(self, paths: Vec<PathBuf>) {
|
2019-01-20 10:22:14 +00:00
|
|
|
let mut meta_list = self.fetch(paths);
|
|
|
|
|
|
|
|
self.sort(&mut meta_list);
|
|
|
|
self.display(meta_list)
|
2018-12-04 13:54:56 +00:00
|
|
|
}
|
2018-12-02 16:22:51 +00:00
|
|
|
|
2019-01-20 10:22:14 +00:00
|
|
|
fn fetch(&self, paths: Vec<PathBuf>) -> Vec<Meta> {
|
|
|
|
let mut meta_list = Vec::with_capacity(paths.len());
|
2018-12-19 18:00:21 +00:00
|
|
|
|
2019-03-08 17:28:35 +00:00
|
|
|
let depth = if self.flags.recursive || self.flags.layout == Layout::Tree {
|
2019-01-20 10:22:14 +00:00
|
|
|
self.flags.recursion_depth
|
|
|
|
} else {
|
|
|
|
1
|
|
|
|
};
|
2018-11-16 13:19:07 +00:00
|
|
|
|
2018-12-04 12:29:54 +00:00
|
|
|
for path in paths {
|
2019-03-28 04:04:49 +00:00
|
|
|
let absolute_path = match fs::canonicalize(&path) {
|
2019-05-08 20:39:51 +00:00
|
|
|
Ok(path) => path.to_path_buf(),
|
2019-03-28 04:04:49 +00:00
|
|
|
Err(err) => {
|
2019-05-16 21:33:50 +00:00
|
|
|
eprintln!("cannot access '{}': {}", path.display(), err);
|
2019-03-28 04:04:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
};
|
2019-03-27 13:21:03 +00:00
|
|
|
|
2019-05-08 21:20:26 +00:00
|
|
|
let meta = match Meta::from_path(&absolute_path) {
|
|
|
|
Ok(meta) => meta,
|
|
|
|
Err(err) => {
|
|
|
|
eprintln!("cannot access '{}': {}", path.display(), err);
|
|
|
|
continue;
|
|
|
|
}
|
2019-01-20 10:22:14 +00:00
|
|
|
};
|
2019-05-08 20:39:51 +00:00
|
|
|
|
2019-05-08 21:20:26 +00:00
|
|
|
match self.flags.display {
|
|
|
|
Display::DisplayDirectoryItself => {
|
|
|
|
meta_list.push(meta);
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
match meta.recurse_into(depth, self.flags.display) {
|
|
|
|
Ok(Some(content)) => meta_list.extend(content),
|
|
|
|
Ok(None) => (),
|
|
|
|
Err(err) => {
|
|
|
|
eprintln!("cannot access '{}': {}", path.display(), err);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2019-05-08 20:39:51 +00:00
|
|
|
};
|
2018-12-02 16:22:51 +00:00
|
|
|
}
|
2018-12-02 14:05:27 +00:00
|
|
|
|
2019-03-26 22:12:21 +00:00
|
|
|
meta_list
|
2018-11-24 16:42:39 +00:00
|
|
|
}
|
|
|
|
|
2019-01-20 10:22:14 +00:00
|
|
|
fn sort(&self, metas: &mut Vec<Meta>) {
|
|
|
|
metas.sort_unstable_by(|a, b| sort::by_meta(a, b, self.flags));
|
|
|
|
|
|
|
|
for meta in metas {
|
|
|
|
if let Some(ref mut content) = meta.content {
|
|
|
|
self.sort(content);
|
2018-12-04 13:54:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-20 10:22:14 +00:00
|
|
|
fn display(&self, metas: Vec<Meta>) {
|
2019-03-08 17:28:35 +00:00
|
|
|
let output = match self.flags.layout {
|
|
|
|
Layout::OneLine { .. } => {
|
|
|
|
display::one_line(metas, self.flags, &self.colors, &self.icons)
|
|
|
|
}
|
|
|
|
Layout::Tree => display::tree(metas, self.flags, &self.colors, &self.icons),
|
|
|
|
Layout::Grid => display::grid(metas, self.flags, &self.colors, &self.icons),
|
2018-11-24 11:02:39 +00:00
|
|
|
};
|
2019-01-20 10:22:14 +00:00
|
|
|
print!("{}", output);
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
}
|