[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

mg cwd, take 3



This is an updated version of a diff which adds buffer-specific
cwd tracking to mg. The idea is, mg should assume you want to keep
working in whatever the cwd of the current buffer is, and use that
for its defaults. (for file operations, grep, compilations, and
so forth). If you feel so inclined, please run with this and
report any breakage.

(Han, be warned. a dirname() is contained within.)

Index: buffer.c
===================================================================
RCS file: /usr/local/cvsweb/openbsd/src/usr.bin/mg/buffer.c,v
retrieving revision 1.56
diff -u -r1.56 buffer.c
--- buffer.c	6 Apr 2006 05:28:17 -0000	1.56
+++ buffer.c	25 Apr 2006 19:36:41 -0000
@@ -13,6 +13,7 @@
 #include "kbd.h"		/* needed for modes */
 
 static struct buffer  *makelist(void);
+static struct buffer *bnew(void);
 
 /* ARGSUSED */
 int
@@ -457,16 +458,13 @@
 /*
  * Search for a buffer, by name.
  * If not found, and the "cflag" is TRUE,
- * create a buffer and put it in the list of
- * all buffers. Return pointer to the BUFFER
- * block for the buffer.
+ * create a new buffer. Return pointer to the found
+ * (or new) buffer.
  */
 struct buffer *
 bfind(const char *bname, int cflag)
 {
 	struct buffer	*bp;
-	struct line	*lp;
-	int		 i;
 
 	bp = bheadp;
 	while (bp != NULL) {
@@ -477,18 +475,34 @@
 	if (cflag != TRUE)
 		return (NULL);
 
-	bp = calloc(1, sizeof(struct buffer));
-	if (bp == NULL) {
-		ewprintf("Can't get %d bytes", sizeof(struct buffer));
-		return (NULL);
-	}
+	bp = bnew();
+
 	if ((bp->b_bname = strdup(bname)) == NULL) {
 		ewprintf("Can't get %d bytes", strlen(bname) + 1);
 		free(bp);
 		return (NULL);
 	}
+
+	return (bp);
+}
+
+/*
+ * Create a new buffer and put it in the list of
+ * all buffers. 
+ */
+static struct buffer *
+bnew()
+{
+	struct buffer *bp;
+	struct line	*lp;
+	int		 i;
+
+	bp = calloc(1, sizeof(struct buffer));
+	if (bp == NULL) {
+		ewprintf("Can't get %d bytes", sizeof(struct buffer));
+		return (NULL);
+	}
 	if ((lp = lalloc(0)) == NULL) {
-		free(bp->b_bname);
 		free(bp);
 		return (NULL);
 	}
@@ -509,11 +523,13 @@
 		bp->b_modes[i] = defb_modes[i];
 	} while (i++ < defb_nmodes);
 	bp->b_fname[0] = '\0';
+	bp->b_cwd[0] = '\0';
 	bzero(&bp->b_fi, sizeof(bp->b_fi));
 	lp->l_fp = lp;
 	lp->l_bp = lp;
 	bp->b_bufp = bheadp;
 	bheadp = bp;
+
 	return (bp);
 }
 
@@ -741,3 +757,30 @@
 	return (popbuf(bp) != NULL);
 }
 #endif
+
+/*
+ * Return the working directory for the current buffer, terminated
+ * with a '/'. First, try to extract it from the current buffer's
+ * filename. If that fails, use global cwd.
+ */
+int
+getbufcwd(char *path, size_t plen)
+{
+	char cwd[NFILEN];
+
+	if (plen == 0)
+		return (FALSE);
+
+	if (curbp->b_cwd[0] != '\0') {
+		(void)strlcpy(path, curbp->b_cwd, plen);
+	} else {
+		if (getcwdir(cwd, sizeof(cwd)) == FALSE)
+			goto error;
+		(void)strlcpy(path, cwd, plen);
+	}
+	return (TRUE);
+error:
+	path[0] = '\0';
+	return (FALSE);
+}
+
Index: def.h
===================================================================
RCS file: /usr/local/cvsweb/openbsd/src/usr.bin/mg/def.h,v
retrieving revision 1.85
diff -u -r1.85 def.h
--- def.h	6 Apr 2006 05:28:17 -0000	1.85
+++ def.h	25 Apr 2006 19:36:37 -0000
@@ -249,6 +249,7 @@
 	char		 b_nwnd;	/* Count of windows on buffer	 */
 	char		 b_flag;	/* Flags			 */
 	char		 b_fname[NFILEN]; /* File name			 */
