diff options
| author | Eric S. Raymond | 1993-04-03 23:28:03 +0000 |
|---|---|---|
| committer | Eric S. Raymond | 1993-04-03 23:28:03 +0000 |
| commit | 465fceed88d57205e6d4da3259093e209e4a030e (patch) | |
| tree | 2483a1845f63b78692989e52a0770f84d66da138 | |
| parent | 4be9a25f024c49e8c114054b1b98c92070d9a494 (diff) | |
| download | emacs-465fceed88d57205e6d4da3259093e209e4a030e.tar.gz emacs-465fceed88d57205e6d4da3259093e209e4a030e.zip | |
Initial revision
| -rw-r--r-- | lisp/faces.el | 740 | ||||
| -rw-r--r-- | lisp/help-macro.el | 108 |
2 files changed, 848 insertions, 0 deletions
diff --git a/lisp/faces.el b/lisp/faces.el new file mode 100644 index 00000000000..0766894f488 --- /dev/null +++ b/lisp/faces.el | |||
| @@ -0,0 +1,740 @@ | |||
| 1 | ;;; faces.el --- Lisp interface to the c "face" structure | ||
| 2 | |||
| 3 | ;; Copyright (C) 1992, 1993 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 8 | ;; it under the terms of the GNU General Public License as published by | ||
| 9 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 10 | ;; any later version. | ||
| 11 | |||
| 12 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;; GNU General Public License for more details. | ||
| 16 | |||
| 17 | ;; You should have received a copy of the GNU General Public License | ||
| 18 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 19 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 20 | |||
| 21 | ;;; Commentary: | ||
| 22 | |||
| 23 | ;; Mostly derived from Lucid. | ||
| 24 | |||
| 25 | ;;; Code: | ||
| 26 | |||
| 27 | (defsubst internal-facep (x) | ||
| 28 | (and (vectorp x) (= (length x) 8) (eq (aref x 0) 'face))) | ||
| 29 | |||
| 30 | (defmacro internal-check-face (face) | ||
| 31 | (` (while (not (internal-facep (, face))) | ||
| 32 | (setq (, face) (signal 'wrong-type-argument (list 'internal-facep (, face))))))) | ||
| 33 | |||
| 34 | |||
| 35 | (defvar global-face-data nil "do not use this") | ||
| 36 | |||
| 37 | (defun face-list () | ||
| 38 | "Returns a list of all defined face names." | ||
| 39 | (mapcar 'car global-face-data)) | ||
| 40 | |||
| 41 | (defun internal-find-face (name &optional frame) | ||
| 42 | "Retrieve the face named NAME. Return nil if there is no such face. | ||
| 43 | If the optional argument FRAME is given, this gets the face NAME for | ||
| 44 | that frame; otherwise, it uses the selected frame. | ||
| 45 | If FRAME is the symbol t, then the global, non-frame face is returned. | ||
| 46 | If NAME is already a face, it is simply returned." | ||
| 47 | (if (and (eq frame t) (not (symbolp name))) | ||
| 48 | (setq name (face-name name))) | ||
| 49 | (if (symbolp name) | ||
| 50 | (cdr (assq name | ||
| 51 | (if (eq frame t) | ||
| 52 | global-face-data | ||
| 53 | (frame-face-alist (or frame (selected-frame)))))) | ||
| 54 | (internal-check-face name) | ||
| 55 | name)) | ||
| 56 | |||
| 57 | (defun internal-get-face (name &optional frame) | ||
| 58 | "Retrieve the face named NAME; error if there is none. | ||
| 59 | If the optional argument FRAME is given, this gets the face NAME for | ||
| 60 | that frame; otherwise, it uses the selected frame. | ||
| 61 | If FRAME is the symbol t, then the global, non-frame face is returned. | ||
| 62 | If NAME is already a face, it is simply returned." | ||
| 63 | (or (internal-find-face name frame) | ||
| 64 | (internal-check-face name))) | ||
| 65 | |||
| 66 | (defsubst face-name (face) | ||
| 67 | "Return the name of face FACE." | ||
| 68 | (aref (internal-get-face face) 1)) | ||
| 69 | |||
| 70 | (defsubst face-id (face) | ||
| 71 | "Return the internal ID number of face FACE." | ||
| 72 | (aref (internal-get-face face) 2)) | ||
| 73 | |||
| 74 | (defsubst face-font (face &optional frame) | ||
| 75 | "Return the font name of face FACE, or nil if it is unspecified. | ||
| 76 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 77 | Otherwise report on the defaults for face FACE (for new frames)." | ||
| 78 | (aref (internal-get-face face frame) 3)) | ||
| 79 | |||
| 80 | (defsubst face-foreground (face &optional frame) | ||
| 81 | "Return the foreground color name of face FACE, or nil if unspecified. | ||
| 82 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 83 | Otherwise report on the defaults for face FACE (for new frames)." | ||
| 84 | (aref (internal-get-face face frame) 4)) | ||
| 85 | |||
| 86 | (defsubst face-background (face &optional frame) | ||
| 87 | "Return the background color name of face FACE, or nil if unspecified. | ||
| 88 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 89 | Otherwise report on the defaults for face FACE (for new frames)." | ||
| 90 | (aref (internal-get-face face frame) 5)) | ||
| 91 | |||
| 92 | (defsubst face-background-pixmap (face &optional frame) | ||
| 93 | "Return the background pixmap name of face FACE, or nil if unspecified. | ||
| 94 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 95 | Otherwise report on the defaults for face FACE (for new frames)." | ||
| 96 | (aref (internal-get-face face frame) 6)) | ||
| 97 | |||
| 98 | (defsubst face-underline-p (face &optional frame) | ||
| 99 | "Return t if face FACE is underlined. | ||
| 100 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 101 | Otherwise report on the defaults for face FACE (for new frames)." | ||
| 102 | (aref (internal-get-face face frame) 7)) | ||
| 103 | |||
| 104 | |||
| 105 | (defun internat-set-face-1 (face name value index frame) | ||
| 106 | (let ((inhibit-quit t)) | ||
| 107 | (if (null frame) | ||
| 108 | (let ((frames (frame-list))) | ||
| 109 | (while frames | ||
| 110 | (internat-set-face-1 (face-name face) name value index (car frames)) | ||
| 111 | (setq frames (cdr frames))) | ||
| 112 | (aset (internal-get-face (if (symbolp face) face (face-name face)) t) | ||
| 113 | index value) | ||
| 114 | value) | ||
| 115 | (or (eq frame t) | ||
| 116 | (set-face-attribute-internal (face-id face) name value frame)) | ||
| 117 | (aset (internal-get-face face frame) index value)))) | ||
| 118 | |||
| 119 | |||
| 120 | (defun read-face-name (prompt) | ||
| 121 | (let (face) | ||
| 122 | (while (= (length face) 0) | ||
| 123 | (setq face (completing-read prompt | ||
| 124 | (mapcar '(lambda (x) (list (symbol-name x))) | ||
| 125 | (list-faces)) | ||
| 126 | nil t))) | ||
| 127 | (intern face))) | ||
| 128 | |||
| 129 | (defun internal-face-interactive (what &optional bool) | ||
| 130 | (let* ((fn (intern (concat "face-" what))) | ||
| 131 | (prompt (concat "Set " what " of face")) | ||
| 132 | (face (read-face-name (concat prompt ": "))) | ||
| 133 | (default (if (fboundp fn) | ||
| 134 | (or (funcall fn face (selected-frame)) | ||
| 135 | (funcall fn 'default (selected-frame))))) | ||
| 136 | (value (if bool | ||
| 137 | (y-or-n-p (concat "Should face " (symbol-name face) | ||
| 138 | " be " bool "? ")) | ||
| 139 | (read-string (concat prompt " " (symbol-name face) " to: ") | ||
| 140 | default)))) | ||
| 141 | (list face (if (equal value "") nil value)))) | ||
| 142 | |||
| 143 | |||
| 144 | (defsubst set-face-font (face font &optional frame) | ||
| 145 | "Change the font of face FACE to FONT (a string). | ||
| 146 | If the optional FRAME argument is provided, change only | ||
| 147 | in that frame; otherwise change each frame." | ||
| 148 | (interactive (internal-face-interactive "font")) | ||
| 149 | (internat-set-face-1 face 'font font 3 frame)) | ||
| 150 | |||
| 151 | (defsubst set-face-foreground (face color &optional frame) | ||
| 152 | "Change the foreground color of face FACE to COLOR (a string). | ||
| 153 | If the optional FRAME argument is provided, change only | ||
| 154 | in that frame; otherwise change each frame." | ||
| 155 | (interactive (internal-face-interactive "foreground")) | ||
| 156 | (internat-set-face-1 face 'foreground color 4 frame)) | ||
| 157 | |||
| 158 | (defsubst set-face-background (face color &optional frame) | ||
| 159 | "Change the background color of face FACE to COLOR (a string). | ||
| 160 | If the optional FRAME argument is provided, change only | ||
| 161 | in that frame; otherwise change each frame." | ||
| 162 | (interactive (internal-face-interactive "background")) | ||
| 163 | (internat-set-face-1 face 'background color 5 frame)) | ||
| 164 | |||
| 165 | (defsubst set-face-background-pixmap (face name &optional frame) | ||
| 166 | "Change the background pixmap of face FACE to PIXMAP. | ||
| 167 | PIXMAP should be a string, the name of a file of pixmap data. | ||
| 168 | The directories listed in the `x-bitmap-file-path' variable are searched. | ||
| 169 | |||
| 170 | Alternatively, PIXMAP may be a list of the form (WIDTH HEIGHT DATA) | ||
| 171 | where WIDTH and HEIGHT are the size in pixels, | ||
| 172 | and DATA is a string, containing the raw bits of the bitmap. | ||
| 173 | |||
| 174 | If the optional FRAME argument is provided, change only | ||
| 175 | in that frame; otherwise change each frame." | ||
| 176 | (interactive (internal-face-interactive "background-pixmap")) | ||
| 177 | (internat-set-face-1 face 'background-pixmap name 6 frame)) | ||
| 178 | |||
| 179 | (defsubst set-face-underline-p (face underline-p &optional frame) | ||
| 180 | "Specify whether face FACE is underlined. (Yes if UNDERLINE-P is non-nil.) | ||
| 181 | If the optional FRAME argument is provided, change only | ||
| 182 | in that frame; otherwise change each frame." | ||
| 183 | (interactive (internal-face-interactive "underline-p" "underlined")) | ||
| 184 | (internat-set-face-1 face 'underline underline-p 7 frame)) | ||
| 185 | |||
| 186 | |||
| 187 | (defun make-face (name) | ||
| 188 | "Define a new FACE on all frames. | ||
| 189 | You can modify the font, color, etc of this face with the set-face- functions. | ||
| 190 | If the face already exists, it is unmodified." | ||
| 191 | (or (internal-find-face name) | ||
| 192 | (let ((face (make-vector 8 nil))) | ||
| 193 | (aset face 0 'face) | ||
| 194 | (aset face 1 name) | ||
| 195 | (let* ((frames (frame-list)) | ||
| 196 | (inhibit-quit t) | ||
| 197 | (id (internal-next-face-id))) | ||
| 198 | (make-face-internal id) | ||
| 199 | (aset face 2 id) | ||
| 200 | (while frames | ||
| 201 | (set-frame-face-alist (car frames) | ||
| 202 | (cons (cons name (copy-sequence face)) | ||
| 203 | (frame-face-alist (car frames)))) | ||
| 204 | (setq frames (cdr frames))) | ||
| 205 | (setq global-face-data (cons (cons name face) global-face-data))) | ||
| 206 | ;; when making a face after frames already exist | ||
| 207 | (if (eq window-system 'x) | ||
| 208 | (make-face-x-resource-internal face)) | ||
| 209 | face))) | ||
| 210 | |||
| 211 | ;; Fill in a face by default based on X resources, for all existing frames. | ||
| 212 | ;; This has to be done when a new face is made. | ||
| 213 | (defun make-face-x-resource-internal (face &optional frame set-anyway) | ||
| 214 | (cond ((null frame) | ||
| 215 | (let ((frames (frame-list))) | ||
| 216 | (while frames | ||
| 217 | (make-face-x-resource-internal (face-name face) | ||
| 218 | (car frames) set-anyway) | ||
| 219 | (setq frames (cdr frames))))) | ||
| 220 | (t | ||
| 221 | (setq face (internal-get-face (face-name face) frame)) | ||
| 222 | ;; | ||
| 223 | ;; These are things like "attributeForeground" instead of simply | ||
| 224 | ;; "foreground" because people tend to do things like "*foreground", | ||
| 225 | ;; which would cause all faces to be fully qualified, making faces | ||
| 226 | ;; inherit attributes in a non-useful way. So we've made them slightly | ||
| 227 | ;; less obvious to specify in order to make them work correctly in | ||
| 228 | ;; more random environments. | ||
| 229 | ;; | ||
| 230 | ;; I think these should be called "face.faceForeground" instead of | ||
| 231 | ;; "face.attributeForeground", but they're the way they are for | ||
| 232 | ;; hysterical reasons. | ||
| 233 | ;; | ||
| 234 | (let* ((name (symbol-name (face-name face))) | ||
| 235 | (fn (or (x-get-resource (concat name ".attributeFont") | ||
| 236 | "Face.AttributeFont") | ||
| 237 | (and set-anyway (face-font face)))) | ||
| 238 | (fg (or (x-get-resource (concat name ".attributeForeground") | ||
| 239 | "Face.AttributeForeground") | ||
| 240 | (and set-anyway (face-foreground face)))) | ||
| 241 | (bg (or (x-get-resource (concat name ".attributeBackground") | ||
| 242 | "Face.AttributeBackground") | ||
| 243 | (and set-anyway (face-background face)))) | ||
| 244 | ;; (bgp (or (x-get-resource (concat name ".attributeBackgroundPixmap") | ||
| 245 | ;; "Face.AttributeBackgroundPixmap") | ||
| 246 | ;; (and set-anyway (face-background-pixmap face)))) | ||
| 247 | (ulp (or (x-get-resource (concat name ".attributeUnderline") | ||
| 248 | "Face.AttributeUnderline") | ||
| 249 | (and set-anyway (face-underline-p face)))) | ||
| 250 | ) | ||
| 251 | (if fn | ||
| 252 | (condition-case () | ||
| 253 | (set-face-font face fn frame) | ||
| 254 | (error (message "font `%s' not found for face `%s'" fn name)))) | ||
| 255 | (if fg | ||
| 256 | (condition-case () | ||
| 257 | (set-face-foreground face fg frame) | ||
| 258 | (error (message "color `%s' not allocated for face `%s'" fg name)))) | ||
| 259 | (if bg | ||
| 260 | (condition-case () | ||
| 261 | (set-face-background face bg frame) | ||
| 262 | (error (message "color `%s' not allocated for face `%s'" bg name)))) | ||
| 263 | ;; (if bgp | ||
| 264 | ;; (condition-case () | ||
| 265 | ;; (set-face-background-pixmap face bgp frame) | ||
| 266 | ;; (error (message "pixmap `%s' not found for face `%s'" bgp name)))) | ||
| 267 | (if (or ulp set-anyway) | ||
| 268 | (set-face-underline-p face ulp frame)) | ||
| 269 | ))) | ||
| 270 | face) | ||
| 271 | |||
| 272 | (defun copy-face (old-face new-name &optional frame) | ||
| 273 | "Define a face just like OLD-FACE, with name NEW-NAME. | ||
| 274 | If NEW-NAME already exists as a face, it is modified to be like OLD-FACE. | ||
| 275 | If the optional argument FRAME is given, this applies only to that frame. | ||
| 276 | Otherwise it applies to each frame separately." | ||
| 277 | (setq old-face (internal-get-face old-face frame)) | ||
| 278 | (let* ((inhibit-quit t) | ||
| 279 | (new-face (or (internal-find-face new-name frame) | ||
| 280 | (make-face new-name)))) | ||
| 281 | (if (null frame) | ||
| 282 | (let ((frames (frame-list))) | ||
| 283 | (while frames | ||
| 284 | (copy-face old-face new-name (car frames)) | ||
| 285 | (setq frames (cdr frames))) | ||
| 286 | (copy-face old-face new-name t)) | ||
| 287 | (set-face-font new-face (face-font old-face frame) frame) | ||
| 288 | (set-face-foreground new-face (face-foreground old-face frame) frame) | ||
| 289 | (set-face-background new-face (face-background old-face frame) frame) | ||
| 290 | (set-face-background-pixmap | ||
| 291 | new-face (face-background-pixmap old-face frame) frame) | ||
| 292 | (set-face-underline-p new-face (face-underline-p old-face frame) | ||
| 293 | frame)) | ||
| 294 | new-face)) | ||
| 295 | |||
| 296 | (defun face-equal (face1 face2 &optional frame) | ||
| 297 | "True if the faces FACE1 and FACE2 display in the the same way." | ||
| 298 | (setq face1 (internal-get-face face1 frame) | ||
| 299 | face2 (internal-get-face face2 frame)) | ||
| 300 | (and (equal (face-foreground face1 frame) (face-foreground face2 frame)) | ||
| 301 | (equal (face-background face1 frame) (face-background face2 frame)) | ||
| 302 | (equal (face-font face1 frame) (face-font face2 frame)) | ||
| 303 | (equal (face-background-pixmap face1 frame) | ||
| 304 | (face-background-pixmap face2 frame)))) | ||
| 305 | |||
| 306 | (defun face-differs-from-default-p (face &optional frame) | ||
| 307 | "True if face FACE displays differently from the default face, on FRAME. | ||
| 308 | A face is considered to be ``the same'' as the default face if it is | ||
| 309 | actually specified in the same way (equivalent fonts, etc) or if it is | ||
| 310 | fully unspecified, and thus inherits the attributes of any face it | ||
| 311 | is displayed on top of." | ||
| 312 | (let ((default (internal-get-face 'default frame))) | ||
| 313 | (setq face (internal-get-face face frame)) | ||
| 314 | (not (and (or (equal (face-foreground default frame) | ||
| 315 | (face-foreground face frame)) | ||
| 316 | (null (face-foreground face frame))) | ||
| 317 | (or (equal (face-background default frame) | ||
| 318 | (face-background face frame)) | ||
| 319 | (null (face-background face frame))) | ||
| 320 | (or (equal (face-font default frame) (face-font face frame)) | ||
| 321 | (null (face-font face frame))) | ||
| 322 | (or (equal (face-background-pixmap default frame) | ||
| 323 | (face-background-pixmap face frame)) | ||
| 324 | (null (face-background-pixmap face frame))) | ||
| 325 | (equal (face-underline-p default frame) | ||
| 326 | (face-underline-p face frame)) | ||
| 327 | )))) | ||
| 328 | |||
| 329 | |||
| 330 | (defun invert-face (face &optional frame) | ||
| 331 | "Swap the foreground and background colors of face FACE. | ||
| 332 | If the face doesn't specify both foreground and background, then | ||
| 333 | its foreground and background are set to the background and | ||
| 334 | foreground of the default face." | ||
| 335 | (interactive (list (read-face-name "Invert face: "))) | ||
| 336 | (setq face (internal-get-face face frame)) | ||
| 337 | (let ((fg (face-foreground face frame)) | ||
| 338 | (bg (face-background face frame))) | ||
| 339 | (if (or fg bg) | ||
| 340 | (progn | ||
| 341 | (set-face-foreground face bg frame) | ||
| 342 | (set-face-background face fg frame)) | ||
| 343 | (set-face-foreground face (face-background 'default frame) frame) | ||
| 344 | (set-face-background face (face-foreground 'default frame) frame))) | ||
| 345 | face) | ||
| 346 | |||
| 347 | |||
| 348 | (defun internal-try-face-font (face font &optional frame) | ||
| 349 | "Like set-face-font, but returns nil on failure instead of an error." | ||
| 350 | (condition-case () | ||
| 351 | (set-face-font face font frame) | ||
| 352 | (error nil))) | ||
| 353 | |||
| 354 | |||
| 355 | (defun set-default-font (font) | ||
| 356 | "Sets the font used for normal text and the modeline to FONT in all frames. | ||
| 357 | For finer-grained control, use set-face-font." | ||
| 358 | (interactive (list (read-string "Set default font: " | ||
| 359 | (face-font 'default (selected-frame))))) | ||
| 360 | (set-face-font 'default font) | ||
| 361 | (set-face-font 'modeline font)) | ||
| 362 | |||
| 363 | ;; Manipulating font names. | ||
| 364 | |||
| 365 | (defconst x-font-regexp nil) | ||
| 366 | (defconst x-font-regexp-head nil) | ||
| 367 | (defconst x-font-regexp-weight nil) | ||
| 368 | (defconst x-font-regexp-slant nil) | ||
| 369 | |||
| 370 | ;;; Regexps matching font names in "Host Portable Character Representation." | ||
| 371 | ;;; | ||
| 372 | (let ((- "[-?]") | ||
| 373 | (foundry "[^-]+") | ||
| 374 | (family "[^-]+") | ||
| 375 | (weight "\\(bold\\|demibold\\|medium\\)") ; 1 | ||
| 376 | ; (weight\? "\\(\\*\\|bold\\|demibold\\|medium\\|\\)") ; 1 | ||
| 377 | (weight\? "\\([^-]*\\)") ; 1 | ||
| 378 | (slant "\\([ior]\\)") ; 2 | ||
| 379 | ; (slant\? "\\([ior?*]?\\)") ; 2 | ||
| 380 | (slant\? "\\([^-]?\\)") ; 2 | ||
| 381 | ; (swidth "\\(\\*\\|normal\\|semicondensed\\|\\)") ; 3 | ||
| 382 | (swidth "\\([^-]*\\)") ; 3 | ||
| 383 | ; (adstyle "\\(\\*\\|sans\\|\\)") ; 4 | ||
| 384 | (adstyle "[^-]*") ; 4 | ||
| 385 | (pixelsize "[0-9]+") | ||
| 386 | (pointsize "[0-9][0-9]+") | ||
| 387 | (resx "[0-9][0-9]+") | ||
| 388 | (resy "[0-9][0-9]+") | ||
| 389 | (spacing "[cmp?*]") | ||
| 390 | (avgwidth "[0-9]+") | ||
| 391 | (registry "[^-]+") | ||
| 392 | (encoding "[^-]+") | ||
| 393 | ) | ||
| 394 | (setq x-font-regexp | ||
| 395 | (concat "\\`\\*?[-?*]" | ||
| 396 | foundry - family - weight\? - slant\? - swidth - adstyle - | ||
| 397 | pixelsize - pointsize - resx - resy - spacing - registry - | ||
| 398 | encoding "[-?*]\\*?\\'" | ||
| 399 | )) | ||
| 400 | (setq x-font-regexp-head | ||
| 401 | (concat "\\`[-?*]" foundry - family - weight\? - slant\? | ||
| 402 | "\\([-*?]\\|\\'\\)")) | ||
| 403 | (setq x-font-regexp-slant (concat - slant -)) | ||
| 404 | (setq x-font-regexp-weight (concat - weight -)) | ||
| 405 | nil) | ||
| 406 | |||
| 407 | (defun x-frob-font-weight (font which) | ||
| 408 | (if (or (string-match x-font-regexp font) | ||
| 409 | (string-match x-font-regexp-head font) | ||
| 410 | (string-match x-font-regexp-weight font)) | ||
| 411 | (concat (substring font 0 (match-beginning 1)) which | ||
| 412 | (substring font (match-end 1))) | ||
| 413 | nil)) | ||
| 414 | |||
| 415 | (defun x-frob-font-slant (font which) | ||
| 416 | (cond ((or (string-match x-font-regexp font) | ||
| 417 | (string-match x-font-regexp-head font)) | ||
| 418 | (concat (substring font 0 (match-beginning 2)) which | ||
| 419 | (substring font (match-end 2)))) | ||
| 420 | ((string-match x-font-regexp-slant font) | ||
| 421 | (concat (substring font 0 (match-beginning 1)) which | ||
| 422 | (substring font (match-end 1)))) | ||
| 423 | (t nil))) | ||
| 424 | |||
| 425 | |||
| 426 | (defun x-make-font-bold (font) | ||
| 427 | "Given an X font specification, this attempts to make a `bold' version | ||
| 428 | of it. If it fails, it returns nil." | ||
| 429 | (x-frob-font-weight font "bold")) | ||
| 430 | |||
| 431 | (defun x-make-font-demibold (font) | ||
| 432 | "Given an X font specification, this attempts to make a `demibold' version | ||
| 433 | of it. If it fails, it returns nil." | ||
| 434 | (x-frob-font-weight font "demibold")) | ||
| 435 | |||
| 436 | (defun x-make-font-unbold (font) | ||
| 437 | "Given an X font specification, this attempts to make a non-bold version | ||
| 438 | of it. If it fails, it returns nil." | ||
| 439 | (x-frob-font-weight font "medium")) | ||
| 440 | |||
| 441 | (defun x-make-font-italic (font) | ||
| 442 | "Given an X font specification, this attempts to make an `italic' version | ||
| 443 | of it. If it fails, it returns nil." | ||
| 444 | (x-frob-font-slant font "i")) | ||
| 445 | |||
| 446 | (defun x-make-font-oblique (font) ; you say tomayto... | ||
| 447 | "Given an X font specification, this attempts to make an `italic' version | ||
| 448 | of it. If it fails, it returns nil." | ||
| 449 | (x-frob-font-slant font "o")) | ||
| 450 | |||
| 451 | (defun x-make-font-unitalic (font) | ||
| 452 | "Given an X font specification, this attempts to make a non-italic version | ||
| 453 | of it. If it fails, it returns nil." | ||
| 454 | (x-frob-font-slant font "r")) | ||
| 455 | |||
| 456 | |||
| 457 | ;;; non-X-specific interface | ||
| 458 | |||
| 459 | (defun make-face-bold (face &optional frame) | ||
| 460 | "Make the font of the given face be bold, if possible. | ||
| 461 | Returns nil on failure." | ||
| 462 | (interactive (list (read-face-name "Make which face bold: "))) | ||
| 463 | (let ((ofont (face-font face frame))) | ||
| 464 | (if (null frame) | ||
| 465 | (let ((frames (frame-list))) | ||
| 466 | (while frames | ||
| 467 | (make-face-bold face (car frames)) | ||
| 468 | (setq frames (cdr frames)))) | ||
| 469 | (setq face (internal-get-face face frame)) | ||
| 470 | (let ((font (or (face-font face frame) | ||
| 471 | (face-font face t) | ||
| 472 | (face-font 'default frame))) | ||
| 473 | f2) | ||
| 474 | (or (and (setq f2 (x-make-font-bold font)) | ||
| 475 | (try-face-font face f2)) | ||
| 476 | (and (setq f2 (x-make-font-demibold font)) | ||
| 477 | (try-face-font face f2))))) | ||
| 478 | (not (equal ofont (face-font face))))) | ||
| 479 | |||
| 480 | (defun make-face-italic (face &optional frame) | ||
| 481 | "Make the font of the given face be italic, if possible. | ||
| 482 | Returns nil on failure." | ||
| 483 | (interactive (list (read-face-name "Make which face italic: "))) | ||
| 484 | (let ((ofont (face-font face frame))) | ||
| 485 | (if (null frame) | ||
| 486 | (let ((frames (frame-list))) | ||
| 487 | (while frames | ||
| 488 | (make-face-italic face (car frames)) | ||
| 489 | (setq frames (cdr frames)))) | ||
| 490 | (setq face (internal-get-face face frame)) | ||
| 491 | (let ((font (or (face-font face frame) | ||
| 492 | (face-font face t) | ||
| 493 | (face-font 'default frame))) | ||
| 494 | f2) | ||
| 495 | (or (and (setq f2 (x-make-font-italic font)) | ||
| 496 | (try-face-font face f2)) | ||
| 497 | (and (setq f2 (x-make-font-oblique font)) | ||
| 498 | (try-face-font face f2))))) | ||
| 499 | (not (equal ofont (face-font face))))) | ||
| 500 | |||
| 501 | (defun make-face-bold-italic (face &optional frame) | ||
| 502 | "Make the font of the given face be bold and italic, if possible. | ||
| 503 | Returns nil on failure." | ||
| 504 | (interactive (list (read-face-name "Make which face bold-italic: "))) | ||
| 505 | (let ((ofont (face-font face frame))) | ||
| 506 | (if (null frame) | ||
| 507 | (let ((frames (frame-list))) | ||
| 508 | (while frames | ||
| 509 | (make-face-bold-italic face (car frames)) | ||
| 510 | (setq frames (cdr frames)))) | ||
| 511 | (setq face (internal-get-face face frame)) | ||
| 512 | (let ((font (or (face-font face frame) | ||
| 513 | (face-font face t) | ||
| 514 | (face-font 'default frame))) | ||
| 515 | f2 f3) | ||
| 516 | (or (and (setq f2 (x-make-font-italic font)) | ||
| 517 | (not (equal font f2)) | ||
| 518 | (setq f3 (x-make-font-bold f2)) | ||
| 519 | (not (equal f2 f3)) | ||
| 520 | (try-face-font face f3)) | ||
| 521 | (and (setq f2 (x-make-font-oblique font)) | ||
| 522 | (not (equal font f2)) | ||
| 523 | (setq f3 (x-make-font-bold f2)) | ||
| 524 | (not (equal f2 f3)) | ||
| 525 | (try-face-font face f3)) | ||
| 526 | (and (setq f2 (x-make-font-italic font)) | ||
| 527 | (not (equal font f2)) | ||
| 528 | (setq f3 (x-make-font-demibold f2)) | ||
| 529 | (not (equal f2 f3)) | ||
| 530 | (try-face-font face f3)) | ||
| 531 | (and (setq f2 (x-make-font-oblique font)) | ||
| 532 | (not (equal font f2)) | ||
| 533 | (setq f3 (x-make-font-demibold f2)) | ||
| 534 | (not (equal f2 f3)) | ||
| 535 | (try-face-font face f3))))) | ||
| 536 | (not (equal ofont (face-font face frame))))) | ||
| 537 | |||
| 538 | (defun make-face-unbold (face &optional frame) | ||
| 539 | "Make the font of the given face be non-bold, if possible. | ||
| 540 | Returns nil on failure." | ||
| 541 | (interactive (list (read-face-name "Make which face non-bold: "))) | ||
| 542 | (let ((ofont (face-font face frame))) | ||
| 543 | (if (null frame) | ||
| 544 | (let ((frames (frame-list))) | ||
| 545 | (while frames | ||
| 546 | (make-face-unbold face (car frames)) | ||
| 547 | (setq frames (cdr frames)))) | ||
| 548 | (setq face (internal-get-face face frame)) | ||
| 549 | (let ((font (x-make-font-unbold | ||
| 550 | (or (face-font face frame) | ||
| 551 | (face-font face t) | ||
| 552 | (face-font 'default frame))))) | ||
| 553 | (if font (try-face-font face font)))) | ||
| 554 | (not (equal ofont (face-font face frame))))) | ||
| 555 | |||
| 556 | (defun make-face-unitalic (face &optional frame) | ||
| 557 | "Make the font of the given face be non-italic, if possible. | ||
| 558 | Returns nil on failure." | ||
| 559 | (interactive (list (read-face-name "Make which face non-italic: "))) | ||
| 560 | (let ((ofont (face-font face frame))) | ||
| 561 | (if (null frame) | ||
| 562 | (let ((frames (frame-list))) | ||
| 563 | (while frames | ||
| 564 | (make-face-unitalic face (car frames)) | ||
| 565 | (setq frames (cdr frames)))) | ||
| 566 | (setq face (internal-get-face face frame)) | ||
| 567 | (let ((font (x-make-font-unitalic | ||
| 568 | (or (face-font face frame) | ||
| 569 | (face-font face t) | ||
| 570 | (face-font 'default frame))))) | ||
| 571 | (if font (try-face-font face font)))) | ||
| 572 | (not (equal ofont (face-font face frame))))) | ||
| 573 | |||
| 574 | |||
| 575 | |||
| 576 | |||
| 577 | ;;; Make the builtin faces; the C code knows these as faces 0, 1, and 2, | ||
| 578 | ;;; respectively, so they must be the first three faces made. | ||
| 579 | |||
| 580 | (if (internal-find-face 'default) | ||
| 581 | nil | ||
| 582 | (make-face 'default) | ||
| 583 | (make-face 'modeline) | ||
| 584 | (make-face 'highlight) | ||
| 585 | ;; | ||
| 586 | ;; These aren't really special in any way, but they're nice to have around. | ||
| 587 | ;; The X-specific code is clever at them. | ||
| 588 | ;; | ||
| 589 | (make-face 'bold) | ||
| 590 | (make-face 'italic) | ||
| 591 | (make-face 'bold-italic) | ||
| 592 | (make-face 'primary-selection) | ||
| 593 | (make-face 'secondary-selection)) | ||
| 594 | |||
| 595 | ;;; This really belongs in setting a frame's own font. | ||
| 596 | ;;; ;; | ||
| 597 | ;;; ;; No font specified in the resource database; try to cope. | ||
| 598 | ;;; ;; | ||
| 599 | ;;; (internal-try-face-font default "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*" | ||
| 600 | ;;; frame) | ||
| 601 | ;;; (internal-try-face-font default "-*-courier-*-r-*-*-*-120-*-*-*-*-iso8859-*" | ||
| 602 | ;;; frame) | ||
| 603 | ;;; (internal-try-face-font default "-*-*-medium-r-*-*-*-120-*-*-m-*-iso8859-*" frame) | ||
| 604 | ;;; (internal-try-face-font default "-*-*-medium-r-*-*-*-120-*-*-c-*-iso8859-*" frame) | ||
| 605 | ;;; (internal-try-face-font default "-*-*-*-r-*-*-*-120-*-*-m-*-iso8859-*" frame) | ||
| 606 | ;;; (internal-try-face-font default "-*-*-*-r-*-*-*-120-*-*-c-*-iso8859-*" frame) | ||
| 607 | ;;; (internal-try-face-font default "-*-*-*-r-*-*-*-120-*-*-*-*-iso8859-*" frame) | ||
| 608 | |||
| 609 | |||
| 610 | ;;; This is called from make-screen-initial-faces to make sure that the | ||
| 611 | ;;; "default" and "modeline" faces for this screen have enough attributes | ||
| 612 | ;;; specified for emacs to be able to display anything on it. This had | ||
| 613 | ;;; better not signal an error. | ||
| 614 | ;;; | ||
| 615 | (defun x-initialize-frame-faces (frame) | ||
| 616 | (or (face-differs-from-default-p 'bold frame) | ||
| 617 | (make-face-bold 'bold frame) | ||
| 618 | ;; if default font is bold, then make the `bold' face be unbold. | ||
| 619 | (make-face-unbold 'bold frame) | ||
| 620 | ;; otherwise the luser specified one of the bogus font names | ||
| 621 | (internal-x-complain-about-font 'bold) | ||
| 622 | ) | ||
| 623 | |||
| 624 | (or (face-differs-from-default-p 'italic frame) | ||
| 625 | (make-face-italic 'italic frame) | ||
| 626 | (progn | ||
| 627 | (make-face-bold 'italic frame) | ||
| 628 | (internal-x-complain-about-font 'italic)) | ||
| 629 | ) | ||
| 630 | |||
| 631 | (or (face-differs-from-default-p 'bold-italic frame) | ||
| 632 | (make-face-bold-italic 'bold-italic frame) | ||
| 633 | ;; if we couldn't get a bold-italic version, try just bold. | ||
| 634 | (make-face-bold 'bold-italic frame) | ||
| 635 | ;; if we couldn't get bold or bold-italic, then that's probably because | ||
| 636 | ;; the default font is bold, so make the `bold-italic' face be unbold. | ||
| 637 | (and (make-face-unbold 'bold-italic frame) | ||
| 638 | (make-face-italic 'bold-italic frame)) | ||
| 639 | ;; if that didn't work, try italic (can this ever happen? what the hell.) | ||
| 640 | (progn | ||
| 641 | (make-face-italic 'bold-italic frame) | ||
| 642 | ;; then bitch and moan. | ||
| 643 | (internal-x-complain-about-font 'bold-italic)) | ||
| 644 | ) | ||
| 645 | |||
| 646 | (or (face-differs-from-default-p 'highlight frame) | ||
| 647 | (condition-case () | ||
| 648 | (if (x-display-color-p) | ||
| 649 | (condition-case () | ||
| 650 | (set-face-background 'highlight "darkseagreen2" frame) | ||
| 651 | (error (set-face-background 'highlight "green" frame))) | ||
| 652 | (set-face-background-pixmap 'highlight "gray1" frame) | ||
| 653 | ) | ||
| 654 | (error (invert-face 'highlight frame)))) | ||
| 655 | |||
| 656 | (or (face-differs-from-default-p 'primary-selection frame) | ||
| 657 | (condition-case () | ||
| 658 | (if (x-display-color-p) | ||
| 659 | (set-face-background 'primary-selection "gray" frame) | ||
| 660 | (set-face-background-pixmap 'primary-selection "gray3" frame) | ||
| 661 | ) | ||
| 662 | (error (invert-face 'primary-selection frame)))) | ||
| 663 | |||
| 664 | (or (face-differs-from-default-p 'secondary-selection frame) | ||
| 665 | (condition-case () | ||
| 666 | (if (x-display-color-p) | ||
| 667 | (condition-case () | ||
| 668 | ;; some older X servers don't have this one. | ||
| 669 | (set-face-background 'secondary-selection "paleturquoise" | ||
| 670 | frame) | ||
| 671 | (error | ||
| 672 | (set-face-background 'secondary-selection "green" frame))) | ||
| 673 | (set-face-background-pixmap 'secondary-selection "gray1" frame) | ||
| 674 | ) | ||
| 675 | (error (invert-face 'secondary-selection frame)))) | ||
| 676 | |||
| 677 | (or (face-differs-from-default-p 'isearch frame) | ||
| 678 | (if (x-display-color-p) | ||
| 679 | (condition-case () | ||
| 680 | (set-face-background 'isearch "paleturquoise" frame) | ||
| 681 | (error | ||
| 682 | (condition-case () | ||
| 683 | (set-face-background 'isearch "green" frame) | ||
| 684 | (error nil)))) | ||
| 685 | nil) | ||
| 686 | (make-face-bold 'isearch frame) | ||
| 687 | ;; if default font is bold, then make the `isearch' face be unbold. | ||
| 688 | (make-face-unbold 'isearch frame)) | ||
| 689 | )) | ||
| 690 | |||
| 691 | (defun internal-x-complain-about-font (face) | ||
| 692 | (if (symbolp face) (setq face (symbol-name face))) | ||
| 693 | (message "%s: couldn't deduce %s %s version of %S\n" | ||
| 694 | invocation-name | ||
| 695 | (if (string-match "\\`[aeiouAEIOU]" face) "an" "a") | ||
| 696 | face | ||
| 697 | (face-font 'default)) | ||
| 698 | (sit-for 1)) | ||
| 699 | |||
| 700 | ;; Like x-create-frame but also set up the faces. | ||
| 701 | |||
| 702 | (defun x-create-frame-with-faces (&optional parameters) | ||
| 703 | (let* ((frame (x-create-frame parameters)) | ||
| 704 | (faces (copy-alist global-face-data)) | ||
| 705 | (rest faces) | ||
| 706 | default modeline) | ||
| 707 | (set-frame-face-alist frame faces) | ||
| 708 | |||
| 709 | ;; Copy the vectors that represent the faces. | ||
| 710 | ;; Also fill them in from X resources. | ||
| 711 | (while rest | ||
| 712 | (setcdr (car rest) (copy-sequence (cdr (car rest)))) | ||
| 713 | (make-face-x-resource-intenal (cdr (car rest)) frame t) | ||
| 714 | (setq rest (cdr rest))) | ||
| 715 | |||
| 716 | (setq default (internal-get-face 'default frame) | ||
| 717 | modeline (internal-get-face 'modeline frame)) | ||
| 718 | |||
| 719 | (x-initialize-frame-faces frame) | ||
| 720 | |||
| 721 | ;; Make sure the modeline face is fully qualified. | ||
| 722 | (if (and (not (face-font modeline frame)) (face-font default frame)) | ||
| 723 | (set-face-font modeline (face-font default frame) frame)) | ||
| 724 | (if (and (not (face-background modeline frame)) | ||
| 725 | (face-background default frame)) | ||
| 726 | (set-face-background modeline (face-background default frame) frame)) | ||
| 727 | (if (and (not (face-foreground modeline frame)) | ||
| 728 | (face-foreground default frame)) | ||
| 729 | (set-face-foreground modeline (face-foreground default frame) frame)) | ||
| 730 | frame)) | ||
| 731 | |||
| 732 | (setq frame-creation-function 'x-create-frame-with-faces) | ||
| 733 | |||
| 734 | ;; Set up the faces of all existing frames. | ||
| 735 | (let ((frames (frame-list))) | ||
| 736 | (while frames | ||
| 737 | (x-initialize-frame-faces (car frames)) | ||
| 738 | (setq frames (cdr frames)))) | ||
| 739 | |||
| 740 | ;;; faces.el ends here | ||
diff --git a/lisp/help-macro.el b/lisp/help-macro.el new file mode 100644 index 00000000000..fa8bf07e62e --- /dev/null +++ b/lisp/help-macro.el | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | ;;; help-screen.el --- Makes command line help such as help-for-help | ||
| 2 | |||
| 3 | ;; Copyright (C) 1993 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Lynn Slater <lrs@indetech.com> | ||
| 6 | ;; Created: : Mon Oct 1 11:42:39 1990 | ||
| 7 | ;; Adapted-By: ESR | ||
| 8 | ;; Last Modified By: Lynn Slater x2048 | ||
| 9 | ;; Last Modified On: Mon Sep 23 14:40:19 1991 | ||
| 10 | |||
| 11 | ;; This file is part of GNU Emacs. | ||
| 12 | |||
| 13 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 14 | ;; it under the terms of the GNU General Public License as published by | ||
| 15 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 16 | ;; any later version. | ||
| 17 | |||
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | ;; GNU General Public License for more details. | ||
| 22 | |||
| 23 | ;; You should have received a copy of the GNU General Public License | ||
| 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 25 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | |||
| 27 | ;;; Commentary: | ||
| 28 | ;; | ||
| 29 | ;; This file supplies the macro make-help-screen which constructs | ||
| 30 | ;; single character dispatching with browsable help such as that provided | ||
| 31 | ;; by help-for-help. This can be used to make many modes easier to use; for | ||
| 32 | ;; example, the Gnu Emacs Empire Tool uses this for every "nested" mode map | ||
| 33 | ;; called from the main mode map. | ||
| 34 | |||
| 35 | ;;-> *********************** Example of use ********************************* | ||
| 36 | |||
| 37 | ;;->(make-help-screen help-for-empire-redistribute-map | ||
| 38 | ;;-> "c:civ m:mil p:population f:food ?" | ||
| 39 | ;;-> "You have discovered the GEET redistribution commands | ||
| 40 | ;;-> From here, you can use the following options: | ||
| 41 | ;;-> | ||
| 42 | ;;->c Redistribute civs from overfull sectors into connected underfull ones | ||
| 43 | ;;-> The functions typically named by empire-ideal-civ-fcn control | ||
| 44 | ;;-> based in part on empire-sector-civ-threshold | ||
| 45 | ;;->m Redistribute military using levels given by empire-ideal-mil-fcn | ||
| 46 | ;;->p Redistribute excess population to highways for max pop growth | ||
| 47 | ;;-> Excess is any sector so full babies will not be born. | ||
| 48 | ;;->f Even out food on highways to highway min and leave levels | ||
| 49 | ;;-> This is good to pump max food to all warehouses/dist pts | ||
| 50 | ;;-> | ||
| 51 | ;;-> | ||
| 52 | ;;->Use \\[help-for-empire-redistribute-map] for help on redistribution. | ||
| 53 | ;;->Use \\[help-for-empire-extract-map] for help on data extraction. | ||
| 54 | ;;->Please use \\[describe-key] to find out more about any of the other keys." | ||
| 55 | ;;-> empire-shell-redistribute-map) | ||
| 56 | |||
| 57 | ;;-> (define-key c-mp "\C-h" 'help-for-empire-redistribute-map) | ||
| 58 | ;;-> (define-key c-mp help-character 'help-for-empire-redistribute-map) | ||
| 59 | |||
| 60 | ;;; Change Log: | ||
| 61 | ;; | ||
| 62 | ;; 22-Jan-1991 Lynn Slater x2048 | ||
| 63 | ;; Last Modified: Mon Oct 1 11:43:52 1990 #3 (Lynn Slater) | ||
| 64 | ;; documented better | ||
| 65 | |||
| 66 | ;;; Code: | ||
| 67 | |||
| 68 | (provide 'help-screen) | ||
| 69 | (require 'backquote) | ||
| 70 | |||
| 71 | (defmacro make-help-screen (fname help-line help-text helped-map) | ||
| 72 | "Constructs function FNAME that when invoked shows HELP-LINE and if a help | ||
| 73 | character is requested, shows HELP-TEXT. The user is prompted for a character | ||
| 74 | from the HELPED-MAP and the corresponding interactive function is executed." | ||
| 75 | (` (defun (, fname) () | ||
| 76 | (, help-text) | ||
| 77 | (interactive) | ||
| 78 | (let ((line-prompt | ||
| 79 | (substitute-command-keys (, help-line)))) | ||
| 80 | (message line-prompt) | ||
| 81 | (let ((char (read-char))) | ||
| 82 | (if (or (= char ??) (= char help-char)) | ||
| 83 | (save-window-excursion | ||
| 84 | (switch-to-buffer-other-window "*Help*") | ||
| 85 | (erase-buffer) | ||
| 86 | (insert (documentation (quote (, fname)))) | ||
| 87 | (goto-char (point-min)) | ||
| 88 | (while (memq char (cons help-char '(?? ?\C-v ?\ ?\177 ?\M-v))) | ||
| 89 | (if (memq char '(?\C-v ?\ )) | ||
| 90 | (scroll-up)) | ||
| 91 | (if (memq char '(?\177 ?\M-v)) | ||
| 92 | (scroll-down)) | ||
| 93 | (message "%s%s: " | ||
| 94 | line-prompt | ||
| 95 | (if (pos-visible-in-window-p (point-max)) | ||
| 96 | "" " or Space to scroll")) | ||
| 97 | (let ((cursor-in-echo-area t)) | ||
| 98 | (setq char (read-char)))))) | ||
| 99 | (let ((defn (cdr (assq (downcase char) (, helped-map))))) | ||
| 100 | (if defn | ||
| 101 | (if (keymapp defn) | ||
| 102 | (error "sorry, this command cannot be run from the help screen. Start over.") | ||
| 103 | (call-interactively defn)) | ||
| 104 | (ding)))))) | ||
| 105 | )) | ||
| 106 | |||
| 107 | ;;; help-screen.el | ||
| 108 | |||