*** empty log message ***
[gnus] / lisp / custom.el
1 ;;; custom.el -- Tools for declaring and initializing options.
2 ;;
3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 ;;
5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
6 ;; Keywords: help, faces
7 ;; Version: 1.55
8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
9
10 ;;; Commentary:
11 ;;
12 ;; If you want to use this code, please visit the URL above.
13 ;;
14 ;; This file only contain the code needed to declare and initialize
15 ;; user options.  The code to customize options is autoloaded from
16 ;; `cus-edit.el'. 
17
18 ;; The code implementing face declarations is in `cus-face.el'
19
20 ;;; Code:
21
22 (require 'widget)
23
24 (define-widget-keywords :prefix :tag :load :link :options :type :group)
25
26 ;; These autoloads should be deleted when the file is added to Emacs
27
28 (unless (fboundp 'load-gc)
29   ;; From cus-edit.el
30   (autoload 'customize "cus-edit" nil t)
31   (autoload 'customize-variable "cus-edit" nil t)
32   (autoload 'customize-face "cus-edit" nil t)
33   (autoload 'customize-apropos "cus-edit" nil t)
34   (autoload 'customize-customized "cus-edit" nil t)
35   (autoload 'custom-buffer-create "cus-edit")
36   (autoload 'custom-menu-update "cus-edit")
37   (autoload 'custom-make-dependencies "cus-edit")
38   ;; From cus-face.el
39   (autoload 'custom-declare-face "cus-face")
40   (autoload 'custom-set-faces "cus-face"))
41
42 ;;; The `defcustom' Macro.
43
44 (defun custom-declare-variable (symbol value doc &rest args)
45   "Like `defcustom', but SYMBOL and VALUE are evaluated as normal arguments."
46   (unless (and (default-boundp symbol)
47                (not (get symbol 'saved-value)))
48     (set-default symbol (if (get symbol 'saved-value)
49                             (eval (car (get symbol 'saved-value)))
50                           (eval value))))
51   (put symbol 'factory-value (list value))
52   (when doc
53     (put symbol 'variable-documentation doc))
54   (while args 
55     (let ((arg (car args)))
56       (setq args (cdr args))
57       (unless (symbolp arg)
58         (error "Junk in args %S" args))
59       (let ((keyword arg)
60             (value (car args)))
61         (unless args
62           (error "Keyword %s is missing an argument" keyword))
63         (setq args (cdr args))
64         (cond ((eq keyword :type)
65                (put symbol 'custom-type value))
66               ((eq keyword :options)
67                (if (get symbol 'custom-options)
68                    ;; Slow safe code to avoid duplicates.
69                    (mapcar (lambda (option)
70                              (custom-add-option symbol option))
71                            value)
72                  ;; Fast code for the common case.
73                  (put symbol 'custom-options (copy-list value))))
74               (t
75                (custom-handle-keyword symbol keyword value
76                                       'custom-variable))))))
77   (run-hooks 'custom-define-hook)
78   symbol)
79
80 (defmacro defcustom (symbol value doc &rest args)
81   "Declare SYMBOL as a customizable variable that defaults to VALUE.
82 DOC is the variable documentation.
83
84 Neither SYMBOL nor VALUE needs to be quoted.
85 If SYMBOL is not already bound, initialize it to VALUE.
86 The remaining arguments should have the form
87
88    [KEYWORD VALUE]... 
89
90 The following KEYWORD's are defined:
91
92 :type   VALUE should be a widget type.
93 :options VALUE should be a list of valid members of the widget type.
94 :group  VALUE should be a customization group.  
95         Add SYMBOL to that group.
96
97 Read the section about customization in the emacs lisp manual for more
98 information."
99   `(eval-and-compile
100      (custom-declare-variable (quote ,symbol) (quote ,value) ,doc ,@args)))
101
102 ;;; The `defface' Macro.
103
104 (defmacro defface (face spec doc &rest args)
105   "Declare FACE as a customizable face that defaults to SPEC.
106 FACE does not need to be quoted.
107
108 Third argument DOC is the face documentation.
109
110 If FACE has been set with `custom-set-face', set the face attributes
111 as specified by that function, otherwise set the face attributes
112 according to SPEC.
113
114 The remaining arguments should have the form
115
116    [KEYWORD VALUE]...
117
118 The following KEYWORD's are defined:
119
120 :group  VALUE should be a customization group.
121         Add FACE to that group.
122
123 SPEC should be an alist of the form ((DISPLAY ATTS)...).
124
125 ATTS is a list of face attributes and their values.  The possible
126 attributes are defined in the variable `custom-face-attributes'.
127 Alternatively, ATTS can be a face in which case the attributes of that
128 face is used.
129
130 The ATTS of the first entry in SPEC where the DISPLAY matches the
131 frame should take effect in that frame.  DISPLAY can either be the
132 symbol `t', which will match all frames, or an alist of the form
133 \((REQ ITEM...)...)
134
135 For the DISPLAY to match a FRAME, the REQ property of the frame must
136 match one of the ITEM.  The following REQ are defined:
137
138 `type' (the value of (window-system))
139   Should be one of `x' or `tty'.
140
141 `class' (the frame's color support)
142   Should be one of `color', `grayscale', or `mono'.
143
144 `background' (what color is used for the background text)