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