Function: define-mail-abbrev

define-mail-abbrev is an autoloaded, interactive and byte-compiled function defined in mailabbrev.el.gz.

Signature

(define-mail-abbrev NAME DEFINITION &optional FROM-MAILRC-FILE)

Documentation

Define NAME as a mail alias abbrev that translates to DEFINITION.

If DEFINITION contains multiple addresses, separate them with commas.

Optional argument FROM-MAILRC-FILE means that DEFINITION comes from a mailrc file. In that case, addresses are separated with spaces and addresses with embedded spaces are surrounded by double-quotes.

View in manual

Probably introduced at or before Emacs version 19.14.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/mail/mailabbrev.el.gz
;; originally defined in mailalias.el ; build-mail-abbrevs calls this with
;; stuff parsed from the .mailrc file.
;;
;;;###autoload
(defun define-mail-abbrev (name definition &optional from-mailrc-file)
  "Define NAME as a mail alias abbrev that translates to DEFINITION.
If DEFINITION contains multiple addresses, separate them with commas.

Optional argument FROM-MAILRC-FILE means that DEFINITION comes
from a mailrc file.  In that case, addresses are separated with
spaces and addresses with embedded spaces are surrounded by
double-quotes."
  ;; When this is called from build-mail-abbrevs, the third argument is
  ;; true, and we do some evil space->comma hacking like /bin/mail does.
  (interactive "sDefine mail alias: \nsDefine %s as mail alias for: ")
  ;; Read the defaults first, if we have not done so.
  (unless (obarrayp mail-abbrevs) (build-mail-abbrevs))
  ;; strip garbage from front and end
  (if (string-match "\\`[ \t\n,]+" definition)
      (setq definition (substring definition (match-end 0))))
  (if (string-match "[ \t\n,]+\\'" definition)
      (setq definition (substring definition 0 (match-beginning 0))))
  (let* ((L (length definition))
	 (start (if (> L 0) 0))
	 end this-entry result)
    (while start
      (cond
       (from-mailrc-file
	;; If we're reading from the mailrc file, addresses are
	;; delimited by spaces, and addresses with embedded spaces are
	;; surrounded by non-escaped double-quotes.
	(if (eq ?\" (aref definition start))
	    (setq start (1+ start)
		  end (and (string-match
			    "[^\\]\\(\\([\\][\\]\\)*\\)\"[ \t,]*"
			    definition start)
			   (match-end 1)))
	  (setq end (string-match "[ \t,]+" definition start)))
	;; Extract the address and advance the loop past it.
	(setq this-entry (substring definition start end)
	      start (and end (/= (match-end 0) L) (match-end 0)))
	;; If the full name contains a problem character, quote it.
	(and (string-match "\\(.+?\\)[ \t]*\\(<.*>\\)" this-entry)
	     (string-match "[^- !#$%&'*+/0-9=?A-Za-z^_`{|}~]"
			   (match-string 1 this-entry))
	     (setq this-entry (replace-regexp-in-string
			       "\\(.+?\\)[ \t]*\\(<.*>\\)"
			       "\"\\1\" \\2"
			       this-entry)))
	(push this-entry result))
       ;; When we are not reading from .mailrc, addresses are
       ;; separated by commas.  Try to accept a rfc822-like syntax.
       ;; (Todo: extend rfc822.el to do the work for us.)
       ((equal (string-match
		"[ \t,]*\\(\"\\(?:[^\"]\\|[^\\]\\(?:[\\][\\]\\)*\"\\)*\"[ \t]*\
<[-.!#$%&'*+/0-9=?A-Za-z^_`{|}~@]+>\\)[ \t,]*"
		definition start)
	       start)
	;; If an entry has a valid [ "foo bar" <foo@example.com> ]
	;; form, use it literally .  This also allows commas in the
	;; quoted string, e.g.  [ "foo bar, jr" <foo@example.com> ]
	(push (match-string 1 definition) result)
	(setq start (and (/= (match-end 0) L) (match-end 0))))
       (t
	;; Otherwise, read the next address by looking for a comma.
	(setq end (string-match "[ \t\n,]*,[ \t\n]*" definition start))
	(setq this-entry (substring definition start end))
	;; Advance the loop past this address.
	(setq start (and end (/= (match-end 0) L) (match-end 0)))
	;; If the full name contains a problem character, quote it.
	(and (string-match "\\(.+?\\)[ \t]*\\(<.*>\\)" this-entry)
	     (string-match "[^- !#$%&'*+/0-9=?A-Za-z^_`{|}~]"
			   (match-string 1 this-entry))
	     (setq this-entry (replace-regexp-in-string
			       "\\(.+?\\)[ \t]*\\(<.*>\\)" "\"\\1\" \\2"
			       this-entry)))
	(push this-entry result))))

    (setq definition (mapconcat (function identity)
				(nreverse result)
				mail-alias-separator-string)))
  (setq mail-abbrev-aliases-need-to-be-resolved t)
  (setq name (downcase name))
  ;; use an abbrev table instead of an alist for mail-abbrevs.
  (let ((abbrevs-changed abbrevs-changed))  ; protect this from being changed.
    (define-abbrev mail-abbrevs name definition 'mail-abbrev-expand-hook 0 t)))