]> code.delx.au - gnu-emacs/blobdiff - lisp/mh-e/mh-alias.el
** offby1@blarg.net, Nov 5: calendar gets wrong end for Daylight Savings Time
[gnu-emacs] / lisp / mh-e / mh-alias.el
index 1356e2c8b95f07377c8b66d90fa390c7e24486d8..6dba65d69df9fd95a2fa74d50e5d769b2388938d 100644 (file)
@@ -1,7 +1,7 @@
 ;;; mh-alias.el --- MH-E mail alias completion and expansion
-;;
-;; Copyright (C) 1994, 95, 96, 1997,
-;;  2001, 02, 03, 2004 Free Software Foundation, Inc.
+
+;; Copyright (C) 1994, 1995, 1996, 1997,
+;;  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Peter S. Galbraith <psg@debian.org>
 ;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -22,8 +22,8 @@
 
 ;; 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.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'mh-acros))
-(mh-require-cl)
 (require 'mh-e)
-(load "cmr" t t)                        ; Non-fatal dependency for
-                                       ; completing-read-multiple.
-(eval-when-compile (defvar mail-abbrev-syntax-table))
 
-;;; Autoloads
-(eval-when (compile load eval)
-  (ignore-errors
-    (require 'mailabbrev)
-    (require 'multi-prompt)))
+(mh-require-cl)
+
+(require 'goto-addr)
 
 (defvar mh-alias-alist 'not-read
   "Alist of MH aliases.")
@@ -55,7 +48,7 @@
 (defvar mh-alias-read-address-map nil)
 (unless mh-alias-read-address-map
   (setq mh-alias-read-address-map
-       (copy-keymap minibuffer-local-completion-map))
+        (copy-keymap minibuffer-local-completion-map))
   (define-key mh-alias-read-address-map
     "," 'mh-alias-minibuffer-confirm-address)
   (define-key mh-alias-read-address-map " " 'self-insert-command))
     "/usr/lib/mh/MailAliases" "/usr/share/mailutils/mh/MailAliases"
     "/etc/passwd")
   "*A list of system files which are a source of aliases.
-If these files are modified, they are automatically reread. This list need
-include only system aliases and the passwd file, since personal alias files
-listed in your `Aliasfile:' MH profile component are automatically included.
-You can update the alias list manually using \\[mh-alias-reload].")
+If these files are modified, they are automatically reread. This list
+need include only system aliases and the passwd file, since personal
+alias files listed in your \"Aliasfile:\" MH profile component are
+automatically included. You can update the alias list manually using
+\\[mh-alias-reload].")
 
 \f
-;;; Alias Loading
 
-(defmacro mh-assoc-ignore-case (key alist)
-  "Search for string KEY in ALIST.
-This is a wrapper around `assoc-string' or `assoc-ignore-case'. Avoid
-`assoc-ignore-case' which is now an obsolete function."
-  (cond ((fboundp 'assoc-string) `(assoc-string ,key ,alist t))
-        ((fboundp 'assoc-ignore-case) `(assoc-ignore-case ,key ,alist))
-        (t (error "The macro mh-assoc-ignore-case not implemented properly"))))
+;;; Alias Loading
 
 (defun mh-alias-tstamp (arg)
   "Check whether alias files have been modified.
-Return t if any file listed in the Aliasfile MH profile component has been
-modified since the timestamp.
+Return t if any file listed in the Aliasfile MH profile component has
+been modified since the timestamp.
 If ARG is non-nil, set timestamp with the current time."
   (if arg
       (let ((time (current-time)))
@@ -102,8 +89,10 @@ If ARG is non-nil, set timestamp with the current time."
 
 (defun mh-alias-filenames (arg)
   "Return list of filenames that contain aliases.
-The filenames come from the Aliasfile profile component and are expanded.
-If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
+The filenames come from the Aliasfile profile component and are
+expanded.
+If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are
+appended."
   (or mh-progs (mh-find-path))
   (save-excursion
     (let* ((filename (mh-profile-component "Aliasfile"))
@@ -124,8 +113,8 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
 
 (defun mh-alias-gecos-name (gecos-name username comma-separator)
   "Return a usable address string from a GECOS-NAME and USERNAME.
-Use only part of the GECOS-NAME up to the first comma if COMMA-SEPARATOR is
-non-nil."
+Use only part of the GECOS-NAME up to the first comma if
+COMMA-SEPARATOR is non-nil."
   (let ((res gecos-name))
     ;; Keep only string until first comma if COMMA-SEPARATOR is t.
     (if (and comma-separator
@@ -133,10 +122,10 @@ non-nil."
         (setq res (match-string 1 res)))
     ;; Replace "&" with capitalized username
     (if (string-match "&" res)
-        (setq res (mh-replace-in-string "&" (capitalize username) res)))
+        (setq res (mh-replace-regexp-in-string "&" (capitalize username) res)))
     ;; Remove " character
     (if (string-match "\"" res)
-        (setq res (mh-replace-in-string "\"" "" res)))
+        (setq res (mh-replace-regexp-in-string "\"" "" res)))
     ;; If empty string, use username instead
     (if (string-equal "" res)
         (setq res username))
@@ -147,7 +136,7 @@ non-nil."
 
 (defun mh-alias-local-users ()
   "Return an alist of local users from /etc/passwd.
-Exclude all aliases already in `mh-alias-alist' from `ali'"
+Exclude all aliases already in `mh-alias-alist' from \"ali\""
   (let (passwd-alist)
     (save-excursion
       (set-buffer (get-buffer-create mh-temp-buffer))
@@ -163,38 +152,38 @@ Exclude all aliases already in `mh-alias-alist' from `ali'"
       (while  (< (point) (point-max))
         (cond
          ((looking-at "\\([^:]*\\):[^:]*:\\([^:]*\\):[^:]*:\\([^:]*\\):")
-          (when (> (string-to-int (match-string 2)) 200)
+          (when (> (string-to-number (match-string 2)) 200)
             (let* ((username (match-string 1))
                    (gecos-name (match-string 3))
                    (realname (mh-alias-gecos-name
                               gecos-name username
                               mh-alias-passwd-gecos-comma-separator-flag))
                    (alias-name (if mh-alias-local-users-prefix
-                                  (concat mh-alias-local-users-prefix
-                                          (mh-alias-suggest-alias realname t))
-                                username))
+                                   (concat mh-alias-local-users-prefix
+                                           (mh-alias-suggest-alias realname t))
+                                 username))
                    (alias-translation
                     (if (string-equal username realname)
                         (concat "<" username ">")
                       (concat realname " <" username ">"))))
-              (when (not (mh-assoc-ignore-case alias-name mh-alias-alist))
+              (when (not (mh-assoc-string alias-name mh-alias-alist t))
                 (setq passwd-alist (cons (list alias-name alias-translation)
                                          passwd-alist)))))))
         (forward-line 1)))
     passwd-alist))
 
-;;;###mh-autoload
 (defun mh-alias-reload ()
   "Reload MH aliases.
 
-Since aliases are updated frequently, MH-E will reload aliases automatically
-whenever an alias lookup occurs if an alias source (a file listed in your
-`Aliasfile:' profile component and your password file if variable
-`mh-alias-local-users' is non-nil) has changed. However, you can reload your
-aliases manually by calling this command directly.
+Since aliases are updated frequently, MH-E reloads aliases
+automatically whenever an alias lookup occurs if an alias source has
+changed. Sources include files listed in your \"Aliasfile:\" profile
+component and your password file if option `mh-alias-local-users' is
+turned on. However, you can reload your aliases manually by calling
+this command directly.
 
-The value of `mh-alias-reloaded-hook' is a list of functions to be called,
-with no arguments, after the aliases have been loaded."
+This function runs `mh-alias-reloaded-hook' after the aliases have
+been loaded."
   (interactive)
   (save-excursion
     (message "Loading MH aliases...")
@@ -206,12 +195,12 @@ with no arguments, after the aliases have been loaded."
       (cond
        ((looking-at "^[ \t]"))          ;Continuation line
        ((looking-at "\\(.+\\): .+: .*$") ; A new -blind- MH alias
-        (when (not (mh-assoc-ignore-case (match-string 1) mh-alias-blind-alist))
+        (when (not (mh-assoc-string (match-string 1) mh-alias-blind-alist t))
           (setq mh-alias-blind-alist
                 (cons (list (match-string 1)) mh-alias-blind-alist))
           (setq mh-alias-alist (cons (list (match-string 1)) mh-alias-alist))))
        ((looking-at "\\(.+\\): .*$")    ; A new MH alias
-        (when (not (mh-assoc-ignore-case (match-string 1) mh-alias-alist))
+        (when (not (mh-assoc-string (match-string 1) mh-alias-alist t))
           (setq mh-alias-alist
                 (cons (list (match-string 1)) mh-alias-alist)))))
       (forward-line 1)))
@@ -222,7 +211,7 @@ with no arguments, after the aliases have been loaded."
           user)
       (while local-users
         (setq user (car local-users))
-        (if (not (mh-assoc-ignore-case (car user) mh-alias-alist))
+        (if (not (mh-assoc-string (car user) mh-alias-alist t))
             (setq mh-alias-alist (append mh-alias-alist (list user))))
         (setq local-users (cdr local-users)))))
   (run-hooks 'mh-alias-reloaded-hook)
@@ -236,13 +225,14 @@ with no arguments, after the aliases have been loaded."
       (mh-alias-reload)))
 
 \f
+
 ;;; Alias Expansion
 
 (defun mh-alias-ali (alias &optional user)
   "Return ali expansion for ALIAS.
 ALIAS must be a string for a single alias.
-If USER is t, then assume ALIAS is an address and call ali -user.
-ali returns the string unchanged if not defined.  The same is done here."
+If USER is t, then assume ALIAS is an address and call ali -user. ali
+returns the string unchanged if not defined. The same is done here."
   (condition-case err
       (save-excursion
         (let ((user-arg (if user "-user" "-nouser")))
@@ -251,25 +241,28 @@ ali returns the string unchanged if not defined.  The same is done here."
         (if (looking-at "^$") (delete-backward-char 1))
         (buffer-substring (point-min)(point-max)))
     (error (progn
-             (message (error-message-string err))
+             (message "%s" (error-message-string err))
              alias))))
 
 (defun mh-alias-expand (alias)
   "Return expansion for ALIAS.
 Blind aliases or users from /etc/passwd are not expanded."
   (cond
-   ((mh-assoc-ignore-case alias mh-alias-blind-alist)
+   ((mh-assoc-string alias mh-alias-blind-alist t)
     alias)                              ; Don't expand a blind alias
-   ((mh-assoc-ignore-case alias mh-alias-passwd-alist)
-    (cadr (mh-assoc-ignore-case alias mh-alias-passwd-alist)))
+   ((mh-assoc-string alias mh-alias-passwd-alist t)
+    (cadr (mh-assoc-string alias mh-alias-passwd-alist t)))
    (t
     (mh-alias-ali alias))))
 
+(mh-require 'crm nil t)                 ; completing-read-multiple
+(mh-require 'multi-prompt nil t)
+
 ;;;###mh-autoload
 (defun mh-read-address (prompt)
   "Read an address from the minibuffer with PROMPT."
   (mh-alias-reload-maybe)
-  (if (not mh-alias-alist)             ; If still no aliases, just prompt
+  (if (not mh-alias-alist)              ; If still no aliases, just prompt
       (read-string prompt)
     (let* ((minibuffer-local-completion-map mh-alias-read-address-map)
            (completion-ignore-case mh-alias-completion-ignore-case-flag)
@@ -296,7 +289,7 @@ Blind aliases or users from /etc/passwd are not expanded."
       (let* ((case-fold-search t)
              (beg (mh-beginning-of-word))
              (the-name (buffer-substring-no-properties beg (point))))
-        (if (mh-assoc-ignore-case the-name mh-alias-alist)
+        (if (mh-assoc-string the-name mh-alias-alist t)
             (message "%s -> %s" the-name (mh-alias-expand the-name))
           ;; Check if if was a single word likely to be an alias
           (if (and (equal mh-alias-flash-on-comma 1)
@@ -304,8 +297,6 @@ Blind aliases or users from /etc/passwd are not expanded."
               (message "No alias for %s" the-name))))))
   (self-insert-command 1))
 
-(mh-do-in-xemacs (defvar mail-abbrevs))
-
 ;;;###mh-autoload
 (defun mh-alias-letter-expand-alias ()
   "Expand mail alias before point."
@@ -319,13 +310,15 @@ Blind aliases or users from /etc/passwd are not expanded."
              (expansion (mh-alias-expand (buffer-substring begin end))))
         (delete-region begin end)
         (insert expansion)))))
+
 \f
-;;; Adding addresses to alias file.
+
+;;; Alias File Updating
 
 (defun mh-alias-suggest-alias (string &optional no-comma-swap)
   "Suggest an alias for STRING.
-Don't reverse the order of strings separated by a comma if NO-COMMA-SWAP is
-non-nil."
+Don't reverse the order of strings separated by a comma if
+NO-COMMA-SWAP is non-nil."
   (cond
    ((string-match "^<\\(.*\\)>$" string)
     ;; <somename@foo.bar>  -> recurse, stripping brackets.
@@ -347,7 +340,7 @@ non-nil."
    ((string-match "^\\(.*\\) +<.*>$" string)
     ;; Some name <somename@foo.bar>  -> recurse -> Some name
     (mh-alias-suggest-alias (match-string 1 string) no-comma-swap))
-   ((string-match (concat mh-address-mail-regexp " +(\\(.*\\))$") string)
+   ((string-match (concat goto-address-mail-regexp " +(\\(.*\\))$") string)
     ;; somename@foo.bar (Some name)  -> recurse -> Some name
     (mh-alias-suggest-alias (match-string 1 string) no-comma-swap))
    ((string-match "^\\(Dr\\|Prof\\)\\.? +\\(.*\\)" string)
@@ -380,8 +373,8 @@ non-nil."
 (defun mh-alias-canonicalize-suggestion (string)
   "Process STRING to replace spaces by periods.
 First all spaces and commas are replaced by periods. Then every run of
-consecutive periods are replaced with a single period. Finally the string
-is converted to lower case."
+consecutive periods are replaced with a single period. Finally the
+string is converted to lower case."
   (with-temp-buffer
     (insert string)
     ;; Replace spaces with periods
@@ -419,10 +412,10 @@ is converted to lower case."
 
 (defun mh-alias-insert-file (&optional alias)
   "Return filename which should be used to add ALIAS.
-The value of the option `mh-alias-insert-file' is used if non-nil\; otherwise
-the value of the `Aliasfile:' profile component is used.
-If the alias already exists, try to return the name of the file that contains
-it."
+The value of the option `mh-alias-insert-file' is used if non-nil\;
+otherwise the value of the \"Aliasfile:\" profile component is used.
+If the alias already exists, try to return the name of the file that
+contains it."
   (cond
    ((and mh-alias-insert-file (listp mh-alias-insert-file))
     (if (not (elt mh-alias-insert-file 1))        ; Only one entry, use it
@@ -446,8 +439,8 @@ it."
                                      (mh-alias-filenames t)))))
       (cond
        ((not autolist)
-        (error "No writable alias file.
-Set `mh-alias-insert-file' or the Aliasfile profile component"))
+        (error "No writable alias file;
+set `mh-alias-insert-file' or the \"Aliasfile:\" profile component"))
        ((not (elt autolist 1))        ; Only one entry, use it
         (car autolist))
        ((or (not alias)
@@ -490,12 +483,14 @@ Set `mh-alias-insert-file' or the Aliasfile profile component"))
 
 (defun mh-alias-add-alias-to-file (alias address &optional file)
   "Add ALIAS for ADDRESS in alias FILE without alias check or prompts.
-Prompt for alias file if not provided and there is more than one candidate.
-
-If the alias exists already, you will have the choice of inserting the new
-alias before or after the old alias. In the former case, this alias will be
-used when sending mail to this alias. In the latter case, the alias serves as
-an additional folder name hint when filing messages."
+Prompt for alias file if not provided and there is more than one
+candidate.
+
+If the alias exists already, you will have the choice of
+inserting the new alias before or after the old alias. In the
+former case, this alias will be used when sending mail to this
+alias. In the latter case, the alias serves as an additional
+folder name hint when filing messages."
   (if (not file)
       (setq file (mh-alias-insert-file alias)))
   (save-excursion
@@ -542,14 +537,15 @@ an additional folder name hint when filing messages."
     (insert (format "%s: %s\n" alias address))
     (save-buffer)))
 
-;;;###mh-autoload
 (defun mh-alias-add-alias (alias address)
-  "*Add ALIAS for ADDRESS in personal alias file.
-This function prompts you for an alias and address. If the alias exists
-already, you will have the choice of inserting the new alias before or after
-the old alias. In the former case, this alias will be used when sending mail
-to this alias. In the latter case, the alias serves as an additional folder
-name hint when filing messages."
+  "Add ALIAS for ADDRESS in personal alias file.
+
+This function prompts you for an alias and address. If the alias
+exists already, you will have the choice of inserting the new
+alias before or after the old alias. In the former case, this
+alias will be used when sending mail to this alias. In the latter
+case, the alias serves as an additional folder name hint when
+filing messages."
   (interactive "P\nP")
   (mh-alias-reload-maybe)
   (setq alias (completing-read "Alias: " mh-alias-alist nil nil alias))
@@ -565,7 +561,7 @@ name hint when filing messages."
     (cond
      ((and (equal alias address-alias)
            (equal address alias-address))
-      (message "Already defined as: %s" alias-address))
+      (message "Already defined as %s" alias-address))
      (address-alias
       (if (y-or-n-p (format "Address has alias %s; set new one? "
                             address-alias))
@@ -575,7 +571,7 @@ name hint when filing messages."
 
 ;;;###mh-autoload
 (defun mh-alias-grab-from-field ()
-  "*Add alias for the sender of the current message."
+  "Add alias for the sender of the current message."
   (interactive)
   (mh-alias-reload-maybe)
   (save-excursion
@@ -593,18 +589,16 @@ name hint when filing messages."
            (alias (mh-alias-suggest-alias address)))
       (mh-alias-add-alias alias address))))
 
-;;;###mh-autoload
 (defun mh-alias-add-address-under-point ()
   "Insert an alias for address under point."
   (interactive)
-  (let ((address (mh-goto-address-find-address-at-point)))
+  (let ((address (goto-address-find-address-at-point)))
     (if address
         (mh-alias-add-alias nil address)
       (message "No email address found under point"))))
 
-;;;###mh-autoload
 (defun mh-alias-apropos (regexp)
-  "Show all aliases or addresses that match REGEXP."
+  "Show all aliases or addresses that match a regular expression REGEXP."
   (interactive "sAlias regexp: ")
   (if mh-alias-local-users
       (mh-alias-reload-maybe))
@@ -659,12 +653,27 @@ name hint when filing messages."
           (princ "\nLocal User Aliases:\n\n")
           (princ passwd-matches))))))
 
+(defun mh-folder-line-matches-show-buffer-p ()
+  "Return t if the message under point in folder-mode is in the show buffer.
+Return nil in any other circumstance (no message under point, no
+show buffer, the message in the show buffer doesn't match."
+  (and (eq major-mode 'mh-folder-mode)
+       (mh-get-msg-num nil)
+       mh-show-buffer
+       (get-buffer mh-show-buffer)
+       (buffer-file-name (get-buffer mh-show-buffer))
+       (string-match ".*/\\([0-9]+\\)$"
+                     (buffer-file-name (get-buffer mh-show-buffer)))
+       (string-equal
+        (match-string 1 (buffer-file-name (get-buffer mh-show-buffer)))
+        (int-to-string (mh-get-msg-num nil)))))
+
 (provide 'mh-alias)
 
-;;; Local Variables:
-;;; indent-tabs-mode: nil
-;;; sentence-end-double-space: nil
-;;; End:
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; sentence-end-double-space: nil
+;; End:
 
-;;; arch-tag: 49879e46-5aa3-4569-bece-e5a58731d690
+;; arch-tag: 49879e46-5aa3-4569-bece-e5a58731d690
 ;;; mh-alias.el ends here