Mark Lumsden contributed code that makes it faster. I use his suggestions as well for other sections of the diff.
Index: dired.c =================================================================== RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.48 diff -u -p -r1.48 dired.c --- dired.c 23 Jan 2011 00:45:03 -0000 1.48 +++ dired.c 26 Aug 2011 06:14:57 -0000 @@ -36,6 +36,11 @@ static int d_rename(int, int); static int d_shell_command(int, int); static int d_create_directory(int, int); static int d_makename(struct line *, char *, size_t); +static int d_warpdot(char *); +static int d_forwpage(int, int); +static int d_backpage(int, int); +static int d_forwline(int, int); +static int d_backline(int, int); static void reaper(int); extern struct keymap_s helpmap, cXmap, metamap; @@ -57,15 +62,15 @@ static PF dirednul[] = { static PF diredcl[] = { reposition, /* ^L */ d_findfile, /* ^M */ - forwline, /* ^N */ + d_forwline, /* ^N */ rescan, /* ^O */ - backline, /* ^P */ + d_backline, /* ^P */ rescan, /* ^Q */ backisearch, /* ^R */ forwisearch, /* ^S */ rescan, /* ^T */ universal_argument, /* ^U */ - forwpage, /* ^V */ + d_forwpage, /* ^V */ rescan, /* ^W */ NULL /* ^X */ }; @@ -77,7 +82,7 @@ static PF diredcz[] = { rescan, /* ^] */ rescan, /* ^^ */ rescan, /* ^_ */ - forwline, /* SP */ + d_forwline, /* SP */ d_shell_command, /* ! */ rescan, /* " */ rescan, /* # */ @@ -99,9 +104,9 @@ static PF diredc[] = { }; static PF diredn[] = { - forwline, /* n */ + d_forwline, /* n */ d_ffotherwindow, /* o */ - backline, /* p */ + d_backline, /* p */ rescan, /* q */ d_rename, /* r */ rescan, /* s */ @@ -116,13 +121,32 @@ static PF direddl[] = { d_undelbak /* del */ }; +static PF diredbp[] = { + d_backpage /* v */ +}; + +static PF dirednull[] = { + NULL +}; + #ifndef DIRED_XMAPS #define NDIRED_XMAPS 0 /* number of extra map sections */ #endif /* DIRED_XMAPS */ -static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = { - 6 + NDIRED_XMAPS, - 6 + NDIRED_XMAPS + IMAPEXT, +static struct KEYMAPE (1 + IMAPEXT) d_backpagemap = { + 1, + 1 + IMAPEXT, + rescan, + { + { + 'v', 'v', diredbp, NULL + } + } +}; + +static struct KEYMAPE (7 + NDIRED_XMAPS + IMAPEXT) diredmap = { + 7 + NDIRED_XMAPS, + 7 + NDIRED_XMAPS + IMAPEXT, rescan, { #ifndef NO_HELP @@ -138,6 +162,10 @@ static struct KEYMAPE (6 + NDIRED_XMAPS CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) & cXmap }, { + CCHR('['), CCHR('['), dirednull, (KEYMAP *) & + d_backpagemap + }, + { CCHR('Z'), '+', diredcz, (KEYMAP *) & metamap }, { @@ -592,6 +620,80 @@ d_makename(struct line *lp, char *fn, si return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE); } +static int +d_warpdot(char *l_text) +{ + char *track; + int col = 0; + int ws = 0; + + track = l_text; + while (track != NULL && track - l_text <= strlen(l_text)) { + if((ws = strspn(track, " ")) > 0) { + track += ws; + if (++col == 9) + break; + } + track++; + } + if (track == NULL) + return (-1); + else + return (track - l_text); +} + +static int +d_forwpage(int f, int n) +{ + int loc; + + forwpage(f | FFRAND, n); + if ((loc = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = loc; + return TRUE; +} + +static int +d_backpage (int f, int n) +{ + int loc; + + backpage(f | FFRAND, n); + if ((loc = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = loc; + return TRUE; +} + +static int +d_forwline (int f, int n) +{ + int loc; + + forwline(f | FFRAND, n); + if ((loc = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = loc; + return TRUE; +} + +static int +d_backline (int f, int n) +{ + int loc; + + backline(f | FFRAND, n); + if ((loc = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = loc; + return TRUE; +} + /* * XXX dname needs to have enough place to store an additional '/'. */ @@ -601,9 +703,8 @@ dired_(char *dname) struct buffer *bp; FILE *dirpipe; char line[256]; - int len, ret, counter, warp; - counter = 0; - warp = 0; + int len, ret, counter, warp, loc; + counter = warp = 0; if ((fopen(dname,"r")) == NULL) { if (errno == EACCES) @@ -649,9 +750,11 @@ dired_(char *dname) if ((strrchr(line,' ')) != NULL) { if (strcmp((strrchr(line,' '))," ..") == 0) warp = counter - 1; - } - if ((strrchr(line,' ')) != NULL) - bp->b_doto = strrchr(line,' ') - line + 1; + } + if ((loc = d_warpdot(line)) == -1) + bp->b_doto = 0; + else + bp->b_doto = loc; if (pclose(dirpipe) == -1) { ewprintf("Problem closing pipe to ls : %s", strerror(errno));