annotate lisp/specifier.el @ 5750:66d2f63df75f

Correct some spelling and formatting in behavior.el. Mentioned in tracker issue 826, the third thing mentioned there (the file name at the bottom of the file) had already been fixed. lisp/ChangeLog addition: 2013-08-05 Aidan Kehoe <kehoea@parhasard.net> * behavior.el: (override-behavior): Correct some spelling and formatting here, thank you Steven Mitchell in tracker issue 826.
author Aidan Kehoe <kehoea@parhasard.net>
date Mon, 05 Aug 2013 10:05:32 +0100
parents 071b810ceb18
children
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.
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
4 ;; Copyright (C) 1995, 1996, 2000, 2002, 2005 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
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
13 ;; XEmacs is free software: you can redistribute it and/or modify it
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
14 ;; under the terms of the GNU General Public License as published by the
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
15 ;; Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
16 ;; option) any later version.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful, but WITHOUT
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
19 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
20 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
21 ;; for more details.
428
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
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5267
diff changeset
24 ;; along with XEmacs. If not, see <http://www.gnu.org/licenses/>.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;;; Commentary:
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 ;; This file is dumped with XEmacs.
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 ;;; Code:
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 (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
33 "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
34
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
35 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
36 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
37 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
38 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
39 form acceptable to `canonicalize-spec-list'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
40 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
41 SPEC-LIST must already be in full form."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 (let ((sp (make-specifier type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 (if (not dont-canonicalize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 (setq spec-list (canonicalize-spec-list spec-list type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 (add-spec-list-to-specifier sp spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 sp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 ;; God damn, do I hate dynamic scoping.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
50 (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
51 ms-tag-set ms-exact-p)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 "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
53
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
54 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
55 If MS-LOCALE is a locale type, MS-FUNC will be mapped over all locales of that
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
56 type. If MS-LOCALE is `all' or nil, MS-FUNC will be mapped over all locales in
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
57 MS-SPECIFIER.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
59 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
60 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
61
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 MS-FUNC is called with four arguments: the MS-SPECIFIER, the locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 being mapped over, the inst-list for that locale, and the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 optional MS-MAPARG. If any invocation of MS-FUNC returns non-nil,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 the mapping will stop and the returned value becomes the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 value returned from `map-specifier'. Otherwise, `map-specifier'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 returns nil."
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
68 (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
69 ms-exact-p))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 ms-result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 (while (and ms-specs (not ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 (let ((ms-this-spec (car ms-specs)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (setq ms-result (funcall ms-func ms-specifier (car ms-this-spec)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 (cdr ms-this-spec) ms-maparg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 (setq ms-specs (cdr ms-specs))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 (defun canonicalize-inst-pair (inst-pair specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 "Canonicalize the given INST-PAIR.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 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
85 `(TAG-SET . INSTANTIATOR)'. A single, untagged instantiator is given
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 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
87 a tag set consisting only of that tag.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 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
90 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; a) a single instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;; b) a cons of a tag and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; c) a cons of a tag set and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 (cond ((valid-instantiator-p inst-pair specifier-type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 (cons nil inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ((not (consp inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ;; not an inst-pair
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (check-valid-instantiator inst-pair specifier-type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105
5244
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
106 ((not (valid-instantiator-p (cdr inst-pair) specifier-type))
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
107 (if noerror
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
108 t
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
109 (check-valid-instantiator (cdr inst-pair) specifier-type)))
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
110
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
111 ((valid-specifier-tag-p (car inst-pair))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 (cons (list (car inst-pair)) (cdr inst-pair)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114
5244
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
115 ((valid-specifier-tag-set-p (car inst-pair))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 ;; case (c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 inst-pair)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 (if noerror t
5244
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
121 (error 'invalid-argument "Invalid specifier tag set"
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
122 (car inst-pair))))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 (defun canonicalize-inst-list (inst-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 "Canonicalize the given INST-LIST (a list of inst-pairs).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 SPECIFIER-TYPE specifies the type of specifier that this INST-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 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
131 `((TAG-SET . INSTANTIATOR) ...)'. This function accepts a single
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 inst-pair or any abbreviation thereof or a list of (possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 abbreviated) inst-pairs. (See `canonicalize-inst-pair'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 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
136 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 ;; a) an inst-pair or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 (let ((result (canonicalize-inst-pair inst-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 (if (not (consp inst-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 ;; not an inst-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 (check-valid-instantiator inst-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 (catch 'cann-inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (let ((rest inst-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (if noerror (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (signal 'error (list "Invalid list format" inst-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 (let ((res2 (canonicalize-inst-pair (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; otherwise canonicalize-inst-pair would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 (defun canonicalize-spec (spec specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 "Canonicalize the given SPEC (a specification).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
177 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
178
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 Canonicalizing means converting to the full form for a spec, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 `(LOCALE (TAG-SET . INSTANTIATOR) ...)'. This function accepts a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 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
182 abbreviated inst-list. (See `canonicalize-inst-list'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 If NOERROR is nil, signal an error if the specification is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 ;; a) an inst-list or some abbreviation thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 ;; b) a cons of a locale and an inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (let ((result (canonicalize-inst-list spec specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (cons 'global result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 (if (not (consp spec))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 ;; not a spec.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 (check-valid-instantiator spec specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 (if (not (valid-specifier-locale-p (car spec)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 ;; invalid locale.
5244
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
203 (if noerror
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
204 t
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
205 (if (consp (car spec))
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
206 ;; If it's a cons, they're probably not passing a locale
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
207 (error 'invalid-argument
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
208 "Not a valid instantiator list" spec)
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
209 (error 'invalid-argument
04811a268716 Be clearer in our error messages, #'canonicalize-inst-pair, #'canonicalize-spec
Aidan Kehoe <kehoea@parhasard.net>
parents: 5222
diff changeset
210 "Invalid specifier locale" (car spec))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (let ((result (canonicalize-inst-list (cdr spec) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 (if (eq result t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 ;; otherwise canonicalize-inst-list would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 (cons (car spec) result))))))))
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 (defun canonicalize-spec-list (spec-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 "Canonicalize the given SPEC-LIST (a list of specifications).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 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
228 `((LOCALE (TAG-SET . INSTANTIATOR) ...) ...)'. This function accepts
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 a possibly abbreviated specification or a list of such things. (See
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 `canonicalize-spec'.) This is the function used to convert spec-lists
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 accepted by `set-specifier' and such into a form suitable for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 `add-spec-list-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
234 The canonicalization algorithm is as follows:
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
235
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
236 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
237 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
238 specifications.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
239 3. If (2) fails, SPEC-LIST is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
240
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
241 A possibly abbreviated specification SPEC is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
242
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
243 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
244 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
245 (abbreviated) inst-list.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
246 3. If (2) fails, SPEC is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
247
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
248 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
249
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
250 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
251 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
252 inst-pairs.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
253 3. If (2) fails, INST-LIST is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
254
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
255 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
256
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
257 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
258 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
259 `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
260 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
261 is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
262
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
263 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
264
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
265 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
266 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
267 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
268 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
269 canonicalization for these types.)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 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
272 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 ;; a) a spec or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 (let ((result (canonicalize-spec spec-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 (list result)
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 (if (not (consp spec-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 ;; not a spec-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 (check-valid-instantiator spec-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (catch 'cann-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (let ((rest spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 (if noerror (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 (signal 'error (list "Invalid list format" spec-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 (let ((res2 (canonicalize-spec (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 ;; otherwise canonicalize-spec would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (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
310 "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
311
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
312 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
313
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
314 -- an instantiator (either a Lisp object which will be returned when the
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
315 specifier is instantiated, or a Lisp object that can be instantiated to
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
316 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
317 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
318 -- a list of instantiators
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
319 -- 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
320 instantiators
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
321 -- 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
322 -- 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
323 -- 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
324 -- a canonical spec-list.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
326 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
327 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
328 and `add-spec-list-to-specifier' instead.
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 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
331 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
332 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
333 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
334 that function.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
335
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
336 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
337 `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
338 that. N.B. `remove-specifier' defaults to removing all specifications, not
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
339 just the `global' one!
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
340
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
341 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
342 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
343 \(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
344 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
345
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 LOCALE indicates where this specification is active, and should be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 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
348 indicate that it applies everywhere. LOCALE defaults to
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
349 `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
350 cases where value is a full specification or a spec-list).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 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
353 with the VALUE. Tags are symbols (usually naming device types, such
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 as `x' and `tty', or device classes, such as `color', `mono', and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 `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
356 devices that match all specified tags. (You can also create your
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 own tags using `define-specifier-tag', and use them to identify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 specifications added by you, so you can remove them later.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 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
361 symbols `prepend', `append', `remove-tag-set-prepend',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 `remove-tag-set-append', `remove-locale', `remove-locale-type',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 or `remove-all'. This specifies what to do with existing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 specifications in LOCALE (and possibly elsewhere in the specifier).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 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
366 the default behavior of `remove-tag-set-prepend' is usually fine.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 See `copy-specifier' and `add-spec-to-specifier' for a full
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 description of what each of these means.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 Note that `set-specifier' is exactly complementary to `specifier-specs'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 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
372 is a valid instantiator (in that case, `specifier-specs' will return
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 nil (meaning no specs) and `set-specifier' will interpret the `nil'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 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
375 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
376 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
377 in such a way as to avoid any such ambiguities.)"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 ;; backward compatibility: the old function had HOW-TO-ADD as the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 ;; third argument and no arguments after that.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 ;; #### this should disappear at some point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (if (and (null how-to-add)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (memq locale '(prepend append remove-tag-set-prepend
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 remove-tag-set-append remove-locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 remove-locale-type remove-all)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (setq how-to-add locale)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (setq locale nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 ;; proper beginning of the function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (let ((is-valid (valid-instantiator-p value (specifier-type specifier)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (nval value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 (cond ((and (not is-valid) (specifierp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 (copy-specifier nval specifier locale tag-set nil how-to-add))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 (if tag-set
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (if (not (listp tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 (setq tag-set (list tag-set)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 ;; You tend to get more accurate errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 ;; for a variety of cases if you call
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 ;; canonicalize-tag-set here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 (setq tag-set (canonicalize-tag-set tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 (if (and (not is-valid) (consp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 (setq nval
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 (mapcar #'(lambda (x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 (check-valid-instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 x (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 (cons tag-set x))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 (setq nval (cons tag-set nval)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 (if locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 (setq nval (cons locale nval)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 (canonicalize-spec-list nval (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 how-to-add))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
420 ;; #### Misnamed and wrong behavior. Should operate on INSTANTIATORS, not
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
421 ;; instances. Need to come up with clean and general functions for
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
422 ;; modifying a specifier. New `specifier-instantiator' may help.
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
423 ;; #### Also need `instantiator-to-instance', a convenient version of
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
424 ;; `specifier-instance-from-inst-list'.
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
425
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
426 (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
427 locale tag-set)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
428 "Modify all specifications that match LOCALE and TAG-SET by FUNC.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
429
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
430 For each specification that exists for SPECIFIER, in locale LOCALE
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
431 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
432 first argument and with optional arguments ARGS. The result is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
433 used as the new value of the instantiator.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
434
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
435 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
436 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
437 specifier instance if that exists or DEFAULT otherwise. If LOCALE is
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
438 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
439 applied like above and the resulting specification is added."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
440
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
441 (let ((spec-list (specifier-spec-list specifier locale tag-set)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
442 (cond
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
443 (spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
444 ;; Destructively edit the spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
445 (mapc #'(lambda (spec)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
446 (mapc #'(lambda (inst-pair)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
447 (setcdr inst-pair
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
448 (apply func (cdr inst-pair) args)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
449 (cdr spec)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
450 spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
451 (add-spec-list-to-specifier specifier spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
452 (force
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
453 (set-specifier specifier
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
454 (apply func
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
455 (or (and (valid-specifier-domain-p locale)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
456 (specifier-instance specifier))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
457 default) args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
458 locale tag-set)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
459
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 (defmacro let-specifier (specifier-list &rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 "Add specifier specs, evaluate forms in BODY and restore the specifiers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 \(let-specifier SPECIFIER-LIST BODY...)
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 Each element of SPECIFIER-LIST should look like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 \(SPECIFIER VALUE &optional LOCALE TAG-SET HOW-TO-ADD).
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 SPECIFIER is the specifier to be temporarily modified. VALUE is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 instantiator to be temporarily added to SPECIFIER in LOCALE. LOCALE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 TAG-SET and HOW-TO-ADD have the same meaning as in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 `add-spec-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 The code resulting from macro expansion will add specifications to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 specifiers using `add-spec-to-specifier'. After BODY is finished, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 temporary specifications are removed and old spec-lists are restored.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 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
477 The value of the last form in BODY is returned.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 NOTE: If you want the specifier's instance to change in all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 circumstances, use (selected-window) as the LOCALE. If LOCALE is nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 or omitted, it defaults to `global'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 Example:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (let-specifier ((modeline-shadow-thickness 0 (selected-window)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (sit-for 1))"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 (check-argument-type 'listp specifier-list)
5567
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
487 (labels ((gensym-frob (x name)
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
488 (if (or (atom x) (eq (car x) 'quote))
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
489 (list x)
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
490 (list (gensym name) x))))
5576
071b810ceb18 Declare labels as line where appropriate; use #'labels, not #'flet, tests.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5567
diff changeset
491 (declare (inline gensym-frob))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 ;; VARLIST is a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 ;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 ;; (TAG-SET) (HOW-TO-ADD))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 ;; If any of these is an atom, then a separate symbol is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 ;; unnecessary, the CAR will contain the atom and CDR will be nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 (let* ((varlist (mapcar #'(lambda (listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 (or (and (consp listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (<= (length listel) 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 (> (length listel) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 (signal 'error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 "should be a list of 2-5 elements"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 listel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 ;; VALUE, TAG-SET and HOW-TO-ADD are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ;; referenced only once, so we needn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 ;; frob them with gensym.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 (list (gensym-frob (nth 0 listel) "specifier-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 (list (nth 1 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (gensym-frob (nth 2 listel) "locale-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 (list (nth 3 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 (list (nth 4 listel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 specifier-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 ;; OLDVALLIST is a list of (OLDVALSYM OLDVALFORM)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 (oldvallist (mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 (list (gensym "old-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 `(specifier-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 ,(car (nth 2 varel)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 varlist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 ;; Bind the appropriate variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 `(let* (,@(mapcan #'(lambda (varel)
5267
668c73e222fd Change forms like (delq nil (mapcar ...)) to (mapcan ...).
Aidan Kehoe <kehoea@parhasard.net>
parents: 5244
diff changeset
523 (mapcan #'(lambda (varcons)
668c73e222fd Change forms like (delq nil (mapcar ...)) to (mapcan ...).
Aidan Kehoe <kehoea@parhasard.net>
parents: 5244
diff changeset
524 (and (cdr varcons) (list varcons)))
668c73e222fd Change forms like (delq nil (mapcar ...)) to (mapcan ...).
Aidan Kehoe <kehoea@parhasard.net>
parents: 5244
diff changeset
525 varel))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 ,@oldvallist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 ,@(mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 `(add-spec-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 ,(car (nth 0 varel)) ,(car (nth 1 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 ,(car (nth 2 varel)) ,(car (nth 3 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 ,(car (nth 4 varel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 ,@body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 ;; Reverse the unwinding order, so that using the same
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 ;; specifier multiple times works.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 ,@(apply #'nconc (nreverse (mapcar*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 #'(lambda (oldval varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 `((remove-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 ,(car (nth 2 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 ,(car oldval))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 oldvallist varlist))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
549 (defun make-integer-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
550 "Return a new `integer' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
551 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
552 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
553 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
554 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
555
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
556 Valid instantiators for integer specifiers are integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
557 (make-specifier-and-init 'integer spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
558
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
559 (defun make-boolean-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
560 "Return a new `boolean' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
561 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
562 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
563 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
564 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
565
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
566 Valid instantiators for boolean specifiers are t and nil."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
567 (make-specifier-and-init 'boolean spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
568
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
569 (defun make-natnum-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
570 "Return a new `natnum' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
571 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
572 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
573 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
574 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
575
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
576 Valid instantiators for natnum specifiers are non-negative integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
577 (make-specifier-and-init 'natnum spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
578
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
579 (defun make-generic-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
580 "Return a new `generic' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
581 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
582 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
583 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
584 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
585
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
586 Valid instantiators for generic specifiers are all Lisp values.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
587 They are returned back unchanged when a specifier is instantiated."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
588 (make-specifier-and-init 'generic spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
589
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
590 (defun make-display-table-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
591 "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
592 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
593 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
594 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
595 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
596
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
597 Valid instantiators for display-table specifiers are described in
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
598 detail in the doc string for `current-display-table'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
599 (make-specifier-and-init 'display-table spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
600
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 ;; Evaluate this for testing:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 ; (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
603
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 (define-specifier-tag 'win 'device-on-window-system-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 ;; Add tags for device types that don't have support compiled
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 ;; into the binary that we're about to dump. This will prevent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 ;; code like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 ;; (set-face-foreground 'default "black" nil '(x color))
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 ;; from producing an error if no X support was compiled in.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613
4194
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
614 (loop
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
615 for tag in '(x tty mswindows msprinter gtk carbon)
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
616 do (unless (valid-specifier-tag-p tag)
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
617 (define-specifier-tag tag #'ignore)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 ;; Add special tag for use by initialization code. Code that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 ;; sets up default specs should use this tag. Code that needs to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 ;; override default specs (e.g. the X resource initialization
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 ;; code) can safely clear specs with this tag without worrying
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 ;; about clobbering user settings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 (define-specifier-tag 'default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626
4194
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
627 ;; The x-resource specifier tag is provide so the X resource initialization
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
628 ;; code can be overridden by custom without trouble.
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
629
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
630 (define-specifier-tag 'x-resource)
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
631
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
632 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
633 ;;; "Heuristic" specifier functions ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
635
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
636 ;;; "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
637 ;;; practice, though.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
638
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
639 ;;; 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
640 ;;; 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
641 ;;; 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
642 ;;; 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
643 ;;; 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
644 ;;; 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
645 ;;; 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
646 ;;; 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
647 ;;; 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
648 ;;; 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
649 ;;; 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
650 ;;; 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
651 ;;; 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
652 ;;; 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
653 ;;; 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
654 ;;; 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
655 ;;; working.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
656
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
657 ;;; 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
658 ;;; 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
659 ;;; 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
660 ;;; high-level code.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
661
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
662 ;;; #### 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
663 ;;; created for general specifier frobbing.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
664
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
665 ;;; #### Other possible extensions to specifiers would be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
666 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
667 ;;; (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
668 ;;; 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
669 ;;; 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
670 ;;; 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
671 ;;; 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
672 ;;; 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
673 ;;; 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
674 ;;; 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
675 ;;; 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
676 ;;; 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
677 ;;; 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
678 ;;; 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
679 ;;; 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
680 ;;; 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
681 ;;; 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
682 ;;; 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
683 ;;; 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
684 ;;; extendable mechanism to control their syntax. For example,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
685 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
686 ;;; [tag :mode 'c] (buffer in c-mode)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
687 ;;; [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
688 ;;; [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
689 ;;; EUC-JP)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
690 ;;; [tag :buffer-file-name "^#.*#$"] (autosave files)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
691 ;;; [tag :language-environment "French"] (whenever the global language
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
692 ;;; environment is French)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
693 ;;; [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
694 ;;; font is at least 12 pixels
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
695 ;;; in this domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
696 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
697 ;;; 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
698 ;;; 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
699 ;;; 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
700 ;;; 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
701 ;;; 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
702 ;;; `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
703 ;;; 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
704 ;;; 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
705 ;;; 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
706 ;;; 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
707 ;;; 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
708 ;;; 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
709 ;;; "behaviors" to choose from, implemented using this mechanism.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
710 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
711 ;;; #### WE NEED CUSTOM SUPPORT!
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
712 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
713 ;;; (b) Another possibility is "partial" inheritance. For example --
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
714 ;;; toolbars and menubars are complex specifications. Currently the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
715 ;;; 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
716 ;;; 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
717 ;;; 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
718 ;;; 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
719 ;;; slightly different approach to instantiation. Currently it just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
720 ;;; 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
721 ;;; 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
722 ;;; 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
723 ;;; 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
724 ;;; create another specifier method "instantiator_inherits_up", which
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
725 ;;; 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
726 ;;; 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
727 ;;; 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
728 ;;; 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
729 ;;; special version, e.g. "instantiate_multi".
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
730
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
731 (defun instance-to-instantiator (inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
732 "Convert an instance to an instantiator.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
733 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
734 (cond ((font-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
735 (setq inst (font-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
736 ((color-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
737 (setq inst (color-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
738 ((image-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
739 (setq inst (image-instance-instantiator inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
740 (t inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
741
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
742 (defun device-type-matches-spec (devtype devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
743 ;; 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
744 ;; 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
745 ;; 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
746 (cond ((not devtype-spec) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
747 ((eq devtype-spec 'window-system)
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
748 (and (not (memq devtype '(msprinter tty stream))) devtype))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
749 (t (and (eq devtype devtype-spec) devtype))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
750
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
751 (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
752 "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
753 ;; Ah, all is sweetness and light with `loop'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
754 (if (null tag-set) inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
755 (loop for (t2 . x2) in inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
756 for newt2 = (delete-duplicates
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
757 (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
758 (if (listp t2) t2 (list t2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
759 collect (cons newt2 x2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
760
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
761 (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
762 "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
763
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
764 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
765
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
766 \[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
767 \"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
768 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
769 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
770 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
771 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
772 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
773 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
774 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
775 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
776 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
777 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
778 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
779 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
780
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
781 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
782 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
783
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
784 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
785 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
786 window-system devices.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
787
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
788 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
789 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
790
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
791 -- 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
792 -- 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
793 -- 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
794 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
795 window on CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
796
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
797 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
798 DEVTYPE-SPEC."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
799 ;; 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
800 ;; 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
801 (let* ((device (or current-device (selected-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
802 (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
803 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
804 device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
805 (first
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
806 (delete-if-not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
807 #'(lambda (x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
808 (device-type-matches-spec (device-type x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
809 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
810 (device-list))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
811 (cond ((memq locale '(all nil global)) device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
812 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
813 (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
814 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
815 locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
816 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
817 (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
818 (or win (and device (selected-window device))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
819
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
820 (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
821 devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
822 "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
823
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
824 If CURRENT-DEVICE is supplied, then this function either returns its type,
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
825 in the event that it matches TAG-SET, or nil.
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
826
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
827 Otherwise, there are three stages that it proceeds through, each one trying
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
828 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
829 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
830 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
831
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
832 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
833 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
834 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
835 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
836
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
837 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
838 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
839 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
840
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
841 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
842 *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
843 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
844 `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
845
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
846 Specifically:
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
847
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
848 \(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
849 \(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
850 listed, use it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
851 \(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
852
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
853 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
854 DEVTYPE-SPEC flag; thus, it may return nil."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
855 (or try-stages (setq try-stages 1))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
856 (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
857 (check-argument-range try-stages 1 3)
5567
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
858 (labels ((delete-wrong-type (x)
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
859 (delete-if-not
3bc58dc9d688 Replace #'flet by #'labels where appropriate, core code.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5473
diff changeset
860 #'(lambda (y) (device-type-matches-spec y devtype-spec)) x)))
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
861 (let ((both (intersection
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
862 (if current-device
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
863 (list (device-type current-device))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
864 (device-type-list))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
865 (canonicalize-tag-set tag-set))))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
866 ;; 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
867 (if both (first (delete-wrong-type both))
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
868 (and (>= try-stages 2)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
869 ;; no device types mentioned. try the hard way,
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
870 ;; i.e. check each existing device (or the
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
871 ;; supplied device) to see if it will pass muster.
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
872 ;;
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
873 ;; Further checking is not relevant if current-device was
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
874 ;; supplied.
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
875 (not current-device)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
876 (let ((okdevs
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
877 (delete-wrong-type
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
878 (delete-duplicates
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
879 (mapcan
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
880 #'(lambda (dev)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
881 (and (device-matches-specifier-tag-set-p
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
882 dev tag-set)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
883 (list (device-type dev))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
884 (if current-device
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
885 (list current-device)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
886 (device-list))))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
887 (devtype (cond ((or (null devtype-spec)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
888 (eq devtype-spec 'window-system))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
889 (let ((dev (derive-domain-from-locale
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
890 'global devtype-spec
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
891 current-device)))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
892 (and dev (device-type dev))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
893 (t devtype-spec))))
5366
f00192e1cd49 Examining the result of #'length: `eql', not `=', it's better style & cheaper
Aidan Kehoe <kehoea@parhasard.net>
parents: 5267
diff changeset
894 (cond ((eql 1 (length okdevs)) (car okdevs))
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
895 ((< try-stages 3) nil)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
896 ((null okdevs) devtype)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
897 ((memq devtype okdevs) devtype)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
898 (t (car okdevs)))))))))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
899
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
900 ;; 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
901 (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
902 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
903 current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
904 "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
905
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
906 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
907 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
908 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
909 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
910 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
911 type from the tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
912
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
913 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
914 (cond ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
915 ;; 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
916 ;; or we exit immediately with nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
917 (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
918 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
919 ((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
920 current-device))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
921 ((and (bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
922 (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
923 (and win (device-type (dfw-device win))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
924 ((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
925 current-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
926
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
927 (defun derive-specifier-specs-from-locale (specifier locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
928 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
929 current-device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
930 global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
931 "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
932
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
933 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
934 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
935 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
936 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
937 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
938
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
939 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
940 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
941 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
942
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
943 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
944
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
945 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
946
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
947 ((TAG-SET . INSTANTIATOR) ...)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
948
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
949 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
950 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
951 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
952 `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
953 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
954 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
955 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
956 \(`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
957 `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
958 proceed as if LOCALE were a domain."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
959 (if (memq locale '(all nil)) (setq locale 'global))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
960 (let ((current (specifier-spec-list specifier locale)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
961 (if current (cdar current)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
962 ;; case 1: a global locale, fallbacks
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
963 (cond ((and (eq locale 'global) global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
964 ;; if nothing there globally, retrieve the fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
965 ;; 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
966 ;; latter case, we need to recursively retrieve its
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
967 ;; fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
968 (let (sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
969 (fallback (specifier-fallback specifier)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
970 (while (specifierp fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
971 (setq sofar (nconc sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
972 (cdar (specifier-spec-list fallback
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
973 'global))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
974 (setq fallback (specifier-fallback fallback)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
975 (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
976 (t
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
977 (let (domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
978 ;; case 2: window, frame, device locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
979 (cond ((eq locale 'global)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
980 (setq domain (or current-device (selected-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
981 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
982 (setq domain locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
983 ;; case 3: buffer locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
984 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
985 (setq domain (derive-domain-from-locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
986 locale devtype-spec current-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
987 (t nil))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
988 ;; retrieve an instance, convert back to instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
989 (when domain
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
990 (let ((inst
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
991 (instance-to-instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
992 (specifier-instance specifier domain))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
993 (list (cons nil inst))))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
994
4489
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
995 ;; Character 160 (octal 0240) displays incorrectly under some X
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
996 ;; installations apparently due to a universally crocked font width
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
997 ;; specification. Display it as a space since that's what's expected.
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
998 ;;
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
999 ;; (make-char-table 'generic) instead of (make-display-table) because
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1000 ;; make-display-table isn't dumped, and this file is.
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1001 ;;
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1002 ;; We also want the global display table to be actually globally
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1003 ;; initialised; that's why this is here, and not in x-init.el, these days.
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1004
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1005 (set-specifier current-display-table
5222
18c0b5909d16 Use keywords in structure syntax; new #define, NEED_TO_HANDLE_21_4_CODE 1
Aidan Kehoe <kehoea@parhasard.net>
parents: 4489
diff changeset
1006 #s(char-table :type generic :data (?\xA0 ?\x20))
4489
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1007 'global)
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1008
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1009 ;;; specifier.el ends here