LCOV - code coverage report
Current view: top level - lisp - custom.el (source / functions) Hit Total Coverage
Test: tramp-tests-after.info Lines: 256 548 46.7 %
Date: 2017-08-30 10:12:24 Functions: 33 61 54.1 %

          Line data    Source code
       1             : ;;; custom.el --- tools for declaring and initializing options
       2             : ;;
       3             : ;; Copyright (C) 1996-1997, 1999, 2001-2017 Free Software Foundation,
       4             : ;; Inc.
       5             : ;;
       6             : ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
       7             : ;; Maintainer: emacs-devel@gnu.org
       8             : ;; Keywords: help, faces
       9             : ;; Package: emacs
      10             : 
      11             : ;; This file is part of GNU Emacs.
      12             : 
      13             : ;; GNU Emacs is free software: you can redistribute it and/or modify
      14             : ;; it under the terms of the GNU General Public License as published by
      15             : ;; the Free Software Foundation, either version 3 of the License, or
      16             : ;; (at your option) any later version.
      17             : 
      18             : ;; GNU Emacs is distributed in the hope that it will be useful,
      19             : ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
      20             : ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21             : ;; GNU General Public License for more details.
      22             : 
      23             : ;; You should have received a copy of the GNU General Public License
      24             : ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
      25             : 
      26             : ;;; Commentary:
      27             : ;;
      28             : ;; This file only contains the code needed to declare and initialize
      29             : ;; user options.  The code to customize options is autoloaded from
      30             : ;; `cus-edit.el' and is documented in the Emacs Lisp Reference manual.
      31             : 
      32             : ;; The code implementing face declarations is in `cus-face.el'.
      33             : 
      34             : ;;; Code:
      35             : 
      36             : (require 'widget)
      37             : 
      38             : (defvar custom-define-hook nil
      39             :   ;; Customize information for this option is in `cus-edit.el'.
      40             :   "Hook called after defining each customize option.")
      41             : 
      42             : (defvar custom-dont-initialize nil
      43             :   "Non-nil means `defcustom' should not initialize the variable.
      44             : That is used for the sake of `custom-make-dependencies'.
      45             : Users should not set it.")
      46             : 
      47             : (defvar custom-current-group-alist nil
      48             :   "Alist of (FILE . GROUP) indicating the current group to use for FILE.")
      49             : 
      50             : ;;; The `defcustom' Macro.
      51             : 
      52             : (defun custom-initialize-default (symbol exp)
      53             :   "Initialize SYMBOL with EXP.
      54             : This will do nothing if symbol already has a default binding.
      55             : Otherwise, if symbol has a `saved-value' property, it will evaluate
      56             : the car of that and use it as the default binding for symbol.
      57             : Otherwise, EXP will be evaluated and used as the default binding for
      58             : symbol."
      59          29 :   (eval `(defvar ,symbol ,(let ((sv (get symbol 'saved-value)))
      60          29 :                             (if sv (car sv) exp)))))
      61             : 
      62             : (defun custom-initialize-set (symbol exp)
      63             :   "Initialize SYMBOL based on EXP.
      64             : If the symbol doesn't have a default binding already,
      65             : then set it using its `:set' function (or `set-default' if it has none).
      66             : The value is either the value in the symbol's `saved-value' property,
      67             : if any, or the value of EXP."
      68           2 :   (condition-case nil
      69           2 :       (default-toplevel-value symbol)
      70             :     (error
      71           0 :      (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
      72           0 :               symbol
      73           0 :               (eval (let ((sv (get symbol 'saved-value)))
      74           2 :                       (if sv (car sv) exp)))))))
      75             : 
      76             : (defun custom-initialize-reset (symbol exp)
      77             :   "Initialize SYMBOL based on EXP.
      78             : Set the symbol, using its `:set' function (or `set-default' if it has none).
      79             : The value is either the symbol's current value
      80             :  (as obtained using the `:get' function), if any,
      81             : or the value in the symbol's `saved-value' property if any,
      82             : or (last of all) the value of EXP."
      83         803 :   (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
      84         803 :            symbol
      85         803 :            (condition-case nil
      86         803 :                (let ((def (default-toplevel-value symbol))
      87         631 :                      (getter (get symbol 'custom-get)))
      88         631 :                  (if getter (funcall getter symbol) def))
      89             :              (error
      90         172 :               (eval (let ((sv (get symbol 'saved-value)))
      91         803 :                       (if sv (car sv) exp)))))))
      92             : 
      93             : (defun custom-initialize-changed (symbol exp)
      94             :   "Initialize SYMBOL with EXP.
      95             : Like `custom-initialize-reset', but only use the `:set' function if
      96             : not using the standard setting.
      97             : For the standard setting, use `set-default'."
      98           1 :   (condition-case nil
      99           1 :       (let ((def (default-toplevel-value symbol)))
     100           1 :         (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
     101           1 :                  symbol
     102           1 :                  (let ((getter (get symbol 'custom-get)))
     103           1 :                    (if getter (funcall getter symbol) def))))
     104             :     (error
     105           0 :      (cond
     106           0 :       ((get symbol 'saved-value)
     107           0 :        (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
     108           0 :                 symbol
     109           0 :                 (eval (car (get symbol 'saved-value)))))
     110             :       (t
     111           1 :        (set-default symbol (eval exp)))))))
     112             : 
     113             : (defvar custom-delayed-init-variables nil
     114             :   "List of variables whose initialization is pending.")
     115             : 
     116             : (defun custom-initialize-delay (symbol _value)
     117             :   "Delay initialization of SYMBOL to the next Emacs start.
     118             : This is used in files that are preloaded (or for autoloaded
     119             : variables), so that the initialization is done in the run-time
     120             : context rather than the build-time context.  This also has the
     121             : side-effect that the (delayed) initialization is performed with
     122             : the :set function.
     123             : 
     124             : For variables in preloaded files, you can simply use this
     125             : function for the :initialize property.  For autoloaded variables,
     126             : you will also need to add an autoload stanza calling this
     127             : function, and another one setting the standard-value property.
     128             : Or you can wrap the defcustom in a progn, to force the autoloader
     129             : to include all of it."                ; see eg vc-sccs-search-project-dir
     130             :   ;; No longer true:
     131             :   ;; "See `send-mail-function' in sendmail.el for an example."
     132             : 
     133             :   ;; Until the var is actually initialized, it is kept unbound.
     134             :   ;; This seemed to be at least as good as setting it to an arbitrary
     135             :   ;; value like nil (evaluating `value' is not an option because it
     136             :   ;; may have undesirable side-effects).
     137          36 :   (push symbol custom-delayed-init-variables))
     138             : 
     139             : (defun custom-declare-variable (symbol default doc &rest args)
     140             :   "Like `defcustom', but SYMBOL and DEFAULT are evaluated as normal arguments.
     141             : DEFAULT should be an expression to evaluate to compute the default value,
     142             : not the default value itself.
     143             : 
     144             : DEFAULT is stored as SYMBOL's standard value, in SYMBOL's property
     145             : `standard-value'.  At the same time, SYMBOL's property `force-value' is
     146             : set to nil, as the value is no longer rogue."
     147         852 :   (put symbol 'standard-value (purecopy (list default)))
     148             :   ;; Maybe this option was rogue in an earlier version.  It no longer is.
     149         852 :   (when (get symbol 'force-value)
     150         852 :     (put symbol 'force-value nil))
     151         852 :   (if (keywordp doc)
     152         852 :       (error "Doc string is missing"))
     153         852 :   (let ((initialize 'custom-initialize-reset)
     154             :         (requests nil))
     155         852 :     (unless (memq :group args)
     156         852 :       (custom-add-to-group (custom-current-group) symbol 'custom-variable))
     157        3091 :     (while args
     158        4478 :       (let ((keyword (pop args)))
     159        2239 :         (unless (symbolp keyword)
     160        2239 :           (error "Junk in args %S" args))
     161        2239 :         (unless args
     162        2239 :           (error "Keyword %s is missing an argument" keyword))
     163        4478 :         (let ((value (pop args)))
     164             :           ;; Can't use `pcase' because it is loaded after `custom.el'
     165             :           ;; during bootstrap.  See `loadup.el'.
     166        2239 :           (cond ((eq keyword :initialize)
     167          51 :                  (setq initialize value))
     168        2188 :                 ((eq keyword :set)
     169          63 :                  (put symbol 'custom-set value))
     170        2125 :                 ((eq keyword :get)
     171           1 :                  (put symbol 'custom-get value))
     172        2124 :                 ((eq keyword :require)
     173         230 :                  (push value requests))
     174        2009 :                 ((eq keyword :risky)
     175           9 :                  (put symbol 'risky-local-variable value))
     176        2000 :                 ((eq keyword :safe)
     177           9 :                  (put symbol 'safe-local-variable value))
     178        1991 :                 ((eq keyword :type)
     179         852 :                  (put symbol 'custom-type (purecopy value)))
     180        1139 :                 ((eq keyword :options)
     181           7 :                  (if (get symbol 'custom-options)
     182             :                      ;; Slow safe code to avoid duplicates.
     183           7 :                      (mapc (lambda (option)
     184          16 :                              (custom-add-option symbol option))
     185           7 :                            value)
     186             :                    ;; Fast code for the common case.
     187           7 :                    (put symbol 'custom-options (copy-sequence value))))
     188             :                 (t
     189        1132 :                  (custom-handle-keyword symbol keyword value
     190        2239 :                                         'custom-variable))))))
     191         852 :     (put symbol 'custom-requests requests)
     192             :     ;; Do the actual initialization.
     193         852 :     (unless custom-dont-initialize
     194         852 :       (funcall initialize symbol default)))
     195             :   ;; Use defvar to set the docstring as well as the special-variable-p flag.
     196             :   ;; FIXME: We should reproduce more of `defvar's behavior, such as the warning
     197             :   ;; when the var is currently let-bound.
     198         852 :   (if (not (default-boundp symbol))
     199             :       ;; Don't use defvar to avoid setting a default-value when undesired.
     200           0 :       (when doc (put symbol 'variable-documentation doc))
     201         852 :     (eval `(defvar ,symbol nil ,@(when doc (list doc)))))
     202        1704 :   (push symbol current-load-list)
     203         852 :   (run-hooks 'custom-define-hook)
     204         852 :   symbol)
     205             : 
     206             : (defmacro defcustom (symbol standard doc &rest args)
     207             :   "Declare SYMBOL as a customizable variable.
     208             : SYMBOL is the variable name; it should not be quoted.
     209             : STANDARD is an expression specifying the variable's standard
     210             : value.  It should not be quoted.  It is evaluated once by
     211             : `defcustom', and the value is assigned to SYMBOL if the variable
     212             : is unbound.  The expression itself is also stored, so that
     213             : Customize can re-evaluate it later to get the standard value.
     214             : DOC is the variable documentation.
     215             : 
     216             : This macro uses `defvar' as a subroutine, which also marks the
     217             : variable as \"special\", so that it is always dynamically bound
     218             : even when `lexical-binding' is t.
     219             : 
     220             : The remaining arguments to `defcustom' should have the form
     221             : 
     222             :    [KEYWORD VALUE]...
     223             : 
     224             : The following keywords are meaningful:
     225             : 
     226             : :type   VALUE should be a widget type for editing the symbol's value.
     227             :         Every `defcustom' should specify a value for this keyword.
     228             : :options VALUE should be a list of valid members of the widget type.
     229             : :initialize
     230             :         VALUE should be a function used to initialize the
     231             :         variable.  It takes two arguments, the symbol and value
     232             :         given in the `defcustom' call.  The default is
     233             :         `custom-initialize-reset'.
     234             : :set    VALUE should be a function to set the value of the symbol
     235             :         when using the Customize user interface.  It takes two arguments,
     236             :         the symbol to set and the value to give it.  The function should
     237             :         not modify its value argument destructively.  The default choice
     238             :         of function is `set-default'.
     239             : :get    VALUE should be a function to extract the value of symbol.
     240             :         The function takes one argument, a symbol, and should return
     241             :         the current value for that symbol.  The default choice of function
     242             :         is `default-value'.
     243             : :require
     244             :         VALUE should be a feature symbol.  If you save a value
     245             :         for this option, then when your init file loads the value,
     246             :         it does (require VALUE) first.
     247             : :set-after VARIABLES
     248             :         Specifies that SYMBOL should be set after the list of variables
     249             :         VARIABLES when both have been customized.
     250             : :risky  Set SYMBOL's `risky-local-variable' property to VALUE.
     251             : :safe   Set SYMBOL's `safe-local-variable' property to VALUE.
     252             :         See Info node `(elisp) File Local Variables'.
     253             : 
     254             : The following common keywords are also meaningful.
     255             : 
     256             : :group  VALUE should be a customization group.
     257             :         Add SYMBOL (or FACE with `defface') to that group.
     258             : :link LINK-DATA
     259             :         Include an external link after the documentation string for this
     260             :         item.  This is a sentence containing an active field which
     261             :         references some other documentation.
     262             : 
     263             :         There are several alternatives you can use for LINK-DATA:
     264             : 
     265             :         (custom-manual INFO-NODE)
     266             :              Link to an Info node; INFO-NODE is a string which specifies
     267             :              the node name, as in \"(emacs)Top\".
     268             : 
     269             :         (info-link INFO-NODE)
     270             :              Like `custom-manual' except that the link appears in the
     271             :              customization buffer with the Info node name.
     272             : 
     273             :         (url-link URL)
     274             :              Link to a web page; URL is a string which specifies the URL.
     275             : 
     276             :         (emacs-commentary-link LIBRARY)
     277             :              Link to the commentary section of LIBRARY.
     278             : 
     279             :         (emacs-library-link LIBRARY)
     280             :              Link to an Emacs Lisp LIBRARY file.
     281             : 
     282             :         (file-link FILE)
     283             :              Link to FILE.
     284             : 
     285             :         (function-link FUNCTION)
     286             :              Link to the documentation of FUNCTION.
     287             : 
     288             :         (variable-link VARIABLE)
     289             :              Link to the documentation of VARIABLE.
     290             : 
     291             :         (custom-group-link GROUP)
     292             :              Link to another customization GROUP.
     293             : 
     294             :         You can specify the text to use in the customization buffer by
     295             :         adding `:tag NAME' after the first element of the LINK-DATA; for
     296             :         example, (info-link :tag \"foo\" \"(emacs)Top\") makes a link to the
     297             :         Emacs manual which appears in the buffer as `foo'.
     298             : 
     299             :         An item can have more than one external link; however, most items
     300             :         have none at all.
     301             : :version
     302             :         VALUE should be a string specifying that the variable was
     303             :         first introduced, or its default value was changed, in Emacs
     304             :         version VERSION.
     305             : :package-version
     306             :         VALUE should be a list with the form (PACKAGE . VERSION)
     307             :         specifying that the variable was first introduced, or its
     308             :         default value was changed, in PACKAGE version VERSION.  This
     309             :         keyword takes priority over :version.  The PACKAGE and VERSION
     310             :         must appear in the alist `customize-package-emacs-version-alist'.
     311             :         Since PACKAGE must be unique and the user might see it in an
     312             :         error message, a good choice is the official name of the
     313             :         package, such as MH-E or Gnus.
     314             : :tag LABEL
     315             :         Use LABEL, a string, instead of the item's name, to label the item
     316             :         in customization menus and buffers.
     317             : :load FILE
     318             :         Load file FILE (a string) before displaying this customization
     319             :         item.  Loading is done with `load', and only if the file is
     320             :         not already loaded.
     321             : 
     322             : If SYMBOL has a local binding, then this form affects the local
     323             : binding.  This is normally not what you want.  Thus, if you need
     324             : to load a file defining variables with this form, or with
     325             : `defvar' or `defconst', you should always load that file
     326             : _outside_ any bindings for these variables.  (`defvar' and
     327             : `defconst' behave similarly in this respect.)
     328             : 
     329             : See Info node `(elisp) Customization' in the Emacs Lisp manual
     330             : for more information."
     331             :   (declare (doc-string 3) (debug (name body)))
     332             :   ;; It is better not to use backquote in this file,
     333             :   ;; because that makes a bootstrapping problem
     334             :   ;; if you need to recompile all the Lisp files using interpreted code.
     335         636 :   `(custom-declare-variable
     336         636 :     ',symbol
     337         636 :     ,(if lexical-binding    ;FIXME: This is not reliable, but is all we have.
     338             :          ;; The STANDARD arg should be an expression that evaluates to
     339             :          ;; the standard value.  The use of `eval' for it is spread
     340             :          ;; over many different places and hence difficult to
     341             :          ;; eliminate, yet we want to make sure that the `standard'
     342             :          ;; expression is checked by the byte-compiler, and that
     343             :          ;; lexical-binding is obeyed, so quote the expression with
     344             :          ;; `lambda' rather than with `quote'.
     345         912 :          ``(funcall #',(lambda () ,standard))
     346         636 :        `',standard)
     347         636 :     ,doc
     348         636 :     ,@args))
     349             : 
     350             : ;;; The `defface' Macro.
     351             : 
     352             : (defmacro defface (face spec doc &rest args)
     353             :   "Declare FACE as a customizable face that defaults to SPEC.
     354             : FACE does not need to be quoted.
     355             : 
     356             : Third argument DOC is the face documentation.
     357             : 
     358             : If FACE has been set with `custom-theme-set-faces', set the face
     359             : attributes as specified by that function, otherwise set the face
     360             : attributes according to SPEC.
     361             : 
     362             : The remaining arguments should have the form [KEYWORD VALUE]...
     363             : For a list of valid keywords, see the common keywords listed in
     364             : `defcustom'.
     365             : 
     366             : SPEC should be a \"face spec\", i.e., an alist of the form
     367             : 
     368             :    ((DISPLAY . ATTS)...)
     369             : 
     370             : where DISPLAY is a form specifying conditions to match certain
     371             : terminals and ATTS is a property list (ATTR VALUE ATTR VALUE...)
     372             : specifying face attributes and values for frames on those
     373             : terminals.  On each terminal, the first element with a matching
     374             : DISPLAY specification takes effect, and the remaining elements in
     375             : SPEC are disregarded.
     376             : 
     377             : As a special exception, in the first element of SPEC, DISPLAY can
     378             : be the special value `default'.  Then the ATTS in that element
     379             : act as defaults for all the following elements.
     380             : 
     381             : For backward compatibility, elements of SPEC can be written
     382             : as (DISPLAY ATTS) instead of (DISPLAY . ATTS).
     383             : 
     384             : Each DISPLAY can have the following values:
     385             :  - `default' (only in the first element).
     386             :  - The symbol t, which matches all terminals.
     387             :  - An alist of conditions.  Each alist element must have the form
     388             :    (REQ ITEM...).  A matching terminal must satisfy each
     389             :    specified condition by matching one of its ITEMs.  Each REQ
     390             :    must be one of the following:
     391             :    - `type' (the terminal type).
     392             :      Each ITEM must be one of the values returned by
     393             :      `window-system'.  Under X, additional allowed values are
     394             :      `motif', `lucid', `gtk' and `x-toolkit'.
     395             :    - `class' (the terminal's color support).
     396             :      Each ITEM should be one of `color', `grayscale', or `mono'.
     397             :    - `background' (what color is used for the background text)
     398             :      Each ITEM should be one of `light' or `dark'.
     399             :    - `min-colors' (the minimum number of supported colors)
     400             :      Each ITEM should be an integer, which is compared with the
     401             :      result of `display-color-cells'.
     402             :    - `supports' (match terminals supporting certain attributes).
     403             :      Each ITEM should be a list of face attributes.  See
     404             :      `display-supports-face-attributes-p' for more information on
     405             :      exactly how testing is done.
     406             : 
     407             : In the ATTS property list, possible attributes are `:family',
     408             : `:width', `:height', `:weight', `:slant', `:underline',
     409             : `:overline', `:strike-through', `:box', `:foreground',
     410             : `:background', `:stipple', `:inverse-video', and `:inherit'.
     411             : 
     412             : See Info node `(elisp) Faces' in the Emacs Lisp manual for more
     413             : information."
     414             :   (declare (doc-string 3))
     415             :   ;; It is better not to use backquote in this file,
     416             :   ;; because that makes a bootstrapping problem
     417             :   ;; if you need to recompile all the Lisp files using interpreted code.
     418          90 :   (nconc (list 'custom-declare-face (list 'quote face) spec doc) args))
     419             : 
     420             : ;;; The `defgroup' Macro.
     421             : 
     422             : (defun custom-current-group ()
     423          48 :   (cdr (assoc load-file-name custom-current-group-alist)))
     424             : 
     425             : (defun custom-declare-group (symbol members doc &rest args)
     426             :   "Like `defgroup', but SYMBOL is evaluated as a normal argument."
     427          79 :   (while members
     428           1 :     (apply 'custom-add-to-group symbol (car members))
     429          78 :     (setq members (cdr members)))
     430          78 :   (when doc
     431             :     ;; This text doesn't get into DOC.
     432          78 :     (put symbol 'group-documentation (purecopy doc)))
     433         244 :   (while args
     434         166 :     (let ((arg (car args)))
     435         166 :       (setq args (cdr args))
     436         166 :       (unless (symbolp arg)
     437         166 :         (error "Junk in args %S" args))
     438         166 :       (let ((keyword arg)
     439         166 :             (value (car args)))
     440         166 :         (unless args
     441         166 :           (error "Keyword %s is missing an argument" keyword))
     442         166 :         (setq args (cdr args))
     443         166 :         (cond ((eq keyword :prefix)
     444          25 :                (put symbol 'custom-prefix (purecopy value)))
     445             :               (t
     446         141 :                (custom-handle-keyword symbol keyword value
     447         166 :                                       'custom-group))))))
     448             :   ;; Record the group on the `current' list.
     449          78 :   (let ((elt (assoc load-file-name custom-current-group-alist)))
     450          78 :     (if elt (setcdr elt symbol)
     451          78 :       (push (cons load-file-name symbol) custom-current-group-alist)))
     452          78 :   (run-hooks 'custom-define-hook)
     453          78 :   symbol)
     454             : 
     455             : (defmacro defgroup (symbol members doc &rest args)
     456             :   "Declare SYMBOL as a customization group containing MEMBERS.
     457             : SYMBOL does not need to be quoted.
     458             : 
     459             : Third argument DOC is the group documentation.  This should be a short
     460             : description of the group, beginning with a capital and ending with
     461             : a period.  Words other than the first should not be capitalized, if they
     462             : are not usually written so.
     463             : 
     464             : MEMBERS should be an alist of the form ((NAME WIDGET)...) where
     465             : NAME is a symbol and WIDGET is a widget for editing that symbol.
     466             : Useful widgets are `custom-variable' for editing variables,
     467             : `custom-face' for editing faces, and `custom-group' for editing groups.
     468             : 
     469             : The remaining arguments should have the form
     470             : 
     471             :    [KEYWORD VALUE]...
     472             : 
     473             : For a list of valid keywords, see the common keywords listed in
     474             : `defcustom'.
     475             : 
     476             : See Info node `(elisp) Customization' in the Emacs Lisp manual
     477             : for more information."
     478             :   (declare (doc-string 3))
     479             :   ;; It is better not to use backquote in this file,
     480             :   ;; because that makes a bootstrapping problem
     481             :   ;; if you need to recompile all the Lisp files using interpreted code.
     482          59 :   (nconc (list 'custom-declare-group (list 'quote symbol) members doc) args))
     483             : 
     484             : (defun custom-add-to-group (group option widget)
     485             :   "To existing GROUP add a new OPTION of type WIDGET.
     486             : If there already is an entry for OPTION and WIDGET, nothing is done."
     487        1116 :   (let ((members (get group 'custom-group))
     488        1116 :         (entry (list option widget)))
     489        1116 :     (unless (member entry members)
     490        1116 :       (put group 'custom-group (nconc members (list entry))))))
     491             : 
     492             : (defun custom-group-of-mode (mode)
     493             :   "Return the custom group corresponding to the major or minor MODE.
     494             : If no such group is found, return nil."
     495           0 :   (or (get mode 'custom-mode-group)
     496           0 :       (if (or (get mode 'custom-group)
     497           0 :               (and (string-match "-mode\\'" (symbol-name mode))
     498           0 :                    (get (setq mode (intern (substring (symbol-name mode)
     499           0 :                                                       0 (match-beginning 0))))
     500           0 :                         'custom-group)))
     501           0 :           mode)))
     502             : 
     503             : ;;; Properties.
     504             : 
     505             : (defun custom-handle-all-keywords (symbol args type)
     506             :   "For customization option SYMBOL, handle keyword arguments ARGS.
     507             : Third argument TYPE is the custom option type."
     508           2 :   (unless (memq :group args)
     509           2 :     (custom-add-to-group (custom-current-group) symbol type))
     510           4 :   (while args
     511           2 :     (let ((arg (car args)))
     512           2 :       (setq args (cdr args))
     513           2 :       (unless (symbolp arg)
     514           2 :         (error "Junk in args %S" args))
     515           2 :       (let ((keyword arg)
     516           2 :             (value (car args)))
     517           2 :         (unless args
     518           2 :           (error "Keyword %s is missing an argument" keyword))
     519           2 :         (setq args (cdr args))
     520           2 :         (custom-handle-keyword symbol keyword value type)))))
     521             : 
     522             : (defun custom-handle-keyword (symbol keyword value type)
     523             :   "For customization option SYMBOL, handle KEYWORD with VALUE.
     524             : Fourth argument TYPE is the custom option type."
     525        1275 :   (if purify-flag
     526        1275 :       (setq value (purecopy value)))
     527        1275 :   (cond ((eq keyword :group)
     528         918 :          (custom-add-to-group value symbol type))
     529         357 :         ((eq keyword :version)
     530         328 :          (custom-add-version symbol value))
     531          29 :         ((eq keyword :package-version)
     532           2 :          (custom-add-package-version symbol value))
     533          27 :         ((eq keyword :link)
     534          19 :          (custom-add-link symbol value))
     535           8 :         ((eq keyword :load)
     536           0 :          (custom-add-load symbol value))
     537           8 :         ((eq keyword :tag)
     538           5 :          (put symbol 'custom-tag value))
     539           3 :         ((eq keyword :set-after)
     540           3 :          (custom-add-dependencies symbol value))
     541             :         (t
     542        1275 :          (error "Unknown keyword %s" keyword))))
     543             : 
     544             : (defun custom-add-dependencies (symbol value)
     545             :   "To the custom option SYMBOL, add dependencies specified by VALUE.
     546             : VALUE should be a list of symbols.  For each symbol in that list,
     547             : this specifies that SYMBOL should be set after the specified symbol,
     548             : if both appear in constructs like `custom-set-variables'."
     549           3 :   (unless (listp value)
     550           3 :     (error "Invalid custom dependency `%s'" value))
     551           3 :   (let* ((deps (get symbol 'custom-dependencies))
     552           3 :          (new-deps deps))
     553           8 :     (while value
     554           5 :       (let ((dep (car value)))
     555           5 :         (unless (symbolp dep)
     556           5 :           (error "Invalid custom dependency `%s'" dep))
     557           5 :         (unless (memq dep new-deps)
     558           5 :           (setq new-deps (cons dep new-deps)))
     559           5 :         (setq value (cdr value))))
     560           3 :     (unless (eq deps new-deps)
     561           3 :       (put symbol 'custom-dependencies new-deps))))
     562             : 
     563             : (defun custom-add-option (symbol option)
     564             :   "To the variable SYMBOL add OPTION.
     565             : 
     566             : If SYMBOL's custom type is a hook, OPTION should be a hook member.
     567             : If SYMBOL's custom type is an alist, OPTION specifies a symbol
     568             : to offer to the user as a possible key in the alist.
     569             : For other custom types, this has no effect."
     570          17 :   (let ((options (get symbol 'custom-options)))
     571          17 :     (unless (member option options)
     572          17 :       (put symbol 'custom-options (cons option options)))))
     573             : (defalias 'custom-add-frequent-value 'custom-add-option)
     574             : 
     575             : (defun custom-add-link (symbol widget)
     576             :   "To the custom option SYMBOL add the link WIDGET."
     577          19 :   (let ((links (get symbol 'custom-links)))
     578          19 :     (unless (member widget links)
     579          19 :       (put symbol 'custom-links (cons (purecopy widget) links)))))
     580             : 
     581             : (defun custom-add-version (symbol version)
     582             :   "To the custom option SYMBOL add the version VERSION."
     583         328 :   (put symbol 'custom-version (purecopy version)))
     584             : 
     585             : (defun custom-add-package-version (symbol version)
     586             :   "To the custom option SYMBOL add the package version VERSION."
     587           2 :   (put symbol 'custom-package-version (purecopy version)))
     588             : 
     589             : (defun custom-add-load (symbol load)
     590             :   "To the custom option SYMBOL add the dependency LOAD.
     591             : LOAD should be either a library file name, or a feature name."
     592         255 :   (let ((loads (get symbol 'custom-loads)))
     593         255 :     (unless (member load loads)
     594         255 :       (put symbol 'custom-loads (cons (purecopy load) loads)))))
     595             : 
     596             : (defun custom-autoload (symbol load &optional noset)
     597             :   "Mark SYMBOL as autoloaded custom variable and add dependency LOAD.
     598             : If NOSET is non-nil, don't bother autoloading LOAD when setting the variable."
     599         255 :   (put symbol 'custom-autoload (if noset 'noset t))
     600         255 :   (custom-add-load symbol load))
     601             : 
     602             : (defun custom-variable-p (variable)
     603             :   "Return non-nil if VARIABLE is a customizable variable.
     604             : A customizable variable is either (i) a variable whose property
     605             : list contains a non-nil `standard-value' or `custom-autoload'
     606             : property, or (ii) an alias for another customizable variable."
     607           0 :   (when (symbolp variable)
     608           0 :     (setq variable (indirect-variable variable))
     609           0 :     (or (get variable 'standard-value)
     610           0 :         (get variable 'custom-autoload))))
     611             : 
     612             : (define-obsolete-function-alias 'user-variable-p 'custom-variable-p "24.3")
     613             : 
     614             : (defun custom-note-var-changed (variable)
     615             :   "Inform Custom that VARIABLE has been set (changed).
     616             : VARIABLE is a symbol that names a user option.
     617             : The result is that the change is treated as having been made through Custom."
     618           0 :   (put variable 'customized-value (list (custom-quote (eval variable)))))
     619             : 
     620             : 
     621             : ;;; Custom Themes
     622             : 
     623             : ;;; Loading files needed to customize a symbol.
     624             : ;;; This is in custom.el because menu-bar.el needs it for toggle cmds.
     625             : 
     626             : (defvar custom-load-recursion nil
     627             :   "Hack to avoid recursive dependencies.")
     628             : 
     629             : (defun custom-load-symbol (symbol)
     630             :   "Load all dependencies for SYMBOL."
     631           0 :   (unless custom-load-recursion
     632           0 :     (let ((custom-load-recursion t))
     633             :       ;; Load these files if not already done,
     634             :       ;; to make sure we know all the dependencies of SYMBOL.
     635           0 :       (condition-case nil
     636           0 :           (require 'cus-load)
     637           0 :         (error nil))
     638           0 :       (condition-case nil
     639           0 :           (require 'cus-start)
     640           0 :         (error nil))
     641           0 :       (dolist (load (get symbol 'custom-loads))
     642           0 :         (cond ((symbolp load) (condition-case nil (require load) (error nil)))
     643             :               ;; This is subsumed by the test below, but it's much faster.
     644           0 :               ((assoc load load-history))
     645             :               ;; This was just (assoc (locate-library load) load-history)
     646             :               ;; but has been optimized not to load locate-library
     647             :               ;; if not necessary.
     648           0 :               ((let ((regexp (concat "\\(\\`\\|/\\)" (regexp-quote load)
     649           0 :                                      "\\(\\'\\|\\.\\)"))
     650             :                      (found nil))
     651           0 :                  (dolist (loaded load-history)
     652           0 :                    (and (stringp (car loaded))
     653           0 :                         (string-match-p regexp (car loaded))
     654           0 :                         (setq found t)))
     655           0 :                  found))
     656             :               ;; Without this, we would load cus-edit recursively.
     657             :               ;; We are still loading it when we call this,
     658             :               ;; and it is not in load-history yet.
     659           0 :               ((equal load "cus-edit"))
     660           0 :               (t (condition-case nil (load load) (error nil))))))))
     661             : 
     662             : (defvar custom-local-buffer nil
     663             :   "Non-nil, in a Customization buffer, means customize a specific buffer.
     664             : If this variable is non-nil, it should be a buffer,
     665             : and it means customize the local bindings of that buffer.
     666             : This variable is a permanent local, and it normally has a local binding
     667             : in every Customization buffer.")
     668             : (put 'custom-local-buffer 'permanent-local t)
     669             : 
     670             : (defun custom-set-default (variable value)
     671             :   "Default :set function for a customizable variable.
     672             : Normally, this sets the default value of VARIABLE to VALUE,
     673             : but if `custom-local-buffer' is non-nil,
     674             : this sets the local binding in that buffer instead."
     675           2 :   (if custom-local-buffer
     676           0 :       (with-current-buffer custom-local-buffer
     677           0 :         (set variable value))
     678           2 :     (set-default variable value)))
     679             : 
     680             : (defun custom-set-minor-mode (variable value)
     681             :   ":set function for minor mode variables.
     682             : Normally, this sets the default value of VARIABLE to nil if VALUE
     683             : is nil and to t otherwise,
     684             : but if `custom-local-buffer' is non-nil,
     685             : this sets the local binding in that buffer instead."
     686           0 :   (if custom-local-buffer
     687           0 :       (with-current-buffer custom-local-buffer
     688           0 :         (funcall variable (if value 1 0)))
     689           0 :     (funcall variable (if value 1 0))))
     690             : 
     691             : (defun custom-quote (sexp)
     692             :   "Quote SEXP if it is not self quoting."
     693           0 :   (if (or (memq sexp '(t nil))
     694           0 :           (keywordp sexp)
     695           0 :           (and (listp sexp)
     696           0 :                (memq (car sexp) '(lambda)))
     697           0 :           (stringp sexp)
     698           0 :           (numberp sexp)
     699           0 :           (vectorp sexp)
     700             : ;;;       (and (fboundp 'characterp)
     701             : ;;;            (characterp sexp))
     702           0 :           )
     703           0 :       sexp
     704           0 :     (list 'quote sexp)))
     705             : 
     706             : (defun customize-mark-to-save (symbol)
     707             :   "Mark SYMBOL for later saving.
     708             : 
     709             : If the default value of SYMBOL is different from the standard value,
     710             : set the `saved-value' property to a list whose car evaluates to the
     711             : default value.  Otherwise, set it to nil.
     712             : 
     713             : To actually save the value, call `custom-save-all'.
     714             : 
     715             : Return non-nil if the `saved-value' property actually changed."
     716           0 :   (custom-load-symbol symbol)
     717           0 :   (let* ((get (or (get symbol 'custom-get) 'default-value))
     718           0 :          (value (funcall get symbol))
     719           0 :          (saved (get symbol 'saved-value))
     720           0 :          (standard (get symbol 'standard-value))
     721           0 :          (comment (get symbol 'customized-variable-comment)))
     722             :     ;; Save default value if different from standard value.
     723           0 :     (if (or (null standard)
     724           0 :             (not (equal value (condition-case nil
     725           0 :                                   (eval (car standard))
     726           0 :                                 (error nil)))))
     727           0 :         (put symbol 'saved-value (list (custom-quote value)))
     728           0 :       (put symbol 'saved-value nil))
     729             :     ;; Clear customized information (set, but not saved).
     730           0 :     (put symbol 'customized-value nil)
     731             :     ;; Save any comment that might have been set.
     732           0 :     (when comment
     733           0 :       (put symbol 'saved-variable-comment comment))
     734           0 :     (not (equal saved (get symbol 'saved-value)))))
     735             : 
     736             : (defun customize-mark-as-set (symbol)
     737             :   "Mark current value of SYMBOL as being set from customize.
     738             : 
     739             : If the default value of SYMBOL is different from the saved value if any,
     740             : or else if it is different from the standard value, set the
     741             : `customized-value' property to a list whose car evaluates to the
     742             : default value.  Otherwise, set it to nil.
     743             : 
     744             : Return non-nil if the `customized-value' property actually changed."
     745           0 :   (custom-load-symbol symbol)
     746           0 :   (let* ((get (or (get symbol 'custom-get) 'default-value))
     747           0 :          (value (funcall get symbol))
     748           0 :          (customized (get symbol 'customized-value))
     749           0 :          (old (or (get symbol 'saved-value) (get symbol 'standard-value))))
     750             :     ;; Mark default value as set if different from old value.
     751           0 :     (if (not (and old
     752           0 :                   (equal value (condition-case nil
     753           0 :                                    (eval (car old))
     754           0 :                                  (error nil)))))
     755           0 :         (progn (put symbol 'customized-value (list (custom-quote value)))
     756           0 :                (custom-push-theme 'theme-value symbol 'user 'set
     757           0 :                                   (custom-quote value)))
     758           0 :       (put symbol 'customized-value nil))
     759             :     ;; Changed?
     760           0 :     (not (equal customized (get symbol 'customized-value)))))
     761             : 
     762             : (defun custom-reevaluate-setting (symbol)
     763             :   "Reset the value of SYMBOL by re-evaluating its saved or standard value.
     764             : Use the :set function to do so.  This is useful for customizable options
     765             : that are defined before their standard value can really be computed.
     766             : E.g. dumped variables whose default depends on run-time information."
     767             :   ;; If it has never been set at all, defvar it so as to mark it
     768             :   ;; special, etc (bug#25770).  This means we are initializing
     769             :   ;; the variable, and normally any :set function would not apply.
     770             :   ;; For custom-initialize-delay, however, it is documented that "the
     771             :   ;; (delayed) initialization is performed with the :set function".
     772             :   ;; This is needed by eg global-font-lock-mode, which uses
     773             :   ;; custom-initialize-delay but needs the :set function custom-set-minor-mode
     774             :   ;; to also run during initialization.  So, long story short, we
     775             :   ;; always do the funcall step, even if symbol was not bound before.
     776           0 :   (or (default-boundp symbol)
     777           0 :       (eval `(defvar ,symbol nil))) ; reset below, so any value is fine
     778           0 :   (funcall (or (get symbol 'custom-set) 'set-default)
     779           0 :            symbol
     780           0 :            (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value))))))
     781             : 
     782             : 
     783             : ;;; Custom Themes
     784             : 
     785             : ;; Custom themes are collections of settings that can be enabled or
     786             : ;; disabled as a unit.
     787             : 
     788             : ;; Each Custom theme is defined by a symbol, called the theme name.
     789             : ;; The `theme-settings' property of the theme name records the
     790             : ;; variable and face settings of the theme.  This property is a list
     791             : ;; of elements, each of the form
     792             : ;;
     793             : ;;     (PROP SYMBOL THEME VALUE)
     794             : ;;
     795             : ;;  - PROP is either `theme-value' or `theme-face'
     796             : ;;  - SYMBOL is the face or variable name
     797             : ;;  - THEME is the theme name (redundant, but simplifies the code)
     798             : ;;  - VALUE is an expression that gives the theme's setting for SYMBOL.
     799             : ;;
     800             : ;; The theme name also has a `theme-feature' property, whose value is
     801             : ;; specified when the theme is defined (see `custom-declare-theme').
     802             : ;; Usually, this is just a symbol named THEME-theme.  This lets
     803             : ;; external libraries call (require 'foo-theme).
     804             : 
     805             : ;; In addition, each symbol (either a variable or a face) affected by
     806             : ;; an *enabled* theme has a `theme-value' or `theme-face' property,
     807             : ;; which is a list of elements each of the form
     808             : ;;
     809             : ;;     (THEME VALUE)
     810             : ;;
     811             : ;; which have the same meanings as in `theme-settings'.
     812             : ;;
     813             : ;; The `theme-value' and `theme-face' lists are ordered by decreasing
     814             : ;; theme precedence.  Thus, the first element is always the one that
     815             : ;; is in effect.
     816             : 
     817             : ;; Each theme is stored in a theme file, with filename THEME-theme.el.
     818             : ;; Loading a theme basically involves calling (load "THEME-theme")
     819             : ;; This is done by the function `load-theme'.  Loading a theme
     820             : ;; automatically enables it.
     821             : ;;
     822             : ;; When a theme is enabled, the `theme-value' and `theme-face'
     823             : ;; properties for the affected symbols are set.  When a theme is
     824             : ;; disabled, its settings are removed from the `theme-value' and
     825             : ;; `theme-face' properties, but the theme's own `theme-settings'
     826             : ;; property remains unchanged.
     827             : 
     828             : (defvar custom-known-themes '(user changed)
     829             :    "Themes that have been defined with `deftheme'.
     830             : The default value is the list (user changed).  The theme `changed'
     831             : contains the settings before custom themes are applied.  The theme
     832             : `user' contains all the settings the user customized and saved.
     833             : Additional themes declared with the `deftheme' macro will be added
     834             : to the front of this list.")
     835             : 
     836             : (defsubst custom-theme-p (theme)
     837             :   "Non-nil when THEME has been defined."
     838          13 :   (memq theme custom-known-themes))
     839             : 
     840             : (defsubst custom-check-theme (theme)
     841             :   "Check whether THEME is valid, and signal an error if it is not."
     842          12 :   (unless (custom-theme-p theme)
     843          12 :     (error "Unknown theme `%s'" theme)))
     844             : 
     845             : (defun custom-push-theme (prop symbol theme mode &optional value)
     846             :   "Record VALUE for face or variable SYMBOL in custom theme THEME.
     847             : PROP is `theme-face' for a face, `theme-value' for a variable.
     848             : 
     849             : MODE can be either the symbol `set' or the symbol `reset'.  If it is the
     850             : symbol `set', then VALUE is the value to use.  If it is the symbol
     851             : `reset', then SYMBOL will be removed from THEME (VALUE is ignored).
     852             : 
     853             : See `custom-known-themes' for a list of known themes."
     854          12 :   (unless (memq prop '(theme-value theme-face))
     855          12 :     (error "Unknown theme property"))
     856          12 :   (let* ((old (get symbol prop))
     857          12 :          (setting (assq theme old))  ; '(theme value)
     858             :          (theme-settings             ; '(prop symbol theme value)
     859          12 :           (get theme 'theme-settings)))
     860          12 :     (cond
     861             :      ;; Remove a setting:
     862          12 :      ((eq mode 'reset)
     863           0 :       (when setting
     864           0 :         (let (res)
     865           0 :           (dolist (theme-setting theme-settings)
     866           0 :             (if (and (eq (car  theme-setting) prop)
     867           0 :                      (eq (cadr theme-setting) symbol))
     868           0 :                 (setq res theme-setting)))
     869           0 :           (put theme 'theme-settings (delq res theme-settings)))
     870           0 :         (put symbol prop (delq setting old))))
     871             :      ;; Alter an existing setting:
     872          12 :      (setting
     873          11 :       (let (res)
     874          11 :         (dolist (theme-setting theme-settings)
     875          11 :           (if (and (eq (car  theme-setting) prop)
     876          11 :                    (eq (cadr theme-setting) symbol))
     877          11 :               (setq res theme-setting)))
     878          11 :         (put theme 'theme-settings
     879          11 :              (cons (list prop symbol theme value)
     880          11 :                    (delq res theme-settings)))
     881          11 :         (setcar (cdr setting) value)))
     882             :      ;; Add a new setting:
     883             :      (t
     884           1 :       (unless custom--inhibit-theme-enable
     885           1 :         (unless old
     886             :           ;; If the user changed a variable outside of Customize, save
     887             :           ;; the value to a fake theme, `changed'.  If the theme is
     888             :           ;; later disabled, we use this to bring back the old value.
     889             :           ;;
     890             :           ;; For faces, we just use `face-new-frame-defaults' to
     891             :           ;; recompute when the theme is disabled.
     892           1 :           (when (and (eq prop 'theme-value)
     893           1 :                      (boundp symbol))
     894           1 :             (let ((sv  (get symbol 'standard-value))
     895           1 :                   (val (symbol-value symbol)))
     896           1 :               (unless (and sv (equal (eval (car sv)) val))
     897           1 :                 (setq old `((changed ,(custom-quote val))))))))
     898           1 :         (put symbol prop (cons (list theme value) old)))
     899           1 :       (put theme 'theme-settings
     900          12 :            (cons (list prop symbol theme value) theme-settings))))))
     901             : 
     902             : (defun custom-fix-face-spec (spec)
     903             :   "Convert face SPEC, replacing obsolete :bold and :italic attributes.
     904             : Also change :reverse-video to :inverse-video."
     905           0 :   (when (listp spec)
     906           0 :     (if (or (memq :bold spec)
     907           0 :             (memq :italic spec)
     908           0 :             (memq :inverse-video spec))
     909           0 :         (let (result)
     910           0 :           (while spec
     911           0 :             (let ((key (car spec))
     912           0 :                   (val (car (cdr spec))))
     913           0 :               (cond ((eq key :italic)
     914           0 :                      (push :slant result)
     915           0 :                      (push (if val 'italic 'normal) result))
     916           0 :                     ((eq key :bold)
     917           0 :                      (push :weight result)
     918           0 :                      (push (if val 'bold 'normal) result))
     919           0 :                     ((eq key :reverse-video)
     920           0 :                      (push :inverse-video result)
     921           0 :                      (push val result))
     922             :                     (t
     923           0 :                      (push key result)
     924           0 :                      (push val result))))
     925           0 :             (setq spec (cddr spec)))
     926           0 :           (nreverse result))
     927           0 :       spec)))
     928             : 
     929             : (defun custom-set-variables (&rest args)
     930             :   "Install user customizations of variable values specified in ARGS.
     931             : These settings are registered as theme `user'.
     932             : The arguments should each be a list of the form:
     933             : 
     934             :   (SYMBOL EXP [NOW [REQUEST [COMMENT]]])
     935             : 
     936             : This stores EXP (without evaluating it) as the saved value for SYMBOL.
     937             : If NOW is present and non-nil, then also evaluate EXP and set
     938             : the default value for the SYMBOL to the value of EXP.
     939             : 
     940             : REQUEST is a list of features we must require in order to
     941             : handle SYMBOL properly.
     942             : COMMENT is a comment string about SYMBOL."
     943          12 :   (apply 'custom-theme-set-variables 'user args))
     944             : 
     945             : (defun custom-theme-set-variables (theme &rest args)
     946             :   "Initialize variables for theme THEME according to settings in ARGS.
     947             : Each of the arguments in ARGS should be a list of this form:
     948             : 
     949             :   (SYMBOL EXP [NOW [REQUEST [COMMENT]]])
     950             : 
     951             : SYMBOL is the variable name, and EXP is an expression which
     952             : evaluates to the customized value.  EXP will also be stored,
     953             : without evaluating it, in SYMBOL's `saved-value' property, so
     954             : that it can be restored via the Customize interface.  It is also
     955             : added to the alist in SYMBOL's `theme-value' property (by
     956             : calling `custom-push-theme').
     957             : 
     958             : NOW, if present and non-nil, means to install the variable's
     959             : value directly now, even if its `defcustom' declaration has not
     960             : been executed.  This is for internal use only.
     961             : 
     962             : REQUEST is a list of features to `require' (which are loaded
     963             : prior to evaluating EXP).
     964             : 
     965             : COMMENT is a comment string about SYMBOL."
     966          12 :   (custom-check-theme theme)
     967             :   ;; Process all the needed autoloads before anything else, so that the
     968             :   ;; subsequent code has all the info it needs (e.g. which var corresponds
     969             :   ;; to a minor mode), regardless of the ordering of the variables.
     970          12 :   (dolist (entry args)
     971          12 :     (let* ((symbol (indirect-variable (nth 0 entry))))
     972          12 :       (unless (or (get symbol 'standard-value)
     973          12 :                   (memq (get symbol 'custom-autoload) '(nil noset)))
     974             :         ;; This symbol needs to be autoloaded, even just for a `set'.
     975          12 :         (custom-load-symbol symbol))))
     976          12 :   (setq args (custom--sort-vars args))
     977          12 :   (dolist (entry args)
     978          12 :     (unless (listp entry)
     979          12 :       (error "Incompatible Custom theme spec"))
     980          12 :     (let* ((symbol (indirect-variable (nth 0 entry)))
     981          12 :            (value (nth 1 entry)))
     982          12 :       (custom-push-theme 'theme-value symbol theme 'set value)
     983          12 :       (unless custom--inhibit-theme-enable
     984             :         ;; Now set the variable.
     985          12 :         (let* ((now (nth 2 entry))
     986          12 :                (requests (nth 3 entry))
     987          12 :                (comment (nth 4 entry))
     988             :                set)
     989          12 :           (when requests
     990           0 :             (put symbol 'custom-requests requests)
     991          12 :             (mapc 'require requests))
     992          12 :           (setq set (or (get symbol 'custom-set) 'custom-set-default))
     993          12 :           (put symbol 'saved-value (list value))
     994          12 :           (put symbol 'saved-variable-comment comment)
     995             :           ;; Allow for errors in the case where the setter has
     996             :           ;; changed between versions, say, but let the user know.
     997          12 :           (condition-case data
     998          12 :               (cond (now
     999             :                      ;; Rogue variable, set it now.
    1000           0 :                      (put symbol 'force-value t)
    1001           0 :                      (funcall set symbol (eval value)))
    1002          12 :                     ((default-boundp symbol)
    1003             :                      ;; Something already set this, overwrite it.
    1004          12 :                      (funcall set symbol (eval value))))
    1005             :             (error
    1006          12 :              (message "Error setting %s: %s" symbol data)))
    1007          12 :           (and (or now (default-boundp symbol))
    1008          12 :                (put symbol 'variable-comment comment)))))))
    1009             : 
    1010             : (defvar custom--sort-vars-table)
    1011             : (defvar custom--sort-vars-result)
    1012             : 
    1013             : (defun custom--sort-vars (vars)
    1014             :   "Sort VARS based on custom dependencies.
    1015             : VARS is a list whose elements have the same form as the ARGS
    1016             : arguments to `custom-theme-set-variables'.  Return the sorted
    1017             : list, in which A occurs before B if B was defined with a
    1018             : `:set-after' keyword specifying A (see `defcustom')."
    1019          12 :   (let ((custom--sort-vars-table (make-hash-table))
    1020          12 :         (dependants (make-hash-table))
    1021             :         (custom--sort-vars-result nil)
    1022             :         last)
    1023             :     ;; Construct a pair of tables keyed with the symbols of VARS.
    1024          12 :     (dolist (var vars)
    1025          12 :       (puthash (car var) (cons t var) custom--sort-vars-table)
    1026          12 :       (puthash (car var) var dependants))
    1027             :     ;; From the second table, remove symbols that are depended-on.
    1028          12 :     (dolist (var vars)
    1029          12 :       (dolist (dep (get (car var) 'custom-dependencies))
    1030          12 :         (remhash dep dependants)))
    1031             :     ;; If a variable is "stand-alone", put it last if it's a minor
    1032             :     ;; mode or has a :require flag.  This is not really necessary, but
    1033             :     ;; putting minor modes last helps ensure that the mode function
    1034             :     ;; sees other customized values rather than default values.
    1035          12 :     (maphash (lambda (sym var)
    1036          12 :                (when (and (null (get sym 'custom-dependencies))
    1037          12 :                           (or (nth 3 var)
    1038          12 :                               (eq (get sym 'custom-set)
    1039          12 :                                   'custom-set-minor-mode)))
    1040           0 :                  (remhash sym dependants)
    1041          12 :                  (push var last)))
    1042          12 :              dependants)
    1043             :     ;; The remaining symbols depend on others but are not
    1044             :     ;; depended-upon.  Do a depth-first topological sort.
    1045          12 :     (maphash #'custom--sort-vars-1 dependants)
    1046          12 :     (nreverse (append last custom--sort-vars-result))))
    1047             : 
    1048             : (defun custom--sort-vars-1 (sym &optional _ignored)
    1049          12 :   (let ((elt (gethash sym custom--sort-vars-table)))
    1050             :     ;; The car of the hash table value is nil if the variable has
    1051             :     ;; already been processed, `dependant' if it is a dependant in the
    1052             :     ;; current graph descent, and t otherwise.
    1053          12 :     (when elt
    1054          12 :       (cond
    1055          12 :        ((eq (car elt) 'dependant)
    1056           0 :         (error "Circular custom dependency on `%s'" sym))
    1057          12 :        ((car elt)
    1058          12 :         (setcar elt 'dependant)
    1059          12 :         (dolist (dep (get sym 'custom-dependencies))
    1060          12 :           (custom--sort-vars-1 dep))
    1061          12 :         (setcar elt nil)
    1062          24 :         (push (cdr elt) custom--sort-vars-result))))))
    1063             : 
    1064             : 
    1065             : ;;; Defining themes.
    1066             : 
    1067             : ;; A theme file is named `THEME-theme.el' (where THEME is the theme
    1068             : ;; name) found in `custom-theme-load-path'.  It has this format:
    1069             : ;;
    1070             : ;;   (deftheme THEME
    1071             : ;;     DOCSTRING)
    1072             : ;;
    1073             : ;;   (custom-theme-set-variables
    1074             : ;;    'THEME
    1075             : ;;    [THEME-VARIABLES])
    1076             : ;;
    1077             : ;;   (custom-theme-set-faces
    1078             : ;;    'THEME
    1079             : ;;    [THEME-FACES])
    1080             : ;;
    1081             : ;;   (provide-theme 'THEME)
    1082             : 
    1083             : 
    1084             : ;; The IGNORED arguments to deftheme come from the XEmacs theme code, where
    1085             : ;; they were used to supply keyword-value pairs like `:immediate',
    1086             : ;; `:variable-reset-string', etc.  We don't use any of these, so ignore them.
    1087             : 
    1088             : (defmacro deftheme (theme &optional doc &rest ignored)
    1089             :   "Declare THEME to be a Custom theme.
    1090             : The optional argument DOC is a doc string describing the theme.
    1091             : 
    1092             : Any theme `foo' should be defined in a file called `foo-theme.el';
    1093             : see `custom-make-theme-feature' for more information."
    1094             :   (declare (doc-string 2))
    1095           0 :   (let ((feature (custom-make-theme-feature theme)))
    1096             :     ;; It is better not to use backquote in this file,
    1097             :     ;; because that makes a bootstrapping problem
    1098             :     ;; if you need to recompile all the Lisp files using interpreted code.
    1099           0 :     (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc)))
    1100             : 
    1101             : (defun custom-declare-theme (theme feature &optional doc &rest ignored)
    1102             :   "Like `deftheme', but THEME is evaluated as a normal argument.
    1103             : FEATURE is the feature this theme provides.  Normally, this is a symbol
    1104             : created from THEME by `custom-make-theme-feature'."
    1105           0 :   (unless (custom-theme-name-valid-p theme)
    1106           0 :     (error "Custom theme cannot be named %S" theme))
    1107           0 :   (add-to-list 'custom-known-themes theme)
    1108           0 :   (put theme 'theme-feature feature)
    1109           0 :   (when doc (put theme 'theme-documentation doc)))
    1110             : 
    1111             : (defun custom-make-theme-feature (theme)
    1112             :   "Given a symbol THEME, create a new symbol by appending \"-theme\".
    1113             : Store this symbol in the `theme-feature' property of THEME.
    1114             : Calling `provide-theme' to provide THEME actually puts `THEME-theme'
    1115             : into `features'.
    1116             : 
    1117             : This allows for a file-name convention for autoloading themes:
    1118             : Every theme X has a property `provide-theme' whose value is \"X-theme\".
    1119             : \(load-theme X) then attempts to load the file `X-theme.el'."
    1120           0 :   (intern (concat (symbol-name theme) "-theme")))
    1121             : 
    1122             : ;;; Loading themes.
    1123             : 
    1124             : (defcustom custom-theme-directory user-emacs-directory
    1125             :   "Default user directory for storing custom theme files.
    1126             : The command `customize-create-theme' writes theme files into this
    1127             : directory.  By default, Emacs searches for custom themes in this
    1128             : directory first---see `custom-theme-load-path'."
    1129             :   :type 'string
    1130             :   :group 'customize
    1131             :   :version "22.1")
    1132             : 
    1133             : (defvar custom-theme-load-path (list 'custom-theme-directory t)
    1134             :   "List of directories to search for custom theme files.
    1135             : When loading custom themes (e.g. in `customize-themes' and
    1136             : `load-theme'), Emacs searches for theme files in the specified
    1137             : order.  Each element in the list should be one of the following:
    1138             : - the symbol `custom-theme-directory', meaning the value of
    1139             :   `custom-theme-directory'.
    1140             : - the symbol t, meaning the built-in theme directory (a directory
    1141             :   named \"themes\" in `data-directory').
    1142             : - a directory name (a string).
    1143             : 
    1144             : Each theme file is named THEME-theme.el, where THEME is the theme
    1145             : name.
    1146             : 
    1147             : This variable is designed for use in lisp code (including
    1148             : external packages).  For manual user customizations, use
    1149             : `custom-theme-directory' instead.")
    1150             : 
    1151             : (defvar custom--inhibit-theme-enable nil
    1152             :   "Whether the custom-theme-set-* functions act immediately.
    1153             : If nil, `custom-theme-set-variables' and `custom-theme-set-faces'
    1154             : change the current values of the given variable or face.  If
    1155             : non-nil, they just make a record of the theme settings.")
    1156             : 
    1157             : (defun provide-theme (theme)
    1158             :   "Indicate that this file provides THEME.
    1159             : This calls `provide' to provide the feature name stored in THEME's
    1160             : property `theme-feature' (which is usually a symbol created by
    1161             : `custom-make-theme-feature')."
    1162           0 :   (unless (custom-theme-name-valid-p theme)
    1163           0 :     (error "Custom theme cannot be named %S" theme))
    1164           0 :   (custom-check-theme theme)
    1165           0 :   (provide (get theme 'theme-feature)))
    1166             : 
    1167             : (defcustom custom-safe-themes '(default)
    1168             :   "Themes that are considered safe to load.
    1169             : If the value is a list, each element should be either the SHA-256
    1170             : hash of a safe theme file, or the symbol `default', which stands
    1171             : for any theme in the built-in Emacs theme directory (a directory
    1172             : named \"themes\" in `data-directory').
    1173             : 
    1174             : If the value is t, Emacs treats all themes as safe.
    1175             : 
    1176             : This variable cannot be set in a Custom theme."
    1177             :   :type '(choice (repeat :tag "List of safe themes"
    1178             :                          (choice string
    1179             :                                  (const :tag "Built-in themes" default)))
    1180             :                  (const :tag "All themes" t))
    1181             :   :group 'customize
    1182             :   :risky t
    1183             :   :version "24.1")
    1184             : 
    1185             : (defun load-theme (theme &optional no-confirm no-enable)
    1186             :   "Load Custom theme named THEME from its file.
    1187             : The theme file is named THEME-theme.el, in one of the directories
    1188             : specified by `custom-theme-load-path'.
    1189             : 
    1190             : If the theme is not considered safe by `custom-safe-themes',
    1191             : prompt the user for confirmation before loading it.  But if
    1192             : optional arg NO-CONFIRM is non-nil, load the theme without
    1193             : prompting.
    1194             : 
    1195             : Normally, this function also enables THEME.  If optional arg
    1196             : NO-ENABLE is non-nil, load the theme but don't enable it, unless
    1197             : the theme was already enabled.
    1198             : 
    1199             : This function is normally called through Customize when setting
    1200             : `custom-enabled-themes'.  If used directly in your init file, it
    1201             : should be called with a non-nil NO-CONFIRM argument, or after
    1202             : `custom-safe-themes' has been loaded.
    1203             : 
    1204             : Return t if THEME was successfully loaded, nil otherwise."
    1205             :   (interactive
    1206           0 :    (list
    1207           0 :     (intern (completing-read "Load custom theme: "
    1208           0 :                              (mapcar 'symbol-name
    1209           0 :                                      (custom-available-themes))))
    1210           0 :     nil nil))
    1211           0 :   (unless (custom-theme-name-valid-p theme)
    1212           0 :     (error "Invalid theme name `%s'" theme))
    1213             :   ;; If THEME is already enabled, re-enable it after loading, even if
    1214             :   ;; NO-ENABLE is t.
    1215           0 :   (if no-enable
    1216           0 :       (setq no-enable (not (custom-theme-enabled-p theme))))
    1217             :   ;; If reloading, clear out the old theme settings.
    1218           0 :   (when (custom-theme-p theme)
    1219           0 :     (disable-theme theme)
    1220           0 :     (put theme 'theme-settings nil)
    1221           0 :     (put theme 'theme-feature nil)
    1222           0 :     (put theme 'theme-documentation nil))
    1223           0 :   (let ((fn (locate-file (concat (symbol-name theme) "-theme.el")
    1224           0 :                          (custom-theme--load-path)
    1225           0 :                          '("" "c"))))
    1226           0 :     (unless fn
    1227           0 :       (error "Unable to find theme file for `%s'" theme))
    1228           0 :     (with-temp-buffer
    1229           0 :       (insert-file-contents fn)
    1230             :       ;; Check file safety with `custom-safe-themes', prompting the
    1231             :       ;; user if necessary.
    1232           0 :       (when (or no-confirm
    1233           0 :                 (eq custom-safe-themes t)
    1234           0 :                 (and (memq 'default custom-safe-themes)
    1235           0 :                      (equal (file-name-directory fn)
    1236           0 :                             (expand-file-name "themes/" data-directory)))
    1237           0 :                 (let ((hash (secure-hash 'sha256 (current-buffer))))
    1238           0 :                   (or (member hash custom-safe-themes)
    1239           0 :                       (custom-theme-load-confirm hash))))
    1240           0 :         (let ((custom--inhibit-theme-enable t)
    1241           0 :               (buffer-file-name fn))    ;For load-history.
    1242           0 :           (eval-buffer))
    1243             :         ;; Optimization: if the theme changes the `default' face, put that
    1244             :         ;; entry first.  This avoids some `frame-set-background-mode' rigmarole
    1245             :         ;; by assigning the new background immediately.
    1246           0 :         (let* ((settings (get theme 'theme-settings))
    1247           0 :                (tail settings)
    1248             :                found)
    1249           0 :           (while (and tail (not found))
    1250           0 :             (and (eq (nth 0 (car tail)) 'theme-face)
    1251           0 :                  (eq (nth 1 (car tail)) 'default)
    1252           0 :                  (setq found (car tail)))
    1253           0 :             (setq tail (cdr tail)))
    1254           0 :           (if found
    1255           0 :               (put theme 'theme-settings (cons found (delq found settings)))))
    1256             :         ;; Finally, enable the theme.
    1257           0 :         (unless no-enable
    1258           0 :           (enable-theme theme))
    1259           0 :         t))))
    1260             : 
    1261             : (defun custom-theme-load-confirm (hash)
    1262             :   "Query the user about loading a Custom theme that may not be safe.
    1263             : The theme should be in the current buffer.  If the user agrees,
    1264             : query also about adding HASH to `custom-safe-themes'."
    1265           0 :   (unless noninteractive
    1266           0 :     (save-window-excursion
    1267           0 :       (rename-buffer "*Custom Theme*" t)
    1268           0 :       (emacs-lisp-mode)
    1269           0 :       (pop-to-buffer (current-buffer))
    1270           0 :       (goto-char (point-min))
    1271           0 :       (prog1 (when (y-or-n-p "Loading a theme can run Lisp code.  Really load? ")
    1272             :                ;; Offer to save to `custom-safe-themes'.
    1273           0 :                (and (or custom-file user-init-file)
    1274           0 :                     (y-or-n-p "Treat this theme as safe in future sessions? ")
    1275           0 :                     (customize-push-and-save 'custom-safe-themes (list hash)))
    1276           0 :                t)
    1277           0 :         (quit-window)))))
    1278             : 
    1279             : (defun custom-theme-name-valid-p (name)
    1280             :   "Return t if NAME is a valid name for a Custom theme, nil otherwise.
    1281             : NAME should be a symbol."
    1282           0 :   (and (symbolp name)
    1283           0 :        name
    1284           0 :        (not (or (zerop (length (symbol-name name)))
    1285           0 :                 (eq name 'user)
    1286           0 :                 (eq name 'changed)))))
    1287             : 
    1288             : (defun custom-available-themes ()
    1289             :   "Return a list of Custom themes available for loading.
    1290             : Search the directories specified by `custom-theme-load-path' for
    1291             : files named FOO-theme.el, and return a list of FOO symbols.
    1292             : 
    1293             : The returned symbols may not correspond to themes that have been
    1294             : loaded, and no effort is made to check that the files contain
    1295             : valid Custom themes.  For a list of loaded themes, check the
    1296             : variable `custom-known-themes'."
    1297           0 :   (let (sym themes)
    1298           0 :     (dolist (dir (custom-theme--load-path))
    1299           0 :       (when (file-directory-p dir)
    1300           0 :         (dolist (file (file-expand-wildcards
    1301           0 :                        (expand-file-name "*-theme.el" dir) t))
    1302           0 :           (setq file (file-name-nondirectory file))
    1303           0 :           (and (string-match "\\`\\(.+\\)-theme.el\\'" file)
    1304           0 :                (setq sym (intern (match-string 1 file)))
    1305           0 :                (custom-theme-name-valid-p sym)
    1306           0 :                (push sym themes)))))
    1307           0 :     (nreverse (delete-dups themes))))
    1308             : 
    1309             : (defun custom-theme--load-path ()
    1310           0 :   (let (lpath)
    1311           0 :     (dolist (f custom-theme-load-path)
    1312           0 :       (cond ((eq f 'custom-theme-directory)
    1313           0 :              (setq f custom-theme-directory))
    1314           0 :             ((eq f t)
    1315           0 :              (setq f (expand-file-name "themes" data-directory))))
    1316           0 :       (if (file-directory-p f)
    1317           0 :           (push f lpath)))
    1318           0 :     (nreverse lpath)))
    1319             : 
    1320             : 
    1321             : ;;; Enabling and disabling loaded themes.
    1322             : 
    1323             : (defun enable-theme (theme)
    1324             :   "Reenable all variable and face settings defined by THEME.
    1325             : THEME should be either `user', or a theme loaded via `load-theme'.
    1326             : After this function completes, THEME will have the highest
    1327             : precedence (after `user')."
    1328           0 :   (interactive (list (intern
    1329           0 :                       (completing-read
    1330             :                        "Enable custom theme: "
    1331           0 :                        obarray (lambda (sym) (get sym 'theme-settings)) t))))
    1332           1 :   (if (not (custom-theme-p theme))
    1333           1 :       (error "Undefined Custom theme %s" theme))
    1334           1 :   (let ((settings (get theme 'theme-settings)))
    1335             :     ;; Loop through theme settings, recalculating vars/faces.
    1336           1 :     (dolist (s settings)
    1337           0 :       (let* ((prop (car s))
    1338           0 :              (symbol (cadr s))
    1339           0 :              (spec-list (get symbol prop)))
    1340           0 :         (put symbol prop (cons (cddr s) (assq-delete-all theme spec-list)))
    1341           0 :         (cond
    1342           0 :          ((eq prop 'theme-face)
    1343           0 :           (custom-theme-recalc-face symbol))
    1344           0 :          ((eq prop 'theme-value)
    1345             :           ;; Ignore `custom-enabled-themes' and `custom-safe-themes'.
    1346           0 :           (unless (memq symbol '(custom-enabled-themes custom-safe-themes))
    1347           1 :             (custom-theme-recalc-variable symbol)))))))
    1348           1 :   (unless (eq theme 'user)
    1349           0 :     (setq custom-enabled-themes
    1350           0 :           (cons theme (delq theme custom-enabled-themes)))
    1351             :     ;; Give the `user' theme the highest priority.
    1352           1 :     (enable-theme 'user)))
    1353             : 
    1354             : (defcustom custom-enabled-themes nil
    1355             :   "List of enabled Custom Themes, highest precedence first.
    1356             : This list does not include the `user' theme, which is set by
    1357             : Customize and always takes precedence over other Custom Themes.
    1358             : 
    1359             : This variable cannot be defined inside a Custom theme; there, it
    1360             : is simply ignored.
    1361             : 
    1362             : Setting this variable through Customize calls `enable-theme' or
    1363             : `load-theme' for each theme in the list."
    1364             :   :group 'customize
    1365             :   :type  '(repeat symbol)
    1366             :   :set-after '(custom-theme-directory custom-theme-load-path
    1367             :                                       custom-safe-themes)
    1368             :   :risky t
    1369             :   :set (lambda (symbol themes)
    1370             :          (let (failures)
    1371             :            (setq themes (delq 'user (delete-dups themes)))
    1372             :            ;; Disable all themes not in THEMES.
    1373             :            (if (boundp symbol)
    1374             :                (dolist (theme (symbol-value symbol))
    1375             :                  (if (not (memq theme themes))
    1376             :                      (disable-theme theme))))
    1377             :            ;; Call `enable-theme' or `load-theme' on each of THEMES.
    1378             :            (dolist (theme (reverse themes))
    1379             :              (condition-case nil
    1380             :                  (if (custom-theme-p theme)
    1381             :                      (enable-theme theme)
    1382             :                    (load-theme theme))
    1383             :                (error (setq failures (cons theme failures)
    1384             :                             themes (delq theme themes)))))
    1385             :            (enable-theme 'user)
    1386             :            (custom-set-default symbol themes)
    1387             :            (if failures
    1388             :                (message "Failed to enable theme: %s"
    1389             :                         (mapconcat 'symbol-name failures ", "))))))
    1390             : 
    1391             : (defsubst custom-theme-enabled-p (theme)
    1392             :   "Return non-nil if THEME is enabled."
    1393           0 :   (memq theme custom-enabled-themes))
    1394             : 
    1395             : (defun disable-theme (theme)
    1396             :   "Disable all variable and face settings defined by THEME.
    1397             : See `custom-enabled-themes' for a list of enabled themes."
    1398           0 :   (interactive (list (intern
    1399           0 :                       (completing-read
    1400             :                        "Disable custom theme: "
    1401           0 :                        (mapcar 'symbol-name custom-enabled-themes)
    1402           0 :                        nil t))))
    1403           0 :   (when (custom-theme-enabled-p theme)
    1404           0 :     (let ((settings (get theme 'theme-settings)))
    1405           0 :       (dolist (s settings)
    1406           0 :         (let* ((prop   (car s))
    1407           0 :                (symbol (cadr s))
    1408           0 :                (val (assq-delete-all theme (get symbol prop))))
    1409           0 :           (put symbol prop val)
    1410           0 :           (cond
    1411           0 :            ((eq prop 'theme-value)
    1412           0 :             (custom-theme-recalc-variable symbol))
    1413           0 :            ((eq prop 'theme-face)
    1414             :             ;; If the face spec specified by this theme is in the
    1415             :             ;; saved-face property, reset that property.
    1416           0 :             (when (equal (nth 3 s) (get symbol 'saved-face))
    1417           0 :               (put symbol 'saved-face (and val (cadr (car val)))))))))
    1418             :       ;; Recompute faces on all frames.
    1419           0 :       (dolist (frame (frame-list))
    1420             :         ;; We must reset the fg and bg color frame parameters, or
    1421             :         ;; `face-set-after-frame-default' will use the existing
    1422             :         ;; parameters, which could be from the disabled theme.
    1423           0 :         (set-frame-parameter frame 'background-color
    1424           0 :                              (custom--frame-color-default
    1425           0 :                               frame :background "background" "Background"
    1426           0 :                               "unspecified-bg" "white"))
    1427           0 :         (set-frame-parameter frame 'foreground-color
    1428           0 :                              (custom--frame-color-default
    1429           0 :                               frame :foreground "foreground" "Foreground"
    1430           0 :                               "unspecified-fg" "black"))
    1431           0 :         (face-set-after-frame-default frame))
    1432           0 :       (setq custom-enabled-themes
    1433           0 :             (delq theme custom-enabled-themes)))))
    1434             : 
    1435             : ;; Only used if window-system not null.
    1436             : (declare-function x-get-resource "frame.c"
    1437             :                   (attribute class &optional component subclass))
    1438             : 
    1439             : (defun custom--frame-color-default (frame attribute resource-attr resource-class
    1440             :                                           tty-default x-default)
    1441           0 :   (let ((col (face-attribute 'default attribute t)))
    1442           0 :     (cond
    1443           0 :      ((and col (not (eq col 'unspecified))) col)
    1444           0 :      ((null (window-system frame)) tty-default)
    1445           0 :      ((setq col (x-get-resource resource-attr resource-class)) col)
    1446           0 :      (t x-default))))
    1447             : 
    1448             : (defun custom-variable-theme-value (variable)
    1449             :   "Return (list VALUE) indicating the custom theme value of VARIABLE.
    1450             : That is to say, it specifies what the value should be according to
    1451             : currently enabled custom themes.
    1452             : 
    1453             : This function returns nil if no custom theme specifies a value for VARIABLE."
    1454           0 :   (let ((theme-value (get variable 'theme-value)))
    1455           0 :     (if theme-value
    1456           0 :         (cdr (car theme-value)))))
    1457             : 
    1458             : (defun custom-theme-recalc-variable (variable)
    1459             :   "Set VARIABLE according to currently enabled custom themes."
    1460           0 :   (let ((valspec (custom-variable-theme-value variable)))
    1461           0 :     (if valspec
    1462           0 :         (put variable 'saved-value valspec)
    1463           0 :       (setq valspec (get variable 'standard-value)))
    1464           0 :     (if (and valspec
    1465           0 :              (or (get variable 'force-value)
    1466           0 :                  (default-boundp variable)))
    1467           0 :         (funcall (or (get variable 'custom-set) 'set-default) variable
    1468           0 :                  (eval (car valspec))))))
    1469             : 
    1470             : (defun custom-theme-recalc-face (face)
    1471             :   "Set FACE according to currently enabled custom themes.
    1472             : If FACE is not initialized as a face, do nothing; otherwise call
    1473             : `face-spec-recalc' to recalculate the face on all frames."
    1474           0 :   (if (get face 'face-alias)
    1475           0 :       (setq face (get face 'face-alias)))
    1476           0 :   (if (facep face)
    1477             :       ;; Reset the faces for each frame.
    1478           0 :       (dolist (frame (frame-list))
    1479           0 :         (face-spec-recalc face frame))))
    1480             : 
    1481             : 
    1482             : ;;; XEmacs compatibility functions
    1483             : 
    1484             : ;; In XEmacs, when you reset a Custom Theme, you have to specify the
    1485             : ;; theme to reset it to.  We just apply the next available theme, so
    1486             : ;; just ignore the IGNORED arguments.
    1487             : 
    1488             : (defun custom-theme-reset-variables (theme &rest args)
    1489             :   "Reset some variable settings in THEME to their values in other themes.
    1490             : Each of the arguments ARGS has this form:
    1491             : 
    1492             :     (VARIABLE IGNORED)
    1493             : 
    1494             : This means reset VARIABLE.  (The argument IGNORED is ignored)."
    1495           0 :   (custom-check-theme theme)
    1496           0 :   (dolist (arg args)
    1497           0 :     (custom-push-theme 'theme-value (car arg) theme 'reset)))
    1498             : 
    1499             : (defun custom-reset-variables (&rest args)
    1500             :   "Reset the specs of some variables to their values in other themes.
    1501             : This creates settings in the `user' theme.
    1502             : 
    1503             : Each of the arguments ARGS has this form:
    1504             : 
    1505             :     (VARIABLE IGNORED)
    1506             : 
    1507             : This means reset VARIABLE.  (The argument IGNORED is ignored)."
    1508           0 :     (apply 'custom-theme-reset-variables 'user args))
    1509             : 
    1510             : ;;; The End.
    1511             : 
    1512             : (provide 'custom)
    1513             : 
    1514             : ;;; custom.el ends here

Generated by: LCOV version 1.12