Skip to content

Commit

Permalink
decouple styles from node
Browse files Browse the repository at this point in the history
  • Loading branch information
solidiquis committed May 14, 2023
1 parent 41adfa3 commit 74277fb
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 97 deletions.
12 changes: 12 additions & 0 deletions src/fs/permissions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ pub struct FileMode {
other_permissions: class::Permissions,
}

/// Implements [Display] which presents symbolic notation of file permissions with the extended
/// attributes.
pub struct FileModeXAttrs<'a>(pub &'a FileMode);

impl FileMode {
/// Constructor for [`FileMode`].
pub const fn new(
Expand Down Expand Up @@ -96,6 +100,14 @@ impl Display for FileMode {
}
}

/// For representing file permissions with extended attributes in symbolic notation.
impl Display for FileModeXAttrs<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mode = self.0;
write!(f, "{mode}@")
}
}

/// For the octal representation of permissions
impl Octal for FileMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
18 changes: 4 additions & 14 deletions src/render/grid/cell.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
context::Context,
disk_usage::file_size::FileSize,
render::theme,
styles::{self, PLACEHOLDER},
tree::node::Node,
};
Expand Down Expand Up @@ -54,14 +55,7 @@ impl<'a> Cell<'a> {
match self.kind {
Kind::FileName { prefix } => {
let pre = prefix.unwrap_or("");

let name = node.symlink_target_file_name().map_or_else(
|| Node::stylize(node.file_name(), node.style()),
|target_name| {
let link_name = node.file_name();
Node::stylize_link_name(link_name, target_name, node.style())
},
);
let name = theme::stylize_file_name(node);

if !ctx.icons {
return write!(f, "{pre}{name}");
Expand Down Expand Up @@ -221,14 +215,10 @@ impl<'a> Cell<'a> {
let node = self.node;
let ctx = self.ctx;

let file_mode = node.mode().unwrap();

let formatted_perms = if ctx.octal {
Node::style_octal_permissions(&file_mode)
} else if node.has_xattrs() {
Node::style_sym_permissions(&file_mode, true)
theme::style_oct_permissions(node)
} else {
Node::style_sym_permissions(&file_mode, false)
theme::style_sym_permissions(node)
};

write!(f, "{formatted_perms}")
Expand Down
72 changes: 72 additions & 0 deletions src/render/theme.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::{
fs::permissions::FileModeXAttrs,
styles::{self, ThemesMap},
tree::node::Node,
};
use ansi_term::{Color, Style};
use std::borrow::Cow;

type Theme = Box<dyn FnMut(&Node) -> &'static ThemesMap>;

Expand Down Expand Up @@ -35,3 +38,72 @@ pub fn link_theme_getter() -> Theme {
}
})
}

/// Stylizes the input `file_name` with the provided `style`. If `None` is provided then the
/// underlying `String` is returned unmodified as a [Cow]. If the provided [Node] is a symlink then
/// it will be styled accordingly.
pub fn stylize_file_name(node: &Node) -> Cow<'_, str> {
let name = node.file_name();
let style = node.style();

let Some(target_name) = node.symlink_target_file_name() else {
if let Some(Style {foreground: Some(ref fg), .. }) = style {
let file_name = name.to_string_lossy();
let styled_name = fg.bold().paint(file_name).to_string();
return Cow::from(styled_name);
}

return name.to_string_lossy();
};

if style.is_some() {
let styled_name = stylize_file_name(node);
let target_name = Color::Red.paint(format!("\u{2192} {}", target_name.to_string_lossy()));

return Cow::from(format!("{styled_name} {target_name}"));
}

let link = name.to_string_lossy();
let target = target_name.to_string_lossy();
Cow::from(format!("{link} \u{2192} {target}"))
}

/// Styles the symbolic notation of file permissions.
#[cfg(unix)]
pub fn style_sym_permissions(node: &Node) -> String {
let perms = node.mode().expect("Expected permissions to be initialized");

let symb = if node.has_xattrs() {
let perm_xattr = FileModeXAttrs(&perms);
format!("{perm_xattr}")
} else {
// extra whitespace to align with permissions with extended attrs
format!("{perms} ")
};

if let Ok(theme) = styles::get_permissions_theme() {
symb.chars()
.filter_map(|ch| {
theme.get(&ch).map(|color| {
let chstr = ch.to_string();
color.paint(chstr).to_string()
})
})
.collect::<String>()
} else {
symb
}
}

/// Styles the octal notation of file permissions.
#[cfg(unix)]
pub fn style_oct_permissions(node: &Node) -> String {
let perms = node.mode().expect("Expected permissions to be initialized");
let oct = format!("{perms:04o}");

if let Ok(style) = styles::get_octal_permissions_style() {
style.paint(oct).to_string()
} else {
oct
}
}
3 changes: 0 additions & 3 deletions src/tree/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ use crate::fs::{
/// Ordering and sorting rules for [Node].
pub mod cmp;

/// Styling utilities for a [Node].
pub mod style;

/// A node of [`Tree`] that can be created from a [`DirEntry`]. Any filesystem I/O and
/// relevant system calls are expected to complete after initialization. A `Node` when `Display`ed
/// uses ANSI colors determined by the file-type and `LS_COLORS`.
Expand Down
80 changes: 0 additions & 80 deletions src/tree/node/style.rs

This file was deleted.

0 comments on commit 74277fb

Please sign in to comment.