@@ -79,6 +79,10 @@ impl Builtin for Ls {
7979 let mut output = String :: new ( ) ;
8080 let multiple_paths = paths. len ( ) > 1 || opts. recursive ;
8181
82+ // Separate file and directory arguments (like real ls)
83+ let mut file_args: Vec < ( & str , crate :: fs:: Metadata ) > = Vec :: new ( ) ;
84+ let mut dir_args: Vec < ( usize , & str , std:: path:: PathBuf ) > = Vec :: new ( ) ;
85+
8286 for ( i, path_str) in paths. iter ( ) . enumerate ( ) {
8387 let path = resolve_path ( ctx. cwd , path_str) ;
8488
@@ -93,37 +97,44 @@ impl Builtin for Ls {
9397 ) ) ;
9498 }
9599
96- // Check if it's a file or directory
97100 let metadata = ctx. fs . stat ( & path) . await ?;
98101
99102 if metadata. file_type . is_file ( ) {
100- // Single file - just list it
101- let name = Path :: new ( path_str)
102- . file_name ( )
103- . map ( |s| s. to_string_lossy ( ) . to_string ( ) )
104- . unwrap_or_else ( || path_str. to_string ( ) ) ;
105-
106- if opts. long {
107- output. push_str ( & format_long_entry ( & name, & metadata, opts. human ) ) ;
108- } else {
109- output. push_str ( & name) ;
110- output. push ( '\n' ) ;
111- }
103+ file_args. push ( ( path_str, metadata) ) ;
112104 } else {
113- // Directory
114- if let Err ( e) = list_directory (
115- & ctx,
116- & path,
117- path_str,
118- & mut output,
119- & opts,
120- multiple_paths,
121- i > 0 ,
122- )
123- . await
124- {
125- return Ok ( ExecResult :: err ( format ! ( "ls: {}\n " , e) , 2 ) ) ;
126- }
105+ dir_args. push ( ( i, path_str, path) ) ;
106+ }
107+ }
108+
109+ // Sort file arguments by time if -t, preserving original paths
110+ if opts. sort_by_time {
111+ file_args. sort_by ( |a, b| b. 1 . modified . cmp ( & a. 1 . modified ) ) ;
112+ }
113+
114+ // Output file arguments first (preserving path as given by user)
115+ for ( path_str, metadata) in & file_args {
116+ if opts. long {
117+ output. push_str ( & format_long_entry ( path_str, metadata, opts. human ) ) ;
118+ } else {
119+ output. push_str ( path_str) ;
120+ output. push ( '\n' ) ;
121+ }
122+ }
123+
124+ // Then output directory listings
125+ for ( i, path_str, path) in & dir_args {
126+ if let Err ( e) = list_directory (
127+ & ctx,
128+ path,
129+ path_str,
130+ & mut output,
131+ & opts,
132+ multiple_paths,
133+ * i > 0 || !file_args. is_empty ( ) ,
134+ )
135+ . await
136+ {
137+ return Ok ( ExecResult :: err ( format ! ( "ls: {}\n " , e) , 2 ) ) ;
127138 }
128139 }
129140
0 commit comments