diff --git a/src/core.rs b/src/core.rs index cc526a1ff..97472ec40 100644 --- a/src/core.rs +++ b/src/core.rs @@ -44,8 +44,6 @@ impl Core { #[cfg(target_os = "windows")] let console_color_ok = crossterm::ansi_support::supports_ansi(); - let mut inner_flags = flags.clone(); - let color_theme = match (tty_available && console_color_ok, flags.color.when) { (_, ColorOption::Never) | (false, ColorOption::Auto) => ThemeOption::NoColor, _ => flags.color.theme.clone(), @@ -66,12 +64,17 @@ impl Core { let icon_separator = flags.icons.separator.0.clone(); + // The output is not a tty, this means the command is piped. e.g. + // + // lsd -l | less + // + // Most of the programs does not handle correctly the ansi colors + // or require a raw output (like the `wc` command). if !tty_available { - // The output is not a tty, this means the command is piped. (ex: lsd -l | less) - // - // Most of the programs does not handle correctly the ansi colors - // or require a raw output (like the `wc` command). - inner_flags.layout = Layout::OneLine; + // we should not overwrite the tree layout + if flags.layout != Layout::Tree { + flags.layout = Layout::OneLine; + } flags.literal = Literal(true); }; diff --git a/src/display.rs b/src/display.rs index a923d1aad..6729529dd 100644 --- a/src/display.rs +++ b/src/display.rs @@ -115,8 +115,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 }) - && flags.layout != Layout::OneLine)) + || (matches!(meta.file_type, FileType::SymLink { is_dir: true })) + && flags.blocks.0.len() == 1) { continue; } @@ -167,7 +167,7 @@ fn inner_display_grid( output += &grid.fit_into_columns(flags.blocks.0.len()).to_string(); } - let should_display_folder_path = should_display_folder_path(depth, metas, flags); + let should_display_folder_path = should_display_folder_path(depth, metas); // print the folder content for meta in metas { @@ -301,7 +301,7 @@ fn inner_display_tree( cells } -fn should_display_folder_path(depth: usize, metas: &[Meta], flags: &Flags) -> bool { +fn should_display_folder_path(depth: usize, metas: &[Meta]) -> bool { if depth > 0 { true } else { @@ -309,8 +309,7 @@ fn should_display_folder_path(depth: usize, metas: &[Meta], flags: &Flags) -> bo .iter() .filter(|x| { matches!(x.file_type, FileType::Directory { .. }) - || (matches!(x.file_type, FileType::SymLink { is_dir: true }) - && flags.layout != Layout::OneLine) + || (matches!(x.file_type, FileType::SymLink { is_dir: true })) }) .count(); @@ -925,23 +924,20 @@ mod tests { const NO: bool = false; assert_eq!( - should_display_folder_path(0, &[file.clone()], &Flags::default()), + should_display_folder_path(0, &[file.clone()]), YES // doesn't matter since there is no folder ); + assert_eq!(should_display_folder_path(0, &[dir.clone()]), NO); assert_eq!( - should_display_folder_path(0, &[dir.clone()], &Flags::default()), - NO - ); - assert_eq!( - should_display_folder_path(0, &[file.clone(), dir.clone()], &Flags::default()), + should_display_folder_path(0, &[file.clone(), dir.clone()]), YES ); assert_eq!( - should_display_folder_path(0, &[dir.clone(), dir.clone()], &Flags::default()), + should_display_folder_path(0, &[dir.clone(), dir.clone()]), YES ); assert_eq!( - should_display_folder_path(0, &[file.clone(), file.clone()], &Flags::default()), + should_display_folder_path(0, &[file.clone(), file.clone()]), YES // doesn't matter since there is no folder ); @@ -966,43 +962,18 @@ mod tests { std::os::unix::fs::symlink("dir", &link_path).unwrap(); let link = Meta::from_path(&link_path, false, PermissionFlag::Rwx).unwrap(); - let grid_flags = Flags { - layout: Layout::Grid, - ..Flags::default() - }; - - let oneline_flags = Flags { - layout: Layout::OneLine, - ..Flags::default() - }; - const YES: bool = true; const NO: bool = false; - assert_eq!( - should_display_folder_path(0, &[link.clone()], &grid_flags), - NO - ); - assert_eq!( - should_display_folder_path(0, &[link.clone()], &oneline_flags), - YES // doesn't matter since this link will be expanded as a directory - ); + assert_eq!(should_display_folder_path(0, &[link.clone()]), NO); assert_eq!( - should_display_folder_path(0, &[file.clone(), link.clone()], &grid_flags), + should_display_folder_path(0, &[file.clone(), link.clone()]), YES ); - assert_eq!( - should_display_folder_path(0, &[file.clone(), link.clone()], &oneline_flags), - YES // doesn't matter since this link will be expanded as a directory - ); assert_eq!( - should_display_folder_path(0, &[dir.clone(), link.clone()], &grid_flags), - YES - ); - assert_eq!( - should_display_folder_path(0, &[dir.clone(), link.clone()], &oneline_flags), + should_display_folder_path(0, &[dir.clone(), link.clone()]), YES ); diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 946387579..57ebbe45b 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -77,7 +77,7 @@ impl Meta { match self.file_type { FileType::Directory { .. } => (), FileType::SymLink { is_dir: true } => { - if flags.layout == Layout::OneLine { + if flags.blocks.0.len() > 1 { return Ok((None, ExitCode::OK)); } } @@ -98,14 +98,14 @@ impl Meta { && flags.layout != Layout::Tree { let mut current_meta = self.clone(); - current_meta.name.name = ".".to_owned(); + ".".clone_into(&mut current_meta.name.name); let mut parent_meta = Self::from_path( &self.path.join(Component::ParentDir), flags.dereference.0, flags.permission, )?; - parent_meta.name.name = "..".to_owned(); + "..".clone_into(&mut parent_meta.name.name); current_meta.git_status = cache.and_then(|cache| cache.get(¤t_meta.path, true)); parent_meta.git_status = cache.and_then(|cache| cache.get(&parent_meta.path, true)); diff --git a/tests/integration.rs b/tests/integration.rs index 11ef41f0b..72442331c 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -213,27 +213,42 @@ fn test_list_broken_link_ok() { .assert() .stderr(predicate::str::contains(matched).not()); } + +// ls link +// should show dir content #[cfg(unix)] #[test] fn test_nosymlink_on_non_long() { let dir = tempdir(); - dir.child("target").touch().unwrap(); + dir.child("target").child("inside").touch().unwrap(); let link = dir.path().join("link"); let link_icon = "⇒"; fs::symlink("target", &link).unwrap(); cmd() - .arg("-l") .arg("--ignore-config") .arg(&link) .assert() - .stdout(predicate::str::contains(link_icon)); + .stdout(predicate::str::contains(link_icon).not()); +} + +// ls -l link +// should show the link itself +#[cfg(unix)] +#[test] +fn test_symlink_on_long() { + let dir = tempdir(); + dir.child("target").child("inside").touch().unwrap(); + let link = dir.path().join("link"); + let link_icon = "⇒"; + fs::symlink("target", &link).unwrap(); cmd() + .arg("-l") .arg("--ignore-config") .arg(&link) .assert() - .stdout(predicate::str::contains(link_icon).not()); + .stdout(predicate::str::contains(link_icon)); } #[cfg(unix)] @@ -322,6 +337,7 @@ fn test_dereference_link_broken_link_output() { .stdout(predicate::str::starts_with("l????????? ? ? ? ?")); } +/// should work both tty available and not #[cfg(unix)] #[test] fn test_show_folder_content_of_symlink() { @@ -338,6 +354,8 @@ fn test_show_folder_content_of_symlink() { .stdout(predicate::str::starts_with("inside")); } +/// ls -l link +/// should show the link itself #[cfg(unix)] #[test] fn test_no_show_folder_content_of_symlink_for_long() { @@ -353,6 +371,17 @@ fn test_no_show_folder_content_of_symlink_for_long() { .assert() .stdout(predicate::str::starts_with("lrw")) .stdout(predicate::str::contains("⇒")); +} + +/// ls -l link/ +/// should show the dir content +#[cfg(unix)] +#[test] +fn test_show_folder_content_of_symlink_for_long_tail_slash() { + let dir = tempdir(); + dir.child("target").child("inside").touch().unwrap(); + let link = dir.path().join("link"); + fs::symlink("target", link).unwrap(); cmd() .arg("-l")