+	char		 b_cwd[NFILEN]; /* working directory		 */
 	struct fileinfo	 b_fi;		/* File attributes		 */
 	LIST_HEAD(, undo_rec) b_undo;	/* Undo actions list		*/
 	int		 b_undopos;	/* Where we were during last undo */
@@ -316,6 +317,7 @@
 void		 dirinit(void);
 int		 changedir(int, int);
 int		 showcwdir(int, int);
+int		 getcwdir(char *, size_t);
 
 /* dired.c */
 struct buffer	*dired_(char *);
@@ -392,6 +394,7 @@
 int		 usebuffer(int, int);
 int		 notmodified(int, int);
 int		 popbuftop(struct buffer *);
+int		 getbufcwd(char *, size_t);
 
 /* display.c */
 int		vtresize(int, int, int);
Index: dir.c
===================================================================
RCS file: /usr/local/cvsweb/openbsd/src/usr.bin/mg/dir.c,v
retrieving revision 1.16
diff -u -r1.16 dir.c
--- dir.c	20 Dec 2005 05:04:28 -0000	1.16
+++ dir.c	25 Apr 2006 19:36:53 -0000
@@ -11,8 +11,7 @@
 
 #include "def.h"
 
-char		*wdir;
-static char	 cwd[NFILEN];
+static char	 mgcwd[NFILEN];
 
 /*
  * Initialize anything the directory management routines need.
@@ -20,11 +19,12 @@
 void
 dirinit(void)
 {
-	if ((wdir = getcwd(cwd, sizeof(cwd))) == NULL) {
+	mgcwd[0] = '\0';
+	if (getcwd(mgcwd, sizeof(mgcwd)) == NULL) {
 		ewprintf("Can't get current directory!");
 		chdir("/");
-		(void)strlcpy(cwd, "/", sizeof(cwd));
 	}
+	(void)strlcat(mgcwd, "/", sizeof(mgcwd));
 }
 
 /*
@@ -34,10 +34,10 @@
 int
 changedir(int f, int n)
 {
-	char	bufc[NPAT], *bufp;
+	char	bufc[NFILEN], *bufp;
 
-	(void)strlcpy(bufc, wdir, sizeof(bufc));
-	if ((bufp = eread("Change default directory: ", bufc, NPAT,
+	(void)strlcpy(bufc, mgcwd, sizeof(bufc));
+	if ((bufp = eread("Change default directory: ", bufc, NFILEN,
 	    EFDEF | EFNEW | EFCR)) == NULL)
 		return (ABORT);
 	else if (bufp[0] == '\0')
@@ -46,9 +46,9 @@
 		ewprintf("Can't change dir to %s", bufc);
 		return (FALSE);
 	} else {
-		if ((wdir = getcwd(cwd, sizeof(cwd))) == NULL)
+		if ((bufp = getcwd(mgcwd, sizeof(mgcwd))) == NULL)
 			panic("Can't get current directory!");
-		ewprintf("Current directory is now %s", wdir);
+		ewprintf("Current directory is now %s", bufp);
 		return (TRUE);
 	}
 }
@@ -60,6 +60,15 @@
 int
 showcwdir(int f, int n)
 {
-	ewprintf("Current directory: %s", wdir);
+	ewprintf("Current directory: %s", mgcwd);
+	return (TRUE);
+}
+
+int
+getcwdir(char *buf, size_t len)
+{
+	if (strlcpy(buf, mgcwd, len) >= len)
+		return (FALSE);
+
 	return (TRUE);
 }
Index: dired.c
===================================================================
RCS file: /usr/local/cvsweb/openbsd/src/usr.bin/mg/dired.c,v
retrieving revision 1.35
diff -u -r1.35 dired.c
--- dired.c	20 Dec 2005 05:04:28 -0000	1.35
+++ dired.c	6 Apr 2006 05:27:33 -0000
@@ -630,7 +630,8 @@
 		return (NULL);
 	}
 	bp->b_dotp = lforw(bp->b_linep);	/* go to first line */
