I introduced 2 new options to ls:
-e, --sort=dirsfirst
This sort option makes ls list directories first.
-j
This is used to range in noncapitals while sorting.
This way the listing is truely sorted alphabetically.
The attached diff is based on fileutils-4.1
Just unpack the fileutils-4.1.tar.gz, copy the file
fu-41.patch to fileutils-4.1/src. Change to the
directory and call: 'patch < fu-41.patch'
Then follow the usual install instructions.
Florian.
--- ls.c Sun Apr 29 11:42:47 2001
+++ ls.c.dirsfirstrangein Sat Nov 3 20:36:29 2001
@@ -293,6 +293,10 @@
const struct fileinfo *file2));
static int rev_cmp_extension PARAMS ((const struct fileinfo *file2,
const struct fileinfo *file1));
+static int compare_dirsfirst PARAMS ((const struct fileinfo *file1,
+ const struct fileinfo *file2));
+static int rev_cmp_dirsfirst PARAMS ((const struct fileinfo *file2,
+ const struct fileinfo *file1));
static int compare_version PARAMS ((const struct fileinfo *file1,
const struct fileinfo *file2));
static int rev_cmp_version PARAMS ((const struct fileinfo *file2,
@@ -422,7 +426,7 @@
static int full_time;
-/* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v. */
+/* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v, -e. */
enum sort_type
{
@@ -431,7 +435,8 @@
sort_extension, /* -X */
sort_time, /* -t */
sort_size, /* -S */
- sort_version /* -v */
+ sort_version, /* -v */
+ sort_dirsfirst /* -e */
};
static enum sort_type sort_type;
@@ -720,12 +725,12 @@
static char const *const sort_args[] =
{
- "none", "time", "size", "extension", "version", 0
+ "none", "time", "size", "extension", "version", "dirsfirst", 0
};
static enum sort_type const sort_types[] =
{
- sort_none, sort_time, sort_size, sort_extension, sort_version
+ sort_none, sort_time, sort_size, sort_extension, sort_version, sort_dirsfirst
};
static char const *const time_args[] =
@@ -771,6 +776,8 @@
for the separating white space. */
#define MIN_COLUMN_WIDTH 3
+/* Default sorting function is strcoll(), considering the locale. */
+static int (*strcmpfunc)() = strcoll;
/* This zero-based index is used solely with the --dired option.
When that option is in effect, this counter is incremented for each
@@ -877,7 +884,7 @@
}
format_needs_stat = sort_type == sort_time || sort_type == sort_size
- || format == long_format
+ || sort_type == sort_dirsfirst || format == long_format
|| trace_links || trace_dirs || print_block_size || print_inode;
format_needs_type = (format_needs_stat == 0
&& (print_with_color || indicator_style != none));
@@ -1076,7 +1083,7 @@
}
while ((c = getopt_long (argc, argv,
- "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1",
+ "abcdefghijklmnopqrstuvw:xABCDFGHI:LNQRST:UX1",
long_options, NULL)) != -1)
{
switch (c)
@@ -1101,6 +1108,11 @@
immediate_dirs = 1;
break;
+ case 'e':
+ sort_type = sort_dirsfirst;
+ sort_type_specified = 1;
+ break;
+
case 'f':
/* Same as enabling -a -U and disabling -l -s. */
all_files = 1;
@@ -1136,6 +1148,10 @@
print_inode = 1;
break;
+ case 'j':
+ strcmpfunc = strcasecmp;
+ break;
+
case 'k':
output_block_size = 1024;
break;
@@ -2169,6 +2185,9 @@
case sort_version:
func = sort_reverse ? rev_cmp_version : compare_version;
break;
+ case sort_dirsfirst:
+ func = sort_reverse ? rev_cmp_dirsfirst : compare_dirsfirst;
+ break;
default:
abort ();
}
@@ -2265,7 +2284,7 @@
static int
compare_name (const struct fileinfo *file1, const struct fileinfo *file2)
{
- return strcoll (file1->name, file2->name);
+ return strcmpfunc (file1->name, file2->name); //strcoll
}
static int
@@ -2317,6 +2336,22 @@
return cmp;
}
+static int
+compare_dirsfirst (const struct fileinfo *file1, const struct fileinfo *file2)
+{
+ if (S_ISDIR(file1->stat.st_mode) == S_ISDIR(file2->stat.st_mode))
+ return compare_name (file1, file2);
+ return S_ISDIR(file1->stat.st_mode) ? -1 : 1;
+}
+
+static int
+rev_cmp_dirsfirst (const struct fileinfo *file2, const struct fileinfo *file1)
+{
+ if (S_ISDIR(file1->stat.st_mode) == S_ISDIR(file2->stat.st_mode))
+ return compare_name (file1, file2);
+ return S_ISDIR(file1->stat.st_mode) ? -1 : 1;
+}
+
/* List all the files now in the table. */
static void
@@ -3268,6 +3303,7 @@
types. WHEN may be `never', `always', or `auto'\n\
-d, --directory list directory entries instead of contents\n\
-D, --dired generate output designed for Emacs' dired mode\n\
+ -e sort alphabetically with directories first\n\
-f do not sort, enable -aU, disable -lst\n\
-F, --classify append indicator (one of */=@|) to entries\n\
--format=WORD across -x, commas -m, horizontal -x, long -l,\n\
@@ -3284,6 +3320,7 @@
--indicator-style=WORD append indicator with style WORD to entry names:\n\
none (default), classify (-F), file-type (-p)\n\
-i, --inode print index number of each file\n\
+ -j sort alphabetically, ranging in noncapitals\n\
-I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\
-k, --kilobytes like --block-size=1024\n\
-l use a long listing format\n\
@@ -3307,7 +3344,7 @@
printf (_("\
-S sort by file size\n\
--sort=WORD extension -X, none -U, size -S, time -t,\n\
- version -v\n\
+ version -v, dirsfirst -e\n\
status -c, time -t, atime -u, access -u, use -u\n\
--time=WORD show time as WORD instead of modification time:\n\
atime, access, use, ctime or status; use\n\