annotate lisp/specifier.el @ 2421:ab71ad6ff3dd

[xemacs-hg @ 2004-12-06 03:50:53 by ben] (none) README.packages: Document use of --package-prefix. Fix error in specifying standard package location. make-docfile.c: Use QXE_PATH_MAX. info.el: Correct doc string giving example package path. menubar-items.el: Move Prefix Rectangle command up one level. xemacs/packages.texi: Add long form of Lisp Reference Manual to links. Add links pointing to Lisp Reference Manual for more detailed package discussion. lispref/range-tables.texi: Document range-table changes. internals/internals.texi: Update history section. elhash.c, elhash.h, profile.c: Create inchash_eq() to allow direct incrementing of hash-table entry. Use in profile.c to try to reduce profiling overhead. Increase initial size of profile hash tables to reduce profiling overhead. buffer.c, device-msw.c, dialog-msw.c, dired-msw.c, editfns.c, event-msw.c, events.c, glyphs-msw.c, keymap.c, objects-msw.c, process-nt.c, syswindows.h, text.c, text.h, unexnt.c: Rename xetcs* -> qxetcs* for consistency with qxestr*. Rename ei*_c(_*) -> ei*_ascii(_*) since they work with ASCII-only strings not "C strings", whatever those are. This is the last place where "c" was incorrectly being used for "ascii". dialog-msw.c, dumper.c, event-msw.c, fileio.c, glyphs-gtk.c, glyphs-x.c, nt.c, process-nt.c, realpath.c, sysdep.c, sysfile.h, unexcw.c, unexnext.c, unexnt.c: Try to avoid differences in systems that do or do not include final null byte in PATH_MAX. Create PATH_MAX_INTERNAL and PATH_MAX_EXTERNAL and use them everywhere. Rewrite code in dumper.c to avoid use of PATH_MAX. When necessary in nt.c, use _MAX_PATH instead of MAX_PATH to be consistent with other places. text.c: Code to short-circuit when binary or Unicode was not working due to EOL wrapping. Fix this code to work when either no EOL autodetection or no CR's or LF's in the text. lisp.h, rangetab.c, rangetab.h, regex.c, search.c: Implement different types of ranges (open/closed start and end). Change default to be start-closed, end-open.
author ben
date Mon, 06 Dec 2004 03:52:23 +0000
parents 13a418960a88
children fd1acd2f457a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; specifier.el --- Lisp interface to specifiers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (C) 1997 Free Software Foundation, Inc.
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
4 ;; Copyright (C) 1995, 1996, 2000, 2002 Ben Wing.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Author: Ben Wing <ben@xemacs.org>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 ;; Keywords: internal, dumped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 ;;; Synched up with: Not in FSF.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; along with XEmacs; see the file COPYING. If not, write to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Free Software Foundation, 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;; Boston, MA 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 (defun make-specifier-and-init (type spec-list &optional dont-canonicalize)
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
35 "Create and initialize a specifier of type TYPE with spec(s) SPEC-LIST.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
37 A convenience API combining `make-specifier' and `set-specifier', allowing you
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
38 to create a specifier and add specs to it at the same time.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
39 TYPE specifies the specifier type. See `make-specifier' for known types.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
40 SPEC-LIST supplies the specification(s) to be added to the specifier, in any
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
41 form acceptable to `canonicalize-spec-list'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
42 Optional DONT-CANONICALIZE, if non-nil, inhibits the conversion, and the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
43 SPEC-LIST must already be in full form."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 (let ((sp (make-specifier type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 (if (not dont-canonicalize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 (setq spec-list (canonicalize-spec-list spec-list type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 (add-spec-list-to-specifier sp spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 sp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; God damn, do I hate dynamic scoping.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
52 (defun map-specifier (ms-specifier ms-func &optional ms-locale ms-maparg
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
53 ms-tag-set ms-exact-p)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 "Apply MS-FUNC to the specification(s) for MS-LOCALE in MS-SPECIFIER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
56 If optional MS-LOCALE is a locale, MS-FUNC will be called for that locale.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
57 If MS-LOCALE is a locale type, MS-FUNC will be mapped over all locales of that
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
58 type. If MS-LOCALE is 'all or nil, MS-FUNC will be mapped over all locales in
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
59 MS-SPECIFIER.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
61 Optional MS-TAG-SET and MS-EXACT-P are as in `specifier-spec-list'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
62 Optional MS-MAPARG will be passed to MS-FUNC.
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
63
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 MS-FUNC is called with four arguments: the MS-SPECIFIER, the locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 being mapped over, the inst-list for that locale, and the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 optional MS-MAPARG. If any invocation of MS-FUNC returns non-nil,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 the mapping will stop and the returned value becomes the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 value returned from `map-specifier'. Otherwise, `map-specifier'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 returns nil."
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
70 (let ((ms-specs (specifier-spec-list ms-specifier ms-locale ms-tag-set
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
71 ms-exact-p))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ms-result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (while (and ms-specs (not ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 (let ((ms-this-spec (car ms-specs)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 (setq ms-result (funcall ms-func ms-specifier (car ms-this-spec)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 (cdr ms-this-spec) ms-maparg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 (setq ms-specs (cdr ms-specs))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 (defun canonicalize-inst-pair (inst-pair specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 "Canonicalize the given INST-PAIR.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 Canonicalizing means converting to the full form for an inst-pair, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 `(TAG-SET . INSTANTIATOR)'. A single, untagged instantiator is given
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 a tag set of nil (the empty set), and a single tag is converted into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 a tag set consisting only of that tag.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 If NOERROR is non-nil, signal an error if the inst-pair is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; a) a single instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; b) a cons of a tag and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; c) a cons of a tag set and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 (cond ((valid-instantiator-p inst-pair specifier-type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 (cons nil inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ((not (consp inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; not an inst-pair
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (check-valid-instantiator inst-pair specifier-type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ((and (valid-specifier-tag-p (car inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 (valid-instantiator-p (cdr inst-pair) specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 (cons (list (car inst-pair)) (cdr inst-pair)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ((and (valid-specifier-tag-set-p (car inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 (valid-instantiator-p (cdr inst-pair) specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;; case (c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 inst-pair)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 (signal 'error (list "Invalid specifier tag set"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 (car inst-pair)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 (defun canonicalize-inst-list (inst-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 "Canonicalize the given INST-LIST (a list of inst-pairs).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 SPECIFIER-TYPE specifies the type of specifier that this INST-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 Canonicalizing means converting to the full form for an inst-list, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 `((TAG-SET . INSTANTIATOR) ...)'. This function accepts a single
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 inst-pair or any abbreviation thereof or a list of (possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 abbreviated) inst-pairs. (See `canonicalize-inst-pair'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 If NOERROR is non-nil, signal an error if the inst-list is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 ;; a) an inst-pair or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 (let ((result (canonicalize-inst-pair inst-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 (if (not (consp inst-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 ;; not an inst-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (check-valid-instantiator inst-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (catch 'cann-inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (let ((rest inst-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (if noerror (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (signal 'error (list "Invalid list format" inst-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (let ((res2 (canonicalize-inst-pair (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; otherwise canonicalize-inst-pair would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 (defun canonicalize-spec (spec specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 "Canonicalize the given SPEC (a specification).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
176 SPECIFIER-TYPE is the type of specifier that this SPEC will be used for.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 Canonicalizing means converting to the full form for a spec, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 `(LOCALE (TAG-SET . INSTANTIATOR) ...)'. This function accepts a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 possibly abbreviated inst-list or a cons of a locale and a possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 abbreviated inst-list. (See `canonicalize-inst-list'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 If NOERROR is nil, signal an error if the specification is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 ;; a) an inst-list or some abbreviation thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 ;; b) a cons of a locale and an inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 (let ((result (canonicalize-inst-list spec specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (cons 'global result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 (if (not (consp spec))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 ;; not a spec.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 (check-valid-instantiator spec specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 (if (not (valid-specifier-locale-p (car spec)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 ;; invalid locale.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (signal 'error (list "Invalid specifier locale" (car spec))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (let ((result (canonicalize-inst-list (cdr spec) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 (if (eq result t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 ;; otherwise canonicalize-inst-list would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 (cons (car spec) result))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (defun canonicalize-spec-list (spec-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 "Canonicalize the given SPEC-LIST (a list of specifications).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 Canonicalizing means converting to the full form for a spec-list, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 `((LOCALE (TAG-SET . INSTANTIATOR) ...) ...)'. This function accepts
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 a possibly abbreviated specification or a list of such things. (See
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 `canonicalize-spec'.) This is the function used to convert spec-lists
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 accepted by `set-specifier' and such into a form suitable for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 `add-spec-list-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
228 The canonicalization algorithm is as follows:
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
229
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
230 1. Attempt to parse SPEC-LIST as a single, possibly abbreviated, specification.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
231 2. If (1) fails, attempt to parse SPEC-LIST as a list of (abbreviated)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
232 specifications.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
233 3. If (2) fails, SPEC-LIST is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
234
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
235 A possibly abbreviated specification SPEC is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
236
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
237 1. Attempt to parse SPEC as a possibly abbreviated inst-list.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
238 2. If (1) fails, attempt to parse SPEC as a cons of a locale and an
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
239 (abbreviated) inst-list.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
240 3. If (2) fails, SPEC is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
241
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
242 A possibly abbreviated inst-list INST-LIST is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
243
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
244 1. Attempt to parse INST-LIST as a possibly abbreviated inst-pair.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
245 2. If (1) fails, attempt to parse INST-LIST as a list of (abbreviated)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
246 inst-pairs.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
247 3. If (2) fails, INST-LIST is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
248
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
249 A possibly abbreviated inst-pair INST-PAIR is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
250
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
251 1. Check if INST-PAIR is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
252 2. If not, check if INST-PAIR is a cons of something that is a tag, ie,
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
253 `valid-specifier-tag-p', and something that is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
254 3. If not, check if INST-PAIR is a cons of a list of tags and something that
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
255 is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
256
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
257 In summary, this function generally prefers more abbreviated forms.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
258
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
259 This function tries extremely hard to resolve any ambiguities, and the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
260 built-in specifier types (font, image, toolbar, etc.) are designed so that
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
261 there won't be any ambiguities. (#### Unfortunately there are bugs in the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
262 treatment of toolbar spec-lists and generic spec-lists; avoid depending on
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
263 canonicalization for these types.)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 If NOERROR is nil, signal an error if the spec-list is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 ;; a) a spec or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 (let ((result (canonicalize-spec spec-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 (if (not (consp spec-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 ;; not a spec-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 (check-valid-instantiator spec-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 (catch 'cann-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 (let ((rest spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (if noerror (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 (signal 'error (list "Invalid list format" spec-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (let ((res2 (canonicalize-spec (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 ;; otherwise canonicalize-spec would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (defun set-specifier (specifier value &optional locale tag-set how-to-add)
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
304 "Add the specification(s) given by VALUE to SPECIFIER in LOCALE.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
305
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
306 VALUE may be any of the values accepted by `canonicalize-spec-list', including
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
307
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
308 -- an instantiator (either a Lisp object which will be returned when the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
309 specifier is instanced, or a Lisp object that can be instantiated to
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
310 produce an opaque value: eg, a font name (string) can be used for a font
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
311 specifier, but an instance will be a font object)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
312 -- a list of instantiators
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
313 -- a cons of a locale and an instantiator, or of a locale and a list of
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
314 instantiators
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
315 -- a cons of a tag or tag-set and an instantiator (or list of instantiators)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
316 -- a cons of a locale and the previous type of item
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
317 -- a list of one or more of any of the previous types of items
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
318 -- a canonical spec-list.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
320 See `canonicalize-spec-list' for details. If you need to know the details,
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
321 though, strongly consider using the unambiguous APIs `add-spec-to-specifier'
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
322 and `add-spec-list-to-specifier' instead.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
323
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
324 Finally, VALUE can itself be a specifier (of the same type as
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
325 SPECIFIER), if you want to copy specifications from one specifier
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
326 to another; this is equivalent to calling `copy-specifier', and
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
327 LOCALE, TAG-SET, and HOW-TO-ADD have the same semantics as with
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
328 that function.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
329
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
330 Note that a VALUE of `nil' is either illegal or will be treated as a value of
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
331 `nil'; it does not remove existing specifications. Use `remove-specifier' for
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
332 that. N.B. `remove-specifier' defaults to removing all specifications, not
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
333 just the 'global one!
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
334
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
335 Warning: this function is inherently heuristic, and should not be relied on to
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
336 properly resolve ambiguities, when specifier instantiators can be lists
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
337 \(currently, for toolbar specifiers and generic specifiers). In those cases
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
338 use either `add-spec-to-specifier' or `add-spec-list-to-specifier'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
339
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 LOCALE indicates where this specification is active, and should be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 a buffer, a window, a frame, a device, or the symbol `global' to
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
342 indicate that it applies everywhere. LOCALE defaults to
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
343 `global' if omitted, and is overridden by locales provided by VALUE (in the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
344 cases where value is a full specification or a spec-list).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 Optional argument TAG-SET is a tag or a list of tags, to be associated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 with the VALUE. Tags are symbols (usually naming device types, such
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 as `x' and `tty', or device classes, such as `color', `mono', and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 `grayscale'); specifying a TAG-SET restricts the scope of VALUE to
2297
13a418960a88 [xemacs-hg @ 2004-09-22 02:05:42 by stephent]
stephent
parents: 1875
diff changeset
350 devices that match all specified tags. (You can also create your
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 own tags using `define-specifier-tag', and use them to identify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 specifications added by you, so you can remove them later.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 Optional argument HOW-TO-ADD should be either nil or one of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 symbols `prepend', `append', `remove-tag-set-prepend',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 `remove-tag-set-append', `remove-locale', `remove-locale-type',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 or `remove-all'. This specifies what to do with existing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 specifications in LOCALE (and possibly elsewhere in the specifier).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 Most of the time, you do not need to worry about this argument;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 the default behavior of `remove-tag-set-prepend' is usually fine.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 See `copy-specifier' and `add-spec-to-specifier' for a full
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 description of what each of these means.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 Note that `set-specifier' is exactly complementary to `specifier-specs'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 except in the case where SPECIFIER has no specs at all in it but nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 is a valid instantiator (in that case, `specifier-specs' will return
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 nil (meaning no specs) and `set-specifier' will interpret the `nil'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 as meaning \"I'm adding a global instantiator and its value is `nil'\"),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 or in strange cases where there is an ambiguity between a spec-list
2297
13a418960a88 [xemacs-hg @ 2004-09-22 02:05:42 by stephent]
stephent
parents: 1875
diff changeset
370 and an inst-list, etc. (The built-in specifier types are designed
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
371 in such a way as to avoid any such ambiguities.)"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 ;; backward compatibility: the old function had HOW-TO-ADD as the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 ;; third argument and no arguments after that.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 ;; #### this should disappear at some point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (if (and (null how-to-add)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (memq locale '(prepend append remove-tag-set-prepend
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 remove-tag-set-append remove-locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 remove-locale-type remove-all)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 (setq how-to-add locale)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (setq locale nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 ;; proper beginning of the function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (let ((is-valid (valid-instantiator-p value (specifier-type specifier)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (nval value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (cond ((and (not is-valid) (specifierp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (copy-specifier nval specifier locale tag-set nil how-to-add))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (if tag-set
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (if (not (listp tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 (setq tag-set (list tag-set)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 ;; You tend to get more accurate errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 ;; for a variety of cases if you call
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 ;; canonicalize-tag-set here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (setq tag-set (canonicalize-tag-set tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (if (and (not is-valid) (consp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 (setq nval
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 (mapcar #'(lambda (x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 (check-valid-instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 x (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 (cons tag-set x))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 (setq nval (cons tag-set nval)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 (if locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 (setq nval (cons locale nval)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 (canonicalize-spec-list nval (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 how-to-add))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
414 (defun modify-specifier-instances (specifier func &optional args force default
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
415 locale tag-set)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
416 "Modify all specifications that match LOCALE and TAG-SET by FUNC.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
417
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
418 For each specification that exists for SPECIFIER, in locale LOCALE
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
419 that matches TAG-SET, call the function FUNC with the instance as its
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
420 first argument and with optional arguments ARGS. The result is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
421 used as the new value of the instantiator.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
422
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
423 If there is no specification in the domain LOCALE matching TAG-SET and
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
424 FORCE is non-nil, an explicit one is created from the matching
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
425 specifier instance if that exists or DEFAULT otherwise. If LOCALE is
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
426 not a domain (i.e. a buffer), DEFAULT is always used. FUNC is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
427 applied like above and the resulting specification is added."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
428
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
429 (let ((spec-list (specifier-spec-list specifier locale tag-set)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
430 (cond
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
431 (spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
432 ;; Destructively edit the spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
433 (mapc #'(lambda (spec)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
434 (mapc #'(lambda (inst-pair)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
435 (setcdr inst-pair
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
436 (apply func (cdr inst-pair) args)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
437 (cdr spec)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
438 spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
439 (add-spec-list-to-specifier specifier spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
440 (force
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
441 (set-specifier specifier
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
442 (apply func
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
443 (or (and (valid-specifier-domain-p locale)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
444 (specifier-instance specifier))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
445 default) args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
446 locale tag-set)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
447
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 (defmacro let-specifier (specifier-list &rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 "Add specifier specs, evaluate forms in BODY and restore the specifiers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 \(let-specifier SPECIFIER-LIST BODY...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 Each element of SPECIFIER-LIST should look like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 \(SPECIFIER VALUE &optional LOCALE TAG-SET HOW-TO-ADD).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 SPECIFIER is the specifier to be temporarily modified. VALUE is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 instantiator to be temporarily added to SPECIFIER in LOCALE. LOCALE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 TAG-SET and HOW-TO-ADD have the same meaning as in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 `add-spec-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 The code resulting from macro expansion will add specifications to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 specifiers using `add-spec-to-specifier'. After BODY is finished, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 temporary specifications are removed and old spec-lists are restored.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 LOCALE, TAG-SET and HOW-TO-ADD may be omitted, and default to nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 The value of the last form in BODY is returned.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 NOTE: If you want the specifier's instance to change in all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 circumstances, use (selected-window) as the LOCALE. If LOCALE is nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 or omitted, it defaults to `global'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 Example:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 (let-specifier ((modeline-shadow-thickness 0 (selected-window)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 (sit-for 1))"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 (check-argument-type 'listp specifier-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 (flet ((gensym-frob (x name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 (if (or (atom x) (eq (car x) 'quote))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 (list x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (list (gensym name) x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 ;; VARLIST is a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 ;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 ;; (TAG-SET) (HOW-TO-ADD))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 ;; If any of these is an atom, then a separate symbol is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 ;; unnecessary, the CAR will contain the atom and CDR will be nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (let* ((varlist (mapcar #'(lambda (listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (or (and (consp listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 (<= (length listel) 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 (> (length listel) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 (signal 'error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 "should be a list of 2-5 elements"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 listel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 ;; VALUE, TAG-SET and HOW-TO-ADD are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 ;; referenced only once, so we needn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 ;; frob them with gensym.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (list (gensym-frob (nth 0 listel) "specifier-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 (list (nth 1 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 (gensym-frob (nth 2 listel) "locale-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 (list (nth 3 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (list (nth 4 listel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 specifier-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 ;; OLDVALLIST is a list of (OLDVALSYM OLDVALFORM)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (oldvallist (mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (list (gensym "old-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 `(specifier-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ,(car (nth 2 varel)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 varlist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 ;; Bind the appropriate variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 `(let* (,@(mapcan #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (delq nil (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 #'(lambda (varcons)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 (and (cdr varcons) varcons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 ,@oldvallist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 ,@(mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 `(add-spec-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 ,(car (nth 0 varel)) ,(car (nth 1 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 ,(car (nth 2 varel)) ,(car (nth 3 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 ,(car (nth 4 varel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 ,@body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 ;; Reverse the unwinding order, so that using the same
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 ;; specifier multiple times works.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 ,@(apply #'nconc (nreverse (mapcar*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 #'(lambda (oldval varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 `((remove-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 ,(car (nth 2 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 ,(car oldval))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 oldvallist varlist))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
537 (defun make-integer-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
538 "Return a new `integer' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
539 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
540 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
541 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
542 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
543
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
544 Valid instantiators for integer specifiers are integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
545 (make-specifier-and-init 'integer spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
546
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
547 (defun make-boolean-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
548 "Return a new `boolean' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
549 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
550 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
551 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
552 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
553
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
554 Valid instantiators for boolean specifiers are t and nil."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
555 (make-specifier-and-init 'boolean spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
556
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
557 (defun make-natnum-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
558 "Return a new `natnum' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
559 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
560 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
561 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
562 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
563
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
564 Valid instantiators for natnum specifiers are non-negative integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
565 (make-specifier-and-init 'natnum spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
566
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
567 (defun make-generic-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
568 "Return a new `generic' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
569 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
570 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
571 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
572 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
573
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
574 Valid instantiators for generic specifiers are all Lisp values.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
575 They are returned back unchanged when a specifier is instantiated."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
576 (make-specifier-and-init 'generic spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
577
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
578 (defun make-display-table-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
579 "Return a new `display-table' specifier object with the given spec list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
580 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
581 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
582 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
583 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
584
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
585 Valid instantiators for display-table specifiers are described in
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
586 detail in the doc string for `current-display-table'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
587 (make-specifier-and-init 'display-table spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
588
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 ;; Evaluate this for testing:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 ; (cl-prettyexpand '(let-specifier ((modeline-shadow-thickness 0 (selected-window) 'x) (fubar (value) baz)) (sit-for 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 (define-specifier-tag 'win 'device-on-window-system-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 ;; Add tags for device types that don't have support compiled
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 ;; into the binary that we're about to dump. This will prevent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 ;; code like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 ;; (set-face-foreground 'default "black" nil '(x color))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 ;; from producing an error if no X support was compiled in.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 (or (valid-specifier-tag-p 'x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 (define-specifier-tag 'x (lambda (dev) (eq (device-type dev) 'x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 (or (valid-specifier-tag-p 'tty)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 (define-specifier-tag 'tty (lambda (dev) (eq (device-type dev) 'tty))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 (or (valid-specifier-tag-p 'mswindows)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 (define-specifier-tag 'mswindows (lambda (dev)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 (eq (device-type dev) 'mswindows))))
630
ff9d7f21f8d0 [xemacs-hg @ 2001-07-18 12:44:51 by stephent]
stephent
parents: 442
diff changeset
609 (or (valid-specifier-tag-p 'gtk)
ff9d7f21f8d0 [xemacs-hg @ 2001-07-18 12:44:51 by stephent]
stephent
parents: 442
diff changeset
610 (define-specifier-tag 'gtk (lambda (dev) (eq (device-type dev) 'gtk))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 ;; Add special tag for use by initialization code. Code that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 ;; sets up default specs should use this tag. Code that needs to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 ;; override default specs (e.g. the X resource initialization
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 ;; code) can safely clear specs with this tag without worrying
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 ;; about clobbering user settings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 (define-specifier-tag 'default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
621 ;;; "Heuristic" specifier functions ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
623
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
624 ;;; "Heuristic" is a euphemism for kludge. This stuff works well in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
625 ;;; practice, though.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
626
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
627 ;;; You might view all the contortions we do here and in Face-frob-property
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
628 ;;; as indicative of design failures with specifiers, and perhaps you're
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
629 ;;; right. But in fact almost all code that attempts to interface to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
630 ;;; humans and produce "intuitive" results gets messy, particularly with a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
631 ;;; system as complicated as specifiers, whose complexity results from an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
632 ;;; attempt to work well in many different circumstances. We could create
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
633 ;;; a much simpler system, but the tradeoff would be that you'd have to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
634 ;;; programmatically control all the stuff that gets handled automatically
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
635 ;;; by setting the right specifiers -- and then things wouldn't "just work"
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
636 ;;; if the user simultaneously creates a TTY and X device, or X devices on
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
637 ;;; different types of machines, or wants some buffers to display
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
638 ;;; differently from others, etc. without a lot of hook functions and other
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
639 ;;; glue machinery to set everything up. The result would be just as much
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
640 ;;; complexity, but worse, and much harder to control, since there wouldn't
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
641 ;;; be any standard framework for managing all these hook functions and the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
642 ;;; user would have to be able to write lots of Lisp code to get things
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
643 ;;; working.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
644
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
645 ;;; The problem is that we have no high-level code, e.g. custom, to make it
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
646 ;;; easy for the user to control specifiers nicely. The following
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
647 ;;; lower-level code, though, should make it easier to implement the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
648 ;;; high-level code.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
649
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
650 ;;; #### Something like Face-frob-property, but more general, should be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
651 ;;; created for general specifier frobbing.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
652
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
653 ;;; #### Other possible extensions to specifiers would be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
654 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
655 ;;; (a) the ability to create specifications for particular types of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
656 ;;; buffers, e.g. all C-mode buffers one way, all text-mode buffers
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
657 ;;; another way, etc. Perhaps this should be implemented through hook
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
658 ;;; functions; but that wouldn't easily allow you to `make-face-bold'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
659 ;;; and have it work on these other kinds of specifications. Probably
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
660 ;;; a better way is to extend the tag mechanism so that it can specify
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
661 ;;; things other than device types. One way would be to simply allow
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
662 ;;; tags to have arbitrary elisp attached to them -- a function that
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
663 ;;; takes a domain and returns whether the attached instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
664 ;;; applies. This should be doable given (a) that we now have code to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
665 ;;; allow elisp to be run inside a "sandbox", sufficiently protected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
666 ;;; that it can even be called from redisplay, and (b) the large amount
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
667 ;;; of caching we already have, which would minimize the speed hit.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
668 ;;; However, this still runs into problems -- (a) it requires
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
669 ;;; programming to get anything at all done, and (b) you'll get
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
670 ;;; horrible namespace clashes very quickly. Another possibility to be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
671 ;;; used in conjunction with this would be vector tags, with an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
672 ;;; extendable mechanism to control their syntax. For example,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
673 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
674 ;;; [tag :mode 'c] (buffer in c-mode)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
675 ;;; [tag :buffer-name "\\*Help: function"] (help-on-function buffers)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
676 ;;; [tag :buffer-coding-system 'japanese-euc] (buffer's coding system is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
677 ;;; EUC-JP)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
678 ;;; [tag :buffer-file-name "^#.*#$"] (autosave files)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
679 ;;; [tag :language-environment "French"] (whenever the global language
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
680 ;;; environment is French)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
681 ;;; [tag :font-height-minimum '(default 12)] (if the height of the default
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
682 ;;; font is at least 12 pixels
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
683 ;;; in this domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
684 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
685 ;;; The general idea is that the properties allowable in a tag vector
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
686 ;;; are extendable, just by specifying the property name and a function
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
687 ;;; of two arguments, the property value and the domain, which should
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
688 ;;; return whether the tag applies. You could imagine very complex
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
689 ;;; behavior (e.g. combining two tags in a single tag set makes an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
690 ;;; `and', and putting the two tags separately with separate (perhaps
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
691 ;;; identical) instantiators makes an `or'. You could effectively do a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
692 ;;; lot of what you might want to do with hooks, but in a much more
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
693 ;;; controllable fashion. Obviously, much of this complexity wouldn't
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
694 ;;; necessarily be directly set by the user -- they wouldn't probably
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
695 ;;; do more than simple tags based on mode, buffer or file name, etc.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
696 ;;; But a higher-level interface could easily have various possible
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
697 ;;; "behaviors" to choose from, implemented using this mechanism.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
698 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
699 ;;; #### WE NEED CUSTOM SUPPORT!
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
700 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
701 ;;; (b) Another possibility is "partial" inheritance. For example --
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
702 ;;; toolbars and menubars are complex specifications. Currently the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
703 ;;; only way to make a change is to copy the entire value and make the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
704 ;;; necessary modifications. What we would like instead is to be able
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
705 ;;; to construct a mini-menubar that says something like "add this menu
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
706 ;;; here" and combine with everything else. That would require a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
707 ;;; slightly different approach to instantiation. Currently it just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
708 ;;; searches up the tree from specific to general, looking for a match;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
709 ;;; from this match, it generates the instance. Instead, it would
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
710 ;;; potentially have to record all the matches it found and pass a list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
711 ;;; of them to the instantiation function. To implement this, we would
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
712 ;;; create another specifier method "instantiator_inherits_up", which
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
713 ;;; looks at the instantiator to determine if it calls for combining
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
714 ;;; itself with the value higher up. this tells the specifier code
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
715 ;;; whether to stop now or keep going. It would then pass a Dynarr of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
716 ;;; the instantiators to the instantiate method, which might be a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
717 ;;; special version, e.g. "instantiate_multi".
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
718
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
719 (defun instance-to-instantiator (inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
720 "Convert an instance to an instantiator.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
721 If we have an instance object, we fetch the instantiator that generated the object. Otherwise, we just return the instance."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
722 (cond ((font-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
723 (setq inst (font-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
724 ((color-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
725 (setq inst (color-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
726 ((image-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
727 (setq inst (image-instance-instantiator inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
728 (t inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
729
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
730 (defun device-type-matches-spec (devtype devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
731 ;; Return DEVTYPE (a devtype) if it matches DEVTYPE-SPEC, else nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
732 ;; DEVTYPE-SPEC can be nil (all types OK), a device type (only that type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
733 ;; OK), or `window-system' -- window system device types OK.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
734 (cond ((not devtype-spec) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
735 ((eq devtype-spec 'window-system)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
736 (and (not (memq devtype '(tty stream))) devtype))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
737 (t (and (eq devtype devtype-spec) devtype))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
738
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
739 (defun add-tag-to-inst-list (inst-list tag-set)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
740 "Add TAG-SET (tag or tag-set) to all tags in INST-LIST."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
741 ;; Ah, all is sweetness and light with `loop'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
742 (if (null tag-set) inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
743 (loop for (t2 . x2) in inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
744 for newt2 = (delete-duplicates
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
745 (append (if (listp tag-set) tag-set (list tag-set))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
746 (if (listp t2) t2 (list t2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
747 collect (cons newt2 x2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
748
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
749 (defun derive-domain-from-locale (locale &optional devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
750 "Given a locale, try to derive the \"most reasonable\" domain.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
751
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
752 This is a heuristic \(\"works most of the time\") algorithm.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
753
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
754 \[Remember that, in specifiers, locales are what you attach specifications or
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
755 \"instantiators\" to, and domains are the contexts in which you can
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
756 retrieve the value or \"instance\" of the specifier. Not all locales are
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
757 domains. In particular, buffers are locales but not domains because
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
758 buffers may be displayed in different windows on different frames, and thus
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
759 end up with different values if the frames each have a frame-local
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
760 instantiator and the instantiators are different. However, we may well
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
761 find ourselves in a situation where we want to figure out the most likely
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
762 value of a specifier in a buffer -- for example we might conceptually want
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
763 to make a buffer's modeline face be bold, so we need to figure out what the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
764 current face is. If the buffer already has an instantiator, it's easy; but
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
765 if it doesn't, we want to do something reasonable rather than just issue an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
766 error, even though technically the value is not well-defined. We want
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
767 something that gives the right answer most of the time.]
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
768
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
769 LOCALE is a specifier locale -- i.e. a buffer, window, frame, device, the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
770 symbol `global', or nil, meaning the same as `global'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
771
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
772 DEVTYPE-SPEC, if given, can restrict the possible return values to domains
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
773 on devices of that device type; or if it's `window-system', to domains on
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
774 window-system devices.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
775
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
776 CURRENT-DEVICE is what should be considered as the \"selected device\" when
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
777 this value is needed. It defaults to the currently selected device.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
778
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
779 -- If LOCALE is a domain, it's simply returned.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
780 -- If LOCALE is `all', `global', or nil, we return CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
781 -- If LOCALE is a buffer, we use `get-buffer-window' to find a window viewing
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
782 the buffer, and return it if there is one; otherwise we return the selected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
783 window on CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
784
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
785 The return value may be nil if the only possible values don't agree with
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
786 DEVTYPE-SPEC."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
787 ;; DEVICE aims to be the selected device, but picks some other
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
788 ;; device if that won't work. may be nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
789 (let* ((device (or current-device (selected-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
790 (device (if (device-type-matches-spec (device-type device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
791 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
792 device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
793 (first
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
794 (delete-if-not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
795 #'(lambda (x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
796 (device-type-matches-spec (device-type x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
797 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
798 (device-list))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
799 (cond ((memq locale '(all nil global)) device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
800 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
801 (and (device-type-matches-spec (device-type (dfw-device locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
802 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
803 locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
804 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
805 (let ((win (get-buffer-window locale t devtype-spec)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
806 (or win (and device (selected-window device))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
807
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
808 (defun derive-device-type-from-tag-set (tag-set &optional try-stages
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
809 devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
810 "Given a tag set, try (heuristically) to get a device type from it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
811
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
812 There are three stages that this function proceeds through, each one trying
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
813 harder than the previous to get a value. TRY-STAGES controls how many
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
814 stages to try. If nil or 1, only stage 1 is done; if 2; stages 1 and 2 are
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
815 done; if 3, stages 1-3 are done; if t, all stages are done (currently 1-3).
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
816
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
817 Stage 1 looks at the tags themselves to see if any of them are device-type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
818 tags. If so, it returns the device type. If there is more than one device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
819 type, this tag can never match anything, but we go ahead and return one of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
820 them. If no device types in the tags, we fail.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
821
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
822 Stage 2 runs all devices through the tag set to see if any match, and
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
823 accumulate a list of device types of all matching devices. If there is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
824 exactly one device type in the list, we return it, else fail.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
825
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
826 Stage 3 picks up from where stage 2 left off, and tries hard to return
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
827 *SOME* device type in all possible situations, modulo the DEVTYPE-SPEC
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
828 flag. \(DEVTYPE-SPEC and CURRENT-DEVICE are the same as in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
829 `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
830
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
831 Specifically:
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
832
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
833 \(a) if no matching devices, return the selected device's type.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
834 \(b) if more than device type and the selected device's type is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
835 listed, use it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
836 \(c) else, pick one of the device types (currently the first).
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
837
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
838 This will never return a device type that's incompatible with the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
839 DEVTYPE-SPEC flag; thus, it may return nil."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
840 (or try-stages (setq try-stages 1))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
841 (if (eq try-stages t) (setq try-stages 3))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
842 (check-argument-range try-stages 1 3)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
843 (flet ((delete-wrong-type (x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
844 (delete-if-not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
845 #'(lambda (y)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
846 (device-type-matches-spec y devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
847 x)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
848 (let ((both (intersection (device-type-list)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
849 (canonicalize-tag-set tag-set))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
850 ;; shouldn't be more than one (will fail), but whatever
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
851 (if both (first (delete-wrong-type both))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
852 (and (>= try-stages 2)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
853 ;; no device types mentioned. try the hard way,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
854 ;; i.e. check each existing device to see if it will
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
855 ;; pass muster.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
856 (let ((okdevs
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
857 (delete-wrong-type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
858 (delete-duplicates
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
859 (mapcan
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
860 #'(lambda (dev)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
861 (and (device-matches-specifier-tag-set-p
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
862 dev tag-set)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
863 (list (device-type dev))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
864 (device-list)))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
865 (devtype (cond ((or (null devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
866 (eq devtype-spec 'window-system))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
867 (let ((dev (derive-domain-from-locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
868 'global devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
869 current-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
870 (and dev (device-type dev))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
871 (t devtype-spec))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
872 (cond ((= 1 (length okdevs)) (car okdevs))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
873 ((< try-stages 3) nil)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
874 ((null okdevs) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
875 ((memq devtype okdevs) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
876 (t (car okdevs)))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
877
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
878 ;; Sheesh, the things you do to get "intuitive" behavior.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
879 (defun derive-device-type-from-locale-and-tag-set (locale tag-set
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
880 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
881 current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
882 "Try to derive a device type from a locale and tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
883
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
884 If the locale is a domain, use the domain's device type. Else, if the tag
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
885 set uniquely specifies a device type, use it. Else, if a buffer is given,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
886 find a window visiting the buffer, and if any, use its device type.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
887 Finally, go back to the tag set and \"try harder\" -- if the selected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
888 device matches the tag set, use its device type, else use some valid device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
889 type from the tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
890
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
891 DEVTYPE-SPEC and CURRENT-DEVICE as in `derive-domain-from-locale'."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
892
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
893 (cond ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
894 ;; if locale is a domain, then it must match DEVTYPE-SPEC,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
895 ;; or we exit immediately with nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
896 (device-type-matches-spec (device-type (dfw-device locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
897 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
898 ((derive-device-type-from-tag-set tag-set 2 devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
899 current-device))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
900 ((and (bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
901 (let ((win (get-buffer-window locale t devtype-spec)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
902 (and win (device-type (dfw-device win))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
903 ((derive-device-type-from-tag-set tag-set t devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
904 current-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
905
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
906 (defun derive-specifier-specs-from-locale (specifier locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
907 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
908 current-device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
909 global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
910 "Heuristically find the specs of a specifier in a locale.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
911
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
912 This tries to find some reasonable instantiators that are most likely to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
913 correspond to the specifier's \"value\" (i.e. instance) in a particular
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
914 locale, even when the user has not specifically set any such instantiators.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
915 This is useful for functions that want to modify the instance of a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
916 specifier in a particular locale, and only in that locale.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
917
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
918 Keep in mind that this is a heuristic (i.e. kludge) function, and that it
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
919 may not always give the right results, since the operation is not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
920 technically well-defined in many cases! (See `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
921
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
922 DEVTYPE-SPEC and CURRENT-DEVICE are as in `derive-domain-from-locale'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
923
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
924 The return value is an inst-list, i.e.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
925
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
926 ((TAG-SET . INSTANTIATOR) ...)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
927
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
928 More specifically, if there is already a spec in the locale, it's just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
929 returned. Otherwise, if LOCALE is `global', `all', or nil: If
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
930 GLOBAL-USE-FALLBACK is non-nil, the fallback is fetched, and returned, with
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
931 `default' added to the tag set; else, we use CURRENT-DEVICE (defaulting to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
932 the selected device) as a domain and proceed as in the following. If
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
933 LOCALE is a domain (window, frame, device), the specifier's instance in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
934 that domain is computed, and converted back to an instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
935 \(`instance-to-instantiator'). Else, if LOCALE is a buffer, we use
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
936 `derive-domain-from-locale' to heuristically get a likely domain, and
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
937 proceed as if LOCALE were a domain."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
938 (if (memq locale '(all nil)) (setq locale 'global))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
939 (let ((current (specifier-spec-list specifier locale)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
940 (if current (cdar current)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
941 ;; case 1: a global locale, fallbacks
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
942 (cond ((and (eq locale 'global) global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
943 ;; if nothing there globally, retrieve the fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
944 ;; this is either an inst-list or a specifier. in the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
945 ;; latter case, we need to recursively retrieve its
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
946 ;; fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
947 (let (sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
948 (fallback (specifier-fallback specifier)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
949 (while (specifierp fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
950 (setq sofar (nconc sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
951 (cdar (specifier-spec-list fallback
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
952 'global))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
953 (setq fallback (specifier-fallback fallback)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
954 (add-tag-to-inst-list (nconc sofar fallback) 'default)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
955 (t
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
956 (let (domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
957 ;; case 2: window, frame, device locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
958 (cond ((eq locale 'global)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
959 (setq domain (or current-device (selected-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
960 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
961 (setq domain locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
962 ;; case 3: buffer locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
963 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
964 (setq domain (derive-domain-from-locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
965 locale devtype-spec current-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
966 (t nil))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
967 ;; retrieve an instance, convert back to instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
968 (when domain
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
969 (let ((inst
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
970 (instance-to-instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
971 (specifier-instance specifier domain))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
972 (list (cons nil inst))))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
973
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974 ;;; specifier.el ends here