Function: expand-mail-aliases

expand-mail-aliases is an autoloaded, interactive and byte-compiled function defined in mailalias.el.gz.

Signature

(expand-mail-aliases BEG END &optional EXCLUDE)

Documentation

Expand all mail aliases in suitable header fields found between BEG and END.

If interactive, expand in header fields. Suitable header fields are To, From, Cc and Bcc, Reply-To, and their Resent- variants.

Optional second arg EXCLUDE may be a regular expression defining text to be removed from alias expansions.

Probably introduced at or before Emacs version 20.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/mail/mailalias.el.gz
;; Called from sendmail-send-it, or similar functions,
;; only if some mail aliases are defined.
;;;###autoload
(defun expand-mail-aliases (beg end &optional exclude)
  "Expand all mail aliases in suitable header fields found between BEG and END.
If interactive, expand in header fields.
Suitable header fields are `To', `From', `Cc' and `Bcc', `Reply-To', and
their `Resent-' variants.

Optional second arg EXCLUDE may be a regular expression defining text to be
removed from alias expansions."
  (interactive
   (save-excursion
     (list (goto-char (point-min))
	   (mail-header-end))))
  (sendmail-sync-aliases)
  (when (eq mail-aliases t)
    (setq mail-aliases nil)
    (build-mail-aliases))
  (save-excursion
    (goto-char beg)
    (setq end (set-marker (make-marker) end))
    (let ((case-fold-search nil))
      (while (let ((case-fold-search t))
	       (re-search-forward mail-address-field-regexp end t))
	(skip-chars-forward " \t")
	(let ((beg1 (point))
	      end1 pos epos seplen
	      ;; DISABLED-ALIASES records aliases temporarily disabled
	      ;; while we scan text that resulted from expanding those aliases.
	      ;; Each element is (ALIAS . TILL-WHEN), where TILL-WHEN
	      ;; is where to reenable the alias (expressed as number of chars
	      ;; counting from END1).
	      (disabled-aliases nil))
	  (re-search-forward "^[^ \t]" end 'move)
	  (beginning-of-line)
	  (skip-chars-backward " \t\n")
	  (setq end1 (point-marker))
	  (goto-char beg1)
	  (while (< (point) end1)
	    (setq pos (point))
	    ;; Reenable any aliases which were disabled for ranges
	    ;; that we have passed out of.
	    (while (and disabled-aliases
			(> pos (- end1 (cdr (car disabled-aliases)))))
	      (setq disabled-aliases (cdr disabled-aliases)))
	    ;; EPOS gets position of end of next name;
	    ;; SEPLEN gets length of whitespace&separator that follows it.
	    (if (re-search-forward "[ \t]*[\n,][ \t]*" end1 t)
		(setq epos (match-beginning 0)
		      seplen (- (point) epos))
	      ;; Handle the last name in this header field.
	      ;; We already moved END1 back across whitespace after it.
              (setq epos (marker-position end1) seplen 0))
	    (let ((string (buffer-substring-no-properties pos epos))
		  translation)
	      (if (and (not (assoc string disabled-aliases))
		       (setq translation (cdr (assoc string mail-aliases))))
		  (progn
		    ;; This name is an alias.  Disable it.
		    (setq disabled-aliases (cons (cons string (- end1 epos))
						 disabled-aliases))
		    ;; Replace the alias with its expansion
		    ;; then rescan the expansion for more aliases.
		    (goto-char pos)
		    (insert translation)
		    (when exclude
		      (let ((regexp (concat "\\b\\(" exclude "\\)\\b"))
			    (end (point-marker)))
			(goto-char pos)
			(while (re-search-forward regexp end t)
			  (replace-match ""))
			(goto-char end)))
		    (delete-region (point) (+ (point) (- epos pos)))
		    (goto-char pos))
		;; Name is not an alias.  Skip to start of next name.
		(goto-char epos)
		(forward-char seplen))))
	  (set-marker end1 nil)))
      (set-marker end nil))))