On Thu, Nov 15, 2012 at 05:01:50PM +0100, Jasper Lievisse Adriaanse wrote: > 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? Here is a slightly updated diff which uses getbufcwd() and (in line with Emacs), returns a permission denied message, as spotted by lum@.
Index: def.h =================================================================== RCS file: /cvs/src/usr.bin/mg/def.h,v retrieving revision 1.129 diff -p -u -r1.129 def.h --- def.h 6 Nov 2012 18:04:10 -0000 1.129 +++ def.h 16 Nov 2012 22:09:16 -0000 @@ -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 *); Index: dir.c =================================================================== RCS file: /cvs/src/usr.bin/mg/dir.c,v retrieving revision 1.19 diff -p -u -r1.19 dir.c --- dir.c 13 Jun 2008 20:07:40 -0000 1.19 +++ dir.c 16 Nov 2012 22:09:16 -0000 @@ -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]; @@ -73,5 +75,69 @@ getcwdir(char *buf, size_t len) if (strlcpy(buf, mgcwd, len) >= len) return (FALSE); + 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; + + if (getbufcwd(bufc, sizeof(bufc)) != TRUE) + return (ABORT); + 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)) { + if (!ishere) + ewprintf("Creating directory: permission denied, %s", path); + else + eerase(); + + umask(oumask); + return (FALSE); + } + } + + if (finished) + break; + + *slash = '/'; + } + + eerase(); + umask(oumask); return (TRUE); } Index: file.c =================================================================== RCS file: /cvs/src/usr.bin/mg/file.c,v retrieving revision 1.84 diff -p -u -r1.84 file.c --- file.c 30 Aug 2012 21:36:48 -0000 1.84 +++ file.c 16 Nov 2012 22:09:16 -0000 @@ -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) Index: funmap.c =================================================================== RCS file: /cvs/src/usr.bin/mg/funmap.c,v retrieving revision 1.41 diff -p -u -r1.41 funmap.c --- funmap.c 12 Oct 2012 21:13:46 -0000 1.41 +++ funmap.c 16 Nov 2012 22:09:16 -0000 @@ -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,} }; Index: mg.1 =================================================================== RCS file: /cvs/src/usr.bin/mg/mg.1,v retrieving revision 1.71 diff -p -u -r1.71 mg.1 --- mg.1 13 Nov 2012 22:03:44 -0000 1.71 +++ mg.1 16 Nov 2012 22:09:17 -0000 @@ -662,6 +662,8 @@ Bind a key mapping in the local (topmost 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"