-	(void) strlcpy(bp->b_fname, dname, sizeof(bp->b_fname));
+	(void)strlcpy(bp->b_fname, dname, sizeof(bp->b_fname));
+	(void)strlcpy(bp->b_cwd, dname, sizeof(bp->b_cwd));
 	if ((bp->b_modes[1] = name_mode("dired")) == NULL) {
 		bp->b_modes[0] = name_mode("fundamental");
 		ewprintf("Could not find mode dired");
Index: file.c
===================================================================
RCS file: /usr/local/cvsweb/openbsd/src/usr.bin/mg/file.c,v
retrieving revision 1.53
diff -u -r1.53 file.c
--- file.c	6 Apr 2006 05:28:17 -0000	1.53
+++ file.c	25 Apr 2006 20:07:02 -0000
@@ -6,10 +6,10 @@
  *	File commands.
  */
 
-#include "def.h"
-
 #include <libgen.h>
 
+#include "def.h"
+
 /*
  * Insert a file into the current buffer.  Real easy - just call the
  * insertfile routine with the file name.
@@ -20,7 +20,10 @@
 {
 	char	 fname[NFILEN], *bufp, *adjf;
 
-	bufp = eread("Insert file: ", fname, NFILEN, EFNEW | EFCR | EFFILE);
+	if (getbufcwd(fname, sizeof(fname)) != TRUE)
+		fname[0] = '\0';
+	bufp = eread("Insert file: ", fname, NFILEN,
+	    EFNEW | EFCR | EFFILE | EFDEF);
 	if (bufp == NULL)
 		return (ABORT);
 	else if (bufp[0] == '\0')
@@ -42,19 +45,11 @@
 filevisit(int f, int n)
 {
 	struct buffer	*bp;
-	char	 fname[NFILEN], *bufp, *adjf, *slash;
+	char	 fname[NFILEN], *bufp, *adjf;
 	int	 status;
 
-	if (curbp->b_fname && curbp->b_fname[0] != '\0') {
-		if (strlcpy(fname, curbp->b_fname, sizeof(fname)) >= sizeof(fname))
-			return (FALSE);
-		if ((slash = strrchr(fname, '/')) != NULL) {
-			*(slash + 1) = '\0';
-		}
-	}
-	else
+	if (getbufcwd(fname, sizeof(fname)) != TRUE)
 		fname[0] = '\0';
-
 	bufp = eread("Find file: ", fname, NFILEN,
 	    EFNEW | EFCR | EFFILE | EFDEF);
 	if (bufp == NULL)
@@ -88,18 +83,11 @@
 filevisitalt(int f, int n)
 {
 	struct buffer	*bp;
-	char	 fname[NFILEN], *bufp, *adjf, *slash;
+	char	 fname[NFILEN], *bufp, *adjf;
 	int	 status;
 
-	if (curbp->b_fname && curbp->b_fname[0] != '\0') {
-		if (strlcpy(fname, curbp->b_fname, sizeof(fname)) >= sizeof(fname))
-			return (FALSE);
-		if ((slash = strrchr(fname, '/')) != NULL) {
-			*(slash + 1) = '\0';
-		}
-	} else
+	if (getbufcwd(fname, sizeof(fname)) != TRUE)
 		fname[0] = '\0';
-
 	bufp = eread("Find alternate file: ", fname, NFILEN,
 	    EFNEW | EFCR | EFFILE | EFDEF);
 	if (bufp == NULL)
@@ -152,8 +140,10 @@
 	char	 fname[NFILEN], *adjf, *bufp;
 	int	 status;
 
+	if (getbufcwd(fname, sizeof(fname)) != TRUE)
+		fname[0] = '\0';
 	if ((bufp = eread("Find file in other window: ", fname, NFILEN,
-	    EFNEW | EFCR | EFFILE)) == NULL)
+	    EFNEW | EFCR | EFFILE | EFDEF)) == NULL)
 		return (ABORT);
 	else if (bufp[0] == '\0')
 		return (FALSE);
@@ -305,8 +295,12 @@
 
 	/* cheap */
 	bp = curbp;
-	if (newname != NULL)
-		(void)strlcpy(bp->b_fname, newname, sizeof bp->b_fname);
+	if (newname != NULL) {
+		(void)strlcpy(bp->b_fname, newname, sizeof(bp->b_fname));
+		(void)strlcpy(bp->b_cwd, dirname(newname),
+		    sizeof(bp->b_cwd));
+		(void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd));
+	}
 
 	/* hard file open */
 	if ((s = ffropen(fname, (replacebuf == TRUE) ? bp : NULL)) == FIOERR)
@@ -331,6 +325,9 @@
 		undo_enable(x);
 		curbp = bp;
 		return (showbuffer(bp, curwp, WFHARD | WFMODE));
