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"