* A few questions about desktop.el @ 2005-07-22 2:42 Juanma Barranquero 2005-07-22 10:53 ` Juanma Barranquero ` (4 more replies) 0 siblings, 5 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-22 2:42 UTC (permalink / raw) (These questions are mainly for Lars Hansen, who did most of the recent cleanup work on desktop.el) I'm having a few problems with highlight-changes-mode, which is a not-very-standard minor mode. I do (global-highlight-changes 'passive) on my .emacs, so most buffers have a local `highlight-changes-mode' variable with value 'passive. Logically, `highlight-changes-mode' goes to the minor-modes list in .emacs.desktop, and it gets restored by calling (highlight-changes-mode 1)... so highlight-changes-mode is active on all buffers after loading Emacs :) I can fix it with the attached patch. Is it reasonable to add to desktop.el code to deal with minor modes from the Emacs library, or should it be done in hilit-chg.el or the user's .emacs? The other question is: why does `desktop-save' save `nil' for active minor-modes which do appear in `desktop-minor-mode-table' as non-restorable? I mean, why (let ((special (assq minor-mode desktop-minor-mode-table))) (when (or special (functionp minor-mode)) (setq ret (cons (if special (cadr special) minor-mode) ret)))) instead of simply (let ((special (cadr (assq minor-mode desktop-minor-mode-table)))) (when (or special (functionp minor-mode)) (add-to-list 'ret (or special minor-mode)))) which wouldn't save nil values to the minor-mode list? -- /L/e/k/t/u Index: lisp/desktop.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/desktop.el,v retrieving revision 1.88 diff -u -2 -r1.88 desktop.el --- lisp/desktop.el 21 Jul 2005 11:49:32 -0000 1.88 +++ lisp/desktop.el 22 Jul 2005 02:27:41 -0000 @@ -229,5 +229,6 @@ change-log-default-name line-number-mode - buffer-file-coding-system) + buffer-file-coding-system + highlight-changes-mode) "List of local variables to save for each buffer. The variables are saved only when they really are local." @@ -346,5 +347,6 @@ (defcustom desktop-minor-mode-table '((auto-fill-function auto-fill-mode) - (vc-mode nil)) + (vc-mode nil) + (highlight-changes-mode nil)) "Table mapping minor mode variables to minor mode functions. Each entry has the form (NAME RESTORE-FUNCTION). ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 2:42 A few questions about desktop.el Juanma Barranquero @ 2005-07-22 10:53 ` Juanma Barranquero 2005-07-22 22:52 ` Richard M. Stallman 2005-08-08 15:02 ` Lars Hansen 2005-07-22 13:50 ` Juanma Barranquero ` (3 subsequent siblings) 4 siblings, 2 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-22 10:53 UTC (permalink / raw) In fact, I'm not sure what criterion is used to decide the default value of `desktop-locals-to-save'. I'd include (at least) - indent-tabs-mode - indicate-buffer-boundaries - indicate-empty-lines - show-trailing-whitespace - save-place and I'm not sure why does it include `line-number-mode'. Why not `column-number-mode' or `size-indication-mode'? -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 10:53 ` Juanma Barranquero @ 2005-07-22 22:52 ` Richard M. Stallman 2005-07-26 8:56 ` Juanma Barranquero 2005-08-08 15:02 ` Lars Hansen 1 sibling, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-22 22:52 UTC (permalink / raw) Cc: emacs-devel - indent-tabs-mode - indicate-buffer-boundaries - indicate-empty-lines - show-trailing-whitespace I guess those are all reasonable to include. How about this: save all minor modes, based on minor-mode-list. and I'm not sure why does it include `line-number-mode'. Why not `column-number-mode' or `size-indication-mode'? Those are newer and not used much, so most likely nobody thought to add them. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 22:52 ` Richard M. Stallman @ 2005-07-26 8:56 ` Juanma Barranquero 2005-07-27 14:03 ` Richard M. Stallman 0 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2005-07-26 8:56 UTC (permalink / raw) Cc: emacs-devel On 7/23/05, Richard M. Stallman <rms@gnu.org> wrote: > - indent-tabs-mode > - indicate-buffer-boundaries > - indicate-empty-lines > - show-trailing-whitespace > > I guess those are all reasonable to include. > > How about this: save all minor modes, based on minor-mode-list. AFAICS, `desktop-save' already saves all active minor-modes except those listed in `desktop-minor-mode-table', which get special processing. The ones listed above are ones that should need a special processing because they're not normal minor modes (there's no `indent-tabs-mode' function, for example). -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-26 8:56 ` Juanma Barranquero @ 2005-07-27 14:03 ` Richard M. Stallman 2005-07-27 14:28 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-27 14:03 UTC (permalink / raw) Cc: emacs-devel AFAICS, `desktop-save' already saves all active minor-modes except those listed in `desktop-minor-mode-table', which get special processing. The ones listed above are ones that should need a special processing because they're not normal minor modes (there's no `indent-tabs-mode' function, for example). As you can see, I don't know much about desktop.el--I don't use it. If you see that a certain mode needs special processing, please just implement that. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:03 ` Richard M. Stallman @ 2005-07-27 14:28 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman ` (3 more replies) 0 siblings, 4 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-27 14:28 UTC (permalink / raw) Cc: emacs-devel > As you can see, I don't know much about desktop.el--I don't use it. It's quite useful, and it'll be great the day we can make it save/restore window and frame configurations. But I don't think there's an easy way to turn a window configuration into elisp and back :( > If you see that a certain mode needs special processing, > please just implement that. I'll do. Not-totally-unrelated: running two or more Emacs instances that use the same desktop file is a classical race condition; the last one to exit overwrites the desktop file (quite funny when the desktop was very elaborate and the last instance to exit uses almost no buffers). It'd be very useful to try to detect it and at least stop the second instance from loading and using the desktop file if it's already in use. There's no way to do that from Emacs, is there? -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:28 ` Juanma Barranquero @ 2005-07-28 3:20 ` Richard M. Stallman 2005-07-28 7:34 ` David Kastrup 2005-07-28 3:20 ` Richard M. Stallman ` (2 subsequent siblings) 3 siblings, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-28 3:20 UTC (permalink / raw) Cc: emacs-devel It's quite useful, and it'll be great the day we can make it save/restore window and frame configurations. But I don't think there's an easy way to turn a window configuration into elisp and back It is straightforward to do walk-windows and record the size and contents of each leaf window. It's necessary in addition to record the structure. I think this can be deduced from that info as follows: Notice when consecutive windows (in the standard window ordering) have the same left and right edges, and when they have the same top and bottom edges. In those cases, you have vertical or horizontal siblings. So make a list of them and replace them with an item that corresponds to the combination of them. Do this over and over until you're left with one "window", and you've reconstructed the whole tree. We could add a primitive which constructs a window configuration from a list of window sizes and contents. If the above algorithm fails to reduce the specified data to a single window, it would signal an error. (We could conceive of making window configurations transparent data using this method. This would make save-window-configuration slower; would it be enough slowdown to cause a problem? Perhaps nowadays it would not be a problem.) ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-28 3:20 ` Richard M. Stallman @ 2005-07-28 7:34 ` David Kastrup 2005-07-28 12:51 ` Juanma Barranquero 2005-07-29 0:11 ` Richard M. Stallman 0 siblings, 2 replies; 72+ messages in thread From: David Kastrup @ 2005-07-28 7:34 UTC (permalink / raw) Cc: Juanma Barranquero, emacs-devel "Richard M. Stallman" <rms@gnu.org> writes: > It's quite useful, and it'll be great the day we can make it > save/restore window and frame configurations. But I don't think > there's an easy way to turn a window configuration into elisp and back > > It is straightforward to do walk-windows and record the size and > contents of each leaf window. It's necessary in addition to record > the structure. I think this can be deduced from that info as > follows: There is no guarantee that the stored desktop file will get used on the same display, not even with the same Emacs. And what if you do emacs -nw ? It sounds like something that has potential for problems, certainly enough to push it till after release. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-28 7:34 ` David Kastrup @ 2005-07-28 12:51 ` Juanma Barranquero 2005-07-29 0:11 ` Richard M. Stallman 1 sibling, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-28 12:51 UTC (permalink / raw) Cc: rms, emacs-devel On 7/28/05, David Kastrup <dak@gnu.org> wrote: > There is no guarantee that the stored desktop file will get used on > the same display, not even with the same Emacs. And what if you do > emacs -nw ? Even with -nw Emacs supports multiple frames and multiple windows. Moreover, at the very worst what can happen? Emacs not creating enough windows? > It sounds like something that has potential for problems, Sure. > certainly > enough to push it till after release. I agree, not because of the problems you see, but because it is a new feature (I wouldn't count adding this to desktop.el as a bug fix). I don't think we should be postponing features with "potential for problems"; we should be postponing *all* new features. IMO. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-28 7:34 ` David Kastrup 2005-07-28 12:51 ` Juanma Barranquero @ 2005-07-29 0:11 ` Richard M. Stallman 1 sibling, 0 replies; 72+ messages in thread From: Richard M. Stallman @ 2005-07-29 0:11 UTC (permalink / raw) Cc: lekktu, emacs-devel There is no guarantee that the stored desktop file will get used on the same display, not even with the same Emacs. And what if you do emacs -nw ? What's the problem? If it does not make sense to restore the window configuration, don't restore it. It sounds like something that has potential for problems, certainly enough to push it till after release. Yes, this is for after the release. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:28 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman @ 2005-07-28 3:20 ` Richard M. Stallman 2005-07-29 0:37 ` Juanma Barranquero 2005-07-28 4:24 ` Masatake YAMATO 2006-04-27 23:05 ` Stuart D. Herring 3 siblings, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-28 3:20 UTC (permalink / raw) Cc: emacs-devel It'd be very useful to try to detect it and at least stop the second instance from loading and using the desktop file if it's already in use. There's no way to do that from Emacs, is there? It needs to use file-locking together with testing of the file modtime. There are primitives to do this: lock-file and unlock-file, and file-attributes. So when you restore an old desktop, you record the modtime of the file. When you update the desktop file, you lock it, them see if its modtime is the same as it was when you restored the desktop. If not, you do whatever. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-28 3:20 ` Richard M. Stallman @ 2005-07-29 0:37 ` Juanma Barranquero 0 siblings, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-29 0:37 UTC (permalink / raw) Cc: emacs-devel On 7/28/05, Richard M. Stallman <rms@gnu.org> wrote: > It needs to use file-locking together with testing of the file modtime. > There are primitives to do this: lock-file and unlock-file, > and file-attributes. I don't see any `lock-file' and `unlock-file'. There are functions `lock-buffer', `unlock-buffer', and `file-locked-p'. Unfortunately, they do nothing on Windows. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:28 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman 2005-07-28 3:20 ` Richard M. Stallman @ 2005-07-28 4:24 ` Masatake YAMATO 2006-04-27 23:05 ` Stuart D. Herring 3 siblings, 0 replies; 72+ messages in thread From: Masatake YAMATO @ 2005-07-28 4:24 UTC (permalink / raw) Cc: rms, emacs-devel > > As you can see, I don't know much about desktop.el--I don't use it. > > It's quite useful, and it'll be great the day we can make it > save/restore window and frame configurations. But I don't think > there's an easy way to turn a window configuration into elisp and back > :( Look at HIROSE-san's hack. http://www.gentei.org/~yuuji/software/revive.el Masatake ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:28 ` Juanma Barranquero ` (2 preceding siblings ...) 2005-07-28 4:24 ` Masatake YAMATO @ 2006-04-27 23:05 ` Stuart D. Herring 2006-04-28 14:56 ` Juanma Barranquero 2006-04-28 15:44 ` Richard Stallman 3 siblings, 2 replies; 72+ messages in thread From: Stuart D. Herring @ 2006-04-27 23:05 UTC (permalink / raw) Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 2219 bytes --] Way back in July 2005, this was part of a discussion about improving desktop.el: > Not-totally-unrelated: running two or more Emacs instances that use > the same desktop file is a classical race condition; the last one to > exit overwrites the desktop file (quite funny when the desktop was > very elaborate and the last instance to exit uses almost no buffers). > > It'd be very useful to try to detect it and at least stop the second > instance from loading and using the desktop file if it's already in > use. There's no way to do that from Emacs, is there? Richard later suggested using the file-locking primitives along with file timestamps to implement this. Here's a stab at implementing the collision detection, but without file locking because I wasn't sure how to mix that with `load' competently. (I suspect this matters little since Emacs sessions are quite unlikely to be actually _accessing_ the desktop file at the same time.) Two things are done: first, a desktop file is modified when it is read (without incident) to include a "in use" tag; further Emacses will complain about this if they see it, and will leave the desktop file unloaded unless the user accepts the collision risk. Second, when a desktop file is read or written, its modification time (which is typically "now", since with this patch even loading the file modifies it) is remembered; if it's different when the desktop is to be saved, appropriate queries are posed. (In particular, if no desktop file is loaded, perhaps because the user decided not to re-load a file, any attempt to save the new desktop over an existing desktop file will be complained about.) I'm certainly not proposing this for installation right now; it needs lots more testing than I've given it (possibly by people who actually use desktop), and my papers-issues aren't yet resolved. But I encourage people (in particular Juanma, who raised the issue) to try it and let me know if it's any good; if the testing and the papers go okay, it'll just need a ChangeLog entry to be good. Enjoy, Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. [-- Attachment #2: desktop-conflict.patch --] [-- Type: application/octet-stream, Size: 14483 bytes --] Index: desktop.el =================================================================== RCS file: /sources/emacs/emacs/lisp/desktop.el,v retrieving revision 1.99 diff -c -r1.99 desktop.el *** desktop.el 10 Feb 2006 11:05:30 -0000 1.99 --- desktop.el 27 Apr 2006 23:00:03 -0000 *************** *** 475,480 **** --- 475,484 ---- (defvar desktop-dirname nil "The directory in which the desktop file should be saved.") + (defun desktop-full-file-name (&optional dirname) + "Return the full name of the current desktop file." + (expand-file-name desktop-base-file-name (or dirname desktop-dirname))) + (defconst desktop-header ";; -------------------------------------------------------------------------- ;; Desktop File for Emacs *************** *** 484,489 **** --- 488,503 ---- (defvar desktop-delay-hook nil "Hooks run after all buffers are loaded; intended for internal use.") + (defvar desktop-file-modtime nil + "When the desktop file was last modified to the knowledge of this Emacs. + Used to detect desktop file conflicts.") + + (defun desktop-conflict-text () + "Return a string for inclusion in the desktop file to detect conflicts. + The string contains a comment for humans and a `setq' for Emacs." + (format "\n;; This desktop file was in use as of %s\n(setq desktop-owner %s)\n" + (format-time-string "%x %X %Z") (emacs-pid))) + ;; ---------------------------------------------------------------------------- (defun desktop-truncate (list n) "Truncate LIST to at most N elements destructively." *************** *** 531,537 **** (when (and desktop-save-mode ! (let ((exists (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname)))) (or (eq desktop-save t) (and exists (memq desktop-save '(ask-if-new if-exists))) --- 545,551 ---- (when (and desktop-save-mode ! (let ((exists (file-exists-p (desktop-full-file-name)))) (or (eq desktop-save t) (and exists (memq desktop-save '(ask-if-new if-exists))) *************** *** 547,553 **** (call-interactively (lambda (dir) (interactive "DDirectory for desktop file: ") dir)))))) (condition-case err ! (desktop-save desktop-dirname) (file-error (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") (signal (car err) (cdr err))))))) --- 561,567 ---- (call-interactively (lambda (dir) (interactive "DDirectory for desktop file: ") dir)))))) (condition-case err ! (desktop-save desktop-dirname t) (file-error (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") (signal (car err) (cdr err))))))) *************** *** 715,730 **** (t (expand-file-name filename)))) ;; ---------------------------------------------------------------------------- ! (defun desktop-save (dirname) "Save the desktop in a desktop file. Parameter DIRNAME specifies where to save the desktop file. See also `desktop-base-file-name'." (interactive "DDirectory to save desktop file in: ") (run-hooks 'desktop-save-hook) ! (setq dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion ! (let ((filename (expand-file-name desktop-base-file-name dirname)) ! (info (mapcar #'(lambda (b) (set-buffer b) --- 729,744 ---- (t (expand-file-name filename)))) ;; ---------------------------------------------------------------------------- ! (defun desktop-save (dirname &optional release) "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'." (interactive "DDirectory to save desktop file in: ") (run-hooks 'desktop-save-hook) ! (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion ! (let ((info (mapcar #'(lambda (b) (set-buffer b) *************** *** 765,808 **** (buffer-list))) (eager desktop-restore-eager) (buf (get-buffer-create "*desktop*"))) ! (set-buffer buf) ! (erase-buffer) ! ! (insert ! ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" ! desktop-header ! ";; Created " (current-time-string) "\n" ! ";; Desktop file format version " desktop-file-version "\n" ! ";; Emacs version " emacs-version "\n\n" ! ";; Global section:\n") ! (mapc (function desktop-outvar) desktop-globals-to-save) ! (if (memq 'kill-ring desktop-globals-to-save) ! (insert ! "(setq kill-ring-yank-pointer (nthcdr " ! (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer))) ! " kill-ring))\n")) ! ! (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n") ! (mapc #'(lambda (l) ! (when (apply 'desktop-save-buffer-p l) ! (insert "(" ! (if (or (not (integerp eager)) ! (unless (zerop eager) ! (setq eager (1- eager)) ! t)) ! "desktop-create-buffer" ! "desktop-append-buffer-args") ! " " ! desktop-file-version) ! (mapc #'(lambda (e) ! (insert "\n " (desktop-value-to-string e))) ! l) ! (insert ")\n\n"))) ! info) ! (setq default-directory dirname) ! (let ((coding-system-for-write 'emacs-mule)) ! (write-region (point-min) (point-max) filename nil 'nomessage)))) ! (setq desktop-dirname dirname)) ;; ---------------------------------------------------------------------------- (defun desktop-remove () --- 779,836 ---- (buffer-list))) (eager desktop-restore-eager) (buf (get-buffer-create "*desktop*"))) ! (let ((new-modtime (nth 5 (file-attributes (desktop-full-file-name))))) ! (when ! (or (not new-modtime) ; nothing to overwrite ! (equal desktop-file-modtime new-modtime) ! (yes-or-no-p (if desktop-file-modtime ! (if (> (float-time new-modtime) (float-time desktop-file-modtime)) ! "Desktop file is more recent than the one loaded. Save anyway? " ! "Desktop file isn't the one loaded. Overwrite it? ") ! "Current desktop was not loaded from a file. Overwrite this desktop file? ")) ! (unless release (error "Desktop file conflict"))) ! ! (set-buffer buf) ! (erase-buffer) ! ! (insert ! ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" ! desktop-header ! ";; Created " (current-time-string) "\n" ! ";; Desktop file format version " desktop-file-version "\n" ! ";; Emacs version " emacs-version "\n" ! (if release "" (desktop-conflict-text)) ! "\n;; Global section:\n") ! (mapc (function desktop-outvar) desktop-globals-to-save) ! (if (memq 'kill-ring desktop-globals-to-save) ! (insert ! "(setq kill-ring-yank-pointer (nthcdr " ! (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer))) ! " kill-ring))\n")) ! ! (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n") ! (mapc #'(lambda (l) ! (when (apply 'desktop-save-buffer-p l) ! (insert "(" ! (if (or (not (integerp eager)) ! (unless (zerop eager) ! (setq eager (1- eager)) ! t)) ! "desktop-create-buffer" ! "desktop-append-buffer-args") ! " " ! desktop-file-version) ! (mapc #'(lambda (e) ! (insert "\n " (desktop-value-to-string e))) ! l) ! (insert ")\n\n"))) ! info) ! ! (setq default-directory 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))))))))) ;; ---------------------------------------------------------------------------- (defun desktop-remove () *************** *** 810,816 **** This function also sets `desktop-dirname' to nil." (interactive) (when desktop-dirname ! (let ((filename (expand-file-name desktop-base-file-name desktop-dirname))) (setq desktop-dirname nil) (when (file-exists-p filename) (delete-file filename))))) --- 838,844 ---- This function also sets `desktop-dirname' to nil." (interactive) (when desktop-dirname ! (let ((filename (desktop-full-file-name))) (setq desktop-dirname nil) (when (file-exists-p filename) (delete-file filename))))) *************** *** 833,884 **** (interactive) (unless noninteractive (setq desktop-dirname ! (file-name-as-directory ! (expand-file-name ! (or ! ;; If DIRNAME is specified, use it. ! (and (< 0 (length dirname)) dirname) ! ;; Otherwise search desktop file in desktop-path. ! (let ((dirs desktop-path)) ! (while ! (and ! dirs ! (not ! (file-exists-p (expand-file-name desktop-base-file-name (car dirs))))) ! (setq dirs (cdr dirs))) ! (and dirs (car dirs))) ! ;; If not found and `desktop-path' is non-nil, use its first element. ! (and desktop-path (car desktop-path)) ! ;; Default: Home directory. ! "~")))) ! (if (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname)) ! ;; Desktop file found, process it. ! (let ((desktop-first-buffer nil) ! (desktop-buffer-ok-count 0) ! (desktop-buffer-fail-count 0)) ! (setq desktop-lazy-timer nil) ! ;; Evaluate desktop buffer. ! (load (expand-file-name desktop-base-file-name desktop-dirname) t t t) ! ;; `desktop-create-buffer' puts buffers at end of the buffer list. ! ;; We want buffers existing prior to evaluating the desktop (and not reused) ! ;; to be placed at the end of the buffer list, so we move them here. ! (mapc 'bury-buffer ! (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) ! (switch-to-buffer (car (buffer-list))) ! (run-hooks 'desktop-delay-hook) ! (setq desktop-delay-hook nil) ! (run-hooks 'desktop-after-read-hook) ! (message "Desktop: %d buffer%s restored%s%s." ! desktop-buffer-ok-count ! (if (= 1 desktop-buffer-ok-count) "" "s") ! (if (< 0 desktop-buffer-fail-count) ! (format ", %d failed to restore" desktop-buffer-fail-count) ! "") ! (if desktop-buffer-args-list ! (format ", %d to restore lazily" ! (length desktop-buffer-args-list)) ! "")) ! t) ;; No desktop file found. (desktop-clear) (let ((default-directory desktop-dirname)) --- 861,930 ---- (interactive) (unless noninteractive (setq desktop-dirname ! (file-name-as-directory ! (expand-file-name ! (or ! ;; If DIRNAME is specified, use it. ! (and (< 0 (length dirname)) dirname) ! ;; Otherwise search desktop file in desktop-path. ! (let ((dirs desktop-path)) ! (while ! (and ! dirs ! (not ! (file-exists-p (desktop-full-file-name (car dirs))))) ! (setq dirs (cdr dirs))) ! (and dirs (car dirs))) ! ;; If not found and `desktop-path' is non-nil, use its first element. ! (and desktop-path (car desktop-path)) ! ;; Default: Home directory. ! "~")))) ! (if (file-exists-p (desktop-full-file-name)) ! ;; Desktop file found, process it. ! (let ((desktop-first-buffer nil) ! (desktop-buffer-ok-count 0) ! (desktop-buffer-fail-count 0) ! desktop-owner) ! (setq desktop-lazy-timer nil) ! ;; Evaluate desktop buffer. ! (load (desktop-full-file-name) t t t) ! (if (and desktop-owner ! (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\nUsing it may cause conflicts. Use it anyway? " desktop-owner)))) ! (progn (desktop-clear) ! (setq desktop-dirname nil) ! (message "Desktop file in use; not loaded.") ! nil) ! ;; If it wasn't already, mark it as in-use, to bother other ! ;; desktop instances. ! (unless desktop-owner ! (condition-case nil ! (write-region (desktop-conflict-text) nil ! (desktop-full-file-name) t 'nomessage) ! (file-error (message "Couldn't mark desktop file as active") ! (sit-for 1)))) ! ;; We remember when it was modified (which is presumably just now). ! (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))) ! ;; `desktop-create-buffer' puts buffers at end of the buffer list. ! ;; We want buffers existing prior to evaluating the desktop (and ! ;; not reused) to be placed at the end of the buffer list, so we ! ;; move them here. ! (mapc 'bury-buffer ! (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) ! (switch-to-buffer (car (buffer-list))) ! (run-hooks 'desktop-delay-hook) ! (setq desktop-delay-hook nil) ! (run-hooks 'desktop-after-read-hook) ! (message "Desktop: %d buffer%s restored%s%s." ! desktop-buffer-ok-count ! (if (= 1 desktop-buffer-ok-count) "" "s") ! (if (< 0 desktop-buffer-fail-count) ! (format ", %d failed to restore" desktop-buffer-fail-count) ! "") ! (if desktop-buffer-args-list ! (format ", %d to restore lazily" ! (length desktop-buffer-args-list)) ! "")) ! t)) ;; No desktop file found. (desktop-clear) (let ((default-directory desktop-dirname)) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-27 23:05 ` Stuart D. Herring @ 2006-04-28 14:56 ` Juanma Barranquero 2006-04-29 4:57 ` Stuart D. Herring 2006-04-28 15:44 ` Richard Stallman 1 sibling, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2006-04-28 14:56 UTC (permalink / raw) Cc: emacs-devel On 4/28/06, Stuart D. Herring <herring@lanl.gov> wrote: > without file locking because I wasn't sure how to mix that > with `load' competently. (I suspect this matters little since Emacs > sessions are quite unlikely to be actually _accessing_ the desktop file at > the same time.) I agree. The probability of two or more Emacs sessions starting or non-catastrophically ending at the very same moment seems remote. > But I encourage > people (in particular Juanma, who raised the issue) to try it and let me > know if it's any good; if the testing and the papers go okay, it'll just > need a ChangeLog entry to be good. Thanks a lot. I like the functionality, but it still has some rough spots, at least for daily use. - Emacs process the desktop file, loading buffers and all, and only then asks about it being in use. Can this be changed so the question is asked at the beginning? (I imagine this could be difficult because of the way the desktop file is loaded.) - If you decide *not* to load the desktop file in use, on exit you're still asked about saving a new desktop file; at least, for certain values of `desktop-save'. My main use case is that I'm starting a fresh Emacs by accident (I have Emacs on another virtual desktop, or just too many open apps), and I'm going to do C-x C-c immediately, so it's a bit cumbersome to "M-x set-variable desktop-save nil RET". Perhaps a desktop-not-loaded-hook could be useful there. - Not a problem with your implementation, but on Windows, using gnuserv/gnuclient, the second Emacs instance shows a message "Server subprocess exited" (because it wasn't able to run gnuserv a second time) which hides the desktop question... -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-28 14:56 ` Juanma Barranquero @ 2006-04-29 4:57 ` Stuart D. Herring 2006-04-30 1:16 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: Stuart D. Herring @ 2006-04-29 4:57 UTC (permalink / raw) Cc: emacs-devel > - Emacs process the desktop file, loading buffers and all, and only > then asks about it being in use. Can this be changed so the question > is asked at the beginning? (I imagine this could be difficult because > of the way the desktop file is loaded.) Well, the reason for it is really quite simple in my implementation -- the use tag is added at the end of the file! The other code has already run. Doing it this way let me do the file update with a single `write-region' append call. But (see other email) Richard wants that done in a separate file, and I don't blame him. So I'll move the check before the desktop file is ever opened when I do that (Monday or so). > - If you decide *not* to load the desktop file in use, on exit > you're still asked about saving a new desktop file; at least, for > certain values of `desktop-save'. My main use case is that I'm > starting a fresh Emacs by accident (I have Emacs on another virtual > desktop, or just too many open apps), and I'm going to do C-x C-c > immediately, so it's a bit cumbersome to "M-x set-variable > desktop-save nil RET". Perhaps a desktop-not-loaded-hook could be > useful there. I thought this was buggy when I first saw it too. But I realized that there's no assumption made by desktop.el that you have only one file; just because this Emacs session isn't associated with the desktop file you originally tried to load doesn't mean it shouldn't be associated with another. But since it doesn't know which other one, it asks! It's really a feature... sorta. I realize that for the common "oh wait, already have Emacs" case, it's annoying; there could be a customization option to disable Desktop if you refuse to re-load the file. I might point out, though, that I've carefully written it so that if you attempt to overwrite the file that you chose not to load (typically just pressing Enter when it offers "~/" as the save location) it'll note that you're overwriting a file that you didn't load, and if you decline to overwrite it, Emacs will still exit. Admittedly, this is still annoying, but pressing C-x C-c RET n o RET is a lot faster than doing `set-variable'. > - Not a problem with your implementation, but on Windows, using > gnuserv/gnuclient, the second Emacs instance shows a message "Server > subprocess exited" (because it wasn't able to run gnuserv a second > time) which hides the desktop question... Pressing C-l will clear this up, so long as you realize that you're in the minibuffer and need it redrawn. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-29 4:57 ` Stuart D. Herring @ 2006-04-30 1:16 ` Juanma Barranquero 2006-05-02 15:06 ` Stuart D. Herring 0 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2006-04-30 1:16 UTC (permalink / raw) Cc: emacs-devel On 4/29/06, Stuart D. Herring <herring@lanl.gov> wrote: > So I'll move the check before the desktop > file is ever opened when I do that (Monday or so). Cool. > But I realized that > there's no assumption made by desktop.el that you have only one file; just > because this Emacs session isn't associated with the desktop file you > originally tried to load doesn't mean it shouldn't be associated with > another. But since it doesn't know which other one, it asks! It's really > a feature... sorta. Yes, I undestand that. That's why I said "for certain values of desktop-save". I should've added "and for certain uses of desktop". For example, when you're mainly using a single desktop file in your $HOME (as I do) instead of per-directory desktop files (which are *very* rare in my setup). In that case, if-exists or ask-if-exists are two useful desktop-save values, and being asked about saving a new one is inconvenient. > there could be a customization option to > disable Desktop if you refuse to re-load the file. A not-loaded hook, as I proposed, would serve the same function and be a bit more general, I think. > Pressing C-l will clear this up, so long as you realize that you're in the > minibuffer and need it redrawn. Yes, realizing that is the problem. But, as I said, is not a problem with your implementation. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-30 1:16 ` Juanma Barranquero @ 2006-05-02 15:06 ` Stuart D. Herring 2006-05-02 15:14 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: Stuart D. Herring @ 2006-05-02 15:06 UTC (permalink / raw) Cc: emacs-devel >> there could be a customization option to >> disable Desktop if you refuse to re-load the file. > > A not-loaded hook, as I proposed, would serve the same function and be > a bit more general, I think. It seems to me that (add-hook 'desktop-not-loaded-hook (lambda () (setq desktop-save nil))) ...would be cumbersome (especially for non-Lispy users). Is there any other use for such a hook (maybe `kill-emacs'? ;), or would it be just as good to have the customization option I suggested? Or instead to ask, when the user chooses to honor a lock, whether to then disable Desktop? Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-02 15:06 ` Stuart D. Herring @ 2006-05-02 15:14 ` Juanma Barranquero 2006-05-02 15:42 ` Stuart D. Herring 0 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2006-05-02 15:14 UTC (permalink / raw) Cc: emacs-devel On 5/2/06, Stuart D. Herring <herring@lanl.gov> wrote: > It seems to me that > (add-hook 'desktop-not-loaded-hook (lambda () (setq desktop-save nil))) > ...would be cumbersome (especially for non-Lispy users). You could always do M-x customize-variable desktop-not-loaded-hook, couldn't you? > Is there any > other use for such a hook (maybe `kill-emacs'? ;) Certainly, running an external app (likely gnuclient) to bring the other Emacs instance to focus and then killing the current one would be my first use, yes. > Or instead to ask, > when the user chooses to honor a lock, whether to then disable Desktop? I hate being asked (by a program :-) about things that could be automated. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-02 15:14 ` Juanma Barranquero @ 2006-05-02 15:42 ` Stuart D. Herring 2006-05-02 17:57 ` Stuart D. Herring 0 siblings, 1 reply; 72+ messages in thread From: Stuart D. Herring @ 2006-05-02 15:42 UTC (permalink / raw) Cc: emacs-devel >> It seems to me that >> (add-hook 'desktop-not-loaded-hook (lambda () (setq desktop-save nil))) >> ...would be cumbersome (especially for non-Lispy users). > > You could always do M-x customize-variable desktop-not-loaded-hook, > couldn't you? Hey, you're right -- the answer is to give (the new, trivial function) `disable-desktop-save-mode' as an :option in the defcustom for `desktop-not-loaded-hook'. >> Is there any >> other use for such a hook (maybe `kill-emacs'? ;) > > Certainly, running an external app (likely gnuclient) to bring the > other Emacs instance to focus and then killing the current one would > be my first use, yes. I'll also put `save-buffers-kill-emacs' in the :options. >> Or instead to ask, >> when the user chooses to honor a lock, whether to then disable Desktop? > > I hate being asked (by a program :-) about things that could be automated. The only problem I see is how to inform the user (aside from etc/NEWS) that the hook exists, since the behavior with it uncustomized can be annoying but it's not an obvious customization locus. Certainly it could be given an obnoxious default value like '(announce-the-presence-of-this-hook), but that's silly. Any ideas? Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-02 15:42 ` Stuart D. Herring @ 2006-05-02 17:57 ` Stuart D. Herring 0 siblings, 0 replies; 72+ messages in thread From: Stuart D. Herring @ 2006-05-02 17:57 UTC (permalink / raw) Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1103 bytes --] >From my previous message: > The only problem I see is how to inform the user (aside from etc/NEWS) > that the hook exists, since the behavior with it uncustomized can be > annoying but it's not an obvious customization locus. Certainly it could > be given an obnoxious default value like > '(announce-the-presence-of-this-hook), but that's silly. Any ideas? I haven't addressed this bit, but the attached patch (superceding the previous one, not combined with it) redoes the locking with a separate file and adds hook support for the not-loaded case, with useful options provided via customize. It also properly disposes of the temporary *desktop* buffer and, as a new feature, runs the desktop-save-hooks with the *desktop* buffer current (but still before any inspection of Emacs state is done) so they can be used to add custom Lisp to the file as well as adjust Emacs state for the write. Let me know if it's less rough-cut now. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. [-- Attachment #2: desktop-conflict-2.patch --] [-- Type: application/octet-stream, Size: 24213 bytes --] Index: desktop.el =================================================================== RCS file: /sources/emacs/emacs/lisp/desktop.el,v retrieving revision 1.99 diff -c -r1.99 desktop.el *** desktop.el 10 Feb 2006 11:05:30 -0000 1.99 --- desktop.el 2 May 2006 17:56:29 -0000 *************** *** 162,167 **** --- 162,171 ---- (define-obsolete-variable-alias 'desktop-enable 'desktop-save-mode "22.1") + (defun desktop-save-mode-off () + "Disable `desktop-save-mode'. Provided for use in hooks." + (desktop-save-mode 0)) + (defcustom desktop-save 'ask-if-new "*Specifies whether the desktop should be saved when it is killed. A desktop is killed when the user changes desktop or quits Emacs. *************** *** 176,187 **** The variables `desktop-dirname' and `desktop-base-file-name' determine where the desktop is saved." :type '(choice ! (const :tag "Always save" t) ! (const :tag "Always ask" ask) ! (const :tag "Ask if desktop file is new, else do save" ask-if-new) ! (const :tag "Ask if desktop file exists, else don't save" ask-if-exists) ! (const :tag "Save if desktop file exists, else don't" if-exists) ! (const :tag "Never save" nil)) :group 'desktop :version "22.1") --- 180,191 ---- The variables `desktop-dirname' and `desktop-base-file-name' determine where the desktop is saved." :type '(choice ! (const :tag "Always save" t) ! (const :tag "Always ask" ask) ! (const :tag "Ask if desktop file is new, else do save" ask-if-new) ! (const :tag "Ask if desktop file exists, else don't save" ask-if-exists) ! (const :tag "Save if desktop file exists, else don't" if-exists) ! (const :tag "Never save" nil)) :group 'desktop :version "22.1") *************** *** 193,198 **** --- 197,209 ---- (define-obsolete-variable-alias 'desktop-basefilename 'desktop-base-file-name "22.1") + (defcustom desktop-base-lock-name + (convert-standard-filename ".emacs.desktop.lock") + "Name of lock file for Emacs desktop, excluding the directory part." + :type 'file + :group 'desktop + :version "22.1") + (defcustom desktop-path '("." "~") "List of directories to search for the desktop file. The base name of the file is specified in `desktop-base-file-name'." *************** *** 212,232 **** (defcustom desktop-no-desktop-file-hook nil "Normal hook run when `desktop-read' can't find a desktop file. May be used to show a dired buffer." :type 'hook :group 'desktop :version "22.1") (defcustom desktop-after-read-hook nil "Normal hook run after a successful `desktop-read'. May be used to show a buffer list." :type 'hook :group 'desktop :version "22.1") (defcustom desktop-save-hook nil "Normal hook run before the desktop is saved in a desktop file. ! This is useful for truncating history lists, for example." :type 'hook :group 'desktop) --- 223,256 ---- (defcustom desktop-no-desktop-file-hook nil "Normal hook run when `desktop-read' can't find a desktop file. + Run in the directory in which the desktop file was sought. May be used to show a dired buffer." :type 'hook :group 'desktop :version "22.1") + (defcustom desktop-not-loaded-hook nil + "Normal hook run when the user declines to re-use a desktop file. + Run in the directory in which the desktop file was found. + May be used to deal with accidental multiple Emacs jobs." + :type 'hook + :group 'desktop + :options '(desktop-save-mode-off save-buffers-kill-emacs) + :version "22.1") + (defcustom desktop-after-read-hook nil "Normal hook run after a successful `desktop-read'. May be used to show a buffer list." :type 'hook :group 'desktop + :options '(list-buffers) :version "22.1") (defcustom desktop-save-hook nil "Normal hook run before the desktop is saved in a desktop file. ! Run with the desktop buffer current with only the header present. ! May be used to add to the desktop code or to truncate history lists, ! for example." :type 'hook :group 'desktop) *************** *** 282,287 **** --- 306,312 ---- size-indication-mode buffer-file-coding-system indent-tabs-mode + tab-width indicate-buffer-boundaries indicate-empty-lines show-trailing-whitespace) *************** *** 475,480 **** --- 500,515 ---- (defvar desktop-dirname nil "The directory in which the desktop file should be saved.") + (defun desktop-full-file-name (&optional dirname) + "Return the full name of the desktop file in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (expand-file-name desktop-base-file-name (or dirname desktop-dirname))) + + (defun desktop-full-lock-name (&optional dirname) + "Return the full name of the desktop lock file in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (expand-file-name desktop-base-lock-name (or dirname desktop-dirname))) + (defconst desktop-header ";; -------------------------------------------------------------------------- ;; Desktop File for Emacs *************** *** 485,490 **** --- 520,558 ---- "Hooks run after all buffers are loaded; intended for internal use.") ;; ---------------------------------------------------------------------------- + ;; Desktop file conflict detection + (defvar desktop-file-modtime nil + "When the desktop file was last modified to the knowledge of this Emacs. + Used to detect desktop file conflicts.") + + (defun desktop-owner (&optional dirname) + "Return the PID of the Emacs process that owns the desktop file in DIRNAME. + Return nil if no desktop file found or no Emacs process is using it. + DIRNAME omitted or nil means use `desktop-dirname'." + (let (owner) + (and (file-exists-p (desktop-full-lock-name dirname)) + (condition-case nil + (with-temp-buffer (insert-file-contents-literally + (desktop-full-lock-name dirname)) + (goto-char (point-min)) + (setq owner (read (current-buffer))) + (integerp owner)) + (error nil)) + owner))) + + (defun desktop-claim-lock (&optional dirname) + "Record this Emacs process as the owner of the desktop file in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (write-region (number-to-string (emacs-pid)) nil + (desktop-full-lock-name dirname))) + + (defun desktop-release-lock (&optional dirname) + "Remove the lock file for the desktop in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (let ((file (desktop-full-lock-name dirname))) + (when (file-exists-p file) (delete-file file)))) + + ;; ---------------------------------------------------------------------------- (defun desktop-truncate (list n) "Truncate LIST to at most N elements destructively." (let ((here (nthcdr (1- n) list))) *************** *** 529,556 **** If the desktop should be saved and `desktop-dirname' is nil, ask the user where to save the desktop." (when ! (and ! desktop-save-mode ! (let ((exists (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname)))) ! (or ! (eq desktop-save t) ! (and exists (memq desktop-save '(ask-if-new if-exists))) ! (and ! (or ! (memq desktop-save '(ask ask-if-new)) ! (and exists (eq desktop-save 'ask-if-exists))) ! (y-or-n-p "Save desktop? "))))) (unless desktop-dirname (setq desktop-dirname ! (file-name-as-directory ! (expand-file-name ! (call-interactively ! (lambda (dir) (interactive "DDirectory for desktop file: ") dir)))))) (condition-case err ! (desktop-save desktop-dirname) (file-error ! (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") ! (signal (car err) (cdr err))))))) ;; ---------------------------------------------------------------------------- (defun desktop-list* (&rest args) --- 597,626 ---- If the desktop should be saved and `desktop-dirname' is nil, ask the user where to save the desktop." (when ! (and ! desktop-save-mode ! (let ((exists (file-exists-p (desktop-full-file-name)))) ! (or ! (eq desktop-save t) ! (and exists (memq desktop-save '(ask-if-new if-exists))) ! (and ! (or ! (memq desktop-save '(ask ask-if-new)) ! (and exists (eq desktop-save 'ask-if-exists))) ! (y-or-n-p "Save desktop? "))))) (unless desktop-dirname (setq desktop-dirname ! (file-name-as-directory ! (expand-file-name ! (call-interactively ! (lambda (dir) (interactive "DDirectory for desktop file: ") dir)))))) (condition-case err ! (desktop-save desktop-dirname t) (file-error ! (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") ! (signal (car err) (cdr err)))))) ! ;; If we own it, we don't anymore. ! (if (eq (emacs-pid) (desktop-owner)) (desktop-release-lock))) ;; ---------------------------------------------------------------------------- (defun desktop-list* (&rest args) *************** *** 565,570 **** --- 635,676 ---- value))) ;; ---------------------------------------------------------------------------- + (defun desktop-buffer-info (buffer) + (set-buffer buffer) + (list + ;; basic information + (desktop-file-name (buffer-file-name) dirname) (buffer-name) major-mode + ;; minor modes + (let (ret) + (mapc + #'(lambda (minor-mode) + (and + (boundp minor-mode) + (symbol-value minor-mode) + (let* ((special (assq minor-mode desktop-minor-mode-table)) + (value (cond (special (cadr special)) + ((functionp minor-mode) minor-mode)))) + (when value (add-to-list 'ret value))))) + (mapcar #'car minor-mode-alist)) + ret) + ;; point and mark, and read-only status + (point) (list (mark t) mark-active) buffer-read-only + ;; auxiliary information + (when (functionp desktop-save-buffer) + (funcall desktop-save-buffer dirname)) + ;; local variables + (let ((locals desktop-locals-to-save) + (loclist (buffer-local-variables)) + (ll)) + (while locals + (let ((here (assq (car locals) loclist))) + (if here (setq ll (cons here ll)) + (when (member (car locals) loclist) + (setq ll (cons (car locals) ll))))) + (setq locals (cdr locals))) + ll))) + + ;; ---------------------------------------------------------------------------- (defun desktop-internal-v2s (value) "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE. TXT is a string that when read and evaluated yields value. *************** *** 715,808 **** (t (expand-file-name filename)))) ;; ---------------------------------------------------------------------------- ! (defun desktop-save (dirname) "Save the desktop in a desktop file. Parameter DIRNAME specifies where to save the desktop file. See also `desktop-base-file-name'." (interactive "DDirectory to save desktop file in: ") ! (run-hooks 'desktop-save-hook) ! (setq dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion ! (let ((filename (expand-file-name desktop-base-file-name dirname)) ! (info ! (mapcar ! #'(lambda (b) ! (set-buffer b) ! (list ! (desktop-file-name (buffer-file-name) dirname) ! (buffer-name) ! major-mode ! ;; minor modes ! (let (ret) ! (mapc ! #'(lambda (minor-mode) ! (and ! (boundp minor-mode) ! (symbol-value minor-mode) ! (let* ((special (assq minor-mode desktop-minor-mode-table)) ! (value (cond (special (cadr special)) ! ((functionp minor-mode) minor-mode)))) ! (when value (add-to-list 'ret value))))) ! (mapcar #'car minor-mode-alist)) ! ret) ! (point) ! (list (mark t) mark-active) ! buffer-read-only ! ;; Auxiliary information ! (when (functionp desktop-save-buffer) ! (funcall desktop-save-buffer dirname)) ! (let ((locals desktop-locals-to-save) ! (loclist (buffer-local-variables)) ! (ll)) ! (while locals ! (let ((here (assq (car locals) loclist))) ! (if here ! (setq ll (cons here ll)) ! (when (member (car locals) loclist) ! (setq ll (cons (car locals) ll))))) ! (setq locals (cdr locals))) ! ll))) ! (buffer-list))) ! (eager desktop-restore-eager) ! (buf (get-buffer-create "*desktop*"))) ! (set-buffer buf) ! (erase-buffer) ! ! (insert ! ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" ! desktop-header ! ";; Created " (current-time-string) "\n" ! ";; Desktop file format version " desktop-file-version "\n" ! ";; Emacs version " emacs-version "\n\n" ! ";; Global section:\n") ! (mapc (function desktop-outvar) desktop-globals-to-save) ! (if (memq 'kill-ring desktop-globals-to-save) ! (insert ! "(setq kill-ring-yank-pointer (nthcdr " ! (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer))) ! " kill-ring))\n")) ! ! (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n") ! (mapc #'(lambda (l) ! (when (apply 'desktop-save-buffer-p l) ! (insert "(" ! (if (or (not (integerp eager)) ! (unless (zerop eager) ! (setq eager (1- eager)) ! t)) ! "desktop-create-buffer" ! "desktop-append-buffer-args") ! " " ! desktop-file-version) ! (mapc #'(lambda (e) ! (insert "\n " (desktop-value-to-string e))) ! l) ! (insert ")\n\n"))) ! info) ! (setq default-directory dirname) ! (let ((coding-system-for-write 'emacs-mule)) ! (write-region (point-min) (point-max) filename nil 'nomessage)))) ! (setq desktop-dirname dirname)) ;; ---------------------------------------------------------------------------- (defun desktop-remove () --- 821,891 ---- (t (expand-file-name filename)))) ;; ---------------------------------------------------------------------------- ! (defun desktop-save (dirname &optional release) "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'." (interactive "DDirectory to save desktop file in: ") ! (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion ! (let ((eager desktop-restore-eager) ! (new-modtime (nth 5 (file-attributes (desktop-full-file-name))))) ! (when ! (or (not new-modtime) ; nothing to overwrite ! (equal desktop-file-modtime new-modtime) ! (yes-or-no-p (if desktop-file-modtime ! (if (> (float-time new-modtime) (float-time desktop-file-modtime)) ! "Desktop file is more recent than the one loaded. Save anyway? " ! "Desktop file isn't the one loaded. Overwrite it? ") ! "Current desktop was not loaded from a file. Overwrite this desktop file? ")) ! (unless release (error "Desktop file conflict"))) ! ! ;; If we're done with it, release the lock. ! ;; Otherwise, claim it if it's unclaimed or if we created it. ! (if release (desktop-release-lock) ! (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) ! ! (with-temp-buffer ! (insert ! ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" ! desktop-header ! ";; Created " (current-time-string) "\n" ! ";; Desktop file format version " desktop-file-version "\n" ! ";; Emacs version " emacs-version "\n\n") ! (save-excursion (run-hooks 'desktop-save-hook)) ! (goto-char (point-max)) ! (insert ";; Global section:\n") ! (mapc (function desktop-outvar) desktop-globals-to-save) ! (if (memq 'kill-ring desktop-globals-to-save) ! (insert ! "(setq kill-ring-yank-pointer (nthcdr " ! (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer))) ! " kill-ring))\n")) ! ! (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n") ! (mapc #'(lambda (l) ! (when (apply 'desktop-save-buffer-p l) ! (insert "(" ! (if (or (not (integerp eager)) ! (unless (zerop eager) ! (setq eager (1- eager)) ! t)) ! "desktop-create-buffer" ! "desktop-append-buffer-args") ! " " ! desktop-file-version) ! (mapc #'(lambda (e) ! (insert "\n " (desktop-value-to-string e))) ! l) ! (insert ")\n\n"))) ! (mapcar 'desktop-buffer-info (buffer-list))) ! ! (setq default-directory 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))))))))) ;; ---------------------------------------------------------------------------- (defun desktop-remove () *************** *** 810,816 **** This function also sets `desktop-dirname' to nil." (interactive) (when desktop-dirname ! (let ((filename (expand-file-name desktop-base-file-name desktop-dirname))) (setq desktop-dirname nil) (when (file-exists-p filename) (delete-file filename))))) --- 893,899 ---- This function also sets `desktop-dirname' to nil." (interactive) (when desktop-dirname ! (let ((filename (desktop-full-file-name))) (setq desktop-dirname nil) (when (file-exists-p filename) (delete-file filename))))) *************** *** 833,884 **** (interactive) (unless noninteractive (setq desktop-dirname ! (file-name-as-directory ! (expand-file-name ! (or ! ;; If DIRNAME is specified, use it. ! (and (< 0 (length dirname)) dirname) ! ;; Otherwise search desktop file in desktop-path. ! (let ((dirs desktop-path)) ! (while ! (and ! dirs ! (not ! (file-exists-p (expand-file-name desktop-base-file-name (car dirs))))) ! (setq dirs (cdr dirs))) ! (and dirs (car dirs))) ! ;; If not found and `desktop-path' is non-nil, use its first element. ! (and desktop-path (car desktop-path)) ! ;; Default: Home directory. ! "~")))) ! (if (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname)) ! ;; Desktop file found, process it. ! (let ((desktop-first-buffer nil) ! (desktop-buffer-ok-count 0) ! (desktop-buffer-fail-count 0)) ! (setq desktop-lazy-timer nil) ! ;; Evaluate desktop buffer. ! (load (expand-file-name desktop-base-file-name desktop-dirname) t t t) ! ;; `desktop-create-buffer' puts buffers at end of the buffer list. ! ;; We want buffers existing prior to evaluating the desktop (and not reused) ! ;; to be placed at the end of the buffer list, so we move them here. ! (mapc 'bury-buffer ! (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) ! (switch-to-buffer (car (buffer-list))) ! (run-hooks 'desktop-delay-hook) ! (setq desktop-delay-hook nil) ! (run-hooks 'desktop-after-read-hook) ! (message "Desktop: %d buffer%s restored%s%s." ! desktop-buffer-ok-count ! (if (= 1 desktop-buffer-ok-count) "" "s") ! (if (< 0 desktop-buffer-fail-count) ! (format ", %d failed to restore" desktop-buffer-fail-count) ! "") ! (if desktop-buffer-args-list ! (format ", %d to restore lazily" ! (length desktop-buffer-args-list)) ! "")) ! t) ;; No desktop file found. (desktop-clear) (let ((default-directory desktop-dirname)) --- 916,983 ---- (interactive) (unless noninteractive (setq desktop-dirname ! (file-name-as-directory ! (expand-file-name ! (or ! ;; If DIRNAME is specified, use it. ! (and (< 0 (length dirname)) dirname) ! ;; Otherwise search desktop file in desktop-path. ! (let ((dirs desktop-path)) ! (while ! (and ! dirs ! (not ! (file-exists-p (desktop-full-file-name (car dirs))))) ! (setq dirs (cdr dirs))) ! (and dirs (car dirs))) ! ;; If not found and `desktop-path' is non-nil, use its first element. ! (and desktop-path (car desktop-path)) ! ;; Default: Home directory. ! "~")))) ! (if (file-exists-p (desktop-full-file-name)) ! ;; Desktop file found, but is it already in use? ! (let ((desktop-first-buffer nil) ! (desktop-buffer-ok-count 0) ! (desktop-buffer-fail-count 0) ! (owner (desktop-owner))) ! (if (and owner ! (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\nUsing it may cause conflicts. Use it anyway? " owner)))) ! (progn (setq desktop-dirname nil) ! (let ((default-directory desktop-dirname)) ! (run-hooks 'desktop-not-loaded-hook)) ! (message "Desktop file in use; not loaded.")) ! (setq desktop-lazy-timer nil) ! ;; Evaluate desktop buffer and remember when it was modified. ! (load (desktop-full-file-name) t t t) ! (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))) ! ;; If it wasn't already, mark it as in-use, to bother other ! ;; desktop instances. ! (unless owner ! (condition-case nil (desktop-claim-lock) ! (file-error (message "Couldn't record use of desktop file") ! (sit-for 1)))) ! ! ;; `desktop-create-buffer' puts buffers at end of the buffer list. ! ;; We want buffers existing prior to evaluating the desktop (and ! ;; not reused) to be placed at the end of the buffer list, so we ! ;; move them here. ! (mapc 'bury-buffer ! (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) ! (switch-to-buffer (car (buffer-list))) ! (run-hooks 'desktop-delay-hook) ! (setq desktop-delay-hook nil) ! (run-hooks 'desktop-after-read-hook) ! (message "Desktop: %d buffer%s restored%s%s." ! desktop-buffer-ok-count ! (if (= 1 desktop-buffer-ok-count) "" "s") ! (if (< 0 desktop-buffer-fail-count) ! (format ", %d failed to restore" desktop-buffer-fail-count) ! "") ! (if desktop-buffer-args-list ! (format ", %d to restore lazily" ! (length desktop-buffer-args-list)) ! "")) ! t)) ;; No desktop file found. (desktop-clear) (let ((default-directory desktop-dirname)) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-27 23:05 ` Stuart D. Herring 2006-04-28 14:56 ` Juanma Barranquero @ 2006-04-28 15:44 ` Richard Stallman 2006-04-29 5:02 ` Stuart D. Herring 2006-05-03 12:48 ` Juri Linkov 1 sibling, 2 replies; 72+ messages in thread From: Richard Stallman @ 2006-04-28 15:44 UTC (permalink / raw) Cc: lekktu, emacs-devel Two things are done: first, a desktop file is modified when it is read (without incident) to include a "in use" tag; further Emacses will complain about this if they see it, and will leave the desktop file unloaded unless the user accepts the collision risk. I think it is somewhat dangerous to modify the file when reading it. My experience tells me that that can lead to various problems in weird cases, and it is much better if operations that only look at data are written so that they do not change anything. Can you use a different file name for the "in use" marker? ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-28 15:44 ` Richard Stallman @ 2006-04-29 5:02 ` Stuart D. Herring 2006-04-30 3:03 ` Richard Stallman 2006-05-03 12:48 ` Juri Linkov 1 sibling, 1 reply; 72+ messages in thread From: Stuart D. Herring @ 2006-04-29 5:02 UTC (permalink / raw) Cc: emacs-devel > I think it is somewhat dangerous to modify the file when reading it. > My experience tells me that that can lead to various problems in weird > cases, and it is much better if operations that only look at data > are written so that they do not change anything. > > Can you use a different file name for the "in use" marker? I'm curious about your experience/worries -- the file is opened twice, so there's no seek issues, and the write is just an append. There's obvious race conditions, but I don't think they're important (as I said previously). And I was trying to avoid introducing another file for which one would have to check for conflicts and such. But I suppose there's no harm in having `desktop-lock-file-name', customizable but defaulted to ".emacs.desktop.lock" or so. It can hold the PID of the owner Emacs process. Speaking of which, is there a way to see from Lisp if an unrelated PID is running? Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-29 5:02 ` Stuart D. Herring @ 2006-04-30 3:03 ` Richard Stallman 0 siblings, 0 replies; 72+ messages in thread From: Richard Stallman @ 2006-04-30 3:03 UTC (permalink / raw) Cc: emacs-devel I don't remember any details--I have just seen enough problems, over the years, with corrupted files that I have reached the conclusion that it is much better not to alter a file when there is no logical reason it should be changed. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-04-28 15:44 ` Richard Stallman 2006-04-29 5:02 ` Stuart D. Herring @ 2006-05-03 12:48 ` Juri Linkov 2006-05-03 14:37 ` Lars Hansen 2006-05-04 16:17 ` Stuart D. Herring 1 sibling, 2 replies; 72+ messages in thread From: Juri Linkov @ 2006-05-03 12:48 UTC (permalink / raw) Cc: lekktu, emacs-devel > Two things are done: first, a desktop file is modified when it is read > (without incident) to include a "in use" tag; further Emacses will > complain about this if they see it, and will leave the desktop file > unloaded unless the user accepts the collision risk. > > I think it is somewhat dangerous to modify the file when reading it. > My experience tells me that that can lead to various problems in weird > cases, and it is much better if operations that only look at data > are written so that they do not change anything. > > Can you use a different file name for the "in use" marker? Wouldn't it be better to use Emacs standard file locking mechanism, i.e. after reading a desktop file to mark the desktop file's buffer as modified? This ensures that trying to save the desktop in another Emacs session will raise a question about stealing/leaving the lock. Another simpler solution (without touching the desktop file's buffer) is to remember the desktop file's timestamp after reading it, and before saving it compare it with the old timestamp, and ask the question about whether to override it or not. -- Juri Linkov http://www.jurta.org/emacs/ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-03 12:48 ` Juri Linkov @ 2006-05-03 14:37 ` Lars Hansen 2006-05-03 20:43 ` Richard Stallman 2006-05-04 16:27 ` Stuart D. Herring 2006-05-04 16:17 ` Stuart D. Herring 1 sibling, 2 replies; 72+ messages in thread From: Lars Hansen @ 2006-05-03 14:37 UTC (permalink / raw) Cc: lekktu, rms, emacs-devel Juri Linkov wrote: >Wouldn't it be better to use Emacs standard file locking mechanism, >i.e. after reading a desktop file to mark the desktop file's buffer >as modified? This ensures that trying to save the desktop in another >Emacs session will raise a question about stealing/leaving the lock. > > I like the idea of using the standard locking mechanism, but I don't like to mark an unmodified buffer as modified. I think the desktop file should be locked as soon as we know it is going to be changed when Emacs exits, i.e. when desktop-save-mode is turned on. And if desktop-save-mode is turned off, the desktop file should be unlocked if its buffer is unmodified. So maybe lock-buffer should have an optional parameter LOCK-UNMODIFIED to make it usable in such cases (I take it this is an after-the-release discussion.) I guess the same type of problem exists for .recentf, .emacs-places, .emacs-history and maybe other files. The problem should be handled in the same way for all these files. >Another simpler solution (without touching the desktop file's buffer) is >to remember the desktop file's timestamp after reading it, and before >saving it compare it with the old timestamp, and ask the question about >whether to override it or not. > > This is pleasingly simple, but then the question would be asked when Emacs is exited rather than when it is started. IMHO, the question should be asked as soon as the problem is detected, i.e. when the second Emacs is started (if desktop-save-mode is turned on). ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-03 14:37 ` Lars Hansen @ 2006-05-03 20:43 ` Richard Stallman 2006-05-04 16:27 ` Stuart D. Herring 1 sibling, 0 replies; 72+ messages in thread From: Richard Stallman @ 2006-05-03 20:43 UTC (permalink / raw) Cc: juri, lekktu, emacs-devel I like the idea of using the standard locking mechanism, but I don't like to mark an unmodified buffer as modified. There is nothing inconsistent with that state of affairs. Type X DEL and you will get an unmodified buffer marked as modified. If it makes you feel better, you could insert a string in the buffer and then delete it. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-03 14:37 ` Lars Hansen 2006-05-03 20:43 ` Richard Stallman @ 2006-05-04 16:27 ` Stuart D. Herring 2006-05-05 6:44 ` Lars Hansen 2007-06-05 9:24 ` Juanma Barranquero 1 sibling, 2 replies; 72+ messages in thread From: Stuart D. Herring @ 2006-05-04 16:27 UTC (permalink / raw) Cc: emacs-devel > I like the idea of using the standard locking mechanism, but I don't > like to mark an unmodified buffer as modified. > > I think the desktop file should be locked as soon as we know it is going > to be changed when Emacs exits, i.e. when desktop-save-mode is turned > on. And if desktop-save-mode is turned off, the desktop file should be > unlocked if its buffer is unmodified. So maybe lock-buffer should have > an optional parameter LOCK-UNMODIFIED to make it usable in such cases (I > take it this is an after-the-release discussion.) So what happens if you turn desktop-save-mode off, another Emacs loads, locks, overwrites, and unlocks the file, and then you turn desktop-save-mode back on? (The desktop file's buffer (if it is made to have one) will always be unmodified unless the user explicitly finds it and changes it; desktop does not use a buffer as some sort of "scratch pad" whose state of modification would reflect the state of the abstract desktop.) Besides, someone could have a "standard desktop" that they load frequently but save rarely, and so never have desktop-save-mode turned on. Then they might occasionally improve on or update the standard, and issue an explicit (desktop-save) which would take place without the protections of file locking. In short, I don't think it's reasonable to "know it is going to be changed when Emacs exits", because settings can change and it might even get changed before Emacs exits (due to `desktop-save' or even `desktop-change-dir'). >> [timestamp check suggestion] > > This is pleasingly simple, but then the question would be asked when > Emacs is exited rather than when it is started. IMHO, the question > should be asked as soon as the problem is detected, i.e. when the second > Emacs is started (if desktop-save-mode is turned on). My patch does this (as I mentioned in my reply to Juri); it also does what you ask, although without the standard file-lock mechanism. A separate lock file is maintained which identifies (by PID) the owner of the desktop file. Then the second Emacs will see the file and complain about it (regardless of the setting of `desktop-save-mode', for the reasons of no-precognition mentioned above), although the user is allowed the option of proceeding anyway (at which point it's up to the modification dates to attempt a peaceful resolution later). I encourage the testing of my patch to see if its behavior is close enough to everyone's idea of safe, correct, vigilant, and intuitive. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-04 16:27 ` Stuart D. Herring @ 2006-05-05 6:44 ` Lars Hansen 2007-06-05 9:24 ` Juanma Barranquero 1 sibling, 0 replies; 72+ messages in thread From: Lars Hansen @ 2006-05-05 6:44 UTC (permalink / raw) Cc: emacs-devel Stuart D. Herring wrote: >So what happens if you turn desktop-save-mode off, another Emacs loads, >locks, overwrites, and unlocks the file, and then you turn >desktop-save-mode back on? (The desktop file's buffer (if it is made to >have one) will always be unmodified unless the user explicitly finds it >and changes it; desktop does not use a buffer as some sort of "scratch >pad" whose state of modification would reflect the state of the abstract >desktop.) Besides, someone could have a "standard desktop" that they load >frequently but save rarely, and so never have desktop-save-mode turned on. > Then they might occasionally improve on or update the standard, and issue >an explicit (desktop-save) which would take place without the protections >of file locking. > > I see your point. >I encourage the testing of my patch to see if its behavior is close enough >to everyone's idea of safe, correct, vigilant, and intuitive. > > I will do so. Thanks. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-04 16:27 ` Stuart D. Herring 2006-05-05 6:44 ` Lars Hansen @ 2007-06-05 9:24 ` Juanma Barranquero 2007-06-08 21:17 ` Davis Herring 1 sibling, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2007-06-05 9:24 UTC (permalink / raw) To: herring; +Cc: emacs-devel On 5/4/06, Stuart D. Herring <herring@lanl.gov> wrote: > My patch does this (as I mentioned in my reply to Juri); it also does what > you ask, although without the standard file-lock mechanism. A separate > lock file is maintained which identifies (by PID) the owner of the desktop > file. Then the second Emacs will see the file and complain about it > (regardless of the setting of `desktop-save-mode', for the reasons of > no-precognition mentioned above), although the user is allowed the option > of proceeding anyway (at which point it's up to the modification dates to > attempt a peaceful resolution later). What happened to this patch to add sort-of-file-locking to desktop.el? Juanma ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-05 9:24 ` Juanma Barranquero @ 2007-06-08 21:17 ` Davis Herring 2007-06-08 21:29 ` Juanma Barranquero 2007-06-08 22:14 ` Juri Linkov 0 siblings, 2 replies; 72+ messages in thread From: Davis Herring @ 2007-06-08 21:17 UTC (permalink / raw) To: Juanma Barranquero; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1643 bytes --] > What happened to this patch to add sort-of-file-locking to desktop.el? As far as I know, nothing has been done with it. I still have it in my working copy (of course), and have, prompted by your message, just now resolved a daunting 57/76-line conflict with the changes between 1.106 and 1.108. My version has one of the tainted `mapc' calls, if that matters; given Stefan's trivial (dolist (x l) (f x)) I would surely have supplied (mapc f l) myself. (No offense meant to Stefan; that one alone was trivial.) Links to the original (er, the second) discussion: April, largely superceded: http://lists.gnu.org/archive/html/emacs-devel/2006-04/msg01253.html May: http://lists.gnu.org/archive/html/emacs-devel/2006-05/msg00084.html I've attached an updated patch vs. current CVS; in it I have optimistically tagged my two new defcustoms as new in 22.2. Here's a stab at a ChangeLog: 2007-06-08 Davis Herring <herring@lanl.gov> * desktop.el (desktop-save-mode-off): New function. (desktop-base-lock-name, desktop-not-loaded-hook): New variables. (desktop-full-lock-name, desktop-file-modtime, desktop-owner) (desktop-claim-lock, desktop-release-lock): New functions. (desktop-kill): Tell `desktop-save' that this is the last save. Release the lock afterwards. (desktop-buffer-info): New function. (desktop-save): Use it. Run `desktop-save-hook' where the doc says to. Detect conflicts, and manage the lock. (desktop-read): Detect conflicts. Manage the lock. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. [-- Attachment #2: desktop-conflict-4.patch --] [-- Type: application/octet-stream, Size: 18053 bytes --] Index: desktop.el =================================================================== RCS file: /sources/emacs/emacs/lisp/desktop.el,v retrieving revision 1.108 diff -c -r1.108 desktop.el *** desktop.el 11 Apr 2007 02:28:26 -0000 1.108 --- desktop.el 8 Jun 2007 20:58:14 -0000 *************** *** 162,167 **** --- 162,171 ---- (define-obsolete-variable-alias 'desktop-enable 'desktop-save-mode "22.1") + (defun desktop-save-mode-off () + "Disable `desktop-save-mode'. Provided for use in hooks." + (desktop-save-mode 0)) + (defcustom desktop-save 'ask-if-new "*Specifies whether the desktop should be saved when it is killed. A desktop is killed when the user changes desktop or quits Emacs. *************** *** 194,199 **** --- 198,210 ---- (define-obsolete-variable-alias 'desktop-basefilename 'desktop-base-file-name "22.1") + (defcustom desktop-base-lock-name + (convert-standard-filename ".emacs.desktop.lock") + "Name of lock file for Emacs desktop, excluding the directory part." + :type 'file + :group 'desktop + :version "22.2") + (defcustom desktop-path '("." "~") "List of directories to search for the desktop file. The base name of the file is specified in `desktop-base-file-name'." *************** *** 219,224 **** --- 230,244 ---- :group 'desktop :version "22.1") + (defcustom desktop-not-loaded-hook nil + "Normal hook run when the user declines to re-use a desktop file. + Run in the directory in which the desktop file was found. + May be used to deal with accidental multiple Emacs jobs." + :type 'hook + :group 'desktop + :options '(desktop-save-mode-off save-buffers-kill-emacs) + :version "22.2") + (defcustom desktop-after-read-hook nil "Normal hook run after a successful `desktop-read'. May be used to show a buffer list." *************** *** 486,491 **** --- 506,516 ---- DIRNAME omitted or nil means use `desktop-dirname'." (expand-file-name desktop-base-file-name (or dirname desktop-dirname))) + (defun desktop-full-lock-name (&optional dirname) + "Return the full name of the desktop lock file in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (expand-file-name desktop-base-lock-name (or dirname desktop-dirname))) + (defconst desktop-header ";; -------------------------------------------------------------------------- ;; Desktop File for Emacs *************** *** 496,501 **** --- 521,559 ---- "Hooks run after all buffers are loaded; intended for internal use.") ;; ---------------------------------------------------------------------------- + ;; Desktop file conflict detection + (defvar desktop-file-modtime nil + "When the desktop file was last modified to the knowledge of this Emacs. + Used to detect desktop file conflicts.") + + (defun desktop-owner (&optional dirname) + "Return the PID of the Emacs process that owns the desktop file in DIRNAME. + Return nil if no desktop file found or no Emacs process is using it. + DIRNAME omitted or nil means use `desktop-dirname'." + (let (owner) + (and (file-exists-p (desktop-full-lock-name dirname)) + (condition-case nil + (with-temp-buffer (insert-file-contents-literally + (desktop-full-lock-name dirname)) + (goto-char (point-min)) + (setq owner (read (current-buffer))) + (integerp owner)) + (error nil)) + owner))) + + (defun desktop-claim-lock (&optional dirname) + "Record this Emacs process as the owner of the desktop file in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (write-region (number-to-string (emacs-pid)) nil + (desktop-full-lock-name dirname))) + + (defun desktop-release-lock (&optional dirname) + "Remove the lock file for the desktop in DIRNAME. + DIRNAME omitted or nil means use `desktop-dirname'." + (let ((file (desktop-full-lock-name dirname))) + (when (file-exists-p file) (delete-file file)))) + + ;; ---------------------------------------------------------------------------- (defun desktop-truncate (list n) "Truncate LIST to at most N elements destructively." (let ((here (nthcdr (1- n) list))) *************** *** 556,565 **** (lambda (dir) (interactive "DDirectory for desktop file: ") dir)))))) (condition-case err ! (desktop-save desktop-dirname) (file-error (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") ! (signal (car err) (cdr err))))))) ;; ---------------------------------------------------------------------------- (defun desktop-list* (&rest args) --- 614,625 ---- (lambda (dir) (interactive "DDirectory for desktop file: ") dir)))))) (condition-case err ! (desktop-save desktop-dirname t) (file-error (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") ! (signal (car err) (cdr err)))))) ! ;; If we own it, we don't anymore. ! (if (eq (emacs-pid) (desktop-owner)) (desktop-release-lock))) ;; ---------------------------------------------------------------------------- (defun desktop-list* (&rest args) *************** *** 574,579 **** --- 634,675 ---- value))) ;; ---------------------------------------------------------------------------- + (defun desktop-buffer-info (buffer) + (set-buffer buffer) + (list + ;; basic information + (desktop-file-name (buffer-file-name) dirname) (buffer-name) major-mode + ;; minor modes + (let (ret) + (mapc + #'(lambda (minor-mode) + (and + (boundp minor-mode) + (symbol-value minor-mode) + (let* ((special (assq minor-mode desktop-minor-mode-table)) + (value (cond (special (cadr special)) + ((functionp minor-mode) minor-mode)))) + (when value (add-to-list 'ret value))))) + (mapcar #'car minor-mode-alist)) + ret) + ;; point and mark, and read-only status + (point) (list (mark t) mark-active) buffer-read-only + ;; auxiliary information + (when (functionp desktop-save-buffer) + (funcall desktop-save-buffer dirname)) + ;; local variables + (let ((locals desktop-locals-to-save) + (loclist (buffer-local-variables)) + (ll)) + (while locals + (let ((here (assq (car locals) loclist))) + (if here (setq ll (cons here ll)) + (when (member (car locals) loclist) + (setq ll (cons (car locals) ll))))) + (setq locals (cdr locals))) + ll))) + + ;; ---------------------------------------------------------------------------- (defun desktop-internal-v2s (value) "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE. TXT is a string that when read and evaluated yields value. *************** *** 724,813 **** ;; ---------------------------------------------------------------------------- ;;;###autoload ! (defun desktop-save (dirname) "Save the desktop in a desktop file. Parameter DIRNAME specifies where to save the desktop file. See also `desktop-base-file-name'." (interactive "DDirectory to save desktop file in: ") ! (run-hooks 'desktop-save-hook) ! (setq dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion ! (let ((filename (desktop-full-file-name dirname)) ! (info ! (mapcar ! #'(lambda (b) ! (set-buffer b) ! (list ! (desktop-file-name (buffer-file-name) dirname) ! (buffer-name) ! major-mode ! ;; minor modes ! (let (ret) ! (mapc ! #'(lambda (minor-mode) ! (and ! (boundp minor-mode) ! (symbol-value minor-mode) ! (let* ((special (assq minor-mode desktop-minor-mode-table)) ! (value (cond (special (cadr special)) ! ((functionp minor-mode) minor-mode)))) ! (when value (add-to-list 'ret value))))) ! (mapcar #'car minor-mode-alist)) ! ret) ! (point) ! (list (mark t) mark-active) ! buffer-read-only ! ;; Auxiliary information ! (when (functionp desktop-save-buffer) ! (funcall desktop-save-buffer dirname)) ! (let ((locals desktop-locals-to-save) ! (loclist (buffer-local-variables)) ! (ll)) ! (while locals ! (let ((here (assq (car locals) loclist))) ! (if here ! (setq ll (cons here ll)) ! (when (member (car locals) loclist) ! (setq ll (cons (car locals) ll))))) ! (setq locals (cdr locals))) ! ll))) ! (buffer-list))) ! (eager desktop-restore-eager)) ! (with-temp-buffer ! (insert ! ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" ! desktop-header ! ";; Created " (current-time-string) "\n" ! ";; Desktop file format version " desktop-file-version "\n" ! ";; Emacs version " emacs-version "\n\n" ! ";; Global section:\n") ! (dolist (varspec desktop-globals-to-save) ! (desktop-outvar varspec)) ! (if (memq 'kill-ring desktop-globals-to-save) ! (insert ! "(setq kill-ring-yank-pointer (nthcdr " ! (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer))) ! " kill-ring))\n")) ! ! (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n") ! (dolist (l info) ! (when (apply 'desktop-save-buffer-p l) ! (insert "(" ! (if (or (not (integerp eager)) ! (unless (zerop eager) ! (setq eager (1- eager)) ! t)) ! "desktop-create-buffer" ! "desktop-append-buffer-args") ! " " ! desktop-file-version) ! (dolist (e l) ! (insert "\n " (desktop-value-to-string e))) ! (insert ")\n\n"))) ! (setq default-directory dirname) ! (let ((coding-system-for-write 'emacs-mule)) ! (write-region (point-min) (point-max) filename nil 'nomessage))))) ! (setq desktop-dirname dirname)) ;; ---------------------------------------------------------------------------- ;;;###autoload --- 820,888 ---- ;; ---------------------------------------------------------------------------- ;;;###autoload ! (defun desktop-save (dirname &optional release) "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'." (interactive "DDirectory to save desktop file in: ") ! (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion ! (let ((eager desktop-restore-eager) ! (new-modtime (nth 5 (file-attributes (desktop-full-file-name))))) ! (when ! (or (not new-modtime) ; nothing to overwrite ! (equal desktop-file-modtime new-modtime) ! (yes-or-no-p (if desktop-file-modtime ! (if (> (float-time new-modtime) (float-time desktop-file-modtime)) ! "Desktop file is more recent than the one loaded. Save anyway? " ! "Desktop file isn't the one loaded. Overwrite it? ") ! "Current desktop was not loaded from a file. Overwrite this desktop file? ")) ! (unless release (error "Desktop file conflict"))) ! ! ;; If we're done with it, release the lock. ! ;; Otherwise, claim it if it's unclaimed or if we created it. ! (if release (desktop-release-lock) ! (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) ! ! (with-temp-buffer ! (insert ! ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" ! desktop-header ! ";; Created " (current-time-string) "\n" ! ";; Desktop file format version " desktop-file-version "\n" ! ";; Emacs version " emacs-version "\n") ! (save-excursion (run-hooks 'desktop-save-hook)) ! (goto-char (point-max)) ! (insert "\n;; Global section:\n") ! (mapc (function desktop-outvar) desktop-globals-to-save) ! (if (memq 'kill-ring desktop-globals-to-save) ! (insert ! "(setq kill-ring-yank-pointer (nthcdr " ! (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer))) ! " kill-ring))\n")) ! ! (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n") ! (dolist (l (mapcar 'desktop-buffer-info (buffer-list))) ! (when (apply 'desktop-save-buffer-p l) ! (insert "(" ! (if (or (not (integerp eager)) ! (unless (zerop eager) ! (setq eager (1- eager)) ! t)) ! "desktop-create-buffer" ! "desktop-append-buffer-args") ! " " ! desktop-file-version) ! (dolist (e l) ! (insert "\n " (desktop-value-to-string e))) ! (insert ")\n\n"))) ! ! (setq default-directory 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))))))))) ;; ---------------------------------------------------------------------------- ;;;###autoload *************** *** 856,890 **** ;; Default: Home directory. "~")))) (if (file-exists-p (desktop-full-file-name)) ! ;; Desktop file found, process it. ! (let ((desktop-first-buffer nil) ! (desktop-buffer-ok-count 0) ! (desktop-buffer-fail-count 0) ! ;; Avoid desktop saving during evaluation of desktop buffer. ! (desktop-save nil)) ! (desktop-lazy-abort) ! ;; Evaluate desktop buffer. ! (load (desktop-full-file-name) t t t) ! ;; `desktop-create-buffer' puts buffers at end of the buffer list. ! ;; We want buffers existing prior to evaluating the desktop (and not reused) ! ;; to be placed at the end of the buffer list, so we move them here. ! (mapc 'bury-buffer ! (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) ! (switch-to-buffer (car (buffer-list))) ! (run-hooks 'desktop-delay-hook) ! (setq desktop-delay-hook nil) ! (run-hooks 'desktop-after-read-hook) ! (message "Desktop: %d buffer%s restored%s%s." ! desktop-buffer-ok-count ! (if (= 1 desktop-buffer-ok-count) "" "s") ! (if (< 0 desktop-buffer-fail-count) ! (format ", %d failed to restore" desktop-buffer-fail-count) ! "") ! (if desktop-buffer-args-list ! (format ", %d to restore lazily" ! (length desktop-buffer-args-list)) ! "")) ! t) ;; No desktop file found. (desktop-clear) (let ((default-directory desktop-dirname)) --- 931,981 ---- ;; Default: Home directory. "~")))) (if (file-exists-p (desktop-full-file-name)) ! ;; Desktop file found, but is it already in use? ! (let ((desktop-first-buffer nil) ! (desktop-buffer-ok-count 0) ! (desktop-buffer-fail-count 0) ! (owner (desktop-owner)) ! ;; Avoid desktop saving during evaluation of desktop buffer. ! (desktop-save nil)) ! (if (and owner ! (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\nUsing it may cause conflicts. Use it anyway? " owner)))) ! (progn (setq desktop-dirname nil) ! (let ((default-directory desktop-dirname)) ! (run-hooks 'desktop-not-loaded-hook)) ! (message "Desktop file in use; not loaded.")) ! (desktop-lazy-abort) ! ;; Evaluate desktop buffer and remember when it was modified. ! (load (desktop-full-file-name) t t t) ! (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))) ! ;; If it wasn't already, mark it as in-use, to bother other ! ;; desktop instances. ! (unless owner ! (condition-case nil (desktop-claim-lock) ! (file-error (message "Couldn't record use of desktop file") ! (sit-for 1)))) ! ! ;; `desktop-create-buffer' puts buffers at end of the buffer list. ! ;; We want buffers existing prior to evaluating the desktop (and ! ;; not reused) to be placed at the end of the buffer list, so we ! ;; move them here. ! (mapc 'bury-buffer ! (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) ! (switch-to-buffer (car (buffer-list))) ! (run-hooks 'desktop-delay-hook) ! (setq desktop-delay-hook nil) ! (run-hooks 'desktop-after-read-hook) ! (message "Desktop: %d buffer%s restored%s%s." ! desktop-buffer-ok-count ! (if (= 1 desktop-buffer-ok-count) "" "s") ! (if (< 0 desktop-buffer-fail-count) ! (format ", %d failed to restore" desktop-buffer-fail-count) ! "") ! (if desktop-buffer-args-list ! (format ", %d to restore lazily" ! (length desktop-buffer-args-list)) ! "")) ! t)) ;; No desktop file found. (desktop-clear) (let ((default-directory desktop-dirname)) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-08 21:17 ` Davis Herring @ 2007-06-08 21:29 ` Juanma Barranquero 2007-06-08 22:05 ` Davis Herring 2007-06-08 22:14 ` Juri Linkov 1 sibling, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2007-06-08 21:29 UTC (permalink / raw) To: herring; +Cc: emacs-devel On 6/8/07, Davis Herring <herring@lanl.gov> wrote: > As far as I know, nothing has been done with it. Well, of course. My question was like a reminder, to get the thing back on track. So thanks for updating the patch :) > I've attached an updated patch vs. current CVS; in it I have > optimistically tagged my two new defcustoms as new in 22.2. I'm gonna give it a try right now. I'm currently running 22.1, EMACS_22_BASE and HEAD, mostly in parallel, and I'm sick of overwriting my desktop file by accident. Juanma ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-08 21:29 ` Juanma Barranquero @ 2007-06-08 22:05 ` Davis Herring 0 siblings, 0 replies; 72+ messages in thread From: Davis Herring @ 2007-06-08 22:05 UTC (permalink / raw) To: Juanma Barranquero; +Cc: emacs-devel Also, I offer a trivial typo patch, which hopefully won't get wrapped badly: *** desktop.el --- desktop.el *************** *** 423,429 **** Each entry has the form (NAME RESTORE-FUNCTION). NAME is the name of the buffer-local variable indicating that the minor mode is active. RESTORE-FUNCTION is the function to activate the minor mode. ! called. RESTORE-FUNCTION nil means don't try to restore the minor mode. Only minor modes for which the name of the buffer-local variable and the name of the minor mode function are different have to be added to this table. See also `desktop-minor-mode-handlers'." --- 443,449 ---- Each entry has the form (NAME RESTORE-FUNCTION). NAME is the name of the buffer-local variable indicating that the minor mode is active. RESTORE-FUNCTION is the function to activate the minor mode. ! RESTORE-FUNCTION nil means don't try to restore the minor mode. Only minor modes for which the name of the buffer-local variable and the name of the minor mode function are different have to be added to this table. See also `desktop-minor-mode-handlers'." Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-08 21:17 ` Davis Herring 2007-06-08 21:29 ` Juanma Barranquero @ 2007-06-08 22:14 ` Juri Linkov 2007-06-09 0:51 ` Davis Herring 1 sibling, 1 reply; 72+ messages in thread From: Juri Linkov @ 2007-06-08 22:14 UTC (permalink / raw) To: herring; +Cc: Juanma Barranquero, emacs-devel > I've attached an updated patch vs. current CVS; in it I have > optimistically tagged my two new defcustoms as new in 22.2. Here's a stab > at a ChangeLog: I have in .emacs (run-at-time 3600 3600 'desktop-save "~") so desktop-save silently saves the desktop every hour. Does you patch cause a problem by asking questions about file locks inside such a timer? -- Juri Linkov http://www.jurta.org/emacs/ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-08 22:14 ` Juri Linkov @ 2007-06-09 0:51 ` Davis Herring 2007-06-09 21:31 ` Juri Linkov 0 siblings, 1 reply; 72+ messages in thread From: Davis Herring @ 2007-06-09 0:51 UTC (permalink / raw) To: Juri Linkov; +Cc: Juanma Barranquero, emacs-devel > I have in .emacs > > (run-at-time 3600 3600 'desktop-save "~") > > so desktop-save silently saves the desktop every hour. > > Does you patch cause a problem by asking questions about file locks > inside such a timer? Er, I'm guessing it does... it certainly doesn't check to see if it's being run in a less than interactive fashion. (How does one even do that? Either of the standard interactive checks?) But the real question is what would you want it to do there instead of ask? - Is this sort of call supposed to automatically get priority and steal locks and such? If so, what happens when two Emacs instances run this timer (as in interleaved, not even simultaneously)? - Alternatively, is it supposed to always fail if a clash is detected? - Or should there be entirely different heuristics...? I guess I should note (partly just to give this message more than one declarative sentence) that if you don't save the desktop from another Emacs (even if you start one and re-use this autosaved desktop), it won't prompt the next time the timer runs. So if you actually "respect" the clash detection and don't create a conflicting desktop, there won't be a problem. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-09 0:51 ` Davis Herring @ 2007-06-09 21:31 ` Juri Linkov 2007-06-10 23:28 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: Juri Linkov @ 2007-06-09 21:31 UTC (permalink / raw) To: herring; +Cc: Juanma Barranquero, emacs-devel >> I have in .emacs >> (run-at-time 3600 3600 'desktop-save "~") >> so desktop-save silently saves the desktop every hour. >> >> Does you patch cause a problem by asking questions about file locks >> inside such a timer? > > Er, I'm guessing it does... it certainly doesn't check to see if it's > being run in a less than interactive fashion. (How does one even do that? > Either of the standard interactive checks?) But the real question is > what would you want it to do there instead of ask? > > - Is this sort of call supposed to automatically get priority and steal > locks and such? If so, what happens when two Emacs instances run this > timer (as in interleaved, not even simultaneously)? Overwriting the desktop of another Emacs instance is not a good thing to do. > - Alternatively, is it supposed to always fail if a clash is detected? Not writing the desktop would be acceptable if it displayed a message about this failure. > - Or should there be entirely different heuristics...? Another alternative is to write the desktop file with a different name. > I guess I should note (partly just to give this message more than one > declarative sentence) that if you don't save the desktop from another > Emacs (even if you start one and re-use this autosaved desktop), it won't > prompt the next time the timer runs. So if you actually "respect" the > clash detection and don't create a conflicting desktop, there won't be a > problem. All on all, we could leave this to the user's discretion. The user should be careful about not creating a configuration where two Emacs instances automatically write to the same file. -- Juri Linkov http://www.jurta.org/emacs/ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-09 21:31 ` Juri Linkov @ 2007-06-10 23:28 ` Juanma Barranquero 2007-06-11 20:54 ` Juri Linkov 0 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2007-06-10 23:28 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel On 6/9/07, Juri Linkov <juri@jurta.org> wrote: > Overwriting the desktop of another Emacs instance is not a good thing to do. Well, that's exactly what happens without this patch. > Not writing the desktop would be acceptable if it displayed a message > about this failure. What is the exact use case? > Another alternative is to write the desktop file with a different name. You can already do that, with or without the patch. The patch offers you the alternative of detecting the conflict when you run the second Emacs instance, so you chose not to load the desktop, and then manually set another name for it or create it in another directory. > All on all, we could leave this to the user's discretion. The user should be > careful about not creating a configuration where two Emacs instances > automatically write to the same file. I'm not sure what this means: are you proposing not installing the patch? Because the point (to me anyway) is not having a configuration where two instances write to the same file, but detecting the case when that happens by accident. The patch is very useful and works quite well (though I've added it an option to configure whether the second instance should automatically overwrite a conflicting desktop file, automatically skip loading it, or ask the user, instead of always asking as Davis' original patch does). I propose installing it and seeing what other people thinks of it. Juanma ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-10 23:28 ` Juanma Barranquero @ 2007-06-11 20:54 ` Juri Linkov 2007-06-12 11:21 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: Juri Linkov @ 2007-06-11 20:54 UTC (permalink / raw) To: Juanma Barranquero; +Cc: emacs-devel >> Overwriting the desktop of another Emacs instance is not a good thing to do. > > Well, that's exactly what happens without this patch. > >> Not writing the desktop would be acceptable if it displayed a message >> about this failure. > > What is the exact use case? Something like a message saying "Can't write the desktop because it is locked by another Emacs instance". Not a good solution either. >> Another alternative is to write the desktop file with a different name. > > You can already do that, with or without the patch. The patch offers > you the alternative of detecting the conflict when you run the second > Emacs instance, so you chose not to load the desktop, and then > manually set another name for it or create it in another directory. But this requires complicate configuration on the user's part. >> All on all, we could leave this to the user's discretion. The user >> should be careful about not creating a configuration where two Emacs >> instances automatically write to the same file. > > I'm not sure what this means: are you proposing not installing the > patch? Because the point (to me anyway) is not having a configuration > where two instances write to the same file, but detecting the case > when that happens by accident. No, I propose installing this patch. I had only doubts how it would behave with my configuration. But with the functions Davis implemented in his patch, it is easy to write a configuration which won't fail, e.g.: (unless (desktop-owner) (run-at-time 3600 3600 'desktop-save "~")) that starts automatic saving only when the desktop is not locked in another Emacs session. > The patch is very useful and works quite well (though I've added it an > option to configure whether the second instance should automatically > overwrite a conflicting desktop file, automatically skip loading it, > or ask the user, instead of always asking as Davis' original patch > does). Such an option would be useful. > I propose installing it and seeing what other people thinks of it. I agree. -- Juri Linkov http://www.jurta.org/emacs/ ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2007-06-11 20:54 ` Juri Linkov @ 2007-06-12 11:21 ` Juanma Barranquero 0 siblings, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2007-06-12 11:21 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel On 6/11/07, Juri Linkov <juri@jurta.org> wrote: > No, I propose installing this patch. I had only doubts how it would > behave with my configuration. But with the functions Davis implemented > in his patch, it is easy to write a configuration which won't fail [...] OK, I've installed Davis' patch and my patch with the new `desktop-load-locked-desktop' option (name's irrelevant, better suggestions welcome). The only nitpick I have now is that when the desktop is not loaded, the message to the user is barely visible. Perhaps it'd be good to define a function like: (defun desktop-warn-desktop-not-loaded () (display-warning 'desktop "Desktop file not loaded" :warning)) and add it as another option for `desktop-not-loaded-hook'. Juanma ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-05-03 12:48 ` Juri Linkov 2006-05-03 14:37 ` Lars Hansen @ 2006-05-04 16:17 ` Stuart D. Herring 1 sibling, 0 replies; 72+ messages in thread From: Stuart D. Herring @ 2006-05-04 16:17 UTC (permalink / raw) Cc: emacs-devel >> Can you use a different file name for the "in use" marker? > > Wouldn't it be better to use Emacs standard file locking mechanism, > i.e. after reading a desktop file to mark the desktop file's buffer > as modified? This ensures that trying to save the desktop in another > Emacs session will raise a question about stealing/leaving the lock. The desktop file is never in a buffer in the current scheme. `load' is called on the file, and then a new desktop is prepared in a file-less buffer "*desktop*" which is then `write-region'ed to the desktop file. `write-region' supports locking (even for file-less buffers), but `load' does not. Obviously one could actually find the desktop file, lock it, and then `eval-buffer' or so. I just want it understood that it's not compatible with the current architecture. > Another simpler solution (without touching the desktop file's buffer) is > to remember the desktop file's timestamp after reading it, and before > saving it compare it with the old timestamp, and ask the question about > whether to override it or not. My patch does this, among other things. The question arises, though, of what to do when the desktop is being saved to a different file; the desktop model does not involve "loading" and "saving" a desktop _file_ which is conceptually central and always-current, but rather "storing" and "reloading" a desktop (session data), using the file only as a persistence mechanism. So the statement "your desktop file has been modified since you read it" is somewhat wrongheaded, since during any Emacs session (or some subsession using a particular desktop; there is a function `desktop-change-dir') there is, conceptually, no "desktop file", just the actual desktop. My patch attempts to say meaningful things when loading from an in-use A and saving to a modified B, but the heuristics might be improvable. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 10:53 ` Juanma Barranquero 2005-07-22 22:52 ` Richard M. Stallman @ 2005-08-08 15:02 ` Lars Hansen 1 sibling, 0 replies; 72+ messages in thread From: Lars Hansen @ 2005-08-08 15:02 UTC (permalink / raw) Juanma Barranquero wrote: >In fact, I'm not sure what criterion is used to decide the default >value of `desktop-locals-to-save'. > I guess it should include variables set directly or indirectly by the user to control some kind of customization, minor modes excluded. But that's not exactly a precise criterion :-) ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 2:42 A few questions about desktop.el Juanma Barranquero 2005-07-22 10:53 ` Juanma Barranquero @ 2005-07-22 13:50 ` Juanma Barranquero 2005-07-22 14:36 ` Juanma Barranquero 2005-07-22 19:11 ` Lars Hansen ` (2 subsequent siblings) 4 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2005-07-22 13:50 UTC (permalink / raw) On 7/22/05, Juanma Barranquero <lekktu@gmail.com> wrote: > instead of simply > > (let ((special (cadr (assq minor-mode desktop-minor-mode-table)))) > (when (or special (functionp minor-mode)) > (add-to-list 'ret (or special minor-mode)))) My fault, for posting untested code. I meant: (let* ((special (assq minor-mode desktop-minor-mode-table)) (value (cond (special (cadr special)) ((functionp minor-mode) minor-mode)))) (when value (add-to-list 'ret value))))) -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 13:50 ` Juanma Barranquero @ 2005-07-22 14:36 ` Juanma Barranquero 2005-07-26 8:27 ` Juanma Barranquero 2005-08-08 15:04 ` Lars Hansen 0 siblings, 2 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-22 14:36 UTC (permalink / raw) The very end of `desktop-save' contains: (setq default-directory dirname) (when (file-exists-p filename) (delete-file filename)) (let ((coding-system-for-write 'emacs-mule)) (write-region (point-min) (point-max) filename nil 'nomessage)))) The code to delete the desktop file before writing into it has existed, AFAICS, since release 1.1 of desktop.el. However, it is bringing me pain on Windows. If I try to exit Emacs while viewing the .emacs.desktop from a command shell, Emacs tries to delete the file (and apparently succeeds), and then tries to write it anew (and it fails). After exiting the viewer program, .emacs.desktop no longer exists. Not nice. It is really necessary to delete the file prior to `write-region' it? Are there use cases where that is an advantage? -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 14:36 ` Juanma Barranquero @ 2005-07-26 8:27 ` Juanma Barranquero 2005-08-08 15:04 ` Lars Hansen 1 sibling, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-26 8:27 UTC (permalink / raw) Regarding this code in `desktop-save': > (setq default-directory dirname) > (when (file-exists-p filename) (delete-file filename)) > (let ((coding-system-for-write 'emacs-mule)) > (write-region (point-min) (point-max) filename nil 'nomessage)))) No one, not even the original author (I've just asked him), knows for sure whether the `delete-file' call is needed or why, and I know for certain it can produce some unexpected results in Windows ("unexpected" including data loss, meaning losing the .emacs.desktop file). So, if no one objects, in a few days I'm gonna delete that line. As we're not even in pretesting, we'll have plenty of time to know whether it causes problems in some environment or other, and reintroduce it (conditional to non-Windows, or not) if needed. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 14:36 ` Juanma Barranquero 2005-07-26 8:27 ` Juanma Barranquero @ 2005-08-08 15:04 ` Lars Hansen 1 sibling, 0 replies; 72+ messages in thread From: Lars Hansen @ 2005-08-08 15:04 UTC (permalink / raw) Cc: emacs-devel Juanma Barranquero wrote: >It is really necessary to delete the file prior to `write-region' it? > > I don't know of any reason why it should be necessary. To me it looks bad. My patch (included in a prior post) deletes the deletion :-) ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 2:42 A few questions about desktop.el Juanma Barranquero 2005-07-22 10:53 ` Juanma Barranquero 2005-07-22 13:50 ` Juanma Barranquero @ 2005-07-22 19:11 ` Lars Hansen 2005-07-22 21:24 ` Juanma Barranquero 2005-07-22 22:50 ` Richard M. Stallman 2005-08-08 14:51 ` Lars Hansen 4 siblings, 1 reply; 72+ messages in thread From: Lars Hansen @ 2005-07-22 19:11 UTC (permalink / raw) Cc: emacs-devel Juanma Barranquero wrote: > (These questions are mainly for Lars Hansen, who did most of the > recent cleanup work on desktop.el) I am just about to go to Greece on vacation, far away form e-mail. But I will be glad to use a bit of time to look into your questions (I bring a laptop). When I return in about 16 days, I will post an answer. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 19:11 ` Lars Hansen @ 2005-07-22 21:24 ` Juanma Barranquero 0 siblings, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-22 21:24 UTC (permalink / raw) Cc: emacs-devel On 7/22/05, Lars Hansen <larsh@soem.dk> wrote: > But I > will be glad to use a bit of time to look into your questions (I bring a > laptop). When I return in about 16 days, I will post an answer. Thanks, and happy holidays. /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 2:42 A few questions about desktop.el Juanma Barranquero ` (2 preceding siblings ...) 2005-07-22 19:11 ` Lars Hansen @ 2005-07-22 22:50 ` Richard M. Stallman 2005-07-26 9:11 ` Juanma Barranquero 2005-08-08 14:51 ` Lars Hansen 4 siblings, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-22 22:50 UTC (permalink / raw) Cc: emacs-devel It would be cleaner if this could be done with code in hilit-chg.el itself. However, making that possible would probably require another way to customize desktop.el. It would be useful to add a suitable mechanism to desktop.el that would make this possible in a clean way. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 22:50 ` Richard M. Stallman @ 2005-07-26 9:11 ` Juanma Barranquero 2005-07-27 14:04 ` Richard M. Stallman 0 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2005-07-26 9:11 UTC (permalink / raw) Cc: emacs-devel On 7/23/05, Richard M. Stallman <rms@gnu.org> wrote: > However, making that possible would probably require > another way to customize desktop.el. It would be useful to add > a suitable mechanism to desktop.el that would make this possible > in a clean way. I can add that mechanism, but I'm not sure it is worth it. There are a bunch of variables that other packages could possibly want to modify: desktop-globals-to-save desktop-globals-to-clear desktop-clear-preserve-buffers-regexp desktop-clear-preserve-buffers desktop-locals-to-save desktop-buffers-not-to-save desktop-files-not-to-save desktop-modes-not-to-save desktop-buffer-mode-handlers desktop-minor-mode-table and the various hooks. I see no clear pattern about what would other packages want to modify; *-locals-to-save and *-minor-mode-table are perhaps the most useful, but other than that everything's game. I don't see what do we gain by adding functions to manipulate these vars instead of doing it directly. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-26 9:11 ` Juanma Barranquero @ 2005-07-27 14:04 ` Richard M. Stallman 2005-07-27 14:16 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-27 14:04 UTC (permalink / raw) Cc: emacs-devel and the various hooks. I see no clear pattern about what would other packages want to modify; *-locals-to-save and *-minor-mode-table are perhaps the most useful, but other than that everything's game. How many minor modes could you take care of with just those two? ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:04 ` Richard M. Stallman @ 2005-07-27 14:16 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman 2005-08-10 9:50 ` Lars Hansen 0 siblings, 2 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-27 14:16 UTC (permalink / raw) Cc: emacs-devel On 7/27/05, Richard M. Stallman <rms@gnu.org> wrote: > How many minor modes could you take care of with just those two? Difficult to say without looking at each one, particularly because we're talking not of the "normal" minor modes, but the ones that do a minor-mode work in a non-conventional way: highlight-change, overwrite, indent-tabs... All in all, though, I suppose that most of them. But, as a datapoint, I recently added "*server*" directly to `desktop-clear-preserve-buffers-regexp' in desktop.el; now I see the clean way would be for server.el to add it (but that would require a redesign of a bit of desktop.el interface). [time passes...] You're gonna say "Then add a function to customize these two and we'll see whether we need to add anything more", aren't you? :) OK, I'll see what I can do. Anyway, I'd prefer not to make many changes to desktop.el (even quite non-intrusive changes like these) until Lars returns from holidays, as he said he would take a look at some questions I posed. I'll post a patch as soon as I've got it ready, and wait for him. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:16 ` Juanma Barranquero @ 2005-07-28 3:20 ` Richard M. Stallman 2005-07-29 0:44 ` Juanma Barranquero 2005-08-10 9:50 ` Lars Hansen 1 sibling, 1 reply; 72+ messages in thread From: Richard M. Stallman @ 2005-07-28 3:20 UTC (permalink / raw) Cc: emacs-devel > How many minor modes could you take care of with just those two? Difficult to say without looking at each one, particularly because we're talking not of the "normal" minor modes, but the ones that do a minor-mode work in a non-conventional way: highlight-change, overwrite, indent-tabs... How about if you start checking them. That is the only way to find out if these two variables would really improve the situation. You're gonna say "Then add a function to customize these two and we'll see whether we need to add anything more", aren't you? :) OK, I'll see what I can do. Not exactly. The first step is to see how much good this would do. Also, the customization mechanism for the minor modes to use does not have to be a function to call. It may be that an alist which major modes can add to would be cleaner. That's entirely a matter of details. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-28 3:20 ` Richard M. Stallman @ 2005-07-29 0:44 ` Juanma Barranquero 0 siblings, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-07-29 0:44 UTC (permalink / raw) Cc: emacs-devel On 7/28/05, Richard M. Stallman <rms@gnu.org> wrote: > How about if you start checking them. That is the only way to find > out if these two variables would really improve the situation. Yeah, I'll do that. > Also, the customization mechanism for the minor modes to use does not > have to be a function to call. It may be that an alist which major > modes can add to would be cleaner. In fact, the current "API", which is a list of lists and alists, is quite clean except for the variables that store regexps: `desktop-clear-preserve-buffers-regexp', `desktop-buffers-not-to-save', `desktop-files-not-to-save'. The easier way to customize these would be turning them into lists and adding functions to generate the regexps from the lists. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-27 14:16 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman @ 2005-08-10 9:50 ` Lars Hansen 2005-08-10 11:24 ` Juanma Barranquero 2005-08-10 22:05 ` Luc Teirlinck 1 sibling, 2 replies; 72+ messages in thread From: Lars Hansen @ 2005-08-10 9:50 UTC (permalink / raw) Cc: Richard Stallman, emacs-devel [-- Attachment #1: Type: text/plain, Size: 336 bytes --] Juanma Barranquero wrote: >Anyway, I'd prefer not to make many changes to desktop.el (even quite >non-intrusive changes like these) until Lars returns from holidays, as >he said he would take a look at some questions I posed. I'll post a >patch as soon as I've got it ready, and wait for him. > > Shall I install the attached patch? [-- Attachment #2: patch.diff --] [-- Type: text/x-patch, Size: 24358 bytes --] *** /home/lh/cvsroot/emacs/lisp/desktop.el.~1.90.~ 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/cvsroot/emacs/lisp/desktop.el 2005-08-10 11:38:08.519228192 +0200 *************** *** 51,63 **** ;; function is added to the `after-init-hook'. This function is ;; responsible for loading the desktop when Emacs is started. ! ;; Some words on minor modes: Most minor modes are controlled by ! ;; buffer-local variables, which have a standard save / restore ! ;; mechanism. To handle all minor modes, we take the following ! ;; approach: (1) check whether the variable name from ! ;; `minor-mode-alist' is also a function; and (2) use translation ! ;; table `desktop-minor-mode-table' in the case where the two names ! ;; are not the same. ;; By the way: don't use desktop.el to customize Emacs -- the file .emacs ;; in your home directory is used for that. Saving global default values --- 51,116 ---- ;; function is added to the `after-init-hook'. This function is ;; responsible for loading the desktop when Emacs is started. ! ;; Special handling. ! ;; ----------------- ! ;; Variables `desktop-buffer-mode-handlers' and `desktop-minor-mode-handlers' ! ;; are supplied to handle special major and minor modes respectively. ! ;; `desktop-buffer-mode-handlers' is an alist of major mode specific functions ! ;; to restore a desktop buffer. Elements must have the form ! ;; ! ;; (MAJOR-MODE . RESTORE-BUFFER-FUNCTION). ! ;; ! ;; Functions listed are called by `desktop-create-buffer' when `desktop-read' ! ;; evaluates the desktop file. Buffers with a major mode not specified here, ! ;; are restored by the default handler `desktop-restore-file-buffer'. ! ;; `desktop-minor-mode-handlers' is an alist of functions to restore ! ;; non-standard minor modes. Elements must have the form ! ;; ! ;; (MINOR-MODE . RESTORE-FUNCTION). ! ;; ! ;; Functions are called by `desktop-create-buffer' to restore minor modes. ! ;; Minor modes not specified here, are restored by the standard minor mode ! ;; function. If you write a module that defines a major or minor mode that ! ;; needs a special handler, then place code like ! ! ;; (defun foo-restore-desktop-buffer ! ;; ... ! ;; (add-to-list 'desktop-buffer-mode-handlers ! ;; '(foo-mode . foo-restore-desktop-buffer)) ! ! ;; or ! ! ;; (defun bar-desktop-restore ! ;; ... ! ;; (add-to-list 'desktop-minor-mode-handlers ! ;; '(bar-mode . bar-desktop-restore)) ! ! ;; in the module itself, and make shure that the mode function is ! ;; autoloaded. See the docstrings of `desktop-buffer-mode-handlers' and ! ;; `desktop-minor-mode-handlers' for more info. ! ! ;; Minor modes. ! ;; ------------ ! ;; Conventional minor modes (see node "Minor Mode Conventions" in the elisp ! ;; manual) are handled in the following way: ! ;; When `desktop-save' saves the state of a buffer to the desktop file, it ! ;; saves as `desktop-minor-modes' the list of names of those variables in ! ;; `minor-mode-alist' that have a non-nil value. ! ;; When `desktop-create' restores the buffer, each of the symbols in ! ;; `desktop-minor-modes' is called as function with parameter 1. ! ;; The variables `desktop-minor-mode-table' and `desktop-minor-mode-handlers' ! ;; are used to handle non-conventional minor modes. `desktop-save' uses ! ;; `desktop-minor-mode-table' to map minor mode variables to minor mode ! ;; functions before writing `desktop-minor-modes'. If a minor mode has a ! ;; variable name that is different form its function name, an entry ! ! ;; (NAME RESTORE-FUNCTION) ! ! ;; should be added to `desktop-minor-mode-table'. If a minor mode should not ! ;; be restored, RESTORE-FUNCTION should be set to nil. `desktop-create' uses ! ;; `desktop-minor-mode-handlers' to lookup minor modes that needs a restore ! ;; function different from the usual minor mode function. ! ;; --------------------------------------------------------------------------- ;; By the way: don't use desktop.el to customize Emacs -- the file .emacs ;; in your home directory is used for that. Saving global default values *************** *** 207,226 **** :group 'desktop :version "22.1") ! (defcustom desktop-clear-preserve-buffers-regexp ! "^\\(\\*scratch\\*\\|\\*Messages\\*\\|\\*server\\*\\|\\*tramp/.+\\*\\)$" ! "Regexp identifying buffers that `desktop-clear' should not delete. ! See also `desktop-clear-preserve-buffers'." ! :type 'regexp ! :group 'desktop ! :version "22.1") ! ! (defcustom desktop-clear-preserve-buffers nil ! "*List of buffer names that `desktop-clear' should not delete. ! See also `desktop-clear-preserve-buffers-regexp'." :type '(repeat string) :group 'desktop) (defcustom desktop-locals-to-save '(desktop-locals-to-save ; Itself! Think it over. truncate-lines --- 260,274 ---- :group 'desktop :version "22.1") ! (defcustom desktop-clear-preserve-buffers ! '("\\*scratch\\*" "\\*Messages\\*" "\\*server\\*" "\\*tramp/.+\\*") ! "*List of buffers that `desktop-clear' should not delete. ! Each element is a regular expression. Buffers with a name matched by any of ! these won't be deleted." :type '(repeat string) :group 'desktop) + ;;;###autoload (defcustom desktop-locals-to-save '(desktop-locals-to-save ; Itself! Think it over. truncate-lines *************** *** 230,241 **** overwrite-mode change-log-default-name line-number-mode ! buffer-file-coding-system) "List of local variables to save for each buffer. ! The variables are saved only when they really are local." :type '(repeat symbol) :group 'desktop) - (make-variable-buffer-local 'desktop-locals-to-save) ;; We skip .log files because they are normally temporary. ;; (ftp) files because they require passwords and whatnot. --- 278,295 ---- overwrite-mode change-log-default-name line-number-mode ! column-number-mode ! size-indication-mode ! buffer-file-coding-system ! indent-tabs-mode ! indicate-buffer-boundaries ! indicate-empty-lines ! show-trailing-whitespace) "List of local variables to save for each buffer. ! The variables are saved only when they really are local. Conventional minor ! modes are restored automatically; they should not be listed here." :type '(repeat symbol) :group 'desktop) ;; We skip .log files because they are normally temporary. ;; (ftp) files because they require passwords and whatnot. *************** *** 301,323 **** When file names are returned, they should be formatted using the call \"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\". ! Later, when `desktop-read' calls a function in `desktop-buffer-mode-handlers' ! to restore the buffer, the auxiliary information is passed as the argument ! DESKTOP-BUFFER-MISC.") (make-variable-buffer-local 'desktop-save-buffer) (make-obsolete-variable 'desktop-buffer-modes-to-save 'desktop-save-buffer "22.1") (make-obsolete-variable 'desktop-buffer-misc-functions 'desktop-save-buffer "22.1") ! (defcustom desktop-buffer-mode-handlers ! '((dired-mode . dired-restore-desktop-buffer) ! (rmail-mode . rmail-restore-desktop-buffer) ! (mh-folder-mode . mh-restore-desktop-buffer) ! (Info-mode . Info-restore-desktop-buffer)) "Alist of major mode specific functions to restore a desktop buffer. ! Functions are called by `desktop-read'. List elements must have the form ! \(MAJOR-MODE . RESTORE-BUFFER-FUNCTION). Buffers with a major mode not specified here, are restored by the default handler `desktop-restore-file-buffer'. --- 355,377 ---- When file names are returned, they should be formatted using the call \"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\". ! Later, when `desktop-read' evaluates the desktop file, auxiliary information ! is passed as the argument DESKTOP-BUFFER-MISC to functions in ! `desktop-buffer-mode-handlers'.") (make-variable-buffer-local 'desktop-save-buffer) (make-obsolete-variable 'desktop-buffer-modes-to-save 'desktop-save-buffer "22.1") (make-obsolete-variable 'desktop-buffer-misc-functions 'desktop-save-buffer "22.1") ! ;;;###autoload ! (defvar desktop-buffer-mode-handlers ! nil "Alist of major mode specific functions to restore a desktop buffer. ! Functions listed are called by `desktop-create-buffer' when `desktop-read' ! evaluates the desktop file. List elements must have the form ! ! (MAJOR-MODE . RESTORE-BUFFER-FUNCTION). Buffers with a major mode not specified here, are restored by the default handler `desktop-restore-file-buffer'. *************** *** 337,345 **** desktop-buffer-locals If a handler returns a buffer, then the saved mode settings ! and variable values for that buffer are copied into it." ! :type 'alist ! :group 'desktop) (put 'desktop-buffer-mode-handlers 'risky-local-variable t) (make-obsolete-variable 'desktop-buffer-handlers --- 391,407 ---- desktop-buffer-locals If a handler returns a buffer, then the saved mode settings ! and variable values for that buffer are copied into it. ! ! Modules that define a major mode that needs a special handler should contain ! code like ! ! (defun foo-restore-desktop-buffer ! ... ! (add-to-list 'desktop-buffer-mode-handlers ! '(foo-mode . foo-restore-desktop-buffer)) ! ! Furthermore the major mode function must be autoloaded.") (put 'desktop-buffer-mode-handlers 'risky-local-variable t) (make-obsolete-variable 'desktop-buffer-handlers *************** *** 355,364 **** called. RESTORE-FUNCTION nil means don't try to restore the minor mode. Only minor modes for which the name of the buffer-local variable and the name of the minor mode function are different have to be added to ! this table." :type 'sexp :group 'desktop) ;; ---------------------------------------------------------------------------- (defvar desktop-dirname nil "The directory in which the desktop file should be saved.") --- 417,472 ---- called. RESTORE-FUNCTION nil means don't try to restore the minor mode. Only minor modes for which the name of the buffer-local variable and the name of the minor mode function are different have to be added to ! this table. See also `desktop-minor-mode-handlers'." :type 'sexp :group 'desktop) + ;;;###autoload + (defvar desktop-minor-mode-handlers + nil + "Alist of functions to restore non-standard minor modes. + Functions are called by `desktop-create-buffer' to restore minor modes. + List elements must have the form + + (MINOR-MODE . RESTORE-FUNCTION). + + Minor modes not specified here, are restored by the standard minor mode + function. + + Handlers are called with argument list + + (DESKTOP-BUFFER-LOCALS) + + Furthermore, they may use the following variables: + + desktop-file-version + desktop-buffer-file-name + desktop-buffer-name + desktop-buffer-major-mode + desktop-buffer-minor-modes + desktop-buffer-point + desktop-buffer-mark + desktop-buffer-read-only + desktop-buffer-misc + + When a handler is called, the buffer has been created and the major mode has + been set, but local variables listed in desktop-buffer-locals has not yet been + created and set. + + Modules that define a minor mode that needs a special handler should contain + code like + + (defun foo-desktop-restore + ... + (add-to-list 'desktop-minor-mode-handlers + '(foo-mode . foo-desktop-restore)) + + Furthermore the minor mode function must be autoloaded. + + See also `desktop-minor-mode-table'.") + + (put 'desktop-minor-mode-handlers 'risky-local-variable t) + ;; ---------------------------------------------------------------------------- (defvar desktop-dirname nil "The directory in which the desktop file should be saved.") *************** *** 382,404 **** ;; ---------------------------------------------------------------------------- (defun desktop-clear () "Empty the Desktop. ! This kills all buffers except for internal ones and those matching ! `desktop-clear-preserve-buffers-regexp' or listed in ! `desktop-clear-preserve-buffers'. Furthermore, it clears the ! variables listed in `desktop-globals-to-clear'." (interactive) (desktop-lazy-abort) (dolist (var desktop-globals-to-clear) (if (symbolp var) (eval `(setq-default ,var nil)) (eval `(setq-default ,(car var) ,(cdr var))))) ! (let ((buffers (buffer-list))) (while buffers (let ((bufname (buffer-name (car buffers)))) (or (null bufname) ! (string-match desktop-clear-preserve-buffers-regexp bufname) ! (member bufname desktop-clear-preserve-buffers) ;; Don't kill buffers made for internal purposes. (and (not (equal bufname "")) (eq (aref bufname 0) ?\s)) (kill-buffer (car buffers)))) --- 490,516 ---- ;; ---------------------------------------------------------------------------- (defun desktop-clear () "Empty the Desktop. ! This kills all buffers except for internal ones and those with names matched by ! a regular expression in the list `desktop-clear-preserve-buffers'. ! Furthermore, it clears the variables listed in `desktop-globals-to-clear'." (interactive) (desktop-lazy-abort) (dolist (var desktop-globals-to-clear) (if (symbolp var) (eval `(setq-default ,var nil)) (eval `(setq-default ,(car var) ,(cdr var))))) ! (let ((buffers (buffer-list)) ! (preserve-regexp (concat "^\\(" ! (mapconcat (lambda (regexp) ! (concat "\\(" regexp "\\)")) ! desktop-clear-preserve-buffers ! "\\|") ! "\\)$"))) (while buffers (let ((bufname (buffer-name (car buffers)))) (or (null bufname) ! (string-match preserve-regexp bufname) ;; Don't kill buffers made for internal purposes. (and (not (equal bufname "")) (eq (aref bufname 0) ?\s)) (kill-buffer (car buffers)))) *************** *** 622,633 **** (and (boundp minor-mode) (symbol-value minor-mode) ! (let ((special (assq minor-mode desktop-minor-mode-table))) ! (when (or special (functionp minor-mode)) ! (setq ret ! (cons ! (if special (cadr special) minor-mode) ! ret)))))) (mapcar #'car minor-mode-alist)) ret) (point) --- 734,743 ---- (and (boundp minor-mode) (symbol-value minor-mode) ! (let* ((special (assq minor-mode desktop-minor-mode-table)) ! (value (cond (special (cadr special)) ! ((functionp minor-mode) minor-mode)))) ! (when value (add-to-list 'ret value))))) (mapcar #'car minor-mode-alist)) ret) (point) *************** *** 685,691 **** (insert ")\n\n"))) info) (setq default-directory dirname) - (when (file-exists-p filename) (delete-file filename)) (let ((coding-system-for-write 'emacs-mule)) (write-region (point-min) (point-max) filename nil 'nomessage)))) (setq desktop-dirname dirname)) --- 795,800 ---- *************** *** 850,862 **** buf) nil))) ;; ---------------------------------------------------------------------------- ;; Create a buffer, load its file, set its mode, ...; ;; called from Desktop file only. ! (eval-when-compile ; Just to silence the byte compiler ! (defvar desktop-first-buffer) ;; Dynamically bound in `desktop-read' ! ) (defun desktop-create-buffer (desktop-file-version --- 959,978 ---- buf) nil))) + (defun desktop-load-file (function) + "Load the file where auto loaded FUNCTION is defined." + (let ((fcell (symbol-function function))) + (when (and (listp fcell) + (eq 'autoload (car fcell))) + (load (cadr fcell))))) + ;; ---------------------------------------------------------------------------- ;; Create a buffer, load its file, set its mode, ...; ;; called from Desktop file only. ! ;; Just to silence the byte compiler. ! (eval-when-compile ! (defvar desktop-first-buffer)) ; Dynamically bound in `desktop-read' (defun desktop-create-buffer (desktop-file-version *************** *** 877,882 **** --- 993,1000 ---- ;; To make desktop files with relative file names possible, we cannot ;; allow `default-directory' to change. Therefore we save current buffer. (save-current-buffer + ;; Give major mode module a chance to add a handler. + (desktop-load-file desktop-buffer-major-mode) (let ((buffer-list (buffer-list)) (result (condition-case err *************** *** 914,922 **** (auto-fill-mode 0)) (t (mapc #'(lambda (minor-mode) ! (when (functionp minor-mode) (funcall minor-mode 1))) desktop-buffer-minor-modes))) ! ;; Even though point and mark are non-nil when written by `desktop-save' ;; they may be modified by handlers wanting to set point or mark themselves. (when desktop-buffer-point (goto-char --- 1032,1046 ---- (auto-fill-mode 0)) (t (mapc #'(lambda (minor-mode) ! ;; Give minor mode module a chance to add a handler. ! (desktop-load-file minor-mode) ! (let ((handler (cdr (assq minor-mode desktop-minor-mode-handlers)))) ! (if handler ! (funcall handler desktop-buffer-locals) ! (when (functionp minor-mode) ! (funcall minor-mode 1))))) desktop-buffer-minor-modes))) ! ;; Even though point and mark are non-nil when written by `desktop-save', ;; they may be modified by handlers wanting to set point or mark themselves. (when desktop-buffer-point (goto-char *** /home/lh/cvsroot/emacs/lisp/hilit-chg.el.~1.34.~ 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/cvsroot/emacs/lisp/hilit-chg.el 2005-08-09 08:17:02.000000000 +0200 *************** *** 673,678 **** --- 673,679 ---- (if new-highlight-changes-mode ;; mode is turned on -- but may be passive (progn + (add-to-list 'desktop-locals-to-save 'highlight-changes-mode) (hilit-chg-set new-highlight-changes-mode) (or was-on ;; run highlight-changes-enable-hook once *************** *** 1154,1159 **** --- 1155,1170 ---- ))) (buffer-list))) + ;;;; Desktop support. + + ;; Called by `desktop-create-buffer' to restore `highlight-changes-mode'. + (defun hilit-chg-desktop-restore (desktop-buffer-locals) + (highlight-changes-mode + (or (cdr (assq 'highlight-changes-mode desktop-buffer-locals)) 1))) + + (add-to-list 'desktop-minor-mode-handlers + '(highlight-changes-mode . hilit-chg-desktop-restore)) + ;; ===================== debug ================== ;; For debug & test use: ;; *** /home/lh/cvsroot/emacs/lisp/dired.el.~1.322.~ 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/cvsroot/emacs/lisp/dired.el 2005-08-09 08:16:24.000000000 +0200 *************** *** 1469,1474 **** --- 1469,1476 ---- ;; Dired mode is suitable only for specially formatted data. (put 'dired-mode 'mode-class 'special) + ;; Autoload cookie needed by desktop.el + ;;;###autoload (defun dired-mode (&optional dirname switches) "\ Mode for \"editing\" directory listings. *************** *** 3270,3276 **** (function (lambda (f) (desktop-file-name (car f) desktop-dirname))) dired-subdir-alist))))) - ;;;###autoload (defun dired-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 3272,3277 ---- *************** *** 3291,3296 **** --- 3292,3300 ---- (when desktop-missing-file-warning (sit-for 1)) nil))) + (add-to-list 'desktop-buffer-mode-handlers + '(dired-mode . dired-restore-desktop-buffer)) + \f (if (eq system-type 'vax-vms) (load "dired-vms")) *** /home/lh/cvsroot/emacs/lisp/info.el.~1.440.~ 2005-08-09 08:01:44.000000000 +0200 --- /home/lh/cvsroot/emacs/lisp/info.el 2005-08-09 08:17:47.000000000 +0200 *************** *** 3199,3204 **** --- 3199,3206 ---- (defvar tool-bar-map) + ;; Autoload cookie needed by desktop.el + ;;;###autoload (defun Info-mode () "Info mode provides commands for browsing through the Info documentation tree. Documentation in Info is divided into \"nodes\", each of which discusses *************** *** 4168,4174 **** (if (not (member Info-current-file '("apropos" "history" "toc"))) (list Info-current-file Info-current-node))) - ;;;###autoload (defun Info-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 4170,4175 ---- *************** *** 4182,4187 **** --- 4183,4191 ---- (Info-find-node first second) (current-buffer)))) + (add-to-list 'desktop-buffer-mode-handlers + '(Info-mode . Info-restore-desktop-buffer)) + (provide 'info) ;; arch-tag: f2480fe2-2139-40c1-a49b-6314991164ac *** /home/lh/cvsroot/emacs/lisp/mail/rmail.el.~1.407.~ 2005-08-08 14:15:19.000000000 +0200 --- /home/lh/cvsroot/emacs/lisp/mail/rmail.el 2005-08-09 08:19:09.000000000 +0200 *************** *** 4058,4064 **** ;;;; Desktop support - ;;;###autoload (defun rmail-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 4058,4063 ---- *************** *** 4073,4078 **** --- 4072,4080 ---- (kill-buffer (current-buffer)) nil))) + (add-to-list 'desktop-buffer-mode-handlers + '(rmail-mode . rmail-restore-desktop-buffer)) + (provide 'rmail) ;;; arch-tag: cff0a950-57fe-4f73-a86e-91ff75afd06c *** /home/lh/cvsroot/emacs/lisp/mh-e/mh-e.el.~1.20.~ 2005-07-12 15:25:36.000000000 +0200 --- /home/lh/cvsroot/emacs/lisp/mh-e/mh-e.el 2005-08-09 08:18:27.000000000 +0200 *************** *** 1507,1512 **** --- 1507,1514 ---- (not (member 'mh-folder-mode which-func-modes))) (push 'mh-folder-mode which-func-modes)) + ;; Autoload cookie needed by desktop.el + ;;;###autoload (define-derived-mode mh-folder-mode fundamental-mode "MH-Folder" "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map> *************** *** 1653,1659 **** (set (make-local-variable (car pairs)) (car (cdr pairs))) (setq pairs (cdr (cdr pairs))))) - ;;;###autoload (defun mh-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 1655,1660 ---- *************** *** 1666,1671 **** --- 1667,1675 ---- (mh-visit-folder desktop-buffer-name) (current-buffer)) + (add-to-list 'desktop-buffer-mode-handlers + '(mh-folder-mode . mh-restore-desktop-buffer)) + (defun mh-scan-folder (folder range &optional dont-exec-pending) "Scan the FOLDER over the RANGE. If the optional argument DONT-EXEC-PENDING is non-nil then pending deletes and [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-10 9:50 ` Lars Hansen @ 2005-08-10 11:24 ` Juanma Barranquero 2006-02-09 16:30 ` Juanma Barranquero 2005-08-10 22:05 ` Luc Teirlinck 1 sibling, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2005-08-10 11:24 UTC (permalink / raw) Cc: emacs-devel On 8/10/05, Lars Hansen <larsh@soem.dk> wrote: > Shall I install the attached patch? You got my vote. I've been testing it and everything seems to work, even the corner cases of `highlight-changes-mode'. BTW, another package that would benefit from special treatment is bs.el, in particular the variable `bs-buffer-show-mark'. I usually have documents loaded (like my TODO) that I mark as "never to be shown". On restoring the desktop they should stay so. Adding the variable to the locals-to-save list is easy enough, of course. The only (very minor) problem is, if the only buffer you have is marked as 'never, after restoring the desktop the file is shown. It should instead show the default *scratch*, I think. I'm not sure whether this can be fixed with a support function in bs, though. Properly speaking, bs is not a minor mode, and in fact the "*buffer-selection*" buffer is not being restored... -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-10 11:24 ` Juanma Barranquero @ 2006-02-09 16:30 ` Juanma Barranquero 2006-02-09 20:00 ` Lars Hansen 2006-02-09 21:11 ` Lars Hansen 0 siblings, 2 replies; 72+ messages in thread From: Juanma Barranquero @ 2006-02-09 16:30 UTC (permalink / raw) Cc: emacs-devel About seven months ago, I said: > You got my vote. I've been testing it and everything seems > to work, even the corner cases of `highlight-changes-mode'. Now, either I was mistaken then or something's changed in between, because h-c-m and desktop.el *do* have a problem. With a simple .emacs.el like this: ;--------- .emacs.el ----------- (setq desktop-save t) (desktop-save-mode 1) (setq highlight-changes-global-initial-state 'passive) (global-highlight-changes 'passive) ;------------------------------- The steps to reproduce the problem: - Start Emacs. - Load a file (for example, .emacs.el). => It is in "-Chg" mode, i.e., passive. - Exit Emacs. - Start Emacs. => .emacs.el is loaded, in "+Chg" mode (active) - M-x hilight-changes-mode RET => .emacs.el is in "-Chg" mode. - Exit Emacs. - Start Emacs. => .emacs.el is loaded, in "-Chg" mode (finally). -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-02-09 16:30 ` Juanma Barranquero @ 2006-02-09 20:00 ` Lars Hansen 2006-02-09 21:11 ` Lars Hansen 1 sibling, 0 replies; 72+ messages in thread From: Lars Hansen @ 2006-02-09 20:00 UTC (permalink / raw) Cc: emacs-devel I can reproduce the problem, I will try to debug it. >With a simple .emacs.el like this: > >;--------- .emacs.el ----------- >(setq desktop-save t) >(desktop-save-mode 1) >(setq highlight-changes-global-initial-state 'passive) >(global-highlight-changes 'passive) >;------------------------------- > >The steps to reproduce the problem: > > - Start Emacs. > - Load a file (for example, .emacs.el). => It is in "-Chg" mode, >i.e., passive. > - Exit Emacs. > - Start Emacs. => .emacs.el is loaded, in "+Chg" mode (active) > - M-x hilight-changes-mode RET => .emacs.el is in "-Chg" mode. > - Exit Emacs. > - Start Emacs. => .emacs.el is loaded, in "-Chg" mode (finally). > >-- > /L/e/k/t/u > > ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-02-09 16:30 ` Juanma Barranquero 2006-02-09 20:00 ` Lars Hansen @ 2006-02-09 21:11 ` Lars Hansen 2006-02-09 23:46 ` Juanma Barranquero 1 sibling, 1 reply; 72+ messages in thread From: Lars Hansen @ 2006-02-09 21:11 UTC (permalink / raw) Cc: emacs-devel >About seven months ago, I said: > > > >>You got my vote. I've been testing it and everything seems >>to work, even the corner cases of `highlight-changes-mode'. >> >> > >Now, either I was mistaken then or something's changed in between, >because h-c-m and desktop.el *do* have a problem. > >With a simple .emacs.el like this: > >;--------- .emacs.el ----------- >(setq desktop-save t) >(desktop-save-mode 1) >(setq highlight-changes-global-initial-state 'passive) >(global-highlight-changes 'passive) >;------------------------------- > >The steps to reproduce the problem: > > - Start Emacs. > - Load a file (for example, .emacs.el). => It is in "-Chg" mode, >i.e., passive. > - Exit Emacs. > - Start Emacs. => .emacs.el is loaded, in "+Chg" mode (active) > - M-x hilight-changes-mode RET => .emacs.el is in "-Chg" mode. > - Exit Emacs. > - Start Emacs. => .emacs.el is loaded, in "-Chg" mode (finally). > >-- > /L/e/k/t/u > > I believe the problem should be fixed by now. Here is the explanation: highlight-changes-mode must be added to desktop-locals-to-save in order to be saved in the desktop file. To do this I originally placed (add-to-list 'desktop-locals-to-save 'highlight-changes-mode) inside the function highlight-changes-mode. Therefore things worked when this function was called, but not when global-highlight-changes was called. Now I have moved the line out of highlight-changes-mode and placed it at top level so it is executed at load. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2006-02-09 21:11 ` Lars Hansen @ 2006-02-09 23:46 ` Juanma Barranquero 0 siblings, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2006-02-09 23:46 UTC (permalink / raw) Cc: emacs-devel On 2/9/06, Lars Hansen <larsh@soem.dk> wrote: > I believe the problem should be fixed by now. Yeah, seems to be working now. Thanks. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-10 9:50 ` Lars Hansen 2005-08-10 11:24 ` Juanma Barranquero @ 2005-08-10 22:05 ` Luc Teirlinck 2005-08-10 23:45 ` Luc Teirlinck 1 sibling, 1 reply; 72+ messages in thread From: Luc Teirlinck @ 2005-08-10 22:05 UTC (permalink / raw) Cc: lekktu, rms, emacs-devel Lars Hansen wrote: Shall I install the attached patch? The installed changes apparently break bootstrapping: Compiling /home/teirllm/emacscvsdir/emacs/lisp/./dired-x.el In toplevel form: dired-x.el:106:1:Error: Symbol's value as variable is void: desktop-buffer-mode-handlers make[1]: *** [compile] Error 1 make[1]: Leaving directory `/home/teirllm/emacscvsdir/emacs/lisp' make: *** [bootstrap-build] Error 2 This after: make maintainer-clean ./configure --without-toolkit-scroll-bars make bootstrap sudo make install ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-10 22:05 ` Luc Teirlinck @ 2005-08-10 23:45 ` Luc Teirlinck 2005-08-11 1:12 ` Luc Teirlinck 0 siblings, 1 reply; 72+ messages in thread From: Luc Teirlinck @ 2005-08-10 23:45 UTC (permalink / raw) Cc: larsh, lekktu, rms The trouble during bootstrapping seems to involve the relationship between loaddefs.el and ldefs-boot, "explained" (sort of) in lisp/Makefile.in: # Prepare a bootstrap in the lisp subdirectory. # # Build loaddefs.el to make sure it's up-to-date. If it's not, that # might lead to errors during the bootstrap because something fails to # autoload as expected. If there is no emacs binary, then we can't # build autoloads yet. In that case we have to use ldefs-boot.el; # bootstrap should always work with ldefs-boot.el. (Because # loaddefs.el is an automatically generated file, we don't want to # store it in the source repository). But ldefs-boot.el claims to be automatically generated too and it appears to be stored in the source repository. desktop-buffer-mode-handlers has a (new) autoload cookie. That makes it into loaddefs.el, but not into ldefs-boot.el, which is apparently necessary for bootstrapping. I can make bootstrapping work by manually copying the defvar for desktop-buffer-mode-handlers from loaddefs to ldefs-boot. I could install this "fix". However, this does not seem to be the right thing to do, since ldefs-boot apparently is supposed to contain _automatically_ extracted autoloads. What is the right thing to do? Sincerely, Luc. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-10 23:45 ` Luc Teirlinck @ 2005-08-11 1:12 ` Luc Teirlinck 2005-08-11 1:36 ` Luc Teirlinck 2005-08-11 3:01 ` Luc Teirlinck 0 siblings, 2 replies; 72+ messages in thread From: Luc Teirlinck @ 2005-08-11 1:12 UTC (permalink / raw) Cc: larsh, lekktu, rms, emacs-devel I figured out from the archives that the solution is to copy a good loaddefs over it. I will do that, after checking that my version of loaddefs is not corrupted with local stuff. Sincerely, Luc. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-11 1:12 ` Luc Teirlinck @ 2005-08-11 1:36 ` Luc Teirlinck 2005-08-11 3:01 ` Luc Teirlinck 1 sibling, 0 replies; 72+ messages in thread From: Luc Teirlinck @ 2005-08-11 1:36 UTC (permalink / raw) Cc: larsh, lekktu, rms >From my previous message: I figured out from the archives that the solution is to copy a good loaddefs over it. I meant: copy a good copy of loaddefs.el over ldefs-boot.el. Sincerely, Luc. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-11 1:12 ` Luc Teirlinck 2005-08-11 1:36 ` Luc Teirlinck @ 2005-08-11 3:01 ` Luc Teirlinck 2005-08-11 6:12 ` Lars Hansen 1 sibling, 1 reply; 72+ messages in thread From: Luc Teirlinck @ 2005-08-11 3:01 UTC (permalink / raw) Cc: larsh, lekktu, rms >From my previous message: I meant: copy a good copy of loaddefs.el over ldefs-boot.el. I have done that and checked that bootstrapping now works OK. Sincerely, Luc. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-11 3:01 ` Luc Teirlinck @ 2005-08-11 6:12 ` Lars Hansen 0 siblings, 0 replies; 72+ messages in thread From: Lars Hansen @ 2005-08-11 6:12 UTC (permalink / raw) Cc: lekktu, rms, emacs-devel Luc Teirlinck wrote: > I have done that and checked that bootstrapping now works OK. Thanks ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-07-22 2:42 A few questions about desktop.el Juanma Barranquero ` (3 preceding siblings ...) 2005-07-22 22:50 ` Richard M. Stallman @ 2005-08-08 14:51 ` Lars Hansen 2005-08-08 18:35 ` Juanma Barranquero 4 siblings, 1 reply; 72+ messages in thread From: Lars Hansen @ 2005-08-08 14:51 UTC (permalink / raw) Cc: Richard Stallman, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1728 bytes --] Juanma Barranquero wrote: >I'm having a few problems with highlight-changes-mode, which is a >not-very-standard minor mode. > > Yes, the desktop module expects minor modes to follow the conventions. The only mechanism to deal with non-conventional minor modes is `desktop-minor-mode-table' that allows the minor mode variable and minor mode function to have different names. To restore highlight changes mode, the function `highlight-changes-mode' needs to be called with the value of `highlight-changes-mode' to get the correct "sub-mode". So what is needed is something like `desktop-buffer-mode-handlers', but for minor modes. I suggest the patch below. It allows modules defining minor modes to define their own restore function without having to change the desktop module. >The other question is: why does `desktop-save' save `nil' for active >minor-modes which do appear in `desktop-minor-mode-table' as >non-restorable? > > I don't think there is any good reason. The patch below includes your suggested change (the second one). Now I have a question: To allow modules defining major or minor modes to add a special handler to `desktop-buffer-mode-handlers' or `desktop-minor-mode-handlers', the module in question must be loaded before the major or minor mode function is called. To do that, the patch below defines the following function: (defun desktop-load-file (function) "Load the file where auto loaded FUNCTION is defined." (let ((fcell (symbol-function function))) (when (and (listp fcell) (eq 'autoload (car fcell))) (load (cadr fcell))))) This function assumes that the mode function is autoloaded. Is this requirement ok? Is there a better solution? [-- Attachment #2: patch.diff --] [-- Type: text/x-patch, Size: 20725 bytes --] *** /home/lh/cvsroot/emacs/lisp/desktop.el 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/emacs/LH-work/desktop/new.desktop.el 2005-08-08 16:27:09.416541856 +0200 *************** *** 51,63 **** ;; function is added to the `after-init-hook'. This function is ;; responsible for loading the desktop when Emacs is started. ! ;; Some words on minor modes: Most minor modes are controlled by ! ;; buffer-local variables, which have a standard save / restore ! ;; mechanism. To handle all minor modes, we take the following ! ;; approach: (1) check whether the variable name from ! ;; `minor-mode-alist' is also a function; and (2) use translation ! ;; table `desktop-minor-mode-table' in the case where the two names ! ;; are not the same. ;; By the way: don't use desktop.el to customize Emacs -- the file .emacs ;; in your home directory is used for that. Saving global default values --- 51,116 ---- ;; function is added to the `after-init-hook'. This function is ;; responsible for loading the desktop when Emacs is started. ! ;; Special handling. ! ;; ----------------- ! ;; Variables `desktop-buffer-mode-handlers' and `desktop-minor-mode-handlers' ! ;; are supplied to handle special major and minor modes respectively. ! ;; `desktop-buffer-mode-handlers' is an alist of major mode specific functions ! ;; to restore a desktop buffer. Elements must have the form ! ;; ! ;; (MAJOR-MODE . RESTORE-BUFFER-FUNCTION). ! ;; ! ;; Functions listed are called by `desktop-create-buffer' when `desktop-read' ! ;; evaluates the desktop file. Buffers with a major mode not specified here, ! ;; are restored by the default handler `desktop-restore-file-buffer'. ! ;; `desktop-minor-mode-handlers' is an alist of functions to restore ! ;; non-standard minor modes. Elements must have the form ! ;; ! ;; (MINOR-MODE . RESTORE-FUNCTION). ! ;; ! ;; Functions are called by `desktop-create-buffer' to restore minor modes. ! ;; Minor modes not specified here, are restored by the standard minor mode ! ;; function. If you write a module that defines a major or minor mode that ! ;; needs a special handler, then place code like ! ! ;; (defun foo-restore-desktop-buffer ! ;; ... ! ;; (add-to-list 'desktop-buffer-mode-handlers ! ;; '(foo-mode . foo-restore-desktop-buffer)) ! ! ;; or ! ! ;; (defun bar-desktop-restore ! ;; ... ! ;; (add-to-list 'desktop-minor-mode-handlers ! ;; '(bar-mode . bar-desktop-restore)) ! ! ;; in the module itself, and make shure that the mode function is ! ;; autoloaded. See the docstrings of `desktop-buffer-mode-handlers' and ! ;; `desktop-minor-mode-handlers' for more info. ! ! ;; Minor modes. ! ;; ------------ ! ;; Conventional minor modes (see node "Minor Mode Conventions" in the elisp ! ;; manual) are handled in the following way: ! ;; When `desktop-save' saves the state of a buffer to the desktop file, it ! ;; saves as `desktop-minor-modes' the list of names of those variables in ! ;; `minor-mode-alist' that have a non-nil value. ! ;; When `desktop-create' restores the buffer, each of the symbols in ! ;; `desktop-minor-modes' is called as function with parameter 1. ! ;; The variables `desktop-minor-mode-table' and `desktop-minor-mode-handlers' ! ;; are used to handle non-conventional minor modes. `desktop-save' uses ! ;; `desktop-minor-mode-table' to map minor mode variables to minor mode ! ;; functions before writing `desktop-minor-modes'. If a minor mode has a ! ;; variable name that is different form its function name, an entry ! ! ;; (NAME RESTORE-FUNCTION) ! ! ;; should be added to `desktop-minor-mode-table'. If a minor mode should not ! ;; be restored, RESTORE-FUNCTION should be set to nil. `desktop-create' uses ! ;; `desktop-minor-mode-handlers' to lookup minor modes that needs a restore ! ;; function different from the usual minor mode function. ! ;; --------------------------------------------------------------------------- ;; By the way: don't use desktop.el to customize Emacs -- the file .emacs ;; in your home directory is used for that. Saving global default values *************** *** 221,226 **** --- 274,280 ---- :type '(repeat string) :group 'desktop) + ;;;###autoload (defcustom desktop-locals-to-save '(desktop-locals-to-save ; Itself! Think it over. truncate-lines *************** *** 230,238 **** overwrite-mode change-log-default-name line-number-mode ! buffer-file-coding-system) "List of local variables to save for each buffer. ! The variables are saved only when they really are local." :type '(repeat symbol) :group 'desktop) (make-variable-buffer-local 'desktop-locals-to-save) --- 284,299 ---- overwrite-mode change-log-default-name line-number-mode ! column-number-mode ! size-indication-mode ! buffer-file-coding-system ! indent-tabs-mode ! indicate-buffer-boundaries ! indicate-empty-lines ! show-trailing-whitespace) "List of local variables to save for each buffer. ! The variables are saved only when they really are local. Conventional minor ! modes are restored automatically; they should not be listed here." :type '(repeat symbol) :group 'desktop) (make-variable-buffer-local 'desktop-locals-to-save) *************** *** 301,323 **** When file names are returned, they should be formatted using the call \"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\". ! Later, when `desktop-read' calls a function in `desktop-buffer-mode-handlers' ! to restore the buffer, the auxiliary information is passed as the argument ! DESKTOP-BUFFER-MISC.") (make-variable-buffer-local 'desktop-save-buffer) (make-obsolete-variable 'desktop-buffer-modes-to-save 'desktop-save-buffer "22.1") (make-obsolete-variable 'desktop-buffer-misc-functions 'desktop-save-buffer "22.1") ! (defcustom desktop-buffer-mode-handlers ! '((dired-mode . dired-restore-desktop-buffer) ! (rmail-mode . rmail-restore-desktop-buffer) ! (mh-folder-mode . mh-restore-desktop-buffer) ! (Info-mode . Info-restore-desktop-buffer)) "Alist of major mode specific functions to restore a desktop buffer. ! Functions are called by `desktop-read'. List elements must have the form ! \(MAJOR-MODE . RESTORE-BUFFER-FUNCTION). Buffers with a major mode not specified here, are restored by the default handler `desktop-restore-file-buffer'. --- 362,384 ---- When file names are returned, they should be formatted using the call \"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\". ! Later, when `desktop-read' evaluates the desktop file, auxiliary information ! is passed as the argument DESKTOP-BUFFER-MISC to functions in ! `desktop-buffer-mode-handlers'.") (make-variable-buffer-local 'desktop-save-buffer) (make-obsolete-variable 'desktop-buffer-modes-to-save 'desktop-save-buffer "22.1") (make-obsolete-variable 'desktop-buffer-misc-functions 'desktop-save-buffer "22.1") ! ;;;###autoload ! (defvar desktop-buffer-mode-handlers ! nil "Alist of major mode specific functions to restore a desktop buffer. ! Functions listed are called by `desktop-create-buffer' when `desktop-read' ! evaluates the desktop file. List elements must have the form ! ! (MAJOR-MODE . RESTORE-BUFFER-FUNCTION). Buffers with a major mode not specified here, are restored by the default handler `desktop-restore-file-buffer'. *************** *** 337,345 **** desktop-buffer-locals If a handler returns a buffer, then the saved mode settings ! and variable values for that buffer are copied into it." ! :type 'alist ! :group 'desktop) (put 'desktop-buffer-mode-handlers 'risky-local-variable t) (make-obsolete-variable 'desktop-buffer-handlers --- 398,414 ---- desktop-buffer-locals If a handler returns a buffer, then the saved mode settings ! and variable values for that buffer are copied into it. ! ! Modules that define a major mode that needs a special handler should contain ! code like ! ! (defun foo-restore-desktop-buffer ! ... ! (add-to-list 'desktop-buffer-mode-handlers ! '(foo-mode . foo-restore-desktop-buffer)) ! ! Furthermore the major mode function must be autoloaded.") (put 'desktop-buffer-mode-handlers 'risky-local-variable t) (make-obsolete-variable 'desktop-buffer-handlers *************** *** 355,364 **** called. RESTORE-FUNCTION nil means don't try to restore the minor mode. Only minor modes for which the name of the buffer-local variable and the name of the minor mode function are different have to be added to ! this table." :type 'sexp :group 'desktop) ;; ---------------------------------------------------------------------------- (defvar desktop-dirname nil "The directory in which the desktop file should be saved.") --- 424,479 ---- called. RESTORE-FUNCTION nil means don't try to restore the minor mode. Only minor modes for which the name of the buffer-local variable and the name of the minor mode function are different have to be added to ! this table. See also `desktop-minor-mode-handlers'." :type 'sexp :group 'desktop) + ;;;###autoload + (defvar desktop-minor-mode-handlers + nil + "Alist of functions to restore non-standard minor modes. + Functions are called by `desktop-create-buffer' to restore minor modes. + List elements must have the form + + (MINOR-MODE . RESTORE-FUNCTION). + + Minor modes not specified here, are restored by the standard minor mode + function. + + Handlers are called with argument list + + (DESKTOP-BUFFER-LOCALS) + + Furthermore, they may use the following variables: + + desktop-file-version + desktop-buffer-file-name + desktop-buffer-name + desktop-buffer-major-mode + desktop-buffer-minor-modes + desktop-buffer-point + desktop-buffer-mark + desktop-buffer-read-only + desktop-buffer-misc + + When a handler is called, the buffer has been created and the major mode has + been set, but local variables listed in desktop-buffer-locals has not yet been + created and set. + + Modules that define a minor mode that needs a special handler should contain + code like + + (defun foo-desktop-restore + ... + (add-to-list 'desktop-minor-mode-handlers + '(foo-mode . foo-desktop-restore)) + + Furthermore the minor mode function must be autoloaded. + + See also `desktop-minor-mode-table'.") + + (put 'desktop-minor-mode-handlers 'risky-local-variable t) + ;; ---------------------------------------------------------------------------- (defvar desktop-dirname nil "The directory in which the desktop file should be saved.") *************** *** 622,633 **** (and (boundp minor-mode) (symbol-value minor-mode) ! (let ((special (assq minor-mode desktop-minor-mode-table))) ! (when (or special (functionp minor-mode)) ! (setq ret ! (cons ! (if special (cadr special) minor-mode) ! ret)))))) (mapcar #'car minor-mode-alist)) ret) (point) --- 737,746 ---- (and (boundp minor-mode) (symbol-value minor-mode) ! (let* ((special (assq minor-mode desktop-minor-mode-table)) ! (value (cond (special (cadr special)) ! ((functionp minor-mode) minor-mode)))) ! (when value (add-to-list 'ret value))))) (mapcar #'car minor-mode-alist)) ret) (point) *************** *** 685,691 **** (insert ")\n\n"))) info) (setq default-directory dirname) - (when (file-exists-p filename) (delete-file filename)) (let ((coding-system-for-write 'emacs-mule)) (write-region (point-min) (point-max) filename nil 'nomessage)))) (setq desktop-dirname dirname)) --- 798,803 ---- *************** *** 850,862 **** buf) nil))) ;; ---------------------------------------------------------------------------- ;; Create a buffer, load its file, set its mode, ...; ;; called from Desktop file only. ! (eval-when-compile ; Just to silence the byte compiler ! (defvar desktop-first-buffer) ;; Dynamically bound in `desktop-read' ! ) (defun desktop-create-buffer (desktop-file-version --- 962,981 ---- buf) nil))) + (defun desktop-load-file (function) + "Load the file where auto loaded FUNCTION is defined." + (let ((fcell (symbol-function function))) + (when (and (listp fcell) + (eq 'autoload (car fcell))) + (load (cadr fcell))))) + ;; ---------------------------------------------------------------------------- ;; Create a buffer, load its file, set its mode, ...; ;; called from Desktop file only. ! ;; Just to silence the byte compiler. ! (eval-when-compile ! (defvar desktop-first-buffer)) ; Dynamically bound in `desktop-read' (defun desktop-create-buffer (desktop-file-version *************** *** 877,882 **** --- 996,1003 ---- ;; To make desktop files with relative file names possible, we cannot ;; allow `default-directory' to change. Therefore we save current buffer. (save-current-buffer + ;; Give major mode module a chance to add a handler. + (desktop-load-file desktop-buffer-major-mode) (let ((buffer-list (buffer-list)) (result (condition-case err *************** *** 914,922 **** (auto-fill-mode 0)) (t (mapc #'(lambda (minor-mode) ! (when (functionp minor-mode) (funcall minor-mode 1))) desktop-buffer-minor-modes))) ! ;; Even though point and mark are non-nil when written by `desktop-save' ;; they may be modified by handlers wanting to set point or mark themselves. (when desktop-buffer-point (goto-char --- 1035,1049 ---- (auto-fill-mode 0)) (t (mapc #'(lambda (minor-mode) ! ;; Give minor mode module a chance to add a handler. ! (desktop-load-file minor-mode) ! (let ((handler (cdr (assq minor-mode desktop-minor-mode-handlers)))) ! (if handler ! (funcall handler desktop-buffer-locals) ! (when (functionp minor-mode) ! (funcall minor-mode 1))))) desktop-buffer-minor-modes))) ! ;; Even though point and mark are non-nil when written by `desktop-save', ;; they may be modified by handlers wanting to set point or mark themselves. (when desktop-buffer-point (goto-char *** /home/lh/cvsroot/emacs/lisp/hilit-chg.el 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/emacs/LH-work/desktop/new.hilit-chg.el 2005-08-08 16:27:55.003611568 +0200 *************** *** 673,678 **** --- 673,679 ---- (if new-highlight-changes-mode ;; mode is turned on -- but may be passive (progn + (add-to-list 'desktop-locals-to-save 'highlight-changes-mode) (hilit-chg-set new-highlight-changes-mode) (or was-on ;; run highlight-changes-enable-hook once *************** *** 1154,1159 **** --- 1155,1170 ---- ))) (buffer-list))) + ;;;; Desktop support. + + ;; Called by `desktop-create-buffer' to restore `highlight-changes-mode'. + (defun hilit-chg-desktop-restore (desktop-buffer-locals) + (highlight-changes-mode + (or (cdr (assq 'highlight-changes-mode desktop-buffer-locals)) 1))) + + (add-to-list 'desktop-minor-mode-handlers + '(highlight-changes-mode . hilit-chg-desktop-restore)) + ;; ===================== debug ================== ;; For debug & test use: ;; *** /home/lh/cvsroot/emacs/lisp/dired.el 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/emacs/LH-work/desktop/new.dired.el 2005-08-08 16:28:28.824470016 +0200 *************** *** 1469,1474 **** --- 1469,1476 ---- ;; Dired mode is suitable only for specially formatted data. (put 'dired-mode 'mode-class 'special) + ;; Autoload cookie needed by desktop.el + ;;;###autoload (defun dired-mode (&optional dirname switches) "\ Mode for \"editing\" directory listings. *************** *** 3270,3276 **** (function (lambda (f) (desktop-file-name (car f) desktop-dirname))) dired-subdir-alist))))) - ;;;###autoload (defun dired-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 3272,3277 ---- *************** *** 3291,3296 **** --- 3292,3300 ---- (when desktop-missing-file-warning (sit-for 1)) nil))) + (add-to-list 'desktop-buffer-mode-handlers + '(dired-mode . dired-restore-desktop-buffer)) + \f (if (eq system-type 'vax-vms) (load "dired-vms")) *** /home/lh/cvsroot/emacs/lisp/info.el 2005-08-08 14:15:26.000000000 +0200 --- /home/lh/emacs/LH-work/desktop/new.info.el 2005-08-08 16:29:18.743881112 +0200 *************** *** 3199,3204 **** --- 3199,3206 ---- (defvar tool-bar-map) + ;; Autoload cookie needed by desktop.el + ;;;###autoload (defun Info-mode () "Info mode provides commands for browsing through the Info documentation tree. Documentation in Info is divided into \"nodes\", each of which discusses *************** *** 4168,4174 **** (if (not (member Info-current-file '("apropos" "history" "toc"))) (list Info-current-file Info-current-node))) - ;;;###autoload (defun Info-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 4170,4175 ---- *************** *** 4182,4187 **** --- 4183,4191 ---- (Info-find-node first second) (current-buffer)))) + (add-to-list 'desktop-buffer-mode-handlers + '(Info-mode . Info-restore-desktop-buffer)) + (provide 'info) ;; arch-tag: f2480fe2-2139-40c1-a49b-6314991164ac *** /home/lh/cvsroot/emacs/lisp/mail/rmail.el 2005-08-08 14:15:19.000000000 +0200 --- /home/lh/emacs/LH-work/desktop/new.rmail.el 2005-08-08 16:30:28.313304952 +0200 *************** *** 4058,4064 **** ;;;; Desktop support - ;;;###autoload (defun rmail-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 4058,4063 ---- *************** *** 4073,4078 **** --- 4072,4080 ---- (kill-buffer (current-buffer)) nil))) + (add-to-list 'desktop-buffer-mode-handlers + '(rmail-mode . rmail-restore-desktop-buffer)) + (provide 'rmail) ;;; arch-tag: cff0a950-57fe-4f73-a86e-91ff75afd06c *** /home/lh/cvsroot/emacs/lisp/mh-e/mh-e.el 2005-07-12 15:25:36.000000000 +0200 --- /home/lh/emacs/LH-work/desktop/new.mh-e.el 2005-08-06 07:26:37.000000000 +0200 *************** *** 1507,1512 **** --- 1507,1514 ---- (not (member 'mh-folder-mode which-func-modes))) (push 'mh-folder-mode which-func-modes)) + ;; Autoload cookie needed by desktop.el + ;;;###autoload (define-derived-mode mh-folder-mode fundamental-mode "MH-Folder" "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map> *************** *** 1653,1659 **** (set (make-local-variable (car pairs)) (car (cdr pairs))) (setq pairs (cdr (cdr pairs))))) - ;;;###autoload (defun mh-restore-desktop-buffer (desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) --- 1655,1660 ---- *************** *** 1666,1671 **** --- 1667,1675 ---- (mh-visit-folder desktop-buffer-name) (current-buffer)) + (add-to-list 'desktop-buffer-mode-handlers + '(mh-folder-mode . mh-restore-desktop-buffer)) + (defun mh-scan-folder (folder range &optional dont-exec-pending) "Scan the FOLDER over the RANGE. If the optional argument DONT-EXEC-PENDING is non-nil then pending deletes and [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-08 14:51 ` Lars Hansen @ 2005-08-08 18:35 ` Juanma Barranquero 2005-08-09 7:12 ` Lars Hansen 0 siblings, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2005-08-08 18:35 UTC (permalink / raw) Cc: Richard Stallman, emacs-devel On 8/8/05, Lars Hansen <larsh@soem.dk> wrote: > I don't think there is any good reason. The patch below includes your > suggested change In general I like your patch. A few more questions, though. - Why is desktop-locals-to-save automatically buffer local? I can understand why should it be buffer-local, but automatically? I'd think that most users/modes are simply going to add to the default value of the variable. Or am I missing something? - Why is necessary to have `desktop-clear-preserve-buffers-regexp' and `desktop-clear-preserve-buffers'? The first one cannot be modified programmatically (there's no general way to automatically modify the regexp), so modes trying to extend the list of preservable buffers will have to add to `desktop-clear-preserve-buffers', which does not accept regexps. I think it would be better to have just one list (accepting regexps) and then combine them into a single regexp on demand. - You say: > This function assumes that the mode function is autoloaded. Is this > requirement ok? Is there a better solution? Wouldn't suffice to add the requeriment that when a mode wants to add to `desktop-*-mode-handlers', the added function *must* be autoloaded? -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-08 18:35 ` Juanma Barranquero @ 2005-08-09 7:12 ` Lars Hansen 2005-08-09 7:36 ` Lars Hansen 2005-08-09 8:49 ` Juanma Barranquero 0 siblings, 2 replies; 72+ messages in thread From: Lars Hansen @ 2005-08-09 7:12 UTC (permalink / raw) Cc: Richard Stallman, emacs-devel Juanma Barranquero wrote: > - Why is desktop-locals-to-save automatically buffer local? I can >understand why should it be buffer-local, but automatically? I'd think >that most users/modes are simply going to add to the default value of >the variable. Or am I missing something? > > I guess it does not have to be automatically buffer local. But I am not shure what the advantages/disadvantages of either choice are. >I think it would be better to have just one list >(accepting regexps) and then combine them into a single regexp on >demand. > > I agree. I will change that. >Wouldn't suffice to add the requeriment that when a mode wants to add >to `desktop-*-mode-handlers', the added function *must* be autoloaded? > > No. Desktop does not know that there *is* a handler since it may not have been added to `desktop-*-mode-handlers' yet. My motive is to make desktop as independent of other modules as possible. I want it to be possible to add or change module foo without having to change desktop, even if foo requires special desktop handling. Therefore I want foo to not only define its own desktop handler, but to add it to the variable `desktop-*-mode-handlers' as well. But then desktop has to load foo before checking for a handler. But how can desktop find out what file to load? It knows the name of the mode (major or minor), so if the mode function is autoloaded, it can find the file name that way. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-09 7:12 ` Lars Hansen @ 2005-08-09 7:36 ` Lars Hansen 2005-08-09 8:49 ` Juanma Barranquero 1 sibling, 0 replies; 72+ messages in thread From: Lars Hansen @ 2005-08-09 7:36 UTC (permalink / raw) Cc: Richard Stallman, emacs-devel I wrote: >I agree. I will change that. > > Now I remember that I added `desktop-clear-preserve-buffers-regexp' to obtain backwards compatibility. If `desktop-clear-preserve-buffers' is changed to accept regexps, strings like "*Messages*" get another meaning, so they must be changed. But it's messy with those two variable, so I still think it should be changed. I guess the compatibility issue is minor. ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-09 7:12 ` Lars Hansen 2005-08-09 7:36 ` Lars Hansen @ 2005-08-09 8:49 ` Juanma Barranquero 2005-08-09 9:31 ` David Kastrup 1 sibling, 1 reply; 72+ messages in thread From: Juanma Barranquero @ 2005-08-09 8:49 UTC (permalink / raw) Cc: emacs-devel On 8/9/05, Lars Hansen <larsh@soem.dk> wrote: > I guess it does not have to be automatically buffer local. But I am not > shure what the advantages/disadvantages of either choice are. Well, the reason `make-local-variable' and `make-variable-buffer-local' both exists is, I think, that in some circumstances the default value of the variable is gonna weight more than local changes (i.e, the local changes are going to be few and far between), and in other cases the variable is going to have frequent buffer-local modifications. Using the latter style when the former works is not "bad", but it's a bit wasteful. In this case, I think the former case is much more frequent; the user, or the mode programmer, can always use `make-local-variable' to force their way when a really local value is needed. > My motive is to make desktop as independent of other modules as > possible. I want it to be possible to add or change module foo without > having to change desktop, even if foo requires special desktop handling. Yes, that's a worthwhile goal. > But how can > desktop find out what file to load? It knows the name of the mode (major > or minor), so if the mode function is autoloaded, it can find the file > name that way. OK, I see now. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-09 8:49 ` Juanma Barranquero @ 2005-08-09 9:31 ` David Kastrup 2005-08-09 9:59 ` Juanma Barranquero 0 siblings, 1 reply; 72+ messages in thread From: David Kastrup @ 2005-08-09 9:31 UTC (permalink / raw) Cc: Lars Hansen, emacs-devel Juanma Barranquero <lekktu@gmail.com> writes: > On 8/9/05, Lars Hansen <larsh@soem.dk> wrote: > >> I guess it does not have to be automatically buffer local. But I am >> not shure what the advantages/disadvantages of either choice are. > > Well, the reason `make-local-variable' and > `make-variable-buffer-local' both exists is, I think, that in some > circumstances the default value of the variable is gonna weight more > than local changes (i.e, the local changes are going to be few and far > between), and in other cases the variable is going to have frequent > buffer-local modifications. Using the latter style when the former > works is not "bad", but it's a bit wasteful. I tend to use make-variable-buffer-local when a variable is tracking some state of a buffer, such that it would always be an error if two buffers shared such a variable. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: A few questions about desktop.el 2005-08-09 9:31 ` David Kastrup @ 2005-08-09 9:59 ` Juanma Barranquero 0 siblings, 0 replies; 72+ messages in thread From: Juanma Barranquero @ 2005-08-09 9:59 UTC (permalink / raw) Cc: Lars Hansen, emacs-devel On 8/9/05, David Kastrup <dak@gnu.org> wrote: > I tend to use make-variable-buffer-local when a variable is tracking > some state of a buffer, such that it would always be an error if two > buffers shared such a variable. Sure. For example, any variable that tracks something related to external characteristics of the buffer (or the buffer's associated file, if any) must usually be automatically buffer-local. In the case at hand, I think most buffers will want the same `desktop-locals-to-save'. I can imagine buffer X in mode M wanting to save its value of LOCAL-VAR-1, and buffer Y also in mode M wanting to save its own LOCAL-VAR-1, but it will be less frequent for buffer X to want to save LOCAL-VAR-1 and for buffer Y *not* wanting to save it. -- /L/e/k/t/u ^ permalink raw reply [flat|nested] 72+ messages in thread
end of thread, other threads:[~2007-06-12 11:21 UTC | newest] Thread overview: 72+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-07-22 2:42 A few questions about desktop.el Juanma Barranquero 2005-07-22 10:53 ` Juanma Barranquero 2005-07-22 22:52 ` Richard M. Stallman 2005-07-26 8:56 ` Juanma Barranquero 2005-07-27 14:03 ` Richard M. Stallman 2005-07-27 14:28 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman 2005-07-28 7:34 ` David Kastrup 2005-07-28 12:51 ` Juanma Barranquero 2005-07-29 0:11 ` Richard M. Stallman 2005-07-28 3:20 ` Richard M. Stallman 2005-07-29 0:37 ` Juanma Barranquero 2005-07-28 4:24 ` Masatake YAMATO 2006-04-27 23:05 ` Stuart D. Herring 2006-04-28 14:56 ` Juanma Barranquero 2006-04-29 4:57 ` Stuart D. Herring 2006-04-30 1:16 ` Juanma Barranquero 2006-05-02 15:06 ` Stuart D. Herring 2006-05-02 15:14 ` Juanma Barranquero 2006-05-02 15:42 ` Stuart D. Herring 2006-05-02 17:57 ` Stuart D. Herring 2006-04-28 15:44 ` Richard Stallman 2006-04-29 5:02 ` Stuart D. Herring 2006-04-30 3:03 ` Richard Stallman 2006-05-03 12:48 ` Juri Linkov 2006-05-03 14:37 ` Lars Hansen 2006-05-03 20:43 ` Richard Stallman 2006-05-04 16:27 ` Stuart D. Herring 2006-05-05 6:44 ` Lars Hansen 2007-06-05 9:24 ` Juanma Barranquero 2007-06-08 21:17 ` Davis Herring 2007-06-08 21:29 ` Juanma Barranquero 2007-06-08 22:05 ` Davis Herring 2007-06-08 22:14 ` Juri Linkov 2007-06-09 0:51 ` Davis Herring 2007-06-09 21:31 ` Juri Linkov 2007-06-10 23:28 ` Juanma Barranquero 2007-06-11 20:54 ` Juri Linkov 2007-06-12 11:21 ` Juanma Barranquero 2006-05-04 16:17 ` Stuart D. Herring 2005-08-08 15:02 ` Lars Hansen 2005-07-22 13:50 ` Juanma Barranquero 2005-07-22 14:36 ` Juanma Barranquero 2005-07-26 8:27 ` Juanma Barranquero 2005-08-08 15:04 ` Lars Hansen 2005-07-22 19:11 ` Lars Hansen 2005-07-22 21:24 ` Juanma Barranquero 2005-07-22 22:50 ` Richard M. Stallman 2005-07-26 9:11 ` Juanma Barranquero 2005-07-27 14:04 ` Richard M. Stallman 2005-07-27 14:16 ` Juanma Barranquero 2005-07-28 3:20 ` Richard M. Stallman 2005-07-29 0:44 ` Juanma Barranquero 2005-08-10 9:50 ` Lars Hansen 2005-08-10 11:24 ` Juanma Barranquero 2006-02-09 16:30 ` Juanma Barranquero 2006-02-09 20:00 ` Lars Hansen 2006-02-09 21:11 ` Lars Hansen 2006-02-09 23:46 ` Juanma Barranquero 2005-08-10 22:05 ` Luc Teirlinck 2005-08-10 23:45 ` Luc Teirlinck 2005-08-11 1:12 ` Luc Teirlinck 2005-08-11 1:36 ` Luc Teirlinck 2005-08-11 3:01 ` Luc Teirlinck 2005-08-11 6:12 ` Lars Hansen 2005-08-08 14:51 ` Lars Hansen 2005-08-08 18:35 ` Juanma Barranquero 2005-08-09 7:12 ` Lars Hansen 2005-08-09 7:36 ` Lars Hansen 2005-08-09 8:49 ` Juanma Barranquero 2005-08-09 9:31 ` David Kastrup 2005-08-09 9:59 ` Juanma Barranquero
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.