lisp/custom.el: Trivial fixes.
[bpt/emacs.git] / lisp / custom.el
index f984d13..cf06fe2 100644 (file)
@@ -1,7 +1,6 @@
 ;;; custom.el --- tools for declaring and initializing options
 ;;
-;; Copyright (C) 1996, 1997, 1999, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1996-1997, 1999, 2001-2011 Free Software Foundation, Inc.
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Maintainer: FSF
@@ -790,10 +789,10 @@ E.g. dumped variables whose default depends on run-time information."
 (defvar custom-known-themes '(user changed)
    "Themes that have been defined with `deftheme'.
 The default value is the list (user changed).  The theme `changed'
-contains the settings before custom themes are applied.  The
-theme `user' contains all the settings the user customized and saved.
-Additional themes declared with the `deftheme' macro will be added to
-the front of this list.")
+contains the settings before custom themes are applied.  The theme
+`user' contains all the settings the user customized and saved.
+Additional themes declared with the `deftheme' macro will be added
+to the front of this list.")
 
 (defsubst custom-theme-p (theme)
   "Non-nil when THEME has been defined."
@@ -1072,7 +1071,7 @@ order.  Each element in the list should be one of the following:
   named \"themes\" in `data-directory').
 - a directory name (a string).
 
-Each theme file is named NAME-theme.el, where THEME is the theme
+Each theme file is named THEME-theme.el, where THEME is the theme
 name."
   :type '(repeat (choice (const :tag "custom-theme-directory"
                                custom-theme-directory)
