Mercurial > hg > xemacs-beta
comparison lisp/custom.el @ 209:41ff10fd062f r20-4b3
Import from CVS: tag r20-4b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:04:58 +0200 |
parents | |
children | d44af0c54775 |
comparison
equal
deleted
inserted
replaced
208:f427b8ec4379 | 209:41ff10fd062f |
---|---|
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 ;; Maintainer: Hrvoje Niksic <hniksic@srce.hr> | |
7 ;; Keywords: help, faces, dumped | |
8 ;; Version: 1.9960-x | |
9 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ | |
10 | |
11 ;; This file is part of XEmacs. | |
12 | |
13 ;; XEmacs 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 2, or (at your option) | |
16 ;; any later version. | |
17 | |
18 ;; XEmacs 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 XEmacs; see the file COPYING. If not, write to the | |
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
26 ;; Boston, MA 02111-1307, USA. | |
27 | |
28 ;;; Commentary: | |
29 | |
30 ;; This file is dumped with XEmacs. | |
31 | |
32 ;; This file only contain the code needed to declare and initialize | |
33 ;; user options. The code to customize options is autoloaded from | |
34 ;; `cus-edit.el'. | |
35 ;; | |
36 ;; The code implementing face declarations is in `cus-face.el' | |
37 | |
38 ;;; Code: | |
39 | |
40 (require 'widget) | |
41 | |
42 (defvar custom-define-hook nil | |
43 ;; Customize information for this option is in `cus-edit.el'. | |
44 "Hook called after defining each customize option.") | |
45 | |
46 ;;; The `defcustom' Macro. | |
47 | |
48 (defun custom-initialize-default (symbol value) | |
49 "Initialize SYMBOL with VALUE. | |
50 This will do nothing if symbol already has a default binding. | |
51 Otherwise, if symbol has a `saved-value' property, it will evaluate | |
52 the car of that and used as the default binding for symbol. | |
53 Otherwise, VALUE will be evaluated and used as the default binding for | |
54 symbol." | |
55 (unless (default-boundp symbol) | |
56 ;; Use the saved value if it exists, otherwise the standard setting. | |
57 (set-default symbol (if (get symbol 'saved-value) | |
58 (eval (car (get symbol 'saved-value))) | |
59 (eval value))))) | |
60 | |
61 (defun custom-initialize-set (symbol value) | |
62 "Initialize SYMBOL with VALUE. | |
63 Like `custom-initialize-default', but use the function specified by | |
64 `:set' to initialize SYMBOL." | |
65 (unless (default-boundp symbol) | |
66 (funcall (or (get symbol 'custom-set) 'set-default) | |
67 symbol | |
68 (if (get symbol 'saved-value) | |
69 (eval (car (get symbol 'saved-value))) | |
70 (eval value))))) | |
71 | |
72 (defun custom-initialize-reset (symbol value) | |
73 "Initialize SYMBOL with VALUE. | |
74 Like `custom-initialize-set', but use the function specified by | |
75 `:get' to reinitialize SYMBOL if it is already bound." | |
76 (funcall (or (get symbol 'custom-set) 'set-default) | |
77 symbol | |
78 (cond ((default-boundp symbol) | |
79 (funcall (or (get symbol 'custom-get) 'default-value) | |
80 symbol)) | |
81 ((get symbol 'saved-value) | |
82 (eval (car (get symbol 'saved-value)))) | |
83 (t | |
84 (eval value))))) | |
85 | |
86 (defun custom-initialize-changed (symbol value) | |
87 "Initialize SYMBOL with VALUE. | |
88 Like `custom-initialize-reset', but only use the `:set' function if the | |
89 not using the standard setting. Otherwise, use the `set-default'." | |
90 (cond ((default-boundp symbol) | |
91 (funcall (or (get symbol 'custom-set) 'set-default) | |
92 symbol | |
93 (funcall (or (get symbol 'custom-get) 'default-value) | |
94 symbol))) | |
95 ((get symbol 'saved-value) | |
96 (funcall (or (get symbol 'custom-set) 'set-default) | |
97 symbol | |
98 (eval (car (get symbol 'saved-value))))) | |
99 (t | |
100 (set-default symbol (eval value))))) | |
101 | |
102 (defun custom-declare-variable (symbol value doc &rest args) | |
103 "Like `defcustom', but SYMBOL and VALUE are evaluated as normal arguments." | |
104 ;; Remember the standard setting. | |
105 (put symbol 'standard-value (list value)) | |
106 ;; Maybe this option was rogue in an earlier version. It no longer is. | |
107 (when (get symbol 'force-value) | |
108 ;; It no longer is. | |
109 (put symbol 'force-value nil)) | |
110 (when doc | |
111 (put symbol 'variable-documentation doc)) | |
112 (let ((initialize 'custom-initialize-reset) | |
113 (requests nil)) | |
114 (while args | |
115 (let ((arg (car args))) | |
116 (setq args (cdr args)) | |
117 (unless (symbolp arg) | |
118 (error "Junk in args %S" args)) | |
119 (let ((keyword arg) | |
120 (value (car args))) | |
121 (unless args | |
122 (error "Keyword %s is missing an argument" keyword)) | |
123 (setq args (cdr args)) | |
124 (cond ((eq keyword :initialize) | |
125 (setq initialize value)) | |
126 ((eq keyword :set) | |
127 (put symbol 'custom-set value)) | |
128 ((eq keyword :get) | |
129 (put symbol 'custom-get value)) | |
130 ((eq keyword :require) | |
131 (setq requests (cons value requests))) | |
132 ((eq keyword :type) | |
133 (put symbol 'custom-type value)) | |
134 ((eq keyword :options) | |
135 (if (get symbol 'custom-options) | |
136 ;; Slow safe code to avoid duplicates. | |
137 (mapc (lambda (option) | |
138 (custom-add-option symbol option)) | |
139 value) | |
140 ;; Fast code for the common case. | |
141 (put symbol 'custom-options (copy-sequence value)))) | |
142 (t | |
143 (custom-handle-keyword symbol keyword value | |
144 'custom-variable)))))) | |
145 (put symbol 'custom-requests requests) | |
146 ;; Do the actual initialization. | |
147 (funcall initialize symbol value)) | |
148 (run-hooks 'custom-define-hook) | |
149 symbol) | |
150 | |
151 (defmacro defcustom (symbol value doc &rest args) | |
152 "Declare SYMBOL as a customizable variable that defaults to VALUE. | |
153 DOC is the variable documentation. | |
154 | |
155 Neither SYMBOL nor VALUE needs to be quoted. | |
156 If SYMBOL is not already bound, initialize it to VALUE. | |
157 The remaining arguments should have the form | |
158 | |
159 [KEYWORD VALUE]... | |
160 | |
161 The following KEYWORD's are defined: | |
162 | |
163 :type VALUE should be a widget type for editing the symbols value. | |
164 The default is `sexp'. | |
165 :options VALUE should be a list of valid members of the widget type. | |
166 :group VALUE should be a customization group. | |
167 Add SYMBOL to that group. | |
168 :initialize VALUE should be a function used to initialize the | |
169 variable. It takes two arguments, the symbol and value | |
170 given in the `defcustom' call. The default is | |
171 `custom-initialize-set' | |
172 :set VALUE should be a function to set the value of the symbol. | |
173 It takes two arguments, the symbol to set and the value to | |
174 give it. The default is `set-default'. | |
175 :get VALUE should be a function to extract the value of symbol. | |
176 The function takes one argument, a symbol, and should return | |
177 the current value for that symbol. The default is | |
178 `default-value'. | |
179 :require VALUE should be a feature symbol. Each feature will be | |
180 required after initialization, of the the user have saved this | |
181 option. | |
182 | |
183 Read the section about customization in the Emacs Lisp manual for more | |
184 information." | |
185 `(custom-declare-variable (quote ,symbol) (quote ,value) ,doc ,@args)) | |
186 | |
187 ;;; The `defface' Macro. | |
188 | |
189 (defmacro defface (face spec doc &rest args) | |
190 "Declare FACE as a customizable face that defaults to SPEC. | |
191 FACE does not need to be quoted. | |
192 | |
193 Third argument DOC is the face documentation. | |
194 | |
195 If FACE has been set with `custom-set-face', set the face attributes | |
196 as specified by that function, otherwise set the face attributes | |
197 according to SPEC. | |
198 | |
199 The remaining arguments should have the form | |
200 | |
201 [KEYWORD VALUE]... | |
202 | |
203 The following KEYWORDs are defined: | |
204 | |
205 :group VALUE should be a customization group. | |
206 Add FACE to that group. | |
207 | |
208 SPEC should be an alist of the form ((DISPLAY ATTS)...). | |
209 | |
210 ATTS is a list of face attributes and their values. The possible | |
211 attributes are defined in the variable `custom-face-attributes'. | |
212 | |
213 The ATTS of the first entry in SPEC where the DISPLAY matches the | |
214 frame should take effect in that frame. DISPLAY can either be the | |
215 symbol t, which will match all frames, or an alist of the form | |
216 \((REQ ITEM...)...) | |
217 | |
218 For the DISPLAY to match a FRAME, the REQ property of the frame must | |
219 match one of the ITEM. The following REQ are defined: | |
220 | |
221 `type' (the value of `window-system') | |
222 Should be one of `x' or `tty'. | |
223 | |
224 `class' (the frame's color support) | |
225 Should be one of `color', `grayscale', or `mono'. | |
226 | |
227 `background' (what color is used for the background text) | |
228 Should be one of `light' or `dark'. | |
229 | |
230 Read the section about customization in the Emacs Lisp manual for more | |
231 information." | |
232 `(custom-declare-face (quote ,face) ,spec ,doc ,@args)) | |
233 | |
234 ;;; The `defgroup' Macro. | |
235 | |
236 (defun custom-declare-group (symbol members doc &rest args) | |
237 "Like `defgroup', but SYMBOL is evaluated as a normal argument." | |
238 (while members | |
239 (apply 'custom-add-to-group symbol (car members)) | |
240 (pop members)) | |
241 (put symbol 'custom-group (nconc members (get symbol 'custom-group))) | |
242 (when doc | |
243 (put symbol 'group-documentation doc)) | |
244 (while args | |
245 (let ((arg (car args))) | |
246 (setq args (cdr args)) | |
247 (unless (symbolp arg) | |
248 (error "Junk in args %S" args)) | |
249 (let ((keyword arg) | |
250 (value (car args))) | |
251 (unless args | |
252 (error "Keyword %s is missing an argument" keyword)) | |
253 (setq args (cdr args)) | |
254 (cond ((eq keyword :prefix) | |
255 (put symbol 'custom-prefix value)) | |
256 (t | |
257 (custom-handle-keyword symbol keyword value | |
258 'custom-group)))))) | |
259 (run-hooks 'custom-define-hook) | |
260 symbol) | |
261 | |
262 (defmacro defgroup (symbol members doc &rest args) | |
263 "Declare SYMBOL as a customization group containing MEMBERS. | |
264 SYMBOL does not need to be quoted. | |
265 | |
266 Third arg DOC is the group documentation. | |
267 | |
268 MEMBERS should be an alist of the form ((NAME WIDGET)...) where NAME | |
269 is a symbol and WIDGET is a widget for editing that symbol. Useful | |
270 widgets are `custom-variable' for editing variables, `custom-face' for | |
271 edit faces, and `custom-group' for editing groups. | |
272 | |
273 The remaining arguments should have the form | |
274 | |
275 [KEYWORD VALUE]... | |
276 | |
277 The following KEYWORD's are defined: | |
278 | |
279 :group VALUE should be a customization group. | |
280 Add SYMBOL to that group. | |
281 | |
282 Read the section about customization in the Emacs Lisp manual for more | |
283 information." | |
284 `(custom-declare-group (quote ,symbol) ,members ,doc ,@args)) | |
285 | |
286 ;; This is preloaded very early, so we avoid using CL features. | |
287 (defvar custom-group-hash-table (make-hashtable 300 'eq) | |
288 "Hash-table of non-empty groups.") | |
289 | |
290 (defun custom-add-to-group (group option widget) | |
291 "To existing GROUP add a new OPTION of type WIDGET. | |
292 If there already is an entry for that option, overwrite it." | |
293 (let* ((members (get group 'custom-group)) | |
294 (old (assq option members))) | |
295 (if old | |
296 (setcar (cdr old) widget) | |
297 (put group 'custom-group (nconc members (list (list option widget)))))) | |
298 (puthash group t custom-group-hash-table)) | |
299 | |
300 ;;; Properties. | |
301 | |
302 (defun custom-handle-all-keywords (symbol args type) | |
303 "For customization option SYMBOL, handle keyword arguments ARGS. | |
304 Third argument TYPE is the custom option type." | |
305 (while args | |
306 (let ((arg (car args))) | |
307 (setq args (cdr args)) | |
308 (unless (symbolp arg) | |
309 (error "Junk in args %S" args)) | |
310 (let ((keyword arg) | |
311 (value (car args))) | |
312 (unless args | |
313 (error "Keyword %s is missing an argument" keyword)) | |
314 (setq args (cdr args)) | |
315 (custom-handle-keyword symbol keyword value type))))) | |
316 | |
317 (defun custom-handle-keyword (symbol keyword value type) | |
318 "For customization option SYMBOL, handle KEYWORD with VALUE. | |
319 Fourth argument TYPE is the custom option type." | |
320 (cond ((eq keyword :group) | |
321 (custom-add-to-group value symbol type)) | |
322 ((eq keyword :link) | |
323 (custom-add-link symbol value)) | |
324 ((eq keyword :load) | |
325 (custom-add-load symbol value)) | |
326 ((eq keyword :tag) | |
327 (put symbol 'custom-tag value)) | |
328 (t | |
329 (error "Unknown keyword %s" symbol)))) | |
330 | |
331 (defun custom-add-option (symbol option) | |
332 "To the variable SYMBOL add OPTION. | |
333 | |
334 If SYMBOL is a hook variable, OPTION should be a hook member. | |
335 For other types variables, the effect is undefined." | |
336 (let ((options (get symbol 'custom-options))) | |
337 (unless (member option options) | |
338 (put symbol 'custom-options (cons option options))))) | |
339 | |
340 (defun custom-add-link (symbol widget) | |
341 "To the custom option SYMBOL add the link WIDGET." | |
342 (let ((links (get symbol 'custom-links))) | |
343 (unless (member widget links) | |
344 (put symbol 'custom-links (cons widget links))))) | |
345 | |
346 (defun custom-add-load (symbol load) | |
347 "To the custom option SYMBOL add the dependency LOAD. | |
348 LOAD should be either a library file name, or a feature name." | |
349 (let ((loads (get symbol 'custom-loads))) | |
350 (unless (member load loads) | |
351 (put symbol 'custom-loads (cons load loads))))) | |
352 | |
353 ;;; Initializing. | |
354 | |
355 (defun custom-set-variables (&rest args) | |
356 "Initialize variables according to user preferences. | |
357 | |
358 The arguments should be a list where each entry has the form: | |
359 | |
360 (SYMBOL VALUE [NOW]) | |
361 | |
362 The unevaluated VALUE is stored as the saved value for SYMBOL. | |
363 If NOW is present and non-nil, VALUE is also evaluated and bound as | |
364 the default value for the SYMBOL." | |
365 (while args | |
366 (let ((entry (car args))) | |
367 (if (listp entry) | |
368 (let* ((symbol (nth 0 entry)) | |
369 (value (nth 1 entry)) | |
370 (now (nth 2 entry)) | |
371 (requests (nth 3 entry)) | |
372 (set (or (get symbol 'custom-set) 'set-default))) | |
373 (put symbol 'saved-value (list value)) | |
374 (cond (now | |
375 ;; Rogue variable, set it now. | |
376 (put symbol 'force-value t) | |
377 (funcall set symbol (eval value))) | |
378 ((default-boundp symbol) | |
379 ;; Something already set this, overwrite it. | |
380 (funcall set symbol (eval value)))) | |
381 (when requests | |
382 (put symbol 'custom-requests requests) | |
383 (mapc 'require requests)) | |
384 (setq args (cdr args))) | |
385 ;; Old format, a plist of SYMBOL VALUE pairs. | |
386 (message "Warning: old format `custom-set-variables'") | |
387 (ding) | |
388 (sit-for 2) | |
389 (let ((symbol (nth 0 args)) | |
390 (value (nth 1 args))) | |
391 (put symbol 'saved-value (list value))) | |
392 (setq args (cdr (cdr args))))))) | |
393 | |
394 ;;; The End. | |
395 | |
396 (provide 'custom) | |
397 | |
398 ;; custom.el ends here |