;; -*- emacs-lisp -*- ;;; gnus-mst-identities.el --- posting styles replacement ;; Description: This code allows you change your identity (signature, from ;; address, x-face, gcc) depending on who you are sending to. ;; Author: Mark Triggs ;; Keywords: news ;; $Id: gnus-mst-identities.el,v 1.40 2004/01/04 05:16:34 mst Exp $ ;; This file 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, or (at your option) ;; any later version. ;; This file 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 GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; While gnus's posting styles work well for news, I wanted to be able to set ;; my identity based on the message receipient for mail messages. This code ;; lets you define 'identities', which are like posting styles but matched ;; against the To: field of the message. ;; Identities are defined by the 'gnus-mst-styles' variable as below. Note that ;; identities are applied in a cascading fashion - if identity 1 matches, its ;; settings take effect but if identity 2 also matches, its settings will take ;; effect also. Headers take the form of (HEADER . VALUE) where VALUE is a ;; form that is evaluated at runtime. Value may reference the free variable ;; TO-ADDRESS, which is the recipient of the message. ;; (setq gnus-mst-styles ;; '( ;; ;; identity 1 ;; ((name . "foobar") ;; (to . ".*@somehost.com") ;; (headers . ((gcc . "somegroup") ;; (organization . "foo") ;; (X-junk . (concat "foo" "bar")) ;; (from . "someuser "))) ;; (signature-file . "~/.somefile")) ;; ;; identity 2 ;; ((name . "work") ;; (to . ".*@workaddress.com") ;; (headers . ((gcc . "someothergroup") ;; (from . "You "))) ;; (signature-file . "~/.someotherfile")))) ;;; Code: (defvar gnus-mst-styles nil "Posting styles") (defmacro with-narrowed-headers (&rest body) `(progn (message-narrow-to-headers) (unwind-protect ,(cons 'progn body) (widen)))) (defun message-mst-add-custom-headers (&optional identity) "Add a custom headers to outgoing messages depending on destination" (ignore-errors (when (message-mail-p) (let ((to-header (with-narrowed-headers (message-fetch-field "To")))) (when to-header (let* ((components (mail-extract-address-components to-header t)) (to-string (mapconcat 'cadr components ", "))) (if (boundp 'identity) (message-mst-do-custom-headers to-string identity) (message-mst-do-custom-headers to-string)))))))) (defun message-mst-clear-custom-headers () "Remove gcc, signature, organization and from address headers" (interactive) (let* ((vars (apropos-internal "message-has")) (headers (mapcar (lambda (str) (replace-regexp-in-string "message-has-" "" (symbol-name str))) vars))) ;; kill the sig (save-excursion (goto-char (point-max)) (ignore-errors (search-backward-regexp "^-- *$")) (kill-region (point) (point-max))) (with-narrowed-headers (mapc (lambda (header) (message-remove-header header)) headers)) (mapc (lambda (var) (set var nil)) vars))) (defun message-mst-do-custom-headers (to-address &optional identity) "Dynamically generate message headers based on recipients" (let ((use-styles (if (and identity (assoc `(name . ,identity) gnus-mst-styles)) (list (assoc `(name . ,identity) gnus-mst-styles)) (remove-if-not (lambda (style) (string-match (cdr (assoc 'to style)) to-address)) gnus-mst-styles)))) (mapc (lambda (style) (mapc (lambda (field) (case (car field) (headers (mapc (lambda (header) (let ((sym (intern (upcase (format "message-has-%s" (car header)))))) (unless (and (boundp sym) (symbol-value sym)) (message-add-header (concat (upcase-initials (symbol-name (car header))) ": " (or (and (consp (eval (cdr header))) (mapconcat (lambda (n) (format "%s" n)) (eval (cdr header)) ", ")) (format "%s" (eval (cdr header)))))) (make-variable-buffer-local sym) (set sym t)))) (cdr field))) (signature-file (message-mst-add-signature (eval (cdr field)))))) style)) use-styles))) (defun message-mst-add-signature (signature-file) "Add a signature to a message if one has not already been added" (let ((message-signature-file signature-file)) (unless (or (and (boundp 'message-has-signature) message-has-signature) (save-excursion (message-goto-signature))) (message-insert-signature t) (make-variable-buffer-local 'message-has-signature) (setq message-has-signature t)))) (defun message-mst-apply-identity () "prompt for an identity and apply it" (interactive) (message-mst-add-custom-headers (completing-read "apply identity: " (mapcar (lambda (n) (cons (cdr n) (car n))) (mapcar 'car gnus-mst-styles))))) (provide 'gnus-mst-identities)