comparison lisp/specifier.el @ 1875:ec2d1e636272

[xemacs-hg @ 2004-01-23 10:00:20 by stephent] specifier docs <87u12nugu7.fsf@tleepslib.sk.tsukuba.ac.jp>
author stephent
date Fri, 23 Jan 2004 10:00:34 +0000
parents 79c6ff3eef26
children 13a418960a88
comparison
equal deleted inserted replaced
1874:31c960994dba 1875:ec2d1e636272
30 ;; This file is dumped with XEmacs. 30 ;; This file is dumped with XEmacs.
31 31
32 ;;; Code: 32 ;;; Code:
33 33
34 (defun make-specifier-and-init (type spec-list &optional dont-canonicalize) 34 (defun make-specifier-and-init (type spec-list &optional dont-canonicalize)
35 "Create and initialize a new specifier. 35 "Create and initialize a specifier of type TYPE with spec(s) SPEC-LIST.
36 36
37 This is a front-end onto `make-specifier' that allows you to create a 37 A convenience API combining `make-specifier' and `set-specifier', allowing you
38 specifier and add specs to it at the same time. TYPE specifies the 38 to create a specifier and add specs to it at the same time.
39 specifier type. SPEC-LIST supplies the specification(s) to be added 39 TYPE specifies the specifier type. See `make-specifier' for known types.
40 to the specifier. Normally, almost any reasonable abbreviation of the 40 SPEC-LIST supplies the specification(s) to be added to the specifier, in any
41 full spec-list form is accepted, and is converted to the full form; 41 form acceptable to `canonicalize-spec-list'.
42 however, if optional argument DONT-CANONICALIZE is non-nil, this 42 Optional DONT-CANONICALIZE, if non-nil, inhibits the conversion, and the
43 conversion is not performed, and the SPEC-LIST must already be in full 43 SPEC-LIST must already be in full form."
44 form. See `canonicalize-spec-list'."
45 (let ((sp (make-specifier type))) 44 (let ((sp (make-specifier type)))
46 (if (not dont-canonicalize) 45 (if (not dont-canonicalize)
47 (setq spec-list (canonicalize-spec-list spec-list type))) 46 (setq spec-list (canonicalize-spec-list spec-list type)))
48 (add-spec-list-to-specifier sp spec-list) 47 (add-spec-list-to-specifier sp spec-list)
49 sp)) 48 sp))
52 51
53 (defun map-specifier (ms-specifier ms-func &optional ms-locale ms-maparg 52 (defun map-specifier (ms-specifier ms-func &optional ms-locale ms-maparg
54 ms-tag-set ms-exact-p) 53 ms-tag-set ms-exact-p)
55 "Apply MS-FUNC to the specification(s) for MS-LOCALE in MS-SPECIFIER. 54 "Apply MS-FUNC to the specification(s) for MS-LOCALE in MS-SPECIFIER.
56 55
57 If MS-LOCALE is a locale, MS-FUNC will be called for that locale. 56 If optional MS-LOCALE is a locale, MS-FUNC will be called for that locale.
58 If MS-LOCALE is a locale type, MS-FUNC will be mapped over all locales 57 If MS-LOCALE is a locale type, MS-FUNC will be mapped over all locales of that
59 of that type. If MS-LOCALE is 'all or nil, MS-FUNC will be mapped 58 type. If MS-LOCALE is 'all or nil, MS-FUNC will be mapped over all locales in
60 over all locales in MS-SPECIFIER. 59 MS-SPECIFIER.
61 60
62 MS-TAG-SET and MS-EXACT-P are as in `specifier-spec-list'. 61 Optional MS-TAG-SET and MS-EXACT-P are as in `specifier-spec-list'.
62 Optional MS-MAPARG will be passed to MS-FUNC.
63 63
64 MS-FUNC is called with four arguments: the MS-SPECIFIER, the locale 64 MS-FUNC is called with four arguments: the MS-SPECIFIER, the locale
65 being mapped over, the inst-list for that locale, and the 65 being mapped over, the inst-list for that locale, and the
66 optional MS-MAPARG. If any invocation of MS-FUNC returns non-nil, 66 optional MS-MAPARG. If any invocation of MS-FUNC returns non-nil,
67 the mapping will stop and the returned value becomes the 67 the mapping will stop and the returned value becomes the
171 (nreverse result))))))) 171 (nreverse result)))))))
172 172
173 (defun canonicalize-spec (spec specifier-type &optional noerror) 173 (defun canonicalize-spec (spec specifier-type &optional noerror)
174 "Canonicalize the given SPEC (a specification). 174 "Canonicalize the given SPEC (a specification).
175 175
176 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST 176 SPECIFIER-TYPE is the type of specifier that this SPEC will be used for.
177 will be used for.
178 177
179 Canonicalizing means converting to the full form for a spec, i.e. 178 Canonicalizing means converting to the full form for a spec, i.e.
180 `(LOCALE (TAG-SET . INSTANTIATOR) ...)'. This function accepts a 179 `(LOCALE (TAG-SET . INSTANTIATOR) ...)'. This function accepts a
181 possibly abbreviated inst-list or a cons of a locale and a possibly 180 possibly abbreviated inst-list or a cons of a locale and a possibly
182 abbreviated inst-list. (See `canonicalize-inst-list'.) 181 abbreviated inst-list. (See `canonicalize-inst-list'.)
224 a possibly abbreviated specification or a list of such things. (See 223 a possibly abbreviated specification or a list of such things. (See
225 `canonicalize-spec'.) This is the function used to convert spec-lists 224 `canonicalize-spec'.) This is the function used to convert spec-lists
226 accepted by `set-specifier' and such into a form suitable for 225 accepted by `set-specifier' and such into a form suitable for
227 `add-spec-list-to-specifier'. 226 `add-spec-list-to-specifier'.
228 227
229 This function tries extremely hard to resolve any ambiguities, 228 The canonicalization algorithm is as follows:
230 and the built-in specifier types (font, image, toolbar, etc.) are 229
231 designed so that there won't be any ambiguities. 230 1. Attempt to parse SPEC-LIST as a single, possibly abbreviated, specification.
231 2. If (1) fails, attempt to parse SPEC-LIST as a list of (abbreviated)
232 specifications.
233 3. If (2) fails, SPEC-LIST is invalid.
234
235 A possibly abbreviated specification SPEC is parsed by
236
237 1. Attempt to parse SPEC as a possibly abbreviated inst-list.
238 2. If (1) fails, attempt to parse SPEC as a cons of a locale and an
239 (abbreviated) inst-list.
240 3. If (2) fails, SPEC is invalid.
241
242 A possibly abbreviated inst-list INST-LIST is parsed by
243
244 1. Attempt to parse INST-LIST as a possibly abbreviated inst-pair.
245 2. If (1) fails, attempt to parse INST-LIST as a list of (abbreviated)
246 inst-pairs.
247 3. If (2) fails, INST-LIST is invalid.
248
249 A possibly abbreviated inst-pair INST-PAIR is parsed by
250
251 1. Check if INST-PAIR is `valid-instantiator-p'.
252 2. If not, check if INST-PAIR is a cons of something that is a tag, ie,
253 `valid-specifier-tag-p', and something that is `valid-instantiator-p'.
254 3. If not, check if INST-PAIR is a cons of a list of tags and something that
255 is `valid-instantiator-p'.
256
257 In summary, this function generally prefers more abbreviated forms.
258
259 This function tries extremely hard to resolve any ambiguities, and the
260 built-in specifier types (font, image, toolbar, etc.) are designed so that
261 there won't be any ambiguities. (#### Unfortunately there are bugs in the
262 treatment of toolbar spec-lists and generic spec-lists; avoid depending on
263 canonicalization for these types.)
232 264
233 If NOERROR is nil, signal an error if the spec-list is invalid; 265 If NOERROR is nil, signal an error if the spec-list is invalid;
234 otherwise return t." 266 otherwise return t."
235 ;; OK, the possibilities are: 267 ;; OK, the possibilities are:
236 ;; 268 ;;
267 (setq result (cons res2 result))))) 299 (setq result (cons res2 result)))))
268 (setq rest (cdr rest))) 300 (setq rest (cdr rest)))
269 (nreverse result))))))) 301 (nreverse result)))))))
270 302
271 (defun set-specifier (specifier value &optional locale tag-set how-to-add) 303 (defun set-specifier (specifier value &optional locale tag-set how-to-add)
272 "Add a specification or specifications to SPECIFIER. 304 "Add the specification(s) given by VALUE to SPECIFIER in LOCALE.
273 305
274 This function adds a specification of VALUE in locale LOCALE. 306 VALUE may be any of the values accepted by `canonicalize-spec-list', including
307
308 -- an instantiator (either a Lisp object which will be returned when the
309 specifier is instanced, or a Lisp object that can be instantiated to
310 produce an opaque value: eg, a font name (string) can be used for a font
311 specifier, but an instance will be a font object)
312 -- a list of instantiators
313 -- a cons of a locale and an instantiator, or of a locale and a list of
314 instantiators
315 -- a cons of a tag or tag-set and an instantiator (or list of instantiators)
316 -- a cons of a locale and the previous type of item
317 -- a list of one or more of any of the previous types of items
318 -- a canonical spec-list.
319
320 See `canonicalize-spec-list' for details. If you need to know the details,
321 though, strongly consider using the unambiguous APIs `add-spec-to-specifier'
322 and `add-spec-list-to-specifier' instead.
323
324 Finally, VALUE can itself be a specifier (of the same type as
325 SPECIFIER), if you want to copy specifications from one specifier
326 to another; this is equivalent to calling `copy-specifier', and
327 LOCALE, TAG-SET, and HOW-TO-ADD have the same semantics as with
328 that function.
329
330 Note that a VALUE of `nil' is either illegal or will be treated as a value of
331 `nil'; it does not remove existing specifications. Use `remove-specifier' for
332 that. N.B. `remove-specifier' defaults to removing all specifications, not
333 just the 'global one!
334
335 Warning: this function is inherently heuristic, and should not be relied on to
336 properly resolve ambiguities, when specifier instantiators can be lists
337 \(currently, for toolbar specifiers and generic specifiers). In those cases
338 use either `add-spec-to-specifier' or `add-spec-list-to-specifier'.
339
275 LOCALE indicates where this specification is active, and should be 340 LOCALE indicates where this specification is active, and should be
276 a buffer, a window, a frame, a device, or the symbol `global' to 341 a buffer, a window, a frame, a device, or the symbol `global' to
277 indicate that it applies everywhere. LOCALE usually defaults to 342 indicate that it applies everywhere. LOCALE defaults to
278 `global' if omitted. 343 `global' if omitted, and is overridden by locales provided by VALUE (in the
279 344 cases where value is a full specification or a spec-list).
280 VALUE is usually what is called an \"instantiator\" (which, roughly
281 speaking, corresponds to the \"value\" of the property governed by
282 SPECIFIER). The valid instantiators for SPECIFIER depend on the type
283 of SPECIFIER (which you can determine using `specifier-type'). The
284 specifier `scrollbar-width', for example, is of type `integer',
285 meaning its valid instantiators are integers. The specifier governing
286 the background color of the `default' face (you can retrieve this
287 specifier using `(face-background 'default)') is of type `color',
288 meaning its valid instantiators are strings naming colors and
289 color-instance objects. For some types of specifiers, such as `image'
290 and `toolbar', the instantiators can be very complex. Generally this
291 is documented in the appropriate creation function --
292 e.g. `make-color-specifier', `make-font-specifier',
293 `make-image-specifier' -- or in the global variable holding the most
294 common specifier for that type (`default-toolbar', `default-gutter',
295 `current-display-table').
296
297 NOTE: It does *not* work to give a VALUE of nil as a way of removing the
298 specifications for a locale -- for many specifier types, such as `boolean',
299 nil is a perfectly legitimate value to set. Use `remove-specifier'
300 instead. (And keep in mind that, if you omit the LOCALE argument to
301 `remove-specifier', it removes *all* specifications! If you want to remove
302 just the `global' specification, make sure to specify a LOCALE of
303 `global'.)
304
305 VALUE can also be a list of instantiators. This means basically,
306 \"try each one in turn until you get one that works\". This allows
307 you to give funky instantiators that may only work in some cases,
308 and provide more normal backups for the other cases. (For example,
309 you might like the color \"darkseagreen2\", but some X servers
310 don't recognize this color, so you could provide a backup
311 \"forest green\". Color TTY devices probably won't recognize this
312 either, so you could provide a second backup \"green\". You'd
313 do this by specifying this list of instantiators:
314
315 '(\"darkseagreen2\" \"forest green\" \"green\")
316
317 VALUE can also be various more complicated forms; see below.
318 345
319 Optional argument TAG-SET is a tag or a list of tags, to be associated 346 Optional argument TAG-SET is a tag or a list of tags, to be associated
320 with the VALUE. Tags are symbols (usually naming device types, such 347 with the VALUE. Tags are symbols (usually naming device types, such
321 as `x' and `tty', or device classes, such as `color', `mono', and 348 as `x' and `tty', or device classes, such as `color', `mono', and
322 `grayscale'); specifying a TAG-SET restricts the scope of VALUE to 349 `grayscale'); specifying a TAG-SET restricts the scope of VALUE to
332 Most of the time, you do not need to worry about this argument; 359 Most of the time, you do not need to worry about this argument;
333 the default behavior of `remove-tag-set-prepend' is usually fine. 360 the default behavior of `remove-tag-set-prepend' is usually fine.
334 See `copy-specifier' and `add-spec-to-specifier' for a full 361 See `copy-specifier' and `add-spec-to-specifier' for a full
335 description of what each of these means. 362 description of what each of these means.
336 363
337 \[VALUE can actually be anything acceptable to `canonicalize-spec-list';
338 this includes, among other things:
339
340 -- a cons of a locale and an instantiator (or list of instantiators)
341 -- a cons of a tag or tag-set and an instantiator (or list of
342 instantiators)
343 -- a cons of a locale and the previous type of item
344 -- a list of one or more of any of the previous types of items
345
346 However, this usage is deprecated. Either iterate and call `set-specifier'
347 multiple times, or use the lower-level `add-spec-list-to-specifier'. Also,
348 in these cases, you cannot give a LOCALE or TAG-SET, because they do not
349 make sense. (You will probably get an error if you try this.)]
350
351 Finally, VALUE can itself be a specifier (of the same type as
352 SPECIFIER), if you want to copy specifications from one specifier
353 to another; this is equivalent to calling `copy-specifier', and
354 LOCALE, TAG-SET, and HOW-TO-ADD have the same semantics as with
355 that function.
356
357 Note that `set-specifier' is exactly complementary to `specifier-specs' 364 Note that `set-specifier' is exactly complementary to `specifier-specs'
358 except in the case where SPECIFIER has no specs at all in it but nil 365 except in the case where SPECIFIER has no specs at all in it but nil
359 is a valid instantiator (in that case, `specifier-specs' will return 366 is a valid instantiator (in that case, `specifier-specs' will return
360 nil (meaning no specs) and `set-specifier' will interpret the `nil' 367 nil (meaning no specs) and `set-specifier' will interpret the `nil'
361 as meaning \"I'm adding a global instantiator and its value is `nil'\"), 368 as meaning \"I'm adding a global instantiator and its value is `nil'\"),
362 or in strange cases where there is an ambiguity between a spec-list 369 or in strange cases where there is an ambiguity between a spec-list
363 and an inst-list, etc. (The built-in specifier types are designed 370 and an inst-list, etc. (The built-in specifier types are designed
364 in such a way as to avoid any such ambiguities.) 371 in such a way as to avoid any such ambiguities.)"
365
366 NOTE: If you want to work with spec-lists, you should probably not
367 use either `set-specifier' or `specifier-specs', but should use the
368 lower-level functions `add-spec-list-to-specifier' and `specifier-spec-list'.
369 These functions always work with fully-qualified spec-lists; thus, there
370 is no possibility for ambiguity and no need to go through the function
371 `canonicalize-spec-list', which is potentially time-consuming."
372 372
373 ;; backward compatibility: the old function had HOW-TO-ADD as the 373 ;; backward compatibility: the old function had HOW-TO-ADD as the
374 ;; third argument and no arguments after that. 374 ;; third argument and no arguments after that.
375 ;; #### this should disappear at some point. 375 ;; #### this should disappear at some point.
376 (if (and (null how-to-add) 376 (if (and (null how-to-add)