Commit 924df208 authored by Bill Wohler's avatar Bill Wohler
Browse files

Upgraded to MH-E version 7.3.

See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
parent 0b325c12
2003-04-24 Bill Wohler <wohler@newt.com>
* MH-E-NEWS: Upgraded to MH-E version 7.3.
2003-04-03 Kenichi Handa <handa@etlken2>
* HELLO: Fix the malayalam line.
......
Copyright (C) 2003 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
* Changes in MH-E 7.3
** New Features in MH-E 7.3
*** Unified function arguments
Any function with MSG-OR-SEQ in its docstring uses the displayed
message by default for this argument. However, if a prefix argument is
provided, then the user is prompted for a message sequence. If the
variable `transient-mark-mode' is non-nil and the mark is active, then
the function operates on the messages in the selected region. In a
program, MSG-OR-SEQ can be a message number, a list of message
numbers, a region in a cons cell, or a sequence.
*** MH-Index view of unseen messages
Use "F n (mh-index-new-messages)" or Folder -> View New Messages menu
item to display messages in the `mh-unseen-seq' sequence in folders
specified by `mh-index-new-messages-folders'. With a prefix argument,
enter a space-separated list of folders, or nothing to search all
folders.
Like other MH-Index folders, use "v (mh-index-visit-folder)" if you
wish to visit the original folder with the unseen message. This is
usually not necessary since the original message is annotated if you
reply, deleted if you delete the message, or refiled if you refile the
message (closes SF #701756).
*** Spam software support
MH-E now supports several spam filters including Bogofilter,
SpamProbe, and SpamAssassin. Spam that is mistakenly considered to be
good mail can be reclassified as spam with "J b (mh-junk-blacklist)".
Conversely, good mail that is accidently considered to be spam can be
reclassified with "J w (mh-junk-whitelist)" (closes SF #669518).
If a message is blacklisted, and `mh-junk-mail-folder' is a string,
then the message is refiled to that folder. If this variable is nil,
the message is deleted. If a message is whitelisted, then the message
is refiled to `mh-inbox'.
To change the spam program being used, customize `mh-junk-program'.
This should only be necessary if you have multiple filters on your
system and MH-E picked the wrong one. These customization variables
are found in the new customization group `mh-junk'.
The documentation for the following functions describes what setup is
needed for the different spam fighting programs:
- `mh-bogofilter-blacklist'
- `mh-spamprobe-blacklist'
- `mh-spamassassin-blacklist'
*** Relative folder specification @ supported
You can now use the relative folder marker @ in folder names (closes
SF #666774).
*** Marking messages
Messages can now be highlighted with "' (mh-toggle-tick)", Sequence ->
Toggle Tick Mark menu item or the "Toggle tick mark" button. These
messages are added to the "tick" sequence, although this sequence can
be changed in `mh-tick-seq'. The highlighting effect can be modified
by customizing `mh-folder-tick-face' (closes SF #623367).
There is also a new keybinding "/ ' (mh-narrow-to-tick)" and menu item
Sequence -> Narrow to Tick Sequence to narrow the view to the
highlighted messages.
*** mh-default-folder-list now takes recipients
If you wish to file a message based upon the recipient of a message
(such as a mailing list), you can now indicate that when filling out
the address in the `mh-default-folder-list' customization variable.
*** Face header field supported
In addition to the X-Face header field, the Face header field, which
can display color images, is now supported. As a bonus, the external
xface-e21 library is no longer required.
*** X-Image-URL support
Images specified in X-Image-URL header fields are now supported.
See the customization variable `mh-fetch-x-image-url' to enable this
support.
*** Fcc completion
Folders in Fcc fields in message drafts can now be completed with
M-TAB.
** New Variables in MH-E 7.3
Variables that have been added to MH-E that have not been discussed
elsewhere are listed here.
*** mh-auto-fields-list
Alist of addresses for which header lines are automatically inserted.
When a regular expression matches in the To or cc fields of a message,
the corresponding header field is automatically inserted in the
message header. It also allows the automatic setting of an identity
(using `mh-insert-identity') to set an alternate identity when sending
messages to a certain person or mailing list.
Since this is a more general use of `mh-insert-mail-followup-to-flag'
and `mh-insert-mail-followup-to-list', these variables have been removed.
*** mh-show-xface-face
Face for displaying the X-Face image.
*** mh-xemacs-toolbar-position
This customization variable allows the user to place the toolbar on
the four edges of the frame.
*** mh-xemacs-use-toolbar-flag
This customization variable is used to enable or disable the toolbar
under XEmacs.
** Variables Deleted in MH-E 7.3
Variables that have been removed from MH-E that have not been
discussed elsewhere are listed here.
*** mh-decode-content-transfer-encoded-message-flag
No longer needed since the external program mimencode is no longer
used.
*** mh-index-show-hook
This hook was never used, so it was removed.
*** mh-tool-bar-reply-3-buttons-flag
Obsolete. This functionality is present `mh-tool-bar-folder-buttons'.
** Bug Fixes in MH-E 7.3
*** Can't refile message
Messages with invalid addresses were causing errors in ali which
prevented the refiling of messages. The ali error is now shown in the
"*MH-E Log*" buffer and refiling suggests the last folder used (closes
SF #680388).
*** Empty body triggers duped header
If the body was empty the header would be treated like the body and
was therefore displayed twice. This has been fixed (closes SF
#681162).
*** mml or mhl directives not always processed
The mml and mhl directives used to create body parts were not
processed if one re-edited a draft, or if they added the directives
manually. The directives are now always processed upon sending the
letter. You may still, of course, use "C-c C-m m (mh-mml-to-mime)" or
"C-c C-e (mh-edit-mhn)" to manually create the MIME body parts from
the directives and then send the draft.
*** mh-alias-grab-from-field fails
MH-E was adding aliases with angle brackets around the address when
there wasn't a phrase (usually, the user's name), to go with it. This
caused ali to fail which caused problems in MH-E. This is probably a
bug in ali, but MH-E no longer inserts angle brackets around the
address unless there is a phrase, which avoids the problem (closes SF
#690216).
*** XEmacs fixes
MH-E is now fully supported under XEmacs and compiles without any
warnings.
In particular, the following now work under XEmacs:
- X-Face, Face, and X-Image-URL header fields
- MH-E logo in mode line
- Emphasis (bold, italics, etc.)
- Smilies
- Toolbar
*** Indexed folders should respect mh-show-threads-flag
Indexed folders are now threaded if `mh-show-threads-flag' is non-nil
(closes SF #709667).
*** Threading index view loses folder info
This has been fixed (closes SF #709672).
*** No undo information when re-editing drafts
Undo is turned on in the draft buffer when using "e (mh-edit-again)"
(closes SF #712777).
*** Forwarded base64 encoded messages are incorrectly displayed
This has been fixed (closes SF #681518).
*** Append to *MH-E Log* buffer
The last 100 lines of log messages are kept in the *MH-E Log* buffer.
Previously, the buffer was erased every time it was written (closes SF
#685476). In addition, many of the MH-E commands now send their output
into this buffer instead of a plethora of other special-purpose
buffers.
*** mh-inc-folder complains if no mail and no current message
The function `mh-inc-folder' no longer calls `mh-show' if point is not
on a valid scan line. This keeps `mh-inc-folder' from complaining
(closes SF #678115).
*** Folder normalization strips leading slash
Leading "/" characters in folder names entered by the user were being
lost. This has been fixed (closes SF #676890).
*** Print header doesn't show message
When printing a sequence, the header simply indicated that a sequence,
but not which one, was being printed and did not show the message
number. This has been fixed. If more than one message is printed, a
page of the scan lines is printed and its header indicates the
sequence or message range. The pages with the actual messages all set
the header to the folder and message displayed on that page.
*** Aliases constantly reloaded
Empty lists are now handled properly (closes SF #693859).
*** Remove RCS keywords
Removed RCS keywords per Emacs conventions (closes SF #680731).
*** Replace mimencode
MH-E was enhanced to decode message based on charset and
Content-Transfer-Encoding. This eliminates the need for the external
program mimencode (closes SF #674857).
* Changes in MH-E 7.2
This release includes the new features of filing hints, hierarchical
......
......@@ -100,7 +100,7 @@ You can now put the init files .emacs and .emacs_SHELL under
** MH-E changes.
Upgraded to MH-E version 7.2. There have been major changes since
Upgraded to MH-E version 7.3. There have been major changes since
version 5.0.2; see MH-E-NEWS for details.
+++
......
This diff is collapsed.
;;; mh-alias.el --- MH-E mail alias completion and expansion
;;
;; Copyright (C) 1994, 1995, 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
;; Copyright (C) 1994, 95, 96, 1997,
;; 2001, 02, 2003 Free Software Foundation, Inc.
;; Author: Peter S. Galbraith <psg@debian.org>
;; Maintainer: Bill Wohler <wohler@newt.com>
......@@ -93,8 +94,6 @@
;;; Change Log:
;; $Id: mh-alias.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
;;; Code:
(require 'mh-e)
......@@ -103,10 +102,12 @@
(eval-when-compile (defvar mail-abbrev-syntax-table))
;;; Autoloads
(autoload 'mail-abbrev-complete-alias "mailabbrev")
(autoload 'multi-prompt "multi-prompt")
(eval-when (compile load eval)
(ignore-errors
(require 'mailabbrev)
(require 'multi-prompt)))
(defvar mh-alias-alist nil
(defvar mh-alias-alist 'not-read
"Alist of MH aliases.")
(defvar mh-alias-blind-alist nil
"Alist of MH aliases that are blind lists.")
......@@ -180,7 +181,7 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
(insert-file-contents "/etc/passwd")))
((stringp mh-alias-local-users)
(insert mh-alias-local-users "\n")
(shell-command-on-region (point-min)(point-max) mh-alias-local-users t)
(shell-command-on-region (point-min) (point-max) mh-alias-local-users t)
(goto-char (point-min))))
(while (< (point) (point-max))
(cond
......@@ -241,7 +242,7 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
(defun mh-alias-reload-maybe ()
"Load new MH aliases."
(if (or (not mh-alias-alist) ; Doesn't exist, so create it.
(if (or (eq mh-alias-alist 'not-read) ; Doesn't exist, so create it.
(mh-alias-tstamp nil)) ; Out of date, so recreate it.
(mh-alias-reload)))
......@@ -253,12 +254,16 @@ If ARG is non-nil, filenames listed in `mh-alias-system-aliases' are appended."
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."
(save-excursion
(let ((user-arg (if user "-user" "-nouser")))
(mh-exec-cmd-quiet t "ali" user-arg "-nolist" alias))
(goto-char (point-max))
(if (looking-at "^$") (delete-backward-char 1))
(buffer-substring (point-min)(point-max))))
(condition-case err
(save-excursion
(let ((user-arg (if user "-user" "-nouser")))
(mh-exec-cmd-quiet t "ali" user-arg "-nolist" alias))
(goto-char (point-max))
(if (looking-at "^$") (delete-backward-char 1))
(buffer-substring (point-min)(point-max)))
(error (progn
(message (error-message-string err))
alias))))
(defun mh-alias-expand (alias)
"Return expansion for ALIAS.
......@@ -280,15 +285,14 @@ Blind aliases or users from /etc/passwd are not expanded."
(let* ((minibuffer-local-completion-map mh-alias-read-address-map)
(completion-ignore-case mh-alias-completion-ignore-case-flag)
(the-answer
(or (cond
((fboundp 'completing-read-multiple)
(completing-read-multiple prompt mh-alias-alist nil nil))
((featurep 'multi-prompt)
(multi-prompt "," nil prompt mh-alias-alist nil nil))
(t
(split-string
(completing-read prompt mh-alias-alist nil nil)
","))))))
(cond ((fboundp 'completing-read-multiple)
(mh-funcall-if-exists
completing-read-multiple prompt mh-alias-alist nil nil))
((featurep 'multi-prompt)
(mh-funcall-if-exists
multi-prompt "," nil prompt mh-alias-alist nil nil))
(t (split-string
(completing-read prompt mh-alias-alist nil nil) ",")))))
(if (not mh-alias-expand-aliases-flag)
(mapconcat 'identity the-answer ", ")
;; Loop over all elements, checking if in passwd aliast or blind first
......@@ -325,12 +329,14 @@ 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."
(mh-alias-reload-maybe)
(let ((mail-abbrevs mh-alias-alist))
(mail-abbrev-complete-alias))
(mh-funcall-if-exists mail-abbrev-complete-alias))
(when mh-alias-expand-aliases-flag
(let* ((end (point))
(syntax-table (syntax-table))
......@@ -350,6 +356,9 @@ Blind aliases or users from /etc/passwd are not expanded."
(defun mh-alias-suggest-alias (string)
"Suggest an alias for STRING."
(cond
((string-match "^<\\(.*\\)>$" string)
;; <somename@foo.bar> -> recurse, stripping brackets.
(mh-alias-suggest-alias (match-string 1 string)))
((string-match "^\\sw+$" string)
;; One word -> downcase it.
(downcase string))
......@@ -389,9 +398,25 @@ Blind aliases or users from /etc/passwd are not expanded."
(format "%s %s" (match-string 2 string) (match-string 1 string))))
(t
;; Output string, with spaces replaced by dots.
(downcase (replace-regexp-in-string
"\\.\\.+" "."
(replace-regexp-in-string " +" "." string))))))
(mh-alias-canonicalize-suggestion string))))
(defun mh-alias-canonicalize-suggestion (string)
"Process STRING to replace spacess by periods.
First all spaces are replaced by periods. Then every run of 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
(goto-char (point-min))
(replace-regexp " +" ".")
;; Replace consecutive periods with a single period
(goto-char (point-min))
(replace-regexp "\\.\\.+" ".")
;; Convert to lower case
(downcase-region (point-min) (point-max))
;; Whew! all done...
(buffer-string)))
(defun mh-alias-which-file-has-alias (alias file-list)
"Return the name of writable file which defines ALIAS from list FILE-LIST."
......@@ -403,7 +428,7 @@ Blind aliases or users from /etc/passwd are not expanded."
(erase-buffer)
(when (file-writable-p (car file-list))
(insert-file-contents (car file-list))
(if (re-search-forward (concat "^" (regexp-quote alias) ":"))
(if (re-search-forward (concat "^" (regexp-quote alias) ":") nil t)
(setq found (car file-list)
the-list nil)
(setq the-list (cdr the-list)))))
......@@ -470,14 +495,18 @@ Set `mh-alias-insert-file' or set AliasFile in your .mh_profile file"))
;;;###mh-autoload
(defun mh-alias-from-has-no-alias-p ()
"Return t is From has no current alias set."
"Return t is From has no current alias set.
In the exceptional situation where there isn't a From header in the message the
function returns nil."
(mh-alias-reload-maybe)
(save-excursion
(if (not (mh-folder-line-matches-show-buffer-p))
nil ;No corresponding show buffer
(if (eq major-mode 'mh-folder-mode)
(set-buffer mh-show-buffer))
(not (mh-alias-address-to-alias (mh-extract-from-header-value))))))
(let ((from-header (mh-extract-from-header-value)))
(and from-header
(not (mh-alias-address-to-alias from-header)))))))
(defun mh-alias-add-alias-to-file (alias address &optional file)
"Add ALIAS for ADDRESS in alias FILE without alias check or prompts.
......@@ -491,7 +520,6 @@ after it."
(goto-char (point-min))
(let ((alias-search (concat alias ":"))
(letter)
(here (point))
(case-fold-search t))
(cond
;; Search for exact match (if we had the same alias before)
......@@ -538,7 +566,11 @@ If the alias is already is use, `mh-alias-add-alias-to-file' will prompt."
(interactive "P\nP")
(mh-alias-reload-maybe)
(setq alias (completing-read "Alias: " mh-alias-alist nil nil alias))
(if (and address (string-match "^<\\(.*\\)>$" address))
(setq address (match-string 1 address)))
(setq address (read-string "Address: " address))
(if (string-match "^<\\(.*\\)>$" address)
(setq address (match-string 1 address)))
(let ((address-alias (mh-alias-address-to-alias address))
(alias-address (mh-alias-expand alias)))
(if (string-equal alias-address alias)
......@@ -571,7 +603,8 @@ already has an alias."
(insert-file-contents (mh-msg-filename (mh-get-msg-num t))))
((eq major-mode 'mh-folder-mode)
(error "Cursor not pointing to a message")))
(let* ((address (mh-extract-from-header-value))
(let* ((address (or (mh-extract-from-header-value)
(error "Message has no From: header")))
(alias (mh-alias-suggest-alias address)))
(mh-alias-add-alias alias address))))
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
;;; mh-funcs.el --- MH-E functions not everyone will use right away
;; Copyright (C) 1993, 1995, 2001, 2002 Free Software Foundation, Inc.
;; Copyright (C) 1993, 1995, 2001, 02, 2003 Free Software Foundation, Inc.
;; Author: Bill Wohler <wohler@newt.com>
;; Maintainer: Bill Wohler <wohler@newt.com>
......@@ -32,8 +32,6 @@
;;; Change Log:
;; $Id: mh-funcs.el,v 1.2 2003/02/03 20:55:30 wohler Exp $
;;; Code:
(require 'mh-e)
......@@ -76,33 +74,21 @@ digest are inserted into the folder after that message."
;;;###mh-autoload
(defun mh-copy-msg (msg-or-seq folder)
"Copy the specified MSG-OR-SEQ to another FOLDER without deleting them.
Default is the displayed message. If optional prefix argument is provided,
then prompt for the message sequence."
(interactive (list (cond
((mh-mark-active-p t)
(cons (region-beginning) (region-end)))
(current-prefix-arg
(mh-read-seq-default "Copy" t))
(t
(cons (line-beginning-position) (line-end-position))))
Default is the displayed message.
If optional prefix argument is provided, then prompt for the message sequence.
If variable `transient-mark-mode' is non-nil and the mark is active, then the
selected region is copied.
In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
region in a cons cell, or a sequence."
(interactive (list (mh-interactive-msg-or-seq "Copy")
(mh-prompt-for-folder "Copy to" "" t)))
(let ((msg-list (cond ((numberp msg-or-seq) (list msg-or-seq))
((symbolp msg-or-seq) (mh-seq-to-msgs msg-or-seq))
((and (consp msg-or-seq) (numberp (car msg-or-seq))
(numberp (cdr msg-or-seq)))
(let ((result ()))
(mh-iterate-on-messages-in-region msg
(car msg-or-seq) (cdr msg-or-seq)
(mh-notate nil mh-note-copied mh-cmd-note)
(push msg result))
result))
(t msg-or-seq))))
(let ((msg-list (let ((result ()))
(mh-iterate-on-msg-or-seq msg msg-or-seq
(mh-notate nil mh-note-copied mh-cmd-note)
(push msg result))
result)))
(mh-exec-cmd "refile" (mh-coalesce-msg-list msg-list)
"-link" "-src" mh-current-folder folder)
(cond ((numberp msg-or-seq)
(mh-notate msg-or-seq mh-note-copied mh-cmd-note))
((symbolp msg-or-seq)
(mh-notate-seq msg-or-seq mh-note-copied mh-cmd-note)))))
"-link" "-src" mh-current-folder folder)))
;;;###mh-autoload
(defun mh-kill-folder ()
......@@ -111,7 +97,7 @@ Removes all of the messages (files) within the specified current folder,
and then removes the folder (directory) itself."
(interactive)
(if (or mh-index-data
(yes-or-no-p (format "Remove folder %s (and all included messages)?"
(yes-or-no-p (format "Remove folder %s (and all included messages)? "
mh-current-folder)))
(let ((folder mh-current-folder)
(window-config mh-previous-window-config))
......@@ -246,57 +232,60 @@ Otherwise just send the message's body without the headers."
;;;###mh-autoload
(defun mh-print-msg (msg-or-seq)
"Print MSG-OR-SEQ (default: displayed message) on printer.
If optional prefix argument provided, then prompt for the message sequence.
"Print MSG-OR-SEQ on printer.
Default is the displayed message.
If optional prefix argument is provided, then prompt for the message sequence.
If variable `transient-mark-mode' is non-nil and the mark is active, then the
selected region is printed.
In a program, MSG-OR-SEQ can be a message number, a list of message numbers, a
region in a cons cell, or a sequence.
The variable `mh-lpr-command-format' is used to generate the print command.
The messages are formatted by mhl. See the variable `mhl-formfile'."
(interactive (list (if current-prefix-arg
(reverse (mh-seq-to-msgs
(mh-read-seq-default "Print" t)))
(mh-get-msg-num t))))
(if (numberp msg-or-seq)
(message "Printing message...")
(message "Printing sequence..."))
(let ((print-command
(if (numberp msg-or-seq)
(format "%s -nobell -clear %s %s | %s"
(expand-file-name "mhl" mh-lib-progs)
(mh-msg-filename msg-or-seq)
(if (stringp mhl-formfile)
(format "-form %s" mhl-formfile)
"")
(format mh-lpr-command-format
(if (numberp msg-or-seq)
(format "%s/%d" mh-current-folder
msg-or-seq)
(format "Sequence from %s" mh-current-folder))))
(format "(scan -clear %s ; %s -nobell -clear %s %s) | %s"
(mapconcat (function (lambda (msg) msg)) msg-or-seq " ")
(expand-file-name "mhl" mh-lib-progs)
(if (stringp mhl-formfile)
(format "-form %s" mhl-formfile)
"")
(mh-msg-filenames msg-or-seq)
(format mh-lpr-command-format
(if (numberp msg-or-seq)
(format "%s/%d" mh-current-folder
msg-or-seq)
(format "Sequence from %s"
mh-current-folder)))))))
(if mh-print-background-flag
(mh-exec-cmd-daemon shell-file-name nil "-c" print-command)
(call-process shell-file-name nil nil nil "-c" print-command))
(if (numberp msg-or-seq)
(mh-notate msg-or-seq mh-note-printed mh-cmd-note)
(mh-notate-seq msg-or-seq mh-note-printed mh-cmd-note))
(mh-add-msgs-to-seq msg-or-seq 'printed t)
(if (numberp msg-or-seq)