Auto backup hook

Discussion of Emacs Lisp
Post Reply
sollidsnake
Posts: 1
Joined: Sat Aug 10, 2013 9:52 pm

Auto backup hook

Post by sollidsnake » Sat Aug 10, 2013 10:11 pm

Hi all!
I'm a Vim user trying to migrate to Emacs. When using Vim I wrote a simple code (in vimscript) where it saves me a copy of my working file (with the file name plus date and time) everytime I open or save it.
I tried doing it with Emacs but ended up in a loophole. Here's what I wrote so far:

Code: Select all

(defvar autobk-default-dir "~/.emacsbk/")

(defun autobk-save ()
  "func description"
  (interactive)
  (defvar autobk-orignal-file-name buffer-file-name)
  (write-file (concat
	       autobk-default-dir
	       (buffer-name)
	       "_"
	       (shell-command-to-string "echo -n $(date +%Y-%m-%d)")
	       ".bak"))
  (write-file autobk-orignal-file-name)
  (message buffer-file-name))

(add-hook 'before-save-hook 'autobk-save)
The loophole happens because I add the function autobk-save to the before-save-hook and inside autobk-save I try to save the file, which calls the hook which calls the function again and again. So I think I need a way to tell the write-file function inside autobk-save to not use the hook, right? I tried sniffing around the file.el code but haven't found a clue the could help me. I know this is probably a bad code and maybe also a bad question, but I'm still a beginner with lisp and I'm open to any suggestions.

Thank you in advance :)

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: Auto backup hook

Post by nuntius » Tue Aug 13, 2013 6:03 pm

sollidsnake wrote: The loophole happens because I add the function autobk-save to the before-save-hook and inside autobk-save I try to save the file, which calls the hook which calls the function again and again. So I think I need a way to tell the write-file function inside autobk-save to not use the hook, right?)
Maybe you could use a dynamic variable to detect and break out of the recursion?

http://www.gnu.org/software/emacs/manua ... nding.html

edgar-rft
Posts: 226
Joined: Fri Aug 06, 2010 6:34 am
Location: Germany

Re: Auto backup hook

Post by edgar-rft » Thu Aug 15, 2013 8:36 am

If I use the internal C function `write-region' instead of `write-file' from "files.el", then the following code works with my Emacs23, because `write-region' doesn't call the Emacs file-hooks:

Code: Select all

(defvar autobk-default-dir (expand-file-name "~/.emacsbk/"))

(defun autobk-save ()
  "Write the entire buffer contents as text to a backup file."
  (interactive)
  (write-region nil nil (format "%s%s_%s.bak" autobk-default-dir (buffer-name)
                          (format-time-string "%Y-%m-%d" (current-time)))))
 
(add-hook 'before-save-hook 'autobk-save)
Note that in contrast to the `write-file' function, `write-region' is a plain and stupid "write buffer contents to destination" function that doesn't check if the "~/.emacsbk/" directory exists or is writable at all. But it writes an error message to the *Messages* buffer if something goes wrong. The first two nil arguments mean "write the entire buffer contents as text, don't care about anything else".

The `autobk-save' function could be improved by adding Elisp code to check if the directory exists and is writable, or automatically creates the directory if it doesn't exist. See the Elisp manual, chapter "Files" that also describes the functions for directories which on Unix and Linux are files as well.

Another alternative would be to use Elisp functions like `copy-file' for simple harddisk "copy and rename" operations *before* opening and *after* saving a file.

- edgar

Post Reply