Mercurial > emacs
comparison lisp/mh-e/mh-alias.el @ 56673:e9a6cbc8ca5e
Upgraded to MH-E version 7.4.80.
See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Sun, 15 Aug 2004 22:00:06 +0000 |
parents | d36b00b98db0 |
children | 4f4f410e6fe8 d8411455de48 |
comparison
equal
deleted
inserted
replaced
56672:83ab2b01744a | 56673:e9a6cbc8ca5e |
---|---|
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
26 ;; Boston, MA 02111-1307, USA. | 26 ;; Boston, MA 02111-1307, USA. |
27 | 27 |
28 ;;; Commentary: | 28 ;;; Commentary: |
29 | 29 |
30 ;; [To be deleted when documented in MH-E manual.] | |
31 ;; | |
32 ;; This module provides mail alias completion when entering addresses. | |
33 ;; | |
34 ;; Use the TAB key to complete aliases (and optionally local usernames) when | |
35 ;; initially composing a message in the To: and Cc: minibuffer prompts. You | |
36 ;; may enter multiple addressees separated with a comma (but do *not* add any | |
37 ;; space after the comma). | |
38 ;; | |
39 ;; In the header of a message draft, use "M-TAB (mh-letter-complete)" to | |
40 ;; complete aliases. This is useful when you want to add an addressee as an | |
41 ;; afterthought when creating a message, or when adding an additional | |
42 ;; addressee to a reply. | |
43 ;; | |
44 ;; By default, completion is case-insensitive. This can be changed by | |
45 ;; customizing the variable `mh-alias-completion-ignore-case-flag'. This is | |
46 ;; useful, for example, to differentiate between people aliases in lowercase | |
47 ;; such as: | |
48 ;; | |
49 ;; p.galbraith: Peter Galbraith <GalbraithP@dfo-mpo.gc.ca> | |
50 ;; | |
51 ;; and lists in uppercase such as: | |
52 ;; | |
53 ;; MH-E: MH-E mailing list <mh-e-devel@lists.sourceforge.net> | |
54 ;; | |
55 ;; Note that this variable affects minibuffer completion only. If you have an | |
56 ;; alias for P.Galbraith and type in p.galbraith at the prompt, it will still | |
57 ;; be expanded in the letter buffer because MH is case-insensitive. | |
58 ;; | |
59 ;; When you press ", (mh-alias-minibuffer-confirm-address)" after an alias in | |
60 ;; the minibuffer, the expansion for the previous mail alias appears briefly. | |
61 ;; To inhibit this, customize the variable `mh-alias-flash-on-comma'. | |
62 ;; | |
63 ;; The addresses and aliases entered in the minibuffer are added to the | |
64 ;; message draft. To expand the aliases before they are added to the draft, | |
65 ;; customize the variable `mh-alias-expand-aliases-flag'. | |
66 ;; | |
67 ;; Completion is also performed on usernames extracted from the /etc/passwd | |
68 ;; file. This can be a handy tool on a machine where you and co-workers | |
69 ;; exchange messages, but should probably be disabled on a system with | |
70 ;; thousands of users you don't know. This is done by customizing the | |
71 ;; variable `mh-alias-local-users'. This variable also takes a string which | |
72 ;; is executed to generate the password file. For example, you'd use "ypcat | |
73 ;; passwd" for NIS. | |
74 ;; | |
75 ;; Aliases are loaded the first time you send mail and get the "To:" prompt | |
76 ;; and whenever a source of aliases changes. Sources of system aliases are | |
77 ;; defined in the customization variable `mh-alias-system-aliases' and | |
78 ;; include: | |
79 ;; | |
80 ;; /etc/nmh/MailAliases | |
81 ;; /usr/lib/mh/MailAliases | |
82 ;; /etc/passwd | |
83 ;; | |
84 ;; Sources of personal aliases are read from the files listed in your MH | |
85 ;; profile component Aliasfile. Multiple files are separated by white space | |
86 ;; and are relative to your mail directory. | |
87 ;; | |
88 ;; Alias Insertions | |
89 ;; ~~~~~~~~~~~~~~~~ | |
90 ;; There are commands to insert new aliases into your alias file(s) (defined | |
91 ;; by the `Aliasfile' component in the .mh_profile file or by the variable | |
92 ;; `mh-alias-insert-file'). In particular, there is a tool-bar icon to grab | |
93 ;; an alias from the From line of the current message. | |
94 | |
95 ;;; Change Log: | 30 ;;; Change Log: |
96 | 31 |
97 ;;; Code: | 32 ;;; Code: |
98 | 33 |
34 (eval-when-compile (require 'mh-acros)) | |
35 (mh-require-cl) | |
99 (require 'mh-e) | 36 (require 'mh-e) |
100 (load "cmr" t t) ; Non-fatal dependency for | 37 (load "cmr" t t) ; Non-fatal dependency for |
101 ; completing-read-multiple. | 38 ; completing-read-multiple. |
102 (eval-when-compile (defvar mail-abbrev-syntax-table)) | 39 (eval-when-compile (defvar mail-abbrev-syntax-table)) |
103 | 40 |
114 (defvar mh-alias-passwd-alist nil | 51 (defvar mh-alias-passwd-alist nil |
115 "Alist of aliases extracted from passwd file and their expansions.") | 52 "Alist of aliases extracted from passwd file and their expansions.") |
116 (defvar mh-alias-tstamp nil | 53 (defvar mh-alias-tstamp nil |
117 "Time aliases were last loaded.") | 54 "Time aliases were last loaded.") |
118 (defvar mh-alias-read-address-map nil) | 55 (defvar mh-alias-read-address-map nil) |
119 (if mh-alias-read-address-map | 56 (unless mh-alias-read-address-map |
120 () | |
121 (setq mh-alias-read-address-map | 57 (setq mh-alias-read-address-map |
122 (copy-keymap minibuffer-local-completion-map)) | 58 (copy-keymap minibuffer-local-completion-map)) |
123 (if mh-alias-flash-on-comma | 59 (define-key mh-alias-read-address-map |
124 (define-key mh-alias-read-address-map | 60 "," 'mh-alias-minibuffer-confirm-address) |
125 "," 'mh-alias-minibuffer-confirm-address)) | |
126 (define-key mh-alias-read-address-map " " 'self-insert-command)) | 61 (define-key mh-alias-read-address-map " " 'self-insert-command)) |
62 | |
63 (defvar mh-alias-system-aliases | |
64 '("/etc/nmh/MailAliases" "/etc/mh/MailAliases" | |
65 "/usr/lib/mh/MailAliases" "/usr/share/mailutils/mh/MailAliases" | |
66 "/etc/passwd") | |
67 "*A list of system files which are a source of aliases. | |
68 If these files are modified, they are automatically reread. This list need | |
69 include only system aliases and the passwd file, since personal alias files | |
70 listed in your `Aliasfile:' MH profile component are automatically included. | |
71 You can update the alias list manually using \\[mh-alias-reload].") | |
127 | 72 |
128 | 73 |
129 ;;; Alias Loading | 74 ;;; Alias Loading |
130 | 75 |
131 (defmacro mh-assoc-ignore-case (key alist) | 76 (defmacro mh-assoc-ignore-case (key alist) |
136 ((fboundp 'assoc-ignore-case) `(assoc-ignore-case ,key ,alist)) | 81 ((fboundp 'assoc-ignore-case) `(assoc-ignore-case ,key ,alist)) |
137 (t (error "The macro mh-assoc-ignore-case not implemented properly")))) | 82 (t (error "The macro mh-assoc-ignore-case not implemented properly")))) |
138 | 83 |
139 (defun mh-alias-tstamp (arg) | 84 (defun mh-alias-tstamp (arg) |
140 "Check whether alias files have been modified. | 85 "Check whether alias files have been modified. |
141 Return t if any file listed in the MH profile component Aliasfile has been | 86 Return t if any file listed in the Aliasfile MH profile component has been |
142 modified since the timestamp. | 87 modified since the timestamp. |
143 If ARG is non-nil, set timestamp with the current time." | 88 If ARG is non-nil, set timestamp with the current time." |
144 (if arg | 89 (if arg |
145 (let ((time (current-time))) | 90 (let ((time (current-time))) |
146 (setq mh-alias-tstamp (list (nth 0 time) (nth 1 time)))) | 91 (setq mh-alias-tstamp (list (nth 0 time) (nth 1 time)))) |
155 (> (cadr stamp) (cadr mh-alias-tstamp))))))) | 100 (> (cadr stamp) (cadr mh-alias-tstamp))))))) |
156 (mh-alias-filenames t))))))) | 101 (mh-alias-filenames t))))))) |
157 | 102 |
158 (defun mh-alias-filenames (arg) | 103 (defun mh-alias-filenames (arg) |
159 "Return list of filenames that contain aliases. | 104 "Return list of filenames that contain aliases. |
160 The filenames come from the MH profile component Aliasfile and are expanded. | 105 The filenames come from the Aliasfile profile component and are expanded. |
161 If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended." | 106 If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended." |
162 (or mh-progs (mh-find-path)) | 107 (or mh-progs (mh-find-path)) |
163 (save-excursion | 108 (save-excursion |
164 (let* ((filename (mh-profile-component "Aliasfile")) | 109 (let* ((filename (mh-profile-component "Aliasfile")) |
165 (filelist (and filename (split-string filename "[ \t]+"))) | 110 (filelist (and filename (split-string filename "[ \t]+"))) |
199 (if (not (string-match "^[ a-zA-Z0-9-]+$" res)) | 144 (if (not (string-match "^[ a-zA-Z0-9-]+$" res)) |
200 (setq res (concat "\"" res "\""))) | 145 (setq res (concat "\"" res "\""))) |
201 res)) | 146 res)) |
202 | 147 |
203 (defun mh-alias-local-users () | 148 (defun mh-alias-local-users () |
204 "Return an alist of local users from /etc/passwd." | 149 "Return an alist of local users from /etc/passwd. |
150 Exclude all aliases already in `mh-alias-alist' from `ali'" | |
205 (let (passwd-alist) | 151 (let (passwd-alist) |
206 (save-excursion | 152 (save-excursion |
207 (set-buffer (get-buffer-create mh-temp-buffer)) | 153 (set-buffer (get-buffer-create mh-temp-buffer)) |
208 (erase-buffer) | 154 (erase-buffer) |
209 (cond | 155 (cond |
220 (when (> (string-to-int (match-string 2)) 200) | 166 (when (> (string-to-int (match-string 2)) 200) |
221 (let* ((username (match-string 1)) | 167 (let* ((username (match-string 1)) |
222 (gecos-name (match-string 3)) | 168 (gecos-name (match-string 3)) |
223 (realname (mh-alias-gecos-name | 169 (realname (mh-alias-gecos-name |
224 gecos-name username | 170 gecos-name username |
225 mh-alias-passwd-gecos-comma-separator-flag))) | 171 mh-alias-passwd-gecos-comma-separator-flag)) |
226 (setq passwd-alist | 172 (alias-name (if mh-alias-local-users-prefix |
227 (cons | 173 (concat mh-alias-local-users-prefix |
228 (list (if mh-alias-local-users-prefix | 174 (mh-alias-suggest-alias realname t)) |
229 (concat mh-alias-local-users-prefix | 175 username)) |
230 (mh-alias-suggest-alias realname t)) | 176 (alias-translation |
231 username) | 177 (if (string-equal username realname) |
232 (if (string-equal username realname) | 178 (concat "<" username ">") |
233 (concat "<" username ">") | 179 (concat realname " <" username ">")))) |
234 (concat realname " <" username ">"))) | 180 (when (not (mh-assoc-ignore-case alias-name mh-alias-alist)) |
235 passwd-alist)))))) | 181 (setq passwd-alist (cons (list alias-name alias-translation) |
182 passwd-alist))))))) | |
236 (forward-line 1))) | 183 (forward-line 1))) |
237 passwd-alist)) | 184 passwd-alist)) |
238 | 185 |
239 ;;;###mh-autoload | 186 ;;;###mh-autoload |
240 (defun mh-alias-reload () | 187 (defun mh-alias-reload () |
241 "Load MH aliases into `mh-alias-alist'." | 188 "Reload MH aliases. |
189 | |
190 Since aliases are updated frequently, MH-E will reload aliases automatically | |
191 whenever an alias lookup occurs if an alias source (a file listed in your | |
192 `Aliasfile:' profile component and your password file if variable | |
193 `mh-alias-local-users' is non-nil) has changed. However, you can reload your | |
194 aliases manually by calling this command directly. | |
195 | |
196 The value of `mh-alias-reloaded-hook' is a list of functions to be called, | |
197 with no arguments, after the aliases have been loaded." | |
242 (interactive) | 198 (interactive) |
243 (save-excursion | 199 (save-excursion |
244 (message "Loading MH aliases...") | 200 (message "Loading MH aliases...") |
245 (mh-alias-tstamp t) | 201 (mh-alias-tstamp t) |
246 (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser") | 202 (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser") |
267 (while local-users | 223 (while local-users |
268 (setq user (car local-users)) | 224 (setq user (car local-users)) |
269 (if (not (mh-assoc-ignore-case (car user) mh-alias-alist)) | 225 (if (not (mh-assoc-ignore-case (car user) mh-alias-alist)) |
270 (setq mh-alias-alist (append mh-alias-alist (list user)))) | 226 (setq mh-alias-alist (append mh-alias-alist (list user)))) |
271 (setq local-users (cdr local-users))))) | 227 (setq local-users (cdr local-users))))) |
228 (run-hooks 'mh-alias-reloaded-hook) | |
272 (message "Loading MH aliases...done")) | 229 (message "Loading MH aliases...done")) |
273 | 230 |
274 ;;;###mh-autoload | 231 ;;;###mh-autoload |
275 (defun mh-alias-reload-maybe () | 232 (defun mh-alias-reload-maybe () |
276 "Load new MH aliases." | 233 "Load new MH aliases." |
277 (if (or (eq mh-alias-alist 'not-read) ; Doesn't exist, so create it. | 234 (if (or (eq mh-alias-alist 'not-read) ; Doesn't exist? |
278 (mh-alias-tstamp nil)) ; Out of date, so recreate it. | 235 (mh-alias-tstamp nil)) ; Out of date? |
279 (mh-alias-reload))) | 236 (mh-alias-reload))) |
280 | 237 |
281 | 238 |
282 ;;; Alias Expansion | 239 ;;; Alias Expansion |
283 | 240 |
459 the-list nil) | 416 the-list nil) |
460 (setq the-list (cdr the-list))))) | 417 (setq the-list (cdr the-list))))) |
461 found))) | 418 found))) |
462 | 419 |
463 (defun mh-alias-insert-file (&optional alias) | 420 (defun mh-alias-insert-file (&optional alias) |
464 "Return the alias file to write a new entry for ALIAS in. | 421 "Return filename which should be used to add ALIAS. |
465 Use variable `mh-alias-insert-file' if non-nil, else use AliasFile component | 422 The value of the option `mh-alias-insert-file' is used if non-nil\; otherwise |
466 value. | 423 the value of the `Aliasfile:' profile component is used. |
467 If ALIAS is specified and it already exists, try to return the file that | 424 If the alias already exists, try to return the name of the file that contains |
468 contains it." | 425 it." |
469 (cond | 426 (cond |
470 ((and mh-alias-insert-file (listp mh-alias-insert-file)) | 427 ((and mh-alias-insert-file (listp mh-alias-insert-file)) |
471 (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it | 428 (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it |
472 (car mh-alias-insert-file) | 429 (car mh-alias-insert-file) |
473 (if (or (not alias) | 430 (if (or (not alias) |
474 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist | 431 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist |
475 (completing-read "Alias file [press Tab]: " | 432 (completing-read "Alias file: " |
476 (mapcar 'list mh-alias-insert-file) nil t) | 433 (mapcar 'list mh-alias-insert-file) nil t) |
477 (or (mh-alias-which-file-has-alias alias mh-alias-insert-file) | 434 (or (mh-alias-which-file-has-alias alias mh-alias-insert-file) |
478 (completing-read "Alias file [press Tab]: " | 435 (completing-read "Alias file: " |
479 (mapcar 'list mh-alias-insert-file) nil t))))) | 436 (mapcar 'list mh-alias-insert-file) nil t))))) |
480 ((and mh-alias-insert-file (stringp mh-alias-insert-file)) | 437 ((and mh-alias-insert-file (stringp mh-alias-insert-file)) |
481 mh-alias-insert-file) | 438 mh-alias-insert-file) |
482 (t | 439 (t |
483 ;; writable ones returned from (mh-alias-filenames): | 440 ;; writable ones returned from (mh-alias-filenames): |
488 file)) | 445 file)) |
489 (mh-alias-filenames t))))) | 446 (mh-alias-filenames t))))) |
490 (cond | 447 (cond |
491 ((not autolist) | 448 ((not autolist) |
492 (error "No writable alias file. | 449 (error "No writable alias file. |
493 Set `mh-alias-insert-file' or set AliasFile in your .mh_profile file")) | 450 Set `mh-alias-insert-file' or the Aliasfile profile component")) |
494 ((not (elt autolist 1)) ; Only one entry, use it | 451 ((not (elt autolist 1)) ; Only one entry, use it |
495 (car autolist)) | 452 (car autolist)) |
496 ((or (not alias) | 453 ((or (not alias) |
497 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist | 454 (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist |
498 (completing-read "Alias file [press Tab]: " | 455 (completing-read "Alias file: " (mapcar 'list autolist) nil t)) |
499 (mapcar 'list autolist) nil t)) | |
500 (t | 456 (t |
501 (or (mh-alias-which-file-has-alias alias autolist) | 457 (or (mh-alias-which-file-has-alias alias autolist) |
502 (completing-read "Alias file [press Tab]: " | 458 (completing-read "Alias file: " |
503 (mapcar 'list autolist) nil t)))))))) | 459 (mapcar 'list autolist) nil t)))))))) |
504 | 460 |
505 ;;;###mh-autoload | 461 ;;;###mh-autoload |
506 (defun mh-alias-address-to-alias (address) | 462 (defun mh-alias-address-to-alias (address) |
507 "Return the ADDRESS alias if defined, or nil." | 463 "Return the ADDRESS alias if defined, or nil." |
518 nil | 474 nil |
519 alias)))) | 475 alias)))) |
520 (split-string aliases ", +"))))))) | 476 (split-string aliases ", +"))))))) |
521 | 477 |
522 ;;;###mh-autoload | 478 ;;;###mh-autoload |
523 (defun mh-alias-from-has-no-alias-p () | 479 (defun mh-alias-for-from-p () |
524 "Return t is From has no current alias set. | 480 "Return t if sender's address has a corresponding alias." |
525 In the exceptional situation where there isn't a From header in the message the | |
526 function returns nil." | |
527 (mh-alias-reload-maybe) | 481 (mh-alias-reload-maybe) |
528 (save-excursion | 482 (save-excursion |
529 (if (not (mh-folder-line-matches-show-buffer-p)) | 483 (if (not (mh-folder-line-matches-show-buffer-p)) |
530 nil ;No corresponding show buffer | 484 nil ;No corresponding show buffer |
531 (if (eq major-mode 'mh-folder-mode) | 485 (if (eq major-mode 'mh-folder-mode) |
532 (set-buffer mh-show-buffer)) | 486 (set-buffer mh-show-buffer)) |
533 (let ((from-header (mh-extract-from-header-value))) | 487 (let ((from-header (mh-extract-from-header-value))) |
534 (and from-header | 488 (and from-header |
535 (not (mh-alias-address-to-alias from-header))))))) | 489 (mh-alias-address-to-alias from-header)))))) |
536 | 490 |
537 (defun mh-alias-add-alias-to-file (alias address &optional file) | 491 (defun mh-alias-add-alias-to-file (alias address &optional file) |
538 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts. | 492 "Add ALIAS for ADDRESS in alias FILE without alias check or prompts. |
539 Prompt for alias file if not provided and there is more than one candidate. | 493 Prompt for alias file if not provided and there is more than one candidate. |
540 If ALIAS matches exactly, prompt to [i]nsert before old value or [a]ppend | 494 |
541 after it." | 495 If the alias exists already, you will have the choice of inserting the new |
496 alias before or after the old alias. In the former case, this alias will be | |
497 used when sending mail to this alias. In the latter case, the alias serves as | |
498 an additional folder name hint when filing messages." | |
542 (if (not file) | 499 (if (not file) |
543 (setq file (mh-alias-insert-file alias))) | 500 (setq file (mh-alias-insert-file alias))) |
544 (save-excursion | 501 (save-excursion |
545 (set-buffer (find-file-noselect file)) | 502 (set-buffer (find-file-noselect file)) |
546 (goto-char (point-min)) | 503 (goto-char (point-min)) |
550 (cond | 507 (cond |
551 ;; Search for exact match (if we had the same alias before) | 508 ;; Search for exact match (if we had the same alias before) |
552 ((re-search-forward | 509 ((re-search-forward |
553 (concat "^" (regexp-quote alias-search) " *\\(.*\\)") nil t) | 510 (concat "^" (regexp-quote alias-search) " *\\(.*\\)") nil t) |
554 (let ((answer (read-string | 511 (let ((answer (read-string |
555 (format "Exists for %s; [i]nsert, [a]ppend: " | 512 (format (concat "Alias %s exists; insert new address " |
513 "[b]efore or [a]fter: ") | |
556 (match-string 1)))) | 514 (match-string 1)))) |
557 (case-fold-search t)) | 515 (case-fold-search t)) |
558 (cond ((string-match "^i" answer)) | 516 (cond ((string-match "^b" answer)) |
559 ((string-match "^a" answer) | 517 ((string-match "^a" answer) |
560 (forward-line 1)) | 518 (forward-line 1)) |
561 (t | 519 (t |
562 (error "Quitting"))))) | 520 (error "Unrecognized response"))))) |
563 ;; No, so sort-in at the right place | 521 ;; No, so sort-in at the right place |
564 ;; search for "^alias", then "^alia", etc. | 522 ;; search for "^alias", then "^alia", etc. |
565 ((eq mh-alias-insertion-location 'sorted) | 523 ((eq mh-alias-insertion-location 'sorted) |
566 (setq letter (substring alias-search -1) | 524 (setq letter (substring alias-search -1) |
567 alias-search (substring alias-search 0 -1)) | 525 alias-search (substring alias-search 0 -1)) |
585 (save-buffer))) | 543 (save-buffer))) |
586 | 544 |
587 ;;;###mh-autoload | 545 ;;;###mh-autoload |
588 (defun mh-alias-add-alias (alias address) | 546 (defun mh-alias-add-alias (alias address) |
589 "*Add ALIAS for ADDRESS in personal alias file. | 547 "*Add ALIAS for ADDRESS in personal alias file. |
590 Prompts for confirmation if the address already has an alias. | 548 This function prompts you for an alias and address. If the alias exists |
591 If the alias is already is use, `mh-alias-add-alias-to-file' will prompt." | 549 already, you will have the choice of inserting the new alias before or after |
550 the old alias. In the former case, this alias will be used when sending mail | |
551 to this alias. In the latter case, the alias serves as an additional folder | |
552 name hint when filing messages." | |
592 (interactive "P\nP") | 553 (interactive "P\nP") |
593 (mh-alias-reload-maybe) | 554 (mh-alias-reload-maybe) |
594 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias)) | 555 (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias)) |
595 (if (and address (string-match "^<\\(.*\\)>$" address)) | 556 (if (and address (string-match "^<\\(.*\\)>$" address)) |
596 (setq address (match-string 1 address))) | 557 (setq address (match-string 1 address))) |
612 (t | 573 (t |
613 (mh-alias-add-alias-to-file alias address))))) | 574 (mh-alias-add-alias-to-file alias address))))) |
614 | 575 |
615 ;;;###mh-autoload | 576 ;;;###mh-autoload |
616 (defun mh-alias-grab-from-field () | 577 (defun mh-alias-grab-from-field () |
617 "*Add ALIAS for ADDRESS in personal alias file. | 578 "*Add alias for the sender of the current message." |
618 Prompts for confirmation if the alias is already in use or if the address | |
619 already has an alias." | |
620 (interactive) | 579 (interactive) |
621 (mh-alias-reload-maybe) | 580 (mh-alias-reload-maybe) |
622 (save-excursion | 581 (save-excursion |
623 (cond | 582 (cond |
624 ((mh-folder-line-matches-show-buffer-p) | 583 ((mh-folder-line-matches-show-buffer-p) |
634 (alias (mh-alias-suggest-alias address))) | 593 (alias (mh-alias-suggest-alias address))) |
635 (mh-alias-add-alias alias address)))) | 594 (mh-alias-add-alias alias address)))) |
636 | 595 |
637 ;;;###mh-autoload | 596 ;;;###mh-autoload |
638 (defun mh-alias-add-address-under-point () | 597 (defun mh-alias-add-address-under-point () |
639 "Insert an alias for email address under point." | 598 "Insert an alias for address under point." |
640 (interactive) | 599 (interactive) |
641 (let ((address (mh-goto-address-find-address-at-point))) | 600 (let ((address (mh-goto-address-find-address-at-point))) |
642 (if address | 601 (if address |
643 (mh-alias-add-alias nil address) | 602 (mh-alias-add-alias nil address) |
644 (message "No email address found under point.")))) | 603 (message "No email address found under point")))) |
645 | 604 |
646 ;;;###mh-autoload | 605 ;;;###mh-autoload |
647 (defun mh-alias-apropos (regexp) | 606 (defun mh-alias-apropos (regexp) |
648 "Show all aliases that match REGEXP either in name or content." | 607 "Show all aliases or addresses that match REGEXP." |
649 (interactive "sAlias regexp: ") | 608 (interactive "sAlias regexp: ") |
650 (if mh-alias-local-users | 609 (if mh-alias-local-users |
651 (mh-alias-reload-maybe)) | 610 (mh-alias-reload-maybe)) |
652 (let ((matches "")(group-matches "")(passwd-matches)) | 611 (let ((matches "") |
612 (group-matches "") | |
613 (passwd-matches)) | |
653 (save-excursion | 614 (save-excursion |
654 (message "Reading MH aliases...") | 615 (message "Reading MH aliases...") |
655 (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser") | 616 (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser") |
656 (message "Reading MH aliases...done. Parsing...") | 617 (message "Parsing MH aliases...") |
657 (while (re-search-forward regexp nil t) | 618 (while (re-search-forward regexp nil t) |
658 (beginning-of-line) | 619 (beginning-of-line) |
659 (cond | 620 (cond |
660 ((looking-at "^[ \t]") ;Continuation line | 621 ((looking-at "^[ \t]") ;Continuation line |
661 (setq group-matches | 622 (setq group-matches |
671 (t | 632 (t |
672 (setq matches | 633 (setq matches |
673 (concat matches | 634 (concat matches |
674 (buffer-substring (point)(progn (end-of-line)(point))) | 635 (buffer-substring (point)(progn (end-of-line)(point))) |
675 "\n"))))) | 636 "\n"))))) |
676 (message "Reading MH aliases...done. Parsing...done.") | 637 (message "Parsing MH aliases...done") |
677 (when mh-alias-local-users | 638 (when mh-alias-local-users |
678 (message | 639 (message "Making passwd aliases...") |
679 "Reading MH aliases...done. Parsing...done. Passwd aliases...") | |
680 (setq passwd-matches | 640 (setq passwd-matches |
681 (mapconcat | 641 (mapconcat |
682 '(lambda (elem) | 642 '(lambda (elem) |
683 (if (or (string-match regexp (car elem)) | 643 (if (or (string-match regexp (car elem)) |
684 (string-match regexp (cadr elem))) | 644 (string-match regexp (cadr elem))) |
685 (format "%s: %s\n" (car elem) (cadr elem)))) | 645 (format "%s: %s\n" (car elem) (cadr elem)))) |
686 mh-alias-passwd-alist "")) | 646 mh-alias-passwd-alist "")) |
687 (message | 647 (message "Making passwd aliases...done"))) |
688 "Reading MH aliases...done. Parsing...done. Passwd aliases...done."))) | |
689 (if (and (string-equal "" matches) | 648 (if (and (string-equal "" matches) |
690 (string-equal "" group-matches) | 649 (string-equal "" group-matches) |
691 (string-equal "" passwd-matches)) | 650 (string-equal "" passwd-matches)) |
692 (message "No matches") | 651 (message "No matches") |
693 (with-output-to-temp-buffer "*Help*" | 652 (with-output-to-temp-buffer mh-aliases-buffer |
694 (if (not (string-equal "" matches)) | 653 (if (not (string-equal "" matches)) |
695 (princ matches)) | 654 (princ matches)) |
696 (when (not (string-equal group-matches "")) | 655 (when (not (string-equal group-matches "")) |
697 (princ "\nGroup Aliases:\n\n") | 656 (princ "\nGroup Aliases:\n\n") |
698 (princ group-matches)) | 657 (princ group-matches)) |