Mercurial > emacs
comparison lisp/desktop.el @ 81324:08f606738d5d
(desktop-load-locked-desktop): New option.
(desktop-read): Use it.
(desktop-truncate, desktop-outvar, desktop-restore-file-buffer): Use `when'.
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Tue, 12 Jun 2007 11:14:28 +0000 |
parents | 71d53e1b86d0 |
children | a53017ab8b85 3619e7770f2e |
comparison
equal
deleted
inserted
replaced
81323:9afe4aab01d1 | 81324:08f606738d5d |
---|---|
188 (const :tag "Save if desktop file exists, else don't" if-exists) | 188 (const :tag "Save if desktop file exists, else don't" if-exists) |
189 (const :tag "Never save" nil)) | 189 (const :tag "Never save" nil)) |
190 :group 'desktop | 190 :group 'desktop |
191 :version "22.1") | 191 :version "22.1") |
192 | 192 |
193 (defcustom desktop-load-locked-desktop 'ask | |
194 "Specifies whether the desktop should be loaded if locked. | |
195 Possible values are: | |
196 t -- load anyway. | |
197 nil -- don't load. | |
198 ask -- ask the user. | |
199 If the value is nil, or `ask' and the user chooses not to load the desktop, | |
200 the normal hook `desktop-not-loaded-hook' is run." | |
201 :type | |
202 '(choice | |
203 (const :tag "Load anyway" t) | |
204 (const :tag "Don't load" nil) | |
205 (const :tag "Ask the user" ask)) | |
206 :group 'desktop | |
207 :version "23.1") | |
208 | |
193 (defcustom desktop-base-file-name | 209 (defcustom desktop-base-file-name |
194 (convert-standard-filename ".emacs.desktop") | 210 (convert-standard-filename ".emacs.desktop") |
195 "Name of file for Emacs desktop, excluding the directory part." | 211 "Name of file for Emacs desktop, excluding the directory part." |
196 :type 'file | 212 :type 'file |
197 :group 'desktop) | 213 :group 'desktop) |
555 | 571 |
556 ;; ---------------------------------------------------------------------------- | 572 ;; ---------------------------------------------------------------------------- |
557 (defun desktop-truncate (list n) | 573 (defun desktop-truncate (list n) |
558 "Truncate LIST to at most N elements destructively." | 574 "Truncate LIST to at most N elements destructively." |
559 (let ((here (nthcdr (1- n) list))) | 575 (let ((here (nthcdr (1- n) list))) |
560 (if (consp here) | 576 (when (consp here) |
561 (setcdr here nil)))) | 577 (setcdr here nil)))) |
562 | 578 |
563 ;; ---------------------------------------------------------------------------- | 579 ;; ---------------------------------------------------------------------------- |
564 ;;;###autoload | 580 ;;;###autoload |
565 (defun desktop-clear () | 581 (defun desktop-clear () |
566 "Empty the Desktop. | 582 "Empty the Desktop. |
569 Furthermore, it clears the variables listed in `desktop-globals-to-clear'." | 585 Furthermore, it clears the variables listed in `desktop-globals-to-clear'." |
570 (interactive) | 586 (interactive) |
571 (desktop-lazy-abort) | 587 (desktop-lazy-abort) |
572 (dolist (var desktop-globals-to-clear) | 588 (dolist (var desktop-globals-to-clear) |
573 (if (symbolp var) | 589 (if (symbolp var) |
574 (eval `(setq-default ,var nil)) | 590 (eval `(setq-default ,var nil)) |
575 (eval `(setq-default ,(car var) ,(cdr var))))) | 591 (eval `(setq-default ,(car var) ,(cdr var))))) |
576 (let ((buffers (buffer-list)) | 592 (let ((buffers (buffer-list)) |
577 (preserve-regexp (concat "^\\(" | 593 (preserve-regexp (concat "^\\(" |
578 (mapconcat (lambda (regexp) | 594 (mapconcat (lambda (regexp) |
579 (concat "\\(" regexp "\\)")) | 595 (concat "\\(" regexp "\\)")) |
678 "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE. | 694 "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE. |
679 TXT is a string that when read and evaluated yields value. | 695 TXT is a string that when read and evaluated yields value. |
680 QUOTE may be `may' (value may be quoted), | 696 QUOTE may be `may' (value may be quoted), |
681 `must' (values must be quoted), or nil (value may not be quoted)." | 697 `must' (values must be quoted), or nil (value may not be quoted)." |
682 (cond | 698 (cond |
683 ((or (numberp value) (null value) (eq t value) (keywordp value)) | 699 ((or (numberp value) (null value) (eq t value) (keywordp value)) |
684 (cons 'may (prin1-to-string value))) | 700 (cons 'may (prin1-to-string value))) |
685 ((stringp value) | 701 ((stringp value) |
686 (let ((copy (copy-sequence value))) | 702 (let ((copy (copy-sequence value))) |
687 (set-text-properties 0 (length copy) nil copy) | 703 (set-text-properties 0 (length copy) nil copy) |
688 ;; Get rid of text properties because we cannot read them | 704 ;; Get rid of text properties because we cannot read them |
689 (cons 'may (prin1-to-string copy)))) | 705 (cons 'may (prin1-to-string copy)))) |
690 ((symbolp value) | 706 ((symbolp value) |
691 (cons 'must (prin1-to-string value))) | 707 (cons 'must (prin1-to-string value))) |
692 ((vectorp value) | 708 ((vectorp value) |
693 (let* ((special nil) | 709 (let* ((special nil) |
694 (pass1 (mapcar | 710 (pass1 (mapcar |
695 (lambda (el) | 711 (lambda (el) |
696 (let ((res (desktop-internal-v2s el))) | 712 (let ((res (desktop-internal-v2s el))) |
697 (if (null (car res)) | 713 (if (null (car res)) |
698 (setq special t)) | 714 (setq special t)) |
699 res)) | 715 res)) |
700 value))) | 716 value))) |
701 (if special | 717 (if special |
702 (cons nil (concat "(vector " | 718 (cons nil (concat "(vector " |
703 (mapconcat (lambda (el) | 719 (mapconcat (lambda (el) |
704 (if (eq (car el) 'must) | 720 (if (eq (car el) 'must) |
705 (concat "'" (cdr el)) | 721 (concat "'" (cdr el)) |
706 (cdr el))) | 722 (cdr el))) |
707 pass1 | 723 pass1 |
708 " ") | 724 " ") |
709 ")")) | 725 ")")) |
710 (cons 'may (concat "[" (mapconcat 'cdr pass1 " ") "]"))))) | 726 (cons 'may (concat "[" (mapconcat 'cdr pass1 " ") "]"))))) |
711 ((consp value) | 727 ((consp value) |
712 (let ((p value) | 728 (let ((p value) |
713 newlist | 729 newlist |
714 use-list* | 730 use-list* |
715 anynil) | 731 anynil) |
716 (while (consp p) | 732 (while (consp p) |
717 (let ((q.txt (desktop-internal-v2s (car p)))) | 733 (let ((q.txt (desktop-internal-v2s (car p)))) |
718 (or anynil (setq anynil (null (car q.txt)))) | 734 (or anynil (setq anynil (null (car q.txt)))) |
719 (setq newlist (cons q.txt newlist))) | 735 (setq newlist (cons q.txt newlist))) |
720 (setq p (cdr p))) | 736 (setq p (cdr p))) |
721 (if p | 737 (if p |
722 (let ((last (desktop-internal-v2s p))) | 738 (let ((last (desktop-internal-v2s p))) |
723 (or anynil (setq anynil (null (car last)))) | 739 (or anynil (setq anynil (null (car last)))) |
724 (or anynil | 740 (or anynil |
725 (setq newlist (cons '(must . ".") newlist))) | 741 (setq newlist (cons '(must . ".") newlist))) |
726 (setq use-list* t) | 742 (setq use-list* t) |
727 (setq newlist (cons last newlist)))) | 743 (setq newlist (cons last newlist)))) |
728 (setq newlist (nreverse newlist)) | 744 (setq newlist (nreverse newlist)) |
729 (if anynil | 745 (if anynil |
730 (cons nil | 746 (cons nil |
731 (concat (if use-list* "(desktop-list* " "(list ") | 747 (concat (if use-list* "(desktop-list* " "(list ") |
732 (mapconcat (lambda (el) | 748 (mapconcat (lambda (el) |
733 (if (eq (car el) 'must) | 749 (if (eq (car el) 'must) |
734 (concat "'" (cdr el)) | 750 (concat "'" (cdr el)) |
735 (cdr el))) | 751 (cdr el))) |
736 newlist | 752 newlist |
737 " ") | 753 " ") |
738 ")")) | 754 ")")) |
739 (cons 'must | 755 (cons 'must |
740 (concat "(" (mapconcat 'cdr newlist " ") ")"))))) | 756 (concat "(" (mapconcat 'cdr newlist " ") ")"))))) |
741 ((subrp value) | 757 ((subrp value) |
742 (cons nil (concat "(symbol-function '" | 758 (cons nil (concat "(symbol-function '" |
743 (substring (prin1-to-string value) 7 -1) | 759 (substring (prin1-to-string value) 7 -1) |
744 ")"))) | 760 ")"))) |
745 ((markerp value) | 761 ((markerp value) |
746 (let ((pos (prin1-to-string (marker-position value))) | 762 (let ((pos (prin1-to-string (marker-position value))) |
747 (buf (prin1-to-string (buffer-name (marker-buffer value))))) | 763 (buf (prin1-to-string (buffer-name (marker-buffer value))))) |
748 (cons nil (concat "(let ((mk (make-marker)))" | 764 (cons nil (concat "(let ((mk (make-marker)))" |
749 " (add-hook 'desktop-delay-hook" | 765 " (add-hook 'desktop-delay-hook" |
750 " (list 'lambda '() (list 'set-marker mk " | 766 " (list 'lambda '() (list 'set-marker mk " |
751 pos " (get-buffer " buf ")))) mk)")))) | 767 pos " (get-buffer " buf ")))) mk)")))) |
752 (t ; save as text | 768 (t ; save as text |
753 (cons 'may "\"Unprintable entity\"")))) | 769 (cons 'may "\"Unprintable entity\"")))) |
754 | 770 |
755 ;; ---------------------------------------------------------------------------- | 771 ;; ---------------------------------------------------------------------------- |
756 (defun desktop-value-to-string (value) | 772 (defun desktop-value-to-string (value) |
757 "Convert VALUE to a string that when read evaluates to the same value. | 773 "Convert VALUE to a string that when read evaluates to the same value. |
758 Not all types of values are supported." | 774 Not all types of values are supported." |
774 \(if the value is a list) before saving the value." | 790 \(if the value is a list) before saving the value." |
775 (let (var size) | 791 (let (var size) |
776 (if (consp varspec) | 792 (if (consp varspec) |
777 (setq var (car varspec) size (cdr varspec)) | 793 (setq var (car varspec) size (cdr varspec)) |
778 (setq var varspec)) | 794 (setq var varspec)) |
779 (if (boundp var) | 795 (when (boundp var) |
780 (progn | 796 (when (and (integerp size) |
781 (if (and (integerp size) | 797 (> size 0) |
782 (> size 0) | 798 (listp (eval var))) |
783 (listp (eval var))) | 799 (desktop-truncate (eval var) size)) |
784 (desktop-truncate (eval var) size)) | 800 (insert "(setq " |
785 (insert "(setq " | 801 (symbol-name var) |
786 (symbol-name var) | 802 " " |
787 " " | 803 (desktop-value-to-string (symbol-value var)) |
788 (desktop-value-to-string (symbol-value var)) | 804 ")\n")))) |
789 ")\n"))))) | |
790 | 805 |
791 ;; ---------------------------------------------------------------------------- | 806 ;; ---------------------------------------------------------------------------- |
792 (defun desktop-save-buffer-p (filename bufname mode &rest dummy) | 807 (defun desktop-save-buffer-p (filename bufname mode &rest dummy) |
793 "Return t if buffer should have its state saved in the desktop file. | 808 "Return t if buffer should have its state saved in the desktop file. |
794 FILENAME is the visited file name, BUFNAME is the buffer name, and | 809 FILENAME is the visited file name, BUFNAME is the buffer name, and |
942 (desktop-buffer-fail-count 0) | 957 (desktop-buffer-fail-count 0) |
943 (owner (desktop-owner)) | 958 (owner (desktop-owner)) |
944 ;; Avoid desktop saving during evaluation of desktop buffer. | 959 ;; Avoid desktop saving during evaluation of desktop buffer. |
945 (desktop-save nil)) | 960 (desktop-save nil)) |
946 (if (and owner | 961 (if (and owner |
947 (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\n\ | 962 (memq desktop-load-locked-desktop '(nil ask)) |
948 Using it may cause conflicts. Use it anyway? " owner)))) | 963 (or (null desktop-load-locked-desktop) |
949 (progn (setq desktop-dirname nil) | 964 (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\n\ |
950 (let ((default-directory desktop-dirname)) | 965 Using it may cause conflicts. Use it anyway? " owner))))) |
951 (run-hooks 'desktop-not-loaded-hook)) | 966 (progn |
952 (message "Desktop file in use; not loaded.")) | 967 (setq desktop-dirname nil) |
968 (let ((default-directory desktop-dirname)) | |
969 (run-hooks 'desktop-not-loaded-hook)) | |
970 (message "Desktop file in use; not loaded.")) | |
953 (desktop-lazy-abort) | 971 (desktop-lazy-abort) |
954 ;; Evaluate desktop buffer and remember when it was modified. | 972 ;; Evaluate desktop buffer and remember when it was modified. |
955 (load (desktop-full-file-name) t t t) | 973 (load (desktop-full-file-name) t t t) |
956 (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))) | 974 (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))) |
957 ;; If it wasn't already, mark it as in-use, to bother other | 975 ;; If it wasn't already, mark it as in-use, to bother other |
1042 ;; ---------------------------------------------------------------------------- | 1060 ;; ---------------------------------------------------------------------------- |
1043 (defun desktop-restore-file-buffer (desktop-buffer-file-name | 1061 (defun desktop-restore-file-buffer (desktop-buffer-file-name |
1044 desktop-buffer-name | 1062 desktop-buffer-name |
1045 desktop-buffer-misc) | 1063 desktop-buffer-misc) |
1046 "Restore a file buffer." | 1064 "Restore a file buffer." |
1047 (if desktop-buffer-file-name | 1065 (when desktop-buffer-file-name |
1048 (if (or (file-exists-p desktop-buffer-file-name) | 1066 (if (or (file-exists-p desktop-buffer-file-name) |
1049 (let ((msg (format "Desktop: File \"%s\" no longer exists." | 1067 (let ((msg (format "Desktop: File \"%s\" no longer exists." |
1050 desktop-buffer-file-name))) | 1068 desktop-buffer-file-name))) |
1051 (if desktop-missing-file-warning | 1069 (if desktop-missing-file-warning |
1052 (y-or-n-p (concat msg " Re-create buffer? ")) | 1070 (y-or-n-p (concat msg " Re-create buffer? ")) |
1053 (message "%s" msg) | 1071 (message "%s" msg) |
1054 nil))) | 1072 nil))) |
1055 (let* ((auto-insert nil) ; Disable auto insertion | 1073 (let* ((auto-insert nil) ; Disable auto insertion |
1056 (coding-system-for-read | 1074 (coding-system-for-read |
1057 (or coding-system-for-read | 1075 (or coding-system-for-read |
1058 (cdr (assq 'buffer-file-coding-system | 1076 (cdr (assq 'buffer-file-coding-system |
1059 desktop-buffer-locals)))) | 1077 desktop-buffer-locals)))) |
1060 (buf (find-file-noselect desktop-buffer-file-name))) | 1078 (buf (find-file-noselect desktop-buffer-file-name))) |
1061 (condition-case nil | 1079 (condition-case nil |
1062 (switch-to-buffer buf) | 1080 (switch-to-buffer buf) |
1063 (error (pop-to-buffer buf))) | 1081 (error (pop-to-buffer buf))) |
1064 (and (not (eq major-mode desktop-buffer-major-mode)) | 1082 (and (not (eq major-mode desktop-buffer-major-mode)) |
1065 (functionp desktop-buffer-major-mode) | 1083 (functionp desktop-buffer-major-mode) |
1066 (funcall desktop-buffer-major-mode)) | 1084 (funcall desktop-buffer-major-mode)) |
1067 buf) | 1085 buf) |
1068 nil))) | 1086 nil))) |
1069 | 1087 |
1070 (defun desktop-load-file (function) | 1088 (defun desktop-load-file (function) |
1071 "Load the file where auto loaded FUNCTION is defined." | 1089 "Load the file where auto loaded FUNCTION is defined." |
1072 (when function | 1090 (when function |
1073 (let ((fcell (and (fboundp function) (symbol-function function)))) | 1091 (let ((fcell (and (fboundp function) (symbol-function function)))) |
1158 ;; '(search-forward ... | 1176 ;; '(search-forward ... |
1159 (eval desktop-buffer-point) | 1177 (eval desktop-buffer-point) |
1160 (error (message "%s" (error-message-string err)) 1)))) | 1178 (error (message "%s" (error-message-string err)) 1)))) |
1161 (when desktop-buffer-mark | 1179 (when desktop-buffer-mark |
1162 (if (consp desktop-buffer-mark) | 1180 (if (consp desktop-buffer-mark) |
1163 (progn | 1181 (progn |
1164 (set-mark (car desktop-buffer-mark)) | 1182 (set-mark (car desktop-buffer-mark)) |
1165 (setq mark-active (car (cdr desktop-buffer-mark)))) | 1183 (setq mark-active (car (cdr desktop-buffer-mark)))) |
1166 (set-mark desktop-buffer-mark))) | 1184 (set-mark desktop-buffer-mark))) |
1167 ;; Never override file system if the file really is read-only marked. | 1185 ;; Never override file system if the file really is read-only marked. |
1168 (if desktop-buffer-read-only (setq buffer-read-only desktop-buffer-read-only)) | 1186 (when desktop-buffer-read-only (setq buffer-read-only desktop-buffer-read-only)) |
1169 (while desktop-buffer-locals | 1187 (while desktop-buffer-locals |
1170 (let ((this (car desktop-buffer-locals))) | 1188 (let ((this (car desktop-buffer-locals))) |
1171 (if (consp this) | 1189 (if (consp this) |
1172 ;; an entry of this form `(symbol . value)' | 1190 ;; an entry of this form `(symbol . value)' |
1173 (progn | 1191 (progn |
1174 (make-local-variable (car this)) | 1192 (make-local-variable (car this)) |
1175 (set (car this) (cdr this))) | 1193 (set (car this) (cdr this))) |
1176 ;; an entry of the form `symbol' | 1194 ;; an entry of the form `symbol' |
1177 (make-local-variable this) | 1195 (make-local-variable this) |
1178 (makunbound this))) | 1196 (makunbound this))) |
1179 (setq desktop-buffer-locals (cdr desktop-buffer-locals))))))) | 1197 (setq desktop-buffer-locals (cdr desktop-buffer-locals))))))) |
1180 | 1198 |