Mercurial > hg > xemacs-beta
comparison man/lispref/specifiers.texi @ 1135:9eddcb9548e2
[xemacs-hg @ 2002-12-02 17:56:58 by stephent]
texinfo improvements <87d6okxq4i.fsf@tleepslib.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Mon, 02 Dec 2002 17:57:09 +0000 |
parents | 576fb035e263 |
children | 05ed51332340 |
comparison
equal
deleted
inserted
replaced
1134:dd61dd14b2a4 | 1135:9eddcb9548e2 |
---|---|
1 @c -*-texinfo-*- | 1 @c -*-texinfo-*- |
2 @c This is part of the XEmacs Lisp Reference Manual. | 2 @c This is part of the XEmacs Lisp Reference Manual. |
3 @c Copyright (C) 1995, 1996 Ben Wing. | 3 @c Copyright (C) 1995, 1996 Ben Wing. |
4 @c Copyright (C) 2002 Free Software Foundation, Inc. | |
4 @c See the file lispref.texi for copying conditions. | 5 @c See the file lispref.texi for copying conditions. |
5 @setfilename ../../info/specifiers.info | 6 @setfilename ../../info/specifiers.info |
6 @node Specifiers, Faces and Window-System Objects, Extents, top | 7 @node Specifiers, Faces and Window-System Objects, Extents, top |
7 @chapter Specifiers | 8 @chapter Specifiers |
8 @cindex specifier | 9 @cindex specifier |
9 | 10 |
10 A specifier is an object used to keep track of a property whose value | 11 A specifier is an object used to keep track of a property whose value |
11 may vary depending on the particular situation (e.g. particular buffer | 12 should vary according to @emph{display context}, a window, a frame, or |
12 displayed in a particular window) that it is used in. The value of many | 13 device. The value of many built-in properties, such as the font, |
13 built-in properties, such as the font, foreground, background, and such | 14 foreground, background, and such properties of a face and variables |
14 properties of a face and variables such as | 15 such as @code{modeline-shadow-thickness} and |
15 @code{modeline-shadow-thickness} and @code{top-toolbar-height}, is | 16 @code{top-toolbar-height}, is actually a specifier object. The |
16 actually a specifier object. The specifier object, in turn, is | 17 specifier object, in turn, is ``instanced'' in a particular situation |
17 ``instanced'' in a particular situation to yield the real value | 18 to yield the real value of the property in the current context. |
18 of the property in that situation. | |
19 | 19 |
20 @defun specifierp object | 20 @defun specifierp object |
21 This function returns non-@code{nil} if @var{object} is a specifier. | 21 This function returns non-@code{nil} if @var{object} is a specifier. |
22 @end defun | 22 @end defun |
23 | 23 |
24 @menu | 24 @menu |
25 * Introduction to Specifiers:: Specifiers provide a clean way for | 25 * Introduction to Specifiers:: Specifiers provide a clean way for |
26 display and other properties to vary | 26 display and other properties to vary |
27 (under user control) in a wide variety | 27 (under user control) in a wide variety |
28 of contexts. | 28 of contexts. |
29 * Simple Specifier Usage:: Getting started with specifiers. | |
29 * Specifiers In-Depth:: Gory details about specifier innards. | 30 * Specifiers In-Depth:: Gory details about specifier innards. |
30 * Specifier Instancing:: Instancing means obtaining the ``value'' of | 31 * Specifier Instancing:: Instancing means obtaining the ``value'' of |
31 a specifier in a particular context. | 32 a specifier in a particular context. |
32 * Specifier Types:: Specifiers come in different flavors. | 33 * Specifier Types:: Specifiers come in different flavors. |
33 * Adding Specifications:: Specifications control a specifier's ``value'' | 34 * Adding Specifications:: Specifications control a specifier's ``value'' |
46 @end menu | 47 @end menu |
47 | 48 |
48 @node Introduction to Specifiers | 49 @node Introduction to Specifiers |
49 @section Introduction to Specifiers | 50 @section Introduction to Specifiers |
50 | 51 |
51 Sometimes you may want the value of a property to vary depending on | 52 Perhaps the most useful way to explain specifiers is via an analogy. |
52 the context the property is used in. A simple example of this in XEmacs | 53 Emacs Lisp programmers are used to @emph{buffer-local variables} |
53 is buffer-local variables. For example, the variable | 54 @ref{buffer-local variables}. For example, the variable |
54 @code{modeline-format}, which controls the format of the modeline, can | 55 @code{modeline-format}, which controls the format of the modeline, can |
55 have different values depending on the particular buffer being edited. | 56 have different values depending on the particular buffer being edited. |
56 The variable has a default value which most modes will use, but a | 57 The variable has a default value which most modes will use, but a |
57 specialized package such as Calendar might change the variable so | 58 specialized package such as Calendar might change the variable so as |
58 as to tailor the modeline to its own purposes. | 59 to tailor the modeline to its own purposes. Other variables are |
60 perhaps best thought of as ``mode local,'' such as font-lock keywords, | |
61 but they are implemented as buffer locals. | |
59 | 62 |
60 Other properties (such as those that can be changed by the | 63 Other properties (such as those that can be changed by the |
61 @code{modify-frame-parameters} function, for example the color of the | 64 @code{modify-frame-parameters} function, for example the color of the |
62 text cursor) can have frame-local values, although it might also make | 65 text cursor) can have frame-local values, although it might also make |
63 sense for them to have buffer-local values. In other cases, you might | 66 sense for them to have buffer-local values. In other cases, you might |
68 value in a specified buffer, another value in all other buffers | 71 value in a specified buffer, another value in all other buffers |
69 displayed on a particular frame, another value in all other buffers | 72 displayed on a particular frame, another value in all other buffers |
70 displayed in all other frames on any mono (two-color, e.g. black and | 73 displayed in all other frames on any mono (two-color, e.g. black and |
71 white only) displays, and a default value in all other circumstances. | 74 white only) displays, and a default value in all other circumstances. |
72 | 75 |
73 A @dfn{specifier} is a generalization of this, allowing a great deal | 76 Specifiers generalize both buffer- and frame-local properties. |
74 of flexibility in controlling exactly what value a property has in which | 77 Specifiers vary according to the @emph{display} context. Font-lock |
75 circumstances. It is most commonly used for display properties, such as | 78 keywords in a buffer will be the same no matter which window the |
76 an image or the foreground color of a face. As a simple example, you can | 79 buffer is displayed in, but windows on TTY devices will simply not be |
77 specify that the foreground of the default face be | 80 capable of the flexibility that windows on modern GUI devices are. |
81 Specifiers provide a way for the programmer to @emph{declare} that a | |
82 emphasized text should be italic on GUI devices and inverse video on | |
83 TTYs. They also provide a way for the programmer to declare | |
84 fallbacks, so that a color specified as ``chartreuse'' where possible | |
85 can fall back to ``yellow'' on devices where only ANSI (4-bit) color | |
86 is available. The complex calculations and device querying are | |
87 transparent to both user and programmer. You ask for what you want; | |
88 it's up to XEmacs to provide it, or a reasonable approximation. | |
89 | |
90 We call such a declaration a @dfn{specification}. A @dfn{specification} | |
91 applies in a particular @dfn{locale}, which is a window, buffer, frame, | |
92 device, or the global locale. The value part of the specification is | |
93 called an @dfn{instantiator}. The process of determining the value in a | |
94 particular context, or @dfn{domain}, is called @dfn{instantiation} or | |
95 @dfn{instancing}. A domain is a window, frame, or device. | |
96 | |
97 The difference between @dfn{locale} and @dfn{domain} is somewhat subtle. | |
98 You may think of a locale as a class of domains, which may span | |
99 different devices. Since the specification is abstract (a Lisp form), | |
100 you can state it without reference to a device. On the other hand, when | |
101 you instantiate a specification, you must know the type of the device. | |
102 It is useless to specify that ``blue mean italic'' on a monochrome | |
103 device. Thus instantiation requires specification of the device on | |
104 which it will be rendered. | |
105 | |
106 Thus a @dfn{specifier} allows a great deal of flexibility in | |
107 controlling exactly what value a property has in which circumstances. | |
108 It is most commonly used for display properties, such as an image or | |
109 the foreground color of a face. As a simple example, you can specify | |
110 that the foreground of the default face be | |
78 | 111 |
79 @itemize @bullet | 112 @itemize @bullet |
80 @item | 113 @item |
81 blue for a particular buffer | 114 blue for a particular buffer |
82 @item | 115 @item |
95 @item | 128 @item |
96 red for all other buffers displayed on a color device | 129 red for all other buffers displayed on a color device |
97 @item | 130 @item |
98 white for all other buffers | 131 white for all other buffers |
99 @end itemize | 132 @end itemize |
133 | |
134 @node Simple Specifier Usage | |
135 @section Simple Specifier Usage | |
136 @cindex specifier examples | |
137 @cindex examples, specifier | |
138 @cindex adding a button to a toolbar | |
139 @cindex toolbar button, adding | |
140 | |
141 A useful specifier application is adding a button to a toolbar. XEmacs | |
142 provides several toolbars, one along each edge of the frame. Normally | |
143 only one is used at a time, the default. The default toolbar is | |
144 actually a specifier object which is the value of @code{default-toolbar}. | |
145 | |
146 The specification of a toolbar is simple: it is a list of buttons. | |
147 Each button is a vector with four elements: an icon, a command, the | |
148 enabled flag, and a help string. Let's retrieve the instance of the | |
149 toolbar you see in the selected frame. | |
150 | |
151 @example | |
152 (specifier-instance default-toolbar) | |
153 @end example | |
154 | |
155 The value returned is, as promised, a list of vectors. Now let's build | |
156 up a button, and add it to the toolbar. Our button will invoke the last | |
157 defined keyboard macro. This is an alternative to | |
158 @code{name-last-kbd-macro} for creating a persistent macro, rather than | |
159 an alias for @kbd{C-x e}. | |
160 | |
161 A toolbar button icon can be quite sophisticated, with different images | |
162 for button up, button down, and disabled states, and a similar set with | |
163 captions. We'll use a very simple icon, but we have to jump through a | |
164 few non-obvious hoops designed to support the sophisticated applications. | |
165 The rest of the button descriptor is straightforward. | |
166 | |
167 @example | |
168 (setq toolbar-my-kbd-macro-button | |
169 `[ (list (make-glyph "MyKbdMac")) | |
170 (lambda () (interactive) (execute-kbd-macro ,last-kbd-macro)) | |
171 t | |
172 "Execute a previously defined keyboard macro." ]) | |
173 | |
174 (set-specifier default-toolbar | |
175 (cons toolbar-my-kbd-macro-button | |
176 (specifier-specs default-toolbar 'global)) | |
177 'global) | |
178 @end example | |
179 | |
180 To remove the button, just substitute the function @code{delete} for the | |
181 @code{cons} above. | |
182 | |
183 What is the difference between @code{specifier-instance}, which we used | |
184 in the example of retrieving the toolbar descriptor, and | |
185 @code{specifier-specs}, which was used in the toolbar manipulating code? | |
186 @code{specifier-specs} retrieves a copy of the instantiator, which is | |
187 abstract and does not depend on context. @code{specifier-instance}, on | |
188 the other hand, actually instantiates the specification, and returns the | |
189 result for the given context. Another way to express this is: | |
190 @code{specifier-specs} takes a @emph{locale} as an argument, while | |
191 @code{specifier-instance} takes a @emph{domain}. The reason for | |
192 providing @code{specifier-instance} is that sometimes you wish to see | |
193 the object that XEmacs will actually use. @code{specifier-specs}, on | |
194 the other hand, shows you what the programmer (or user) requested. When | |
195 a program manipulates specifications, clearly it's the latter that is | |
196 desirable. | |
197 | |
198 In the case of the toolbar descriptor, it turns out that these are the | |
199 same: the instancing process is trivial. However, many specifications | |
200 have non-trivial instancing. Compare the results of the following forms | |
201 on my system. (The @samp{(cdr (first ...))} form is due to my use of | |
202 Mule. On non-Mule XEmacsen, just use @code{specifier-specs}.) | |
203 | |
204 @example | |
205 (cdr (first (specifier-specs (face-font 'default) 'global))) | |
206 => "-*--14-*jisx0208*-0" | |
207 | |
208 (specifier-instance (face-font 'default)) | |
209 #<font-instance "-*--14-*jisx0208*-0" on #<x-device on ":0.0" 0x970> 0xe0028b 0x176b> | |
210 @end example | |
211 | |
212 In this case, @code{specifier-instance} returns an opaque object; | |
213 programs can't work on it, they can only pass it around. Worse, in some | |
214 environments the instantiation will fail, resulting in a different value | |
215 (when another instantiation succeeds), or worse yet, an error, if all | |
216 attempts to instance the specifier fail. @code{specifier-instance} is | |
217 context-dependent, even for the exact same specification. | |
218 @code{specifier-specs} is deterministic, and only depends on the | |
219 specifications. | |
220 | |
221 Note that in the toolbar-changing code we operate in the global locale. | |
222 This means that narrower locales, if they have specifications, will | |
223 shadow our changes. (Specifier instancing does not merge | |
224 specifications. It selects the "highest-priority successful | |
225 specification" and instances that.) | |
226 | |
227 In fact, in our example, it seems pretty likely that different buffers | |
228 @emph{should} have different buttons. (The icon can be the same, but | |
229 the keyboard macro you create in a Dired buffer is highly unlikely to be | |
230 useful in a LaTeX buffer!) Here's one way to implement this: | |
231 | |
232 @example | |
233 (setq toolbar-my-kbd-macro-button | |
234 `[ (list (make-glyph "MyKbdMac")) | |
235 (lambda () (interactive) (execute-kbd-macro ,last-kbd-macro)) | |
236 t | |
237 "Execute a previously defined keyboard macro." ]) | |
238 | |
239 (set-specifier default-toolbar | |
240 (cons toolbar-my-kbd-macro-button | |
241 (cond ((specifier-specs default-toolbar | |
242 (current-buffer))) | |
243 ((specifier-specs default-toolbar | |
244 'global))) | |
245 (current-buffer)) | |
246 @end example | |
247 | |
248 Finally, a cautionary note: the use of @code{specifier-specs} in the | |
249 code above is for expository purposes. Don't use it in production code. | |
250 In fact, the @code{set-specifier} form above is likely to fail | |
251 occasionally, because you can add many specifications for the same | |
252 locale. | |
253 | |
254 In these cases, @code{specifier-specs} will return a list. A further | |
255 refinement is that a specification may be associated with a set of | |
256 @dfn{specifier tags}. If the list of specifier tags is non-nil, then | |
257 @code{specifier-specs} will return a cons of the tag set and the | |
258 instantiator. Evidently @code{specifier-specs} is a bit unreliable. | |
259 (For toolbars, the code above should work 99% of the time, because | |
260 toolbars are rarely changed. Since instantiation is trivial, multiple | |
261 specs are not useful---the first one always succeeds.) | |
262 | |
263 In fact, @code{specifier-specs} is intended to be used to display specs | |
264 to humans with a minimum of clutter. The robust way to access | |
265 specifications is via @code{specifier-spec-list}. @xref{Adding | |
266 Specifications}, for the definition of @dfn{spec-list}. | |
267 @xref{Retrieving Specifications} for documentation of | |
268 @code{specifier-specs} and @code{specifier-spec-list}. To get the | |
269 desired effect, replace the form @code{(specifier-spec default-toolbar | |
270 'global)} with | |
271 | |
272 @example | |
273 (cdr (second (first (specifier-spec-list default-toolbar 'global)))) | |
274 @end example | |
275 | |
276 (It should be obvious why the example uses the lazy unreliable method!) | |
100 | 277 |
101 @node Specifiers In-Depth | 278 @node Specifiers In-Depth |
102 @section In-Depth Overview of a Specifier | 279 @section In-Depth Overview of a Specifier |
103 @cindex specification (in a specifier) | 280 @cindex specification (in a specifier) |
104 @cindex domain (in a specifier) | 281 @cindex domain (in a specifier) |
119 @cindex specifier, inst-list | 296 @cindex specifier, inst-list |
120 @cindex specifier, inst-pair | 297 @cindex specifier, inst-pair |
121 @cindex specifier, tag | 298 @cindex specifier, tag |
122 @cindex specifier, tag set | 299 @cindex specifier, tag set |
123 | 300 |
124 A specifier object encapsulates a set of @dfn{specifications}, each of | 301 Having variables vary according the editing context is very useful, and |
125 which says what its value should be if a particular condition applies. | 302 the buffer is the natural ``atomic'' unit of editing context. In a GUI |
303 environment, it can be similarly useful to have variables whose values | |
304 vary according to display context. The atomic unit of display context | |
305 is the Emacs window. Buffers are cleanly grouped by modes, but windows | |
306 are not so easily pigeonholed. On the one hand, a window displays a | |
307 buffer, and thus one possible hierarchy is window, buffer, mode. On the | |
308 other, a window is a component of a frame. This generates the window, | |
309 frame, device hierarchy. Finally, there are objects such as toolbars | |
310 whose properties are described by specifiers. These do not fit | |
311 naturally into either hierarchy. This problem is as yet not cleanly | |
312 solved. | |
313 | |
314 Another potential source of conceptual confusion is the instantiation | |
315 process. Instantiating a buffer-local variable is simple: at any given | |
316 point in time there is a current buffer, and its local values are used | |
317 and set whenever the variable is accessed, unless the programmer goes to | |
318 some special effort (uses @code{default-value} and @code{set-default}. | |
319 However, a specifier object encapsulates a set of @dfn{specifications}, | |
320 each of which says what its value should be if a particular condition | |
321 applies. Several such conditions might apply simultaneously in a given | |
322 window. | |
323 | |
126 For example, one specification might be ``The value should be | 324 For example, one specification might be ``The value should be |
127 darkseagreen2 on X devices'' another might be ``The value should be blue | 325 darkseagreen2 on X devices'' another might be ``The value should be blue |
128 in the *Help* buffer''. In specifier terminology, these conditions are | 326 in the *Help* buffer''. So what do we do for "the *Help* buffer on an X |
129 called @dfn{locales} and the values are called @dfn{instantiators}. | 327 device"? The answer is simple: give each type of locale a priority and |
328 check them in priority order, returning the first instantiator that | |
329 successfully instantiates a value. | |
330 | |
130 Given a specifier, a logical question is ``What is its value in a | 331 Given a specifier, a logical question is ``What is its value in a |
131 particular situation?'' This involves looking through the specifications | 332 particular situation?'' This involves looking through the specifications |
132 to see which ones apply to this particular situation, and perhaps | 333 to see which ones apply to this particular situation, and perhaps |
133 preferring one over another if more than one applies. In specifier | 334 preferring one over another if more than one applies. In specifier |
134 terminology, a ``particular situation'' is called a @dfn{domain}, and | 335 terminology, a ``particular situation'' is called a @dfn{domain}, and |
138 a particular window, it retrieves the specifier for the foreground color | 339 a particular window, it retrieves the specifier for the foreground color |
139 of the default face and @dfn{instances} it in the domain given by that | 340 of the default face and @dfn{instances} it in the domain given by that |
140 window; in other words, it asks the specifier, ``What is your value in | 341 window; in other words, it asks the specifier, ``What is your value in |
141 this window?''. | 342 this window?''. |
142 | 343 |
344 Note that the redisplay example is in a sense canonical. That is, | |
345 specifiers are designed to present a uniform and @emph{efficient} API | |
346 to redisplay. It is the efficiency constraint that motivates the | |
347 introduction of specifier tags, and many restrictions on access (for | |
348 example, a buffer is not a domain, and you cannot instantiate a | |
349 specifier over a buffer). | |
350 | |
143 More specifically, a specifier contains a set of @dfn{specifications}, | 351 More specifically, a specifier contains a set of @dfn{specifications}, |
144 each of which associates a @dfn{locale} (a window object, a buffer | 352 each of which associates a @dfn{locale} (a window object, a buffer |
145 object, a frame object, a device object, or the symbol @code{global}) | 353 object, a frame object, a device object, or the symbol @code{global}) |
146 with an @dfn{inst-list}, which is a list of one or more | 354 with an @dfn{inst-list}, which is a list of one or more |
147 @dfn{inst-pairs}. (For each possible locale, there can be at most one | 355 @dfn{inst-pairs}. (For each possible locale, there can be at most one |
158 @dfn{predicate} associated with it, which is a function of one argument | 366 @dfn{predicate} associated with it, which is a function of one argument |
159 (a device) that specifies whether the tag matches that particular | 367 (a device) that specifies whether the tag matches that particular |
160 device. (If a tag does not have a predicate, it matches all devices.) | 368 device. (If a tag does not have a predicate, it matches all devices.) |
161 All tags in a tag set must match a device for the associated inst-pair | 369 All tags in a tag set must match a device for the associated inst-pair |
162 to be instantiable over that device. (A null tag set is perfectly | 370 to be instantiable over that device. (A null tag set is perfectly |
163 valid.) | 371 valid, and trivially matches all devices.) |
164 | 372 |
373 @c #### don't we have more device types now, gtk, ms-windows, mac-carbon? | |
165 The valid device types (normally @code{x}, @code{tty}, and | 374 The valid device types (normally @code{x}, @code{tty}, and |
166 @code{stream}) and device classes (normally @code{color}, | 375 @code{stream}) and device classes (normally @code{color}, |
167 @code{grayscale}, and @code{mono}) can always be used as tags, and match | 376 @code{grayscale}, and @code{mono}) can always be used as tags, and match |
168 devices of the associated type or class (@pxref{Consoles and Devices}). | 377 devices of the associated type or class (@pxref{Consoles and Devices}). |
169 User-defined tags may be defined, with an optional predicate specified. | 378 User-defined tags may be defined, with an optional predicate specified. |