[note: I've modifed this diff from the first version with comments
from eric@ and Sunil Nimmagadda.] 

I find the backup files mg creates scattered around a pain but then
again I don't want to switch backups off since they can be useful.
Also, I don't feel the need to implement something in mg as fancy as
emacs's backup functionality ie. moving backup files, versioning,
deleting old backup versions etc.... 

With this diff I've only added the emacs functionality of moving the
backup files to a single directory instead of having them scattered
around everywhere. 

There are some drawbacks to having the backups in one directory of
course, only one backup version is maintained for files of the same
name but which originate in different directories (But that is
enough for me)

Since the functionality isn't trying to mimic emacs exactly, the
command name I've chosen isn't trying to reuse one of emacs'. 

backup-to-home-directory

This is open to suggestions of course.

The backup directory name ~/.mg.d stems from emacs's ~/.emacs.d.

Any comments?

-lum

Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.123
diff -u -p -r1.123 def.h
--- def.h       7 Jun 2012 15:15:04 -0000       1.123
+++ def.h       7 Jun 2012 17:38:26 -0000
@@ -446,6 +446,7 @@ struct list *make_file_list(char *);
 int             fisdir(const char *);
 int             fchecktime(struct buffer *);
 int             fupdstat(struct buffer *);
+int             backuptohomedir(int, int);
 
 /* kbd.c X */
 int             do_meta(int, int);
Index: fileio.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/fileio.c,v
retrieving revision 1.89
diff -u -p -r1.89 fileio.c
--- fileio.c    25 May 2012 04:56:58 -0000      1.89
+++ fileio.c    7 Jun 2012 17:38:26 -0000
@@ -22,6 +22,10 @@
 
 #include "kbd.h"
 
+static char *bkuplocation(const char *);
+
+static char *bkupdir;
+
 /*
  * Open a file for reading.
  */
@@ -189,6 +193,26 @@ ffgetline(FILE *ffp, char *buf, int nbuf
 }
 
 /*
+ * Location of backup file. This function creates the correct path.
+ */
+static char *
+bkuplocation(const char *fn)
+{
+       struct stat sb;
+       char *fname, *c;
+
+       if (bkupdir != NULL && (stat(bkupdir, &sb) == 0) &&
+           S_ISDIR(sb.st_mode)) {
+               c = strrchr(fn, '/');
+               if (asprintf(&fname, "%s%s", bkupdir, c) == -1)
+                       return (NULL);
+       } else if ((fname = strndup(fn, NFILEN)) == NULL)
+               return (NULL);
+
+       return (fname);
+}
+
+/*
  * Make a backup copy of "fname".  On Unix the backup has the same
  * name as the original file, with a "~" on the end; this seems to
  * be newest of the new-speak. The error handling is all in "file.c".
@@ -203,23 +227,27 @@ fbackupfile(const char *fn)
        int              from, to, serrno;
        ssize_t          nread;
        char             buf[BUFSIZ];
-       char            *nname, *tname;
+       char            *nname, *tname, *bkpth;
 
        if (stat(fn, &sb) == -1) {
                ewprintf("Can't stat %s : %s", fn, strerror(errno));
                return (FALSE);
        }
 
-       if (asprintf(&nname, "%s~", fn) == -1) {
+       if ((bkpth = bkuplocation(fn)) == NULL)
+               return (FALSE);
+
+       if (asprintf(&nname, "%s~", bkpth) == -1) {
                ewprintf("Can't allocate temp file name : %s", strerror(errno));
                return (ABORT);
        }
 
-       if (asprintf(&tname, "%s.XXXXXXXXXX", fn) == -1) {
+       if (asprintf(&tname, "%s.XXXXXXXXXX", bkpth) == -1) {
                ewprintf("Can't allocate temp file name : %s", strerror(errno));
                free(nname);
                return (ABORT);
        }
+       free(bkpth);
 
        if ((from = open(fn, O_RDONLY)) == -1) {
                free(nname);
@@ -610,4 +638,28 @@ fchecktime(struct buffer *bp)
 
        return (TRUE);
        
+}
+
+int
+backuptohomedir(int f, int n)
+{
+       const char      *c = "~/.mg.d";
+       char            *p;
+
+       if (bkupdir == NULL) {
+               p = adjustname(c, TRUE);
+               bkupdir = strndup(p, NFILEN);
+               if (bkupdir == NULL)
+                       return(FALSE);
+
+               if (mkdir(bkupdir, 0700) == -1 && errno != EEXIST) {
+                       free(bkupdir);
+                       bkupdir = NULL;
+               }
+       } else {
+               free(bkupdir);
+               bkupdir = NULL;
+       }
+
+       return (TRUE);
 }
Index: funmap.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/funmap.c,v
retrieving revision 1.39
diff -u -p -r1.39 funmap.c
--- funmap.c    7 Jun 2012 15:15:04 -0000       1.39
+++ funmap.c    7 Jun 2012 17:38:26 -0000
@@ -25,6 +25,7 @@ static struct funmap functnames[] = {
        {fillmode, "auto-fill-mode",},
        {indentmode, "auto-indent-mode",},
        {backtoindent, "back-to-indentation",},
+       {backuptohomedir, "backup-to-home-directory",},
        {backchar, "backward-char",},
        {delbword, "backward-kill-word",},
        {gotobop, "backward-paragraph",},
Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.61
diff -u -p -r1.61 mg.1
--- mg.1        7 Jun 2012 15:15:04 -0000       1.61
+++ mg.1        7 Jun 2012 17:38:26 -0000
@@ -350,6 +350,9 @@ to a new line.
 Toggle indent mode, where indentation is preserved after a newline.
 .It back-to-indentation
 Move the dot to the first non-whitespace character on the current line.
+.It backup-to-home-directory
+Save backup copies to a ~/.mg.d directory instead of working directory.
+Requires make-backup-files to be on.
 .It backward-char
 Move cursor backwards one character.
 .It backward-kill-word

Reply via email to