Skip to content

Commit

Permalink
Support ln=target in LS_COLORS (#774)
Browse files Browse the repository at this point in the history
Setting "ln=target" highlights a link in the same color as the referred
file. Dangling/orphaned links are always colored using the specified
"or=" color.
  • Loading branch information
LarsHaalck committed Sep 24, 2021
1 parent ec78620 commit e014f13
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 27 deletions.
16 changes: 15 additions & 1 deletion src/output/file_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,21 @@ 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_link() => {
match self.colours.symlink() {
crate::theme::LinkStyle::AnsiStyle(x) => x,
_ => {
if let FileTarget::Ok(file) = self.target.as_ref().unwrap() {
return FileName {
file: &file,
target: None,
..*self
}.style()
}
return Style::default();
}
}
}
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(),
Expand Down
12 changes: 8 additions & 4 deletions src/output/render/filetype.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use ansi_term::{ANSIString, Style};

use crate::fs::fields as f;

use crate::{fs::fields as f, theme::LinkStyle};

impl f::Type {
pub fn render<C: Colours>(self, colours: &C) -> ANSIString<'static> {
match self {
Self::File => colours.normal().paint("."),
Self::Directory => colours.directory().paint("d"),
Self::Pipe => colours.pipe().paint("|"),
Self::Link => colours.symlink().paint("l"),
Self::Link => {
match colours.symlink() {
LinkStyle::AnsiStyle(s) => s.paint("l"),
LinkStyle::Target => colours.normal().paint("l")
}
}
Self::BlockDevice => colours.block_device().paint("b"),
Self::CharDevice => colours.char_device().paint("c"),
Self::Socket => colours.socket().paint("s"),
Expand All @@ -23,7 +27,7 @@ pub trait Colours {
fn normal(&self) -> Style;
fn directory(&self) -> Style;
fn pipe(&self) -> Style;
fn symlink(&self) -> Style;
fn symlink(&self) -> LinkStyle;
fn block_device(&self) -> Style;
fn char_device(&self) -> Style;
fn socket(&self) -> Style;
Expand Down
2 changes: 1 addition & 1 deletion src/theme/default_theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl UiStyles {
filekinds: FileKinds {
normal: Style::default(),
directory: Blue.bold(),
symlink: Cyan.normal(),
symlink: LinkStyle::AnsiStyle(Cyan.normal()),
pipe: Yellow.normal(),
block_device: Yellow.bold(),
char_device: Yellow.bold(),
Expand Down
40 changes: 21 additions & 19 deletions src/theme/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::output::render;
mod ui_styles;
pub use self::ui_styles::UiStyles;
pub use self::ui_styles::Size as SizeColours;
pub use self::ui_styles::LinkStyle as LinkStyle;

mod lsc;
pub use self::lsc::LSColors;
Expand Down Expand Up @@ -210,7 +211,7 @@ impl render::FiletypeColours for Theme {
fn normal(&self) -> Style { self.ui.filekinds.normal }
fn directory(&self) -> Style { self.ui.filekinds.directory }
fn pipe(&self) -> Style { self.ui.filekinds.pipe }
fn symlink(&self) -> Style { self.ui.filekinds.symlink }
fn symlink(&self) -> LinkStyle { self.ui.filekinds.symlink }
fn block_device(&self) -> Style { self.ui.filekinds.block_device }
fn char_device(&self) -> Style { self.ui.filekinds.char_device }
fn socket(&self) -> Style { self.ui.filekinds.socket }
Expand Down Expand Up @@ -403,26 +404,27 @@ mod customs_test {


// LS_COLORS can affect all of these colours:
test!(ls_di: ls "di=31", exa "" => colours c -> { c.filekinds.directory = Red.normal(); });
test!(ls_ex: ls "ex=32", exa "" => colours c -> { c.filekinds.executable = Green.normal(); });
test!(ls_fi: ls "fi=33", exa "" => colours c -> { c.filekinds.normal = Yellow.normal(); });
test!(ls_pi: ls "pi=34", exa "" => colours c -> { c.filekinds.pipe = Blue.normal(); });
test!(ls_so: ls "so=35", exa "" => colours c -> { c.filekinds.socket = Purple.normal(); });
test!(ls_bd: ls "bd=36", exa "" => colours c -> { c.filekinds.block_device = Cyan.normal(); });
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_di: ls "di=31", exa "" => colours c -> { c.filekinds.directory = Red.normal(); });
test!(ls_ex: ls "ex=32", exa "" => colours c -> { c.filekinds.executable = Green.normal(); });
test!(ls_fi: ls "fi=33", exa "" => colours c -> { c.filekinds.normal = Yellow.normal(); });
test!(ls_pi: ls "pi=34", exa "" => colours c -> { c.filekinds.pipe = Blue.normal(); });
test!(ls_so: ls "so=35", exa "" => colours c -> { c.filekinds.socket = Purple.normal(); });
test!(ls_bd: ls "bd=36", exa "" => colours c -> { c.filekinds.block_device = Cyan.normal(); });
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 = LinkStyle::AnsiStyle(Blue.normal()); });
test!(ls_or: ls "or=33", exa "" => colours c -> { c.broken_symlink = Yellow.normal(); });
test!(ls_ln_target: ls "ln=target", exa "" => colours c -> { c.filekinds.symlink = LinkStyle::Target; });

// EXA_COLORS can affect all those colours too:
test!(exa_di: ls "", exa "di=32" => colours c -> { c.filekinds.directory = Green.normal(); });
test!(exa_ex: ls "", exa "ex=33" => colours c -> { c.filekinds.executable = Yellow.normal(); });
test!(exa_fi: ls "", exa "fi=34" => colours c -> { c.filekinds.normal = Blue.normal(); });
test!(exa_pi: ls "", exa "pi=35" => colours c -> { c.filekinds.pipe = Purple.normal(); });
test!(exa_so: ls "", exa "so=36" => colours c -> { c.filekinds.socket = Cyan.normal(); });
test!(exa_bd: ls "", exa "bd=35" => colours c -> { c.filekinds.block_device = Purple.normal(); });
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_di: ls "", exa "di=32" => colours c -> { c.filekinds.directory = Green.normal(); });
test!(exa_ex: ls "", exa "ex=33" => colours c -> { c.filekinds.executable = Yellow.normal(); });
test!(exa_fi: ls "", exa "fi=34" => colours c -> { c.filekinds.normal = Blue.normal(); });
test!(exa_pi: ls "", exa "pi=35" => colours c -> { c.filekinds.pipe = Purple.normal(); });
test!(exa_so: ls "", exa "so=36" => colours c -> { c.filekinds.socket = Cyan.normal(); });
test!(exa_bd: ls "", exa "bd=35" => colours c -> { c.filekinds.block_device = Purple.normal(); });
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 = LinkStyle::AnsiStyle(Yellow.normal()); });
test!(exa_or: ls "", exa "or=32" => colours c -> { c.broken_symlink = Green.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(); });
Expand Down
20 changes: 18 additions & 2 deletions src/theme/ui_styles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,22 @@ pub struct UiStyles {
pub broken_path_overlay: Style,
}


#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LinkStyle {
AnsiStyle(Style),
Target
}

impl Default for LinkStyle {
fn default() -> Self { LinkStyle::AnsiStyle(Style::default()) }
}

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct FileKinds {
pub normal: Style,
pub directory: Style,
pub symlink: Style,
pub symlink: LinkStyle,
pub pipe: Style,
pub block_device: Style,
pub char_device: Style,
Expand Down Expand Up @@ -125,7 +136,12 @@ impl UiStyles {
"so" => self.filekinds.socket = pair.to_style(), // SOCK
"bd" => self.filekinds.block_device = pair.to_style(), // BLK
"cd" => self.filekinds.char_device = pair.to_style(), // CHR
"ln" => self.filekinds.symlink = pair.to_style(), // LINK
"ln" => {
self.filekinds.symlink = match pair.value {
"target" => LinkStyle::Target,
_ => LinkStyle::AnsiStyle(pair.to_style())
}
}
"or" => self.broken_symlink = pair.to_style(), // ORPHAN
_ => return false,
// Codes we don’t do anything with:
Expand Down

0 comments on commit e014f13

Please sign in to comment.