From 572b0f6b702db71f181526ebe58c68e64e9441c5 Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszczyk Date: Mon, 30 Jan 2023 20:31:38 +0100 Subject: [PATCH] Add coloring of multihardlinks filenames --- man/exa_colors.5.md | 3 +++ src/fs/file.rs | 5 +++++ src/output/file_name.rs | 20 ++++++++++++-------- src/theme/default_theme.rs | 1 + src/theme/mod.rs | 4 ++++ src/theme/ui_styles.rs | 6 ++++-- 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/man/exa_colors.5.md b/man/exa_colors.5.md index c775f0a1..cde8641a 100644 --- a/man/exa_colors.5.md +++ b/man/exa_colors.5.md @@ -76,6 +76,9 @@ LIST OF CODES `or` : symlinks with no target +`mh` +: files containing multiple hard links + `EXA_COLORS` can use many more: diff --git a/src/fs/file.rs b/src/fs/file.rs index ea83f08b..c27eddba 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -279,6 +279,11 @@ impl<'dir> File<'dir> { } } + /// Whether there are multiple hard links to this file. + pub fn has_multiple_hard_links(&self) -> bool { + self.links().multiple + } + /// This file’s inode. pub fn inode(&self) -> f::Inode { f::Inode(self.metadata.ino()) diff --git a/src/output/file_name.rs b/src/output/file_name.rs index b6a38c0e..a996cdcb 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -300,14 +300,15 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> { } match self.file { - f if f.is_directory() => self.colours.directory(), - f if f.is_executable_file() => self.colours.executable_file(), - f if f.is_link() => self.colours.symlink(), - f if f.is_pipe() => self.colours.pipe(), - f if f.is_block_device() => self.colours.block_device(), - f if f.is_char_device() => self.colours.char_device(), - f if f.is_socket() => self.colours.socket(), - f if ! f.is_file() => self.colours.special(), + f if f.is_directory() => self.colours.directory(), + f if f.is_executable_file() => self.colours.executable_file(), + f if f.is_link() => self.colours.symlink(), + f if f.is_pipe() => self.colours.pipe(), + f if f.is_block_device() => self.colours.block_device(), + f if f.is_char_device() => self.colours.char_device(), + f if f.is_socket() => self.colours.socket(), + f if f.has_multiple_hard_links() => self.colours.multiple_hard_links_file(), + f if ! f.is_file() => self.colours.special(), _ => self.colours.colour_file(self.file), } } @@ -342,6 +343,9 @@ pub trait Colours: FiletypeColours { /// The style to paint a file that has its executable bit set. fn executable_file(&self) -> Style; + /// The style to paint a file that has multiple hard links. + fn multiple_hard_links_file(&self) -> Style; + fn colour_file(&self, file: &File<'_>) -> Style; } diff --git a/src/theme/default_theme.rs b/src/theme/default_theme.rs index b4269b73..2ff02ca8 100644 --- a/src/theme/default_theme.rs +++ b/src/theme/default_theme.rs @@ -76,6 +76,7 @@ impl UiStyles { symlink_path: Cyan.normal(), control_char: Red.normal(), broken_symlink: Red.normal(), + multiple_hard_links: Red.on(Black), broken_path_overlay: Style::default().underline(), } } diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 255f054d..57276fb2 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -300,10 +300,12 @@ impl FileNameColours for Theme { fn control_char(&self) -> Style { self.ui.control_char } fn symlink_path(&self) -> Style { self.ui.symlink_path } fn executable_file(&self) -> Style { self.ui.filekinds.executable } + fn multiple_hard_links_file(&self) -> Style { self.ui.multiple_hard_links } fn colour_file(&self, file: &File<'_>) -> Style { self.exts.colour_file(file).unwrap_or(self.ui.filekinds.normal) } + } @@ -412,6 +414,7 @@ mod customs_test { test!(ls_cd: ls "cd=35", exa "" => colours c -> { c.filekinds.char_device = Purple.normal(); }); test!(ls_ln: ls "ln=34", exa "" => colours c -> { c.filekinds.symlink = Blue.normal(); }); test!(ls_or: ls "or=33", exa "" => colours c -> { c.broken_symlink = Yellow.normal(); }); + test!(ls_mh: ls "mh=32", exa "" => colours c -> { c.multiple_hard_links = Green.normal(); }); // EXA_COLORS can affect all those colours too: test!(exa_di: ls "", exa "di=32" => colours c -> { c.filekinds.directory = Green.normal(); }); @@ -423,6 +426,7 @@ mod customs_test { test!(exa_cd: ls "", exa "cd=34" => colours c -> { c.filekinds.char_device = Blue.normal(); }); test!(exa_ln: ls "", exa "ln=33" => colours c -> { c.filekinds.symlink = Yellow.normal(); }); test!(exa_or: ls "", exa "or=32" => colours c -> { c.broken_symlink = Green.normal(); }); + test!(exa_mh: ls "", exa "mh=31" => colours c -> { c.multiple_hard_links = Red.normal(); }); // EXA_COLORS will even override options from LS_COLORS: test!(ls_exa_di: ls "di=31", exa "di=32" => colours c -> { c.filekinds.directory = Green.normal(); }); diff --git a/src/theme/ui_styles.rs b/src/theme/ui_styles.rs index f92c5442..cfb5780d 100644 --- a/src/theme/ui_styles.rs +++ b/src/theme/ui_styles.rs @@ -24,6 +24,7 @@ pub struct UiStyles { pub symlink_path: Style, pub control_char: Style, pub broken_symlink: Style, + pub multiple_hard_links: Style, pub broken_path_overlay: Style, } @@ -127,10 +128,11 @@ impl UiStyles { "cd" => self.filekinds.char_device = pair.to_style(), // CHR "ln" => self.filekinds.symlink = pair.to_style(), // LINK "or" => self.broken_symlink = pair.to_style(), // ORPHAN + "mh" => self.multiple_hard_links = pair.to_style(), // MULTIHARDLINK _ => return false, // Codes we don’t do anything with: - // MULTIHARDLINK, DOOR, SETUID, SETGID, CAPABILITY, - // STICKY_OTHER_WRITABLE, OTHER_WRITABLE, STICKY, MISSING + // DOOR, SETUID, SETGID, CAPABILITY, STICKY_OTHER_WRITABLE, + // OTHER_WRITABLE, STICKY, MISSING } true }