@@ -1105,26 +1104,27 @@ property `theme-feature' (which is usually a symbol created by
     (let ((custom-enabling-themes t))
       (enable-theme 'user))))
 
-(defcustom custom-safe-theme-files '(default)
-  "List of theme files that are considered safe to load.
-Each list element should be either an absolute file name, or the
-symbol `default', which stands for the built-in Emacs theme
-directory (a directory named \"themes\" in `data-directory'."
+(defcustom custom-safe-themes '(default)
+  "List of themes that are considered safe to load.
+Each list element should be the `sha1' hash of a theme file, or
+the symbol `default', which stands for any theme in the built-in
+Emacs theme directory (a directory named \"themes\" in
+`data-directory')."
   :type '(repeat
-         (choice file (const :tag "Built-in theme directory" default)))
+         (choice string (const :tag "Built-in themes" default)))
   :group 'customize
+  :risky t
   :version "24.1")
 
-(defvar safe-functions) ; From unsafep.el
-
 (defun load-theme (theme &optional no-enable)
-  "Load a theme's settings from its file.
-Normally, this also enables the theme; use `disable-theme' to
-disable it.  If optional arg NO-ENABLE is non-nil, don't enable
-the theme.
+  "Load Custom theme named THEME from its file.
+Normally, this also enables THEME.  If optional arg NO-ENABLE is
+non-nil, load THEME but don't enable it.
+
+The theme file is named THEME-theme.el, in one of the directories
+specified by `custom-theme-load-path'.
 
-A theme file is named THEME-theme.el, where THEME is the theme name,
-in one of the directories specified by `custom-theme-load-path'."
+Return t if THEME was successfully loaded, nil otherwise."
   (interactive
    (list
     (intern (completing-read "Load custom theme: "
@@ -1140,74 +1140,63 @@ in one of the directories specified by `custom-theme-load-path'."
     (put theme 'theme-documentation nil))
   (let ((fn (locate-file (concat (symbol-name theme) "-theme.el")
                         (custom-theme--load-path)
-                        '("" "c"))))
+                        '("" "c")))
+       hash)
     (unless fn
-      (error "Unable to find theme file for `%s'." theme))
-    ;; Check file safety.
-    (when (or (and (memq 'default custom-safe-theme-files)
-                  (equal (file-name-directory fn)
-                         (expand-file-name "themes/" data-directory)))
-             (member fn custom-safe-theme-files)
-             ;; If the file is not in the builtin theme directory or
-             ;; in `custom-safe-theme-files', check it with unsafep.
-             (with-temp-buffer
-               (require 'unsafep)
-               (insert-file-contents fn)
-               (let ((safe-functions (append '(provide-theme deftheme
-                                               custom-theme-set-variables
-                                               custom-theme-set-faces)
-                                             safe-functions))
-                     unsafep form)
-                 (while (and (setq form (condition-case nil
-                                            (let ((read-circle nil))
-                                              (read (current-buffer)))
-                                          (end-of-file nil)))
-                             (null (setq unsafep (unsafep form)))))
-                 (or (null unsafep)
-                     (custom-theme-load-confirm fn)))))
-      (let ((custom--inhibit-theme-enable no-enable))
-       (load fn)))))
-
-(defun custom-theme-load-confirm (filename)
+      (error "Unable to find theme file for `%s'" theme))
+    (with-temp-buffer
+      (insert-file-contents fn)
+      (setq hash (sha1 (current-buffer)))
+      ;; Check file safety with `custom-safe-themes', prompting the
+      ;; user if necessary.
+      (when (or (and (memq 'default custom-safe-themes)
+                    (equal (file-name-directory fn)
+                           (expand-file-name "themes/" data-directory)))
+               (member hash custom-safe-themes)
+               (custom-theme-load-confirm hash))
+       (let ((custom--inhibit-theme-enable no-enable))
+         (eval-buffer)
+         t)))))
+
+(defun custom-theme-load-confirm (hash)
+  "Query the user about loading a Custom theme that may not be safe.
+The theme should be in the current buffer.  If the user agrees,
+query also about adding HASH to `custom-safe-themes'."
   (if noninteractive
       nil
-    (let ((existing-buffer (find-buffer-visiting filename))
-         (exit-chars '(?y ?n ?\s ?\C-g))
-         prompt char)
+    (let ((exit-chars '(?y ?n ?\s))
+         window prompt char)
       (save-window-excursion
-       (if existing-buffer
-           (pop-to-buffer existing-buffer)
-         (find-file filename))
-       (unwind-protect
-           (progn
-             (setq prompt
-                   (format "This theme is not guaranteed to be safe.  Really load? %s"
-                           (if (< (line-number-at-pos (point-max))
-                                  (window-body-height))
-                               "(y or n) "
-                             (push ?\C-v exit-chars)
-                             "Type y or n, or C-v to scroll: ")))
-             (goto-char (point-min))
-             (while (null char)
-               (setq char (read-char-choice prompt exit-chars t))
-               (when (eq char ?\C-v)
+       (rename-buffer "*Custom Theme*" t)
+       (emacs-lisp-mode)
+       (setq window (display-buffer (current-buffer)))
+       (setq prompt
+             (format "Loading a theme can run Lisp code.  Really load?%s"
+                     (if (and window
+                              (< (line-number-at-pos (point-max))
+                                 (window-body-height)))
+                         " (y or n) "
+                       (push ?\C-v exit-chars)
+                       "\nType y or n, or C-v to scroll: ")))
+       (goto-char (point-min))
+       (while (null char)
+         (setq char (read-char-choice prompt exit-chars))
+         (when (eq char ?\C-v)
+           (if window
+               (with-selected-window window
                  (condition-case nil
                      (scroll-up)
-                   (error (goto-char (point-min))))
-                 (setq char nil)))
-             (when (memq char '(?\s ?y))
-               (push filename custom-safe-theme-files)
-               ;; Offer to save to `custom-safe-theme-files'.
-               (and (or custom-file user-init-file)
-                    (y-or-n-p "Treat %s as safe for future loads? "
-                              (file-name-nondirectory filename))
-                    (let ((coding-system-for-read nil))
-                      (customize-save-variable
-                       'custom-safe-theme-files
-                       custom-safe-theme-files)))
-               t))
-         ;; Unwind form.
-         (unless existing-buffer (kill-buffer)))))))
+                   (error (goto-char (point-min))))))
+           (setq char nil)))
+       (when (memq char '(?\s ?y))
+         ;; Offer to save to `custom-safe-themes'.
+         (and (or custom-file user-init-file)
+              (y-or-n-p "Treat this theme as safe in future sessions? ")
+              (let ((coding-system-for-read nil))
+                (push hash custom-safe-themes)
+                (customize-save-variable 'custom-safe-themes
+                                         custom-safe-themes)))
+         t)))))
 
 (defun custom-theme-name-valid-p (name)
   "Return t if NAME is a valid name for a Custom theme, nil otherwise.
@@ -1220,7 +1209,7 @@ NAME should be a symbol."
 
 (defun custom-available-themes ()
   "Return a list of available Custom themes (symbols)."
-  (let* (sym themes)
+  (let (sym themes)
     (dolist (dir (custom-theme--load-path))
       (when (file-directory-p dir)
        (dolist (file (file-expand-wildcards
@@ -1230,7 +1219,7 @@ NAME should be a symbol."
               (setq sym (intern (match-string 1 file)))
               (custom-theme-name-valid-p sym)
               (push sym themes)))))
-    (delete-dups themes)))
+    (nreverse (delete-dups themes))))
 
 (defun custom-theme--load-path ()
   (let (lpath)
@@ -1284,7 +1273,8 @@ This does not include the `user' theme, which is set by Customize,
 and always takes precedence over other Custom Themes."
   :group 'customize
   :type  '(repeat symbol)
-  :set-after '(custom-theme-directory custom-theme-load-path)
+  :set-after '(custom-theme-directory custom-theme-load-path
+                                     custom-safe-themes)
   :risky t
   :set (lambda (symbol themes)
         ;; Avoid an infinite loop when custom-enabled-themes is
@@ -1345,7 +1335,7 @@ That is to say, it specifies what the value should be according to
 currently enabled custom themes.
 
 This function returns nil if no custom theme specifies a value for VARIABLE."
-  (let* ((theme-value (get variable 'theme-value)))
+  (let ((theme-value (get variable 'theme-value)))
     (if theme-value
        (cdr (car theme-value)))))
 
@@ -1407,5 +1397,4 @@ This means reset VARIABLE.  (The argument IGNORED is ignored)."
 
 (provide 'custom)
 
-;; arch-tag: 041b6116-aabe-4f9a-902d-74092bc3dab2
 ;;; custom.el ends here