diff --git a/src/core.rs b/src/core.rs index 740ff7d..c188e2d 100644 --- a/src/core.rs +++ b/src/core.rs @@ -95,12 +95,7 @@ impl Core { meta_list.push(meta); } _ => { - match meta.recurse_into( - depth, - self.flags.display, - &self.flags.ignore_globs, - self.flags.dereference, - ) { + match meta.recurse_into(depth, &self.flags) { Ok(content) => { meta.content = content; meta_list.push(meta); diff --git a/src/display.rs b/src/display.rs index 5b53c0a..13155ac 100644 --- a/src/display.rs +++ b/src/display.rs @@ -68,7 +68,8 @@ fn inner_display_grid( // Maybe skip showing the directory meta now; show its contents later. if skip_dirs && (matches!(meta.file_type, FileType::Directory{..}) - || matches!(meta.file_type, FileType::SymLink { is_dir: true })) + || (matches!(meta.file_type, FileType::SymLink { is_dir: true }) + && flags.layout != Layout::OneLine)) { continue; } @@ -109,7 +110,7 @@ fn inner_display_grid( output += &grid.fit_into_columns(flags.blocks.len()).to_string(); } - let should_display_folder_path = should_display_folder_path(depth, &metas); + let should_display_folder_path = should_display_folder_path(depth, &metas, &flags); // print the folder content for meta in metas { @@ -218,7 +219,7 @@ fn inner_display_tree( output } -fn should_display_folder_path(depth: usize, metas: &[Meta]) -> bool { +fn should_display_folder_path(depth: usize, metas: &[Meta], flags: &Flags) -> bool { if depth > 0 { true } else { @@ -226,7 +227,8 @@ fn should_display_folder_path(depth: usize, metas: &[Meta]) -> bool { .iter() .filter(|x| { matches!(x.file_type, FileType::Directory { .. }) - || matches!(x.file_type, FileType::SymLink { is_dir: true }) + || (matches!(x.file_type, FileType::SymLink { is_dir: true }) + && flags.layout != Layout::OneLine) }) .count(); diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 2be44ea..4a916f4 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -20,7 +20,7 @@ pub use self::owner::Owner; pub use self::permissions::Permissions; pub use self::size::Size; pub use self::symlink::SymLink; -pub use crate::flags::Display; +pub use crate::flags::{Display, Flags, Layout}; pub use crate::icon::Icons; use crate::print_error; @@ -28,8 +28,6 @@ use std::fs::read_link; use std::io::{Error, ErrorKind}; use std::path::{Component, Path, PathBuf}; -use globset::GlobSet; - #[derive(Clone, Debug)] pub struct Meta { pub name: Name, @@ -49,21 +47,23 @@ impl Meta { pub fn recurse_into( &self, depth: usize, - display: Display, - ignore_globs: &GlobSet, - dereference: bool, + flags: &Flags, ) -> Result>, std::io::Error> { if depth == 0 { return Ok(None); } - if display == Display::DisplayDirectoryItself { + if flags.display == Display::DisplayDirectoryItself { return Ok(None); } match self.file_type { FileType::Directory { .. } => (), - FileType::SymLink { is_dir: true } => (), + FileType::SymLink { is_dir: true } => { + if flags.layout == Layout::OneLine { + return Ok(None); + } + } _ => return Ok(None), } @@ -77,13 +77,14 @@ impl Meta { let mut content: Vec = Vec::new(); - if let Display::DisplayAll = display { + if let Display::DisplayAll = flags.display { let mut current_meta; current_meta = self.clone(); current_meta.name.name = ".".to_owned(); - let parent_meta = Self::from_path(&self.path.join(Component::ParentDir), dereference)?; + let parent_meta = + Self::from_path(&self.path.join(Component::ParentDir), flags.dereference)?; content.push(current_meta); content.push(parent_meta); @@ -96,17 +97,17 @@ impl Meta { .file_name() .ok_or_else(|| Error::new(ErrorKind::InvalidInput, "invalid file name"))?; - if ignore_globs.is_match(&name) { + if flags.ignore_globs.is_match(&name) { continue; } - if let Display::DisplayOnlyVisible = display { + if let Display::DisplayOnlyVisible = flags.display { if name.to_string_lossy().starts_with('.') { continue; } } - let mut entry_meta = match Self::from_path(&path, dereference) { + let mut entry_meta = match Self::from_path(&path, flags.dereference) { Ok(res) => res, Err(err) => { print_error!("lsd: {}: {}\n", path.display(), err); @@ -114,7 +115,7 @@ impl Meta { } }; - match entry_meta.recurse_into(depth - 1, display, ignore_globs, dereference) { + match entry_meta.recurse_into(depth - 1, &flags) { Ok(content) => entry_meta.content = content, Err(err) => { print_error!("lsd: {}: {}\n", path.display(), err); diff --git a/tests/integration.rs b/tests/integration.rs index fe4eeaf..554c72b 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -219,6 +219,47 @@ fn test_show_folder_content_of_symlink() { .stdout(predicate::str::starts_with("inside")); } +#[cfg(unix)] +#[test] +fn test_no_show_folder_content_of_symlink_for_long() { + let dir = tempdir(); + dir.child("target").child("inside").touch().unwrap(); + let link = dir.path().join("link"); + fs::symlink("target", &link).unwrap(); + + cmd() + .arg("-l") + .arg(link) + .assert() + .stdout(predicate::str::starts_with("lrw")) + .stdout(predicate::str::contains("⇒")); + + cmd() + .arg("-l") + .arg(dir.path().join("link/")) + .assert() + .stdout(predicate::str::starts_with(".rw")) + .stdout(predicate::str::contains("⇒").not()); +} + +#[cfg(unix)] +#[test] +fn test_show_folder_of_symlink_for_long_multi() { + let dir = tempdir(); + dir.child("target").child("inside").touch().unwrap(); + let link = dir.path().join("link"); + fs::symlink("target", &link).unwrap(); + + cmd() + .arg("-l") + .arg(dir.path().join("link/")) + .arg(dir.path().join("link")) + .assert() + .stdout(predicate::str::starts_with("lrw")) + .stdout(predicate::str::contains("link:").not()) // do not show dir content when no / + .stdout(predicate::str::contains("link/:")); +} + fn cmd() -> Command { Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap() }