;;; vm-summary-faces.el --- faces support for VM summary buffers ;; ;; Copyright (C) 2001 Robert Fenk ;; ;; Author: Robert Fenk ;; Status: Tested with XEmacs 21.4.15 & VM 7.18 ;; Keywords: VM ;; X-URL: http://www.robf.de/Hacking/elisp ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License along ;; with this program; if not, write to the Free Software Foundation, Inc., ;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ;;; Commentary: ;; ;; to use this add the following line to your ~/.vm file ;; ;; (require 'vm-summary-faces) ;; (vm-summary-faces-mode 1) ;; (defgroup vm nil "VM" :group 'mail) (defgroup vm-summary-faces nil "VM additional virtual folder selectors and functions." :group 'vm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (eval-when-compile (require 'cl)) (eval-and-compile (require 'advice) (require 'vm-summary) (require 'vm-virtual)) (eval-and-compile (if vm-xemacs-p (require 'overlay))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defface vm-summary-selected-face '((t (:bold on))) "The face used in VM Summary buffers for the selected message." :group 'vm-summary-faces) (defface vm-summary-marked-face '((((type x)) (:foreground "red3"))) "The face used in VM Summary buffers for marked messages." :group 'vm-summary-faces) (defface vm-summary-deleted-face '((t (:foreground "grey50" :strikethru t))) "The face used in VM Summary buffers for deleted messages." :group 'vm-summary-faces) (defface vm-summary-new-face '((t (:foreground "blue"))) "The face used in VM Summary buffers for new messages." :group 'vm-summary-faces) (defface vm-summary-unread-face '((t (:foreground "blue4"))) "The face used in VM Summary buffers for unread messages." :group 'vm-summary-faces) (defface vm-summary-filed-face '((t (:foreground "green4" :underline t))) "The face used in VM Summary buffers for filed messages." :group 'vm-summary-faces) (defface vm-summary-written-face '((t (:foreground "green4" :underline t))) "The face used in VM Summary buffers for written messages." :group 'vm-summary-faces) (defface vm-summary-replied-face '((t (:foreground "grey50"))) "The face used in VM Summary buffers for replied messages." :group 'vm-summary-faces) (defface vm-summary-forwarded-face '((t (:foreground "grey50"))) "The face used in VM Summary buffers for forwarded messages." :group 'vm-summary-faces) (defface vm-summary-edited-face nil "The face used in VM Summary buffers for edited messages." :group 'vm-summary-faces) (defface vm-summary-redistributed-face '((t (:foreground "grey50"))) "The face used in VM Summary buffers for redistributed messages." :group 'vm-summary-faces) (defface vm-summary-outgoing-face '((t (:foreground "grey50"))) "The face used in VM Summary buffers for outgoing messages." :group 'vm-summary-faces) (defface vm-summary-high-priority-face '((t (:foreground "red"))) "The face used in VM Summary buffers for high-priority messages." :group 'vm-summary-faces) (defface vm-summary-default-face nil "The default face used in VM Summary buffers." :group 'vm-summary-faces) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defcustom vm-summary-faces-alist '( ((or (header "Priority: urgent") (header "Importance: high") (header "X-Priority: 1") (label "!") (header "X-VM-postponed-data:")) vm-summary-high-priority-face) ((deleted) vm-summary-deleted-face) ((new) vm-summary-new-face) ((unread) vm-summary-unread-face) ((filed) vm-summary-filed-face) ((written) vm-summary-written-face) ((replied) vm-summary-replied-face) ((forwarded) vm-summary-forwarded-face) ((edited) vm-summary-edited-face) ((redistributed) vm-summary-redistributed-face) ((marked) vm-summary-marked-face) ((outgoing) vm-summary-outgoing-face) ((any) vm-summary-default-face)) "Alist of virtual folder conditions and corresponding faces. Order matters. The first matching one will be used as face." :type '(repeat (cons (sexp) (face))) :group 'vm-summary-faces) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (eval-and-compile (if (fboundp 'mapcar-extents) (defun vm-summary-faces-list-extents () (mapcar-extents 'identity)) (defun vm-summary-faces-list-extents () (let ((o (overlay-lists))) (nconc (car o) (cdr o)))))) (defvar vm-summary-faces-hide nil "Last face hidden by `vm-summary-faces-hide'.") ;;;###autoload (defun vm-summary-faces-hide (&optional face) "Toggle visibility of messages with FACE. When called with a prefix arg prompt for the face." (interactive "P") (if (and (listp face) (numberp (car face))) (setq face (completing-read "Face name: " (mapcar (lambda (f) (list (format "%s" (caar f)))) vm-summary-faces-alist) nil t "deleted"))) (setq face (or face vm-summary-faces-hide "deleted")) (vm-summarize) (vm-select-folder-buffer) (set-buffer vm-summary-buffer) (let ((extents (vm-summary-faces-list-extents)) (face (intern (concat "vm-summary-" face "-face"))) x) (while extents (setq x (car extents)) (when (equal face (vm-extent-property x 'face)) (vm-set-extent-property x 'invisible (not (vm-extent-property x 'invisible)))) (setq extents (cdr extents))))) ;;;###autoload (defun vm-summary-faces-add (msg) "Add a face to a summary entry according to `vm-summary-faces-alist'." (let ((faces vm-summary-faces-alist) (x (or (vm-su-summary-mouse-track-overlay-of msg) (vm-extent-at (vm-su-start-of msg)) (vm-extent-at (vm-su-end-of msg))))) (while faces (when (apply 'vm-vs-or msg (list (caar faces))) (vm-set-extent-property x 'face (cadar faces)) (setq faces nil)) (setq faces (cdr faces))))) (defun vm-summary-faces-destroy () "Removes the face from all summary entries." (let ((extents (vm-summary-faces-list-extents)) x) (while extents (setq x (car extents)) (vm-set-extent-property x 'face nil) (setq extents (cdr extents))))) (defvar vm-summary-faces-mode nil) ;;;###autoload (defun vm-summary-faces-mode (&optional arg) "Toggle `vm-summary-faces-mode'. Remove/add the `vm-summary-fontify-buffer' hook from the hook variable `vm-summary-mode-hook' and when in a summary buffer, then toggle the `font-lock-mode'." (interactive "P") (if (null arg) (setq vm-summary-faces-mode (not vm-summary-faces-mode)) (if (> (prefix-numeric-value arg) 0) (setq vm-summary-faces-mode t) (setq vm-summary-faces-mode nil))) (when (interactive-p) (message "VM summary faces mode is %s" (if vm-summary-faces-mode "on" "off"))) (if (memq major-mode '(vm-mode vm-virtual-mode vm-summary-mode vm-presentation-mode)) (save-excursion (vm-select-folder-buffer) (vm-summarize) (set-buffer vm-summary-buffer) (if vm-summary-faces-mode (let ((mp vm-message-list)) (while mp (vm-summary-faces-add (car mp)) (setq mp (cdr mp)))) (vm-summary-faces-destroy) (if vm-summary-overlay (vm-set-extent-property vm-summary-overlay 'face vm-summary-highlight-face)))))) (defadvice vm-mouse-set-mouse-track-highlight (after vm-summary-faces activate) (when (and vm-summary-faces-mode (eq major-mode 'vm-summary-mode) (boundp 'm) m) ;; FIXME there is a warning about a free variable here, sorry! (vm-summary-faces-add m))) (defun vm-summary-faces-fix-pointer () (if vm-summary-overlay (vm-set-extent-property vm-summary-overlay 'face (if vm-summary-faces-mode 'vm-summary-selected-face vm-summary-highlight-face)))) (add-hook 'vm-summary-pointer-update-hook 'vm-summary-faces-fix-pointer) (provide 'vm-summary-faces)