Skip to content

Commit

Permalink
Add style_for_path_components function
Browse files Browse the repository at this point in the history
closes #5
  • Loading branch information
sharkdp committed Dec 15, 2018
1 parent 65813b7 commit 4e214a3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
10 changes: 5 additions & 5 deletions src/bin.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::alloc::System;
use std::io;
use std::io::prelude::*;
use std::path::Path;

use lscolors::{LsColors, Style};

Expand All @@ -22,11 +21,12 @@ fn run() -> io::Result<()> {
}

let path_str = String::from_utf8_lossy(&buf[..(buf.len() - 1)]);
let path = Path::new(path_str.as_ref());
let style = ls_colors.style_for_path(path);
let ansi_style = style.map(Style::to_ansi_term_style).unwrap_or_default();

writeln!(stdout, "{}", ansi_style.paint(path_str))?;
for (component, style) in ls_colors.style_for_path_components(path_str.as_ref()) {
let ansi_style = style.map(Style::to_ansi_term_style).unwrap_or_default();
write!(stdout, "{}", ansi_style.paint(component.to_string_lossy()))?;
}
writeln!(stdout)?;

buf.clear();
}
Expand Down
42 changes: 41 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ mod fs;
pub mod style;

use std::env;
use std::path::Path;
use std::ffi::OsString;
use std::path::{Component, Path, PathBuf, MAIN_SEPARATOR};

pub use crate::style::{Color, FontStyle, Style};

Expand Down Expand Up @@ -180,6 +181,45 @@ impl LsColors {

None
}

/// Get ANSI styles for each component of a given path. Components already
/// include the patj separator symbol, if required. For a path like
/// `foo/bar/test.md`, this would return three pairs for the components
/// `foo/`, `bar/` and `test.md` together with their respective styles.
pub fn style_for_path_components<P: AsRef<Path>>(
&self,
path: P,
) -> Vec<(OsString, Option<&Style>)> {
let mut styled_components = vec![];

// Full path to the current component.
let mut component_path = PathBuf::new();

// Traverse the path and colorize each component
let mut components = path.as_ref().components().peekable();
while let Some(component) = components.next() {
let mut component_str = component.as_os_str().to_os_string();

component_path.push(&component_str);
let style = self.style_for_path(&component_path);

if components.peek().is_some() {
match component {
// Prefix needs no separator, as it is always followed by RootDir.
// RootDir is already a separator.
Component::Prefix(_) | Component::RootDir => {}
// Everything else uses a separator that is painted the same way as the component.
Component::CurDir | Component::ParentDir | Component::Normal(_) => {
component_str.push(MAIN_SEPARATOR.to_string());
}
}
}

styled_components.push((component_str, style));
}

styled_components
}
}

#[cfg(test)]
Expand Down

0 comments on commit 4e214a3

Please sign in to comment.