|
| 1 | +use std::borrow::Cow; |
1 | 2 | use std::io::{self, StdoutLock, Write};
|
2 | 3 | use std::path::Path;
|
3 | 4 | use std::process;
|
4 | 5 | use std::sync::atomic::{AtomicBool, Ordering};
|
5 | 6 | use std::sync::Arc;
|
6 | 7 |
|
7 |
| -use lscolors::{LsColors, Style}; |
| 8 | +use lscolors::{Indicator, LsColors, Style}; |
8 | 9 |
|
9 | 10 | use crate::error::print_error;
|
10 | 11 | use crate::exit_codes::ExitCode;
|
@@ -53,32 +54,51 @@ fn print_entry_colorized(
|
53 | 54 | ls_colors: &LsColors,
|
54 | 55 | wants_to_quit: &Arc<AtomicBool>,
|
55 | 56 | ) -> io::Result<()> {
|
56 |
| - let default_style = ansi_term::Style::default(); |
57 |
| - |
58 |
| - // Traverse the path and colorize each component |
59 |
| - for (component, style) in ls_colors.style_for_path_components(path) { |
60 |
| - let style = style |
61 |
| - .map(Style::to_ansi_term_style) |
62 |
| - .unwrap_or(default_style); |
| 57 | + // Split the path between the parent and the last component |
| 58 | + let mut offset = 0; |
| 59 | + let path_str = path.to_string_lossy(); |
| 60 | + |
| 61 | + if let Some(parent) = path.parent() { |
| 62 | + offset = parent.to_string_lossy().len(); |
| 63 | + for c in path_str[offset..].chars() { |
| 64 | + if std::path::is_separator(c) { |
| 65 | + offset += c.len_utf8(); |
| 66 | + } else { |
| 67 | + break; |
| 68 | + } |
| 69 | + } |
| 70 | + } |
63 | 71 |
|
64 |
| - let mut path_string = component.to_string_lossy(); |
| 72 | + if offset > 0 { |
| 73 | + let mut parent_str = Cow::from(&path_str[..offset]); |
65 | 74 | if let Some(ref separator) = config.path_separator {
|
66 |
| - *path_string.to_mut() = replace_path_separator(&path_string, separator); |
| 75 | + *parent_str.to_mut() = replace_path_separator(&parent_str, separator); |
67 | 76 | }
|
68 |
| - write!(stdout, "{}", style.paint(path_string))?; |
69 | 77 |
|
70 |
| - // TODO: can we move this out of the if-statement? Why do we call it that often? |
71 |
| - if wants_to_quit.load(Ordering::Relaxed) { |
72 |
| - writeln!(stdout)?; |
73 |
| - process::exit(ExitCode::KilledBySigint.into()); |
74 |
| - } |
| 78 | + let style = ls_colors |
| 79 | + .style_for_indicator(Indicator::Directory) |
| 80 | + .map(Style::to_ansi_term_style) |
| 81 | + .unwrap_or_default(); |
| 82 | + write!(stdout, "{}", style.paint(parent_str))?; |
75 | 83 | }
|
76 | 84 |
|
| 85 | + let style = ls_colors |
| 86 | + .style_for_path(path) |
| 87 | + .map(Style::to_ansi_term_style) |
| 88 | + .unwrap_or_default(); |
| 89 | + write!(stdout, "{}", style.paint(&path_str[offset..]))?; |
| 90 | + |
77 | 91 | if config.null_separator {
|
78 |
| - write!(stdout, "\0") |
| 92 | + write!(stdout, "\0")?; |
79 | 93 | } else {
|
80 |
| - writeln!(stdout) |
| 94 | + writeln!(stdout)?; |
81 | 95 | }
|
| 96 | + |
| 97 | + if wants_to_quit.load(Ordering::Relaxed) { |
| 98 | + process::exit(ExitCode::KilledBySigint.into()); |
| 99 | + } |
| 100 | + |
| 101 | + Ok(()) |
82 | 102 | }
|
83 | 103 |
|
84 | 104 | // TODO: this function is performance critical and can probably be optimized
|
|
0 commit comments