Hi, One of the things lacking in mg was support M-x make-directory, which comes quite handy. This diff mimics the rather silent behaviour of Emacs: there's basically no feedback in case creating the directory failed for whatever reason. Should we be more verbose about it, or just stay in line with Emacs?
diff --git def.h def.h index 6a752d5..11e3c24 100644 --- def.h +++ def.h @@ -335,6 +335,7 @@ void dirinit(void); int changedir(int, int); int showcwdir(int, int); int getcwdir(char *, size_t); +int makedir(int, int); /* dired.c */ struct buffer *dired_(char *); diff --git dir.c dir.c index 2352773..18eb946 100644 --- dir.c +++ dir.c @@ -9,6 +9,8 @@ * Modified for MG 2a by Mic Kaczmarczik 03-Aug-1987 */ +#include <sys/stat.h> + #include "def.h" static char mgcwd[NFILEN]; @@ -75,3 +77,62 @@ getcwdir(char *buf, size_t len) return (TRUE); } + +/* Create the directory and it's parents. */ +/* ARGSUSED */ +int +makedir(int f, int n) +{ + struct stat sb; + int finished, ishere; + mode_t dir_mode, mode, oumask; + char bufc[NFILEN], *path, *slash; + + (void)strlcpy(bufc, curbp->b_cwd, sizeof(bufc)); + if ((path = eread("Make directory: ", bufc, NFILEN, + EFDEF | EFNEW | EFCR | EFFILE)) == NULL) + return (ABORT); + else if (path[0] == '\0') + return (FALSE); + + slash = path; + oumask = umask(0); + mode = 0777 & ~oumask; + dir_mode = mode | S_IWUSR | S_IXUSR; + + for (;;) { + slash += strspn(slash, "/"); + slash += strcspn(slash, "/"); + + finished = (*slash == '\0'); + *slash = '\0'; + + ishere = !stat(path, &sb); + if (!finished && ishere && S_ISDIR(sb.st_mode)) { + *slash = '/'; + continue; + } + + if (mkdir(path, finished ? mode : dir_mode) == 0) { + if (mode > 0777 && chmod(path, mode) < 0) { + umask(oumask); + return (ABORT); + } + } else { + if (!ishere || !S_ISDIR(sb.st_mode)) { + eerase(); + umask(oumask); + return (ABORT); + } + } + + if (finished) + break; + + *slash = '/'; + } + + eerase(); + umask(oumask); + return (TRUE); +} diff --git file.c file.c index 8c1297b..2717931 100644 --- file.c +++ file.c @@ -258,13 +258,14 @@ readin(char *fname) dp = dirname(fname); if (stat(dp, &statbuf) == -1 && errno == ENOENT) { /* no read-only; like emacs */ - ewprintf("Parent directory missing"); + ewprintf("Use M-x make-directory RET RET to " + "create the directory and it's parents"); } else if (access(dp, W_OK) == -1 && errno == EACCES) { ewprintf("File not found and directory" " write-protected"); ro = TRUE; - } + } } } if (ro == TRUE) diff --git funmap.c funmap.c index 66dd414..9a1be39 100644 --- funmap.c +++ funmap.c @@ -198,6 +198,7 @@ static struct funmap functnames[] = { {csprevfile, "cscope-prev-file",}, {cscreatelist, "cscope-create-list-of-files-to-index",}, {revertbuffer, "revert-buffer",}, + {makedir, "make-directory",}, {NULL, NULL,} }; diff --git mg.1 mg.1 index 42411c6..3d46675 100644 --- mg.1 +++ mg.1 @@ -662,6 +662,8 @@ Bind a key mapping in the local (topmost) mode. Unbind a key mapping in the local (topmost) mode. .It make-backup-files Toggle generation of backup files. +.It make-directory +Prompt the user for a path or directory name which is then created. .It mark-whole-buffer Marks whole buffer as a region by putting dot at the beginning and mark at the end of buffer. -- Cheers, Jasper "Stay Hungry. Stay Foolish"