From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Re: desktop.el: autosave? Date: Thu, 11 Apr 2013 11:29:08 +0300 Organization: JURTA Message-ID: <87k3o9v5bf.fsf@mail.jurta.org> References: <8763zjfe0v.fsf@jurta.org> <87mysridxt.fsf@jurta.org> <20071206153806.GA20731@www.trapp.net> <87d4tjbh0g.fsf@jurta.org> <87abon5q1f.fsf@jurta.org> <87lk835rb7.fsf@jurta.org> <87ejdu6rna.fsf@jurta.org> <87mysi3wx7.fsf@jurta.org> <87k3oaswbl.fsf@mail.jurta.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1365669080 9546 80.91.229.3 (11 Apr 2013 08:31:20 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 11 Apr 2013 08:31:20 +0000 (UTC) Cc: tomas@tuxteam.de, emacs-devel@gnu.org To: Reuben Thomas Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Apr 11 10:31:16 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UQCuY-0004Fq-C8 for ged-emacs-devel@m.gmane.org; Thu, 11 Apr 2013 10:31:14 +0200 Original-Received: from localhost ([::1]:40167 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQCuX-0006Ky-VJ for ged-emacs-devel@m.gmane.org; Thu, 11 Apr 2013 04:31:13 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:37344) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQCuS-0006KG-R3 for emacs-devel@gnu.org; Thu, 11 Apr 2013 04:31:11 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UQCuQ-0005hj-Qr for emacs-devel@gnu.org; Thu, 11 Apr 2013 04:31:08 -0400 Original-Received: from ps18281.dreamhost.com ([69.163.218.105]:43021 helo=ps18281.dreamhostps.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQCuQ-0005h3-Jf for emacs-devel@gnu.org; Thu, 11 Apr 2013 04:31:06 -0400 Original-Received: from localhost (ps18281.dreamhostps.com [69.163.218.105]) by ps18281.dreamhostps.com (Postfix) with ESMTP id 8E915258B92943; Thu, 11 Apr 2013 01:31:03 -0700 (PDT) In-Reply-To: (Reuben Thomas's message of "Wed, 10 Apr 2013 11:57:27 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (x86_64-pc-linux-gnu) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 69.163.218.105 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:158831 Archived-At: > I don't think anyone had a problem with run-with-timer (I just skimmed back > through the thread to check), so go ahead and change my patch to use it. In the patch below a new option is `desktop-auto-save-timeout' instead of `desktop-auto-save-interval' because it should be more like `auto-save-timeout' instead of `auto-save-interval'. `auto-save-timeout' is the number of seconds between auto-saves, but `auto-save-interval' is the number of characters typed between auto-saves. In terms of the desktop, an interval would rather mean a number of changes in the buffer list or something like that. I'm not sure whether this is useful, so the following patch implements only timer-based auto-saving: === modified file 'lisp/desktop.el' --- lisp/desktop.el 2013-01-02 16:13:04 +0000 +++ lisp/desktop.el 2013-04-11 08:28:14 +0000 @@ -189,6 +189,17 @@ (defcustom desktop-save 'ask-if-new :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) + (desktop-auto-save-update)) + :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 +550,10 @@ (defconst desktop-header (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 @@ -854,11 +869,12 @@ (defun desktop-file-name (filename dirna ;; ---------------------------------------------------------------------------- ;;;###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 @@ -918,10 +934,17 @@ (defun desktop-save (dirname &optional r (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) + (+ 300 (point-min)) (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 @@ -1075,6 +1098,37 @@ (defun desktop-save-in-desktop-dir () (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-update'." + (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-update)) + +(defun desktop-auto-save-update () + "Update the timer for next auto-saving. +Cancel the previous timer and run a new timer when the number +of seconds between auto-saves is a positive integer." + (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 () "Revert to the last loaded desktop." @@ -1327,6 +1381,7 @@ (add-hook 'after-init-hook (setq desktop-save-mode nil))) (when desktop-save-mode (desktop-read) + (desktop-auto-save-update) (setq inhibit-startup-screen t)))) (provide 'desktop)