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