]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/desktop.el (desktop-auto-save-timeout): New option.
authorJuri Linkov <juri@jurta.org>
Sat, 27 Apr 2013 20:55:00 +0000 (23:55 +0300)
committerJuri Linkov <juri@jurta.org>
Sat, 27 Apr 2013 20:55:00 +0000 (23:55 +0300)
(desktop-file-checksum): New variable.
(desktop-save): Add optional arg `auto-save' and don't auto-save
if nothing changed.
(desktop-auto-save-timer): New variable.
(desktop-auto-save, desktop-auto-save-set-timer): New functions.
(after-init-hook): Call `desktop-auto-save-set-timer'.
Suggested by Reuben Thomas <rrt@sc3d.org> in
<http://lists.gnu.org/archive/html/emacs-devel/2013-04/msg00327.html>.

etc/NEWS
lisp/ChangeLog
lisp/desktop.el

index f6335d314eb0b0cd98ef1be346b400a5c3ebccd0..0a8cf2c032554b02d87862801b4236be40b4b3a1 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -169,6 +169,11 @@ on the given date.
 
 *** Support for ISO 8601 dates.
 
+** Desktop
+
+*** `desktop-auto-save-timeout' defines the number of seconds between
+auto-saves of the desktop.
+
 ** Dired
 
 *** New minor mode `dired-hide-details-mode' hides details.
index f1dade06c99f3d1469d0894fed916c61257c1d1f..8a6ea86983d2bb448e8d4cae41bb2ca29df0af8e 100644 (file)
@@ -1,3 +1,15 @@
+2013-04-27  Juri Linkov  <juri@jurta.org>
+
+       * desktop.el (desktop-auto-save-timeout): New option.
+       (desktop-file-checksum): New variable.
+       (desktop-save): Add optional arg `auto-save' and don't auto-save
+       if nothing changed.
+       (desktop-auto-save-timer): New variable.
+       (desktop-auto-save, desktop-auto-save-set-timer): New functions.
+       (after-init-hook): Call `desktop-auto-save-set-timer'.
+       Suggested by Reuben Thomas <rrt@sc3d.org> in
+       <http://lists.gnu.org/archive/html/emacs-devel/2013-04/msg00327.html>.
+
 2013-04-27  Leo Liu  <sdl.web@gmail.com>
 
        * progmodes/octave.el (octave-function-file-p)
        (opascal-parse-next-literal, opascal-debug-unparse-buffer):
        Adjust callers.
 
-2013-04-24  Reuben Thomas <rrt@sc3d.org>
+2013-04-24  Reuben Thomas  <rrt@sc3d.org>
 
        * textmodes/remember.el (remember-handler-functions): Add an
        option for a new handler `remember-store-in-files'.
index 9c95f597fff9bc0aa150489f4d9a9c27dbf911fc..e9a839c4cf7ca7ccb18f716b976713e11b6250bf 100644 (file)
@@ -189,6 +189,19 @@ determine where the desktop is saved."
   :group 'desktop
   :version "22.1")
 
+(defcustom desktop-auto-save-timeout nil
+  "Number of seconds between auto-saves of the desktop.
+Zero or nil means disable timer-based auto-saving."
+  :type '(choice (const :tag "Off" nil)
+                 (integer :tag "Seconds"))
+  :set (lambda (symbol value)
+         (set-default symbol value)
+         (condition-case nil
+            (desktop-auto-save-set-timer)
+          (error nil)))
+  :group 'desktop
+  :version "24.4")
+
 (defcustom desktop-load-locked-desktop 'ask
   "Specifies whether the desktop should be loaded if locked.
 Possible values are:
@@ -539,6 +552,10 @@ DIRNAME omitted or nil means use `desktop-dirname'."
 (defvar desktop-delay-hook nil
   "Hooks run after all buffers are loaded; intended for internal use.")
 
