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"

Reply via email to