2 @c This is part of the SXEmacs Lisp Reference Manual.
3 @c Copyright (C) 1995, 1996 Ben Wing.
4 @c Copyright (C) 2002, 2004 Free Software Foundation, Inc.
5 @c Copyright (C) 2005 Sebastian Freundt <hroptatyr@sxemacs.org>
6 @c See the file lispref.texi for copying conditions.
7 @setfilename ../../info/specifiers.info
9 @node Specifiers, Faces and Window-System Objects, Extents, top
13 A specifier is an object used to keep track of a property whose value
14 should vary according to @emph{display context}, a window, a frame, or
15 device. The value of many built-in properties, such as the font,
16 foreground, background, and such properties of a face and variables
17 such as @code{modeline-shadow-thickness} and
18 @code{top-toolbar-height}, is actually a specifier object. The
19 specifier object, in turn, is ``instanced'' in a particular situation
20 to yield the real value of the property in the current context.
22 @defun specifierp object
23 This function returns non-@code{nil} if @var{object} is a specifier.
27 * Introduction to Specifiers:: Specifiers provide a clean way for
28 display and other properties to vary
29 (under user control) in a wide variety
31 * Simple Specifier Usage:: Getting started with specifiers.
32 * Specifiers In-Depth:: Gory details about specifier innards.
33 * Specifier Instancing:: Instancing means obtaining the ``value'' of
34 a specifier in a particular context.
35 * Specifier Types:: Specifiers come in different flavors.
36 * Adding Specifications:: Specifications control a specifier's ``value''
37 by giving conditions under which a
38 particular value is valid.
39 * Retrieving Specifications:: Querying a specifier's specifications.
40 * Specifier Tag Functions:: Working with specifier tags.
41 * Specifier Instancing Functions::
42 Functions to instance a specifier.
43 * Specifier Examples:: Making all this stuff clearer.
44 * Creating Specifiers:: Creating specifiers for your own use.
45 * Specifier Validation Functions::
46 Validating the components of a specifier.
47 * Other Specification Functions::
48 Other ways of working with specifications.
52 @node Introduction to Specifiers
53 @section Introduction to Specifiers
55 Perhaps the most useful way to explain specifiers is via an analogy.
56 SXEmacs Lisp programmers are used to @emph{buffer-local variables}
57 @ref{Buffer-Local Variables}. For example, the variable
58 @code{modeline-format}, which controls the format of the modeline, can
59 have different values depending on the particular buffer being edited.
60 The variable has a default value which most modes will use, but a
61 specialized package such as Calendar might change the variable so as to
62 tailor the modeline to its own purposes. Other variables are perhaps
63 best thought of as ``mode local,'' such as font-lock keywords, but they
64 are implemented as buffer locals.
66 Other properties (such as those that can be changed by the
67 @code{modify-frame-parameters} function, for example the color of the
68 text cursor) can have frame-local values, although it might also make
69 sense for them to have buffer-local values. In other cases, you might
70 want the property to vary depending on the particular window within the
71 frame that applies (e.g. the top or bottom window in a split frame), the
72 device type that that frame appears on (X or tty), etc. Perhaps you can
73 envision some more complicated scenario where you want a particular
74 value in a specified buffer, another value in all other buffers
75 displayed on a particular frame, another value in all other buffers
76 displayed in all other frames on any mono (two-color, e.g. black and
77 white only) displays, and a default value in all other circumstances.
79 Specifiers generalize both buffer- and frame-local properties.
80 Specifiers vary according to the @emph{display} context. Font-lock
81 keywords in a buffer will be the same no matter which window the
82 buffer is displayed in, but windows on TTY devices will simply not be
83 capable of the flexibility that windows on modern GUI devices are.
84 Specifiers provide a way for the programmer to @emph{declare} that an
85 emphasized text should be italic on GUI devices and inverse video on
86 TTYs. They also provide a way for the programmer to declare
87 fallbacks, so that a color specified as ``chartreuse'' where possible
88 can fall back to ``yellow'' on devices where only ANSI (4-bit) color
89 is available. The complex calculations and device querying are
90 transparent to both user and programmer. You ask for what you want;
91 it's up to SXEmacs to provide it, or a reasonable approximation.
93 We call such a declaration a @dfn{specification}. A @dfn{specification}
94 applies in a particular @dfn{locale}, which is a window, buffer, frame,
95 device, or the global locale. The value part of the specification is
96 called an @dfn{instantiator}. The process of determining the value in a
97 particular context, or @dfn{domain}, is called @dfn{instantiation} or
98 @dfn{instancing}. A domain is a window, frame, or device.
100 The difference between @dfn{locale} and @dfn{domain} is somewhat subtle.
101 You may think of a locale as a class of domains, which may span
102 different devices. Since the specification is abstract (a Lisp form),
103 you can state it without reference to a device. On the other hand, when
104 you instantiate a specification, you must know the type of the device.
105 It is useless to specify that ``blue means emphasis'' on a monochrome
106 device. Thus instantiation requires specification of the device on
107 which it will be rendered.
109 Thus a @dfn{specifier} allows a great deal of flexibility in
110 controlling exactly what value a property has in which circumstances.
111 Specifiers are most commonly used for display properties, such as an image or
112 the foreground color of a face. As a simple example, you can specify
113 that the foreground of the default face be
117 blue for a particular buffer
119 green for all other buffers
122 As a more complicated example, you could specify that the foreground of
127 forest green for all buffers displayed in a particular SXEmacs window, or
128 green if the X server doesn't recognize the color @samp{forest green}
130 blue for all buffers displayed in a particular frame
132 red for all other buffers displayed on a color device
134 white for all other buffers
138 @node Simple Specifier Usage
139 @section Simple Specifier Usage
140 @cindex specifier examples
141 @cindex examples, specifier
142 @cindex adding a button to a toolbar
143 @cindex toolbar button, adding
145 A useful specifier application is adding a button to a toolbar. SXEmacs
146 provides several toolbars, one along each edge of the frame. Normally
147 only one is used at a time, the default. The default toolbar is
148 actually a specifier object which is the value of
149 @code{default-toolbar}. @xref{Toolbar Intro}.
151 The specification of a toolbar is simple: it is a list of buttons.
152 Each button is a vector with four elements: an icon, a command, the
153 enabled flag, and a help string. Let's retrieve the instance of the
154 toolbar you see in the selected frame.
157 (specifier-instance default-toolbar)
160 The value returned is, as promised, a list of vectors. Now let's build
161 up a button, and add it to the toolbar. Our button will invoke the last
162 defined keyboard macro. This is an alternative to
163 @code{name-last-kbd-macro} for creating a persistent macro, rather than
164 an alias for @kbd{C-x e}.
166 A toolbar button icon can be quite sophisticated, with different images
167 for button up, button down, and disabled states, and a similar set with
168 captions. We'll use a very simple icon, but we have to jump through a
169 few non-obvious hoops designed to support the sophisticated applications.
170 The rest of the button descriptor is straightforward.
173 (setq toolbar-my-kbd-macro-button
174 `[ (list (make-glyph "MyKbdMac"))
175 (lambda () (interactive) (execute-kbd-macro ,last-kbd-macro))
177 "Execute a previously defined keyboard macro." ])
179 (set-specifier default-toolbar
180 (cons toolbar-my-kbd-macro-button
181 (specifier-specs default-toolbar 'global))
185 To remove the button, just substitute the function @code{delete} for the
188 What is the difference between @code{specifier-instance}, which we used
189 in the example of retrieving the toolbar descriptor, and
190 @code{specifier-specs}, which was used in the toolbar manipulating code?
191 @code{specifier-specs} retrieves a copy of the instantiator, which is
192 abstract and does not depend on context. @code{specifier-instance}, on
193 the other hand, actually instantiates the specification, and returns the
194 result for the given context. Another way to express this is:
195 @code{specifier-specs} takes a @emph{locale} as an argument, while
196 @code{specifier-instance} takes a @emph{domain}. The reason for
197 providing @code{specifier-instance} is that sometimes you wish to see
198 the object that SXEmacs will actually use. @code{specifier-specs}, on
199 the other hand, shows you what the programmer (or user) requested. When
200 a program manipulates specifications, clearly it's the latter that is
203 In the case of the toolbar descriptor, it turns out that these are the
204 same: the instancing process is trivial. However, many specifications
205 have non-trivial instancing. Compare the results of the following forms
206 on my system. (The @samp{(cdr (first ...))} form is due to my use of
207 Mule. On non-Mule SXEmacsen, just use @code{specifier-specs}.)
210 (cdr (first (specifier-specs (face-font 'default) 'global)))
211 => "-*--14-*jisx0208*-0"
213 (specifier-instance (face-font 'default))
214 #<font-instance "-*--14-*jisx0208*-0" on #<x-device on ":0.0" 0x970> 0xe0028b 0x176b>
217 In this case, @code{specifier-instance} returns an opaque object;
218 programs can't work on it, they can only pass it around. Worse, in some
219 environments the instantiation will fail, resulting in a different value
220 (when another instantiation succeeds), or worse yet, an error, if all
221 attempts to instance the specifier fail. @code{specifier-instance} is
222 context-dependent, even for the exact same specification.
223 @code{specifier-specs} is deterministic, and only depends on the
226 Note that in the toolbar-changing code we operate in the global locale.
227 This means that narrower locales, if they have specifications, will
228 shadow our changes. (Specifier instancing does not merge
229 specifications. It selects the "highest-priority successful
230 specification" and instances that.)
232 In fact, in our example, it seems pretty likely that different buffers
233 @emph{should} have different buttons. (The icon can be the same, but
234 the keyboard macro you create in a Dired buffer is highly unlikely to be
235 useful in a LaTeX buffer!) Here's one way to implement this:
238 (setq toolbar-my-kbd-macro-button
239 `[ (list (make-glyph "MyKbdMac"))
240 (lambda () (interactive) (execute-kbd-macro ,last-kbd-macro))
242 "Execute a previously defined keyboard macro." ])
244 (set-specifier default-toolbar
245 (cons toolbar-my-kbd-macro-button
246 (cond ((specifier-specs default-toolbar
248 ((specifier-specs default-toolbar
253 Finally, a cautionary note: the use of @code{specifier-specs} in the
254 code above is for expository purposes. Don't use it in production code.
255 In fact, the @code{set-specifier} form above is likely to fail
256 occasionally, because you can add many specifications for the same
259 In these cases, @code{specifier-specs} will return a list. A further
260 refinement is that a specification may be associated with a set of
261 @dfn{specifier tags}. If the list of specifier tags is non-nil, then
262 @code{specifier-specs} will return a cons of the tag set and the
263 instantiator. Evidently @code{specifier-specs} is a bit unreliable.
264 (For toolbars, the code above should work 99% of the time, because
265 toolbars are rarely changed. Since instantiation is trivial, multiple
266 specs are not useful---the first one always succeeds.)
268 In fact, @code{specifier-specs} is intended to be used to display specs
269 to humans with a minimum of clutter. The robust way to access
270 specifications is via @code{specifier-spec-list}. @xref{Adding
271 Specifications}, for the definition of @dfn{spec-list}. @xref{Retrieving
272 Specifications}, for documentation of @code{specifier-specs} and
273 @code{specifier-spec-list}. To get the desired effect, replace the form
274 @code{(specifier-spec default-toolbar 'global)} with
277 (cdr (second (first (specifier-spec-list default-toolbar 'global))))
280 (It should be obvious why the example uses the lazy unreliable method!)
283 @node Specifiers In-Depth
284 @section In-Depth Overview of a Specifier
285 @cindex specification (in a specifier)
286 @cindex domain (in a specifier)
287 @cindex locale (in a specifier)
288 @cindex instantiator (in a specifier)
289 @cindex instancing (in a specifier)
290 @cindex instance (in a specifier)
291 @cindex inst-list (in a specifier)
292 @cindex inst-pair (in a specifier)
293 @cindex tag (in a specifier)
294 @cindex tag set (in a specifier)
295 @cindex specifier, specification
296 @cindex specifier, domain
297 @cindex specifier, locale
298 @cindex specifier, instantiator
299 @cindex specifier, instancing
300 @cindex specifier, instance
301 @cindex specifier, inst-list
302 @cindex specifier, inst-pair
303 @cindex specifier, tag
304 @cindex specifier, tag set
306 Having variables vary according the editing context is very useful, and
307 the buffer is the natural ``atomic'' unit of editing context. In a GUI
308 environment, it can be similarly useful to have variables whose values
309 vary according to display context. The atomic unit of display context
310 is the SXEmacs window. Buffers are cleanly grouped by modes, but windows
311 are not so easily pigeonholed. On the one hand, a window displays a
312 buffer, and thus one possible hierarchy is window, buffer, mode. On the
313 other, a window is a component of a frame. This generates the window,
314 frame, device hierarchy. Finally, there are objects such as toolbars
315 whose properties are described by specifiers. These do not fit
316 naturally into either hierarchy. This problem is as yet not cleanly
319 Another potential source of conceptual confusion is the instantiation
320 process. Instantiating a buffer-local variable is simple: at any given
321 point in time there is a current buffer, and its local values are used
322 and set whenever the variable is accessed, unless the programmer goes to
323 some special effort (uses @code{default-value} and @code{set-default}.
324 However, a specifier object encapsulates a set of @dfn{specifications},
325 each of which says what its value should be if a particular condition
326 applies. Several such conditions might apply simultaneously in a given
329 For example, one specification might be ``The value should be
330 darkseagreen2 on X devices'' another might be ``The value should be blue
331 in the *Help* buffer''. So what do we do for "the *Help* buffer on an X
332 device"? The answer is simple: give each type of locale a priority and
333 check them in priority order, returning the first instantiator that
334 successfully instantiates a value.
336 Given a specifier, a logical question is ``What is its value in a
337 particular situation?'' This involves looking through the specifications
338 to see which ones apply to this particular situation, and perhaps
339 preferring one over another if more than one applies. In specifier
340 terminology, a ``particular situation'' is called a @dfn{domain}, and
341 determining its value in a particular domain is called @dfn{instancing}.
342 Most of the time, a domain is identified by a particular window. For
343 example, if the redisplay engine is drawing text in the default face in
344 a particular window, it retrieves the specifier for the foreground color
345 of the default face and @dfn{instances} it in the domain given by that
346 window; in other words, it asks the specifier, ``What is your value in
349 Note that the redisplay example is in a sense canonical. That is,
350 specifiers are designed to present a uniform and @emph{efficient} API
351 to redisplay. It is the efficiency constraint that motivates the
352 introduction of specifier tags, and many restrictions on access (for
353 example, a buffer is not a domain, and you cannot instantiate a
354 specifier over a buffer).
356 More specifically, a specifier contains a set of @dfn{specifications},
357 each of which associates a @dfn{locale} (a window object, a buffer
358 object, a frame object, a device object, or the symbol @code{global})
359 with an @dfn{inst-list}, which is a list of one or more
360 @dfn{inst-pairs}. (For each possible locale, there can be at most one
361 specification containing that locale.) Each inst-pair is a cons of a
362 @dfn{tag set} (an unordered list of zero or more symbols, or @dfn{tags})
363 and an @dfn{instantiator} (the allowed form of this varies depending on
364 the type of specifier). In a given specification, there may be more
365 than one inst-pair with the same tag set; this is unlike for locales.
367 The tag set is used to restrict the sorts of devices over which the
368 instantiator is valid and to uniquely identify instantiators added by a
369 particular application, so that different applications can work on the
370 same specifier and not interfere with each other. Each tag can have a
371 @dfn{predicate} associated with it, which is a function of one argument
372 (a device) that specifies whether the tag matches that particular
373 device. (If a tag does not have a predicate, it matches all devices.)
374 All tags in a tag set must match a device for the associated inst-pair
375 to be instantiable over that device. (A null tag set is perfectly
376 valid, and trivially matches all devices.)
378 @c #### don't we have more device types now, gtk, ms-windows, mac-carbon?
379 The valid device types (normally @code{x}, @code{tty}, and
380 @code{stream}) and device classes (normally @code{color},
381 @code{grayscale}, and @code{mono}) can always be used as tags, and match
382 devices of the associated type or class (@pxref{Consoles and Devices}).
383 User-defined tags may be defined, with an optional predicate specified.
384 An application can create its own tag, use it to mark all its
385 instantiators, and be fairly confident that it will not interfere with
386 other applications that modify the same specifier---Functions that add
387 a specification to a specifier usually only overwrite existing
388 inst-pairs with the same tag set as was given, and a particular tag or
389 tag set can be specified when removing instantiators.
391 When a specifier is instanced in a domain, both the locale and the tag
392 set can be viewed as specifying necessary conditions that must apply in
393 that domain for an instantiator to be considered as a possible result of
394 the instancing. More specific locales always override more general
395 locales (thus, there is no particular ordering of the specifications in
396 a specifier); however, the tag sets are simply considered in the order
397 that the inst-pairs occur in the specification's inst-list.
399 Note also that the actual object that results from the instancing
400 (called an @dfn{instance object}) may not be the same as the instantiator
401 from which it was derived. For some specifier types (such as integer
402 specifiers and boolean specifiers), the instantiator will be returned
403 directly as the instance object. For other types, however, this
404 is not the case. For example, for font specifiers, the instantiator
405 is a font-description string and the instance object is a font-instance
406 object, which describes how the font is displayed on a particular device.
407 A font-instance object encapsulates such things as the actual font name
408 used to display the font on that device (a font-description string
409 under X is usually a wildcard specification that may resolve to
410 different font names, with possibly different foundries, widths, etc.,
411 on different devices), the extra properties of that font on that
412 device, etc. Furthermore, this conversion (called @dfn{instantiation})
413 might fail---a font or color might not exist on a particular device,
417 @node Specifier Instancing
418 @section How a Specifier Is Instanced
419 @cindex fallback (in a specifier)
420 @cindex specifier, fallback
422 Instancing of a specifier in a particular window domain proceeds as
427 First, SXEmacs searches for a specification whose locale is the same as
428 the window. If that fails, the search is repeated, looking for a locale
429 that is the same as the window's buffer. If that fails, the search is
430 repeated using the window's frame, then using the device that frame is
431 on. Finally, the specification whose locale is the symbol @code{global}
432 (if there is such a specification) is considered.
434 The inst-pairs contained in the specification that was found are
435 considered in their order in the inst-list, looking for one whose tag
436 set matches the device that is derived from the window domain. (The
437 tag set is an unordered list of zero or more tag symbols. For all
438 tags that have predicates associated with them, the predicate must
441 If a matching tag set is found, the corresponding instantiator is passed
442 to the specifier's instantiation method, which is specific to the type
443 of the specifier. If it succeeds, the resulting instance object is
444 returned as the result of the instancing and the instancing is done.
445 Otherwise, the operation continues, looking for another matching
446 inst-pair in the current specification.
448 When there are no more inst-pairs to be considered in the current
449 specification, the search starts over, looking for another specification
450 as in the first step above.
452 If all specifications are exhausted and no instance object can be
453 derived, the instancing fails. (Actually, this is not completely true.
454 Some specifier objects for built-in properties have a @dfn{fallback}
455 value, which is either an inst-list or another specifier object, that is
456 consulted if the instancing is about to fail. If it is an inst-list,
457 the searching proceeds using the inst-pairs in that list. If it is a
458 specifier, the entire instancing starts over using that specifier
459 instead of the given one. Fallback values are set by the C code and
460 cannot be modified, except perhaps indirectly, using any Lisp functions.
461 The purpose of them is to supply some values to make sure that
462 instancing of built-in properties can't fail and to implement some basic
463 specifier inheritance, such as the fact that faces inherit their
464 properties from the @code{default} face.)
467 It is also possible to instance a specifier over a frame domain or
468 device domain instead of over a window domain. The C code, for example,
469 instances the @code{top-toolbar-height} variable over a frame domain in
470 order to determine the height of a frame's top toolbar. Instancing over
471 a frame or device is similar to instancing over a window except that
472 specifications for locales that cannot be derived from the domain are
473 ignored. Specifically, instancing over a frame looks first for frame
474 locales, then device locales, then the @code{global} locale. Instancing
475 over a device domain looks only for device locales and the @code{global}
479 @node Specifier Types
480 @section Specifier Types
482 There are various different types of specifiers. The type of a
483 specifier controls what sorts of instantiators are valid, how an
484 instantiator is instantiated, etc. Here is a list of built-in specifier
489 The valid instantiators are the symbols @code{t} and @code{nil}.
490 Instance objects are the same as instantiators so no special
491 instantiation function is needed.
494 The valid instantiators are integers. Instance objects are the same as
495 instantiators so no special instantiation function is needed.
496 @code{modeline-shadow-thickness} is an example of an integer specifier
497 (negative thicknesses indicate that the shadow is drawn recessed instead
501 The valid instantiators are natnums (non-negative integers). Instance
502 objects are the same as instantiators so no special instantiation
503 function is needed. Natnum specifiers are used for dimension variables
504 such as @code{top-toolbar-height}.
507 All Lisp objects are valid instantiators. Instance objects are the same
508 as instantiators so no special instantiation function is needed.
511 The valid instantiators are strings describing fonts or vectors
512 indicating inheritance from the font of some face. Instance objects are
513 font-instance objects, which are specific to a particular device. The
514 instantiation method for font specifiers can fail, unlike for integer,
515 natnum, boolean, and generic specifiers.
518 The valid instantiators are strings describing colors or vectors
519 indicating inheritance from the foreground or background of some face.
520 Instance objects are color-instance objects, which are specific to a
521 particular device. The instantiation method for color specifiers can fail,
522 as for font specifiers.
525 Images are perhaps the most complicated type of built-in specifier. The
526 valid instantiators are strings (a filename, inline data for a pixmap,
527 or text to be displayed in a text glyph) or vectors describing inline
528 data of various sorts or indicating inheritance from the
529 background-pixmap property of some face. Instance objects are either
530 strings (for text images), image-instance objects (for pixmap images),
531 or subwindow objects (for subwindow images). The instantiation method
532 for image specifiers can fail, as for font and color specifiers.
535 The valid instantiators are the symbols @code{t} and @code{nil} and
536 vectors indicating inheritance from a boolean property of some face.
537 Specifiers of this sort are used for all of the built-in boolean
538 properties of faces. Instance objects are either the symbol @code{t}
539 or the symbol @code{nil}.
542 The valid instantiators are toolbar descriptors, which are lists
543 of toolbar-button descriptors (each of which is a vector of two
544 or four elements). @xref{Toolbar}, for more information.
547 Color and font instance objects can also be used in turn as
548 instantiators for a new color or font instance object. Since these
549 instance objects are device-specific, the instantiator can be used
550 directly as the new instance object, but only if they are of the same
551 device. If the devices differ, the base color or font of the
552 instantiating object is effectively used instead as the instantiator.
554 @xref{Faces and Window-System Objects}, for more information on fonts,
555 colors, and face-boolean specifiers. @xref{Glyphs}, for more information
556 about image specifiers. @xref{Toolbar}, for more information on toolbar
559 @defun specifier-type specifier
560 This function returns the type of @var{specifier}. The returned value
561 will be a symbol: one of @code{integer}, @code{boolean}, etc., as
562 listed in the above table.
565 Functions are also provided to query whether an object is a particular
568 @defun boolean-specifier-p object
569 This function returns non-@code{nil} if @var{object} is a boolean
573 @defun integer-specifier-p object
574 This function returns non-@code{nil} if @var{object} is an integer
578 @defun natnum-specifier-p object
579 This function returns non-@code{nil} if @var{object} is a natnum
583 @defun generic-specifier-p object
584 This function returns non-@code{nil} if @var{object} is a generic
588 @defun face-boolean-specifier-p object
589 This function returns non-@code{nil} if @var{object} is a face-boolean
593 @defun toolbar-specifier-p object
594 This function returns non-@code{nil} if @var{object} is a toolbar
598 @defun font-specifier-p object
599 This function returns non-@code{nil} if @var{object} is a font
603 @defun color-specifier-p object
604 This function returns non-@code{nil} if @var{object} is a color
608 @defun image-specifier-p object
609 This function returns non-@code{nil} if @var{object} is an image
614 @node Adding Specifications
615 @section Adding specifications to a Specifier
617 @defun add-spec-to-specifier specifier instantiator &optional locale tag-set how-to-add
618 This function adds a specification to @var{specifier}. The
619 specification maps from @var{locale} (which should be a window, buffer,
620 frame, device, or the symbol @code{global}, and defaults to
621 @code{global}) to @var{instantiator}, whose allowed values depend on the
622 type of the specifier. Optional argument @var{tag-set} limits the
623 instantiator to apply only to the specified tag set, which should be a
624 list of tags all of which must match the device being instantiated over
625 (tags are a device type, a device class, or tags defined with
626 @code{define-specifier-tag}). Specifying a single symbol for
627 @var{tag-set} is equivalent to specifying a one-element list containing
628 that symbol. Optional argument @var{how-to-add} specifies what to do if
629 there are already specifications in the specifier. It should be one of
633 Put at the beginning of the current list of instantiators for @var{locale}.
635 Add to the end of the current list of instantiators for @var{locale}.
636 @item remove-tag-set-prepend
637 This is the default. Remove any existing instantiators whose tag set is
638 the same as @var{tag-set}; then put the new instantiator at the
639 beginning of the current list.
640 @item remove-tag-set-append
641 Remove any existing instantiators whose tag set is the same as
642 @var{tag-set}; then put the new instantiator at the end of the current
645 Remove all previous instantiators for this locale before adding the new
647 @item remove-locale-type
648 Remove all specifications for all locales of the same type as
649 @var{locale} (this includes @var{locale} itself) before adding the new
652 Remove all specifications from the specifier before adding the new spec.
655 @code{remove-tag-set-prepend} is the default.
657 You can retrieve the specifications for a particular locale or locale type
658 with the function @code{specifier-spec-list} or @code{specifier-specs}.
661 @defun add-spec-list-to-specifier specifier spec-list &optional how-to-add
662 This function adds a @dfn{spec-list} (a list of specifications) to
663 @var{specifier}. The format of a spec-list is
666 @code{((@var{locale} (@var{tag-set} . @var{instantiator}) ...) ...)}
673 @var{locale} := a window, a buffer, a frame, a device, or @code{global}
675 @var{tag-set} := an unordered list of zero or more @var{tags}, each of
678 @var{tag} := a device class (@pxref{Consoles and Devices}), a device type,
679 or a tag defined with @code{define-specifier-tag}
681 @var{instantiator} := format determined by the type of specifier
684 The pair @code{(@var{tag-set} . @var{instantiator})} is called an
685 @dfn{inst-pair}. A list of inst-pairs is called an @dfn{inst-list}.
686 The pair @code{(@var{locale} . @var{inst-list})} is called a
687 @dfn{specification}. A spec-list, then, can be viewed as a list of
690 @var{how-to-add} specifies how to combine the new specifications with
691 the existing ones, and has the same semantics as for
692 @code{add-spec-to-specifier}.
694 The higher-level function @code{set-specifier} is often
695 more convenient because it allows abbreviations of spec-lists to be used
696 instead of the heavily nested canonical syntax. However, one should
697 take great care in using them with specifiers types which can have lists
698 as instantiators, such as toolbar specifiers and generic specifiers. In
699 those cases it's probably best to use @code{add-spec-to-specifier} or
700 @code{add-spec-list-to-specifier}.
703 @defspec let-specifier specifier-list &rest body
704 This special form temporarily adds specifications to specifiers,
705 evaluates forms in @var{body} and restores the specifiers to their
706 previous states. The specifiers and their temporary specifications are
707 listed in @var{specifier-list}.
709 The format of @var{specifier-list} is
712 ((@var{specifier} @var{value} &optional @var{locale} @var{tag-set} @var{how-to-add}) ...)
715 @var{specifier} is the specifier to be temporarily modified.
716 @var{value} is the instantiator to be temporarily added to specifier in
717 @var{locale}. @var{locale}, @var{tag-set} and @var{how-to-add} have the
718 same meaning as in @code{add-spec-to-specifier}.
720 This special form is implemented as a macro; the code resulting from
721 macro expansion will add specifications to specifiers using
722 @code{add-spec-to-specifier}. After forms in @var{body} are evaluated,
723 the temporary specifications are removed and old specifier spec-lists
726 @var{locale}, @var{tag-set} and @var{how-to-add} may be omitted, and
727 default to @code{nil}. The value of the last form in @var{body} is
730 NOTE: If you want the specifier's instance to change in all
731 circumstances, use @code{(selected-window)} as the @var{locale}. If
732 @var{locale} is @code{nil} or omitted, it defaults to @code{global}.
734 The following example removes the 3D modeline effect in the currently
735 selected window for the duration of a second:
738 (let-specifier ((modeline-shadow-thickness 0 (selected-window)))
743 @defun set-specifier specifier value &optional locale tag-set how-to-add
744 This function adds some specifications to @var{specifier}. @var{value}
745 can be a single instantiator or tagged instantiator (added as a global
746 specification), a list of tagged and/or untagged instantiators (added as
747 a global specification), a cons of a locale and instantiator or locale
748 and instantiator list, a list of such conses, or nearly any other
749 reasonable form. More specifically, @var{value} can be anything
750 accepted by @code{canonicalize-spec-list} (described below).
752 @var{locale}, @var{tag-set}, and @var{how-to-add} are the same as in
753 @code{add-spec-to-specifier}.
755 Note that @code{set-specifier} is exactly complementary to
756 @code{specifier-specs} except in the case where @var{specifier} has no
757 specs at all in it but @code{nil} is a valid instantiator (in that case,
758 @code{specifier-specs} will return @code{nil} (meaning no specs) and
759 @code{set-specifier} will interpret the @code{nil} as meaning ``I'm
760 adding a global instantiator and its value is @code{nil}''), or in
761 strange cases where there is an ambiguity between a spec-list and an
762 inst-list, etc. (The built-in specifier types are designed in such a way
763 as to avoid any such ambiguities.) For robust code,
764 @code{set-specifier} should probably be avoided for specifier types
765 which accept lists as instantiators (currently toolbar specifiers and
768 If you want to work with spec-lists, you should probably not use these
769 functions, but should use the lower-level functions
770 @code{specifier-spec-list} and @code{add-spec-list-to-specifier}. These
771 functions always work with fully-qualified spec-lists; thus, there is no
775 @defun canonicalize-inst-pair inst-pair specifier-type &optional noerror
776 This function canonicalizes the given @var{inst-pair}.
778 @var{specifier-type} specifies the type of specifier that this
779 @var{spec-list} will be used for.
781 Canonicalizing means converting to the full form for an inst-pair, i.e.
782 @code{(@var{tag-set} . @var{instantiator})}. A single, untagged
783 instantiator is given a tag set of @code{nil} (the empty set), and a
784 single tag is converted into a tag set consisting only of that tag.
786 If @var{noerror} is non-@code{nil}, signal an error if the inst-pair is
787 invalid; otherwise return @code{t}.
790 @defun canonicalize-inst-list inst-list specifier-type &optional noerror
791 This function canonicalizes the given @var{inst-list} (a list of
794 @var{specifier-type} specifies the type of specifier that this @var{inst-list}
797 Canonicalizing means converting to the full form for an inst-list, i.e.
798 @code{((@var{tag-set} . @var{instantiator}) ...)}. This function
799 accepts a single inst-pair or any abbreviation thereof or a list of
800 (possibly abbreviated) inst-pairs. (See @code{canonicalize-inst-pair}.)
802 If @var{noerror} is non-@code{nil}, signal an error if the inst-list is
803 invalid; otherwise return @code{t}.
806 @defun canonicalize-spec spec specifier-type &optional noerror
807 This function canonicalizes the given @var{spec} (a specification).
809 @var{specifier-type} specifies the type of specifier that this
810 @var{spec-list} will be used for.
812 Canonicalizing means converting to the full form for a spec, i.e.
813 @code{(@var{locale} (@var{tag-set} . @var{instantiator}) ...)}. This
814 function accepts a possibly abbreviated inst-list or a cons of a locale
815 and a possibly abbreviated inst-list. (See
816 @code{canonicalize-inst-list}.)
818 If @var{noerror} is @code{nil}, signal an error if the specification is
819 invalid; otherwise return @code{t}.
822 @defun canonicalize-spec-list spec-list specifier-type &optional noerror
823 This function canonicalizes the given @var{spec-list} (a list of
826 @var{specifier-type} specifies the type of specifier that this
827 @var{spec-list} will be used for.
829 If @var{noerror} is @code{nil}, signal an error if the spec-list is
830 invalid; otherwise return @code{t} for an invalid spec-list. (Note that
831 this cannot be confused with a canonical spec-list.)
833 Canonicalizing means converting to the full form for a spec-list, i.e.
834 @code{((@var{locale} (@var{tag-set} . @var{instantiator}) ...) ...)}.
835 This function accepts a possibly abbreviated specification or a list of
836 such things. (See @code{canonicalize-spec}.) This is the function used
837 to convert spec-lists accepted by @code{set-specifier} and such into a
838 form suitable for @code{add-spec-list-to-specifier}.
840 This function tries extremely hard to resolve any ambiguities,
841 and the built-in specifier types (font, image, toolbar, etc.) are
842 designed so that there won't be any ambiguities.
844 The canonicalization algorithm is as follows:
848 Attempt to parse @var{spec-list} as a single, possibly abbreviated,
851 If that fails, attempt to parse @var{spec-list} as a list of (abbreviated)
854 If that fails, @var{spec-list} is invalid.
857 A possibly abbreviated specification @var{spec} is parsed by
861 Attempt to parse @var{spec} as a possibly abbreviated inst-list.
863 If that fails, attempt to parse @var{spec} as a cons of a locale and an
864 (abbreviated) inst-list.
866 If that fails, @var{spec} is invalid.
869 A possibly abbreviated inst-list @var{inst-list} is parsed by
873 Attempt to parse @var{inst-list} as a possibly abbreviated inst-pair.
875 If that fails, attempt to parse @var{inst-list} as a list of (abbreviated)
878 If that fails, @var{inst-list} is invalid.
881 A possibly abbreviated inst-pair @var{inst-pair} is parsed by
885 Check if @var{inst-pair} is @code{valid-instantiator-p}.
887 If not, check if @var{inst-pair} is a cons of something that is a tag, ie,
888 @code{valid-specifier-tag-p}, and something that is @code{valid-instantiator-p}.
890 If not, check if @var{inst-pair} is a cons of a list of tags and something that
891 is @code{valid-instantiator-p}.
893 Otherwise, @var{inst-pair} is invalid.
896 In summary, this function generally prefers more abbreviated forms.
900 @node Retrieving Specifications
901 @section Retrieving the Specifications from a Specifier
903 @defun specifier-spec-list specifier &optional locale tag-set exact-p
904 This function returns the spec-list of specifications for
905 @var{specifier} in @var{locale}.
907 If @var{locale} is a particular locale (a window, buffer, frame, device,
908 or the symbol @code{global}), a spec-list consisting of the
909 specification for that locale will be returned.
911 If @var{locale} is a locale type (i.e. one of the symbols @code{window},
912 @code{buffer}, @code{frame}, or @code{device}), a spec-list of the
913 specifications for all locales of that type will be returned.
915 If @var{locale} is @code{nil} or the symbol @code{all}, a spec-list of
916 all specifications in @var{specifier} will be returned.
918 @var{locale} can also be a list of locales, locale types, and/or
919 @code{all}; the result is as if @code{specifier-spec-list} were called
920 on each element of the list and the results concatenated together.
922 Only instantiators where @var{tag-set} (a list of zero or more tags) is
923 a subset of (or possibly equal to) the instantiator's tag set are
924 returned. (The default value of @code{nil} is a subset of all tag sets,
925 so in this case no instantiators will be screened out.) If @var{exact-p}
926 is non-@code{nil}, however, @var{tag-set} must be equal to an
927 instantiator's tag set for the instantiator to be returned.
930 @defun specifier-specs specifier &optional locale tag-set exact-p
931 This function returns the specification(s) for @var{specifier} in
934 If @var{locale} is a single locale or is a list of one element
935 containing a single locale, then a ``short form'' of the instantiators
936 for that locale will be returned. Otherwise, this function is identical
937 to @code{specifier-spec-list}.
939 The ``short form'' is designed for readability and not for ease of use
940 in Lisp programs, and is as follows:
944 If there is only one instantiator, then an inst-pair (i.e. cons of tag
945 and instantiator) will be returned; otherwise a list of inst-pairs will
948 For each inst-pair returned, if the instantiator's tag is @code{any},
949 the tag will be removed and the instantiator itself will be returned
950 instead of the inst-pair.
952 If there is only one instantiator, its value is @code{nil}, and its tag
953 is @code{any}, a one-element list containing @code{nil} will be returned
954 rather than just @code{nil}, to distinguish this case from there being
955 no instantiators at all.
960 @defun specifier-fallback specifier
961 This function returns the fallback value for @var{specifier}. Fallback
962 values are provided by the C code for certain built-in specifiers to
963 make sure that instancing won't fail even if all specs are removed from
964 the specifier, or to implement simple inheritance behavior (e.g. this
965 method is used to ensure that faces other than @code{default} inherit
966 their attributes from @code{default}). By design, you cannot change the
967 fallback value, and specifiers created with @code{make-specifier} will
968 never have a fallback (although a similar, Lisp-accessible capability
969 may be provided in the future to allow for inheritance).
971 The fallback value will be an inst-list that is instanced like
972 any other inst-list, a specifier of the same type as @var{specifier}
973 (results in inheritance), or @code{nil} for no fallback.
975 When you instance a specifier, you can explicitly request that the
976 fallback not be consulted. (The C code does this, for example, when
977 merging faces.) See @code{specifier-instance}.
981 @node Specifier Tag Functions
982 @section Working With Specifier Tags
984 A specifier tag set is an entity that is attached to an instantiator
985 and can be used to restrict the scope of that instantiator to a
986 particular device class or device type and/or to mark instantiators
987 added by a particular package so that they can be later removed.
989 A specifier tag set consists of a list of zero or more specifier tags,
990 each of which is a symbol that is recognized by SXEmacs as a tag. (The
991 valid device types and device classes are always tags, as are any tags
992 defined by @code{define-specifier-tag}.) It is called a ``tag set'' (as
993 opposed to a list) because the order of the tags or the number of times
994 a particular tag occurs does not matter.
996 Each tag has a predicate associated with it, which specifies whether
997 that tag applies to a particular device. The tags which are device
998 types and classes match devices of that type or class. User-defined
999 tags can have any predicate, or none (meaning that all devices match).
1000 When attempting to instance a specifier, a particular instantiator is
1001 only considered if the device of the domain being instanced over matches
1002 all tags in the tag set attached to that instantiator.
1004 Most of the time, a tag set is not specified, and the instantiator gets
1005 a null tag set, which matches all devices.
1007 @defun valid-specifier-tag-p tag
1008 This function returns non-@code{nil} if @var{tag} is a valid specifier
1012 @defun valid-specifier-tag-set-p tag-set
1013 This function returns non-@code{nil} if @var{tag-set} is a valid
1017 @defun canonicalize-tag-set tag-set
1018 This function canonicalizes the given tag set. Two canonicalized tag
1019 sets can be compared with @code{equal} to see if they represent the same
1020 tag set. (Specifically, canonicalizing involves sorting by symbol name
1021 and removing duplicates.)
1024 @defun device-matches-specifier-tag-set-p device tag-set
1025 This function returns non-@code{nil} if @var{device} matches specifier
1026 tag set @var{tag-set}. This means that @var{device} matches each tag in
1030 @defun define-specifier-tag tag &optional predicate
1031 This function defines a new specifier tag. If @var{predicate} is
1032 specified, it should be a function of one argument (a device) that
1033 specifies whether the tag matches that particular device. If
1034 @var{predicate} is omitted, the tag matches all devices.
1036 You can redefine an existing user-defined specifier tag. However, you
1037 cannot redefine the built-in specifier tags (the device types and
1038 classes) or the symbols @code{nil}, @code{t}, @code{all}, or
1042 @defun device-matching-specifier-tag-list &optional device
1043 This function returns a list of all specifier tags matching
1044 @var{device}. @var{device} defaults to the selected device if omitted.
1047 @defun specifier-tag-list
1048 This function returns a list of all currently-defined specifier tags.
1049 This includes the built-in ones (the device types and classes).
1052 @defun specifier-tag-predicate tag
1053 This function returns the predicate for the given specifier tag.
1057 @node Specifier Instancing Functions
1058 @section Functions for Instancing a Specifier
1060 @defun specifier-instance specifier &optional domain default no-fallback
1061 This function instantiates @var{specifier} (returns its value) in
1062 @var{domain}. If no instance can be generated for this domain, return
1065 @var{domain} should be a window, frame, or device. Other values that
1066 are legal as a locale (e.g. a buffer) are not valid as a domain because
1067 they do not provide enough information to identify a particular device
1068 (see @code{valid-specifier-domain-p}). @var{domain} defaults to the
1069 selected window if omitted.
1071 @dfn{Instantiating} a specifier in a particular domain means determining
1072 the specifier's ``value'' in that domain. This is accomplished by
1073 searching through the specifications in the specifier that correspond to
1074 all locales that can be derived from the given domain, from specific to
1075 general. In most cases, the domain is an SXEmacs window. In that case
1076 specifications are searched for as follows:
1080 A specification whose locale is the window itself;
1082 A specification whose locale is the window's buffer;
1084 A specification whose locale is the window's frame;
1086 A specification whose locale is the window's frame's device;
1088 A specification whose locale is the symbol @code{global}.
1091 If all of those fail, then the C-code-provided fallback value for this
1092 specifier is consulted (see @code{specifier-fallback}). If it is an
1093 inst-list, then this function attempts to instantiate that list just as
1094 when a specification is located in the first five steps above. If the
1095 fallback is a specifier, @code{specifier-instance} is called recursively
1096 on this specifier and the return value used. Note, however, that if the
1097 optional argument @var{no-fallback} is non-@code{nil}, the fallback
1098 value will not be consulted.
1100 Note that there may be more than one specification matching a particular
1101 locale; all such specifications are considered before looking for any
1102 specifications for more general locales. Any particular specification
1103 that is found may be rejected because it is tagged to a particular
1104 device class (e.g. @code{color}) or device type (e.g. @code{x}) or both
1105 and the device for the given domain does not match this, or because the
1106 specification is not valid for the device of the given domain (e.g. the
1107 font or color name does not exist for this particular X server).
1109 The returned value is dependent on the type of specifier. For example,
1110 for a font specifier (as returned by the @code{face-font} function), the
1111 returned value will be a font-instance object. For images, the returned
1112 value will be a string, pixmap, or subwindow.
1115 @defun specifier-matching-instance specifier matchspec &optional domain default no-fallback
1116 This function returns an instance for @var{specifier} in @var{domain}
1117 that matches @var{matchspec}. If no instance can be generated for
1118 @var{domain}, return @var{default}.
1120 This function is identical to @code{specifier-instance} except that a
1121 specification will only be considered if it matches @var{matchspec}.
1122 The definition of ``match,'' and allowed values for @var{matchspec}, are
1123 dependent on the particular type of specifier. Here are some examples:
1127 For chartable (e.g. display table) specifiers, @var{matchspec} should be a
1128 character, and the specification (a chartable) must give a value for
1129 that character in order to be considered. This allows you to specify,
1130 @emph{e.g.}, a buffer-local display table that only gives values for particular
1131 characters. All other characters are handled as if the buffer-local
1132 display table is not there. (Chartable specifiers are not yet
1135 For font specifiers, @var{matchspec} should be a charset,
1136 and the specification (a font string) must have
1137 a registry that matches the charset's registry. (This only makes sense
1138 with Mule support.) This makes it easy to choose a font that can
1139 display a particular character. (This is what redisplay does, in fact.)
1143 @defun specifier-instance-from-inst-list specifier domain inst-list &optional default
1144 This function attempts to convert a particular inst-list into an
1145 instance. This attempts to instantiate @var{inst-list} in the given
1146 @var{domain}, as if @var{inst-list} existed in a specification in
1147 @var{specifier}. If the instantiation fails, @var{default} is returned.
1148 In most circumstances, you should not use this function; use
1149 @code{specifier-instance} instead.
1153 @node Specifier Examples
1154 @section Examples of Specifier Usage
1156 Now let us present an example to clarify the theoretical discussions we
1157 have been through. In this example, we will use the general specifier
1158 functions for clarity. Keep in mind that many types of specifiers, and
1159 some other types of objects that are associated with specifiers
1160 (e.g. faces), provide convenience functions making it easier to work
1161 with objects of that type.
1163 Let us consider the background color of the default face. A specifier
1164 is used to specify how that color will appear in different domains.
1165 First, let's retrieve the specifier:
1168 (setq sp (face-property 'default 'background))
1169 @result{} #<color-specifier 0x3da>
1173 (specifier-specs sp)
1174 @result{} ((#<buffer "device.c"> (nil . "forest green"))
1175 (#<window on "Makefile" 0x8a2b> (nil . "hot pink"))
1176 (#<x-frame "emacs" 0x4ac> (nil . "puke orange")
1178 (#<x-frame "VM" 0x4ac> (nil . "magenta"))
1179 (global ((tty) . "cyan") (nil . "white"))
1183 Then, say we want to determine what the background color of the default
1184 face is for the window currently displaying the buffer @samp{*scratch*}.
1188 (get-buffer-window "*scratch*")
1189 @result{} #<window on "*scratch*" 0x4ad>
1190 (window-frame (get-buffer-window "*scratch*"))
1191 @result{} #<x-frame "emacs" 0x4ac>
1192 (specifier-instance sp (get-buffer-window "*scratch*"))
1193 @result{} #<color-instance moccasin 47=(FFFF,E4E4,B5B5) 0x6309>
1196 Note that we passed a window to @code{specifier-instance}, not a buffer.
1197 We cannot pass a buffer because a buffer by itself does not provide enough
1198 information. The buffer might not be displayed anywhere at all, or
1199 could be displayed in many different frames on different devices.
1201 The result is arrived at like this:
1205 First, we look for a specification matching the buffer displayed in the
1206 window, i.e. @samp{*scratch*}. There are none, so we proceed.
1208 Then, we look for a specification matching the window itself. Again, there
1211 Then, we look for a specification matching the window's frame. The
1212 specification @code{(#<x-frame "emacs" 0x4ac> . "puke orange")} is
1213 found. We call the instantiation method for colors, passing it the
1214 locale we were searching over (i.e. the window, in this case) and the
1215 instantiator (@samp{"puke orange"}). However, the particular device
1216 which this window is on (let's say it's an X connection) doesn't
1217 recognize the color @samp{"puke orange"}, so the specification is
1220 So we continue looking for a specification matching the window's frame.
1221 We find @samp{(#<x-frame "emacs" 0x4ac> . "moccasin")}. Again, we
1222 call the instantiation method for colors. This time, the X server
1223 our window is on recognizes the color @samp{moccasin}, and so the
1224 instantiation method succeeds and returns a color instance.
1227 Here's another example, which implements something like GNU Emacs's
1228 ``frame-local'' variables.
1233 ;; There are probably better ways to write this macro
1234 ;; Heaven help you if VAR is a buffer-local; you will become very
1235 ;; confused. Probably should error on that.
1236 (defmacro define-frame-local-variable (var)
1237 "Make the unbound symbol VAR become a frame-local variable."
1238 (let ((val (if (boundp var) (symbol-value var) nil)))
1240 (setq ,var (make-specifier 'generic))
1241 (add-spec-to-specifier ,var ',val 'global))))
1243 ;; I'm not real happy about this terminology, how can `setq' be a defun?
1244 ;; But `frame-set' would have people writing "(frame-set 'foo value)".
1245 (defun frame-setq (var value &optional frame)
1246 "Set the local value of VAR to VALUE in FRAME.
1248 FRAME defaults to the selected frame."
1249 (and frame (not (framep frame))
1250 (error 'invalid-argument "FRAME must be a frame", frame))
1251 (add-spec-to-specifier var value (or frame (selected-frame))))
1253 (defun frame-value (var &optional frame)
1254 "Get the local value of VAR in FRAME.
1256 FRAME defaults to the selected frame."
1257 (and frame (not (framep frame))
1258 (error 'invalid-argument "FRAME must be a frame", frame))
1259 ;; this is not just a map from frames to values; it also falls back
1260 ;; to the global value
1261 (specifier-instance var (or frame (selected-frame))))
1264 (defun frame-set-default (var value)
1265 "Set the default value of frame-local variable VAR to VALUE."
1266 (add-spec-to-specifier var value 'global))
1268 (defun frame-get-default (var)
1269 "Get the default value of frame-local variable VAR."
1270 (car (specifier-specs var 'global)))
1273 Now you can execute the above definitions (eg, with @code{eval-last-sexp})
1274 and switch to @file{*scratch*} to play. Things will work differently if
1275 you already have a variable named @code{foo}.
1281 @error{} Symbol's value as variable is void: foo
1283 (define-frame-local-variable foo)
1286 ;; the value of foo is a specifier, which is an opaque object;
1287 ;; you must use accessor functions to get values
1290 @result{} #<generic-specifier global=(nil) 0x4f5cb>
1292 ;; since no frame-local value is set, the global value (which is the
1293 ;; constant `nil') is returned
1297 ;; get the default explicitly
1298 (frame-get-default foo)
1301 ;; get the whole specification list
1302 (specifier-specs foo 'global)
1305 ;; give foo a frame-local value
1307 (frame-setq foo 'bar)
1310 ;; access foo in several ways
1312 ;; Note that the print function for this kind of specifier only
1313 ;; gives you the global setting. To get the full list of specs for
1314 ;; debugging or study purposes, you must use specifier-specs or
1315 ;; specifier-spec-list.
1317 @result{} #<generic-specifier global=(nil) 0x4f5cb>
1319 ;; get the whole specification list
1320 (specifier-specs foo)
1321 @result{} ((#<x-frame "Message" 0x1bd66> (nil . bar)) (global (nil)))
1323 ;; get the frame-local value
1327 ;; get the default explicitly
1328 (frame-get-default foo)
1331 ;; Switch to another frame and evaluate:
1332 ;; C-x 5 o M-: (frame-setq foo 'baz) RET M-: (frame-value foo) RET
1337 (specifier-specs foo)
1338 @result{} ((#<x-frame "emacs" 0x28ec> (nil . baz))
1339 (#<x-frame "Message" 0x1bd66> (nil . bar))
1345 (frame-get-default foo)
1349 Note that since specifiers generalize both frame-local and buffer-local
1350 variables in a sensible way, SXEmacs is not likely to put a high priority
1351 on implementing frame-local variables.
1352 @c Thanks to Jerry James for the following explanation. He is not
1353 @c responsible for its use here, Stephen Turnbull is.
1354 In fact, some developers think that frame-local variables are evil for
1355 the same reason that buffer-local variables are evil: the declaration is
1356 both global and invisible. That is, you cannot tell whether a variable
1357 is ``normal,'' buffer-local, or frame-local just by looking at it. So
1358 if you have namespace management problems, and some other Lisp package
1359 happens to use a variable name that you already declared frame- or
1360 buffer-local, weird stuff happens, and it is extremely hard to track
1364 @node Creating Specifiers
1365 @section Creating New Specifier Objects
1367 @defun make-specifier type
1368 This function creates a new specifier.
1370 A specifier is an object that can be used to keep track of a property
1371 whose value can be per-buffer, per-window, per-frame, or per-device,
1372 and can further be restricted to a particular device-type or device-class.
1373 Specifiers are used, for example, for the various built-in properties of a
1374 face; this allows a face to have different values in different frames,
1375 buffers, etc. For more information, see @code{specifier-instance},
1376 @code{specifier-specs}, and @code{add-spec-to-specifier}; or, for a detailed
1377 description of specifiers, including how they are instantiated over a
1378 particular domain (i.e. how their value in that domain is determined),
1379 see the chapter on specifiers in the SXEmacs Lisp Reference Manual.
1381 @var{type} specifies the particular type of specifier, and should be one
1382 of the symbols @code{generic}, @code{integer}, @code{natnum},
1383 @code{boolean}, @code{color}, @code{font}, @code{image},
1384 @code{face-boolean}, or @code{toolbar}.
1386 For more information on particular types of specifiers, see the
1387 functions @code{make-generic-specifier}, @code{make-integer-specifier},
1388 @code{make-natnum-specifier}, @code{make-boolean-specifier},
1389 @code{make-color-specifier}, @code{make-font-specifier},
1390 @code{make-image-specifier}, @code{make-face-boolean-specifier}, and
1391 @code{make-toolbar-specifier}.
1394 @defun make-specifier-and-init type spec-list &optional dont-canonicalize
1395 This function creates and initializes a new specifier.
1397 This is a convenience API combining @code{make-specifier} and
1398 @code{set-specifier} that allows you to create
1399 a specifier and add specs to it at the same time. @var{type} specifies
1400 the specifier type. Allowed types are as for @code{make-specifier}.
1402 @var{spec-list} supplies the specification(s) to be
1403 added to the specifier. Any abbreviation of
1404 the full spec-list form accepted by @code{canonicalize-spec-list} may
1406 However, if the optional argument @var{dont-canonicalize} is non-@code{nil},
1407 canonicalization is not performed, and the @var{spec-list} must already
1411 @defun make-integer-specifier spec-list
1413 Return a new @code{integer} specifier object with the given
1414 specification list. @var{spec-list} can be a list of specifications
1415 (each of which is a cons of a locale and a list of instantiators), a
1416 single instantiator, or a list of instantiators.
1418 Valid instantiators for integer specifiers are integers.
1421 @defun make-boolean-specifier spec-list
1423 Return a new @code{boolean} specifier object with the given
1424 specification list. @var{spec-list} can be a list of specifications
1425 (each of which is a cons of a locale and a list of instantiators), a
1426 single instantiator, or a list of instantiators.
1428 Valid instantiators for boolean specifiers are @code{t} and @code{nil}.
1431 @defun make-natnum-specifier spec-list
1433 Return a new @code{natnum} specifier object with the given specification
1434 list. @var{spec-list} can be a list of specifications (each of which is
1435 a cons of a locale and a list of instantiators), a single instantiator,
1436 or a list of instantiators.
1438 Valid instantiators for natnum specifiers are non-negative integers.
1441 @defun make-generic-specifier spec-list
1443 Return a new @code{generic} specifier object with the given
1444 specification list. @var{spec-list} can be a list of specifications
1445 (each of which is a cons of a locale and a list of instantiators), a
1446 single instantiator, or a list of instantiators.
1448 Valid instantiators for generic specifiers are all Lisp values. They
1449 are returned back unchanged when a specifier is instantiated.
1452 @defun make-display-table-specifier spec-list
1454 Return a new @code{display-table} specifier object with the given spec
1455 list. @var{spec-list} can be a list of specifications (each of which is
1456 a cons of a locale and a list of instantiators), a single instantiator,
1457 or a list of instantiators.
1459 Valid instantiators for display-table specifiers are described in detail
1460 in the doc string for @code{current-display-table} (@pxref{Active
1465 @node Specifier Validation Functions
1466 @section Functions for Checking the Validity of Specifier Components
1468 @defun valid-specifier-domain-p domain
1469 This function returns non-@code{nil} if @var{domain} is a valid
1470 specifier domain. A domain is used to instance a specifier
1471 (i.e. determine the specifier's value in that domain). Valid domains
1472 are a window, frame, or device. (@code{nil} is not valid.)
1475 @defun valid-specifier-locale-p locale
1476 This function returns non-@code{nil} if @var{locale} is a valid
1477 specifier locale. Valid locales are a device, a frame, a window, a
1478 buffer, and @code{global}. (@code{nil} is not valid.)
1481 @defun valid-specifier-locale-type-p locale-type
1482 Given a specifier @var{locale-type}, this function returns non-@code{nil} if it
1483 is valid. Valid locale types are the symbols @code{global},
1484 @code{device}, @code{frame}, @code{window}, and @code{buffer}. (Note,
1485 however, that in functions that accept either a locale or a locale type,
1486 @code{global} is considered an individual locale.)
1489 @defun valid-specifier-type-p specifier-type
1490 Given a @var{specifier-type}, this function returns non-@code{nil} if it
1491 is valid. Valid types are @code{generic}, @code{integer},
1492 @code{boolean}, @code{color}, @code{font}, @code{image},
1493 @code{face-boolean}, and @code{toolbar}.
1496 @defun valid-specifier-tag-p tag
1497 This function returns non-@code{nil} if @var{tag} is a valid specifier
1501 @defun valid-instantiator-p instantiator specifier-type
1502 This function returns non-@code{nil} if @var{instantiator} is valid for
1503 @var{specifier-type}.
1506 @defun valid-inst-list-p inst-list type
1507 This function returns non-@code{nil} if @var{inst-list} is valid for
1508 specifier type @var{type}.
1511 @defun valid-spec-list-p spec-list type
1512 This function returns non-@code{nil} if @var{spec-list} is valid for
1513 specifier type @var{type}.
1516 @defun check-valid-instantiator instantiator specifier-type
1517 This function signals an error if @var{instantiator} is invalid for
1518 @var{specifier-type}.
1521 @defun check-valid-inst-list inst-list type
1522 This function signals an error if @var{inst-list} is invalid for
1523 specifier type @var{type}.
1526 @defun check-valid-spec-list spec-list type
1527 This function signals an error if @var{spec-list} is invalid for
1528 specifier type @var{type}.
1532 @node Other Specification Functions
1533 @section Other Functions for Working with Specifications in a Specifier
1535 @defun copy-specifier specifier &optional dest locale tag-set exact-p how-to-add
1536 This function copies @var{specifier} to @var{dest}, or creates a new one
1537 if @var{dest} is @code{nil}.
1539 If @var{dest} is @code{nil} or omitted, a new specifier will be created
1540 and the specifications copied into it. Otherwise, the specifications
1541 will be copied into the existing specifier in @var{dest}.
1543 If @var{locale} is @code{nil} or the symbol @code{all}, all
1544 specifications will be copied. If @var{locale} is a particular locale,
1545 the specification for that particular locale will be copied. If
1546 @var{locale} is a locale type, the specifications for all locales of
1547 that type will be copied. @var{locale} can also be a list of locales,
1548 locale types, and/or @code{all}; this is equivalent to calling
1549 @code{copy-specifier} for each of the elements of the list. See
1550 @code{specifier-spec-list} for more information about @var{locale}.
1552 Only instantiators where @var{tag-set} (a list of zero or more tags) is
1553 a subset of (or possibly equal to) the instantiator's tag set are
1554 copied. (The default value of @code{nil} is a subset of all tag sets,
1555 so in this case no instantiators will be screened out.) If @var{exact-p}
1556 is non-@code{nil}, however, @var{tag-set} must be equal to an
1557 instantiator's tag set for the instantiator to be copied.
1559 Optional argument @var{how-to-add} specifies what to do with existing
1560 specifications in @var{dest}. If @code{nil}, then whichever locales or locale
1561 types are copied will first be completely erased in @var{dest}.
1562 Otherwise, it is the same as in @code{add-spec-to-specifier}.
1565 @defun remove-specifier specifier &optional locale tag-set exact-p
1566 This function removes specification(s) for @var{specifier}.
1568 If @var{locale} is a particular locale (a buffer, window, frame, device,
1569 or the symbol @code{global}), the specification for that locale will be
1572 If instead, @var{locale} is a locale type (i.e. a symbol @code{buffer},
1573 @code{window}, @code{frame}, or @code{device}), the specifications for
1574 all locales of that type will be removed.
1576 If @var{locale} is @code{nil} or the symbol @code{all}, all
1577 specifications will be removed.
1579 @var{locale} can also be a list of locales, locale types, and/or
1580 @code{all}; this is equivalent to calling @code{remove-specifier} for
1581 each of the elements in the list.
1583 Only instantiators where @var{tag-set} (a list of zero or more tags) is
1584 a subset of (or possibly equal to) the instantiator's tag set are
1585 removed. (The default value of @code{nil} is a subset of all tag sets,
1586 so in this case no instantiators will be screened out.) If @var{exact-p}
1587 is non-@code{nil}, however, @var{tag-set} must be equal to an
1588 instantiator's tag set for the instantiator to be removed.
1591 @defun map-specifier specifier func &optional locale maparg
1592 This function applies @var{func} to the specification(s) for
1593 @var{locale} in @var{specifier}.
1595 If optional @var{locale} is a locale, @var{func} will be called for that
1597 If @var{locale} is a locale type, @var{func} will be mapped over all
1598 locales of that type. If @var{locale} is @code{nil} or the symbol
1599 @code{all}, @var{func} will be mapped over all locales in
1602 Optional @var{ms-maparg} will be passed to @var{ms-func}.
1604 @var{func} is called with four arguments: the @var{specifier}, the
1605 locale being mapped over, the inst-list for that locale, and the
1606 optional @var{maparg}. If any invocation of @var{func} returns
1607 non-@code{nil}, the mapping will stop and the returned value becomes the
1608 value returned from @code{map-specifier}. Otherwise,
1609 @code{map-specifier} returns @code{nil}.
1612 @defun specifier-locale-type-from-locale locale
1613 Given a specifier @var{locale}, this function returns its type.