2

New to Emacs and Lisp. I'm trying to replicate BBEdit's automatic backups, that is:

  • create a subfolder for each day (2022-11-02)
  • include the date and time in the backup's filename (2022-11-02 21-45-07-123)

Managed to create one backup file by changing this code:

(defun my-make-backup-file-name (FILE)
    (let ((dirname (concat "~/Documents/Emacs/Emacs Backups/" (format-time-string "%Y-%m-%d/"))))
        (if (not (file-exists-p dirname)) (make-directory dirname t))
        
        (setq filenameWithExtension (file-name-nondirectory FILE))
        (setq filenameWithoutExtension (file-name-sans-extension filenameWithExtension))
        (setq filenameExtension (file-name-extension filenameWithExtension))
        (concat dirname filenameWithoutExtension " (" (format-time-string "%Y-%m-%d %H-%M-%S-%3N") ")." filenameExtension)   
    )
)

(setq make-backup-file-name-function #'my-make-backup-file-name)

But I'd also like to create a backup on every save. This code does it:

(setq vc-make-backup-files t)

(setq version-control t 
    kept-new-versions 10 
    kept-old-versions 0 
    delete-old-versions t 
    backup-by-copying t) 

;; Default and per-save backups go here:
(setq backup-directory-alist '(("" . "~/.emacs.d/backup/per-save")))
(defun force-backup-of-buffer ()
;; Make a special "per session" backup at the first save of each
;; emacs session.
(when (not buffer-backed-up)
  ;; Override the default parameters for per-session backups.
  (let ((backup-directory-alist '(("" . "~/.emacs.d/backup/per-session")))
        (kept-new-versions 3))
    (backup-buffer)))
;; Make a "per save" backup on each save.  The first save results in
;; both a per-session and a per-save backup, to keep the numbering
;; of per-save backups consistent.
(let ((buffer-backed-up nil))
  (backup-buffer)))
(add-hook 'before-save-hook  'force-backup-of-buffer)

But how can I make both codes work together?

(I'm not interested in the split into two folders (in the code example ~/.emacs.d/backup/per-save and ~/.emacs.d/backup/per-session), just trying to get Emacs to make a backup on every save with a custom filename into ~/Documents/Emacs/Emacs Backups/[YYYY-MM-DD].)

cyberbisson
  • 887
  • 1
  • 6
  • 17
Pete
  • 31
  • 3

1 Answers1

1

Got it. This code creates a backup file on each save. File path example: ~/Documents/Emacs/Emacs Backups/2022-11-04/todo (2022-11-04 00-28-00-674).org.

;;;; Create versioned backup file on every save into date hierachy  

;;;; Create YYYY-MM-DD subfolder and backup filename    
;;;; Based on: https://emacs.stackexchange.com/questions/28124/change-naming-scheme-for-backup-files/28145#28145    
(defun my-make-backup-file-name (FILE)  
    (let ((dirname (concat "~/Documents/Emacs/Emacs Backups/" (format-time-string "%Y-%m-%d/"))))   
    (setq backup-directory-alist '(("" . dirname))) 

    (if (not (file-exists-p dirname)) (make-directory dirname t))   

    (setq filenameWithExtension (file-name-nondirectory FILE))  
    (setq filenameWithoutExtension (file-name-sans-extension filenameWithExtension))    
    (setq filenameExtension (file-name-extension filenameWithExtension))    
    (concat dirname filenameWithoutExtension " (" (format-time-string "%Y-%m-%d %H-%M-%S-%3N") ")." filenameExtension)      
))  

(setq make-backup-file-name-function #'my-make-backup-file-name)    

;;;; Create versioned backup file on every save 
;;;; Based on: https://www.emacswiki.org/emacs/ForceBackups 
(setq version-control 'never    
    vc-make-backup-files t  
    backup-by-copying t)    

(defun force-backup-of-buffer ()    
    (when (not buffer-backed-up)    
        (setq buffer-backed-up t))  
    (let ((buffer-backed-up nil))   
        (backup-buffer))    
)   

(add-hook 'before-save-hook  'force-backup-of-buffer)   
cyberbisson
  • 887
  • 1
  • 6
  • 17
Pete
  • 31
  • 3