Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions src/options/file_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ use crate::options::{flags, OptionsError, NumberSource};
use crate::options::parser::MatchedFlags;
use crate::options::vars::{self, Vars};

use crate::output::file_name::{Options, Classify, ShowIcons};
use crate::output::file_name::{Options, Classify, UseIcons};


impl Options {
pub fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
pub fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V, is_a_tty: bool) -> Result<Self, OptionsError> {
let classify = Classify::deduce(matches)?;
let show_icons = ShowIcons::deduce(matches, vars)?;
let show_icons = UseIcons::deduce(matches, vars)?;

Ok(Self { classify, show_icons })
Ok(Self { classify, show_icons, is_a_tty })
}
}

Expand All @@ -23,24 +23,40 @@ impl Classify {
}
}

impl ShowIcons {
impl UseIcons {
pub fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
if matches.has(&flags::NO_ICONS)? || !matches.has(&flags::ICONS)? {
Ok(Self::Off)
enum AlwaysOrAuto { Always, Automatic }

let mode_opt = matches.get(&flags::ICONS)?;
if matches.has(&flags::NO_ICONS)? || (!matches.has(&flags::ICONS)? && mode_opt.is_none()) {
return Ok(Self::Never);
}
else if let Some(columns) = vars.get(vars::EXA_ICON_SPACING).and_then(|s| s.into_string().ok()) {

let mode = match mode_opt {
Some(word) => match word.to_str() {
Some("always") => AlwaysOrAuto::Always,
Some("auto") | Some("automatic") => AlwaysOrAuto::Automatic,
Some("never") => return Ok(Self::Never),
_ => return Err(OptionsError::BadArgument(&flags::COLOR, word.into()))
}
None => AlwaysOrAuto::Automatic,
};

let width = if let Some(columns) = vars.get(vars::EXA_ICON_SPACING).and_then(|s| s.into_string().ok()) {
match columns.parse() {
Ok(width) => {
Ok(Self::On(width))
}
Ok(width) => width,
Err(e) => {
let source = NumberSource::Env(vars::EXA_ICON_SPACING);
Err(OptionsError::FailedParse(columns, source, e))
return Err(OptionsError::FailedParse(columns, source, e));
}
}
}
else {
Ok(Self::On(1))
} else {
1
};

match mode {
AlwaysOrAuto::Always => Ok(Self::Always(width)),
AlwaysOrAuto::Automatic => Ok(Self::Automatic(width)),
}
}
}
4 changes: 3 additions & 1 deletion src/options/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ pub static BYTES: Arg = Arg { short: Some(b'B'), long: "bytes", takes_
pub static GROUP: Arg = Arg { short: Some(b'g'), long: "group", takes_value: TakesValue::Forbidden };
pub static NUMERIC: Arg = Arg { short: Some(b'n'), long: "numeric", takes_value: TakesValue::Forbidden };
pub static HEADER: Arg = Arg { short: Some(b'h'), long: "header", takes_value: TakesValue::Forbidden };
pub static ICONS: Arg = Arg { short: None, long: "icons", takes_value: TakesValue::Forbidden };
// pub static ICONS: Arg = Arg { short: None, long: "icons", takes_value: TakesValue::Forbidden };
pub static ICONS: Arg = Arg { short: None, long: "icons", takes_value: TakesValue::Optional(Some(ICONS_MODE)) };
const ICONS_MODE: &[&str] = &["always", "auto", "never"];
pub static INODE: Arg = Arg { short: Some(b'i'), long: "inode", takes_value: TakesValue::Forbidden };
pub static LINKS: Arg = Arg { short: Some(b'H'), long: "links", takes_value: TakesValue::Forbidden };
pub static MODIFIED: Arg = Arg { short: Some(b'm'), long: "modified", takes_value: TakesValue::Forbidden };
Expand Down
2 changes: 1 addition & 1 deletion src/options/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl View {
pub fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
let mode = Mode::deduce(matches, vars)?;
let width = TerminalWidth::deduce(vars)?;
let file_style = FileStyle::deduce(matches, vars)?;
let file_style = FileStyle::deduce(matches, vars, width.actual_terminal_width().is_some())?;
Ok(Self { mode, width, file_style })
}
}
Expand Down
30 changes: 21 additions & 9 deletions src/output/file_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ pub struct Options {
pub classify: Classify,

/// Whether to prepend icon characters before file names.
pub show_icons: ShowIcons,
pub show_icons: UseIcons,

/// Whether we are in a console or redirecting the output
pub is_a_tty: bool,
}

impl Options {
Expand Down Expand Up @@ -74,14 +77,16 @@ impl Default for Classify {

/// Whether and how to show icons.
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum ShowIcons {
pub enum UseIcons {
/// Display icons next to file names, with the given number of spaces between
/// the icon and the file name, even when output isn’t going to a terminal.
Always(u32),

/// Don’t show icons at all.
Off,
/// Same as Always, but only when output is going to a terminal, not otherwise.
Automatic(u32),

/// Show icons next to file names, with the given number of spaces between
/// the icon and the file name.
On(u32),
/// Never display them, even when output is going to a terminal.
Never,
}


Expand Down Expand Up @@ -125,7 +130,13 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
pub fn paint(&self) -> TextCellContents {
let mut bits = Vec::new();

if let ShowIcons::On(spaces_count) = self.options.show_icons {
let spaces_count_opt = match self.options.show_icons {
UseIcons::Always(spaces_count) => Some(spaces_count),
UseIcons::Automatic(spaces_count) if self.options.is_a_tty => Some(spaces_count),
_ => None,
};

if let Some(spaces_count) = spaces_count_opt {
let style = iconify_style(self.style());
let file_icon = icon_for_file(self.file).to_string();

Expand Down Expand Up @@ -170,7 +181,8 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
if ! target.name.is_empty() {
let target_options = Options {
classify: Classify::JustFilenames,
show_icons: ShowIcons::Off,
show_icons: UseIcons::Never,
is_a_tty: self.options.is_a_tty,
};

let target_name = FileName {
Expand Down