diff --git a/src/uu_ls/ls.rs.html b/src/uu_ls/ls.rs.html index 7f70f7887..562267e10 100644 --- a/src/uu_ls/ls.rs.html +++ b/src/uu_ls/ls.rs.html @@ -1881,6 +1881,80 @@ 1879 1880 1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955
 // This file is part of the uutils coreutils package.
 //
@@ -3278,14 +3352,17 @@ only ignore '.' and '..'.",
     }
 }
 
-fn display_dir_entry_size(entry: &PathData, config: &Config) -> (usize, usize) {
+fn display_dir_entry_size(entry: &PathData, config: &Config) -> (usize, usize, usize, usize) {
+    // TODO: Cache/memoize the display_* results so we don't have to recalculate them.
     if let Some(md) = entry.md() {
         (
             display_symlink_count(md).len(),
+            display_uname(md, config).len(),
+            display_group(md, config).len(),
             display_size_or_rdev(md, config).len(),
         )
     } else {
-        (0, 0)
+        (0, 0, 0, 0)
     }
 }
 
@@ -3293,15 +3370,28 @@ only ignore '.' and '..'.",
     format!("{:>width$}", string, width = count)
 }
 
+fn pad_right(string: String, count: usize) -> String {
+    format!("{:<width$}", string, width = count)
+}
+
 fn display_items(items: &[PathData], config: &Config, out: &mut BufWriter<Stdout>) {
     if config.format == Format::Long {
-        let (mut max_links, mut max_width) = (1, 1);
+        let (
+            mut longest_link_count_len,
+            mut longest_uname_len,
+            mut longest_group_len,
+            mut longest_size_len,
+        ) = (1, 1, 1, 1);
         let mut total_size = 0;
 
         for item in items {
-            let (links, width) = display_dir_entry_size(item, config);
-            max_links = links.max(max_links);
-            max_width = width.max(max_width);
+            let (link_count_len, uname_len, group_len, size_len) =
+                display_dir_entry_size(item, config);
+            longest_link_count_len = link_count_len.max(longest_link_count_len);
+            longest_size_len = size_len.max(longest_size_len);
+            longest_uname_len = uname_len.max(longest_uname_len);
+            longest_group_len = group_len.max(longest_group_len);
+            longest_size_len = size_len.max(longest_size_len);
             total_size += item.md().map_or(0, |md| get_block_size(md, config));
         }
 
@@ -3310,7 +3400,15 @@ only ignore '.' and '..'.",
         }
 
         for item in items {
-            display_item_long(item, max_links, max_width, config, out);
+            display_item_long(
+                item,
+                longest_link_count_len,
+                longest_uname_len,
+                longest_group_len,
+                longest_size_len,
+                config,
+                out,
+            );
         }
     } else {
         let names = items.iter().filter_map(|i| display_file_name(i, config));
@@ -3415,10 +3513,48 @@ only ignore '.' and '..'.",
     }
 }
 
+/// This writes to the BufWriter out a single string of the output of `ls -l`.
+///
+/// It writes the following keys, in order:
+/// * `inode` ([`get_inode`], config-optional)
+/// * `permissions` ([`display_permissions`])
+/// * `symlink_count` ([`display_symlink_count`])
+/// * `owner` ([`display_uname`], config-optional)
+/// * `group` ([`display_group`], config-optional)
+/// * `author` ([`display_uname`], config-optional)
+/// * `size / rdev` ([`display_size_or_rdev`])
+/// * `system_time` ([`get_system_time`])
+/// * `file_name` ([`display_file_name`])
+///
+/// This function needs to display information in columns:
+/// * permissions and system_time are already guaranteed to be pre-formatted in fixed length.
+/// * file_name is the last column and is left-aligned.
+/// * Everything else needs to be padded using [`pad_left`].
+///
+/// That's why we have the parameters:
+/// ```txt
+///    max_links: usize,
+///    longest_uname_len: usize,
+///    longest_group_len: usize,
+///    max_size: usize,
+/// ```
+/// that decide the maximum possible character count of each field.
+///
+/// [`get_inode`]: ls::get_inode
+/// [`display_permissions`]: ls::display_permissions
+/// [`display_symlink_count`]: ls::display_symlink_count
+/// [`display_uname`]: ls::display_uname
+/// [`display_group`]: ls::display_group
+/// [`display_size_or_rdev`]: ls::display_size_or_rdev
+/// [`get_system_time`]: ls::get_system_time
+/// [`display_file_name`]: ls::display_file_name
+/// [`pad_left`]: ls::pad_left
 fn display_item_long(
     item: &PathData,
-    max_links: usize,
-    max_size: usize,
+    longest_link_count_len: usize,
+    longest_uname_len: usize,
+    longest_group_len: usize,
+    longest_size_len: usize,
     config: &Config,
     out: &mut BufWriter<Stdout>,
 ) {
@@ -3441,27 +3577,39 @@ only ignore '.' and '..'.",
         out,
         "{} {}",
         display_permissions(md, true),
-        pad_left(display_symlink_count(md), max_links),
+        pad_left(display_symlink_count(md), longest_link_count_len),
     );
 
     if config.long.owner {
-        let _ = write!(out, " {}", display_uname(md, config));
+        let _ = write!(
+            out,
+            " {}",
+            pad_right(display_uname(md, config), longest_uname_len)
+        );
     }
 
     if config.long.group {
-        let _ = write!(out, " {}", display_group(md, config));
+        let _ = write!(
+            out,
+            " {}",
+            pad_right(display_group(md, config), longest_group_len)
+        );
     }
 
     // Author is only different from owner on GNU/Hurd, so we reuse
     // the owner, since GNU/Hurd is not currently supported by Rust.
     if config.long.author {
-        let _ = write!(out, " {}", display_uname(md, config));
+        let _ = write!(
+            out,
+            " {}",
+            pad_right(display_uname(md, config), longest_uname_len)
+        );
     }
 
     let _ = writeln!(
         out,
         " {} {} {}",
-        pad_left(display_size_or_rdev(md, config), max_size),
+        pad_left(display_size_or_rdev(md, config), longest_size_len),
         display_date(md, config),
         // unwrap is fine because it fails when metadata is not available
         // but we already know that it is because it's checked at the
diff --git a/uu_ls/index.html b/uu_ls/index.html
index 8764464d1..ef00c7797 100644
--- a/uu_ls/index.html
+++ b/uu_ls/index.html
@@ -1,5 +1,5 @@
 uu_ls - Rust
 
-

Crate uu_ls[][src]

Modules

+

Crate uu_ls[][src]

Modules

options

Functions

uu_app
uumain
\ No newline at end of file