mailalias.el 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. ;; Expand mailing address aliases defined in ~/.mailrc.
  2. ;; Copyright (C) 1985 Free Software Foundation, Inc.
  3. ;; This file is part of GNU Emacs.
  4. ;; GNU Emacs is distributed in the hope that it will be useful,
  5. ;; but WITHOUT ANY WARRANTY. No author or distributor
  6. ;; accepts responsibility to anyone for the consequences of using it
  7. ;; or for whether it serves any particular purpose or works at all,
  8. ;; unless he says so in writing. Refer to the GNU Emacs General Public
  9. ;; License for full details.
  10. ;; Everyone is granted permission to copy, modify and redistribute
  11. ;; GNU Emacs, but only under the conditions described in the
  12. ;; GNU Emacs General Public License. A copy of this license is
  13. ;; supposed to have been given to you along with GNU Emacs so you
  14. ;; can know your rights and responsibilities. It should be in a
  15. ;; file named COPYING. Among other things, the copyright notice
  16. ;; and this notice must be preserved on all copies.
  17. ;; Called from sendmail-send-it, or similar functions,
  18. ;; only if some mail aliases are defined.
  19. (defun expand-mail-aliases (beg end)
  20. "Expand all mail aliases in suitable header fields found between BEG and END.
  21. Suitable header fields are To, Cc and Bcc."
  22. (if (eq mail-aliases t)
  23. (progn (setq mail-aliases nil) (build-mail-aliases)))
  24. (goto-char beg)
  25. (setq end (set-marker (make-marker) end))
  26. (let ((case-fold-search nil))
  27. (while (let ((case-fold-search t))
  28. (re-search-forward "^\\(to\\|cc\\|bcc\\):" end t))
  29. (skip-chars-forward " \t")
  30. (let ((beg1 (point))
  31. end1 pos epos seplen
  32. ;; DISABLED-ALIASES records aliases temporarily disabled
  33. ;; while we scan text that resulted from expanding those aliases.
  34. ;; Each element is (ALIAS . TILL-WHEN), where TILL-WHEN
  35. ;; is where to reenable the alias (expressed as number of chars
  36. ;; counting from END1).
  37. (disabled-aliases nil))
  38. (re-search-forward "^[^ \t]" end 'move)
  39. (beginning-of-line)
  40. (skip-chars-backward " \t\n")
  41. (setq end1 (point-marker))
  42. (goto-char beg1)
  43. (while (< (point) end1)
  44. (setq pos (point))
  45. ;; Reenable any aliases which were disabled for ranges
  46. ;; that we have passed out of.
  47. (while (and disabled-aliases (> pos (- end1 (cdr (car disabled-aliases)))))
  48. (setq disabled-aliases (cdr disabled-aliases)))
  49. ;; EPOS gets position of end of next name;
  50. ;; SEPLEN gets length of whitespace&separator that follows it.
  51. (if (re-search-forward "[ \t]*[\n,][ \t]*" end1 t)
  52. (setq epos (match-beginning 0)
  53. seplen (- (point) epos))
  54. (setq epos (marker-position end1) seplen 0))
  55. (let (translation
  56. (string (buffer-substring pos epos)))
  57. (if (and (not (assoc string disabled-aliases))
  58. (setq translation
  59. (cdr (assoc string mail-aliases))))
  60. (progn
  61. ;; This name is an alias. Disable it.
  62. (setq disabled-aliases (cons (cons string (- end1 epos))
  63. disabled-aliases))
  64. ;; Replace the alias with its expansion
  65. ;; then rescan the expansion for more aliases.
  66. (goto-char pos)
  67. (insert translation)
  68. (delete-region (point) (+ (point) (- epos pos)))
  69. (goto-char pos))
  70. ;; Name is not an alias. Skip to start of next name.
  71. (goto-char epos)
  72. (forward-char seplen))))
  73. (set-marker end1 nil)))
  74. (set-marker end nil)))
  75. ;; Called by mail-setup, or similar functions, only if ~/.mailrc exists.
  76. (defun build-mail-aliases ()
  77. "Read mail aliases from ~/.mailrc and set mail-aliases."
  78. (let (buffer exists name (file "~/.mailrc"))
  79. (setq exists (get-file-buffer file))
  80. (unwind-protect
  81. (if (not (file-exists-p file))
  82. (setq buffer nil)
  83. (save-excursion
  84. (set-buffer (setq buffer (find-file-noselect file)))
  85. (goto-char (point-min))
  86. (while (re-search-forward "^alias[ \t]*\\|^a[ \t]*" nil t)
  87. (re-search-forward "[^ \t]+")
  88. (setq name (buffer-substring (match-beginning 0) (match-end 0)))
  89. (skip-chars-forward " \t")
  90. (define-mail-alias
  91. name
  92. (buffer-substring (point) (progn (end-of-line) (point)))))
  93. mail-aliases))
  94. (or exists (null buffer) (kill-buffer buffer)))))
  95. ;; Always autoloadable in case the user wants to define aliases
  96. ;; interactively or in .emacs.
  97. (defun define-mail-alias (name definition)
  98. "Define NAME as a mail-alias that translates to DEFINITION."
  99. (interactive "sDefine mail alias: \nsDefine %s as mail alias for: ")
  100. (let ((aelt (assoc name mail-aliases)))
  101. (if aelt
  102. (rplacd aelt definition)
  103. (setq mail-aliases (cons (cons name definition) mail-aliases)))))