This fixes Nima's PR and mark's issue with filenames that start with a space.
Index: src/usr.bin/mg/dired.c =================================================================== RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.48 diff -u -p -r1.48 dired.c --- src/usr.bin/mg/dired.c 23 Jan 2011 00:45:03 -0000 1.48 +++ src/usr.bin/mg/dired.c 29 Aug 2011 15:17:15 -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 }, { @@ -165,8 +193,12 @@ dired_init(void) funmap_add(d_findfile, "dired-find-file"); funmap_add(d_ffotherwindow, "dired-find-file-other-window"); funmap_add(d_del, "dired-flag-file-deleted"); + funmap_add(d_forwline, "dired-next-line"); funmap_add(d_otherwindow, "dired-other-window"); + funmap_add(d_backline, "dired-previous-line"); funmap_add(d_rename, "dired-rename-file"); + funmap_add(d_backpage, "dired-scroll-down"); + funmap_add(d_forwpage, "dired-scroll-up"); funmap_add(d_undel, "dired-unflag"); maps_add((KEYMAP *)&diredmap, "dired"); dobindkey(fundamental_map, "dired", "^Xd"); @@ -563,13 +595,13 @@ d_create_directory(int f, int n) return (showbuffer(bp, curwp, WFFULL | WFMODE)); } -#define NAME_FIELD 8 static int d_makename(struct line *lp, char *fn, size_t len) { - int i; + int i, col; char *p, *ep; + col = 0; if (strlcpy(fn, curbp->b_fname, len) >= len) return (FALSE); @@ -577,21 +609,98 @@ d_makename(struct line *lp, char *fn, si return (ABORT); ep = lp->l_text + llength(lp); p++; /* skip action letter, if any */ - for (i = 0; i < NAME_FIELD; i++) { - while (p < ep && isspace(*p)) - p++; - while (p < ep && !isspace(*p)) - p++; - while (p < ep && isspace(*p)) - p++; - if (p == ep) - return (ABORT); - } + while (p < ep) { + if ((i = strspn(p, " ")) > 0 && ((p + i) < ep)) { + if (++col == 9 && ((p + 1) < ep)) { + p++; + break; + } + p += i; + } + p++; + } if (strlcat(fn, p, len) >= len) return (FALSE); return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE); } +static int +d_warpdot(char *l_text) +{ + char *track, *anchor, *end; + int col = 0; + int i = 0; + anchor = NULL; + track = l_text; + end = track + strlen(track); + while (track < end) { + if((i = strspn(track, " ")) > 0 && ((track + i) < end)) { + if (++col == 9 && ((track + 1) < end)) { + anchor = ++track; + break; + } + track += i; + } + track++; + } + if (anchor == NULL) + return (-1); + else + return (track - l_text); +} + +static int +d_forwpage(int f, int n) +{ + int i; + + forwpage(f | FFRAND, n); + if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = i; + return TRUE; +} + +static int +d_backpage (int f, int n) +{ + int i; + + backpage(f | FFRAND, n); + if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = i; + return TRUE; +} + +static int +d_forwline (int f, int n) +{ + int i; + + forwline(f | FFRAND, n); + if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = i; + return TRUE; +} + +static int +d_backline (int f, int n) +{ + int i; + + backline(f | FFRAND, n); + if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1) + curwp->w_doto = 0; + else + curwp->w_doto = i; + return TRUE; +} + /* * XXX dname needs to have enough place to store an additional '/'. */ @@ -600,10 +709,13 @@ dired_(char *dname) { struct buffer *bp; FILE *dirpipe; - char line[256]; - int len, ret, counter, warp; + char line[256], tmp[256], ini[256]; + int len, ret, counter, warp, i, pos; + char *meta, *orig, *anchor; counter = 0; warp = 0; + pos = 0; + meta = "(){}[]'\"\\;<>|?!$^&~ "; if ((fopen(dname,"r")) == NULL) { if (errno == EACCES) @@ -627,7 +739,19 @@ dired_(char *dname) if (bclear(bp) != TRUE) return (NULL); bp->b_flag |= BFREADONLY; + (void) strlcpy(ini, dname, sizeof(ini)); + while ((anchor = strpbrk(&ini[pos], meta)) != NULL) { + pos = anchor - &ini[0]; + (void) strlcpy(tmp, &ini[pos], sizeof(tmp)); + ini[pos] = '\\'; + ini[pos+1] = '\0'; + (void) strlcat(&ini[pos], tmp, sizeof(ini)); + pos += 2; + } + orig = dname; + dname = &ini[0]; ret = snprintf(line, sizeof(line), "ls -al %s", dname); + dname = orig; if (ret < 0 || ret >= sizeof(line)) { ewprintf("Path too long"); return (NULL); @@ -649,9 +773,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 ((i = d_warpdot(line)) == -1) + bp->b_doto = 0; + else + bp->b_doto = i; if (pclose(dirpipe) == -1) { ewprintf("Problem closing pipe to ls : %s", strerror(errno));