+(defvar desktop-file-checksum nil
+  "Checksum of the last auto-saved contents of the desktop file.
+Used to avoid writing contents unchanged between auto-saves.")
+
 ;; ----------------------------------------------------------------------------
 ;; Desktop file conflict detection
 (defvar desktop-file-modtime nil
@@ -842,11 +859,12 @@ DIRNAME must be the directory in which the desktop file will be saved."
 
 ;; ----------------------------------------------------------------------------
 ;;;###autoload
-(defun desktop-save (dirname &optional release)
+(defun desktop-save (dirname &optional release auto-save)
   "Save the desktop in a desktop file.
 Parameter DIRNAME specifies where to save the desktop file.
 Optional parameter RELEASE says whether we're done with this desktop.
-See also `desktop-base-file-name'."
+If AUTO-SAVE is non-nil, compare the saved contents to the one last saved,
+and don't save the buffer if they are the same."
   (interactive "DDirectory to save desktop file in: ")
   (setq desktop-dirname (file-name-as-directory (expand-file-name dirname)))
   (save-excursion
@@ -906,10 +924,17 @@ See also `desktop-base-file-name'."
                (insert ")\n\n"))))
 
          (setq default-directory desktop-dirname)
-         (let ((coding-system-for-write 'emacs-mule))
-           (write-region (point-min) (point-max) (desktop-full-file-name) nil 'nomessage))
-         ;; We remember when it was modified (which is presumably just now).
-         (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))))))))
+         ;; If auto-saving, avoid writing if nothing has changed since the last write.
+         ;; Don't check 300 characters of the header that contains the timestamp.
+         (let ((checksum (and auto-save (md5 (current-buffer)
+                                             (+ (point-min) 300) (point-max)
+                                             'emacs-mule))))
+           (unless (and auto-save (equal checksum desktop-file-checksum))
+             (let ((coding-system-for-write 'emacs-mule))
+               (write-region (point-min) (point-max) (desktop-full-file-name) nil 'nomessage))
+             (setq desktop-file-checksum checksum)
+             ;; We remember when it was modified (which is presumably just now).
+             (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))))))))))
 
 ;; ----------------------------------------------------------------------------
 ;;;###autoload
@@ -1062,6 +1087,37 @@ directory DIRNAME."
     (call-interactively 'desktop-save))
   (message "Desktop saved in %s" (abbreviate-file-name desktop-dirname)))
 
+;; ----------------------------------------------------------------------------
+;; Auto-Saving.
+(defvar desktop-auto-save-timer nil)
+
+(defun desktop-auto-save ()
+  "Save the desktop periodically.
+Called by the timer created in `desktop-auto-save-set-timer'."
+  (when (and desktop-save-mode
+            (integerp desktop-auto-save-timeout)
+            (> desktop-auto-save-timeout 0)
+            ;; Avoid desktop saving during lazy loading.
+            (not desktop-lazy-timer)
+            ;; Save only to own desktop file.
+            (eq (emacs-pid) (desktop-owner))
+            desktop-dirname)
+    (desktop-save desktop-dirname nil t))
+  (desktop-auto-save-set-timer))
+
+(defun desktop-auto-save-set-timer ()
+  "Reset the auto-save timer.
+Cancel any previous timer.  When `desktop-auto-save-timeout' is a positive
+integer, start a new timer to call `desktop-auto-save' in that many seconds."
+  (when desktop-auto-save-timer
+    (cancel-timer desktop-auto-save-timer)
+    (setq desktop-auto-save-timer nil))
+  (when (and (integerp desktop-auto-save-timeout)
+            (> desktop-auto-save-timeout 0))
+    (setq desktop-auto-save-timer
+         (run-with-timer desktop-auto-save-timeout nil
+                         'desktop-auto-save))))
+
 ;; ----------------------------------------------------------------------------
 ;;;###autoload
 (defun desktop-revert ()
@@ -1315,6 +1371,7 @@ If there are no buffers left to create, kill the timer."
         (setq desktop-save-mode nil)))
     (when desktop-save-mode
       (desktop-read)
+      (desktop-auto-save-set-timer)
       (setq inhibit-startup-screen t))))
 
 (provide 'desktop)