diff --git a/src/uu/ls/src/display.rs b/src/uu/ls/src/display.rs index eb61816a8e3..a286433cfd9 100644 --- a/src/uu/ls/src/display.rs +++ b/src/uu/ls/src/display.rs @@ -747,6 +747,7 @@ fn display_item_name( target_path.file_name().map(Cow::Borrowed), config, false, + false, ); // Check if the target actually needs coloring diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 392aed0972e..470c5bcbdee 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -816,6 +816,7 @@ pub struct PathData<'a> { p_buf: Cow<'a, Path>, must_dereference: bool, command_line: bool, + is_dot_dir: bool, } impl<'a> PathData<'a> { @@ -838,6 +839,7 @@ impl<'a> PathData<'a> { file_name: Option>, config: &Config, command_line: bool, + is_dot_dir: bool, ) -> Self { // We cannot use `Path::ends_with` or `Path::Components`, because they remove occurrences of '.' // For '..', the filename is None @@ -904,6 +906,7 @@ impl<'a> PathData<'a> { p_buf, must_dereference, command_line, + is_dot_dir, } } @@ -976,6 +979,15 @@ impl<'a> PathData<'a> { PathDataDisplayName::Custom(ref cow) => cow, } } + + fn file_name(&self) -> &OsStr { + match self.display_name { + PathDataDisplayName::SelfReferential => { + self.p_buf.file_name().unwrap_or(self.p_buf.as_os_str()) + } + PathDataDisplayName::Custom(ref cow) => cow, + } + } } impl Colorable for PathData<'_> { @@ -1164,7 +1176,7 @@ pub fn list_with_output( let initial_locs_len = locs.len(); for loc in locs { - let path_data = PathData::new(loc.into(), None, None, config, true); + let path_data = PathData::new(loc.into(), None, None, config, true, false); // Getting metadata here is no big deal as it's just the CWD // and we really just want to know if the strings exist as files/dirs @@ -1278,6 +1290,7 @@ fn collect_directory_entries( Some(OsStr::new(".").into()), config, false, + true, )); entries.push(PathData::new( dotdot_path(path_data.path()).into(), @@ -1285,6 +1298,7 @@ fn collect_directory_entries( Some(OsStr::new("..").into()), config, false, + true, )); } @@ -1305,6 +1319,7 @@ fn collect_directory_entries( None, config, false, + false, )); } } @@ -1375,6 +1390,7 @@ fn enter_directory( None, config, entry.command_line, + false, ); if !entry.is_first { @@ -1404,12 +1420,9 @@ fn enter_directory( write_directory_entries(entries, config, output)?; if config.recursive { - let start = if config.files == Files::All { 2 } else { 0 }; - for child in entries .iter() - .skip(start) - .filter(|p| p.file_type().is_some_and(FileType::is_dir)) + .filter(|p| p.file_type().is_some_and(FileType::is_dir) && !p.is_dot_dir) .rev() { let child_path = child.path().to_path_buf(); @@ -1473,8 +1486,8 @@ fn sort_entries(entries: &mut [PathData], config: &Config) { Sort::Name => entries.sort_unstable_by(|a, b| a.display_name().cmp(b.display_name())), Sort::Version => entries.sort_unstable_by(|a, b| { version_cmp( - os_str_as_bytes_lossy(a.path().as_os_str()).as_ref(), - os_str_as_bytes_lossy(b.path().as_os_str()).as_ref(), + os_str_as_bytes_lossy(a.file_name()).as_ref(), + os_str_as_bytes_lossy(b.file_name()).as_ref(), ) .then(a.path().cmp(b.path())) }), diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 52191c0c9f8..81edec8d87f 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3661,7 +3661,7 @@ fn test_ls_version_sort() { ); let result = scene.ucmd().arg("-a1v").succeeds(); - expected.insert(expected.len() - 1, ".."); + expected.insert(0, ".."); expected.insert(0, "."); assert_eq!( result.stdout_str().split('\n').collect::>(),