diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index 465fae16ff..b1b231a4a5 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -339,7 +339,7 @@ fn ls_for_one_pattern( let path = pattern_arg.into_spanned(p_tag); let (prefix, paths) = if just_read_dir { let expanded = nu_path::expand_path_with(path.item.as_ref(), &cwd, path.item.is_expand()); - let paths = read_dir(&expanded)?; + let paths = read_dir(&expanded, use_threads)?; // just need to read the directory, so prefix is path itself. (Some(expanded), paths) } else { @@ -979,10 +979,20 @@ mod windows_helper { #[allow(clippy::type_complexity)] fn read_dir( f: &Path, + use_threads: bool, ) -> Result> + Send>, ShellError> { - let iter = f.read_dir()?.map(|d| { + let items = f.read_dir()?.map(|d| { d.map(|r| r.path()) .map_err(|e| ShellError::IOError { msg: e.to_string() }) }); - Ok(Box::new(iter)) + if !use_threads { + let mut collected = items.collect::>(); + collected.sort_by(|a, b| { + let a = a.as_ref().expect("path should be valid"); + let b = b.as_ref().expect("path should be valid"); + a.cmp(b) + }); + return Ok(Box::new(collected.into_iter())); + } + Ok(Box::new(items)) } diff --git a/crates/nu-command/tests/commands/ls.rs b/crates/nu-command/tests/commands/ls.rs index 7ac0063741..4140ea64bc 100644 --- a/crates/nu-command/tests/commands/ls.rs +++ b/crates/nu-command/tests/commands/ls.rs @@ -833,3 +833,27 @@ fn list_symlink_with_full_path() { ); }) } + +#[test] +fn consistent_list_order() { + Playground::setup("ls_test_order", |dirs, sandbox| { + sandbox.with_files(&[ + EmptyFile("los.txt"), + EmptyFile("tres.txt"), + EmptyFile("amigos.txt"), + EmptyFile("arepas.clu"), + ]); + + let no_arg = nu!( + cwd: dirs.test(), pipeline( + "ls" + )); + + let with_arg = nu!( + cwd: dirs.test(), pipeline( + "ls ." + )); + + assert_eq!(no_arg.out, with_arg.out); + }) +}