2019-02-09 11:41:42 +01:00
|
|
|
use crate::color::{self, Colors};
|
|
|
|
use crate::display;
|
2020-09-24 20:09:26 +02:00
|
|
|
use crate::flags::{ColorOption, Display, Flags, IconOption, IconTheme, Layout, SortOrder};
|
2019-02-09 11:41:42 +01:00
|
|
|
use crate::icon::{self, Icons};
|
|
|
|
use crate::meta::Meta;
|
2019-12-11 10:46:41 +01:00
|
|
|
use crate::{print_error, print_output, sort};
|
2019-01-20 11:22:14 +01:00
|
|
|
use std::path::PathBuf;
|
2019-06-18 17:24:40 +10:00
|
|
|
|
2019-11-20 19:34:34 -06:00
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
use std::io;
|
2019-06-18 17:24:40 +10:00
|
|
|
#[cfg(not(target_os = "windows"))]
|
2019-06-18 14:15:57 +10:00
|
|
|
use std::os::unix::io::AsRawFd;
|
2019-06-18 17:24:40 +10:00
|
|
|
|
2019-06-18 14:15:57 +10:00
|
|
|
#[cfg(target_os = "windows")]
|
2018-12-05 20:32:25 +01:00
|
|
|
use terminal_size::terminal_size;
|
2018-11-16 14:19:07 +01:00
|
|
|
|
2018-12-05 20:54:17 +01:00
|
|
|
pub struct Core {
|
2018-12-08 14:00:42 +01:00
|
|
|
flags: Flags,
|
2018-12-08 19:52:56 +01:00
|
|
|
icons: Icons,
|
2019-01-20 11:22:14 +01:00
|
|
|
//display: Display,
|
2018-12-05 20:12:33 +01:00
|
|
|
colors: Colors,
|
2020-08-17 21:26:56 +10:00
|
|
|
sorters: Vec<(SortOrder, sort::SortFn)>,
|
2018-11-16 14:19:07 +01:00
|
|
|
}
|
|
|
|
|
2018-12-05 20:54:17 +01:00
|
|
|
impl Core {
|
2018-12-13 16:50:47 +01:00
|
|
|
pub fn new(flags: Flags) -> Self {
|
2019-06-18 14:15:57 +10:00
|
|
|
// Check through libc if stdout is a tty. Unix specific so not on windows.
|
|
|
|
// Determine color output availability (and initialize color output (for Windows 10))
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
let tty_available = unsafe { libc::isatty(io::stdout().as_raw_fd()) == 1 };
|
2019-06-18 17:24:40 +10:00
|
|
|
|
2019-05-07 12:57:01 -05:00
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
let console_color_ok = true;
|
2019-06-18 14:15:57 +10:00
|
|
|
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
let tty_available = terminal_size().is_some(); // terminal_size allows us to know if the stdout is a tty or not.
|
2019-07-24 15:19:16 +02:00
|
|
|
|
2019-05-07 12:57:01 -05:00
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
let console_color_ok = ansi_term::enable_ansi_support().is_ok();
|
|
|
|
|
2019-03-30 16:28:36 +05:30
|
|
|
let mut inner_flags = flags.clone();
|
2018-12-05 20:54:17 +01:00
|
|
|
|
2020-09-24 20:09:26 +02:00
|
|
|
let color_theme = match (tty_available && console_color_ok, flags.color.when) {
|
|
|
|
(_, ColorOption::Never) | (false, ColorOption::Auto) => color::Theme::NoColor,
|
2019-01-29 18:16:55 +01:00
|
|
|
_ => color::Theme::Default,
|
2018-12-13 14:51:31 +01:00
|
|
|
};
|
|
|
|
|
2020-09-24 20:09:26 +02:00
|
|
|
let icon_theme = match (tty_available, flags.icons.when, flags.icons.theme) {
|
|
|
|
(_, IconOption::Never, _) | (false, IconOption::Auto, _) => icon::Theme::NoIcon,
|
2019-01-29 18:16:55 +01:00
|
|
|
(_, _, IconTheme::Fancy) => icon::Theme::Fancy,
|
|
|
|
(_, _, IconTheme::Unicode) => icon::Theme::Unicode,
|
2018-12-08 14:21:32 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
if !tty_available {
|
2018-12-05 20:54:17 +01: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-10-23 18:13:58 +02:00
|
|
|
inner_flags.layout = Layout::OneLine;
|
2018-12-05 20:32:25 +01:00
|
|
|
};
|
|
|
|
|
2020-08-17 21:26:56 +10:00
|
|
|
let sorters = sort::assemble_sorters(&flags);
|
2019-09-13 18:29:11 +10:00
|
|
|
|
2018-12-13 16:50:47 +01:00
|
|
|
Self {
|
2018-12-08 14:00:42 +01:00
|
|
|
flags,
|
2019-01-20 11:22:14 +01:00
|
|
|
//display: Display::new(inner_flags),
|
2018-12-13 14:51:31 +01:00
|
|
|
colors: Colors::new(color_theme),
|
|
|
|
icons: Icons::new(icon_theme),
|
2020-08-17 21:26:56 +10:00
|
|
|
sorters,
|
2018-12-04 14:54:56 +01:00
|
|
|
}
|
2018-11-16 14:19:07 +01:00
|
|
|
}
|
|
|
|
|
2018-12-04 14:54:56 +01:00
|
|
|
pub fn run(self, paths: Vec<PathBuf>) {
|
2019-01-20 11:22:14 +01:00
|
|
|
let mut meta_list = self.fetch(paths);
|
|
|
|
|
|
|
|
self.sort(&mut meta_list);
|
2019-10-23 17:26:39 +02:00
|
|
|
self.display(&meta_list)
|
2018-12-04 14:54:56 +01:00
|
|
|
}
|
2018-12-02 17:22:51 +01:00
|
|
|
|
2019-01-20 11:22:14 +01:00
|
|
|
fn fetch(&self, paths: Vec<PathBuf>) -> Vec<Meta> {
|
|
|
|
let mut meta_list = Vec::with_capacity(paths.len());
|
2019-05-28 17:51:51 +02:00
|
|
|
let depth = match self.flags.layout {
|
2020-09-24 20:09:26 +02:00
|
|
|
Layout::Tree { .. } => self.flags.recursion.depth,
|
|
|
|
_ if self.flags.recursion.enabled => self.flags.recursion.depth,
|
2019-05-28 17:51:51 +02:00
|
|
|
_ => 1,
|
2019-01-20 11:22:14 +01:00
|
|
|
};
|
2018-11-16 14:19:07 +01:00
|
|
|
|
2018-12-04 13:29:54 +01:00
|
|
|
for path in paths {
|
2020-09-24 20:09:26 +02:00
|
|
|
let mut meta = match Meta::from_path(&path, self.flags.dereference.0) {
|
2019-05-08 23:20:26 +02:00
|
|
|
Ok(meta) => meta,
|
|
|
|
Err(err) => {
|
2020-04-07 13:49:57 +08:00
|
|
|
print_error!("lsd: {}: {}\n", path.display(), err);
|
2019-05-08 23:20:26 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-01-20 11:22:14 +01:00
|
|
|
};
|
2019-05-08 22:39:51 +02:00
|
|
|
|
2019-05-08 23:20:26 +02:00
|
|
|
match self.flags.display {
|
2020-09-24 20:09:26 +02:00
|
|
|
Display::DirectoryItself => {
|
2019-05-08 23:20:26 +02:00
|
|
|
meta_list.push(meta);
|
|
|
|
}
|
|
|
|
_ => {
|
2020-08-22 00:46:59 +05:30
|
|
|
match meta.recurse_into(depth, &self.flags) {
|
2019-05-24 15:30:36 +02:00
|
|
|
Ok(content) => {
|
|
|
|
meta.content = content;
|
|
|
|
meta_list.push(meta);
|
|
|
|
}
|
2019-05-08 23:20:26 +02:00
|
|
|
Err(err) => {
|
2020-04-07 13:49:57 +08:00
|
|
|
print_error!("lsd: {}: {}\n", path.display(), err);
|
2019-05-08 23:20:26 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2019-05-08 22:39:51 +02:00
|
|
|
};
|
2018-12-02 17:22:51 +01:00
|
|
|
}
|
2020-09-24 20:09:26 +02:00
|
|
|
if self.flags.total_size.0 {
|
2019-06-16 20:48:35 +02:00
|
|
|
for meta in &mut meta_list.iter_mut() {
|
|
|
|
meta.calculate_total_size();
|
|
|
|
}
|
|
|
|
}
|
2018-12-02 15:05:27 +01:00
|
|
|
|
2019-03-27 01:12:21 +03:00
|
|
|
meta_list
|
2018-11-24 17:42:39 +01:00
|
|
|
}
|
|
|
|
|
2019-01-20 11:22:14 +01:00
|
|
|
fn sort(&self, metas: &mut Vec<Meta>) {
|
2020-08-17 21:26:56 +10:00
|
|
|
metas.sort_unstable_by(|a, b| sort::by_meta(&self.sorters, a, b));
|
2019-01-20 11:22:14 +01:00
|
|
|
|
|
|
|
for meta in metas {
|
|
|
|
if let Some(ref mut content) = meta.content {
|
|
|
|
self.sort(content);
|
2018-12-04 14:54:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 17:26:39 +02:00
|
|
|
fn display(&self, metas: &[Meta]) {
|
2019-10-24 17:18:42 +02:00
|
|
|
let output = if self.flags.layout == Layout::Tree {
|
|
|
|
display::tree(&metas, &self.flags, &self.colors, &self.icons)
|
|
|
|
} else {
|
|
|
|
display::grid(&metas, &self.flags, &self.colors, &self.icons)
|
2018-11-24 12:02:39 +01:00
|
|
|
};
|
2019-10-24 17:18:42 +02:00
|
|
|
|
2019-12-11 10:46:41 +01:00
|
|
|
print_output!("{}", output);
|
2018-11-16 14:19:07 +01:00
|
|
|
}
|
|
|
|
}
|