comparison lisp/facemenu.el @ 40275:113233ecd44a

(facemenu-unlisted-faces): Improve doc strings of t and nil values. (facemenu-set-face): Handle START and END interactively. (facemenu-set-foreground): Don't use a face; specify color directly. (facemenu-set-background): Likewise. (facemenu-set-face-from-menu): Doc fix. (facemenu-active-faces): Use face-attribute-vector to handle bare attributes not in faces. (facemenu-get-face): Don't handle face names fg:... and bg:... specially. (facemenu-add-new-face): New argument MENU. New way to handle adding colors to the color menus.
author Richard M. Stallman <rms@gnu.org>
date Wed, 24 Oct 2001 22:53:45 +0000
parents 6e075079aef3
children e14f2ec78074
comparison
equal deleted inserted replaced
40274:d2e0c5832e0d 40275:113233ecd44a
151 call `facemenu-update' to recalculate the menu contents. 151 call `facemenu-update' to recalculate the menu contents.
152 152
153 If this variable is t, no faces will be added to the menu. This is useful for 153 If this variable is t, no faces will be added to the menu. This is useful for
154 temporarily turning off the feature that automatically adds faces to the menu 154 temporarily turning off the feature that automatically adds faces to the menu
155 when they are created." 155 when they are created."
156 :type '(choice (const :tag "Don't add" t) 156 :type '(choice (const :tag "Don't add faces" t)
157 (const :tag "None" nil) 157 (const :tag "None (do add any face)" nil)
158 (repeat (choice symbol regexp))) 158 (repeat (choice symbol regexp)))
159 :group 'facemenu) 159 :group 'facemenu)
160 160
161 ;;;###autoload 161 ;;;###autoload
162 (defvar facemenu-face-menu 162 (defvar facemenu-face-menu
319 (facemenu-complete-face-list facemenu-keybindings))) 319 (facemenu-complete-face-list facemenu-keybindings)))
320 320
321 ;;;###autoload 321 ;;;###autoload
322 (defun facemenu-set-face (face &optional start end) 322 (defun facemenu-set-face (face &optional start end)
323 "Add FACE to the region or next character typed. 323 "Add FACE to the region or next character typed.
324 It will be added to the top of the face list; any faces lower on the list that 324 This adds FACE to the top of the face list; any faces lower on the list that
325 will not show through at all will be removed. 325 will not show through at all will be removed.
326 326
327 Interactively, the face to be used is read with the minibuffer. 327 Interactively, reads the face name with the minibuffer.
328 328
329 In the Transient Mark mode, if the region is active and there is no 329 If the region is active (normally true except in Transient Mark mode)
330 prefix argument, this command sets the region to the requested face. 330 and there is no prefix argument, this command sets the region to the
331 requested face.
331 332
332 Otherwise, this command specifies the face for the next character 333 Otherwise, this command specifies the face for the next character
333 inserted. Moving point or switching buffers before 334 inserted. Moving point or switching buffers before
334 typing a character to insert cancels the specification." 335 typing a character to insert cancels the specification."
335 (interactive (list (read-face-name "Use face"))) 336 (interactive (list (progn
336 (barf-if-buffer-read-only) 337 (barf-if-buffer-read-only)
338 (read-face-name "Use face"))
339 (if (and mark-active (not current-prefix-arg))
340 (region-beginning))
341 (if (and mark-active (not current-prefix-arg))
342 (region-end))))
337 (facemenu-add-new-face face) 343 (facemenu-add-new-face face)
338 (if (and mark-active (not current-prefix-arg)) 344 (facemenu-add-face face start end))
339 (let ((start (or start (region-beginning)))
340 (end (or end (region-end))))
341 (facemenu-add-face face start end))
342 (facemenu-add-face face)))
343 345
344 ;;;###autoload 346 ;;;###autoload
345 (defun facemenu-set-foreground (color &optional start end) 347 (defun facemenu-set-foreground (color &optional start end)
346 "Set the foreground COLOR of the region or next character typed. 348 "Set the foreground COLOR of the region or next character typed.
347 The color is prompted for. A face named `fg:color' is used \(or created). 349 The color is prompted for. A face named `fg:color' is used \(or created).
348 If the region is active, it will be set to the requested face. If 350
349 it is inactive \(even if mark-even-if-inactive is set) the next 351 If the region is active (normally true except in Transient Mark mode)
350 character that is typed \(via `self-insert-command') will be set to 352 and there is no prefix argument, this command sets the region to the
351 the selected face. Moving point or switching buffers before 353 requested face.
352 typing a character cancels the request." 354
353 (interactive (list (facemenu-read-color "Foreground color: "))) 355 Otherwise, this command specifies the face for the next character
354 (let ((face (intern (concat "fg:" color)))) 356 inserted. Moving point or switching buffers before
355 (or (facemenu-get-face face) 357 typing a character to insert cancels the specification."
356 (error "Unknown color: %s" color)) 358 (interactive (list (progn
357 (facemenu-set-face face start end))) 359 (barf-if-buffer-read-only)
360 (facemenu-read-color "Foreground color: "))
361 (if (and mark-active (not current-prefix-arg))
362 (region-beginning))
363 (if (and mark-active (not current-prefix-arg))
364 (region-end))))
365 (unless (color-defined-p color)
366 (message "Color `%s' undefined" color))
367 (facemenu-add-new-face color 'facemenu-foreground-menu)
368 (facemenu-add-face (list (list :foreground color)) start end))
358 369
359 ;;;###autoload 370 ;;;###autoload
360 (defun facemenu-set-background (color &optional start end) 371 (defun facemenu-set-background (color &optional start end)
361 "Set the background COLOR of the region or next character typed. 372 "Set the background COLOR of the region or next character typed.
362 The color is prompted for. A face named `bg:color' is used \(or created). 373 Reads the color in the minibuffer.
363 If the region is active, it will be set to the requested face. If 374
364 it is inactive \(even if mark-even-if-inactive is set) the next 375 If the region is active (normally true except in Transient Mark mode)
365 character that is typed \(via `self-insert-command') will be set to 376 and there is no prefix argument, this command sets the region to the
366 the selected face. Moving point or switching buffers before 377 requested face.
367 typing a character cancels the request." 378
368 (interactive (list (facemenu-read-color "Background color: "))) 379 Otherwise, this command specifies the face for the next character
369 (let ((face (intern (concat "bg:" color)))) 380 inserted. Moving point or switching buffers before
370 (or (facemenu-get-face face) 381 typing a character to insert cancels the specification."
371 (error "Unknown color: %s" color)) 382 (interactive (list (progn
372 (facemenu-set-face face start end))) 383 (barf-if-buffer-read-only)
384 (facemenu-read-color "Background color: "))
385 (if (and mark-active (not current-prefix-arg))
386 (region-beginning))
387 (if (and mark-active (not current-prefix-arg))
388 (region-end))))
389 (unless (color-defined-p color)
390 (message "Color `%s' undefined" color))
391 (facemenu-add-new-face color 'facemenu-background-menu)
392 (facemenu-add-face (list (list :background color)) start end))
373 393
374 ;;;###autoload 394 ;;;###autoload
375 (defun facemenu-set-face-from-menu (face start end) 395 (defun facemenu-set-face-from-menu (face start end)
376 "Set the FACE of the region or next character typed. 396 "Set the FACE of the region or next character typed.
377 This function is designed to be called from a menu; the face to use 397 This function is designed to be called from a menu; the face to use
378 is the menu item's name. 398 is the menu item's name.
379 399
380 In the Transient Mark mode, if the region is active and there is no 400 If the region is active (normally true except in Transient Mark mode)
381 prefix argument, this command sets the region to the requested face. 401 and there is no prefix argument, this command sets the region to the
402 requested face.
382 403
383 Otherwise, this command specifies the face for the next character 404 Otherwise, this command specifies the face for the next character
384 inserted. Moving point or switching buffers before 405 inserted. Moving point or switching buffers before
385 typing a character to insert cancels the specification." 406 typing a character to insert cancels the specification."
386 (interactive (list last-command-event 407 (interactive (list last-command-event
586 "Return from FACE-LIST those faces that would be used for display. 607 "Return from FACE-LIST those faces that would be used for display.
587 This means each face attribute is not specified in a face earlier in FACE-LIST 608 This means each face attribute is not specified in a face earlier in FACE-LIST
588 and such a face is therefore active when used to display text. 609 and such a face is therefore active when used to display text.
589 If the optional argument FRAME is given, use the faces in that frame; otherwise 610 If the optional argument FRAME is given, use the faces in that frame; otherwise
590 use the selected frame. If t, then the global, non-frame faces are used." 611 use the selected frame. If t, then the global, non-frame faces are used."
591 (let* ((mask-atts (copy-sequence (internal-get-face (car face-list) frame))) 612 (let* ((mask-atts (copy-sequence
613 (if (consp (car face-list))
614 (face-attribute-vector (car face-list))
615 (or (internal-lisp-face-p (car face-list) frame)
616 (check-face (car face-list))))))
592 (active-list (list (car face-list))) 617 (active-list (list (car face-list)))
593 (face-list (cdr face-list)) 618 (face-list (cdr face-list))
594 (mask-len (length mask-atts))) 619 (mask-len (length mask-atts)))
595 (while face-list 620 (while face-list
596 (if (let ((face-atts (internal-get-face (car face-list) frame)) 621 (if (let ((face-atts
597 (i mask-len) (useful nil)) 622 (if (consp (car face-list))
623 (face-attribute-vector (car face-list))
624 (or (internal-lisp-face-p (car face-list) frame)
625 (check-face (car face-list)))))
626 (i mask-len)
627 (useful nil))
598 (while (> (setq i (1- i)) 1) 628 (while (> (setq i (1- i)) 1)
599 (and (aref face-atts i) (not (aref mask-atts i)) 629 (and (not (memq (aref face-atts i) '(nil unspecified)))
630 (memq (aref mask-atts i) '(nil unspecified))
600 (aset mask-atts i (setq useful t)))) 631 (aset mask-atts i (setq useful t))))
601 useful) 632 useful)
602 (setq active-list (cons (car face-list) active-list))) 633 (setq active-list (cons (car face-list) active-list)))
603 (setq face-list (cdr face-list))) 634 (setq face-list (cdr face-list)))
604 (nreverse active-list))) 635 (nreverse active-list)))
605 636
606 (defun facemenu-get-face (symbol) 637 (defun facemenu-get-face (symbol)
607 "Make sure FACE exists. 638 "Make sure FACE exists.
608 If not, create it and add it to the appropriate menu. Return the SYMBOL. 639 If not, create it and add it to the appropriate menu. Return the SYMBOL."
609
610 If a window system is in use, and this function creates a face named
611 `fg:color', then it sets the foreground to that color. Likewise, `bg:color'
612 means to set the background. In either case, if the color is undefined,
613 no color is set and a warning is issued."
614 (let ((name (symbol-name symbol)) 640 (let ((name (symbol-name symbol))
615 foreground) 641 foreground)
616 (cond ((facep symbol)) 642 (cond ((facep symbol))
617 ((and (display-color-p)
618 (or (setq foreground (string-match "^fg:" name))
619 (string-match "^bg:" name)))
620 (let ((face (make-face symbol))
621 (color (substring name 3)))
622 (if (x-color-defined-p color)
623 (if foreground
624 (set-face-foreground face color)
625 (set-face-background face color))
626 (message "Color \"%s\" undefined" color))))
627 (t (make-face symbol)))) 643 (t (make-face symbol))))
628 symbol) 644 symbol)
629 645
630 (defun facemenu-add-new-face (face) 646 (defun facemenu-add-new-face (face-or-color &optional menu)
631 "Add a FACE to the appropriate Face menu. 647 "Add FACE-OR-COLOR (a face or a color) to the appropriate Face menu.
632 Automatically called when a new face is created." 648 If MENU is nil, then FACE-OR-COLOR is a face to be added
633 (let* ((name (symbol-name face)) 649 to `facemenu-face-menu'. If MENU is `facemenu-foreground-menu'
634 menu docstring 650 or `facemenu-background-menu', FACE-OR-COLOR is a color
651 to be added to the specified menu.
652
653 This is called whenever you create a new face."
654 (let* (name
655 symbol
656 docstring
635 (key (cdr (assoc face facemenu-keybindings))) 657 (key (cdr (assoc face facemenu-keybindings)))
636 function menu-val) 658 function menu-val)
637 (cond ((string-match "^fg:" name) 659 (if (symbolp face-or-color)
638 (setq name (substring name 3)) 660 (setq name (symbol-name face-or-color)
661 symbol face-or-color)
662 (setq name face-or-color
663 face (intern name)))
664 (cond ((eq menu 'facemenu-foreground-menu)
639 (setq docstring 665 (setq docstring
640 (format "Select foreground color %s for subsequent insertion." 666 (format "Select foreground color %s for subsequent insertion."
641 name)) 667 name)))
642 (setq menu 'facemenu-foreground-menu)) 668 ((eq menu 'facemenu-background-menu)
643 ((string-match "^bg:" name)
644 (setq name (substring name 3))
645 (setq docstring 669 (setq docstring
646 (format "Select background color %s for subsequent insertion." 670 (format "Select background color %s for subsequent insertion."
647 name)) 671 name)))
648 (setq menu 'facemenu-background-menu))
649 (t 672 (t
673 (setq menu 'facemenu-face-menu)
650 (setq docstring 674 (setq docstring
651 (format "Select face `%s' for subsequent insertion." 675 (format "Select face `%s' for subsequent insertion."
652 name)) 676 name))))
653 (setq menu 'facemenu-face-menu)))
654 (cond ((eq t facemenu-unlisted-faces)) 677 (cond ((eq t facemenu-unlisted-faces))
655 ((memq face facemenu-unlisted-faces)) 678 ((memq symbol facemenu-unlisted-faces))
656 ;; test against regexps in facemenu-unlisted-faces 679 ;; test against regexps in facemenu-unlisted-faces
657 ((let ((unlisted facemenu-unlisted-faces) 680 ((let ((unlisted facemenu-unlisted-faces)
658 (matched nil)) 681 (matched nil))
659 (while (and unlisted (not matched)) 682 (while (and unlisted (not matched))
660 (if (and (stringp (car unlisted)) 683 (if (and (stringp (car unlisted))
666 (setq function (intern (concat "facemenu-set-" name))) 689 (setq function (intern (concat "facemenu-set-" name)))
667 (fset function 690 (fset function
668 `(lambda () 691 `(lambda ()
669 ,docstring 692 ,docstring
670 (interactive) 693 (interactive)
671 (facemenu-set-face (quote ,face)))) 694 (facemenu-set-face (quote ,symbol))))
672 (define-key 'facemenu-keymap key (cons name function)) 695 (define-key 'facemenu-keymap key (cons name function))
673 (define-key menu key (cons name function))) 696 (define-key menu key (cons name function)))
674 ((facemenu-iterate ; check if equivalent face is already in the menu 697 ((facemenu-iterate ; check if equivalent face is already in the menu
675 (lambda (m) (and (listp m) 698 (lambda (m) (and (listp m)
676 (symbolp (car m)) 699 (symbolp (car m))
677 (face-equal (car m) face))) 700 (face-equal (car m) symbol)))
678 (cdr (symbol-function menu)))) 701 (cdr (symbol-function menu))))
679 (t ; No keyboard equivalent. Figure out where to put it: 702 (t ; No keyboard equivalent. Figure out where to put it:
680 (setq key (vector face) 703 (setq key (vector symbol)
681 function 'facemenu-set-face-from-menu 704 function 'facemenu-set-face-from-menu
682 menu-val (symbol-function menu)) 705 menu-val (symbol-function menu))
683 (if (and facemenu-new-faces-at-end 706 (if (and facemenu-new-faces-at-end
684 (> (length menu-val) 3)) 707 (> (length menu-val) 3))
685 (define-key-after menu-val key (cons name function) 708 (define-key-after menu-val key (cons name function)