From 95dcb2fd6c67bb1e406f5129451262fd8739729b Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Sun, 9 Mar 2025 15:34:55 -0700 Subject: [PATCH] Add `filesize.show_unit` config option (#15276) # Description Continuation of #15271. This PR adds the `$env.config.filesize.show_unit` option to allow the ability to omit the filesize unit. Useful if `$env.config.filesize.unit` is set to a fixed unit, and you don't want the same unit repeated over and over. # User-Facing Changes - Adds the `$env.config.filesize.show_unit` option. --- crates/nu-protocol/src/config/filesize.rs | 5 +++ crates/nu-protocol/src/value/filesize.rs | 34 ++++++++++++++++++- .../nu-utils/src/default_files/doc_config.nu | 7 +++- crates/nu-utils/src/locale.rs | 2 ++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/crates/nu-protocol/src/config/filesize.rs b/crates/nu-protocol/src/config/filesize.rs index 863f9d8293..3b0b27824a 100644 --- a/crates/nu-protocol/src/config/filesize.rs +++ b/crates/nu-protocol/src/config/filesize.rs @@ -11,6 +11,7 @@ impl IntoValue for FilesizeUnitFormat { #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct FilesizeConfig { pub unit: FilesizeUnitFormat, + pub show_unit: bool, pub precision: Option, } @@ -18,6 +19,7 @@ impl FilesizeConfig { pub fn formatter(&self) -> FilesizeFormatter { FilesizeFormatter::new() .unit(self.unit) + .show_unit(self.show_unit) .precision(self.precision) .locale(get_system_locale()) // TODO: cache this somewhere or pass in as argument } @@ -31,6 +33,7 @@ impl Default for FilesizeConfig { fn default() -> Self { Self { unit: FilesizeUnitFormat::Metric, + show_unit: true, precision: Some(1), } } @@ -67,6 +70,7 @@ impl UpdateFromValue for FilesizeConfig { errors.type_mismatch(path, Type::String, val) } } + "show_unit" => self.show_unit.update(val, path, errors), "precision" => match *val { Value::Nothing { .. } => self.precision = None, Value::Int { val, .. } if val >= 0 => self.precision = Some(val as usize), @@ -83,6 +87,7 @@ impl IntoValue for FilesizeConfig { fn into_value(self, span: Span) -> Value { record! { "unit" => self.unit.into_value(span), + "show_unit" => self.show_unit.into_value(span), "precision" => self.precision.map(|x| x as i64).into_value(span), } .into_value(span) diff --git a/crates/nu-protocol/src/value/filesize.rs b/crates/nu-protocol/src/value/filesize.rs index cf748289de..5a451b1f0e 100644 --- a/crates/nu-protocol/src/value/filesize.rs +++ b/crates/nu-protocol/src/value/filesize.rs @@ -610,6 +610,7 @@ impl FromStr for FilesizeUnitFormat { /// /// [`FilesizeFormatter`] is a builder struct that you can modify via the following methods: /// - [`unit`](Self::unit) +/// - [`show_unit`](Self::show_unit) /// - [`precision`](Self::precision) /// - [`locale`](Self::locale) /// @@ -637,6 +638,7 @@ impl FromStr for FilesizeUnitFormat { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct FilesizeFormatter { unit: FilesizeUnitFormat, + show_unit: bool, precision: Option, locale: Locale, } @@ -646,12 +648,14 @@ impl FilesizeFormatter { /// /// The default formatter has: /// - a [`unit`](Self::unit) of [`FilesizeUnitFormat::Metric`]. + /// - a [`show_unit`](Self::show_unit) of `true`. /// - a [`precision`](Self::precision) of `None`. /// - a [`locale`](Self::locale) of [`Locale::en_US_POSIX`] /// (a very plain format with no thousands separators). pub fn new() -> Self { FilesizeFormatter { unit: FilesizeUnitFormat::Metric, + show_unit: true, precision: None, locale: Locale::en_US_POSIX, } @@ -682,6 +686,30 @@ impl FilesizeFormatter { self } + /// Sets whether to show or omit the file size unit in the formatted output. + /// + /// This setting can be used to disable the unit formatting from [`FilesizeFormatter`] + /// and instead provide your own. + /// + /// Note that the [`FilesizeUnitFormat`] provided to [`unit`](Self::unit) is still used to + /// format the numeric portion of a [`Filesize`]. So, setting `show_unit` to `false` is only + /// recommended for [`FilesizeUnitFormat::Unit`], since this will keep the unit the same + /// for all [`Filesize`]s. [`FilesizeUnitFormat::Metric`] and [`FilesizeUnitFormat::Binary`], + /// on the other hand, will adapt the unit to match the magnitude of each formatted [`Filesize`]. + /// + /// # Examples + /// ``` + /// # use nu_protocol::{Filesize, FilesizeFormatter, FilesizeUnit}; + /// let filesize = Filesize::from_unit(4, FilesizeUnit::KiB).unwrap(); + /// let formatter = FilesizeFormatter::new().show_unit(false); + /// + /// assert_eq!(formatter.unit(FilesizeUnit::B).format(filesize).to_string(), "4096"); + /// assert_eq!(format!("{} KB", formatter.unit(FilesizeUnit::KiB).format(filesize)), "4 KB"); + /// ``` + pub fn show_unit(self, show_unit: bool) -> Self { + Self { show_unit, ..self } + } + /// Set the number of digits to display after the decimal place. /// /// Note that digits after the decimal place will never be shown if: @@ -790,6 +818,7 @@ impl fmt::Display for FormattedFilesize { let Self { filesize, format } = *self; let FilesizeFormatter { unit, + show_unit, precision, locale, } = format; @@ -839,7 +868,10 @@ impl fmt::Display for FormattedFilesize { } } - write!(f, " {unit}")?; + if show_unit { + write!(f, " {unit}")?; + } + Ok(()) } } diff --git a/crates/nu-utils/src/default_files/doc_config.nu b/crates/nu-utils/src/default_files/doc_config.nu index b5817985e4..d2a4d5195e 100644 --- a/crates/nu-utils/src/default_files/doc_config.nu +++ b/crates/nu-utils/src/default_files/doc_config.nu @@ -381,9 +381,14 @@ $env.config.datetime_format.normal = "%m/%d/%y %I:%M:%S%p" # Otherwise, setting this to one of the filesize units will use that particular unit when displaying all file sizes. $env.config.filesize.unit = 'metric' +# filesize.show_unit (bool): +# Whether to show or hide the file size unit. Useful if `$env.config.filesize.unit` is set to a fixed unit, +# and you don't want that same unit repeated over and over again in which case you can set this to `false`. +$env.config.filesize.show_unit = true + # filesize.precision (int or nothing): # The number of digits to display after the decimal point for file sizes. -# When set to `null`, all digits after the decimal point will be displayed. +# When set to `null`, all digits after the decimal point, if any, will be displayed. $env.config.filesize.precision = 1 # --------------------- diff --git a/crates/nu-utils/src/locale.rs b/crates/nu-utils/src/locale.rs index 663756814b..033e4caeb6 100644 --- a/crates/nu-utils/src/locale.rs +++ b/crates/nu-utils/src/locale.rs @@ -29,6 +29,8 @@ pub fn get_system_locale_string() -> Option { }, #[cfg(test)] { + // For tests, we use the same locale on all systems. + // To override this, set `LOCALE_OVERRIDE_ENV_VAR`. || Some(Locale::en_US_POSIX.name().to_owned()) }, )