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

Reply via email to