diff --git a/rustfmt.toml b/rustfmt.toml deleted file mode 100644 index 24b94cad2..000000000 --- a/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -ignore = ['src/options/flags.rs'] diff --git a/src/options/file_name.rs b/src/options/file_name.rs index a45d35d4e..6b32de087 100644 --- a/src/options/file_name.rs +++ b/src/options/file_name.rs @@ -98,13 +98,19 @@ impl QuoteStyle { } impl EmbedHyperlinks { - fn deduce(matches: &MatchedFlags<'_>) -> Result { - let flagged = matches.has(&flags::HYPERLINK)?; + pub fn deduce(matches: &MatchedFlags<'_>) -> Result { + let Some(word) = matches.get(&flags::HYPERLINK)? else { + return Ok(Self::Automatic) + }; - if flagged { - Ok(Self::On) + if word == "always" { + Ok(Self::Always) + } else if word == "auto" || word == "automatic" { + Ok(Self::Automatic) + } else if word == "never" { + Ok(Self::Never) } else { - Ok(Self::Off) + Err(OptionsError::BadArgument(&flags::HYPERLINK, word.into())) } } } diff --git a/src/options/flags.rs b/src/options/flags.rs index 715f5bbfd..1e1562658 100644 --- a/src/options/flags.rs +++ b/src/options/flags.rs @@ -60,7 +60,7 @@ pub static TIME: Arg = Arg { short: Some(b't'), long: "time", take pub static ACCESSED: Arg = Arg { short: Some(b'u'), long: "accessed", takes_value: TakesValue::Forbidden }; pub static CREATED: Arg = Arg { short: Some(b'U'), long: "created", takes_value: TakesValue::Forbidden }; pub static TIME_STYLE: Arg = Arg { short: None, long: "time-style", takes_value: TakesValue::Necessary(Some(TIME_STYLES)) }; -pub static HYPERLINK: Arg = Arg { short: None, long: "hyperlink", takes_value: TakesValue::Forbidden }; +pub static HYPERLINK: Arg = Arg { short: None, long: "hyperlink", takes_value: TakesValue::Optional(Some(WHEN), "auto") }; pub static MOUNTS: Arg = Arg { short: Some(b'M'), long: "mounts", takes_value: TakesValue::Forbidden }; pub static SMART_GROUP: Arg = Arg { short: None, long: "smart-group", takes_value: TakesValue::Forbidden }; const TIMES: Values = &["modified", "changed", "accessed", "created"]; diff --git a/src/options/theme.rs b/src/options/theme.rs index 80e88f5b4..7963968c8 100644 --- a/src/options/theme.rs +++ b/src/options/theme.rs @@ -1,12 +1,14 @@ use crate::options::parser::MatchedFlags; use crate::options::{flags, vars, OptionsError, Vars}; use crate::output::color_scale::ColorScaleOptions; +use crate::output::file_name::EmbedHyperlinks; use crate::theme::{Definitions, Options, UseColours}; impl Options { pub fn deduce(matches: &MatchedFlags<'_>, vars: &V) -> Result { let use_colours = UseColours::deduce(matches, vars)?; let colour_scale = ColorScaleOptions::deduce(matches, vars)?; + let embed_hyperlinks = EmbedHyperlinks::deduce(matches)?; let definitions = if use_colours == UseColours::Never { Definitions::default() @@ -17,6 +19,7 @@ impl Options { Ok(Self { use_colours, colour_scale, + embed_hyperlinks, definitions, }) } diff --git a/src/output/file_name.rs b/src/output/file_name.rs index 2b0f768e7..ea01440d5 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -52,6 +52,14 @@ impl Options { mounted_fs: file.mount_point_info(), } } + + pub fn do_embed_hyperlinks(&self) -> bool { + match self.embed_hyperlinks { + EmbedHyperlinks::Always => true, + EmbedHyperlinks::Never => false, + EmbedHyperlinks::Automatic => self.is_a_tty, + } + } } /// When displaying a file name, there needs to be some way to handle broken @@ -114,8 +122,14 @@ pub enum ShowIcons { /// Whether to embed hyperlinks. #[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum EmbedHyperlinks { - Off, - On, + /// Embed links even when output isn’t going to a terminal. + Always, + + /// Embed links when output is going to a terminal, but not otherwise. + Automatic, + + /// Never embed links, even when output is going to a terminal. + Never, } /// Whether or not to wrap file names with spaces in quotes. @@ -230,7 +244,7 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> { classify: Classify::JustFilenames, quote_style: QuoteStyle::QuoteSpaces, show_icons: ShowIcons::Never, - embed_hyperlinks: EmbedHyperlinks::Off, + embed_hyperlinks: EmbedHyperlinks::Never, is_a_tty: self.options.is_a_tty, }; @@ -373,7 +387,7 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> { let mut bits = Vec::new(); let mut display_hyperlink = false; - if self.options.embed_hyperlinks == EmbedHyperlinks::On { + if self.options.do_embed_hyperlinks() { if let Some(abs_path) = self .file .absolute_path() diff --git a/src/output/grid.rs b/src/output/grid.rs index 4e6b2ff1c..50cf1c615 100644 --- a/src/output/grid.rs +++ b/src/output/grid.rs @@ -4,8 +4,8 @@ use term_grid as tg; use crate::fs::filter::FileFilter; use crate::fs::File; +use crate::output::file_name::ShowIcons; use crate::output::file_name::{Classify, Options as FileStyle}; -use crate::output::file_name::{EmbedHyperlinks, ShowIcons}; use crate::theme::Theme; use super::file_name::QuoteStyle; @@ -64,33 +64,27 @@ impl<'a> Render<'a> { }; let contents = filename.paint(); let width = match ( - filename.options.embed_hyperlinks, + filename.options.do_embed_hyperlinks(), filename.options.show_icons, ) { - ( - EmbedHyperlinks::On, - ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing), - ) => { + (true, ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing)) => { filename.bare_utf8_width() + classification_width + 1 + (spacing as usize) + space_filename_offset } - (EmbedHyperlinks::On, ShowIcons::Never) => { + (true, ShowIcons::Never) => { filename.bare_utf8_width() + classification_width + space_filename_offset } - ( - EmbedHyperlinks::Off, - ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing), - ) => { + (false, ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing)) => { filename.bare_utf8_width() + classification_width + 1 + (spacing as usize) + space_filename_offset } - (EmbedHyperlinks::Off, _) => *contents.width(), + (false, _) => *contents.width(), }; grid.add(tg::Cell { diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index 3f2044212..262eeb479 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -14,7 +14,7 @@ use crate::output::details::{ Options as DetailsOptions, Render as DetailsRender, Row as DetailsRow, }; use crate::output::file_name::Options as FileStyle; -use crate::output::file_name::{EmbedHyperlinks, ShowIcons}; +use crate::output::file_name::ShowIcons; use crate::output::grid::Options as GridOptions; use crate::output::table::{Options as TableOptions, Row as TableRow, Table}; use crate::output::tree::{TreeDepth, TreeParams}; @@ -186,19 +186,17 @@ impl<'a> Render<'a> { QuoteStyle::QuoteSpaces => 0, // Default case }; let width = match ( - filename.options.embed_hyperlinks, + filename.options.do_embed_hyperlinks(), filename.options.show_icons, ) { - (EmbedHyperlinks::On, ShowIcons::Automatic(spacing)) => { + (true, ShowIcons::Automatic(spacing)) => { filename.bare_utf8_width() + 1 + (spacing as usize) + space_filename_offset } - (EmbedHyperlinks::On, ShowIcons::Always(spacing)) => { + (true, ShowIcons::Always(spacing)) => { filename.bare_utf8_width() + 1 + (spacing as usize) + space_filename_offset } - (EmbedHyperlinks::On, ShowIcons::Never) => { - filename.bare_utf8_width() + space_filename_offset - } - (EmbedHyperlinks::Off, _) => *contents.width(), + (true, ShowIcons::Never) => filename.bare_utf8_width() + space_filename_offset, + (false, _) => *contents.width(), }; TextCell { diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 659d70646..ac90e5df8 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -3,7 +3,7 @@ use ansiterm::Style; use crate::fs::File; use crate::info::filetype::FileType; use crate::output::color_scale::ColorScaleOptions; -use crate::output::file_name::Colours as FileNameColours; +use crate::output::file_name::{Colours as FileNameColours, EmbedHyperlinks}; use crate::output::render; mod ui_styles; @@ -20,6 +20,8 @@ pub struct Options { pub colour_scale: ColorScaleOptions, + pub embed_hyperlinks: EmbedHyperlinks, + pub definitions: Definitions, }