mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-12-25 09:50:03 +00:00
Move icon generation into file name module
This commit makes adding icons to file names something that the file name renderer does, rather than something that each individual view does. This is now possible thanks to the previous commit a1869f2
, which moved the option to do this into the same module. The repeated code has been removed.
It happens to fix a bug where the width of each column was being incorrectly calculated for the grid-details view, making lines slightly too long for the terminal because the icon wasn't being taken into account.
This commit is contained in:
parent
b05f18cae0
commit
f1e3e7c7ff
@ -65,7 +65,7 @@ use std::mem::MaybeUninit;
|
||||
use std::path::PathBuf;
|
||||
use std::vec::IntoIter as VecIntoIter;
|
||||
|
||||
use ansi_term::{ANSIGenericString, Style};
|
||||
use ansi_term::Style;
|
||||
use scoped_threadpool::Pool;
|
||||
|
||||
use crate::fs::{Dir, File};
|
||||
@ -74,7 +74,6 @@ use crate::fs::feature::git::GitCache;
|
||||
use crate::fs::feature::xattr::{Attribute, FileAttributes};
|
||||
use crate::fs::filter::FileFilter;
|
||||
use crate::output::cell::TextCell;
|
||||
use crate::output::icons::painted_icon;
|
||||
use crate::output::file_name::Options as FileStyle;
|
||||
use crate::output::table::{Table, Options as TableOptions, Row as TableRow};
|
||||
use crate::output::tree::{TreeTrunk, TreeParams, TreeDepth};
|
||||
@ -137,7 +136,6 @@ struct Egg<'a> {
|
||||
errors: Vec<(io::Error, Option<PathBuf>)>,
|
||||
dir: Option<Dir>,
|
||||
file: &'a File<'a>,
|
||||
icon: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> AsRef<File<'a>> for Egg<'a> {
|
||||
@ -266,10 +264,7 @@ impl<'a> Render<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
let icon = if self.file_style.icons { Some(painted_icon(file, self.theme)) }
|
||||
else { None };
|
||||
|
||||
let egg = Egg { table_row, xattrs, errors, dir, file, icon };
|
||||
let egg = Egg { table_row, xattrs, errors, dir, file };
|
||||
unsafe { std::ptr::write(file_eggs.lock().unwrap()[idx].as_mut_ptr(), egg) }
|
||||
});
|
||||
}
|
||||
@ -287,22 +282,15 @@ impl<'a> Render<'a> {
|
||||
t.add_widths(row);
|
||||
}
|
||||
|
||||
let mut name_cell = TextCell::default();
|
||||
if let Some(icon) = egg.icon {
|
||||
name_cell.push(ANSIGenericString::from(icon), 2)
|
||||
}
|
||||
|
||||
let style = self.file_style.for_file(egg.file, self.theme)
|
||||
.with_link_paths()
|
||||
.paint()
|
||||
.promote();
|
||||
name_cell.append(style);
|
||||
|
||||
let file_name = self.file_style.for_file(egg.file, self.theme)
|
||||
.with_link_paths()
|
||||
.paint()
|
||||
.promote();
|
||||
|
||||
let row = Row {
|
||||
tree: tree_params,
|
||||
cells: egg.table_row,
|
||||
name: name_cell,
|
||||
name: file_name,
|
||||
};
|
||||
|
||||
rows.push(row);
|
||||
|
@ -6,6 +6,7 @@ use ansi_term::{ANSIString, Style};
|
||||
use crate::fs::{File, FileTarget};
|
||||
use crate::output::cell::TextCellContents;
|
||||
use crate::output::escape;
|
||||
use crate::output::icons::{icon_for_file, iconify_style};
|
||||
use crate::output::render::FiletypeColours;
|
||||
|
||||
|
||||
@ -111,6 +112,14 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
|
||||
pub fn paint(&self) -> TextCellContents {
|
||||
let mut bits = Vec::new();
|
||||
|
||||
if self.options.icons {
|
||||
let style = iconify_style(self.colours.colour_file(self.file));
|
||||
let file_icon = icon_for_file(self.file).to_string();
|
||||
|
||||
bits.push(style.paint(file_icon));
|
||||
bits.push(Style::default().paint(" "));
|
||||
}
|
||||
|
||||
if self.file.parent_dir.is_none() {
|
||||
if let Some(parent) = self.file.path.parent() {
|
||||
self.add_parent_bits(&mut bits, parent);
|
||||
|
@ -3,9 +3,7 @@ use std::io::{self, Write};
|
||||
use term_grid as tg;
|
||||
|
||||
use crate::fs::File;
|
||||
use crate::output::cell::DisplayWidth;
|
||||
use crate::output::file_name::Options as FileStyle;
|
||||
use crate::output::icons::painted_icon;
|
||||
use crate::theme::Theme;
|
||||
|
||||
|
||||
@ -40,17 +38,11 @@ impl<'a> Render<'a> {
|
||||
grid.reserve(self.files.len());
|
||||
|
||||
for file in &self.files {
|
||||
let icon = if self.file_style.icons { Some(painted_icon(file, self.theme)) }
|
||||
else { None };
|
||||
|
||||
let filename = self.file_style.for_file(file, self.theme).paint();
|
||||
|
||||
let width = if self.file_style.icons { DisplayWidth::from(2) + filename.width() }
|
||||
else { filename.width() };
|
||||
|
||||
grid.add(tg::Cell {
|
||||
contents: format!("{}{}", &icon.unwrap_or_default(), filename.strings()),
|
||||
width: *width,
|
||||
contents: filename.strings().to_string(),
|
||||
width: *filename.width(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -62,10 +54,6 @@ impl<'a> Render<'a> {
|
||||
// This isn’t *quite* the same as the lines view, which also
|
||||
// displays full link paths.
|
||||
for file in &self.files {
|
||||
if self.file_style.icons {
|
||||
write!(w, "{}", painted_icon(file, self.theme))?;
|
||||
}
|
||||
|
||||
let name_cell = self.file_style.for_file(file, self.theme).paint();
|
||||
writeln!(w, "{}", name_cell.strings())?;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use std::io::{self, Write};
|
||||
|
||||
use ansi_term::{ANSIGenericString, ANSIStrings};
|
||||
use ansi_term::ANSIStrings;
|
||||
use term_grid as grid;
|
||||
|
||||
use crate::fs::{Dir, File};
|
||||
@ -13,7 +13,6 @@ use crate::output::cell::TextCell;
|
||||
use crate::output::details::{Options as DetailsOptions, Row as DetailsRow, Render as DetailsRender};
|
||||
use crate::output::file_name::Options as FileStyle;
|
||||
use crate::output::grid::Options as GridOptions;
|
||||
use crate::output::icons::painted_icon;
|
||||
use crate::output::table::{Table, Row as TableRow, Options as TableOptions};
|
||||
use crate::output::tree::{TreeParams, TreeDepth};
|
||||
use crate::theme::Theme;
|
||||
@ -155,18 +154,7 @@ impl<'a> Render<'a> {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let file_names = self.files.iter()
|
||||
.map(|file| {
|
||||
if self.file_style.icons {
|
||||
let mut icon_cell = TextCell::default();
|
||||
icon_cell.push(ANSIGenericString::from(painted_icon(file, self.theme)), 2);
|
||||
let file_cell = self.file_style.for_file(file, self.theme).paint().promote();
|
||||
icon_cell.append(file_cell);
|
||||
icon_cell
|
||||
}
|
||||
else {
|
||||
self.file_style.for_file(file, self.theme).paint().promote()
|
||||
}
|
||||
})
|
||||
.map(|file| self.file_style.for_file(file, self.theme).paint().promote())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut last_working_table = self.make_grid(1, options, &file_names, rows.clone(), &drender);
|
||||
|
@ -2,7 +2,6 @@ use ansi_term::Style;
|
||||
|
||||
use crate::fs::File;
|
||||
use crate::info::filetype::FileExtensions;
|
||||
use crate::theme::Theme;
|
||||
|
||||
|
||||
pub trait FileIcon {
|
||||
@ -28,33 +27,24 @@ impl Icons {
|
||||
}
|
||||
|
||||
|
||||
pub fn painted_icon(file: &File<'_>, theme: &Theme) -> String {
|
||||
use crate::output::file_name::Colours;
|
||||
|
||||
let file_icon = icon(file).to_string();
|
||||
let c = theme.colour_file(file);
|
||||
|
||||
// Remove underline from icon
|
||||
let painted =
|
||||
if c.is_underline {
|
||||
match c.foreground {
|
||||
Some(color) => {
|
||||
Style::from(color).paint(file_icon).to_string()
|
||||
}
|
||||
None => {
|
||||
Style::default().paint(file_icon).to_string()
|
||||
}
|
||||
pub fn iconify_style<'a>(style: Style) -> Style {
|
||||
if style.is_underline {
|
||||
match style.foreground {
|
||||
Some(color) => {
|
||||
Style::from(color)
|
||||
}
|
||||
None => {
|
||||
Style::default()
|
||||
}
|
||||
}
|
||||
else {
|
||||
c.paint(file_icon).to_string()
|
||||
};
|
||||
|
||||
format!("{} ", painted)
|
||||
}
|
||||
else {
|
||||
style
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn icon(file: &File<'_>) -> char {
|
||||
pub fn icon_for_file(file: &File<'_>) -> char {
|
||||
let extensions = Box::new(FileExtensions);
|
||||
|
||||
if file.points_to_directory() {
|
||||
|
@ -1,11 +1,10 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use ansi_term::{ANSIStrings, ANSIGenericString};
|
||||
use ansi_term::ANSIStrings;
|
||||
|
||||
use crate::fs::File;
|
||||
use crate::output::cell::{TextCell, TextCellContents};
|
||||
use crate::output::cell::TextCellContents;
|
||||
use crate::output::file_name::{Options as FileStyle};
|
||||
use crate::output::icons::painted_icon;
|
||||
use crate::theme::Theme;
|
||||
|
||||
|
||||
@ -20,17 +19,7 @@ impl<'a> Render<'a> {
|
||||
pub fn render<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
for file in &self.files {
|
||||
let name_cell = self.render_file(file);
|
||||
if self.file_style.icons {
|
||||
// Create a TextCell for the icon then append the text to it
|
||||
let mut cell = TextCell::default();
|
||||
let icon = painted_icon(file, self.theme);
|
||||
cell.push(ANSIGenericString::from(icon), 2);
|
||||
cell.append(name_cell.promote());
|
||||
writeln!(w, "{}", ANSIStrings(&cell))?;
|
||||
}
|
||||
else {
|
||||
writeln!(w, "{}", ANSIStrings(&name_cell))?;
|
||||
}
|
||||
writeln!(w, "{}", ANSIStrings(&name_cell))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -1,6 +1,7 @@
|
||||
1_bytes 3_bytes 5_bytes 7_bytes 9_bytes 11_bytes 13_bytes
|
||||
1_KiB 3_KiB 5_KiB 7_KiB 9_KiB 11_KiB 13_KiB
|
||||
1_MiB 3_MiB 5_MiB 7_MiB 9_MiB 11_MiB 13_MiB
|
||||
2_bytes 4_bytes 6_bytes 8_bytes 10_bytes 12_bytes
|
||||
2_KiB 4_KiB 6_KiB 8_KiB 10_KiB 12_KiB
|
||||
2_MiB 4_MiB 6_MiB 8_MiB 10_MiB 12_MiB
|
||||
1_bytes 3_KiB 5_MiB 8_bytes 10_KiB 12_MiB
|
||||
1_KiB 3_MiB 6_bytes 8_KiB 10_MiB 13_bytes
|
||||
1_MiB 4_bytes 6_KiB 8_MiB 11_bytes 13_KiB
|
||||
2_bytes 4_KiB 6_MiB 9_bytes 11_KiB 13_MiB
|
||||
2_KiB 4_MiB 7_bytes 9_KiB 11_MiB
|
||||
2_MiB 5_bytes 7_KiB 9_MiB 12_bytes
|
||||
3_bytes 5_KiB 7_MiB 10_bytes 12_KiB
|
||||
|
Loading…
Reference in New Issue
Block a user