create display option of name

This commit is contained in:
dvvvvvv 2020-02-02 23:32:40 +09:00 committed by Abin Simon
parent 79adfff370
commit 708a6f5dc1
4 changed files with 35 additions and 32 deletions

View file

@ -2,6 +2,7 @@ use crate::color::{ColoredString, Colors};
use crate::flags::{Block, Display, Flags, Layout}; use crate::flags::{Block, Display, Flags, Layout};
use crate::icon::Icons; use crate::icon::Icons;
use crate::meta::{FileType, Meta}; use crate::meta::{FileType, Meta};
use crate::meta::name::DisplayOption;
use ansi_term::{ANSIString, ANSIStrings}; use ansi_term::{ANSIString, ANSIStrings};
use std::collections::HashMap; use std::collections::HashMap;
use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
@ -59,8 +60,10 @@ fn inner_display_grid(
if let (true, FileType::Directory { .. }) = (skip_dirs, meta.file_type) { if let (true, FileType::Directory { .. }) = (skip_dirs, meta.file_type) {
continue; continue;
} }
let display_option = DisplayOption::Current;
let blocks = get_output(&meta, &colors, &icons, &flags, &padding_rules); let blocks = get_output(&meta, &colors, &icons, &flags, display_option, &padding_rules);
for block in blocks { for block in blocks {
let block_str = block.to_string(); let block_str = block.to_string();
@ -131,7 +134,7 @@ fn inner_display_tree(
}); });
for meta in metas.iter() { for meta in metas.iter() {
for block in get_output(&meta, &colors, &icons, &flags, &padding_rules) { for block in get_output(&meta, &colors, &icons, &flags, DisplayOption::FileName, &padding_rules) {
let block_str = block.to_string(); let block_str = block.to_string();
grid.add(Cell { grid.add(Cell {
@ -216,6 +219,7 @@ fn get_output<'a>(
colors: &'a Colors, colors: &'a Colors,
icons: &'a Icons, icons: &'a Icons,
flags: &'a Flags, flags: &'a Flags,
display_option: DisplayOption,
padding_rules: &HashMap<Block, usize>, padding_rules: &HashMap<Block, usize>,
) -> Vec<ANSIString<'a>> { ) -> Vec<ANSIString<'a>> {
let mut strings: Vec<ANSIString> = Vec::new(); let mut strings: Vec<ANSIString> = Vec::new();
@ -242,13 +246,13 @@ fn get_output<'a>(
Block::Name => { Block::Name => {
let s: String = if flags.no_symlink { let s: String = if flags.no_symlink {
ANSIStrings(&[ ANSIStrings(&[
meta.name.render(colors, icons), meta.name.render(colors, icons, &display_option),
meta.indicator.render(&flags), meta.indicator.render(&flags),
]) ])
.to_string() .to_string()
} else { } else {
ANSIStrings(&[ ANSIStrings(&[
meta.name.render(colors, icons), meta.name.render(colors, icons, &display_option),
meta.indicator.render(&flags), meta.indicator.render(&flags),
meta.symlink.render(colors), meta.symlink.render(colors),
]) ])

View file

@ -91,15 +91,13 @@ impl Icons {
return res; return res;
} }
if let Some(icon) = name.file_name() if let Some(icon) = self.icons_by_name.get(name.file_name()) {
.map(std::ffi::OsStr::to_string_lossy)
.and_then(|file_name| self.icons_by_name.get(file_name.as_ref())) {
// Use the known names. // Use the known names.
res += icon; res += icon;
res += ICON_SPACE; res += ICON_SPACE;
res res
} else if let Some(icon) = name.extension() } else if let Some(icon) = name.extension()
.and_then(|extension| self.icons_by_extension.get(extension)) { .and_then(|extension| self.icons_by_extension.get(extension)){
// Use the known extensions. // Use the known extensions.
res += icon; res += icon;
res += ICON_SPACE; res += ICON_SPACE;

View file

@ -2,7 +2,7 @@ mod date;
mod filetype; mod filetype;
mod indicator; mod indicator;
mod inode; mod inode;
mod name; pub mod name;
mod owner; mod owner;
mod permissions; mod permissions;
mod size; mod size;

View file

@ -5,6 +5,13 @@ use std::cmp::{Ordering, PartialOrd};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::ffi::OsStr; use std::ffi::OsStr;
pub enum DisplayOption<'a> {
Parent,
Current,
FileName,
Relative{base_path: &'a Path},
}
#[derive(Clone, Debug, Eq)] #[derive(Clone, Debug, Eq)]
pub struct Name { pub struct Name {
path: PathBuf, path: PathBuf,
@ -13,8 +20,16 @@ pub struct Name {
} }
impl Name { impl Name {
pub fn file_name(&self) -> Option<&OsStr> { pub fn file_name(&self) -> &str {
self.path.file_name() self.path.file_name().and_then(OsStr::to_str).unwrap_or("?")
}
fn relative_path(&self, base_path: &Path) -> std::borrow::Cow<'_, str> {
if let Ok(relative_path) = self.path.strip_prefix(base_path) {
relative_path.to_string_lossy()
} else {
std::borrow::Cow::Borrowed("?")
}
} }
pub fn new(path: &Path, file_type: FileType) -> Self { pub fn new(path: &Path, file_type: FileType) -> Self {
@ -34,15 +49,13 @@ impl Name {
} }
} }
pub fn name_string(&self, icons: &Icons) -> String { pub fn render(&self, colors: &Colors, icons: &Icons, display_option: &DisplayOption) -> ColoredString {
let icon = icons.get(self); let content = match display_option {
let display = &self.path.to_string_lossy(); DisplayOption::Parent => format!("{}..", icons.get(self)),
DisplayOption::Current => format!("{}.", icons.get(self)),
format!("{}{}", icon.as_str(), display) DisplayOption::FileName => format!("{}{}", icons.get(self), self.file_name()),
} DisplayOption::Relative{base_path} => format!("{}{}", icons.get(self), self.relative_path(base_path)),
};
pub fn render(&self, colors: &Colors, icons: &Icons) -> ColoredString {
let content = self.name_string(&icons);
let elem = match self.file_type { let elem = match self.file_type {
FileType::CharDevice => Elem::CharDevice, FileType::CharDevice => Elem::CharDevice,
@ -219,7 +232,6 @@ mod test {
let path = Path::new("some-file.txt"); let path = Path::new("some-file.txt");
let name = Name::new( let name = Name::new(
Path::new("/"),
&path, &path,
FileType::File { FileType::File {
uid: false, uid: false,
@ -235,7 +247,6 @@ mod test {
let path = Path::new(".gitignore"); let path = Path::new(".gitignore");
let name = Name::new( let name = Name::new(
Path::new("/"),
&path, &path,
FileType::File { FileType::File {
uid: false, uid: false,
@ -250,7 +261,6 @@ mod test {
fn test_order_impl_is_case_insensitive() { fn test_order_impl_is_case_insensitive() {
let path_1 = Path::new("AAAA"); let path_1 = Path::new("AAAA");
let name_1 = Name::new( let name_1 = Name::new(
Path::new("/"),
&path_1, &path_1,
FileType::File { FileType::File {
uid: false, uid: false,
@ -260,7 +270,6 @@ mod test {
let path_2 = Path::new("aaaa"); let path_2 = Path::new("aaaa");
let name_2 = Name::new( let name_2 = Name::new(
Path::new("/"),
&path_2, &path_2,
FileType::File { FileType::File {
uid: false, uid: false,
@ -275,7 +284,6 @@ mod test {
fn test_partial_order_impl() { fn test_partial_order_impl() {
let path_a = Path::new("aaaa"); let path_a = Path::new("aaaa");
let name_a = Name::new( let name_a = Name::new(
Path::new("/"),
&path_a, &path_a,
FileType::File { FileType::File {
uid: false, uid: false,
@ -285,7 +293,6 @@ mod test {
let path_z = Path::new("zzzz"); let path_z = Path::new("zzzz");
let name_z = Name::new( let name_z = Name::new(
Path::new("/"),
&path_z, &path_z,
FileType::File { FileType::File {
uid: false, uid: false,
@ -300,7 +307,6 @@ mod test {
fn test_partial_order_impl_is_case_insensitive() { fn test_partial_order_impl_is_case_insensitive() {
let path_a = Path::new("aaaa"); let path_a = Path::new("aaaa");
let name_a = Name::new( let name_a = Name::new(
Path::new("/"),
&path_a, &path_a,
FileType::File { FileType::File {
uid: false, uid: false,
@ -310,7 +316,6 @@ mod test {
let path_z = Path::new("ZZZZ"); let path_z = Path::new("ZZZZ");
let name_z = Name::new( let name_z = Name::new(
Path::new("/"),
&path_z, &path_z,
FileType::File { FileType::File {
uid: false, uid: false,
@ -325,7 +330,6 @@ mod test {
fn test_partial_eq_impl() { fn test_partial_eq_impl() {
let path_1 = Path::new("aaaa"); let path_1 = Path::new("aaaa");
let name_1 = Name::new( let name_1 = Name::new(
Path::new("/"),
&path_1, &path_1,
FileType::File { FileType::File {
uid: false, uid: false,
@ -335,7 +339,6 @@ mod test {
let path_2 = Path::new("aaaa"); let path_2 = Path::new("aaaa");
let name_2 = Name::new( let name_2 = Name::new(
Path::new("/"),
&path_2, &path_2,
FileType::File { FileType::File {
uid: false, uid: false,
@ -350,7 +353,6 @@ mod test {
fn test_partial_eq_impl_is_case_insensitive() { fn test_partial_eq_impl_is_case_insensitive() {
let path_1 = Path::new("AAAA"); let path_1 = Path::new("AAAA");
let name_1 = Name::new( let name_1 = Name::new(
Path::new("/"),
&path_1, &path_1,
FileType::File { FileType::File {
uid: false, uid: false,
@ -360,7 +362,6 @@ mod test {
let path_2 = Path::new("aaaa"); let path_2 = Path::new("aaaa");
let name_2 = Name::new( let name_2 = Name::new(
Path::new("/"),
&path_2, &path_2,
FileType::File { FileType::File {
uid: false, uid: false,