This diff allows dired mode to sort directory contents alphabetically
or by date order. It uses the same key as emacs: 's', though the
extended command name is 'dired-sort'. Comments/ok?
-lum
Index: dired.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/dired.c,v
retrieving revision 1.78
diff -u -p -u -p -r1.78 dired.c
--- dired.c 12 Oct 2015 19:08:39 -0000 1.78
+++ dired.c 13 Oct 2015 19:57:48 -0000
@@ -51,15 +51,20 @@ static int d_forwline(int, int);
static int d_backline(int, int);
static int d_killbuffer_cmd(int, int);
static int d_refreshbuffer(int, int);
+static int d_sort(int, int);
static void reaper(int);
static struct buffer *refreshbuffer(struct buffer *);
static int createlist(struct buffer *);
static void redelete(struct buffer *);
static char *findfname(struct line *, char *);
+static void finddotlsal(struct buffer *);
extern struct keymap_s helpmap, cXmap, metamap;
-const char DDELCHAR = 'D';
+const char DDELCHAR = 'D';
+const int LSALT = 4; /* 4 = -alt, 3 = -al) */
+char lsargs[5] = "-al"; /* see LSALT above */
+int lsarg_toggle = 0; /* 's' has implications for dot */
/*
* Structure which holds a linked list of file names marked for
@@ -134,7 +139,7 @@ static PF diredn[] = {
d_backline, /* p */
d_killbuffer_cmd, /* q */
d_rename, /* r */
- rescan, /* s */
+ d_sort, /* s */
rescan, /* t */
d_undel, /* u */
rescan, /* v */
@@ -212,6 +217,7 @@ dired_init(void)
funmap_add(d_rename, "dired-do-rename");
funmap_add(d_backpage, "dired-scroll-down");
funmap_add(d_forwpage, "dired-scroll-up");
+ funmap_add(d_sort, "dired-sort");
funmap_add(d_undel, "dired-unmark");
funmap_add(d_killbuffer_cmd, "quit-window");
maps_add((KEYMAP *)&diredmap, "dired");
@@ -750,7 +756,16 @@ refreshbuffer(struct buffer *bp)
if (ddel)
redelete(bp);
- /* find dot line */
+ /* If required, find suitable dot line if toggling sort order. */
+ if (lsarg_toggle && (strlen(lsargs) == LSALT)) {
+ tmp_w_dotline = 2; /* 2nd line for -alt */
+ lsarg_toggle = 0;
+ } else if (lsarg_toggle) {
+ finddotlsal(bp); /* or after ".." if -al */
+ lsarg_toggle = 0;
+ curbp = bp;
+ return (bp);
+ }
bp->b_dotp = bfirstlp(bp);
if (tmp_w_dotline > bp->b_lines)
tmp_w_dotline = bp->b_lines - 1;
@@ -848,7 +863,6 @@ struct buffer *
dired_(char *dname)
{
struct buffer *bp;
- int i;
size_t len;
if ((dname = adjustname(dname, TRUE)) == NULL) {
@@ -881,26 +895,11 @@ dired_(char *dname)
bp = bfind(dname, TRUE);
bp->b_flag |= BFREADONLY | BFIGNDIRTY;
- if ((d_exec(2, bp, NULL, "ls", "-al", dname, NULL)) != TRUE)
+ if ((d_exec(2, bp, NULL, "ls", lsargs, dname, NULL)) != TRUE)
return (NULL);
- /* Find the line with ".." on it. */
- bp->b_dotp = bfirstlp(bp);
- bp->b_dotline = 1;
- for (i = 0; i < bp->b_lines; i++) {
- bp->b_dotp = lforw(bp->b_dotp);
- bp->b_dotline++;
- if (d_warpdot(bp->b_dotp, &bp->b_doto) == FALSE)
- continue;
- if (strcmp(ltext(bp->b_dotp) + bp->b_doto, "..") == 0)
- break;
- }
+ finddotlsal(bp);
- /* We want dot on the entry right after "..", if possible. */
- if (++i < bp->b_lines - 2) {
- bp->b_dotp = lforw(bp->b_dotp);
- bp->b_dotline++;
- }
d_warpdot(bp->b_dotp, &bp->b_doto);
(void)strlcpy(bp->b_fname, dname, sizeof(bp->b_fname));
@@ -1035,4 +1034,46 @@ findfname(struct line *lp, char *fn)
return NULL;
fn = &lp->l_text[start];
return fn;
+}
+
+static int
+d_sort(int f, int n)
+{
+ struct buffer *bp;
+
+ if (strlen(lsargs) == LSALT)
+ (void)snprintf(lsargs, sizeof(lsargs), "-al");
+ else
+ (void)snprintf(lsargs, sizeof(lsargs), "-alt");
+
+ lsarg_toggle = 1;
+
+ if ((bp = refreshbuffer(curbp)) == NULL)
+ return (FALSE);
+ return (showbuffer(bp, curwp, WFFULL | WFMODE));
+}
+
+static void
+finddotlsal(struct buffer *bp)
+{
+ int i;
+
+ bp->b_dotp = bfirstlp(bp);
+ bp->b_dotline = 1;
+ for (i = 0; i < bp->b_lines; i++) {
+ bp->b_dotp = lforw(bp->b_dotp);
+ bp->b_dotline++;
+ if (d_warpdot(bp->b_dotp, &bp->b_doto) == FALSE)
+ continue;
+ if (strcmp(ltext(bp->b_dotp) + bp->b_doto, "..") == 0)
+ break;
+ }
+
+ /* We want dot on the entry right after "..", if possible. */
+ if (++i < bp->b_lines - 2) {
+ bp->b_dotp = lforw(bp->b_dotp);
+ bp->b_dotline++;
+ }
+
+ return;
}
Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.94
diff -u -p -u -p -r1.94 mg.1
--- mg.1 12 Oct 2015 07:55:52 -0000 1.94
+++ mg.1 13 Oct 2015 19:57:48 -0000
@@ -965,6 +965,8 @@ dired-previous-line
quit-window
.It r
dired-do-rename
+.It s
+dired-sort
.It u
dired-unmark
.It x
@@ -1009,6 +1011,8 @@ Refresh the dired buffer.
Scroll down the dired buffer.
.It dired-scroll-up
Scroll up the dired buffer.
+.It dired-sort
+Toggle the listing of directory contents alphabetically or by date order.
.It dired-unmark
Remove the deletion flag for the file on the current line.
.It dired-unmark-backward