+	} else {
+		(void)strlcpy(bp->b_cwd, dirname(fname), sizeof(bp->b_cwd));
+		(void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd));
 	}
 	opos = curwp->w_doto;
 
@@ -474,8 +471,10 @@
 	char	 fname[NFILEN], bn[NBUFN];
 	char	*adjfname, *bufp;
 
+	if (getbufcwd(fname, sizeof(fname)) != TRUE)
+		fname[0] = '\0';
 	if ((bufp = eread("Write file: ", fname, NFILEN,
-	    EFNEW | EFCR | EFFILE)) == NULL)
+	    EFDEF | EFNEW | EFCR | EFFILE)) == NULL)
 		return (ABORT);
 	else if (bufp[0] == '\0')
 		return (FALSE);
@@ -487,6 +486,8 @@
 	bzero(&curbp->b_fi, sizeof(curbp->b_fi));
 	if ((s = writeout(curbp, adjfname)) == TRUE) {
 		(void)strlcpy(curbp->b_fname, adjfname, sizeof(curbp->b_fname));
+		if (getbufcwd(curbp->b_cwd, sizeof(curbp->b_cwd)) != TRUE)
+			(void)strlcpy(curbp->b_cwd, "/", sizeof(curbp->b_cwd));
 		free(curbp->b_bname);
 		if (baugname(bn, basename(curbp->b_fname), sizeof(bn))
 		    == FALSE)
Index: grep.c
===================================================================
RCS file: /usr/local/cvsweb/openbsd/src/usr.bin/mg/grep.c,v
retrieving revision 1.27
diff -u -r1.27 grep.c
--- grep.c	3 Apr 2006 00:19:32 -0000	1.27
+++ grep.c	25 Apr 2006 20:21:12 -0000
@@ -39,8 +39,7 @@
 static int	 grep(int, int);
 static int	 compile(int, int);
 static int	 gid(int, int);
-static struct buffer	*compile_mode(const char *, const char *, const char *);
-static int	 getbufcwd(char *, size_t);
+static struct buffer	*compile_mode(const char *, const char *);
 static int	 xlint(int, int);
 
 void grep_init(void);
@@ -88,14 +87,6 @@
 	char	 cprompt[NFILEN], *bufp;
 	struct buffer	*bp;
 	struct mgwin	*wp;
-	char	 path[NFILEN];
-
-	/* get buffer cwd */
-	if (getbufcwd(path, sizeof(path)) == FALSE) {
-		ewprintf("Failed. "
-		    "Can't get working directory of current buffer.");
-		return (FALSE);
-	}
 
 	(void)strlcpy(cprompt, "grep -n ", sizeof(cprompt));
 	if ((bufp = eread("Run grep: ", cprompt, NFILEN,
@@ -105,7 +96,7 @@
 		return (FALSE);
 	(void)snprintf(command, sizeof(command), "%s /dev/null", bufp);
 
-	if ((bp = compile_mode("*grep*", command, path)) == NULL)
+	if ((bp = compile_mode("*grep*", command)) == NULL)
 		return (FALSE);
 	if ((wp = popbuf(bp)) == NULL)
 		return (FALSE);
@@ -122,14 +113,6 @@
 	char	 cprompt[NFILEN], *bufp;
 	struct buffer	*bp;
 	struct mgwin	*wp;
-	char	 path[NFILEN];
-
-	/* get buffer cwd */
-	if (getbufcwd(path, sizeof(path)) == FALSE) {
-		ewprintf("Failed. "
-		    "Can't get working directory of current buffer.");
-		return (FALSE);
-	}
 
 	(void)strlcpy(cprompt, "make lint ", sizeof(cprompt));
 	if ((bufp = eread("Run lint: ", cprompt, NFILEN,
@@ -139,7 +122,7 @@
 		return (FALSE);
 	(void)snprintf(command, sizeof(command), "%s 2>&1", bufp);
 
-	if ((bp = compile_mode("*lint*", command, path)) == NULL)
+	if ((bp = compile_mode("*lint*", command)) == NULL)
 		return (FALSE);
 	if ((wp = popbuf(bp)) == NULL)
 		return (FALSE);
@@ -156,14 +139,6 @@
 	char	 cprompt[NFILEN], *bufp;
 	struct buffer	*bp;
 	struct mgwin	*wp;
-	char	 path[NFILEN];
-
-	/* get buffer cwd */
-	if (getbufcwd(path, sizeof(path)) == FALSE) {
-		ewprintf("Failed. "
-		    "Can't get working directory of current buffer.");
-		return (FALSE);
-	}
 
 	(void)strlcpy(cprompt, compile_last_command, sizeof(cprompt));
 	if ((bufp = eread("Compile command: ", cprompt, NFILEN,
@@ -177,7 +152,7 @@
 
 	(void)snprintf(command, sizeof(command), "%s 2>&1", bufp);
 
-	if ((bp = compile_mode("*compile*", command, path)) == NULL)
+	if ((bp = compile_mode("*compile*", command)) == NULL)
 		return (FALSE);
 	if ((wp = popbuf(bp)) == NULL)
 		return (FALSE);
@@ -197,14 +172,6 @@
 	struct buffer	*bp;
 	struct mgwin	*wp;
 	int	 i, j;
-	char	 path[NFILEN];
-
-	/* get buffer cwd */
-	if (getbufcwd(path, sizeof(path)) == FALSE) {
-		ewprintf("Failed. "
-		    "Can't get working directory of current buffer.");
-		return (FALSE);
-	}
 
 	/* catch ([^\s(){}]+)[\s(){}]* */
 
@@ -241,7 +208,7 @@
 		return (FALSE);
 	(void)snprintf(command, sizeof(command), "gid %s", cprompt);
 
-	if ((bp = compile_mode("*gid*", command, path)) == NULL)
+	if ((bp = compile_mode("*gid*", command)) == NULL)
 		return (FALSE);
 	if ((wp = popbuf(bp)) == NULL)
 		return (FALSE);
@@ -251,7 +218,7 @@
 }
 
 struct buffer *
-compile_mode(const char *name, const char *command, const char *path)
+compile_mode(const char *name, const char *command)
 {
 	struct buffer	*bp;
 	FILE	*fpipe;
@@ -266,14 +233,16 @@
 	if (bclear(bp) != TRUE)
 		return (NULL);
 
-	addlinef(bp, "cd %s", path);
+	if (getbufcwd(bp->b_cwd, sizeof(bp->b_cwd)) != TRUE)
+		return (NULL);
+	addlinef(bp, "cd %s", bp->b_cwd);
 	addline(bp, command);
 	addline(bp, "");
 
 	if (getcwd(cwd, sizeof(cwd)) == NULL)
 		panic("Can't get current directory!");
-	if (chdir(path) == -1) {
-		ewprintf("Can't change dir to %s", path);
+	if (chdir(bp->b_cwd) == -1) {
+		ewprintf("Can't change dir to %s", bp->b_cwd);
 		return (NULL);
 	}
 	if ((fpipe = popen(command, "r")) == NULL) {
@@ -321,7 +290,7 @@
 	struct mgwin	*wp;
 	char	*fname, *line, *lp, *ln;
 	int	 lineno, len;
-	char	*adjf;
+	char	*adjf, path[NFILEN];
 	const char *errstr;
 	struct line	*last;
 
@@ -350,8 +319,15 @@
 	lineno = (int)strtonum(ln, INT_MIN, INT_MAX, &errstr);
 	if (errstr)
 		goto fail;
-
-	adjf = adjustname(fname);
+	
+	if (fname && fname[0] != '/') {
+		(void)strlcpy(path, curbp->b_cwd, sizeof(path));
+		if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
+			goto fail;
+		adjf = path;
+	} else {
+		adjf = adjustname(fname);
+	}
 	free(line);
 
 	if (adjf == NULL)
@@ -396,34 +372,4 @@
 	curwp->w_flag |= WFMOVE;
 
 	return (compile_goto_error(f, n));
-}
-
-/*
- * Return the working directory for the current buffer, terminated
- * with a '/'. First, try to extract it from the current buffer's
- * filename. If that fails, use global cwd.
- */
-static int
-getbufcwd(char *path, size_t plen)
-{
-	char *dname, cwd[NFILEN];
-	if (plen == 0)
-		goto error;
-
-	if (curbp->b_fname && curbp->b_fname[0] != '\0' &&
-	    (dname = dirname(curbp->b_fname)) != NULL) {
-		if (strlcpy(path, dname, plen) >= plen)
-			goto error;
-		if (strlcat(path, "/", plen) >= plen)
-			goto error;
-	} else {
-		if ((dname = getcwd(cwd, sizeof(cwd))) == NULL)
-			goto error;
-		if (strlcpy(path, dname, plen) >= plen)
-			goto error;
-	}
-	return (TRUE);
-error:
-	path = NULL;
-	return (FALSE);
 }