X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/95b6d681b1121e1be8955aa3f79dd39098edf4cf..17711ed9be4253d8e1371f6e771505578725c711:/lisp/desktop.el diff --git a/lisp/desktop.el b/lisp/desktop.el index b4d3dfd55c..a873a6b63b 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -1,12 +1,10 @@ ;;; desktop.el --- save partial status of Emacs when killed -;; Copyright (C) 1993, 1994, 1995, 1997, 2000, 2001, 2002, 2003, -;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 -;; Free Software Foundation, Inc. +;; Copyright (C) 1993-1995, 1997, 2000-2012 Free Software Foundation, Inc. ;; Author: Morten Welinder ;; Keywords: convenience -;; Favourite-brand-of-beer: None, I hate beer. +;; Favorite-brand-of-beer: None, I hate beer. ;; This file is part of GNU Emacs. @@ -147,20 +145,21 @@ backward compatibility.") "Save status of Emacs when you exit." :group 'frames) +;; Maintained for backward compatibility +(define-obsolete-variable-alias 'desktop-enable 'desktop-save-mode "22.1") ;;;###autoload (define-minor-mode desktop-save-mode - "Toggle desktop saving mode. -With numeric ARG, turn desktop saving on if ARG is positive, off -otherwise. If desktop saving is turned on, the state of Emacs is -saved from one session to another. See variable `desktop-save' -and function `desktop-read' for details." + "Toggle desktop saving (Desktop Save mode). +With a prefix argument ARG, enable Desktop Save mode if ARG is +positive, and disable it otherwise. If called from Lisp, enable +the mode if ARG is omitted or nil. + +If Desktop Save mode is enabled, the state of Emacs is saved from +one session to another. See variable `desktop-save' and function +`desktop-read' for details." :global t :group 'desktop) -;; Maintained for backward compatibility -(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)) @@ -221,7 +220,7 @@ the normal hook `desktop-not-loaded-hook' is run." :group 'desktop :version "22.2") -(defcustom desktop-path (list "." user-emacs-directory "~") +(defcustom desktop-path (list user-emacs-directory "~") "List of directories to search for the desktop file. The base name of the file is specified in `desktop-base-file-name'." :type '(repeat directory) @@ -411,8 +410,7 @@ is passed as the argument DESKTOP-BUFFER-MISC to functions in 'desktop-save-buffer "22.1") ;;;###autoload -(defvar desktop-buffer-mode-handlers - nil +(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 @@ -472,8 +470,7 @@ this table. See also `desktop-minor-mode-handlers'." :group 'desktop) ;;;###autoload -(defvar desktop-minor-mode-handlers - nil +(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 @@ -613,7 +610,8 @@ Furthermore, it clears the variables listed in `desktop-globals-to-clear'." (delete-other-windows)) ;; ---------------------------------------------------------------------------- -(add-hook 'kill-emacs-hook 'desktop-kill) +(unless noninteractive + (add-hook 'kill-emacs-hook 'desktop-kill)) (defun desktop-kill () "If `desktop-save-mode' is non-nil, do what `desktop-save' says to do. @@ -700,9 +698,9 @@ is nil, ask the user where to save the desktop." ;; ---------------------------------------------------------------------------- (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. +TXT is a string that when read and evaluated yields VALUE. QUOTE may be `may' (value may be quoted), -`must' (values must be quoted), or nil (value may not be quoted)." +`must' (value must be quoted), or nil (value must not be quoted)." (cond ((or (numberp value) (null value) (eq t value) (keywordp value)) (cons 'may (prin1-to-string value))) @@ -812,7 +810,7 @@ which means to truncate VAR's value to at most MAX-SIZE elements ")\n")))) ;; ---------------------------------------------------------------------------- -(defun desktop-save-buffer-p (filename bufname mode &rest dummy) +(defun desktop-save-buffer-p (filename bufname mode &rest _dummy) "Return t if buffer should have its state saved in the desktop file. FILENAME is the visited file name, BUFNAME is the buffer name, and MODE is the major mode. @@ -968,8 +966,8 @@ It returns t if a desktop file was loaded, nil otherwise." (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. - "~")))) + ;; Default: .emacs.d. + user-emacs-directory)))) (if (file-exists-p (desktop-full-file-name)) ;; Desktop file found, but is it already in use? (let ((desktop-first-buffer nil) @@ -981,6 +979,7 @@ It returns t if a desktop file was loaded, nil otherwise." (if (and owner (memq desktop-load-locked-desktop '(nil ask)) (or (null desktop-load-locked-desktop) + (daemonp) (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\n\ Using it may cause conflicts. Use it anyway? " owner))))) (let ((default-directory desktop-dirname)) @@ -1020,6 +1019,18 @@ Using it may cause conflicts. Use it anyway? " owner))))) (format ", %d to restore lazily" (length desktop-buffer-args-list)) "")) + ;; Bury the *Messages* buffer to not reshow it when burying + ;; the buffer we switched to above. + (when (buffer-live-p (get-buffer "*Messages*")) + (bury-buffer "*Messages*")) + ;; Clear all windows' previous and next buffers, these have + ;; been corrupted by the `switch-to-buffer' calls in + ;; `desktop-restore-file-buffer' (bug#11556). This is a + ;; brute force fix and should be replaced by a more subtle + ;; strategy eventually. + (walk-window-tree (lambda (window) + (set-window-prev-buffers window nil) + (set-window-next-buffers window nil))) t)) ;; No desktop file found. (desktop-clear) @@ -1077,15 +1088,16 @@ directory DIRNAME." (defvar desktop-buffer-major-mode) (defvar desktop-buffer-locals) +(defvar auto-insert) ; from autoinsert.el ;; ---------------------------------------------------------------------------- -(defun desktop-restore-file-buffer (desktop-buffer-file-name - desktop-buffer-name - desktop-buffer-misc) +(defun desktop-restore-file-buffer (buffer-filename + _buffer-name + _buffer-misc) "Restore a file buffer." - (when desktop-buffer-file-name - (if (or (file-exists-p desktop-buffer-file-name) + (when buffer-filename + (if (or (file-exists-p buffer-filename) (let ((msg (format "Desktop: File \"%s\" no longer exists." - desktop-buffer-file-name))) + buffer-filename))) (if desktop-missing-file-warning (y-or-n-p (concat msg " Re-create buffer? ")) (message "%s" msg) @@ -1095,7 +1107,7 @@ directory DIRNAME." (or coding-system-for-read (cdr (assq 'buffer-file-coding-system desktop-buffer-locals)))) - (buf (find-file-noselect desktop-buffer-file-name))) + (buf (find-file-noselect buffer-filename))) (condition-case nil (switch-to-buffer buf) (error (pop-to-buffer buf))) @@ -1107,11 +1119,8 @@ directory DIRNAME." (defun desktop-load-file (function) "Load the file where auto loaded FUNCTION is defined." - (when function - (let ((fcell (and (fboundp function) (symbol-function function)))) - (when (and (listp fcell) - (eq 'autoload (car fcell))) - (load (cadr fcell)))))) + (when (fboundp function) + (autoload-do-load (symbol-function function) function))) ;; ---------------------------------------------------------------------------- ;; Create a buffer, load its file, set its mode, ...; @@ -1126,104 +1135,114 @@ directory DIRNAME." (defvar desktop-buffer-fail-count) (defun desktop-create-buffer - (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 - &optional - desktop-buffer-locals) - ;; 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-no-debug err - (funcall (or (cdr (assq desktop-buffer-major-mode - desktop-buffer-mode-handlers)) - 'desktop-restore-file-buffer) - desktop-buffer-file-name - desktop-buffer-name - desktop-buffer-misc) - (error - (message "Desktop: Can't load buffer %s: %s" - desktop-buffer-name - (error-message-string err)) - (when desktop-missing-file-warning (sit-for 1)) - nil)))) - (if (bufferp result) - (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count)) - (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count)) - (setq result nil)) - ;; Restore buffer list order with new buffer at end. Don't change - ;; the order for old desktop files (old desktop module behaviour). - (unless (< desktop-file-version 206) - (mapc 'bury-buffer buffer-list) - (when result (bury-buffer result))) - (when result - (unless (or desktop-first-buffer (< desktop-file-version 206)) - (setq desktop-first-buffer result)) - (set-buffer result) - (unless (equal (buffer-name) desktop-buffer-name) - (rename-buffer desktop-buffer-name t)) - ;; minor modes - (cond ((equal '(t) desktop-buffer-minor-modes) ; backwards compatible - (auto-fill-mode 1)) - ((equal '(nil) desktop-buffer-minor-modes) ; backwards compatible - (auto-fill-mode 0)) - (t - (dolist (minor-mode desktop-buffer-minor-modes) - ;; 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))))))) - ;; 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 - (condition-case err - ;; Evaluate point. Thus point can be something like - ;; '(search-forward ... - (eval desktop-buffer-point) - (error (message "%s" (error-message-string err)) 1)))) - (when desktop-buffer-mark - (if (consp desktop-buffer-mark) - (progn - (set-mark (car desktop-buffer-mark)) - (setq mark-active (car (cdr desktop-buffer-mark)))) - (set-mark desktop-buffer-mark))) - ;; Never override file system if the file really is read-only marked. - (when desktop-buffer-read-only (setq buffer-read-only desktop-buffer-read-only)) - (while desktop-buffer-locals - (let ((this (car desktop-buffer-locals))) - (if (consp this) - ;; an entry of this form `(symbol . value)' + (file-version + buffer-filename + buffer-name + buffer-majormode + buffer-minormodes + buffer-point + buffer-mark + buffer-readonly + buffer-misc + &optional + buffer-locals) + + (let ((desktop-file-version file-version) + (desktop-buffer-file-name buffer-filename) + (desktop-buffer-name buffer-name) + (desktop-buffer-major-mode buffer-majormode) + (desktop-buffer-minor-modes buffer-minormodes) + (desktop-buffer-point buffer-point) + (desktop-buffer-mark buffer-mark) + (desktop-buffer-read-only buffer-readonly) + (desktop-buffer-misc buffer-misc) + (desktop-buffer-locals buffer-locals)) + ;; 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-unless-debug err + (funcall (or (cdr (assq desktop-buffer-major-mode + desktop-buffer-mode-handlers)) + 'desktop-restore-file-buffer) + desktop-buffer-file-name + desktop-buffer-name + desktop-buffer-misc) + (error + (message "Desktop: Can't load buffer %s: %s" + desktop-buffer-name + (error-message-string err)) + (when desktop-missing-file-warning (sit-for 1)) + nil)))) + (if (bufferp result) + (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count)) + (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count)) + (setq result nil)) + ;; Restore buffer list order with new buffer at end. Don't change + ;; the order for old desktop files (old desktop module behavior). + (unless (< desktop-file-version 206) + (mapc 'bury-buffer buffer-list) + (when result (bury-buffer result))) + (when result + (unless (or desktop-first-buffer (< desktop-file-version 206)) + (setq desktop-first-buffer result)) + (set-buffer result) + (unless (equal (buffer-name) desktop-buffer-name) + (rename-buffer desktop-buffer-name t)) + ;; minor modes + (cond ((equal '(t) desktop-buffer-minor-modes) ; backwards compatible + (auto-fill-mode 1)) + ((equal '(nil) desktop-buffer-minor-modes) ; backwards compatible + (auto-fill-mode 0)) + (t + (dolist (minor-mode desktop-buffer-minor-modes) + ;; 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))))))) + ;; 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 + (condition-case err + ;; Evaluate point. Thus point can be something like + ;; '(search-forward ... + (eval desktop-buffer-point) + (error (message "%s" (error-message-string err)) 1)))) + (when desktop-buffer-mark + (if (consp desktop-buffer-mark) (progn - (make-local-variable (car this)) - (set (car this) (cdr this))) - ;; an entry of the form `symbol' - (make-local-variable this) - (makunbound this))) - (setq desktop-buffer-locals (cdr desktop-buffer-locals))))))) + (set-mark (car desktop-buffer-mark)) + (setq mark-active (car (cdr desktop-buffer-mark)))) + (set-mark desktop-buffer-mark))) + ;; Never override file system if the file really is read-only marked. + (when desktop-buffer-read-only (setq buffer-read-only desktop-buffer-read-only)) + (while desktop-buffer-locals + (let ((this (car desktop-buffer-locals))) + (if (consp this) + ;; an entry of this form `(symbol . value)' + (progn + (make-local-variable (car this)) + (set (car this) (cdr this))) + ;; an entry of the form `symbol' + (make-local-variable this) + (makunbound this))) + (setq desktop-buffer-locals (cdr desktop-buffer-locals)))))))) ;; ---------------------------------------------------------------------------- ;; Backward compatibility -- update parameters to 205 standards. -(defun desktop-buffer (desktop-buffer-file-name desktop-buffer-name - desktop-buffer-major-mode - mim pt mk ro tl fc cfs cr desktop-buffer-misc) - (desktop-create-buffer 205 desktop-buffer-file-name desktop-buffer-name - desktop-buffer-major-mode (cdr mim) pt mk ro - desktop-buffer-misc +(defun desktop-buffer (buffer-filename buffer-name buffer-majormode + mim pt mk ro tl fc cfs cr buffer-misc) + (desktop-create-buffer 205 buffer-filename buffer-name + buffer-majormode (cdr mim) pt mk ro + buffer-misc (list (cons 'truncate-lines tl) (cons 'fill-column fc) (cons 'case-fold-search cfs) @@ -1312,5 +1331,4 @@ If there are no buffers left to create, kill the timer." (provide 'desktop) -;; arch-tag: 221907c3-1771-4fd3-9c2e-c6f700c6ede9 ;;; desktop.el ends here