;; ;; Sample zephyr mode configuration file. Should be usable for starting ;; zephyr mode under either gnu-emacs or lucid emacs, but the bulk of the ;; code here is tailored to take advantage of lucid emacs. ;; ;; Arup Mukherjee 3/93 (updated 6/95 for XEmacs 19.12) ;; This file defines 3 types of zephyr-windows under XEmacs. The ;; setups defined also work under gnu-emacs version 18, although they ;; won't show up in frames (emacspeak for "X windows") of their own. ;; The 3 functions defined are: ;; ;; zephyr-personal: ;; Creates a zephyr buffer that receives only person zgrams. It beeps ;; whenever a zgram comes in, and under xemacs, it deiconifies and raises ;; itself too. ;; ;; zephyr-nonpersonal: ;; Creates a buffer receiving everything but personal zgrams. It doesn't ;; beep, deiconify, or raise itself when a zgram comes in. Good if you want ;; to be subscribed to *, but only read when you have a moment to spare. ;; ;; zephyr-all: ;; Creates a single buffer receiving everything out there. Beeps only ;; when personal zgrams come in. Never deiconifies itself. ;; ;; This file is intended mainly as an example of what one can do with ;; XEmacs. If you don't like it, don't use it -- you can always load ;; zephyr.el directly and configure your setup as you please. If you do use ;; it, however, you may wish to define two variables before loading: ;; zephyr-aliases and zephyr-last-recipient ;; (see comments later for examples of their use) ;; ;; You may also wish to define M-z or some other key to finger the person ;; you're about to send a zgram to. An example of this is also provided in ;; a comment below. ;; ;; The following load-paths have been added to make this behave well ;; with the vendor xemacs on the fc* machines. Remove when the ;; xemacs misc collection or the elisp site-packages have been ported ;; to the new platform. ;; - Mahim Mishra, 8/05 (setq load-path (cons "/afs/cs/misc/xemacs/common/packages/001/lib/xemacs/site-packages/lisp/zephyr" load-path)) (setq load-path (cons "/afs/cs/misc/xemacs/common/packages/001/lib/xemacs/site-packages/lisp/hot-url" load-path)) (require 'zephyr) (require 'zephyr-url) ;;smiley (require 'zephyr-smiley) ;;zephyr faces ;(require 'zface) ;(autoload 'zf::enable-faces "zface" "Enable zephyr faces" t) ;(load-library "/afs/cs/user/andrzej/emacs/zface.elc") ;(autoload 'zf::enable-faces "zface" "Enable zephyr faces" t) ;(setq zf::autoenable-faces t ; zf::use-color t ; zf::face-sources '(server) ; zf::http-face-server "zarchive.srv.cs.cmu.edu" ; zf::http-face-port 25173) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; What my signature looks like: (setq zephyr-signature "holy batman") ;(add-hook 'zface-hooks ; '(lambda () (setq zf::custom-instances (cons "test" zf::custom-instances)))) ;; These delimit userids from messages. If you change these, you'll also have ;; change the regexps used in zephyr-personal, zephyr-nonpersonal, and ;; zephyr-all if you want those functions to choose faces properly (setq zephyr-receive-divider "::") ;; no newline because timestamper adds it (setq zephyr-receive-divider-regexp "::\\( \\[.*\\]\\)*$") (setq zephyr-send-divider "::\n") (setq zephyr-send-divider-regexp "::[ \t]*\n") (setq zephyr-auto-fill-on-send t) ;; auto-fill zgrams before sending (setq zephyr-lazy-beep-time 3600) ;; No minimum time limit between beeps (setq zephyr-beep-personal-only t);; Beep only for personal zgrams (setq zephyr-deiconify-on-receive ;; deiconify frame when a zgram comes in t) ;; print messages about authentication status (setq zephyr-unauth-string "[UNAUTH]") (setq zephyr-failed-string "[FORGED]") (setq zephyr-buffer-limit 100000) ;;Only notify for personal zgrams (setq zephyr-notify-with-message-p 'zephyr-personal-msg-p) ;;I like to use netscape instead of W3 (hot-url-use-netscape) ;; Turn auto-fill-mode on for zephyr buffers ;; -- set paragraph-separate so that fill-paragraph will work properly ;; with the send/receiver dividers that have newlines in them (if (fboundp 'add-hook) (add-hook 'zephyr-mode-hook '(lambda () (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) (auto-fill-mode 1))) ;; for the benefit of emacs 18 (setq zephyr-mode-hook '(lambda () (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) (auto-fill-mode 1)))) ;; zephyr-send-function used to be called zephyr-send-hook (setq zephyr-send-function ;; Insert a "To: " list on zgrams with 'zephyr-send-show-multiple) ;; multiple recipients ;; originally from Nat, worked over a bit by allbery (defun zephyr-munge-cyrus-notifications (msg) "Munge zephyrgrams from Cyrus into a more pleasing and shorter form." (if (and (eq (cdr (assq 'class msg)) 'MAIL) (string-match "^From:[ \t]*\\([^\n]*\\)\n\\(Subject:[ \t]*\\([^\n]*\\)\\)?" (cdr (assq 'print-as msg)))) (let* ((text (cdr (assq 'print-as msg))) (sender (concat (match-string 1 text))) (subj (or (match-string 3 text) "[no subject]")) banner) ;; clean up the sender address (if (string-match "<\\([^>]+\\)>" sender) (setq sender (match-string 1 sender)) (while (string-match "^\\(.*\\)\\([ \t]*\\)([^\)]*)\\([ \t]*\\)\\(.*\\)$" sender) (let ((pre (match-string 1 sender)) (prews (match-string 2 sender)) (postws (match-string 3 sender)) (post (match-string 4 sender))) (setq sender (concat pre (if (or (string-match "^[ \t]+$" prews) (string-match "^[ \t]+$" postws)) " " "") post))))) (setq banner (concat sender ": " subj)) (if (> (length banner) 74) (setq banner (substring banner 0 74))) (setcdr (assq 'print-as msg) banner)) nil) msg) ;;(setq zephyr-insert-hook-list ;; (cons 'zephyr-munge-cyrus-notofications zephyr-insert-hook-list)) ;;interesting little filter... (defun magus-zephyr-george-redact (msg) "Munge George Gusciora's zephyrs so that the body of the zephyr is replaced with a harmless string." ;; check the sender of the zephyr; if not george, send it on; ;; if it is a ping, send it on (if (or (eq 'PING (cdr (assq 'opcode msg))) (not (string= "gusciora" (cdr (assq 'sender msg))))) msg ;; otherwise, delete the print-as field and replace it with one ;; that contains an amusing message (cons (cons 'print-as (yow)) (remassq 'print-as msg)))) ;I don't want to ;(setq zephyr-insert-hook-list ; (cons 'magus-zephyr-george-redact zephyr-insert-hook-list)) ;; Tries to get bumbot snapshots by default (load "/afs/cs/user/dkindred/tmp/bumbot-hoturl-test.el") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The subscription stuff below is all superceded by the new ;; zephyr-filters variable! The old stuff is retained below as an example ;; of the conversion process... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Don't pay attention to recipients when deciding what to accept or ignore ;(setq zephyr-recipients-accept-regexp nil) ;(setq zephyr-recipients-ignore-regexp nil) ;; Ignore messages to these zephyr instances ;(setq zephyr-instances-ignore-regexp ; (concat "fortune\\|service-query\\|hearts\\|weather\\|usenet_alert" ; "\\|mayan-date\\|zippy")) ;;;;;;;; ;; The new version of the above... (these are all things to ignore) ;; (in a function just for convenience) ;; ;; This function appends stuff to the end of zephyr-filters so that if the ;; user has set his own filters, those will take precedence over anything here. ;; ;; The value of zephyr-filters is clobbered when this file is loaded, so if you ;; want to set your own filters, do it after loading this file, but before ;; invoking zephyr-personal, zephyr-nonpersonal, or zephyr-all... ;;;;;;;; ;(defun zephyr-set-default-filters () ; (setq zephyr-filters ; (append (default-value 'zephyr-filters) ; '(((instance . "^fortune$") nil) ;; ignore these... ; ((instance . "^service-query$") nil) ; ((instance . "^games-hearts$") nil) ; ((instance . "^usenet_alert$") nil) ; ((instance . "^weather$") (sender . "^bsy$") nil) ; ((instance . "^weather.temp$") (sender . "^weather$") nil) ; ((instance . "^mayan-date$") (sender . "^ghn$") nil) ; ((instance . "^netnews.status$") (sender . "^news$") nil) ; ((instance . "^zippy$") (sender . "^acid$") nil) ; ((instance . "^top-ten$") (sender . "^acid$") nil) ; ((instance . "^confession$") (sender . "^nobody$") nil) ; ((instance . "^coke\\.mail$") (sender . "^ghn$") nil) ; ((instance . "^coke\\.mail$") (sender . "^coke$") nil) ; ((instance . "^coda$") nil) ; ((instance . "^paragon$") nil) ; ((instance . "^iwarp$") nil) ; (t) ;; accept anything else ; )))) (setq zephyr-extra-subscriptions (append (list '("plusplus" "*" "*") '("GLOBAL" "*" "*") '("XLATE" "*" "*") '("FORUM" "*" "*") ;; Uncomment the following line and change to your own email address to ;; receive mail notifications from the IMAP server. Add one line for ;; each mailbox you want to receive notifications for (e.g., INBOX, ;; INBOX.RESEARCH, INBOX.JUNK etc.) ; '("MAIL" "INBOX" "foobar@cs.cmu.edu") ) (and (boundp 'zephyr-extra-subscriptions) zephyr-extra-subscriptions))) (defun zephyr-set-default-filters () (setq zephyr-filters (append (default-value 'zephyr-filters) '(;((instance . "^fortune$") nil) ;; ignore these... ((instance . "^service-query$") nil) ;((instance . "^games-hearts$") nil) ((instance . "^usenet_alert$") nil) ;((instance . "^weather$") (sender . "^bsy$") nil) ;((instance . "^weather.temp$") (sender . "^weather$") nil) ((instance . "^mayan-date$") (sender . "^ghn$") nil) ;((instance . "^netnews.status$") (sender . "^news$") nil) ((instance . "^zippy$") (sender . "^acid$") nil) ;((instance . "^top-ten$") (sender . "^acid$") nil) ;((instance . "^confession$") (sender . "^nobody$") nil) ;((instance . "^coke\\.mail$") (sender . "^ghn$") nil) ;((instance . "^coke\\.mail$") (sender . "^coke$") nil) ((instance . "^tts") nil) ((instance . "^coda$") nil) ((instance . "^paragon$") nil) ((instance . "^iwarp$") nil) ;((instance . "^rfw") nil) ((instance . "^chess") nil) ((instance . "^chat.games") nil) (t) ;; accept anything else )))) ;; ;; Note: If you're in coda or iwarp, you probably want to add something like ;; the following to your .emacs file... (at a point BEFORE you call ;; zephyr-nonpersonal or zephyr-all to start getting zgrams) ;; ;; (setq zephyr-filters (cons '((instance . "^coda$") t) zephyr-filters)) ;; ;; clobber default value of zephyr filters - we want PINGs to get through... (setq zephyr-filters '()) ;; Not used in new-style subscriptions... ; ;(setq zephyr-opcodes-ignore-list ;; Don't filter out zephyr PINGs ; nil) ; ;; To filter out PINGs in the new scheme, you want to cons in ;; '((opcode . "PING") nil) to the front of zephyr-filters ;; If changing the next two variables is all you want to do, just set them ;; in your .emacs as per the example ;; Initialize the zephyr-history list. This is the list of recipients that ;; you always want zephyr-mode to know about. You can scroll through the ;; list using M-p and M-n in zephyr-mode, and it is used to perform completion ;; on recipient names when you use C-c C-s to change the recipient. ;; ;; The last item on this list becomes the initial recipient when a zephyr ;; buffer is created. ;; ;(setq zephyr-initial-history '("larry" "curly" "moe" "nobody")) ;; Zephyr-aliases is a list of aliases. The first item in each alias is ;; aliased to the other (1 or more) items in the list. For example: ;; ;; (setq zephyr-aliases ;; '(("pals" . ("dahmer" "lechter" "bates")) ;; ("harry" . ("bovik")))) ;; You may want to do this. Shows idle times for the user(s) you're ;; about to send a zgram to. ;; ;; (define-key zephyr-mode-map "\ez" 'zephyr-zlocate-finger) ;;; Fn to iconify a frame.... (defun iconify-this-frame () (interactive) (iconify-frame (selected-frame))) ;; (We don't want this any more, because button 3 is the zephyr mode menu) ;; ;;;(if running-xemacs ;;; (define-key zephyr-mode-map 'button3 'iconify-this-frame)) (if (not (string= "Iconify" (elt (car zephyr-menu) 0))) (setq zephyr-menu (cons '["Iconify" iconify-this-frame t] zephyr-menu))) ;; This variable is used later in this file (defvar zephyr-use-timestamped-banner t "Use a timestamped banner in zephyr-add-banner. Must be setq'd to nil before the sample setup is loaded if you don't want timestamped banners.") ;; Initialize the xemacs faces -- the faces get their attributes from ;; your .Xdefaults (defvar zephyr-sender-face (make-face 'zephyr-sender-face)) (set-face-foreground 'zephyr-sender-face "Red") (defvar zephyr-received-instance-face (make-face 'zephyr-received-instance-face)) (set-face-foreground 'zephyr-received-instance-face "Blue") (defvar zephyr-timestamp-face (make-face 'zephyr-timestamp-face)) (set-face-foreground 'zephyr-timestamp-face "Magenta") (defvar zephyr-sent-instance-face (make-face 'zephyr-sent-instance-face)) (set-face-foreground 'zephyr-sent-instance-face "Purple") (defvar zephyr-recipient-face (make-face 'zephyr-recipient-face)) (set-face-foreground 'zephyr-recipient-face "Orange") (defvar zephyr-unauth-face (make-face 'zephyr-unauth-face)) (set-face-foreground 'zephyr-unauth-face "DarkGreen") (defvar zephyr-send-regexp "^\\(\\(\([^\n]*\)\\)?\\)::$") (defvar zephyr-send-regexp-uid "^\\([^()\n]+\\)\\(\\(\([^\n]*\)\\)?\\)::$") ;this next one is the original ;(defvar zephyr-send-regexp "^\\([^(\n]*\\)\\(\\(\([^\n]*\)\\)?\\)::$") ;this next one is bad ;(defvar zephyr-send-regexp "^\\([^\n]*\\)::$") ; Mahim: this next one is the original regexp for timestamps of the form hh:mm:ss ;(defvar zephyr-receive-regexp "^\\([^[(\n]+\\)\\(\\(\([^\n]*\)\\)?\\)\\(\\(\\[\\(FORGED\\|UNAUTH\\)\\]\\)?\\):: \\(\\[[0-9:]*\\]\\)$") (defvar zephyr-receive-regexp "^\\([^[(\n]+\\)\\(\\(\([^\n]*\)\\)?\\)\\(\\(\\[\\(FORGED\\|UNAUTH\\)\\]\\)?\\):: \\(\\[[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9]* [0-9:]* [0-9]*\\]\\)$") (defvar zephyr-font-lock-keywords (list (list zephyr-send-regexp-uid (list 1 'zephyr-recipient-face t)) (list zephyr-send-regexp-uid (list 2 'zephyr-sent-instance-face t)) (list zephyr-send-regexp (list 1 'zephyr-sent-instance-face t)) (list zephyr-receive-regexp (list 1 'zephyr-sender-face t)) (list zephyr-receive-regexp (list 2 'zephyr-received-instance-face t)) (list zephyr-receive-regexp (list 4 'zephyr-unauth-face t)) (list zephyr-receive-regexp (list 7 'zephyr-timestamp-face t)) ) "zephyr font lock keywords" ) (defun zephyr-fontify () "Hook to turn on and customize fonts for zephyr." (require 'font-lock) ; for font-lock-keywords below (make-local-variable 'font-lock-mode-hook) ; don't affect other buffers (add-hook 'font-lock-mode-hook ; set a hook with inline function (function ; modifies font-lock-keywords when (lambda () ; font-lock-mode run (setq font-lock-keywords zephyr-font-lock-keywords ))) nil 'local) (font-lock-mode 1) ; change the typefaces ) (if window-system ; can't do this on ASCII terminal (add-hook 'zephyr-mode-hook 'zephyr-fontify)) (defun make-zephyr-faces () (let ((dont-provide-tty-defaults (or (find-face 'zephyr-receive-face) (find-face 'zephyr-userid-face) (find-face 'zephyr-mail-face) (not (eq (device-type (selected-device)) 'tty))))) (or (find-face 'zephyr-receive-face) (and (setq zephyr-receive-face (make-face 'zephyr-receive-face)) (if (not dont-provide-tty-defaults) (make-face-bold 'zephyr-receive-face)))) (or (find-face 'zephyr-userid-face) (and (setq zephyr-userid-face (make-face 'zephyr-userid-face)) (if (not dont-provide-tty-defaults) (set-face-reverse-p 'zephyr-userid-face t)))) (or (find-face 'zephyr-mail-face) (and (setq zephyr-mail-face (make-face 'zephyr-mail-face)) (if (not dont-provide-tty-defaults) (set-face-underline-p 'zephyr-mail-face t)))))) ;; Just in case we're not under XEmacs ... (or (boundp 'running-xemacs) (setq running-xemacs (and (string-match "XEmacs\\|Lucid" emacs-version) t))) (if running-xemacs (make-zephyr-faces)) (defun zephyr-personal () (interactive) (let ((old-frame (if running-xemacs (selected-frame))) (old-buffer (current-buffer))) (make-local-variable 'zephyr-personal-msg-p) ;;Only notify for personal zgrams (setq zephyr-notify-with-message-p 'zephyr-personal-msg-p) (if running-xemacs (progn (or (eq (device-type (selected-device)) 'tty) (select-frame (new-frame '((name . "zephyr-personal"))))) ;; accept only zgrams addressed explicitly to user (zephyr-new-buffer "personal-zgrams") (set-buffer-dedicated-frame (current-buffer) (selected-frame)) (set-buffer-menubar nil) (make-local-variable 'frame-icon-title-format) (setq frame-icon-title-format "personal zgrams") ;; (setq zephyr-recipients-accept-regexp ;; (concat "^" (user-login-name) "$")) ;; new style.... (use append to avoid clobbering stuff user has set) (setq zephyr-filters (append zephyr-filters (list (list (cons 'recipient (concat "^" (user-login-name) )) t) (list (cons 'recipient (concat "^" (user-login-name) "\\(@cs\\.cmu\\.edu\\)?$")) t) '((instance . "^facilities.announce$") t) '((class . "mail") t) '((class . "MAIL") t) ;'((class . "LOGIN") t) '(nil)))) ;; '(nil) means ignore everything else (zephyr-fontify) ;; use font-lock-mode to highlight certain zgrams ; (make-local-variable 'font-lock-keywords) ; (font-lock-mode) ; (setq font-local-keywords zephyr-font-lock-keywords) ; (setq font-lock-keywords ; (list '("^.*(mail_delivery)::$" . zephyr-mail-face) ; '("^NEW:.*" . zephyr-mail-face) ; '("^.*::\\( \\|$\\)" . zephyr-userid-face))) ; (font-lock-fontify-buffer) (message "Personal zgram window iconified and awaiting output.") (select-frame old-frame) ) (progn (zephyr-new-buffer "personal-zgrams") ;; accept only zgrams addressed explicitly to user ;;(setq zephyr-recipients-accept-regexp ;; (concat "^" (user-login-name) "$")) ;; new style... (setq zephyr-filters (append zephyr-filters (list (list (cons 'recipient (concat "^" (user-login-name) )) t) (list (cons 'recipient (concat "^" (user-login-name) "\\(@cs\\.cmu\\.edu\\)?$")) t) '((instance . "^facilities.announce$") t) '((class . "LOGIN") t) '(nil)))) ;; '(nil) means ignore all else )) (set-buffer old-buffer) )) (defun zephyr-nonpersonal () (interactive) (let ((old-frame (if running-xemacs (selected-frame))) (old-buffer (current-buffer))) (make-local-variable 'zephyr-personal-msg-p) ;;Only notify for personal zgrams (setq zephyr-notify-with-message-p 'zephyr-personal-msg-p) (if running-xemacs (progn (or (eq (device-type (selected-device)) 'tty) (select-frame (new-frame '((name . "zephyr-nonpersonal"))))) (zephyr-new-buffer "nonpersonal-zgrams") (set-buffer-dedicated-frame (current-buffer) (selected-frame)) (set-buffer-menubar nil) (make-local-variable 'frame-icon-title-format) (setq frame-icon-title-format "nonpersonal zgrams") ;; accept zgrams not addressed explicitly to user, and ignore ;; stuff as defined earlier... (zephyr-set-default-filters) ;; reject things with a recip (setq zephyr-filters (append (list '((recipient . "^[^@]") nil) '((class . "LOGIN") nil) '((class . "forum") nil)) zephyr-filters)) ;; zephyr-nonpersonal will never beep, because ;; zephyr-beep-personal-only was set earlier, and this ;; buffer doesn't get any personal zgrams. ;; don't deiconify on zephyr receipt (make-local-variable 'zephyr-deiconify-on-receive) (setq zephyr-deiconify-on-receive nil) ;; don't get personal zgrams in this window (no longer needed) ;; (setq zephyr-recipients-always-accept-regexp nil) ;We have explictly call out fontify hook (zephyr-fontify) ;; use font-lock-mode to highlight userids ; (make-local-variable 'font-lock-keywords) ; (font-lock-mode) ; (setq font-lock-keywords ; (list '("^.*::\\( \\|$\\)" . zephyr-userid-face))) ; (font-lock-fontify-buffer) (select-frame old-frame) ) (progn (zephyr-new-buffer "nonpersonal-zgrams") ;; accept only zgrams not addressed explicitly to user, subject ;; to constraints set up earlier... (zephyr-set-default-filters) (setq zephyr-filters (cons '((recipient . "^[^@]") nil) ; reject things w/ a recipnt zephyr-filters)) )) (set-buffer old-buffer) )) (defun zephyr-all () (interactive) (let ((old-frame (if running-xemacs (selected-frame))) (old-buffer (current-buffer))) (if running-xemacs (progn (or (eq (device-type (selected-device)) 'tty) (select-frame (new-frame '((name . "zephyr-all"))))) (zephyr-new-buffer "all-zgrams") (set-buffer-dedicated-frame (current-buffer) (selected-frame)) (set-buffer-menubar nil) (make-local-variable 'frame-icon-title-format) (setq frame-icon-title-format "all zgrams") (zephyr-set-default-filters) ;; don't deiconify on zephyr receipt (make-local-variable 'zephyr-deiconify-on-receive) (setq zephyr-deiconify-on-receive nil) ;; use font-lock-mode to highlight certain zgrams (make-local-variable 'font-lock-keywords) (font-lock-mode) (setq font-lock-keywords (list '("^.*(mail_delivery)::$" . zephyr-mail-face) '("^NEW:.*" . zephyr-mail-face) '("^.*::\\( \\|$\\)" . zephyr-userid-face))) (font-lock-fontify-buffer) (select-frame old-frame) ) (progn (zephyr-new-buffer "all-zgrams") (zephyr-set-default-filters))) (set-buffer old-buffer))) ;; The following code adds in a timestamp to incoming messages. ;; Since setq'ing the zephyr-hook-list is best avoided, this code redefines ;; zephyr-add-banner to add a timestamp if zephyr-use-timestamped-banner is ;; set (if not, it calls the original zephyr-add-banner) ;; Mahim: the timestamp string is of the form Sat Jun 24 12:45:56 2004 ;; Originally, the substring was with limits 11 19 (only hh:mm:ss) (defun zephyr-add-timestamp-to-banner (msg) (let* ((banner-assoc-orig (assq 'banner msg)) (old-banner (cdr banner-assoc-orig)) (timestamp (cdr (assq 'time msg))) (new-msg (delq banner-assoc-orig msg))) (cons (cons 'banner (concat old-banner ; Change the following to (substring timestamp 11 19) if you want ; timestamps of the form hh:mm:ss " [" (substring timestamp 0 24) "]\012")) new-msg))) (fset 'zephyr-add-banner-orig (symbol-function 'zephyr-add-banner)) (defun zephyr-add-banner (msg) (if zephyr-use-timestamped-banner (setq msg (zephyr-add-timestamp-to-banner (zephyr-add-banner-orig msg))) (setq msg (zephyr-add-banner-orig msg))) (zephyr-munge-cyrus-notifications msg))