## Info files to build and install on all platforms.
INFO_COMMON = auth autotype calc ccmode cl dbus dired-x \
- ediff edt efaq eglot eieio emacs-gnutls \
+ ediff efaq eglot eieio emacs-gnutls \
emacs-mime epa erc ert eshell eudc eww flymake forms gnus \
- htmlfontify idlwave ido info.info mairix-el message mh-e \
+ htmlfontify idlwave ido info.info mairix-el message \
modus-themes newsticker nxml-mode octave-mode org pcl-cvs pgg \
rcirc reftex remember sasl sc ses sieve smtpmail \
speedbar todo-mode tramp transient url use-package \
+++ /dev/null
-\input texinfo
-@setfilename ../../info/edt.info
-@settitle EDT Emulation for Emacs
-@include docstyle.texi
-
-@copying
-This file documents the EDT emulation package for Emacs.
-
-Copyright @copyright{} 1986, 1992, 1994--1995, 1999--2024 Free Software
-Foundation, Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
-and with the Back-Cover Texts as in (a) below. A copy of the license
-is included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.''
-@end quotation
-@end copying
-
-@dircategory Emacs misc features
-@direntry
-* EDT: (edt). An Emacs emulation of the EDT editor.
-@end direntry
-
-@titlepage
-@title EDT Emulation User's Manual
-@author Kevin Gallagher
-@author @email{kevin.gal@@verizon.net}
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@contents
-
-@ifnottex
-@node Top
-@top Emacs EDT emulation
-This manual describes the Emacs EDT package, which provides emulation
-of DEC's EDT editor.
-
-@insertcopying
-@end ifnottex
-
-@menu
-* Overview:: Overview of the EDT package.
-* Supported terminals:: Terminals/keyboards that are supported.
-* Starting emulation:: How to get started.
-* Platform-specific notes:: Notes specific to certain platforms.
-* Differences:: How does this EDT emulation differ from real EDT?
-* Highlights:: Some highlights, and comparisons to the
- original Emacs EDT emulation.
-* Customizing:: Customizing emulation.
-* GNU Free Documentation License:: The license for this manual.
-@end menu
-
-@node Overview
-@chapter Overview of the EDT Package
-
-This manual describes version 4.0 of the EDT Emulation for Emacs.
-It comes with special functions which replicate nearly all of
-EDT's keypad mode behavior. It sets up default keypad and function key
-bindings which closely match those found in EDT@. Support is provided so
-that users may reconfigure most keypad and function key bindings to
-their own liking.
-
-Version 4.0 contains several enhancements (@pxref{Changes}).
-
-@menu
-* Quick start:: How to begin using EDT.
-* Changes:: What's new in version 4.0.
-* Goals:: The aims of this package.
-@end menu
-
-@node Quick start
-@section How to Begin Using EDT
-
-To start the EDT Emulation, first start Emacs and then enter @kbd{M-x
-edt-emulation-on} to begin the emulation. After initialization is
-complete, the following message will appear below the status line
-informing you that the emulation has been enabled: ``Default EDT keymap
-active''.
-
- You can have the EDT Emulation start up automatically, each time you
-initiate an Emacs session, by adding the following line to your
-@file{.emacs} file:
-
-@example
-(add-hook 'emacs-startup-hook 'edt-emulation-on)
-@end example
-
-@noindent @strong{Important:} Be sure to read the rest of this manual.
-It contains very useful information on how the EDT Emulation behaves and
-how to customize it to your liking.
-
-@noindent The EDT emulation consists of the following files:
-
-@itemize
-
-@item
-@file{edt.texi}---This manual.
-
-@item
-@file{edt-user.el}---An example customization file (located in the
-Emacs distribution etc directory).
-
-@item
-@file{edt.el}---EDT emulation functions and default configuration.
-
-@item
-@file{edt-lk201.el}---Built-in support for DEC LK-201 keyboards.
-
-@item
-@file{edt-vt100.el}---Built-in support for DEC VT-100 (and above) terminals.
-
-@item
-@file{edt-pc.el}---Built-in support for PC 101 Keyboards under MS-DOS.
-
-@item
-@file{edt-mapper.el}---Create an EDT LK-201 map file for keyboards
-without built-in support.
-
-@end itemize
-
-@node Changes
-@section What's New in Version 4.0
-
-Version 4.0 contains the following enhancements:
-
-@enumerate
-
-@item
-Scroll margins at the top and bottom of the window are now supported.
-(The design was copied from @file{tpu-extras.el}.) By default, this
-feature is enabled with the top margin set to 10% of the window and the
-bottom margin set to 15% of the window. To change these settings, you
-can invoke the function @code{edt-set-scroll-margins} in your
-@file{.emacs} file. For example, the following line
-
-@example
-(edt-set-scroll-margins "20%" "25%")
-@end example
-
-@noindent sets the top margin to 20% of the window and the bottom margin
-to 25% of the window. To disable this feature, set each margin to 0%.
-You can also invoke @code{edt-set-scroll-margins} interactively while
-EDT Emulation is active to change the settings for that session.
-
-@strong{Please note:} Another way to set the scroll margins is to use
-the Emacs customization feature to set the following two variables
-directly: @code{edt-top-scroll-margin} and @code{edt-bottom-scroll-margin}.
-
-Enter the Emacs @code{customize} command. First select the
-@samp{Editing} group and then select the @samp{Emulations} group.
-Finally, select the @samp{Edt} group and follow the directions.
-
-@item
-The @samp{SUBS} command is now supported and bound to @kbd{GOLD-Enter}
-by default. (This design was copied from @file{tpu-edt.el}.) Note, in
-earlier versions of EDT Emulation, @kbd{GOLD-Enter} was assigned to the
-Emacs function @code{query-replace}. The binding of
-@code{query-replace} has been moved to @kbd{GOLD-/}. If you prefer to
-restore @code{query-replace} to @kbd{GOLD-Enter}, then use an EDT user
-customization file, @file{edt-user.el}, to do this
-(@pxref{Customizing}).
-
-@item
-If you access a workstation using an X Server, observe that the
-initialization file generated by @file{edt-mapper.el} will now contain
-the name of the X Server vendor. This is a convenience for those who
-have access to their Unix account from more than one type of X Server.
-Since different X Servers typically require different EDT emulation
-initialization files, @file{edt-mapper.el} will now generate these
-different initialization files and save them with different names.
-Then, the correct initialization file for the particular X server in use
-is loaded correctly automatically.
-
-@item
-Also, @file{edt-mapper.el} is now capable of binding an @acronym{ASCII}
-key sequence, providing the @acronym{ASCII} key sequence prefix is
-already known by Emacs to be a prefix. As a result of providing this
-support, some terminal/keyboard/window system configurations, which
-don't have a complete set of sensible function key bindings built into
-Emacs in @code{input-decode-map}, can still be configured for use with
-EDT Emulation. (Note: In a few rare circumstances this does not work
-properly. In particular, it does not work if a subset of the leading
-@acronym{ASCII} characters in a key sequence are recognized by Emacs as
-having an existing binding. For example, if the keypad 7 (@key{KP7})
-key generates the sequence @samp{@key{ESC}Ow} and @samp{@key{ESC}O} is already
-bound to a function, pressing @key{KP7} when told to do so by
-@file{edt-mapper.el} will result in @file{edt-mapper.el} incorrectly
-mapping @samp{@key{ESC}O} to @key{KP7} and @samp{w} to @key{KP8}. If
-something like this happens to you, it is probably a bug in the support
-for your keyboard within Emacs @strong{or} a bug in the Unix
-termcap/terminfo support for your terminal @strong{or} a bug in the
-terminal emulation software you are using.)
-
-@item
-The @code{edt-quit} function (bound to @kbd{GOLD-q} by default) has been
-modified to warn the user when file-related buffer modifications exist.
-It now cautions the user that those modifications will be lost if the
-user quits without saving those buffers.
-
-@end enumerate
-
-@node Goals
-@section The Aims of this Package
-
-@enumerate
-
-@item
-Emulate EDT Keypad Mode commands closely so that current EDT users will
-find that it easy and comfortable to use Emacs with a small learning
-curve.
-
-@item
-Make it easy for a user to customize EDT emulation key bindings without
-knowing much about Emacs Lisp.
-
-@item
-Make it easy to switch between the original EDT default bindings and the
-user's customized EDT bindings, without having to exit Emacs.
-
-@item
-Provide support for some TPU/EVE functions not supported in EDT.
-
-@item
-Provide an easy way to restore @strong{all} original Emacs key bindings,
-just as they existed before the EDT emulation was first invoked.
-
-@item
-Supports highlighting of marked text within the EDT emulation on all
-platforms on which Emacs supports highlighting of marked text.
-
-@item
-Handle terminal configuration interactively for most terminal
-configurations, when the emulation is invoked for the first time.
-
-@item
-Support a PC AT keyboard under MS-DOS.
-
-@end enumerate
-
-@node Supported terminals
-@chapter Terminals/Keyboards that are Supported
-
-Keyboards used under a Window System are supported via the
-@code{edt-mapper} function. The first time you invoke the emulation
-under a window system, the @code{edt-mapper} function is run
-automatically and the user is prompted to identify which keys the
-emulation is to use for the standard keypad and function keys EDT
-expects (e.g., @key{PF1}, @key{PF2}, @key{KP0}, @key{KP1}, @key{F1},
-@key{F2}, etc.). This configuration is saved to disk read each time the
-emulation is invoked.
-
-In character oriented connections not running a window manager, built-in
-support for the following terminals/keyboards is provided:
-
-@enumerate
-
-@item
-DEC VT-100 series and higher. This includes well behaved VT clones and
-emulators. If you are using a VT series terminal, be sure that the
-@env{TERM} environment variable is set properly before invoking emacs.
-
-@item
-PC AT keyboard under MS-DOS.
-
-@end enumerate
-
-Be sure to read @ref{Platform-specific notes} to see if those notes
-apply to you.
-
-@node Starting emulation
-@chapter How to Get Started
-
-Start up Emacs and enter @kbd{M-x edt-emulation-on} to begin the
-emulation. After initialization is complete, the following message will
-appear below the status line informing you that the emulation has been
-enabled: ``Default EDT keymap active''.
-
-You can have the EDT Emulation start up automatically, each time you
-initiate an Emacs session, by adding the following line to your
-@file{.emacs} file:
-
-@example
-(add-hook 'emacs-startup-hook 'edt-emulation-on)
-@end example
-
-A reference sheet is included (later on) listing the default EDT
-Emulation key bindings. This sheet is also accessible on line from
-within Emacs by pressing @key{PF2}, @kbd{GOLD-H}, or @samp{HELP} (when
-in the EDT Default Mode).
-
-It is easy to customize key bindings in the EDT Emulation
-(@pxref{Customizing}). Customizations are placed in a file called
-@file{edt-user.el}. The Emacs @file{etc/} directory contains an
-example. If @file{edt-user.el} is found in your Emacs load path
-during EDT Emulation initialization, then the following message will
-appear below the status line indicating that the emulation has been
-enabled, enhanced by your own customizations: ``User EDT custom keymap
-active''.
-
-Once enabled, it is easy to switch back and forth between your
-customized EDT Emulation key bindings and the default EDT Emulation key
-bindings. (Look at the binding to @kbd{GOLD-Z} in the sample
-@file{edt-user.el} file.) It is also easy to turn off the emulation
-(via the command @code{edt-emulation-off}). Doing so completely
-restores the original key bindings in effect just prior to invoking the
-emulation.
-
-Emacs binds keys to @acronym{ASCII} control characters and so does the
-real EDT@. Where EDT key bindings and Emacs key bindings conflict,
-the default Emacs key bindings are retained by the EDT emulation by
-default. If you are a die-hard EDT user you may not like this. The
-@ref{Control keys} section explains how to change this so that the EDT
-bindings to @acronym{ASCII} control characters override the default
-Emacs bindings.
-
-@node Platform-specific notes
-@chapter Notes Specific to Certain Platforms
-
-@menu
-* Sun workstations:: Sun workstations running X.
-* MS-DOS:: PC users running MS-DOS.
-* GNU/Linux:: PC users running GNU/Linux.
-* Unix:: Using @key{NumLock} for the @key{PF1} key on Unix systems.
-@end menu
-
-@node Sun workstations
-@section Sun Workstations Running X
-
-Some earlier Sun keyboards do not have arrow keys separate from the
-keypad keys. It is difficult to emulate the full EDT keypad and still
-retain use of the arrow keys on such keyboards.
-
-The Sun Type 5 and other more recent Sun keyboards, however, do have
-separate arrow keys. This makes them candidates for setting up a
-reasonable EDT keypad emulation.
-
-Depending upon the configuration of the version of X installed on your
-system, you may find the default X keynames for the keypad keys don't
-permit Emacs to interpret some or all the keypad keys as something other
-than arrow keys, numeric keys, @key{Home}, @key{PageUp}, etc. Both Sun
-and HP have been particularly guilty of making bizarre keysym
-assignments to the keypad keys.
-
-In most cases, the X Windows command, @code{xmodmap}, can be used to
-correct the problem. Here's a sample @file{.xmodmaprc} file which
-corrects this problem on one Sun workstation configuration using an
-older SunOS release configured with a Sun Type 5 keyboard:
-
-@example
-! File: .xmodmaprc
-!
-! Set up Sun Type 5 keypad for use with the Emacs EDT Emulation
-!
-keycode 53 = KP_Divide
-keycode 54 = KP_Multiply
-keycode 57 = KP_Decimal
-keycode 75 = KP_7
-keycode 76 = KP_8
-keycode 77 = KP_9
-keycode 78 = KP_Subtract
-keycode 97 = KP_Enter
-keycode 98 = KP_4
-keycode 99 = KP_5
-keycode 100 = KP_6
-keycode 101 = KP_0
-keycode 105 = F24
-keycode 119 = KP_1
-keycode 120 = KP_2
-keycode 121 = KP_3
-keycode 132 = KP_Add
-@end example
-
-If @file{edt-mapper.el} does not recognize your keypad keys as unique
-keys, use the command @samp{xmodmap -pke} to get a listing of the actual
-key codes and the keysyms mapped to them and then generate you own
-custom @file{.xmodmaprc} similar to the one above.
-
-Next, feed @file{.xmodmaprc} to the @code{xmodmap} command and all the
-Sun Type 5 keypad keys will now be configurable for the emulation of an
-LK-201 keypad (less the @key{,} key). In this example, the line
-
-@example
-keycode 105 = F24
-@end example
-
-@noindent changes the X Windows name of the keypad @key{NumLock} key to
-be known internally as the @key{F24} key. Doing so permits it to be
-configured to behave as the @key{PF1} (@key{GOLD}) key.
-
-The side effect of this change is that you will no longer have a
-@key{NumLock} key. If you are using other software under X which
-requires a @key{NumLock} key, then examine your keyboard and look for
-one you don't use and redefine it to be the @key{NumLock} key.
-Basically, you need to clear the @key{NumLock} key from being assigned
-as a modifier, assign it to the key of your choice, and then add it back
-as a modifier. (@ref{Unix} for further help on how to do this.)
-
-@node MS-DOS
-@section PC Users Running MS-DOS
-
-By default, F1 is configured to emulate the @key{PF1} (@key{GOLD}) key.
-But @key{NumLock} can be used instead if you load a freeware TSR
-distributed with MS-Kermit, call @samp{gold.com}. This was once
-distributed in a file called @file{gold22.zip} and came with the source
-code as well as a loadable binary image. (See @file{edt-pc.el} in the
-Emacs @file{lisp/emulation} directory for more information.)
-
-@node GNU/Linux
-@section PC Users Running GNU/Linux
-
-The default X server configuration varies from distribution to
-distribution and release to release of GNU/Linux. If your system fails
-to recognize the keypad keys as distinct keys, change the NumLock state,
-turning it on or off, as the case may be, then try again. If this
-doesn't solve your problem, you may have to modify the X keysym mappings
-with @code{xmodmap}.
-
-On one distribution on an Intel PC, the following @file{.xmodmaprc} set
-things up nicely.
-
-@example
-! File: .xmodmaprc
-!
-! Set up PC keypad under GNU/Linux for the Emacs EDT Emulation
-!
-clear mod2
-keycode 77 = F12
-keycode 96 = Num_Lock Pointer_EnableKeys
-add mod2 = Num_Lock
-@end example
-
-In this example, after feeding the file to the @code{xmodmap} command,
-the PC @key{NumLock} keypad key will be configurable for the emulation
-of the @key{PF1} key. The PC keypad can now emulate an LK-201 keypad
-(less the comma key), the standard keyboard supplied with DEC terminals
-VT-200 and above. This @file{.xmodmaprc} file switches the role of the
-@key{F12} and @key{NumLock} keys. It has been tested on Red Hat
-GNU/Linux 5.2. Other versions of GNU/Linux may require different
-keycodes. (@ref{Unix} for further help on how to do this.)
-
-@strong{Please note:} Remember, it may be necessary to have @key{NumLock} in
-one position (ON) or the other (OFF) for the PC keypad to emulate the
-LK-201 keypad properly.
-
-@node Unix
-@section General Notes on Using @key{NumLock} for the @key{PF1} Key on Unix Systems
-
-Making the physical @key{NumLock} key available for use in the EDT Emulation
-requires some modification to the default X Window settings. Since the
-keycode assignments vary from system to system, some investigation is
-needed to see how to do this on a particular system.
-
-You will need to look at the output generated by @code{xmodmap} invoked
-with the "-pm" switch. For example, on Red Hat GNU/Linux 5.2 on a PC, we
-get the following output when running @samp{xmodmap -pm}:
-
-@example
-xmodmap: up to 2 keys per modifier, (keycodes in parentheses):
-
-shift Shift_L (0x32), Shift_R (0x3e)
-lock Caps_Lock (0x42)
-control Control_L (0x25), Control_R (0x6d)
-mod1 Alt_L (0x40), Alt_R (0x71)
-mod2 Num_Lock (0x4d)
-mod3
-mod4
-mod5 Scroll_Lock (0x4e)
-@end example
-
-@noindent Note that Num_Lock is assigned to the modifier @samp{mod2}. This is
-what hides Num_Lock from being seen by Emacs.
-
-Now, @samp{xmodmap -pke} yields:
-
-@example
- .
- .
- .
-keycode 77 = Num_Lock Pointer_EnableKeys
- .
- .
- .
-keycode 96 = F12
- .
- .
- .
-@end example
-
-@noindent So, in Red Hat GNU/Linux 5.2 on a PC, Num_Lock generates keycode 77.
-The following steps are taken:
-
-@enumerate
-@item
-clear the assignment of Num_Lock to mod2;
-@item
-swap the keycodes assigned to F12 and Num_Lock;
-@item
-assign Num_Lock back to mod2.
-@end enumerate
-
-@noindent The @file{.xmodmaprc} file looks like this:
-
-@example
-! File: .xmodmaprc
-!
-! Set up PC keypad under GNU/Linux for the Emacs EDT Emulation
-!
-clear mod2
-keycode 77 = F12
-keycode 96 = Num_Lock Pointer_EnableKeys
-add mod2 = Num_Lock
-@end example
-
-So, after executing @samp{xmodmap .xmodmaprc}, a press of the physical
-@key{F12} key looks like a Num_Lock keypress to X@. Also, a press of the
-physical @key{NumLock} key looks like a press of the @key{F12} key to X.
-
-Now, @file{edt-mapper.el} will see @samp{f12} when the physical
-@key{NumLock} key is pressed, allowing the @key{NumLock} key to be used
-as the EDT @key{PF1} (@key{GOLD}) key.
-
-@node Differences
-@chapter How Does this EDT Emulation Differ from Real EDT?
-
-In general, you will find that this emulation of EDT replicates most,
-but not all, of EDT's most used Keypad Mode editing functions and
-behavior. It is not perfect, but most EDT users who have tried the
-emulation agree that it is quite good enough to make it easy for
-die-hard EDT users to move over to using Emacs.
-
-Here's a list of the most important differences between EDT and this GNU
-Emacs EDT Emulation. The list is short but you must be aware of these
-differences if you are to use the EDT Emulation effectively.
-
-@enumerate
-
-@item
-Entering repeat counts works a little differently than in EDT.
-
-EDT allows users to enter a repeat count before entering a command that
-accepts repeat counts. For example, when using the real EDT, pressing
-these three keys in sequence, @kbd{GOLD 5 KP1}, will move the cursor in
-the current direction 5 words. This does @strong{not} work in Emacs!
-
-Emacs provides two ways to enter repeat counts and neither involves
-using the @key{GOLD} key. First, repeat counts can be entered in Emacs
-by using the @key{ESC} key. For example, pressing these keys in
-sequence, @kbd{ESC 1 0 KP1}, will move the cursor in the current
-direction 10 words. Second, Emacs provides another command called
-@code{universal-argument} that can be used to do the same thing.
-Normally, in Emacs has this bound to @kbd{C-u}.
-
-@item
-EDT's line mode commands and nokeypad mode commands are @strong{not}
-supported (with one important exception; see item 8 in
-@ref{Highlights}). Although, at first, this may seem like a big
-omission, the set of built-in Emacs commands provides a much richer set
-of capabilities which more than make up for this omission.
-
-To enter Emacs commands not bound to keys, you can press @kbd{GOLD KP7}
-or the @key{DO} key. Emacs will display its own command prompt "M-x".
-This stands for the keypress @kbd{Meta-x}, where @key{Meta} is a special
-shift key. The @key{Alt} key is often mapped to behave as a @key{Meta}
-key. So, you can also invoke this prompt by pressing @kbd{Meta-x}.
-Typing the sequence @kbd{ESC x} will also invoke the prompt.
-
-@item
-Selected text is highlighted @strong{only} on systems where Emacs
-supports the highlighting of text.
-
-@item
-Just like in TPU/EVE, the @key{ENTER} key is @strong{not} used to
-terminate input when the editor prompts you for input. The @key{RETURN}
-key is used, instead. (@key{KP4} and @key{KP5} (the direction keys) do
-terminate input for the @samp{FIND} command, just like in EDT, however.)
-
-@end enumerate
-
-@node Highlights
-@chapter Some Highlights, and Comparisons to the Original Emacs EDT Emulation
-
-@enumerate
-
-@item
-The EDT define key command is supported (@code{edt-define-key}) and is
-bound to @kbd{C-k} in the default EDT mode when EDT control sequence
-bindings are enabled, or when the sample @file{edt-user.el}
-customization file is used. The TPU/EVE learn command is supported but
-not bound to a key in the default EDT mode but is bound in the sample
-@file{edt-user.el} file.
-
-Unlike the TPU/EVE learn command, which uses one key to begin the learn
-sequence, @kbd{C-l}, and another command to remember the sequence,
-@kbd{C-r}, this version of the learn command (@code{edt-learn}) serves
-as a toggle to both begin and to remember the learn sequence.
-
-Many users who change the meaning of a key with the define key and the
-learn commands, would like to be able to restore the original key
-binding without having to quit and restart emacs. So a restore key
-command is provided to do just that. When invoked, it prompts you to
-press the key to which you wish the last replaced key definition
-restored. It is bound to @kbd{GOLD C-k} in the default EDT mode when
-EDT control sequence bindings are enabled or the sample
-@file{edt-user.el} customization file is used.
-
-@item
-Direction support is fully supported.
-
-@item
-All original Emacs bindings are fully restored when EDT emulation is
-turned off. So, if a fellow worker comes over to your terminal to help
-you with a software problem, for example, and is completely confused by
-your EDT emulation bindings, just enter the command,
-@code{edt-emulation-off}, at the @samp{M-x} prompt and the original
-Emacs bindings will be restored. To resume the EDT emulation, just
-enter @code{edt-emulation-on}.
-
-@item
-User custom EDT bindings are kept separate from the default EDT
-bindings. One can toggle back and forth between the custom EDT bindings
-and default EDT bindings.
-
-@item
-The Emacs functions in @file{edt.el} attempt to emulate, where
-practical, the exact behavior of the corresponding EDT keypad mode
-commands. In a few cases, the emulation is not exact, but we hope you
-will agree it is close enough. In a very few cases, we chose to use the
-Emacs way of handling things. As mentioned earlier, we do not emulate
-the EDT @samp{SUBS} command. Instead, we chose to use the Emacs
-@code{query-replace} function, which we find to be easier to use.
-
-@item
-Emacs uses the regexp assigned to @code{page-delimiter} to determine
-what marks a page break. This is normally @samp{^\f}, which causes the
-@code{edt-page} command to ignore form feeds not located at the
-beginning of a line. To emulate the EDT @samp{PAGE} command exactly,
-page-delimiter is set to @samp{\f} when EDT emulation is turned on, and
-restored to @samp{^\f} when EDT emulation is turned off. But, since
-some users prefer the Emacs definition of a page break, or may wish to
-preserve a customized definition of page break, one can override the EDT
-definition by placing
-
-@example
-(setq edt-keep-current-page-delimiter t)
-@end example
-
-@noindent in your @file{.emacs} file. Or, you can used the Emacs customize
-command to change its setting.
-
-@item
-The EDT definition of a section of a terminal window is hardwired to be
-16 lines of its one-and-only 24-line window (the EDT @samp{SECT} command
-bound to @key{KP8}). That's two-thirds of the window at a time. Since
-Emacs, like TPU/EVE, can handle multiple windows of sizes of other than
-24 lines, the definition of section used here has been modified to
-two-thirds of the current window. (There is also an
-@code{edt-scroll-window} function which you may prefer over the
-@samp{SECT} emulation.)
-
-@item
-Cursor movement and deletion involving word entities is identical to
-EDT@. This, above all else, gives the die-hard EDT user a sense of being
-at home. Also, an emulation of EDT's @samp{SET ENTITY WORD} command is
-provided, for those users who like to customize movement by a word at a
-time to their own liking.
-
-@item
-EDT's @samp{FIND} and @samp{FNDNXT} are supported.
-
-@item
-EDT's @samp{APPEND}, @samp{REPLACE}, and @samp{SUBS} commands are supported.
-
-@item
-@samp{CHNGCASE} is supported. It works on individual characters or
-selected text, if @samp{SELECT} is active. In addition, two new
-commands are provided: @code{edt-lowercase} and @code{edt-uppercase}.
-They work on individual @strong{words} or selected text, if
-@samp{SELECT} is active.
-
-@item
-Form feed and tab insert commands are supported.
-
-@item
-A new command, @code{edt-duplicate-word}, is provided. If you
-experiment with it, you might find it to be surprisingly useful and may
-wonder how you ever got along without it! It is assigned to @kbd{C-j}
-in the sample @file{edt-user.el} customization file.
-
-@item
-TPU/EVE's Rectangular Cut and Paste functions (originally from the
-EVE-Plus package) are supported. But unlike the TPU/EVE versions, these
-here support both insert and overwrite modes. The seven rectangular
-functions are bound to @key{F7}, @key{F8}, @kbd{GOLD-F8}, @key{F9},
-@kbd{GOLD-F9}, @key{F10}, and @kbd{GOLD-F10} in the default EDT mode.
-
-@item
-The original EDT emulation package set up many default regular and GOLD
-bindings. We tried to preserve most (but not all!)@: of these, so users
-of the original emulation package will feel more at home.
-
-Nevertheless, there are still many GOLD key sequences which are not
-bound to any functions. These are prime candidates to use for your own
-customizations.
-
-Also, there are several commands in @file{edt.el} not bound to any key.
-So, you will find it worthwhile to look through @file{edt.el} for
-functions you may wish to add to your personal customized bindings.
-
-@item
-The VT200/VT300 series terminals steal the function keys @key{F1} to
-@key{F5} for their own use. These do not generate signals which are
-sent to the host. So, @file{edt.el} does not assign any default
-bindings to @key{F1} through @key{F5}.
-
-In addition, our VT220 terminals generate an interrupt when the @key{F6}
-key is pressed (@samp{^C} or @samp{^Y}, can't remember which) and not
-the character sequence documented in the manual. So, binding Emacs
-commands to @key{F6} will not work if your terminal behaves the same
-way.
-
-@item
-The VT220 terminal has no @key{ESC}, @key{BS}, nor @key{LF} keys, as
-does a VT100. So the default EDT bindings adopt the standard DEC
-convention of having the @key{F11}, @key{F12}, and @key{F13} keys, on a
-VT200 series (and above) terminal, assigned to the same EDT functions
-that are bound to @key{ESC}, @key{BS}, and @key{LF} on a VT100 terminal.
-
-@item
-Each user, through the use of a private @file{edt-user.el} file, can
-customize, very easily, personal EDT emulation bindings.
-
-@item
-The EDT @samp{SELECT} and @samp{RESET} functions are supported.
-However, unlike EDT, pressing @samp{RESET} to cancel text selection does
-@strong{not} reset the existing setting of the current direction.
-
-We also provide a TPU/EVE like version of the single @samp{SELECT/RESET}
-function, called @code{edt-toggle-select}, which makes the EDT
-@samp{SELECT} function into a toggle on/off switch. That is, if
-selection is on, pressing @samp{SELECT} again turns selection off
-(cancels selection). This function is used in the sample
-@file{edt-user.el} customization file.
-
-@item
-EDT scroll margins are supported, but are disabled by default.
-(@ref{Scroll margins} for instructions on how to enable them.)
-
-@end enumerate
-
-@node Customizing
-@chapter Customizing Emulation
-
-Most EDT users, at one time or another, make some custom key bindings,
-or use someone else's custom key bindings, which they come to depend
-upon just as if they were built-in bindings. This EDT Emulation for GNU
-Emacs is designed to make it easy to customize bindings.
-
-If you wish to customize the EDT Emulation to use some of your own key
-bindings, you need to make a private version of @file{edt-user.el} in
-your own private lisp directory. The Emacs @file{etc/} directory
-contains an example for you to use as a template and for ideas.
-@c This seems to be untrue.
-@ignore
-There are two sample files @file{edt-user.el1} and @file{edt-user.el2}
-for you to use as templates and for ideas. Look at @file{edt-user.el1}
-first. Unless you will be using two or more very different types of
-terminals on the same system, you need not look at @file{edt-user.el2}.
-@end ignore
-
-First, you need to have your own private lisp directory, say
-@file{~/lisp}, and you should add it to the Emacs load path.
-
-@strong{Please note:} A few sites have different load-path requirements,
-so the above directions may need some modification if your site has such
-special needs.
-
-@menu
-* Init file:: Creating your own @file{edt-user.el} file.
-* Words:: Specifying word entities.
-* Control keys:: Enabling EDT control key sequence bindings.
-* Scroll margins:: Setting scroll margins.
-@end menu
-
-@node Init file
-@section Creating your own @file{edt-user.el} File
-
-A sample @file{edt-user.el} file is provided in the Emacs @file{etc/}
-directory. You should use it as a guide to learn how you can customize
-EDT emulation bindings to your own liking. Names used to identify the
-set of LK-201 keypad and function keys are:
-
-@example
-Keypad Keys:
- PF1 PF2 PF3 PF4
- KP7 KP8 KP9 KP-
- KP4 KP5 KP6 KP,
- KP1 KP2 KP3
- KP0 KPP KPE
-@end example
-
-@example
-Arrow Keys:
- LEFT RIGHT DOWN UP
-@end example
-
-@example
-Function Keys:
- F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14
- HELP DO F17 F18 F19 F20
-
- FIND INSERT REMOVE
- SELECT PREVIOUS NEXT
-@end example
-
-Note: Many VT-200 terminals, and above, steal function keys @key{F1}
-through @key{F5} for terminal setup control and don't send anything to
-the host if pressed. So customizing bindings to these keys may not work
-for you.
-
-There are three basic functions that do the EDT emulation custom
-bindings: @code{edt-bind-key}, @code{edt-bind-gold-key}, and
-@code{edt-bind-function-key}.
-
-The first two are for binding functions to keys which are standard
-across most keyboards. This makes them keyboard independent, making it
-possible to define these key bindings for all terminals in the file
-@file{edt.el}.
-
-The first, @code{edt-bind-key}, is used typically to bind emacs commands
-to control keys, although some people use it to bind commands to other
-keys, as well. (For example, some people use it to bind the VT200
-seldom used back-tick key (@samp{`}) to the function @samp{ESC-prefix}
-so it will behave like an @key{ESC} key.) The second function,
-@code{edt-bind-gold-key}, is used to bind emacs commands to gold key
-sequences involving alphanumeric keys, special character keys, and
-control keys.
-
-The third function, @code{edt-bind-function-key}, is terminal dependent
-and is defined in a terminal specific file (see @file{edt-vt100.el} for
-example). It is used to bind emacs commands to LK-201 function keys, to
-keypad keys, and to gold sequences of those keys.
-
-@node Words
-@section Specifying Word Entities
-
-The variable @code{edt-word-entities} is used to emulate EDT's @samp{SET
-ENTITY WORD} command. It contains a list of characters to be treated as
-words in themselves. If the user does not define
-@code{edt-word-entities} in his/her @file{.emacs} file, then it is set
-up with the EDT default containing only @key{TAB}.
-
-The characters are stored in the list by their numerical values, not as
-strings. Emacs supports several ways to specify the numerical value of
-a character. One method is to use the question mark: @samp{?A} means
-the numerical value for @samp{A}, @samp{?/} means the numerical value
-for @samp{/}, and so on. Several unprintable characters have special
-representations:
-
-@example
-?\b specifies BS, C-h
-?\t specifies TAB, C-i
-?\n specifies LFD, C-j
-?\v specifies VTAB, C-k
-?\f specifies FF, C-l
-?\r specifies CR, C-m
-?\e specifies ESC, C-[
-?\\ specifies \
-@end example
-
-Here are some examples:
-
-@example
-(setq edt-word-entities '(?\t ?- ?/)) ; specifies TAB, - , and /
-(setq edt-word-entities '(?\t) ; specifies TAB, the default
-@end example
-
-@noindent You can also specify characters by their decimal ASCII values:
-
-@example
-(setq edt-word-entities '(9 45 47)) ; specifies TAB, - , and /
-@end example
-
-@node Control keys
-@section Enabling EDT Control Key Sequence Bindings
-
-Where EDT key bindings and Emacs key bindings conflict, the default
-Emacs key bindings are retained by default. Some die-hard EDT users
-may not like this. So, if the variable
-@code{edt-use-EDT-control-key-bindings} is set to true in a user's
-@file{.emacs} file, then the default EDT Emulation mode will enable most
-of the original EDT control key sequence bindings. If you wish to do
-this, add the following line to your @file{.emacs} file:
-
-@example
-(setq edt-use-EDT-control-key-bindings t)
-@end example
-
-@node Scroll margins
-@section Setting Scroll Margins
-
-Scroll margins at the top and bottom of the window are now supported.
-(The design was copied from @file{tpu-extras.el}.) By default, this
-feature is enabled with the top margin set to 10% of the window and the
-bottom margin set to 15% of the window. To change these settings, you
-can invoke the function @code{edt-set-scroll-margins} in your
-@file{.emacs} file. For example, the following line
-
-@example
-(edt-set-scroll-margins "20%" "25%")
-@end example
-
-@noindent sets the top margin to 20% of the window and the bottom margin
-to 25% of the window. To disable this feature, set each margin to 0%.
-You can also invoke @code{edt-set-scroll-margins} interactively while
-EDT Emulation is active to change the settings for that session.
-
-@strong{Please note:} Another way to set the scroll margins is to use
-the Emacs customization feature to set the following two variables
-directly: @code{edt-top-scroll-margin} and @code{edt-bottom-scroll-margin}.
-
-Enter the Emacs @code{customize} command. First select the
-@samp{Editing} group and then select the @samp{Emulations} group.
-Finally, select the @samp{Edt} group and follow the directions.
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-@bye
@vindex message-send-mail-function
@findex message-send-mail-function
@findex message-send-mail-with-sendmail
-@findex message-send-mail-with-mh
@findex message-send-mail-with-qmail
@findex message-smtpmail-send-it
@findex smtpmail-send-it
@code{message-send-mail-with-sendmail}, or @code{smtpmail-send-it}
according to the system. Other valid values include
@code{message-send-mail-with-mailclient},
-@code{message-send-mail-with-mh}, @code{message-send-mail-with-qmail},
-@code{message-smtpmail-send-it} and @code{feedmail-send-it}.
+@code{message-send-mail-with-qmail}, @code{message-smtpmail-send-it} and
+@code{feedmail-send-it}.
The function
@code{message-send-mail-with-sendmail} pipes your article to the
mailclient.
-@item message-mh-deletable-headers
-@vindex message-mh-deletable-headers
-Most versions of MH doesn't like being fed messages that contain the
-headers in this variable. If this variable is non-@code{nil} (which is
-the default), these headers will be removed before mailing when sending
-messages via MH@. Set it to @code{nil} if your MH can handle these
-headers.
-
@item message-qmail-inject-program
@vindex message-qmail-inject-program
@cindex qmail
+++ /dev/null
-\input texinfo @c -*- mode: texinfo; coding: utf-8; -*-
-@c
-@c Note: This document requires makeinfo version 4.6 or greater to build.
-@c
-@c %**start of header
-@setfilename ../../info/mh-e.info
-@settitle The MH-E Manual
-@include docstyle.texi
-@c %**end of header
-
-@c Version of the software and manual.
-@set VERSION 8.6
-@c Edition of the manual. It is either empty for the first edition or
-@c has the form ", nth Edition" (without the quotes).
-@set EDITION
-@set UPDATED 2016-04-29
-@set UPDATE-MONTH April, 2016
-
-@c Other variables.
-@set MH-BOOK-HOME https://rand-mh.sourceforge.io/book/
-@set MH-E-HOME https://mh-e.sourceforge.io/
-
-@c Copyright
-@copying
-This is version @value{VERSION}@value{EDITION} of @cite{The MH-E
-Manual}, last updated @value{UPDATED}.
-
-Copyright @copyright{} 1995, 2001--2003, 2005--2024 Free Software
-Foundation, Inc.
-
-@c This dual license has been agreed upon by the FSF.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of either:
-
-@enumerate a
-@item
-the GNU Free Documentation License, Version 1.3 or any later version
-published by the Free Software Foundation; with no Invariant Sections,
-with the Front-Cover Texts being ``A GNU Manual,'' and with the
-Back-Cover Texts as in (a) below. A copy of the license is included in
-the section entitled ``GNU Free Documentation License.''
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.''
-
-@item
-the GNU General Public License as published by the Free Software
-Foundation; either version 3, or (at your option) any later version. A
-copy of the license is included in the section entitled ``GNU General
-Public License.''
-@end enumerate
-
-@end quotation
-@end copying
-
-@c Info Directory Entry
-@dircategory Emacs network features
-@direntry
-* MH-E: (mh-e). Emacs interface to the MH mail system.
-@end direntry
-
-@c Title Page
-@titlepage
-@title The MH-E Manual
-@subtitle Version @value{VERSION}@value{EDITION}
-@subtitle @value{UPDATE-MONTH}
-@author Bill Wohler
-
-@c Copyright Page
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@ifnottex
-@html
-<!--
-@end html
-@node Top
-@top The MH-E Manual
-@html
--->
-@end html
-@insertcopying
-@end ifnottex
-
-@c Table of Contents
-@contents
-
-@html
-<!--
-@end html
-
-@menu
-* Preface:: Preface
-* Conventions:: GNU Emacs Terms and Conventions
-* Getting Started:: Getting Started
-* Tour Through MH-E:: Tour Through MH-E
-* Using This Manual:: Using This Manual
-* Incorporating Mail:: Incorporating Mail
-* Reading Mail:: Reading Mail
-* Folders:: Organizing Your Mail with Folders
-* Sending Mail:: Sending Mail
-* Editing Drafts:: Editing a Draft
-* Aliases:: Aliases
-* Identities:: Identities
-* Speedbar:: The Speedbar
-* Menu Bar:: The Menu Bar
-* Tool Bar:: The Tool Bar
-* Searching:: Searching Through Messages
-* Threading:: Viewing Message Threads
-* Limits:: Limiting Display
-* Sequences:: Using Sequences
-* Junk:: Dealing With Junk Mail
-* Miscellaneous:: Miscellaneous Commands, Variables, and Buffers
-* Scan Line Formats:: Scan Line Formats
-* Procmail:: Reading Mailing Lists Effectively
-* Odds and Ends:: Odds and Ends
-* History:: History of MH-E
-* GFDL:: GNU Free Documentation License
-* GPL:: GNU General Public License
-* Key Index:: Key (Character) Index
-* Command Index:: Command Index
-* Option Index:: Option (Variable) Index
-* Concept Index:: Concept Index
-
-@detailmenu
- --- The Detailed Node Listing ---
-
-Tour Through MH-E
-
-* Sending Mail Tour::
-* Reading Mail Tour::
-* Processing Mail Tour::
-* Leaving MH-E::
-* More About MH-E::
-
-Using This Manual
-
-* Options::
-* Ranges::
-* Folder Selection::
-
-Reading Your Mail
-
-* Viewing::
-* Viewing Attachments::
-* HTML::
-* Digests::
-* Reading PGP::
-* Printing::
-* Files and Pipes::
-* Navigating::
-* Miscellaneous Commands and Options::
-
-Sending Mail
-
-* Composing::
-* Replying::
-* Forwarding::
-* Redistributing::
-* Editing Again::
-
-Editing a Draft
-
-* Editing Message::
-* Inserting Letter::
-* Inserting Messages::
-* Signature::
-* Picture::
-* Adding Attachments::
-* Sending PGP::
-* Checking Recipients::
-* Sending Message::
-* Killing Draft::
-
-Odds and Ends
-
-* Bug Reports::
-* Mailing Lists::
-* MH FAQ and Support::
-* Getting MH-E::
-
-History of MH-E
-
-* From Brian Reid::
-* From Jim Larus::
-* From Stephen Gildea::
-* From Bill Wohler::
-
-@end detailmenu
-@end menu
-
-@html
--->
-@end html
-
-@node Preface
-@unnumbered Preface
-
-@cindex Emacs
-@cindex Unix commands, Emacs
-@cindex preface
-
-This manual introduces another interface to the MH mail system that is
-accessible through the GNU Emacs editor, namely, @emph{MH-E}. MH-E is
-easy to use. I don't assume that you know GNU Emacs or even MH at this
-point, since I didn't know either of them when I discovered MH-E@.
-However, MH-E was the tip of the iceberg, and I discovered more and
-more niceties about GNU Emacs and MH@. Now I'm fully hooked on both of
-them.
-
-The MH-E package is distributed with Emacs@footnote{Version
-@value{VERSION} of MH-E appeared in Emacs 24.4. It is compatible with
-MH versions 6.8.4 and higher, all versions of nmh, and GNU mailutils
-1.0 and higher}, so you shouldn't have to do anything special to use
-it. Gnus is also required; it is bundled with Emacs. This manual
-covers MH-E version @value{VERSION}. To help you decide which version
-you have, see @ref{Getting Started}.
-
-@findex help-with-tutorial
-@kindex C-h t
-
-If you don't already use GNU Emacs but want to learn more, you can
-read a built-in tutorial by starting GNU Emacs and typing @kbd{C-h t}
-(@code{help-with-tutorial}). (To learn about this notation, see
-@ref{Conventions}.) If you want to take the plunge, consult the
-@iftex
-@cite{GNU Emacs Manual},
-@end iftex
-@ifinfo
-@ref{Top, , GNU Emacs Manual, emacs, GNU Emacs Manual},
-@end ifinfo
-@ifhtml
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/,
-@cite{GNU Emacs Manual}},
-@end ifhtml
-from the Free Software Foundation.
-
-If more information is needed, you can go to the Unix manual pages of
-the individual MH commands. When the name is not obvious, I'll guide
-you to a relevant MH manual page that describes the action more fully.
-
-@c ":" does not work in index entries in Info.
-@cindex @cite{MH & nmh - Email for Users & Programmers}
-@cindex MH book
-@cindex info
-@kindex C-h i
-
-This manual is available in both Info and online formats. The Info
-version is distributed with Emacs and can be accessed with the
-@command{info} command (@samp{info mh-e}) or within Emacs (@kbd{C-h i
-m mh-e @key{RET}}). The online version is available at
-@uref{https://mh-e.sourceforge.io/manual/, SourceForge}. Another great
-online resource is the book
-@uref{https://rand-mh.sourceforge.io/book/, @cite{MH & nmh: Email for
-Users & Programmers}} (also known as @dfn{the MH book}).
-
-I hope you enjoy this manual! If you have any comments, or suggestions
-for this document, please let me know.
-
-@cindex Bill Wohler
-@cindex Wohler, Bill
-
-@noindent
-Bill Wohler <@i{wohler at newt.com}>@*
-8 February 1995@*
-24 February 2006
-
-@node Conventions
-@chapter GNU Emacs Terms and Conventions
-
-@cindex Emacs
-@cindex Emacs, conventions
-@cindex Emacs, terms
-@cindex Unix commands, Emacs
-@cindex conventions, Emacs
-@cindex terms, Emacs
-
-If you're an experienced Emacs user, you can skip the following
-conventions and definition of terms and go directly to the next
-section (@pxref{Getting Started}).
-
-@cindex Emacs commands
-@cindex MH commands
-@cindex Unix commands
-@cindex commands
-@cindex commands, MH
-@cindex commands, Unix
-@cindex commands, shell
-@cindex functions
-@cindex shell commands
-
-In general, @dfn{functions} in this text refer to Emacs Lisp functions
-that one would call from within Emacs Lisp programs (for example,
-@code{(mh-inc-folder)}). On the other hand, @dfn{commands} are those
-things that are run by the user, such as @kbd{i} or @kbd{M-x
-mh-inc-folder}. Programs outside of Emacs are specifically called MH
-commands, shell commands, or Unix commands.
-
-@cindex conventions, key names
-@cindex key names
-
-The conventions for key names are as follows:
-
-@table @kbd
-@item C-x
-Hold down the @key{CTRL} (Control) key and press the @kbd{x} key.
-@c -------------------------
-@item M-x
-Hold down the @key{META} or @key{ALT} key and press the @kbd{x} key.
-
-Since some keyboards don't have a @key{META} key, you can generate
-@kbd{M-x}, for example, by pressing @key{ESC} (Escape),
-@emph{releasing it}, and then pressing the @kbd{x} key.
-@c -------------------------
-@item @key{RET}
-Press the @key{RETURN} or @key{ENTER} key. This is normally used to
-complete a command.
-@c -------------------------
-@item @key{SPC}
-Press the space bar.
-@c -------------------------
-@item @key{TAB}
-Press the @key{TAB} key.
-@c -------------------------
-@item @key{DEL}
-Press the @key{DELETE} key.
-@c -------------------------
-@item @key{BS}
-Press the @key{BACKSPACE} key.
-@end table
-
-@cindex Emacs, prefix argument
-@cindex prefix argument
-@kindex C-u
-
-A @dfn{prefix argument} allows you to pass an argument to any Emacs
-function. To pass an argument, type @kbd{C-u} before the Emacs command
-or keystroke. Numeric arguments can be passed as well. For example, to
-insert five f's, use @kbd{C-u 5 f}. There is a default of four when
-using @kbd{C-u}, and you can use multiple prefix arguments to provide
-arguments of powers of four. To continue our example, you could insert
-four f's with @kbd{C-u f}, 16 f's with @kbd{C-u C-u f}, 64 f's with
-@kbd{C-u C-u C-u f}, and so on. Numeric and valueless negative
-arguments can also be inserted with the @key{META} key. Examples
-include @kbd{M-5} to specify an argument of 5, or @kbd{M--} which
-specifies a negative argument with no particular value.
-
-@sp 1
-@center @strong{NOTE}
-
-@quotation
-The prefix @kbd{C-u} or @kbd{M-} is not necessary in MH-E's MH-Folder
-mode (@pxref{Reading Mail Tour}). In this mode, simply enter the
-numerical argument before entering the command.
-@end quotation
-@sp 1
-
-@cindex @file{.emacs}
-@cindex Emacs, variables
-@cindex files, @file{.emacs}
-@cindex variables
-@findex setq
-
-Emacs uses @dfn{variables} to hold values. These can be changed via
-calls to the function @code{setq} in @file{~/.emacs}.
-
-@cindex Emacs, options
-@cindex options
-@findex customize-group
-@findex customize-option
-
-Variables in MH-E that are normally modified by the user are called
-@dfn{options} and are modified through the customize functions (such
-as @kbd{M-x customize-option} or @kbd{M-x customize-group}).
-@ifnothtml
-@xref{Easy Customization,,,emacs,The GNU Emacs Manual}, in @cite{The
-GNU Emacs Manual}.
-@end ifnothtml
-@ifhtml
-See section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Easy-Customization.html,
-Easy Customization} in @cite{The GNU Emacs Manual}.
-@end ifhtml
-@xref{Options}.
-
-@cindex Emacs, faces
-@cindex faces
-@cindex highlighting
-@findex customize-face
-
-You can specify various styles for displaying text using @dfn{faces}.
-MH-E provides a set of faces that you can use to personalize the look
-of your MH-E buffers. Use the command @kbd{M-x customize-face} to do
-this.
-@ifnothtml
-@xref{Face Customization,,,emacs,The GNU Emacs Manual}, in @cite{The
-GNU Emacs Manual}.
-@end ifnothtml
-@ifhtml
-See section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Face-Customization.html,
-Face Customization} in @cite{The GNU Emacs Manual}.
-@end ifhtml
-
-@cindex abnormal hooks
-@cindex hooks
-@cindex normal hooks
-@findex add-hook
-@findex customize-option
-
-Commands often offer @dfn{hooks} which enable you to extend or modify
-the way a command works.
-@ifnothtml
-@ref{Hooks, , Hooks, emacs, The GNU Emacs Manual}, in @cite{The GNU
-Emacs Manual}
-@end ifnothtml
-@ifhtml
-See section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html,
-Hooks} in @cite{The GNU Emacs Manual}
-@end ifhtml
-for a description about @dfn{normal hooks} and @dfn{abnormal hooks}.
-MH-E uses normal hooks in nearly all cases, so you can assume that we
-are talking about normal hooks unless we explicitly mention that a
-hook is abnormal. We also follow the conventions described in that
-section: the name of the abnormal hooks end in @code{-functions} and all
-the rest of the MH-E hooks end in @code{-hook}. You can add hooks with
-either @code{customize-option} or @code{add-hook}.
-
-@cindex Emacs, mark
-@cindex Emacs, point
-@cindex Emacs, region
-@cindex mark
-@cindex point
-@cindex region
-@kindex C-@@
-@kindex C-SPC
-
-There are several other terms that are used in Emacs that you should
-know. The @dfn{point} is where the cursor currently is. You can save
-your current place in the file by setting a @dfn{mark}. This operation
-is useful in several ways. The mark can be later used when defining a
-@dfn{region}, which is the text between the point and mark. Many
-commands operate on regions, such as those for deleting text or
-filling paragraphs. A mark can be set with @kbd{C-@@} (or
-@kbd{C-@key{SPC}}).
-
-@cindex completion
-@cindex Emacs, completion
-@cindex Emacs, file completion
-@cindex Emacs, folder completion
-@cindex Emacs, minibuffer
-@cindex file completion
-@cindex folder completion
-@cindex minibuffer
-@kindex SPC
-@kindex TAB
-
-The @dfn{minibuffer} is the bottom line of the Emacs window, where all
-prompting and multiple-character input is directed. You can use
-@dfn{completion} to enter values such as folders. Completion means
-that Emacs fills in text for you when you type @key{SPC} or @key{TAB}.
-A second @key{SPC} or @key{TAB} will list all possibilities at that
-point.
-@ifnothtml
-@xref{Completion, , Completion, emacs, The GNU Emacs Manual}.
-@end ifnothtml
-@ifhtml
-See the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion.html,
-Completion} in @cite{The GNU Emacs Manual}.
-@end ifhtml
-Note that @key{SPC} cannot be used for completing filenames and
-folders.
-
-@findex help-with-tutorial
-@kindex C-h t
-@kindex M-x
-
-The minibuffer is also where you enter Emacs function names after
-typing @kbd{M-x}. For example, in the preface, I mentioned that you
-could obtain help with @kbd{C-h t} (@code{help-with-tutorial}). What
-this means is that you can get a tutorial by typing either @kbd{C-h t}
-or @kbd{M-x help-with-tutorial}. In the latter case, you are prompted
-for @samp{help-with-tutorial} in the minibuffer after typing
-@kbd{M-x}.
-
-@cindex ~
-
-The @samp{~} notation in filenames represents your home directory.
-This notation is used by many shells including @command{bash},
-@code{tcsh}, and @command{csh}. It is analogous to the environment
-variable @samp{$HOME}. For example, @file{~/.emacs} can be written
-@file{$HOME/.emacs} or using the absolute path as in
-@file{/home/wohler/.emacs} instead.
-
-@cindex Emacs, interrupting
-@cindex Emacs, quitting
-@cindex interrupting
-@cindex quitting
-
-@i{In case of trouble:} Emacs can be interrupted at any time with
-@kbd{C-g}. For example, if you've started a command that requests that
-you enter something in the minibuffer, but then you change your mind,
-type @kbd{C-g} and you'll be back where you started. If you want to
-exit Emacs entirely, use @kbd{C-x C-c}.
-
-@node Getting Started
-@chapter Getting Started
-
-@cindex MH-E, versions
-@cindex history
-@cindex versions of MH-E
-
-Because there are many old versions of MH-E out there, it is important
-to know which version you have. I'll be talking about @w{Version 8}
-which is pretty close to @w{Version 6} and @w{Version 7}. It differs
-from @w{Version 4} and @w{Version 5} and is vastly different from
-@w{Version 3}. @xref{History}.
-
-@findex mh-version
-
-To determine which version of MH-E that you have, enter @kbd{M-x
-mh-version @key{RET}}. Hopefully it says that you're running
-@w{Version @value{VERSION}} which is the latest version as of this
-printing.
-
-If your version is much older than this, please consider upgrading.
-You can have your system administrator upgrade the system-wide
-version, or you can install your own personal version. It's really
-quite easy. @xref{Getting MH-E}, for instructions for getting and
-installing MH-E.
-
-If the @code{mh-version} command displays @samp{No MH variant
-detected}@footnote{In very old versions of MH-E, you may get the error
-message, @samp{Cannot find the commands `inc' and `mhl' and the file
-`components'} if MH-E can't find MH@. In this case, you need to update
-MH-E, and you may need to install MH too. However, newer versions of
-MH-E are better at finding MH if it is on your system.}, then you need
-to install MH or tell MH-E where to find MH.
-
-@cindex Debian
-@cindex nmh
-@cindex GNU mailutils MH
-
-If you don't have MH on your system already, you must install a
-variant of MH@. The Debian mh-e package does this for you
-automatically (@pxref{Getting MH-E}). Most people use
-@uref{https://www.nongnu.org/nmh/, nmh}, but you may be interested in
-trying out @uref{https://mailutils.org/, GNU mailutils MH}, which
-supports IMAP@. Your GNU/Linux distribution probably has packages for
-both of these.
-
-@cindex @command{install-mh}
-@cindex MH commands, @command{install-mh}
-@cindex MH book
-
-If you've never run MH before, you need to run @command{install-mh}
-from the shell before you continue. This sets up your personal MH
-environment@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/../overall/setup.html, Setting Up MH} in the
-MH book.}. If you don't, you'll be greeted with the error message:
-@samp{Install MH and run install-mh before running MH-E}. This is all
-you need to know about MH to use MH-E, but the more you know about MH,
-the more you can leverage its power. See the
-@uref{@value{MH-BOOK-HOME}/../, MH book} to learn more about MH.
-
-@cindex @samp{Path} MH profile component
-@cindex MH profile
-@cindex MH profile component
-@cindex MH profile component, @samp{Path}
-
-Your MH environment includes your @dfn{MH profile} which is found in
-the file @file{~/.mh_profile}, or the file named in the environment
-variable @samp{$MH}. This file contains a number of @dfn{MH
-profile components}. For example, the @samp{Path:} MH profile
-component contains the path to your mail directory, which is
-@file{~/Mail} by default.
-
-@cindex @command{mhparam}
-@cindex MH commands, @command{mhparam}
-@vindex exec-path
-@vindex mh-path
-@vindex mh-sys-path
-@vindex mh-variant
-@vindex mh-variant-in-use
-
-There are several options MH-E uses to interact with your MH
-installation. The option @code{mh-variant} specifies the variant used
-by MH-E (@pxref{Options}). The default setting of this option is
-@samp{Auto-detect} which means that MH-E will automatically choose the
-first of nmh, MH, or GNU mailutils MH that it finds in the directories
-listed in @code{mh-path} (which you can customize),
-@code{mh-sys-path}, and @code{exec-path}. If MH-E can't find MH at
-all, you may have to customize @code{mh-path} and add the directory in
-which the command @command{mhparam} is located. If, on the other hand,
-you have both nmh and GNU mailutils MH installed (for example) and
-@code{mh-variant-in-use} was initialized to nmh but you want to use
-GNU mailutils MH, then you can set @code{mh-variant} to
-@samp{gnu-mh}.
-
-@vindex mh-flists-present-flag
-@vindex mh-lib
-@vindex mh-lib-progs
-@vindex mh-progs
-
-When @code{mh-variant} is changed, MH-E resets @code{mh-progs},
-@code{mh-lib}, @code{mh-lib-progs}, @code{mh-flists-present-flag}, and
-@code{mh-variant-in-use} accordingly.
-
-@cindex @file{.emacs}
-@cindex files, @file{.emacs}
-
-@sp 1
-@center @strong{NOTE}
-
-@quotation
-Prior to version 8, it was often necessary to set some of these
-variables in @file{~/.emacs}; now it is no longer necessary and can
-actually cause problems.
-@end quotation
-@sp 1
-
-@cindex MH profile component, @samp{Draft-Folder}
-@cindex MH profile component, @samp{Path}
-@cindex MH profile component, @samp{Previous-Sequence}
-@cindex MH profile component, @samp{Unseen-Sequence}
-@cindex @samp{Draft-Folder} MH profile component
-@cindex @samp{Path} MH profile component
-@cindex @samp{Previous-Sequence} MH profile component
-@cindex @samp{Unseen-Sequence} MH profile component
-@findex mh-find-path
-@vindex mh-draft-folder
-@vindex mh-find-path-hook
-@vindex mh-inbox
-@vindex mh-previous-seq
-@vindex mh-unseen-seq
-@vindex mh-user-path
-
-In addition to setting variables that point to MH itself, MH-E also
-sets a handful of variables that point to where you keep your mail.
-During initialization, the function @code{mh-find-path} sets
-@code{mh-user-path} from your @samp{Path:} MH profile component (but
-defaults to @samp{Mail} if one isn't present), @code{mh-draft-folder}
-from @samp{Draft-Folder:}, @code{mh-unseen-seq} from
-@samp{Unseen-Sequence:}, @code{mh-previous-seq} from
-@samp{Previous-Sequence:}, and @code{mh-inbox} from @samp{Inbox:}
-(defaults to @samp{+inbox}). The hook @code{mh-find-path-hook} is run
-after these variables have been set. This hook can be used the change
-the value of these variables if you need to run with different values
-between MH and MH-E.
-
-@node Tour Through MH-E
-@chapter Tour Through MH-E
-
-@cindex introduction
-@cindex tour
-@cindex tutorial
-
-This chapter introduces some of the terms you'll need to know and then
-takes you on a tour of MH-E@footnote{The keys mentioned in these
-chapters refer to the default key bindings. If you've changed the
-bindings, refer to the command summaries at the beginning of each
-chapter for a mapping between default key bindings and function
-names.}. When you're done, you'll be able to send, read, and file
-mail, which is all that a lot of people ever do. But if you're the
-curious or adventurous type, read the rest of the manual to be able to
-use all the features of MH-E@. I suggest you read this chapter first to
-get the big picture, and then you can read the manual as you wish.
-
-@menu
-* Sending Mail Tour::
-* Reading Mail Tour::
-* Processing Mail Tour::
-* Leaving MH-E::
-* More About MH-E::
-@end menu
-
-@node Sending Mail Tour
-@section Sending Mail
-
-@cindex MH-Letter mode
-@cindex mode
-@cindex modes, MH-Letter
-@cindex sending mail
-@findex mh-smail
-
-Let's start our tour by sending ourselves a message which we can later
-read and process. Enter @kbd{M-x mh-smail} to invoke the MH-E program
-to send messages. Your message appears in an Emacs buffer whose
-mode@footnote{A @dfn{mode} changes Emacs to make it easier to edit a
-particular type of text.} is MH-Letter.
-
-Enter your login name in the @samp{To:} header field. Press the
-@key{TAB} twice to move the cursor past the @samp{Cc:} field, since no
-carbon copies are to be sent, and on to the @samp{Subject:} field.
-Enter @kbd{Test} or anything else that comes to mind.
-
-Press @key{TAB} again to move the cursor to the body of the message.
-Enter some text, using normal Emacs commands. You should now have
-something like this@footnote{If you're running Emacs under the X
-Window System, then you would also see a menu bar and a tool bar. I've
-left out the menu bar and tool bar in all of the example screens.}:
-
-@cartouche
-@smallexample
-
-
-
-
-
-
---:-- *scratch* All L1 (Lisp Interaction)-------------------------
-To: wohler
-cc:
-Subject: Test
-X-Mailer: MH-E 8.1; nmh 1.1; GNU Emacs 23.1
---------
-This is a test message to get the wheels churning...#
-
-
---:** @{draft@} All L5 (MH-Letter)----------------------------------
-Type C-c C-c to send message, C-C ? for help
-@end smallexample
-@end cartouche
-@i{MH-E message composition window}
-
-Note the line of dashes that separates the header and the body of the
-message. It is essential that these dashes (or a blank line) are
-present or the body of your message will be considered to be part of
-the header.
-
-@cindex help
-@findex describe-mode
-@kindex C-c ?
-@kindex C-c C-c
-@kindex C-h m
-
-There are several commands specific to MH-Letter mode@footnote{You can
-get quick help for the commands used most often with @kbd{C-c ?} or
-more complete help with the @kbd{C-h m} (@code{describe-mode})
-command.}, but at this time we'll only use @kbd{C-c C-c} to send your
-message. Type @kbd{C-c C-c} now. That's all there is to it!
-
-@node Reading Mail Tour
-@section Receiving Mail
-
-@cindex @command{inc}
-@cindex @command{scan}
-@cindex MH commands, @command{inc}
-@cindex MH commands, @command{scan}
-@cindex MH-Folder mode
-@cindex modes, MH-Folder
-@cindex reading mail
-@findex mh-rmail
-
-To read the mail you've just sent yourself, enter @kbd{M-x mh-rmail}.
-This incorporates the new mail and puts the output from
-@command{inc}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/reapre.html, Reading Mail: inc show next
-prev} in the MH book.} (called @dfn{scan lines} after the MH program
-@command{scan}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/faswsprs.html, Find and Specify with scan
-pick Ranges Sequences} in the MH book.} which prints a one-line
-summary of each message) into a buffer called @samp{+inbox} whose
-major mode is MH-Folder.
-
-@findex mh-rmail
-@kindex F r
-
-@sp 1
-@center @strong{NOTE}
-
-@quotation
-
-The @kbd{M-x mh-rmail} command will show you only new mail, not mail
-you have already read. If you were to run this tour again, you would
-use @kbd{F r} to pull all your messages into MH-E.
-@end quotation
-@sp 1
-
-@kindex RET
-@kindex n
-@kindex p
-
-You should see the scan line for your message, and perhaps others. Use
-@kbd{n} or @kbd{p} to move the cursor to your test message and type
-@key{RET} to read your message. You should see something like:
-
-@cartouche
-@smallexample
- 3 t08/24 root received fax files on Wed Aug 24 11:00:13 -0700 1
-# 4+t08/24 To:wohler Test<<This is a test message to get the wheels
-
--:%% @{+inbox/select@} 4 msgs (1-4) Bot L4 (MH-Folder Show)---------
-To: wohler
-Subject: Test
-X-Mailer: MH-E 8.1; nmh 1.1; GNU Emacs 23.1
-Date: Fri, 17 Mar 2006 10:49:11 -0800
-From: Bill Wohler <wohler@@stop.mail-abuse.org>
-
-This is a test message to get the wheels churning...
-
-
-
---:-- @{show-+inbox@} 4 All L1 (MH-Show)----------------------------
-
-@end smallexample
-@end cartouche
-@i{After incorporating new messages}
-
-@kindex DEL
-@kindex SPC
-
-If you typed a long message, you can view subsequent pages with
-@key{SPC} and previous pages with @key{DEL}.
-
-@node Processing Mail Tour
-@section Processing Mail
-
-@cindex processing mail
-@kindex RET
-@kindex r
-
-The first thing we want to do is reply to the message that we sent
-ourselves. Ensure that the cursor is still on the same line as your
-test message and type @kbd{r}. You are prompted in the minibuffer with
-@samp{Reply to whom:}. Here MH-E is asking whether you'd like to reply
-to the original sender only, to the sender and primary recipients, or
-to the sender and all recipients. You can press @key{TAB} to see these
-choices. If you simply press @key{RET}, you'll reply only to the
-sender. Press @key{RET} now.
-
-You'll find yourself in an Emacs buffer similar to that when you were
-sending the original message, like this:
-
-@cartouche
-@smallexample
-To:
-cc:
-Subject: Re: Test
-In-Reply-To: <31054.1142621351@@stop.mail-abuse.org>
-References: <31054.1142621351@@stop.mail-abuse.org>
-Comments: In-Reply-To Bill Wohler <wohler@@stop.mail-abuse.org>
- message dated "Fri, 17 Mar 2006 10:49:11 -0800."
-X-Mailer: MH-E 8.1; nmh 1.1; GNU Emacs 23.1
---------
-#
-
---:-- @{draft@} All L10 (MH-Letter)----------------------------------
-To: wohler
-Subject: Test
-X-Mailer: MH-E 8.1; nmh 1.1; GNU Emacs 23.1
-Date: Fri, 17 Mar 2006 10:49:11 -0800
-From: Bill Wohler <wohler@@stop.mail-abuse.org>
-
-This is a test message to get the wheels churning...
-
---:-- @{show-+inbox@} 4 All L1 (MH-Show)----------------------------
-Type C-c C-c to send message, C-c ? for help
-@end smallexample
-@end cartouche
-@i{Composition window during reply}
-
-@findex backward-char
-@findex forward-char
-@findex next-line
-@findex previous-line
-@kindex C-b
-@kindex C-c C-c
-@kindex C-c C-f C-t
-@kindex C-f
-@kindex C-n
-@kindex C-p
-@kindex BS
-
-By default, MH will not add you to the address list of your replies,
-so if you find that the @samp{To:} header field is missing, don't
-worry. In this case, type @kbd{C-c C-f C-t} to create and go to the
-@samp{To:} field, where you can type your login name again. You can
-move around with the arrow keys or with @kbd{C-p}
-(@code{previous-line}), @kbd{C-n} (@code{next-line}), @kbd{C-b}
-(@code{backward-char}), and @kbd{C-f} (@code{forward-char}) and can
-delete the previous character with @key{BS}. When you're finished
-editing your message, send it with @kbd{C-c C-c} as before.
-
-@cindex @command{refile}
-@cindex MH commands, @command{refile}
-@cindex folders
-@kindex SPC
-@kindex o
-
-You'll often want to save messages that were sent to you in an
-organized fashion. This is done with @dfn{folders}. You can use
-folders to keep messages from your friends, or messages related to a
-particular topic. With your cursor in the MH-Folder buffer and
-positioned on the message you sent to yourself, type @kbd{o} to output
-(@command{refile} in MH parlance) that message to a folder. Enter
-@kbd{test} at the @samp{Destination folder:} prompt and type @kbd{y}
-(or @key{SPC}) when MH-E asks to create the folder @samp{+test}. Note
-that a @samp{^} (caret) appears next to the message number, which
-means that the message has been marked for refiling but has not yet
-been refiled. We'll talk about how the refile is actually carried out
-in a moment.
-
-@cindex MH-Folder mode
-@cindex modes, MH-Folder
-@kindex d
-@kindex i
-@kindex RET
-@kindex n
-@kindex p
-@kindex x
-
-Your previous reply is now waiting in the system mailbox. You
-incorporate this mail into your MH-Folder buffer named @samp{+inbox}
-with the @kbd{i} command. Do this now. After the mail is incorporated,
-use @kbd{n} or @kbd{p} to move the cursor to the new message, and read
-it with @key{RET}. Let's delete this message by typing @kbd{d}. Note
-that a @samp{D} appears next to the message number. This means that
-the message is marked for deletion but is not yet deleted. To perform
-the deletion (and the refile we did previously), use the @kbd{x}
-command.
-
-@findex mh-smail
-@kindex m
-
-If you want to send another message you can use @kbd{m} instead of
-@kbd{M-x mh-smail}. So go ahead, send some mail to your friends!
-
-@cindex help
-@cindex prefix characters
-@findex describe-mode
-@kindex ?
-@kindex C-h m
-@kindex F ?
-
-You can get a quick reminder about these commands by typing @kbd{?}.
-This lists several @dfn{prefix characters}. To list the commands
-available via the prefix characters, type the prefix character
-followed by a @kbd{?}, for example, @kbd{F ?}. More complete help is
-available with the @kbd{C-h m} (@code{describe-mode}) command.
-
-@node Leaving MH-E
-@section Leaving MH-E
-
-@cindex Emacs, quitting
-@cindex quitting
-@kindex C-x C-c
-@kindex x
-
-You may now wish to exit @command{emacs} entirely. Use @kbd{C-x C-c}
-to exit @command{emacs}. If you exited without running @kbd{x} in the
-@samp{+inbox} buffer, Emacs will offer to save it for you. Type
-@kbd{y} or @key{SPC} to save @samp{+inbox} changes, which means to
-perform any refiles and deletes that you did there.
-
-@findex mh-rmail
-@kindex C-x b
-@kindex C-x k
-@kindex q
-
-If you don't want to leave Emacs, you can type @kbd{q} to bury (hide)
-the MH-E folder or delete it entirely with @kbd{C-x k}. You can then
-later recall it with @kbd{C-x b} or @kbd{M-x mh-rmail}.
-
-@cindex @command{packf}
-@cindex MH commands, @command{packf}
-@cindex exporting folders
-@cindex folders, exporting
-@cindex mbox-style folder
-
-On the other hand, if you no longer want to use MH and MH-E, you can
-take your mail with you. You can copy all of your mail into a single
-file, mbox-style, by using the MH command @command{packf}. For
-example, to create a file called @file{msgbox} with the messages in
-your @samp{+inbox} folder, use @samp{packf +inbox}. The
-@command{packf} command will append the messages to the file if it
-already exists, so you can use @samp{folders -recurse -fast} in a
-script to copy all of your messages into a single file, or using the
-@samp{-file} argument, a file for each folder.
-
-@node More About MH-E
-@section More About MH-E
-
-These are the basic commands to get you going, but there are plenty
-more. If you think that MH-E is for you, read the rest of the manual
-to find out how you can:
-
-@itemize @bullet
-@item
-Print your messages (@pxref{Printing}).
-@c -------------------------
-@item
-Edit messages and include your signature (@pxref{Editing Drafts}).
-@c -------------------------
-@item
-Forward messages (@pxref{Forwarding}).
-@c -------------------------
-@item
-Read digests (@pxref{Digests}).
-@c -------------------------
-@item
-Edit bounced messages (@pxref{Editing Again}).
-@c -------------------------
-@item
-Send multimedia messages (@pxref{Adding Attachments}).
-@c -------------------------
-@item
-Read HTML messages (@pxref{HTML}).
-@c -------------------------
-@item
-Use aliases and identities (@pxref{Aliases}, @pxref{Identities}).
-@c -------------------------
-@item
-Create different views of your mail (@pxref{Threading}, @pxref{Limits}).
-@c -------------------------
-@item
-Deal with junk mail (@pxref{Junk}).
-@c -------------------------
-@item
-Handle signed and encrypted messages (@pxref{Reading PGP},
-@pxref{Sending PGP}).
-@c -------------------------
-@item
-Process mail that was sent with @command{shar} or @command{uuencode}
-(@pxref{Files and Pipes}).
-@c -------------------------
-@item
-Use sequences conveniently (@pxref{Sequences}).
-@c -------------------------
-@item
-Use the speedbar, tool bar, and menu bar (@pxref{Speedbar}, @pxref{Tool
-Bar}, @pxref{Menu Bar}).
-@c -------------------------
-@item
-Show header fields in different fonts (@pxref{Reading Mail}).
-@c -------------------------
-@item
-Find previously refiled messages (@pxref{Searching}).
-@c -------------------------
-@item
-Place messages in a file (@pxref{Files and Pipes}).
-@end itemize
-
-Remember that you can also use MH commands when you're not running
-MH-E (and when you are!).
-
-@node Using This Manual
-@chapter Using This Manual
-
-This chapter begins the meat of the manual which goes into more detail
-about every MH-E command and option.
-
-@cindex Emacs, info
-@cindex Emacs, built-in help
-@cindex info
-@cindex built-in help
-@findex describe-mode
-@findex mh-help
-@kindex ?
-@kindex C-c ?
-@kindex C-h C-h
-@kindex C-h C-k i
-@kindex C-h i
-@kindex C-h m
-
-There are many commands, but don't get intimidated. There are command
-summaries at the beginning of each chapter. In case you have or would
-like to rebind the keys, the command summaries also list the
-associated Emacs Lisp function. Furthermore, even if you're stranded
-on a desert island with a laptop and are without your manuals, you can
-get a summary of all these commands with GNU Emacs built-in help: use
-@kbd{C-h m} (@code{describe-mode}) for a brief summary of commands,
-@kbd{?} (@code{mh-help}) for an even briefer summary@footnote{This
-help appears in a buffer called @file{*MH-E Help*}
-(@pxref{Miscellaneous}).} (@kbd{C-c ?} in MH-Letter mode), or @kbd{C-h
-i} to read this manual via Info. The built-in help is quite good; try
-running @kbd{C-h C-h}. This brings up a list of available help topics,
-one of which displays the documentation for a given key (like @kbd{C-h
-k C-n}). Another useful help feature is to view the manual section
-that describes a given key (such as @kbd{C-h K i}). In addition,
-review @ref{Conventions}, if any of the GNU Emacs conventions are
-strange to you.
-
-In addition to all of the commands, it is also possible to reconfigure
-MH-E to fit the needs of even the most demanding user. The following
-chapters also describe all of the options, show the defaults, and make
-recommendations for customization.
-
-However, when customizing your mail environment, first try to change
-what you want in MH, and only change MH-E if changing MH is not
-possible. That way you will get the same behavior inside and outside
-GNU Emacs. Note that MH-E does not provide hooks for customizations
-that can be done in MH; this omission is intentional.
-
-@cindex Emacs Lisp Manual
-@cindex Emacs, Emacs Lisp Manual
-@cindex Emacs, info
-@cindex Emacs, online help
-@cindex info
-@cindex online help
-
-I hope I've included enough examples here to get you well on your way.
-If you want to explore Emacs Lisp further, a programming manual does
-exist,
-@c Yes, some of the stuff in the following sections is redundant, but
-@c TeX barfs if the @ifs are inside the @footnote.
-@iftex
-@footnote{The @cite{GNU Emacs Lisp Reference Manual} should be available
-via the Info system by typing @kbd{C-h i m Emacs Lisp
-@key{RET}}. It is also available online at @*
-@uref{https://www.gnu.org/software/emacs/manual/elisp.html}.}
-@end iftex
-@ifinfo
-@footnote{@xref{Top, The GNU Emacs Lisp Reference Manual, , elisp, GNU
-Emacs Lisp Reference Manual}, which should be available via the
-Info system. It is also available online at
-@uref{https://www.gnu.org/software/emacs/manual/elisp.html}.}
-@end ifinfo
-@ifhtml
-@footnote{The
-@uref{https://www.gnu.org/software/emacs/manual/elisp.html,
-The GNU Emacs Lisp Reference Manual} should be available via
-the Info system by typing @kbd{C-h i m Emacs Lisp @key{RET}}.}
-@end ifhtml
-and you can look at the code itself for examples. Look in the Emacs
-Lisp directory on your system (such as
-@file{/usr/local/share/emacs/lisp/mh-e}) and find all the @file{mh-*.el}
-files there. When calling MH-E and other Emacs Lisp functions directly
-from Emacs Lisp code, you'll need to know the correct arguments. Use
-the built-in help for this. For example, try @kbd{C-h f
-mh-execute-commands @key{RET}}. If you write your own functions,
-please do not prefix your symbols (variables and functions) with
-@samp{mh-}. This prefix is reserved for the MH-E package. To avoid
-conflicts with existing MH-E symbols, use a prefix like @samp{my-} or
-your initials. (Unless, of course, your initials happen to be @emph{mh}!)
-
-@menu
-* Options::
-* Ranges::
-* Folder Selection::
-@end menu
-
-@node Options
-@section Options
-
-@cindex Emacs, customizing
-@cindex Emacs, setting options
-@cindex customizing MH-E
-@cindex setting options
-@findex customize-option
-@vindex mh-lpr-command-format@r{, example}
-
-Many string or integer options are easy to modify using @kbd{M-x
-customize-option}. For example, to modify the option that controls
-printing, you would run @kbd{M-x customize-option @key{RET}
-mh-lpr-command-format @key{RET}}. In the buffer that appears, modify
-the string to the right of the variable. For example, you may change
-the @command{lpr} command with @samp{nenscript -G -r -2 -i'%s'}. Then
-use the @samp{State} combo box and select @samp{Save for Future
-Sessions}. To read more about @code{mh-lpr-command-format}, see
-@ref{Printing}.
-
-@cindex nil
-@cindex off, option
-@cindex on, option
-@cindex option, turning on and off
-@cindex t
-@findex customize-option
-@vindex mh-bury-show-buffer-flag@r{, example}
-
-Options can also hold boolean values. In Emacs Lisp, the boolean
-values are @code{nil}, which means false, and @code{t}, which means
-true. The @code{customize-option} function makes it easy to change
-boolean values; simply click on the toggle button in the customize
-buffer to switch between @samp{on} (@code{t}) and @samp{off}
-(@code{nil}). For example, try setting @code{mh-bury-show-buffer-flag}
-to @samp{off} to keep the MH-Show buffer at the top of the buffer
-stack. Use the @samp{State} combo box and choose @samp{Set for Current
-Session} to see how the option affects the show buffer. Then choose
-the @samp{Erase Customization} menu item to reset the option to the
-default, which places the MH-Show buffer at the bottom of the buffer
-stack.
-
-@vindex mh-mhl-format-file@r{, example}
-
-The text usually says to turn on an option by setting it to a
-@emph{non-@code{nil}} value, because sometimes values other than
-@samp{on} are meaningful. An example of this is the variable
-@code{mh-mhl-format-file} (@pxref{Viewing}). Other options, such as
-hooks, involve a little more Emacs Lisp programming expertise.
-
-@cindex customization group, @samp{mh}
-@cindex @samp{mh} customization group
-@findex customize-group
-@findex mh-customize
-
-You can browse all of the MH-E options with the @code{customize-group}
-function. Try entering @kbd{M-x customize-group @key{RET} mh
-@key{RET}} to view the top-level options as well as buttons for all of
-the MH-E customization groups. Another way to view the MH-E
-customization group is to use @kbd{M-x mh-customize @key{RET}}.
-
-@node Ranges
-@section Ranges
-
-@c Sync with mh-folder-mode docstring.
-
-@cindex message abbreviations
-@cindex message ranges
-@cindex ranges
-
-Many commands that operate on individual messages, such as
-@code{mh-forward} or @code{mh-refile-msg} take a @code{RANGE}
-argument. This argument can be used in several ways.
-
-@kindex C-u@r{, with ranges}
-
-If you provide the prefix argument @kbd{C-u} to these commands, then
-you will be prompted for the message range. This can be any valid MH
-range which can include messages, sequences (@pxref{Sequences}), and
-the abbreviations (described in the @command{mh}(1) man page):
-
-@table @samp
-@item <num1>-<num2>
-Indicates all messages in the range <num1> to <num2>, inclusive. The
-range must be nonempty.
-@c -------------------------
-@item <num>:N
-@itemx <num>:+N
-@itemx <num>:-N
-Up to N messages beginning with (or ending with) message num. Num may
-be any of the predefined symbols: first, prev, cur, next or last.
-@c -------------------------
-@item first:N
-@itemx prev:N
-@itemx next:N
-@itemx last:N
-The first, previous, next or last messages, if they exist.
-@c -------------------------
-@item all
-All of the messages.
-@end table
-
-For example, a range that shows all of these things is @samp{1 2 3
-5-10 last:5 unseen}.
-
-@vindex transient-mark-mode
-
-If the option @code{transient-mark-mode} is turned on and you set a
-region in the MH-Folder buffer, then the MH-E command will perform the
-operation on all messages in that region.
-
-@cindex @samp{mh-range} customization group
-@cindex customization group, @samp{mh-range}
-
-The @samp{mh-range} customization group contains a single option which
-affects how ranges are interpreted.
-
-@vtable @code
-@item mh-interpret-number-as-range-flag
-On means interpret a number as a range (default: @samp{on}).
-@end vtable
-
-@vindex mh-interpret-number-as-range-flag
-
-Since one of the most frequent ranges used is @samp{last:N}, MH-E will
-interpret input such as @samp{200} as @samp{last:200} if the
-@code{mh-interpret-number-as-range-flag} option is on (which is the
-default). If you need to scan just the message 200, then use the range
-@samp{200:1} or @samp{200-200}.
-
-@node Folder Selection
-@section Folder Selection
-
-@cindex completion, folders
-@cindex folders, completion
-@cindex folders, selecting
-
-When you choose a folder in MH-E via a command such as @kbd{o}
-(@code{mh-refile-msg}), completion is used to enter the folder
-@ifnothtml
-(@pxref{Completion, , , emacs, The GNU Emacs Manual}).
-@end ifnothtml
-@ifhtml
-(see the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion.html,
-Completion} in @cite{The GNU Emacs Manual}).
-@end ifhtml
-In addition, MH-E has several ways of choosing a suitable default so
-that the folder can often be selected with a single @key{RET} key.
-
-@cindex customization group, @samp{mh-folder-selection}
-@cindex @samp{mh-folder-selection} customization group
-
-The @samp{mh-folder-selection} customization group contains some
-options which are used to help with this.
-
-@vtable @code
-@item mh-default-folder-for-message-function
-Function to select a default folder for refiling or @samp{Fcc:}
-(default: @code{nil}).
-@c -------------------------
-@item mh-default-folder-list
-List of addresses and folders (default: @code{nil}).
-@c -------------------------
-@item mh-default-folder-must-exist-flag
-On means guessed folder name must exist to be used (default:
-@samp{on}).
-@c -------------------------
-@item mh-default-folder-prefix
-Prefix used for folder names generated from aliases (default: @code{""}).
-@end vtable
-
-@vindex mh-default-folder-for-message-function
-
-You can set the option @code{mh-default-folder-for-message-function}
-to a function that provides a default folder for the message to be
-refiled. When this function is called, the current buffer contains the
-message being refiled and point is at the start of the message. This
-function should return the default folder as a string with a leading
-@samp{+} sign. It can also return @code{nil} so that the last folder
-name is used as the default, or an empty string to suppress the
-default entirely.
-
-Otherwise, the name of the destination folder is derived from the
-sender as follows:
-
-@enumerate
-@vindex mh-default-folder-list
-@item
-The folder name associated with the first address found in the list
-@code{mh-default-folder-list} is used. Each element in this list
-contains a @samp{Check Recipient} item. If this item is turned on,
-then the address is checked against the recipient instead of the
-sender. This is useful for mailing lists.
-@c -------------------------
-@vindex mh-default-folder-prefix
-@item
-An alias prefixed by @code{mh-default-folder-prefix} corresponding to
-the address is used. The prefix is used to prevent clutter in your
-mail directory. @xref{Aliases}.
-@end enumerate
-
-@vindex mh-default-folder-must-exist-flag
-
-If the derived folder does not exist, and
-@code{mh-default-folder-must-exist-flag} is @code{t}, then the last
-folder name used is suggested. This is useful if you get mail from
-various people for whom you have an alias, but file them all in the
-same project folder.
-
-@node Incorporating Mail
-@chapter Incorporating Your Mail
-
-@cindex @samp{Folder} menu
-@cindex incorporating
-@cindex menu, @samp{Folder}
-
-This chapter talks about getting mail from your system mailbox into
-your MH @samp{+inbox} folder. The following command accomplishes that
-and is found in the @samp{Folder} menu.
-
-@table @kbd
-@cindex @samp{Folder > Incorporate New Mail} menu item
-@cindex menu item, @samp{Folder > Incorporate New Mail}
-@findex mh-inc-folder
-@kindex i
-@item i
-Incorporate new mail into a folder (@code{mh-inc-folder}).
-@end table
-
-@cindex @samp{mh-inc} customization group
-@cindex customization group, @samp{mh-inc}
-
-The following options in the @samp{mh-inc} customization group are
-used.
-
-@vtable @code
-@item mh-inc-prog
-Program to incorporate mail (default: @code{"inc"}).
-@c -------------------------
-@item mh-inc-spool-list
-Alternate spool files (default: @code{nil}).
-@end vtable
-
-The following hook is available.
-
-@vtable @code
-@findex mh-inc-folder
-@item mh-inc-folder-hook
-Hook run by @code{mh-inc-folder} after incorporating mail into a
-folder (default: @code{nil}).
-@end vtable
-
-@cindex @samp{+inbox}
-@findex mh-inc-folder
-@kindex i
-
-If at any time you receive new mail, incorporate the new mail into
-your @samp{+inbox} buffer with @kbd{i} (@code{mh-inc-folder}). Note
-that @kbd{i} will display the @samp{+inbox} buffer, even if there
-isn't any new mail. You can incorporate mail from any file into the
-current folder by specifying a prefix argument; you'll be prompted for
-the name of the file to use as well as the destination folder (for
-example, @kbd{C-u i ~/mbox @key{RET} +tmp @key{RET}}).
-
-@cindex @file{.emacs}
-@cindex Emacs, notification of new mail
-@cindex files, @file{.emacs}
-@cindex new mail
-@cindex notification of new mail
-
-Emacs can notify you when you have new mail by displaying @samp{Mail}
-in the mode line. To enable this behavior, and to have a clock in the
-mode line as well, add the following to @file{~/.emacs}:
-
-@findex display-time
-
-@smalllisp
-(display-time)
-@end smalllisp
-
-@cindex @command{inc}
-@cindex incorporating
-@cindex MH commands, @command{inc}
-@vindex mh-inc-prog
-@vindex mh-progs
-
-The name of the program that incorporates new mail is stored in
-@code{mh-inc-prog}; it is @code{"inc"} by default. This program
-generates a one-line summary for each of the new messages. Unless it
-is an absolute pathname, the file is assumed to be in the
-@code{mh-progs} directory (@pxref{Getting Started}). You may also link
-a file to @command{inc} that uses a different format (see
-@samp{mh-profile}(5), and sections
-@uref{@value{MH-BOOK-HOME}/reapre.html, Reading Mail: inc show next
-prev} and @uref{@value{MH-BOOK-HOME}/mhstr.html, MH Format Strings} in
-the MH book). You'll then need to modify several variables
-appropriately (@pxref{Scan Line Formats}).
-
-@vindex mh-inc-spool-list
-
-You can use the @code{mh-inc-spool-list} variable to direct MH-E to
-retrieve mail from arbitrary spool files other than your system
-mailbox, file it in folders other than your @samp{+inbox}, and assign
-key bindings to incorporate this mail.
-
-@cindex @command{procmail}
-@cindex @file{.procmailrc}
-@cindex Unix commands, @command{procmail}
-@cindex files, @file{.procmailrc}
-
-Suppose you are subscribed to the @i{mh-e-devel} mailing list and you
-use @command{procmail} to filter this mail into @file{~/mail/mh-e}
-with the following recipe in @file{.procmailrc}:
-
-@smallexample
-PATH=$PATH:/usr/bin/mh
-MAILDIR=$HOME/`mhparam Path`
-:0:
-* ^From mh-e-devel-admin@@stop.mail-abuse.org
-mh-e
-@end smallexample
-
-@findex mh-inc-spool-*
-@kindex I *
-
-In order to incorporate @file{~/mail/mh-e} into @samp{+mh-e} with an
-@kbd{I m} (@code{mh-inc-spool-mh-e}) command, customize this option,
-and click on the @samp{INS} button. Enter a @samp{Spool File} of
-@samp{~/mail/mh-e}, a @samp{Folder} of @samp{mh-e}, and a @samp{Key
-Binding} of @samp{m}.
-
-@cindex @command{emacsclient}
-@cindex @command{xbuffy}
-@cindex Unix commands, @command{emacsclient}
-@cindex Unix commands, @command{xbuffy}
-
-You can use @command{xbuffy} to automate the incorporation of this
-mail using the Emacs command @command{emacsclient} as follows:
-
-@smallexample
-box ~/mail/mh-e
- title mh-e
- origMode
- polltime 10
- headertime 0
- command emacsclient --eval '(mh-inc-spool-mh-e)'
-@end smallexample
-
-@findex mh-inc-folder
-@kindex i
-@vindex mh-inc-folder-hook
-
-You can set the hook @code{mh-inc-folder-hook}, which is called after
-new mail is incorporated by the @kbd{i} (@code{mh-inc-folder})
-command. A good use of this hook is to rescan the whole folder either
-after running @kbd{M-x mh-rmail} the first time or when you've changed
-the message numbers from outside of MH-E.
-
-@findex mh-execute-commands
-@findex mh-rescan-folder@r{, example}
-@findex mh-show@r{, example}
-@vindex mh-inc-folder-hook@r{, example}
-
-@smalllisp
-@group
-(defun my-mh-inc-folder-hook ()
- "Hook to rescan folder after incorporating mail."
- (if (buffer-modified-p) ; @r{if outstanding refiles and deletes,}
- (mh-execute-commands)) ; @r{carry them out}
- (mh-rescan-folder) ; @r{synchronize with +inbox}
- (mh-show)) ; @r{show the current message}
-
-(add-hook 'mh-inc-folder-hook 'my-mh-inc-folder-hook)
-
-@i{Rescan folder after incorporating new mail via mh-inc-folder-hook}
-
-@end group
-@end smalllisp
-
-@node Reading Mail
-@chapter Reading Your Mail
-
-@cindex @samp{+inbox}
-@cindex MH-Folder mode
-@cindex MH-Show mode
-@cindex modes, MH-Folder
-@cindex modes, MH-Show
-@cindex reading mail
-@findex mh-rmail
-@kindex F r
-@kindex F v
-
-The MH-E entry point for reading mail is @kbd{M-x mh-rmail}. This
-command incorporates your mail and creates a buffer called
-@samp{+inbox} in MH-Folder mode. The command @kbd{M-x mh-rmail} shows
-you only new mail, not mail you have already read@footnote{If you want
-to see your old mail as well, use @kbd{F r} to pull all your messages
-into MH-E@. Or, give a prefix argument to @code{mh-rmail} so it will
-prompt you for folder to visit like @kbd{F v} (for example, @kbd{C-u
-M-x mh-rmail @key{RET} bob @key{RET}}). @xref{Folders}.}.
-
-@findex display-time
-@vindex read-mail-command
-
-There are some commands that need to read mail, such as @kbd{mouse-2}
-over the @samp{Mail} button that @code{display-time} adds to the mode
-line. You can configure Emacs to have these commands use MH-E by
-setting the option @code{read-mail-command} to @samp{mh-rmail}.
-
-@cindex @command{scan}
-@cindex @samp{Message} menu
-@cindex MH commands, @command{scan}
-@cindex menu, @samp{Message}
-@cindex scan lines
-
-The @samp{+inbox} buffer contains @dfn{scan lines}, which are one-line
-summaries of each incorporated message. You can perform most MH
-commands on these messages via one- or two-letter commands in either
-the MH-Folder or MH-Show buffers or by using the @samp{Message} menu.
-See @command{scan}(1) for a description of the contents of the scan
-lines, and see the Figure in @ref{Reading Mail Tour}, for an example.
-
-@table @kbd
-@kindex ?
-@findex mh-help
-@item ?
-Display cheat sheet for the MH-E commands (@code{mh-help}).
-@c -------------------------
-@cindex @samp{Message > Show Message} menu item
-@cindex menu item, @samp{Message > Show Message}
-@kindex RET
-@findex mh-show
-@item @key{RET}
-Display message (@code{mh-show}).
-@c -------------------------
-@cindex @samp{Message > Show Message with Header} menu item
-@cindex menu item, @samp{Message > Show Message with Header}
-@kindex , @r{(comma)}
-@findex mh-header-display
-@item , (comma)
-Display message with all header fields (@code{mh-header-display}).
-@c -------------------------
-@cindex @samp{Message > Show Message with Preferred Alternative} menu item
-@cindex menu item, @samp{Message > Show Message with Preferred Alternative}
-@kindex : @r{(colon)}
-@findex mh-show-preferred-alternative
-@item : (colon)
-Display message with the default preferred alternative
-(@code{mh-show-preferred-alternative}).
-@c -------------------------
-@kindex ; @r{(semicolon)}
-@findex mh-toggle-mh-decode-mime-flag
-@item ; (semicolon)
-Toggle the value of @code{mh-decode-mime-flag}
-(@code{mh-toggle-mh-decode-mime-flag}).
-@c -------------------------
-@kindex SPC
-@findex mh-page-msg
-@item @key{SPC}
-Display next page in message (@code{mh-page-msg}).
-@c -------------------------
-@kindex BS
-@findex mh-previous-page
-@item @key{BS}
-Display previous page in message (@code{mh-previous-page}).
-@c -------------------------
-@cindex @samp{Message > Write Message to File...} menu item
-@cindex menu item, @samp{Message > Write Message to File...}
-@kindex >
-@findex mh-write-msg-to-file
-@item >
-Append message to end of file (@code{mh-write-msg-to-file}).
-@c -------------------------
-@cindex @samp{Message > Pipe Message to Command...} menu item
-@cindex menu item, @samp{Message > Pipe Message to Command...}
-@kindex |
-@findex mh-pipe-msg
-@item |
-Pipe message through shell command (@code{mh-pipe-msg}).
-@c -------------------------
-@kindex C-d
-@findex mh-delete-msg-no-motion
-@item C-d
-Delete range, don't move to next message
-(@code{mh-delete-msg-no-motion}).
-@c -------------------------
-@cindex @samp{Message > Delete Message} menu item
-@cindex menu item, @samp{Message > Delete Message}
-@kindex d
-@findex mh-delete-msg
-@item d
-Delete range (@code{mh-delete-msg}).
-@c -------------------------
-@kindex D ?
-@findex mh-prefix-help
-@item D ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@kindex D SPC
-@findex mh-page-digest
-@item D @key{SPC}
-Display next message in digest (@code{mh-page-digest}).
-@c -------------------------
-@kindex D BS
-@findex mh-page-digest-backwards
-@item D @key{BS}
-Display previous message in digest (@code{mh-page-digest-backwards}).
-@c -------------------------
-@cindex @samp{Message > Burst Digest Message} menu item
-@cindex menu item, @samp{Message > Burst Digest Message}
-@kindex D b
-@findex mh-burst-digest
-@item D b
-Break up digest into separate messages (@code{mh-burst-digest}).
-@c -------------------------
-@cindex @samp{Message > Go to Message by Number...} menu item
-@cindex menu item, @samp{Message > Go to Message by Number...}
-@kindex g
-@findex mh-goto-msg
-@item g
-Go to a message (@code{mh-goto-msg}).
-@c -------------------------
-@kindex k
-@findex mh-delete-subject-or-thread
-@item k
-Delete messages with same subject or thread
-(@code{mh-delete-subject-or-thread}).
-@c -------------------------
-@kindex K ?
-@findex mh-prefix-help
-@item K ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@kindex K TAB
-@findex mh-next-button
-@item K @key{TAB}
-Go to the next button (@code{mh-next-button}).
-@c -------------------------
-@kindex K S-TAB
-@findex mh-prev-button
-@item K S-@key{TAB}
-Go to the previous button (@code{mh-prev-button}).
-@c -------------------------
-@kindex K a
-@findex mh-mime-save-parts
-@item K a
-Save attachments (@code{mh-mime-save-parts}).
-@c -------------------------
-@kindex K e
-@findex mh-display-with-external-viewer
-@item K e
-View attachment externally (@code{mh-display-with-external-viewer}).
-@c -------------------------
-@kindex K i
-@findex mh-folder-inline-mime-part
-@item K i
-Show attachment verbatim (@code{mh-folder-inline-mime-part}).
-@c -------------------------
-@kindex K o
-@findex mh-folder-save-mime-part
-@item K o
-Save (output) attachment (@code{mh-folder-save-mime-part}).
-@c -------------------------
-@kindex K t
-@findex mh-toggle-mime-buttons
-@item K t
-Toggle option @code{mh-display-buttons-for-inline-parts-flag}
-(@code{mh-toggle-mime-buttons}).
-@c -------------------------
-@kindex K v
-@findex mh-folder-toggle-mime-part
-@item K v
-View attachment (@code{mh-folder-toggle-mime-part}).
-@c -------------------------
-@cindex @samp{Message > Modify Message} menu item
-@cindex menu item, @samp{Message > Modify Message}
-@kindex M
-@findex mh-modify
-@item M
-Edit message (@code{mh-modify}).
-@c -------------------------
-@cindex @samp{Message > Go to First Message} menu item
-@cindex menu item, @samp{Message > Go to First Message}
-@kindex M-<
-@findex mh-first-msg
-@item M-<
-Display first message (@code{mh-first-msg}).
-@c -------------------------
-@cindex @samp{Message > Go to Last Message} menu item
-@cindex menu item, @samp{Message > Go to Last Message}
-@kindex M->
-@findex mh-last-msg
-@item M->
-Display last message (@code{mh-last-msg}).
-@c -------------------------
-@kindex M-n
-@findex mh-next-unread-msg
-@item M-n
-Display next unread message (@code{mh-next-unread-msg}).
-@c -------------------------
-@kindex M-p
-@findex mh-previous-unread-msg
-@item M-p
-Display previous unread message (@code{mh-previous-unread-msg}).
-@c -------------------------
-@cindex @samp{Message > Next Message} menu item
-@cindex menu item, @samp{Message > Next Message}
-@kindex n
-@findex mh-next-undeleted-msg
-@item n
-Display next message (@code{mh-next-undeleted-msg}).
-@c -------------------------
-@cindex @samp{Message > Previous Message} menu item
-@cindex menu item, @samp{Message > Previous Message}
-@kindex p
-@findex mh-previous-undeleted-msg
-@item p
-Display previous message (@code{mh-previous-undeleted-msg}).
-@c -------------------------
-@kindex P ?
-@findex mh-prefix-help
-@item P ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@kindex P C
-@findex mh-ps-print-toggle-color
-@item P C
-Toggle whether color is used in printing messages
-(@code{mh-ps-print-toggle-color}).
-@c -------------------------
-@kindex P F
-@findex mh-ps-print-toggle-faces
-@item P F
-Toggle whether printing is done with faces or not
-(@code{mh-ps-print-toggle-faces}).
-@c -------------------------
-@kindex P f
-@findex mh-ps-print-msg-file
-@item P f
-Print range to file (@code{mh-ps-print-msg-file}).
-@c -------------------------
-@cindex @samp{Message > Print Message} menu item
-@cindex menu item, @samp{Message > Print Message}
-@kindex P l
-@findex mh-print-msg
-@item P l
-Print range the old fashioned way
-(@code{mh-print-msg}).
-@c -------------------------
-@kindex P p
-@findex mh-ps-print-msg
-@item P p
-Print range (@code{mh-ps-print-msg}).
-@c -------------------------
-@kindex X ?
-@findex mh-prefix-help
-@item X ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@cindex @samp{Message > Unpack Uuencoded Message...} menu item
-@cindex menu item, @samp{Message > Unpack Uuencoded Message...}
-@kindex X s
-@kindex X u
-@findex mh-store-msg
-@item X s
-@itemx X u
-Unpack message created with @command{uudecode} or @command{shar}
-(@code{mh-store-msg}).
-@c -------------------------
-@kindex mouse-2
-@findex mh-show-mouse
-@item mouse-2
-Move point to mouse event and show message (@code{mh-show-mouse}).
-@end table
-
-Within the MH-Show buffer, the following command is defined.
-
-@table @kbd
-@kindex RET
-@kindex mouse-1
-@kindex mouse-2
-@findex mh-press-button
-@item @key{RET}
-@itemx mouse-1
-@itemx mouse-2
-View contents of button (@code{mh-press-button}).
-@end table
-
-@cindex @samp{mh-show} customization group
-@cindex customization group, @samp{mh-show}
-
-The following table lists options in the @samp{mh-show} customization
-group that are used while reading mail.
-
-@vtable @code
-@item mh-bury-show-buffer-flag
-On means show buffer is buried (default: @samp{on}).
-@c -------------------------
-@item mh-clean-message-header-flag
-On means remove extraneous header fields (default: @samp{on}).
-@c -------------------------
-@item mh-decode-mime-flag
-On means attachments are handled (default: @samp{on} if the Gnus
-@samp{mm-decode} package is present).
-@c -------------------------
-@item mh-display-buttons-for-alternatives-flag
-On means display buttons for all alternative attachments (default:
-@samp{off}).
-@c -------------------------
-@item mh-display-buttons-for-inline-parts-flag
-On means display buttons for all inline attachments (default:
-@samp{off}).
-@c -------------------------
-@item mh-do-not-confirm-flag
-On means non-reversible commands do not prompt for confirmation
-(default: @samp{off}).
-@c -------------------------
-@item mh-fetch-x-image-url
-Control fetching of @samp{X-Image-URL:} header field image (default:
-@samp{Never Fetch}).
-@c -------------------------
-@item mh-graphical-smileys-flag
-On means graphical smileys are displayed (default: @samp{on}).
-@c -------------------------
-@item mh-graphical-emphasis-flag
-On means graphical emphasis is displayed (default: @samp{on}).
-@c -------------------------
-@item mh-highlight-citation-style
-Style for highlighting citations (default: @samp{Multicolor}).
-@c -------------------------
-@item mh-invisible-header-fields-default
-List of hidden header fields (default: a checklist too long to list
-here).
-@c -------------------------
-@item mh-invisible-header-fields
-Additional header fields to hide (default: @code{nil}).
-@c -------------------------
-@item mh-lpr-command-format
-Command used to print (default: @code{"lpr -J '%s'"}).
-@c -------------------------
-@item mh-max-inline-image-height
-Maximum inline image height if @samp{Content-Disposition:} is not
-present (default: 0).
-@c -------------------------
-@item mh-max-inline-image-width
-Maximum inline image width if @samp{Content-Disposition:} is not
-present(default: 0).
-@c -------------------------
-@item mh-mhl-format-file
-Specifies the format file to pass to the @command{mhl} program
-(default: @samp{Use Default mhl Format (Printing Only)}).
-@c -------------------------
-@item mh-mime-save-parts-default-directory
-Default directory to use for @kbd{K a}.
-@c -------------------------
-@item mh-print-background-flag
-On means messages should be printed in the background (default:
-@samp{off}).
-@c -------------------------
-@item mh-show-buffer-mode-line-buffer-id
-Format string to produce @code{mode-line-buffer-identification} for
-show buffers (default: @code{" @{show-%s@} %d"}).
-@c -------------------------
-@item mh-show-maximum-size
-Maximum size of message (in bytes) to display automatically (default:
-0).
-@c -------------------------
-@item mh-show-use-xface-flag
-On means display face images in MH-Show buffers (default: @samp{on}).
-@c -------------------------
-@item mh-store-default-directory
-Default directory for @kbd{X s} (default: @samp{Current}).
-@c -------------------------
-@item mh-summary-height
-Number of lines in MH-Folder buffer (including the mode line)
-(default: depends on size of frame).
-@end vtable
-
-The following hooks are available.
-
-@vtable @code
-@item mh-delete-msg-hook
-Hook run after marking each message for deletion (default: @code{nil}).
-@c -------------------------
-@item mh-show-hook
-Hook run after @key{RET} shows a message (default: @code{nil}).
-@c -------------------------
-@item mh-show-mode-hook
-Hook run upon entry to @code{mh-show-mode} (default: @code{nil}).
-@end vtable
-
-The following faces are available.
-
-@vtable @code
-@item mh-show-cc
-Face used to highlight @samp{cc:} header fields.
-@c -------------------------
-@item mh-show-date
-Face used to highlight @samp{Date:} header fields.
-@c -------------------------
-@item mh-show-from
-Face used to highlight @samp{From:} header fields.
-@c -------------------------
-@item mh-show-header
-Face used to deemphasize less interesting header fields.
-@c -------------------------
-@item mh-show-pgg-bad
-Bad PGG signature face.
-@c -------------------------
-@item mh-show-pgg-good
-Good PGG signature face.
-@c -------------------------
-@item mh-show-pgg-unknown
-Unknown or untrusted PGG signature face.
-@c -------------------------
-@item mh-show-signature
-Signature face.
-@c -------------------------
-@item mh-show-subject
-Face used to highlight @samp{Subject:} header fields.
-@c -------------------------
-@item mh-show-to
-Face used to highlight @samp{To:} header fields.
-@c -------------------------
-@item mh-show-xface
-X-Face image face.
-@end vtable
-
-The functions and variables introduced here are explained in more
-detail in the following sections.
-
-@menu
-* Viewing::
-* Viewing Attachments::
-* HTML::
-* Digests::
-* Reading PGP::
-* Printing::
-* Files and Pipes::
-* Navigating::
-* Miscellaneous Commands and Options::
-@end menu
-
-@node Viewing
-@section Viewing Your Mail
-
-@findex mh-header-display
-@findex mh-page-msg
-@findex mh-previous-page
-@findex mh-show
-@findex mh-show-mouse
-@kindex , @r{(comma)}
-@kindex . @r{(period)}
-@kindex BS
-@kindex RET
-@kindex SPC
-@kindex mouse-2
-
-The command @key{RET} (@code{mh-show}) displays the message that the
-cursor is on while @kbd{mouse-2} (@code{mh-show-mouse}) displays the
-message that the mouse cursor is on. If the message is already
-displayed, it scrolls to the beginning of the message. Use @key{SPC}
-(@code{mh-page-msg}) and @key{BS} (@code{mh-previous-page}) to move
-forwards and backwards one page at a time through the message. You can
-give either of these commands a prefix argument that specifies the
-number of lines to scroll (such as @kbd{10 @key{SPC}}). The @key{SPC}
-command will also show the next undeleted message if it is used at the
-bottom of a message. MH-E normally hides a lot of the superfluous
-header fields that mailers add to a message, but if you wish to see
-all of them, use the command @kbd{,} (comma;
-@code{mh-header-display}).
-
-@vindex mh-show-maximum-size
-
-The option @code{mh-show-maximum-size} provides an opportunity to skip
-over large messages which may be slow to load. The default value of 0
-means that all message are shown regardless of size.
-
-A litany of options control what displayed messages look like.
-
-@vindex mh-show-cc
-@vindex mh-show-date
-@vindex mh-show-from
-@vindex mh-show-header
-@vindex mh-show-subject
-@vindex mh-show-to
-
-First, the appearance of the header fields can be modified by
-customizing the associated face: @code{mh-show-to}, @code{mh-show-cc},
-@code{mh-show-from}, @code{mh-show-date}, and @code{mh-show-subject}.
-The face @code{mh-show-header} is used to deemphasize the other, less
-interesting, header fields.
-
-@cindex regular expressions, @code{mh-invisible-header-fields}
-@vindex mh-clean-message-header-flag
-@vindex mh-invisible-header-fields
-@vindex mh-invisible-header-fields-default
-
-Normally messages are delivered with a handful of uninteresting header
-fields. These are hidden by turning on the option
-@code{mh-clean-message-header-flag} (which it is by default). The
-header fields listed in the option
-@code{mh-invisible-header-fields-default} are hidden, although you can
-check off any field that you would like to see. Header fields that you
-would like to hide that aren't listed can be added to the option
-@code{mh-invisible-header-fields} with a couple of caveats. Regular
-expressions are not allowed. Unique fields should have a @samp{:}
-suffix; otherwise, the element can be used to render invisible an
-entire class of fields that start with the same prefix. If you think a
-header field should be generally ignored, please update
-@uref{https://sourceforge.net/p/mh-e/bugs/245/, SF #245}.
-
-@cindex header field, @samp{Face}
-@cindex header field, @samp{X-Face}
-@cindex header field, @samp{X-Image-URL}
-@cindex @samp{Face} header field
-@cindex @samp{X-Face} header field
-@cindex @samp{X-Image-URL} header field
-@vindex mh-show-use-xface-flag
-
-MH-E can display the content of @samp{Face:}, @samp{X-Face:}, and
-@samp{X-Image-URL:} header fields. If any of these fields occur in the
-header of your message, the sender's face will appear in the
-@samp{From:} header field. If more than one of these fields appear,
-then the first field found in the order @samp{Face:}, @samp{X-Face:},
-and @samp{X-Image-URL:} will be used. The option
-@code{mh-show-use-xface-flag} is used to turn this feature on and off.
-This feature will be turned on by default if your system supports it.
-
-The first header field used, if present, is the Gnus-specific
-@samp{Face:} field@footnote{For more information, see
-@uref{https://quimby.gnus.org/circus/face/}.}.
-
-@cindex @command{uncompface}
-@cindex Emacs, packages, @samp{x-face}
-@cindex Unix commands, @command{uncompface}
-@cindex @samp{x-face} package
-@vindex mh-show-xface
-
-@c FIXME: These URLs do not seem to work any more.
-Next is the traditional @samp{X-Face:} header field@footnote{The
-display of this field requires the
-@uref{ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z,
-@command{uncompface} program}.} MH-E renders the foreground and
-background of the image using the associated attributes of the face
-@code{mh-show-xface}.
-
-@cindex @command{convert}
-@cindex @command{wget}
-@cindex ImageMagick
-@cindex Unix commands, @command{convert}
-@cindex Unix commands, @command{wget}
-@vindex mh-fetch-x-image-url
-
-Finally, MH-E will display images referenced by the
-@samp{X-Image-URL:} header field if neither the @samp{Face:} nor the
-@samp{X-Face:} fields are present@footnote{The display of the images
-requires the @uref{https://www.gnu.org/software/wget/wget.html,
-@command{wget} program} to fetch the image and the @command{convert}
-program from the @uref{https://www.imagemagick.org/script/index.php,
-ImageMagick suite}.}. Of the three header fields this is the most
-efficient in terms of network usage since the image doesn't need to be
-transmitted with every single mail. The option
-@code{mh-fetch-x-image-url} controls the fetching of the
-@samp{X-Image-URL:} header field image with the following values:
-
-@table @samp
-@item Ask Before Fetching
-You are prompted before the image is fetched. MH-E will remember your
-reply and will either use the already fetched image the next time the
-same URL is encountered or silently skip it if you didn't fetch it the
-first time. This is a good setting.
-@c -------------------------
-@item Never Fetch
-Images are never fetched and only displayed if they are already
-present in the cache. This is the default.
-@end table
-
-There isn't a value of @samp{Always Fetch} for privacy and DOS (denial
-of service) reasons. For example, fetching a URL can tip off a spammer
-that you've read his email (which is why you shouldn't blindly answer
-yes if you've set this option to @samp{Ask Before Fetching}). Someone
-may also flood your network and fill your disk drive by sending a
-torrent of messages, each specifying a unique URL to a very large
-file.
-
-@cindex @file{.mhe-x-image-cache}
-@cindex files, @file{.mhe-x-image-cache}
-
-The cache of images is found in the directory
-@file{.mhe-x-image-cache} within your MH directory. You can add your
-own face to the @samp{From:} field too. @xref{Picture}.
-
-@cindex @command{mhl}
-@cindex MH commands, @command{mhl}
-@vindex mh-mhl-format-file
-
-Normally MH-E takes care of displaying messages itself (rather than
-calling an MH program to do the work). If you'd rather have
-@command{mhl} display the message (within MH-E), change the option
-@code{mh-mhl-format-file} from its default value of @samp{Use Default
-mhl Format (Printing Only)}. You can set this option to @samp{Use
-Default mhl Format} to get the same output as you would get if you ran
-@command{mhl} from the shell. If you have a format file that you want
-MH-E to use, you can set this option to @samp{Specify an mhl Format
-File} and enter the name of your format file (@command{mhl}(1) or
-section @uref{@value{MH-BOOK-HOME}/shomes.html#Usisho, Using mhl} in
-the MH book tells you how to write one). Your format file should
-specify a non-zero value for @samp{overflowoffset} to allow MH-E to
-parse the header. Note that @command{mhl} is always used for printing
-and forwarding; in this case, the value of @code{mh-mhl-format-file}
-is consulted if you have specified a format file.
-
-@cindex citations, highlighting
-@cindex highlighting citations
-@vindex mh-highlight-citation-style
-
-If the sender of the message has cited other messages in his message,
-then MH-E will highlight these citations to emphasize the sender's
-actual response. The option @code{mh-highlight-citation-style} can be
-customized to change the highlighting style. The @samp{Multicolor}
-method uses a different color for each indentation while the
-@samp{Monotone} method highlights all citations in red. To disable
-highlighting of citations entirely, choose @samp{None}.
-
-@cindex URLs, highlighting
-@cindex email addresses, highlighting
-@cindex highlighting URLs
-@cindex highlighting email addresses
-@cindex links, following
-@findex goto-address-at-point
-@kindex C-c RET
-@kindex mouse-2
-@vindex goto-address-highlight-p
-
-Email addresses and URLs in the message are highlighted if the option
-@code{goto-address-highlight-p} is on, which it is by default. To view
-the web page for a highlighted URL or to send a message using a
-highlighted email address, use @kbd{mouse-2} or @kbd{C-c @key{RET}}
-(@code{goto-address-at-point}). @xref{Sending Mail}, to see how to
-configure Emacs to send the message using MH-E.
-
-@cindex boldface, showing
-@cindex emphasis
-@cindex italics, showing
-@cindex smileys
-@cindex typesetting
-@cindex underline, showing
-@vindex gnus-emphasis-alist
-@vindex mh-decode-mime-flag
-@vindex mh-graphical-emphasis-flag
-@vindex mh-graphical-smileys-flag
-
-It is a long standing custom to inject body language using a
-cornucopia of punctuation, also known as the @dfn{smileys}. MH-E can
-render these as graphical widgets if the option
-@code{mh-graphical-smileys-flag} is turned on, which it is by default.
-Smileys include patterns such as :-) and ;-). Similarly, a few
-typesetting features are indicated in ASCII text with certain
-characters. If your terminal supports it, MH-E can render these
-typesetting directives naturally if the option
-@code{mh-graphical-emphasis-flag} is turned on, which it is by
-default. For example, _underline_ will be
-@ifhtml
-@html
-<u>underlined</u>,
-@end html
-@end ifhtml
-@ifnothtml
-underlined,
-@end ifnothtml
-*bold* will appear in @b{bold}, /italics/ will appear in @i{italics},
-and so on. See the option @code{gnus-emphasis-alist} for the whole
-list. Both of these options are disabled if the option
-@code{mh-decode-mime-flag} is turned off. @xref{Viewing Attachments}.
-
-@cindex signature separator
-@cindex vCard
-@vindex mh-show-signature
-
-MH-E normally renders signatures and vCards in italics so that the
-body of the message stands out more. MH-E depends on the presence of
-the @dfn{signature separator} (@code{"-- "}) to do this. You can also
-customize the face @code{mh-show-signature} so the appearance of the
-signature block is more to your liking.
-
-@vindex mh-show-hook
-@vindex mh-show-mode-hook
-
-Two hooks can be used to control how messages are displayed. The first
-hook, @code{mh-show-mode-hook}, is called early on in the process of
-the message display. It is usually used to perform some action on the
-message's buffer. The second hook, @code{mh-show-hook}, is the last
-thing called after messages are displayed. It's used to affect the
-message's content, the behavior of MH-E in general, or when
-@code{mh-show-mode-hook} is too early.
-
-@cindex MH-Show mode
-@cindex modes, MH-Show
-@vindex mh-show-buffer-mode-line-buffer-id
-
-For those who like to modify their mode lines, use
-@code{mh-show-buffer-mode-line-buffer-id} to modify the mode line in
-the MH-Show buffers. Place the two escape strings @samp{%s} and
-@samp{%d}, which will display the folder name and the message number,
-respectively, somewhere in the string in that order. The default value
-of @code{"@{show-%s@} %d"} yields a mode line of
-
-@smallexample
------@{show-+inbox@} 4 (MH-Show)--Bot--------------------------------
-@end smallexample
-
-@node Viewing Attachments
-@section Viewing Attachments
-
-@cindex attachments
-@cindex body parts
-@cindex @command{mhshow}
-@cindex @command{show}
-@cindex MH commands, @command{mhshow}
-@cindex MH commands, @command{show}
-@cindex MIME
-@cindex multimedia mail
-
-MH has the ability to display @dfn{@sc{mime}} (Multipurpose Internet
-Mail Extensions) messages which are simply messages with additional
-@dfn{body parts} or @dfn{attachments}. You can use the MH commands
-@command{show}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/reapre.html, Reading Mail: inc show next
-prev} in the MH book.} or @command{mhshow}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/usimim.html#ReMIMa, Reading MIME Mail} in
-the MH book.} from the shell to read @sc{mime} messages@footnote{You
-can call them directly from Emacs if you're running the X Window
-System: type @kbd{M-! xterm -e mhshow @var{message-number}}. You can
-leave out the @samp{xterm -e} if you use @command{mhlist} or
-@command{mhstore}.}.
-
-@cindex Emacs, packages, @samp{mm-decode}
-@cindex @samp{mm-decode} package
-@findex mh-toggle-mh-decode-mime-flag
-@kindex ; @r{(semicolon)}
-@vindex mh-decode-mime-flag
-
-MH-E can handle attachments as well if the Gnus @samp{mm-decode}
-package is present. If so, the option @code{mh-decode-mime-flag} will
-be on. Otherwise, you'll see the @sc{mime} body parts rather than text
-or attachments. There isn't much point in turning off the option
-@code{mh-decode-mime-flag}; however, you can inspect it if it appears
-that the body parts are not being interpreted correctly or toggle it
-with the command @kbd{;} (semicolon;
-@code{mh-toggle-mh-decode-mime-flag}) to view the raw message. This
-option also controls the display of quoted-printable messages and
-other graphical widgets. @xref{Viewing}.
-
-@cindex buttons
-
-Attachments in MH-E are indicated by @dfn{buttons} like this:
-
-@smallexample
-[1. image/jpeg; foo.jpg]...
-@end smallexample
-
-@findex mh-next-button
-@findex mh-press-button
-@findex mh-prev-button
-@kindex RET
-@kindex K TAB
-@kindex K S-TAB
-@kindex mouse-1
-@kindex mouse-2
-
-To view the contents of the button, use either @kbd{mouse-1} or
-@kbd{mouse-2} on the button or @key{RET} (@code{mh-press-button}) when
-the cursor is over the button. This command is a toggle so if you use
-it again on the same attachment, it is hidden. If Emacs does not know
-how to display the attachment, then Emacs offers to save the
-attachment in a file. To move the cursor to the next button, use the
-command @kbd{K @key{TAB}} (@code{mh-next-button}). If the end of the
-buffer is reached then the search wraps over to the start of the
-buffer. To move the cursor to the previous button, use the command
-@kbd{K S-@key{TAB}} (@code{mh-prev-button}). If the beginning of the
-buffer is reached then the search wraps over to the end of the buffer.
-
-@cindex attachments, viewing
-@cindex viewing attachments
-@findex mh-folder-toggle-mime-part
-@kindex K v
-
-Another way to view the contents of a button is to use the command
-@kbd{K v} (@code{mh-folder-toggle-mime-part}). This command displays
-(or hides) the attachment associated with the button under the cursor.
-If the cursor is not located over a button, then the cursor first
-moves to the next button, wrapping to the beginning of the message if
-necessary. This command has the advantage over the previous commands
-of working from the MH-Folder buffer. You can also provide a numeric
-prefix argument (as in @kbd{4 K v}) to view the attachment labeled
-with that number. If Emacs does not know how to display the
-attachment, then Emacs offers to save the attachment in a file.
-
-@cindex @file{/etc/mailcap}
-@cindex files, @file{/etc/mailcap}
-@findex mailcap-mime-info
-@findex mh-display-with-external-viewer
-@kindex K e
-
-If Emacs does not know how to view an attachment, you could save it
-into a file and then run some program to open it. It is easier,
-however, to launch the program directly from MH-E with the command
-@kbd{K e} (@code{mh-display-with-external-viewer}). While you'll most
-likely use this to view spreadsheets and documents, it is also useful
-to use your browser to view HTML attachments with higher fidelity than
-what Emacs can provide. This command displays the attachment
-associated with the button under the cursor. If the cursor is not
-located over a button, then the cursor first moves to the next button,
-wrapping to the beginning of the message if necessary. You can provide
-a numeric prefix argument (as in @kbd{4 K e}) to view the attachment
-labeled with that number. This command tries to provide a reasonable
-default for the viewer by calling the Emacs function
-@code{mailcap-mime-info}. This function usually reads the file
-@file{/etc/mailcap}.
-
-@cindex attachments, saving
-@cindex saving attachments
-@findex mh-folder-save-mime-part
-@kindex K o
-
-Use the command @kbd{K o} (@code{mh-folder-save-mime-part}) to save
-attachments (the mnemonic is ``output''). This command saves the
-attachment associated with the button under the cursor. If the cursor
-is not located over a button, then the cursor first moves to the next
-button, wrapping to the beginning of the message if necessary. You can
-also provide a numeric prefix argument (as in @kbd{3 K o}) to save the
-attachment labeled with that number. This command prompts you for a
-filename and suggests a specific name if it is available.
-
-@cindex @command{mhn}
-@cindex @command{mhstore}
-@cindex MH commands, @command{mhn}
-@cindex MH commands, @command{mhstore}
-@findex mh-mime-save-parts
-@kindex K a
-@vindex mh-mime-save-parts-default-directory
-
-You can save all of the attachments at once with the command @kbd{K a}
-(@code{mh-mime-save-parts}). The attachments are saved in the
-directory specified by the option
-@code{mh-mime-save-parts-default-directory} unless you use a prefix
-argument (as in @kbd{C-u K a}) in which case you are prompted for the
-directory. These directories may be superseded by MH profile
-components, since this function calls on @command{mhstore}
-(@command{mhn}) to do the work.
-
-@vindex mh-mime-save-parts-default-directory
-
-The default value for the option
-@code{mh-mime-save-parts-default-directory} is @samp{Prompt Always} so
-that you are always prompted for the directory in which to save the
-attachments. However, if you usually use the same directory within a
-session, then you can set this option to @samp{Prompt the First Time}
-to avoid the prompt each time. you can make this directory permanent
-by choosing @samp{Directory} and entering the directory's name.
-
-@cindex attachments, inline
-@cindex inline attachments
-@findex mh-toggle-mime-buttons
-@kindex K t
-@vindex mh-display-buttons-for-inline-parts-flag
-
-The sender can request that attachments should be viewed inline so
-that they do not really appear like an attachment at all to the
-reader. Most of the time, this is desirable, so by default MH-E
-suppresses the buttons for inline attachments. On the other hand, you
-may receive code or HTML which the sender has added to his message as
-inline attachments so that you can read them in MH-E@. In this case, it
-is useful to see the buttons so that you know you don't have to cut
-and paste the code into a file; you can simply save the attachment. If
-you want to make the buttons visible for inline attachments, you can
-use the command @kbd{K t} (@code{mh-toggle-mime-buttons}) to toggle
-the visibility of these buttons. You can turn on these buttons
-permanently by turning on the option
-@code{mh-display-buttons-for-inline-parts-flag}.
-
-MH-E cannot display all attachments inline however. It can display
-text (including @sc{html}) and images.
-
-@cindex header field, @samp{Content-Disposition}
-@cindex inline images
-@cindex @samp{Content-Disposition} header field
-@vindex mh-max-inline-image-height
-@vindex mh-max-inline-image-width
-
-Some older mail programs do not insert the needed
-plumbing@footnote{This plumbing is the @samp{Content-Disposition:}
-header field.} to tell MH-E whether to display the attachments inline
-or not. If this is the case, MH-E will display these images inline if
-they are smaller than the window. However, you might want to allow
-larger images to be displayed inline. To do this, you can change the
-options @code{mh-max-inline-image-width} and
-@code{mh-max-inline-image-height} from their default value of zero to
-a large number. The size of your screen is a good choice for these
-numbers.
-
-@cindex alternatives
-@cindex attachments, alternatives
-@vindex mh-display-buttons-for-alternatives-flag
-
-Sometimes, a mail program will produce multiple alternatives of an
-attachment in increasing degree of faithfulness to the original
-content. By default, only the preferred alternative is displayed. If
-the option @code{mh-display-buttons-for-alternatives-flag} is on, then
-the preferred part is shown inline and buttons are shown for each of
-the other alternatives.
-
-@vindex mm-discouraged-alternatives
-
-Many people prefer to see the @samp{text/plain} alternative rather
-than the @samp{text/html} alternative. To do this in MH-E, customize
-the option @code{mm-discouraged-alternatives}, and add
-@samp{text/html}. The next best alternative, if any, will be shown.
-
-@findex mh-show-preferred-alternative
-@kindex : @r{(colon)}
-
-Occasionally, though, you might want to see the preferred alternative.
-The command @kbd{:} (@code{mh-show-preferred-alternative}) displays
-the message with the default preferred alternative. This is as if
-@code{mm-discouraged-alternatives} is set to @samp{nil}. Use the
-command @key{RET} (@code{mh-show}) to show the message normally again.
-
-@kindex K i
-@findex mh-folder-inline-mime-part
-
-You can view the raw contents of an attachment with the command @kbd{K
-i} (@code{mh-folder-inline-mime-part}). This command displays (or
-hides) the contents of the attachment associated with the button under
-the cursor verbatim. If the cursor is not located over a button, then
-the cursor first moves to the next button, wrapping to the beginning
-of the message if necessary. You can also provide a numeric prefix
-argument (as in @kbd{4 K i}) to view the attachment labeled with that
-number.
-
-For additional information on buttons, see
-@ifinfo
-@ref{Article Buttons,,,gnus}, and @ref{MIME Commands,,,gnus}.
-@end ifinfo
-@ifnotinfo
-the chapters @uref{https://www.gnus.org/manual/gnus_101.html#SEC101,
-Article Buttons} and
-@uref{https://www.gnus.org/manual/gnus_108.html#SEC108, MIME Commands}
-in the @cite{The Gnus Manual}.
-@end ifnotinfo
-
-@node HTML
-@section HTML
-
-@cindex HTML
-@cindex Gnus
-
-MH-E can display messages that have been sent in HTML. The
-content of the message will appear in the MH-Show buffer as you would
-expect if the entire message is HTML, or there is an inline HTML body
-part. However, if there is an HTML body part that is an attachment,
-then you'll see a button like this:
-
-@smallexample
-[1. text/html; foo.html]...
-@end smallexample
-
-To see how to read the contents of this body part, see @ref{Viewing
-Attachments}.
-
-@vindex mm-text-html-renderer
-
-The browser that MH-E uses is determined by the option
-@code{mm-text-html-renderer}. The default setting is set automatically
-based upon the presence of a known browser on your system. If you wish
-to use a different browser, then set this option accordingly. See the
-documentation for the browser you use for additional information on
-how to use it. In particular, find and disable the option to render
-images, as displaying remote images can tip off spammers that the
-email address they have used is valid.
-
-@vindex mm-text-html-renderer
-
-If you're confused about which @code{mm-text-html-renderer} to use,
-here's a brief description of each, sorted by name.
-
-@table @asis
-@cindex browser, @samp{gnus-w3m}
-@cindex @samp{gnus-w3m}
-@cindex browser, @samp{w3m}
-@cindex @samp{w3m}
-@item @samp{gnus-w3m}
-The @samp{gnus-w3m} browser requires an external program. It's quick,
-produces pretty nice output, and it highlights links. It renders
-@samp{–} and @samp{®} okay. It sometimes fails to wrap lines
-properly. It always downloads remote images.
-@c -------------------------
-@cindex browser, @samp{links}
-@cindex @samp{links}
-@item @samp{links}
-The @samp{links} browser requires an external program. It's quick, and
-produces nicer output than @samp{lynx} on single column mails in
-tables. However, it doesn't show links and it doesn't do as nice a job
-on multi-column tables as some lines wrap. It does do a good job of
-fitting text within 80 columns. It appears to render special
-characters using ASCII equivalents. For example, @samp{®} appears
-as (R). It does not download images.
-@c -------------------------
-@cindex browser, @samp{lynx}
-@cindex @samp{lynx}
-@item @samp{lynx}
-The @samp{lynx} browser requires an external program. It's quick and
-produces pretty decent output but it doesn't show links. It doesn't
-seem to do multi-column tables which makes output much cleaner. It
-centers the output and wraps long lines more than most. It does not
-always handle special characters like @samp{®} or @samp{–}.
-It does not download images.
-@c -------------------------
-@item @samp{shr}
-@cindex @samp{shr}
-This choice does not require an external program, but it does require
-that Emacs be configured at build time to use @samp{libxml2}. It is
-fairly quick, it highlights links, and it supports HTML color
-declarations. It renders @samp{–} and @samp{®} okay. It
-sometimes truncates text, particularly if the message tries to have
-fancy text layout. By default it does not download images; this
-behavior is controlled by the options @code{mm-html-blocked-images}
-and @code{mm-html-inhibit-images}
-@ifinfo
-(@pxref{Display Customization,,,emacs-mime}).
-@end ifinfo
-@ifnotinfo
-(see section @uref{https://www.gnus.org/manual/emacs-mime_6.html,
-Display Customization} in the @cite{The Emacs MIME Manual}).
-@end ifnotinfo
-@c -------------------------
-@cindex browser, @samp{w3m}
-@cindex @samp{w3m}
-@kindex mouse-2
-@item @samp{w3m}
-The @samp{w3m} browser requires an external program. It's quick,
-produces pretty nice output, and it highlights links. These can be
-clicked with @kbd{mouse-2} to view the content of the link in
-@samp{w3m}. The @samp{w3m} browser handles tables well and actually
-respects the table's width parameter (which can cause text to wrap if
-the author didn't anticipate that the page would be viewed in Emacs).
-It does not download images by default; this behavior is controlled by
-the option @code{mm-w3m-safe-url-regexp}
-@ifinfo
-(@pxref{Display Customization,,,emacs-mime}).
-@end ifinfo
-@ifnotinfo
-(see section @uref{https://www.gnus.org/manual/emacs-mime_6.html,
-Display Customization} in the @cite{The Emacs MIME Manual}).
-@end ifnotinfo
-@c -------------------------
-@cindex browser, @samp{w3m-standalone}
-@cindex @samp{w3m-standalone}
-@cindex browser, @samp{w3m}
-@cindex @samp{w3m}
-@item @samp{w3m-standalone}
-This browser is quick, but does not show links. It handles simple
-tables but some tables get rendered much wider than the Emacs frame.
-This browser renders @samp{–} and @samp{®} okay. It does not
-download images.
-@end table
-
-@vindex mm-text-html-renderer
-
-For a couple more sources of information about
-@code{mm-text-html-renderer},
-@ifinfo
-@xref{Display Customization,,,emacs-mime}, and the documentation for
-the Gnus command @kbd{W h} (@pxref{Article Washing,,,gnus}).
-@end ifinfo
-@ifnotinfo
-see section @uref{https://www.gnus.org/manual/emacs-mime_6.html,
-Display Customization} in the @cite{The Emacs MIME Manual} and the
-documentation for the Gnus command @kbd{W h} (see section
-@uref{https://www.gnus.org/manual/gnus_48.html#Article-Washing, Article
-Washing} in the
-@cite{The Gnus Manual}).
-@end ifnotinfo
-
-@cindex @file{.emacs}
-@cindex files, @file{.emacs}
-@findex browse-url-at-mouse
-@kindex S-mouse-2
-
-A useful key binding that you can add to @file{~/.emacs} is the
-following which displays an HTML link or textual URL in an external
-browser when clicked with @kbd{S-mouse-2}. This binding works in any
-buffer, including HTML buffers.
-
-@smalllisp
-(global-set-key [S-mouse-2] 'browse-url-at-mouse)
-@end smalllisp
-
-@node Digests
-@section Digests
-
-@cindex digests
-@findex mh-page-digest
-@findex mh-page-digest-backwards
-@kindex D BS
-@kindex D SPC
-@kindex BS
-@kindex SPC
-
-A digest is a message that contains other messages. Special MH-E
-commands let you read digests conveniently. You can use @key{SPC} and
-@key{BS} to page through the digest as if it were a normal message,
-but if you wish to skip to the next message in the digest, use
-@kbd{D @key{SPC}} (@code{mh-page-digest}). To return to a previous message,
-use @kbd{D @key{BS}} (@code{mh-page-digest-backwards}).
-
-@cindex @command{burst}
-@cindex MH commands, @command{burst}
-@cindex MH-Folder Show mode
-@cindex modes, MH-Folder Show
-@findex mh-burst-digest
-@kindex d
-@kindex D b
-@kindex t
-
-Another handy command is @kbd{D b} (@code{mh-burst-digest}). This
-command uses the MH command @command{burst}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/burdig.html, Bursting Messages} in the MH
-book.} to break out each message in the digest into its own message.
-Using this command, you can quickly delete unwanted messages, like
-this: Once the digest is split up, toggle out of MH-Folder Show mode
-with @kbd{t} (@pxref{Folders}) so that the scan lines fill the screen
-and messages aren't displayed. Then use @kbd{d} (@pxref{Reading Mail})
-to quickly delete messages that you don't want to read (based on the
-@samp{Subject:} header field). You can also burst the digest to reply
-directly to the people who posted the messages in the digest. One
-problem you may encounter is that the @samp{From:} header fields are
-preceded with a @samp{>} so that your reply can't create the
-@samp{To:} field correctly. In this case, you must correct the
-@samp{To:} field yourself. This is described later (@pxref{Editing
-Drafts}).
-
-@node Reading PGP
-@section Signed and Encrypted Messages
-
-@cindex GPG
-@cindex GnuPG
-@cindex Gnus
-@cindex OpenPGP
-@cindex PGP
-@cindex RFC 3156
-@cindex encrypted messages
-@cindex security
-@cindex signed messages
-
-You can read encrypted or signed PGP or GPG messages with
-MH-E@footnote{@cite{MIME Security with OpenPGP} is documented in
-@uref{https://www.rfc-editor.org/rfc/rfc3156.txt, RFC 3156}. However,
-MH-E can also decrypt old-style PGP messages that are not in MIME
-format.}. This section assumes that you already have a good
-understanding of GPG and have set up your keys appropriately.
-
-If someone sends you a signed message, here is what you'll see:
-
-@smallexample
-@group
-[[PGP Signed Part:Bill Wohler <wohler@@stop.mail-abuse.org>]]
-This is a signed message.
-
-[[End of PGP Signed Part]]
-@end group
-@end smallexample
-
-@cindex keychain
-@cindex key server
-@cindex signed messages
-
-If the key for the given signature is not in your keychain, you'll be
-given the opportunity to fetch the key from a key server and verify
-the key. If the message is really large, the verification process can
-take a long time. You can press @kbd{C-g} at any time to
-cancel@footnote{Unfortunately in the current version, the validation
-process doesn't display a message so it appears that MH-E has hung. We
-hope that this will be fixed in the future.}.
-
-If the signature doesn't check out, you might see something like this:
-
-@smallexample
-@group
-[[PGP Signed Part:Failed]]
-This is a signed message.
-This is garbage added after the signature was made.
-
-[[End of PGP Signed Part]]
-@end group
-@end smallexample
-
-@cindex decrypting messages
-
-If someone sends you an encrypted message, MH-E will ask for your
-passphrase to decrypt the message. You should see something like this:
-
-@smallexample
-@group
-[[PGP Encrypted Part:OK]]
-
-[[PGP Signed Part:Bill Wohler <wohler@@stop.mail-abuse.org>]]
-This is the secret message.
-
-[[End of PGP Signed Part]]
-
-[[End of PGP Encrypted Part]]
-@end group
-@end smallexample
-
-If there is a problem decrypting the message, the button will say:
-
-@smallexample
-[[PGP Encrypted Part:Failed]]
-@end smallexample
-
-You can read the contents of this button using the methods described in
-@ref{Viewing Attachments}. If the message were corrupted, you'd see
-this:
-
-@smallexample
-[[PGP Encrypted Part:Failed]
-Invalid base64 data]
-@end smallexample
-
-If your passphrase were incorrect, you'd see something like this:
-
-@smallexample
-[GNUPG:] ENC_TO CD9C88BB610BD9AD 1 0
-[GNUPG:] USERID_HINT CD9C88BB610BD9AD Bill Wohler <wohler@@stop.mail-abuse.org>
-[GNUPG:] NEED_PASSPHRASE CD9C88BB610BD9AD CD9C88BB610BD9AD 1 0
-[GNUPG:] BAD_PASSPHRASE CD9C88BB610BD9AD
-gpg: encrypted with 1024-bit RSA key, ID 610BD9AD, created 1997-09-09
- "Bill Wohler <wohler@@stop.mail-abuse.org>"
-gpg: public key decryption failed: bad passphrase
-[GNUPG:] BEGIN_DECRYPTION
-[GNUPG:] DECRYPTION_FAILED
-gpg: decryption failed: secret key not available
-[GNUPG:] END_DECRYPTION
-
-gpg exited abnormally: '2'
-@end smallexample
-
-@vindex mh-show-pgg-bad
-@vindex mh-show-pgg-good
-@vindex mh-show-pgg-unknown
-
-The appearance of the buttons is controlled by the faces
-@code{mh-show-pgg-good}, @code{mh-show-pgg-bad}, and
-@code{mh-show-pgg-unknown} depending on the validity of the signature.
-The latter is used whether the signature is unknown or untrusted.
-
-@node Printing
-@section Printing Your Mail
-
-@cindex printing
-@findex mh-ps-print-msg
-@findex mh-ps-print-msg-file
-@kindex P f
-@kindex P p
-@vindex mh-lpr-command-format
-@vindex mh-print-background-flag
-
-To print messages in MH-E, use the command @kbd{P p}
-(@code{mh-ps-print-msg}). You can print all the messages in a range
-(as in @kbd{C-u P p 1 3 5-7 last:5 frombob @key{RET}},
-@pxref{Ranges}). You can also send the output to a file with @kbd{P f}
-(@code{mh-ps-print-msg-file}). This command will print inline text
-attachments but will not decrypt messages. However, when a message is
-displayed in an MH-Show buffer, then that buffer is used verbatim for
-printing with the caveat that only text attachments, if opened inline,
-are printed. Therefore, encrypted messages can be printed by showing
-and decrypting them first. The commands @kbd{P p} and @kbd{P f} do not
-use the options @code{mh-lpr-command-format} or
-@code{mh-print-background-flag}, described below.
-
-@findex mh-ps-print-toggle-color
-@kindex P C
-@vindex ps-print-color-p
-
-Colors are emulated on black-and-white printers with shades of gray.
-This might produce illegible output, even if your screen colors only
-use shades of gray. If this is the case, try using the command @kbd{P
-C} (@code{mh-ps-print-toggle-color}) to toggle between color, no
-color, and a black and white representation of the colors and see
-which works best. You change this setting permanently by customizing
-the option @code{ps-print-color-p}.
-
-@findex mh-ps-print-toggle-faces
-@kindex P F
-
-Another related function is the command @kbd{P F}
-(@code{mh-ps-print-toggle-faces}). This command toggles between using
-faces and not. When faces are enabled, the printed message will look
-very similar to the message in the MH-Show buffer.
-
-@cindex @samp{ps-print} package
-@cindex Emacs, packages, @samp{ps-print}
-
-MH-E uses the @samp{ps-print} package to do the printing, so you can
-customize the printing further by going to the @samp{ps-print}
-customization group.
-
-@cindex @command{lpr}
-@cindex @command{mhl}
-@cindex MH commands, @command{mhl}
-@cindex Unix commands, @command{lpr}
-@findex mh-print-msg
-@kindex P l
-
-An alternative to using the @samp{ps-print} package is the command
-@kbd{P l} (@code{mh-print-msg}) (the @i{l} is for @i{l}ine printer or
-@i{l}pr). You can print all the messages in a range. The message is
-formatted with @command{mhl}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/shomes.html#Usisho, Using mhl} in the MH
-book.} and printed with the @command{lpr} command.
-
-@kindex P f
-@kindex P l
-@kindex P p
-@vindex mh-lpr-command-format
-@vindex mh-print-background-flag
-
-The command @kbd{P l} uses two options. The option
-@code{mh-lpr-command-format} contains the Unix command line which
-performs the actual printing. The string can contain one escape,
-@samp{%s}, which is replaced by the name of the folder and the message
-number and is useful for print job names. The default setting is
-@code{"lpr -J '%s'"}. I use @code{"mpage -h'%s' -b Letter -H1of -mlrtb
--P"} which produces a nice header and adds a bit of margin so the text
-fits within my printer's margins. Normally messages are printed in the
-foreground. If this is slow on your system, you may elect to turn on
-the option @code{mh-print-background-flag} to print in the background.
-If you do this, do not delete the message until it is printed or else
-the output may be truncated. These options are not used by the
-commands @kbd{P p} or @kbd{P f}.
-
-@node Files and Pipes
-@section Files and Pipes
-
-@cindex files
-@cindex pipes
-@findex mh-refile-or-write-again
-@findex mh-write-msg-to-file
-@kindex >
-@kindex !
-
-MH-E does offer a couple of commands that are not a part of MH@. The
-first one, @kbd{>} (@code{mh-write-msg-to-file}), writes a message to
-a file. You are prompted for the filename. If the file already exists,
-the message is appended to it. You can also write the message to the
-file without the header by specifying a prefix argument (such as
-@kbd{C-u > /tmp/foobar @key{RET}}). Subsequent writes to the same file
-can be made with the command @kbd{!}
-(@code{mh-refile-or-write-again}).
-
-@findex mh-pipe-msg
-@kindex |
-@kindex l
-
-You can also pipe the message through a Unix shell command with the
-command @kbd{|} (@code{mh-pipe-msg}). You are prompted for the Unix
-command through which you wish to run your message. If you give a
-prefix argument to this command, the message header is included in the
-text passed to the command (the contrived example @kbd{C-u | lpr}
-would be done with the @kbd{l} command instead).
-
-@cindex @command{shar}
-@cindex @command{uuencode}
-@cindex Unix commands, @command{shar}
-@cindex Unix commands, @command{uuencode}
-@findex mh-store-msg
-@kindex X s
-@vindex mh-store-default-directory
-
-If the message is a shell archive @command{shar} or has been run
-through @command{uuencode} use @kbd{X s} (@code{mh-store-msg}) to
-extract the body of the message. The default directory for extraction
-is the current directory; however, you have a chance to specify a
-different extraction directory. The next time you use this command,
-the default directory is the last directory you used. If you would
-like to change the initial default directory, customize the option
-@code{mh-store-default-directory}, change the value from
-@samp{Current} to @samp{Directory}, and then enter the name of the
-directory for storing the content of these messages.
-
-@findex mh-store-buffer
-@kindex RET
-@kindex X s
-
-By the way, @kbd{X s} calls the Emacs Lisp function
-@code{mh-store-buffer}. I mention this because you can use it directly
-if you're editing a buffer that contains a file that has been run
-through @command{uuencode} or @command{shar}. For example, you can
-extract the contents of the current buffer in your home directory by
-typing @kbd{M-x mh-store-buffer @key{RET} ~ @key{RET}}.
-
-@node Navigating
-@section Navigating
-
-@cindex moving between messages
-@cindex navigation
-@findex mh-first-msg
-@findex mh-goto-msg
-@findex mh-last-msg
-@findex mh-next-undeleted-msg
-@findex mh-next-unread-msg
-@findex mh-previous-undeleted-msg
-@findex mh-previous-unread-msg
-@kindex g
-@kindex M-<
-@kindex M->
-@kindex M-n
-@kindex M-p
-@kindex n
-@kindex p
-
-To move on to the next message, use the command @kbd{n}
-(@code{mh-next-undeleted-msg}); use @kbd{p}
-(@code{mh-previous-undeleted-msg}) to read the previous message. To
-move to the next unread message, use @kbd{M-n}
-(@code{mh-next-unread-msg}); use @kbd{M-p}
-(@code{mh-previous-unread-msg}) to move to the previous unread
-message. These commands can be given a prefix argument to specify how
-many messages to skip (for example, @kbd{5 n}). You can also move to a
-specific message with @kbd{g} (@code{mh-goto-msg}). You can enter the
-message number either before or after typing @kbd{g}. In the latter
-case, Emacs prompts you. Finally, you can go to the first or last
-message with @kbd{M-<} (@code{mh-first-msg}) and @kbd{M->}
-(@code{mh-last-msg}) respectively.
-
-@cindex MH-Folder mode
-@cindex modes, MH-Folder
-@findex next-line
-@findex previous-line
-@kindex C-n
-@kindex C-p
-@kindex RET
-
-You can also use the Emacs commands @kbd{C-p} (@code{previous-line})
-and @kbd{C-n} (@code{next-line}) to move up and down the scan lines in
-the MH-Folder window. These commands can be used in conjunction with
-@key{RET} to look at deleted or refiled messages.
-
-@cindex deleting messages
-@findex mh-delete-msg
-@kindex d
-@kindex n
-@kindex p
-
-To mark a message for deletion, use the command @kbd{d}
-(@code{mh-delete-msg}). A @samp{D} is placed by the message in the
-scan window, and the next undeleted message is displayed. If the
-previous command had been @kbd{p}, then the next message displayed is
-the first undeleted message previous to the message just deleted. Use
-@kbd{n} to force subsequent @kbd{d} commands to move forward to the
-next undeleted message after deleting the message under the cursor.
-You may also specify a range (for example, @kbd{C-u d 1 3 5-7 last:5
-frombob @key{RET}}, @pxref{Ranges}).
-
-@findex mh-delete-msg-no-motion
-@kindex C-d
-
-The command @kbd{C-d} (@code{mh-delete-msg-no-motion}) marks the
-message (or messages in range) for deletion but leaves the cursor at
-the current message in case you wish to perform other operations on
-the message.
-
-@findex mh-delete-subject
-@findex mh-delete-subject-or-thread
-@findex mh-thread-delete
-@findex mh-undo
-@kindex k
-@kindex T d
-@kindex u
-
-And to delete more messages faster, you can use @kbd{k}
-(@code{mh-delete-subject-or-thread}) to delete all the messages with
-the same subject as the current message. This command puts these
-messages in a sequence named @samp{subject}. You can undo this action
-by using @kbd{u} (@code{mh-undo}) with a prefix argument and then
-specifying the @samp{subject} sequence. However, if the buffer is
-displaying a threaded view of the folder then @kbd{k} behaves like
-@kbd{T d} (@code{mh-thread-delete}). @xref{Threading}.
-
-@findex mh-execute-commands
-@kindex x
-
-However you mark a message for deletion, the command @kbd{x}
-(@code{mh-execute-commands}) actually carries out the deletion
-(@pxref{Folders}).
-
-@vindex mh-delete-msg-hook
-
-The hook @code{mh-delete-msg-hook} is called after you mark a message
-for deletion. For example, a past maintainer of MH-E used this once
-when he kept statistics on his mail usage.
-
-@node Miscellaneous Commands and Options
-@section Miscellaneous Commands and Options
-
-This section contains a few more miscellaneous commands and options.
-
-@cindex editing message
-@findex mh-modify
-@kindex M
-
-There are times when you need to edit a message. For example, you may
-need to fix a broken Content-Type header field. You can do this with
-the command @kbd{M} (@code{mh-modify}). It displays the raw message in
-an editable buffer. When you are done editing, save and kill the
-buffer as you would any other.
-
-@findex mh-kill-folder
-@findex mh-pack-folder
-@vindex mh-do-not-confirm-flag
-
-Commands such as @code{mh-pack-folder} prompt to confirm whether to
-process outstanding moves and deletes or not before continuing.
-Turning on the option @code{mh-do-not-confirm-flag} means that these
-actions will be performed---which is usually desired but cannot be
-retracted---without question@footnote{In previous versions of MH-E,
-this option suppressed the confirmation in @code{mh-kill-folder}.
-Since this kept most users from setting this option,
-@code{mh-kill-folder} was modified in version 6.0 to always ask for
-confirmation subject to @code{mh-kill-folder-suppress-prompt-functions}.
-@xref{Folders}.}.
-
-@cindex MH-Folder mode
-@cindex modes, MH-Folder
-@vindex mh-summary-height
-
-The option @code{mh-summary-height} controls the number of scan lines
-displayed in the MH-Folder window, including the mode line. The
-default value of this option is @samp{Automatic} which means that the
-MH-Folder buffer will maintain the same proportional size if the frame
-is resized. If you'd prefer a fixed height, then choose the
-@samp{Fixed Size} option and enter the number of lines you'd like to
-see.
-
-@vindex mh-bury-show-buffer-flag
-
-Normally the buffer for displaying messages is buried at the bottom at
-the buffer stack. You may wish to disable this feature by turning off
-the option @code{mh-bury-show-buffer-flag}. One advantage of not
-burying the show buffer is that one can delete the show buffer more
-easily in an electric buffer list because of its proximity to its
-associated MH-Folder buffer. Try running @kbd{M-x
-electric-buffer-list} to see what I mean.
-
-@cindex @file{.emacs}
-@cindex files, @file{.emacs}
-@cindex reading mail
-
-Before we leave this section, I'll include a function that I use as a
-front end to MH-E@footnote{Stephen Gildea's favorite binding is
-@kbd{(global-set-key "\C-cr" 'mh-rmail)}.}. It toggles between your
-working window configuration, which may be quite involved---windows
-filled with source, compilation output, man pages, and other
-documentation---and your MH-E window configuration. Like the rest of
-the customization described in this section, simply add the following
-code to @file{~/.emacs}.
-
-@iftex
-@filbreak
-@end iftex
-
-@findex mh-rmail@r{, example}
-
-@smalllisp
-@group
-(defvar my-mh-screen-saved nil
- "Set to non-nil when MH-E window configuration shown.")
-(defvar my-normal-screen nil "Normal window configuration.")
-(defvar my-mh-screen nil "MH-E window configuration.")
-
-(defun my-mh-rmail (&optional arg)
- "Toggle between MH-E and normal screen configurations.
-With non-nil or prefix argument, include mailbox as well
-when going into mail."
- (interactive "P") ; @r{user callable function, P=prefix arg}
- (setq my-mh-screen-saved ; @r{save state}
- (cond
- ;; @r{Bring up MH-E screen if arg or normal window configuration.}
- ;; @r{If arg or +inbox buffer doesn't exist, run mh-rmail.}
- ((or arg (null my-mh-screen-saved))
- (setq my-normal-screen (current-window-configuration))
- (if (or arg (null (get-buffer "+inbox")))
- (mh-rmail)
- (set-window-configuration my-mh-screen))
- t) ; @r{set my-mh-screen-saved to @code{t}}
- ;; @r{Otherwise, save MH-E screen and restore normal screen.}
- (t
- (setq my-mh-screen (current-window-configuration))
- (set-window-configuration my-normal-screen)
- nil)))) ; @r{set my-mh-screen-saved to nil}
-
-(global-set-key "\C-x\r" 'my-mh-rmail) ;@r{ call with C-x @key{RET}}
-
-@i{Starting MH-E}
-
-@end group
-@end smalllisp
-
-If you type an argument (@kbd{C-u}) or if @code{my-mh-screen-saved} is
-@code{nil} (meaning a non-MH-E window configuration), the current
-window configuration is saved, either the @samp{+inbox} buffer is
-displayed or @code{mh-rmail} is run, and the MH-E window configuration
-is shown. Otherwise, the MH-E window configuration is saved and the
-original configuration is displayed.
-
-@node Folders
-@chapter Organizing Your Mail with Folders
-
-@cindex @samp{Folder} menu
-@cindex @samp{Message} menu
-@cindex folders
-@cindex menu, @samp{Folder}
-@cindex menu, @samp{Message}
-@cindex using folders
-
-This chapter discusses the things you can do with folders within MH-E@.
-The commands in this chapter are also found in the @samp{Folder} and
-@samp{Message} menus.
-
-@table @kbd
-@kindex ?
-@findex mh-help
-@item ?
-Display cheat sheet for the MH-E commands (@code{mh-help}).
-@c -------------------------
-@kindex !
-@findex mh-refile-or-write-again
-@item !
-Repeat last output command (@code{mh-refile-or-write-again}).
-@c -------------------------
-@cindex @samp{Message > Copy Message to Folder...} menu item
-@cindex menu item, @samp{Message > Copy Message to Folder...}
-@kindex c
-@findex mh-copy-msg
-@item c
-Copy range to folder (@code{mh-copy-msg}).
-@c -------------------------
-@kindex F ?
-@findex mh-prefix-help
-@item F ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@kindex F '
-@findex mh-index-ticked-messages
-@item F '
-Display ticked messages (@code{mh-index-ticked-messages}).
-@c -------------------------
-@kindex F c
-@findex mh-catchup
-@item F c
-Delete range from the @samp{unseen} sequence (@code{mh-catchup}).
-@c -------------------------
-@kindex F k
-@findex mh-kill-folder
-@item F k
-Remove folder (@code{mh-kill-folder}).
-@c -------------------------
-@cindex @samp{Folder > List Folders} menu item
-@cindex menu item, @samp{Folder > List Folders}
-@kindex F l
-@findex mh-list-folders
-@item F l
-List all folders (@code{mh-list-folders}).
-@c -------------------------
-@cindex @samp{Folder > View New Messages} menu item
-@cindex menu item, @samp{Folder > View New Messages}
-@kindex F n
-@findex mh-index-new-messages
-@item F n
-Display unseen messages (@code{mh-index-new-messages}).
-@c -------------------------
-@cindex @samp{Folder > Pack Folder} menu item
-@cindex menu item, @samp{Folder > Pack Folder}
-@kindex F p
-@findex mh-pack-folder
-@item F p
-Pack folder (@code{mh-pack-folder}).
-@c -------------------------
-@kindex F q
-@findex mh-index-sequenced-messages
-@item F q
-Display messages in any sequence (@code{mh-index-sequenced-messages}).
-@c -------------------------
-@cindex @samp{Folder > Rescan Folder} menu item
-@cindex menu item, @samp{Folder > Rescan Folder}
-@kindex F r
-@findex mh-rescan-folder
-@item F r
-Rescan folder (@code{mh-rescan-folder}).
-@c -------------------------
-@cindex @samp{Folder > Search...} menu item
-@cindex menu item, @samp{Folder > Search...}
-@kindex F s
-@findex mh-search
-@item F s
-Search your MH mail (@code{mh-search}).
-@c -------------------------
-@cindex @samp{Folder > Sort Folder} menu item
-@cindex menu item, @samp{Folder > Sort Folder}
-@kindex F S
-@findex mh-sort-folder
-@item F S
-Sort folder (@code{mh-sort-folder}).
-@c -------------------------
-@kindex F u
-@findex mh-undo-folder
-@item F u
-Undo all refiles and deletes in the current folder (@code{mh-undo-folder}).
-@c -------------------------
-@cindex @samp{Folder > Visit a Folder...} menu item
-@cindex menu item, @samp{Folder > Visit a Folder...}
-@kindex F v
-@findex mh-visit-folder
-@item F v
-Visit folder (@code{mh-visit-folder}).
-@c -------------------------
-@cindex @samp{Message > Refile Message} menu item
-@cindex menu item, @samp{Message > Refile Message}
-@kindex o
-@findex mh-refile-msg
-@item o
-Refile (output) range into folder (@code{mh-refile-msg}).
-@c -------------------------
-@cindex @samp{Folder > Quit MH-E} menu item
-@cindex menu item, @samp{Folder > Quit MH-E}
-@kindex q
-@findex mh-quit
-@item q
-Quit the current MH-E folder (@code{mh-quit}).
-@c -------------------------
-@cindex @samp{Folder > Toggle Show/Folder} menu item
-@cindex menu item, @samp{Folder > Toggle Show/Folder}
-@kindex t
-@findex mh-toggle-showing
-@item t
-Toggle between MH-Folder and MH-Folder Show modes
-(@code{mh-toggle-showing}).
-@c -------------------------
-@cindex @samp{Message > Undo Delete/Refile} menu item
-@cindex menu item, @samp{Message > Undo Delete/Refile}
-@kindex u
-@findex mh-undo
-@item u
-Undo pending deletes or refiles in range (@code{mh-undo}).
-@c -------------------------
-@cindex @samp{Message > Execute Delete/Refile} menu item
-@cindex menu item, @samp{Message > Execute Delete/Refile}
-@kindex x
-@findex mh-execute-commands
-@item x
-Process outstanding delete and refile requests
-(@code{mh-execute-commands}).
-@end table
-
-@cindex @samp{mh-folder} customization group
-@cindex customization group, @samp{mh-folder}
-
-The @samp{mh-folder} customization group is used to tune these
-commands.
-
-@vtable @code
-@item mh-new-messages-folders
-Folders searched for the @samp{unseen} sequence (default:
-@code{Inbox}).
-@c -------------------------
-@item mh-ticked-messages-folders
-Folders searched for @code{mh-tick-seq} (default: @code{t}).
-@c -------------------------
-@item mh-large-folder
-The number of messages that indicates a large folder (default: 200).
-@c -------------------------
-@item mh-recenter-summary-flag
-On means to recenter the summary window (default: @samp{off}).
-@c -------------------------
-@item mh-recursive-folders-flag
-On means that commands which operate on folders do so recursively
-(default: @samp{off}).
-@c -------------------------
-@item mh-sortm-args
-Additional arguments for @command{sortm} (default: @code{nil}).
-@end vtable
-
-The following hooks are available.
-
-@vtable @code
-@item mh-after-commands-processed-hook
-Hook run by @kbd{x} after performing outstanding refile and delete
-requests (default: @code{nil}).
-@c -------------------------
-@item mh-before-commands-processed-hook
-Hook run by @kbd{x} before performing outstanding refile and delete
-requests (default: @code{nil}).
-@c -------------------------
-@item mh-before-quit-hook
-Hook run by q before quitting MH-E (default: @code{nil}).
-@c -------------------------
-@item mh-folder-mode-hook
-Hook run by @code{mh-folder-mode} when visiting a new folder (default:
-@code{nil}).
-@c -------------------------
-@item mh-kill-folder-suppress-prompt-functions
-Abnormal hook run at the beginning of @code{mh-kill-folder} (default:
-@code{'mh-search-p}).
-@c -------------------------
-@item mh-pack-folder-hook
-Hook run by @code{mh-pack-folder} after renumbering the messages
-(default: @code{nil}).
-@c -------------------------
-@item mh-quit-hook
-Hook run by q after quitting MH-E (default: @code{nil}).
-@c -------------------------
-@item mh-refile-msg-hook
-Hook run by o after marking each message for refiling (default:
-@code{nil}).
-@end vtable
-
-The following faces are available for customizing the appearance of
-the MH-Folder buffer. @xref{Scan Line Formats}.
-
-@vtable @code
-@item mh-folder-address
-Recipient face.
-@c -------------------------
-@item mh-folder-body
-Body text face.
-@c -------------------------
-@item mh-folder-cur-msg-number
-Current message number face.
-@c -------------------------
-@item mh-folder-date
-Date face.
-@c -------------------------
-@item mh-folder-deleted
-Deleted message face.
-@c -------------------------
-@item mh-folder-followup
-@samp{Re:} face.
-@c -------------------------
-@item mh-folder-msg-number
-Message number face.
-@c -------------------------
-@item mh-folder-refiled
-Refiled message face.
-@c -------------------------
-@vindex mh-scan-format-nmh
-@vindex mh-scan-sent-to-me-sender-regexp
-@item mh-folder-sent-to-me-hint
-Fontification hint face in messages sent directly to us. The detection
-of messages sent to us is governed by the scan format
-@code{mh-scan-format-nmh} and regular expression
-@code{mh-scan-sent-to-me-sender-regexp}.
-@c -------------------------
-@vindex mh-scan-format-nmh
-@vindex mh-scan-sent-to-me-sender-regexp
-@item mh-folder-scan-format
-Sender face in messages sent directly to us. The detection of messages
-sent to us is governed by the scan format @code{mh-scan-format-nmh}
-and regular expression @code{mh-scan-sent-to-me-sender-regexp}.
-@c -------------------------
-@item mh-folder-subject
-Subject face.
-@c -------------------------
-@item mh-folder-tick
-Ticked message face.
-@c -------------------------
-@item mh-folder-to
-@samp{To:} face.
-@end vtable
-
-@vindex mh-folder-mode-hook
-
-The hook @code{mh-folder-mode-hook} is called when visiting a new
-folder in MH-Folder mode. This could be used to set your own key
-bindings, for example:
-
-@vindex mh-folder-mode-hook@r{, example}
-
-@smalllisp
-@group
-(defvar my-mh-init-done nil
- "Non-nil when one-time MH-E settings made.")
-
-(defun my-mh-folder-mode-hook ()
- "Hook to set key bindings in MH-Folder mode."
- (if (not my-mh-init-done) ; @r{only need to bind the keys once }
- (progn
- (local-set-key "//" 'my-search-msg)
- (local-set-key "b" 'mh-burst-digest) ; @r{better use of @kbd{b}}
- (setq my-mh-init-done t))))
-
-(add-hook 'mh-folder-mode-hook 'my-mh-folder-mode-hook)
-
-(defun my-search-msg ()
- "Search for a regexp in the current message."
- (interactive) ; @r{user function}
- (save-window-excursion
- (other-window 1) ; @r{go to next window}
- (isearch-forward-regexp))) ; @r{string search; hit return}
- ; @r{ when done}
-
-@i{Create additional key bindings via mh-folder-mode-hook}
-
-@end group
-@end smalllisp
-
-@cindex @command{folder}
-@cindex @command{refile}
-@cindex MH commands, @command{folder}
-@cindex MH commands, @command{refile}
-@findex mh-refile-msg
-@kindex o
-@vindex mh-refile-msg-hook
-
-MH-E has analogies for each of the MH @command{folder} and
-@command{refile} commands@footnote{See the sections
-@uref{@value{MH-BOOK-HOME}/fol.html#Youfol, Your Current Folder:
-folder} and @uref{@value{MH-BOOK-HOME}/fol.html#Movref, Moving and
-Linking Messages: refile} in the MH book.}. To refile a message in
-another folder, use the command @kbd{o} (@code{mh-refile-msg})
-(mnemonic: ``output''). You are prompted for the folder name
-(@pxref{Folder Selection}). Note that this command can also be used to
-create folders. If you specify a folder that does not exist, you will
-be prompted to create it. The hook @code{mh-refile-msg-hook} is called
-after a message is marked to be refiled.
-
-@findex mh-write-msg-to-file
-@kindex !
-
-If you are refiling several messages into the same folder, you can use
-the command @kbd{!} (@code{mh-refile-or-write-again}) to repeat the
-last refile or write (for the description of @kbd{>}
-(@code{mh-write-msg-to-file}), @pxref{Files and Pipes}). You can use a
-range in either case (for example, @kbd{C-u o 1 3 5-7 last:5 frombob
-@key{RET}}, @pxref{Ranges}).
-
-@cindex expunging refiles and deletes
-@cindex undoing refiles and deletes
-@findex mh-undo
-@kindex u
-
-If you've deleted a message or refiled it, but changed your mind, you
-can cancel the action before you've executed it. Use @kbd{u}
-(@code{mh-undo}) to undo a refile on or deletion of a single message.
-You can also undo refiles and deletes for messages that are found in a
-given range (@pxref{Ranges}).
-
-@findex mh-undo-folder
-@kindex F u
-
-Alternatively, you can use @kbd{F u} (@code{mh-undo-folder}) to undo
-all refiles and deletes in the current folder.
-
-@findex mh-execute-commands
-@kindex x
-
-If you've marked messages to be deleted or refiled and you want to go
-ahead and delete or refile the messages, use @kbd{x}
-(@code{mh-execute-commands}). Many MH-E commands that may affect the
-numbering of the messages (such as @kbd{F r} or @kbd{F p}) will ask if
-you want to process refiles or deletes first and then either run
-@kbd{x} for you or undo the pending refiles and deletes.
-
-@kindex x
-@vindex mh-after-commands-processed-hook
-@vindex mh-before-commands-processed-hook
-@vindex mh-current-folder
-
-The command @kbd{x} runs @code{mh-before-commands-processed-hook}
-before the commands are processed and
-@code{mh-after-commands-processed-hook} after the commands are
-processed. Variables that are useful with the former hook include
-@code{mh-delete-list} and @code{mh-refile-list} which can be used to
-see which changes will be made to the current folder,
-@code{mh-current-folder}. Variables that are useful with the latter
-hook include @code{mh-folders-changed}, which lists which folders were
-affected by deletes and refiles. This list will always include the
-current folder @code{mh-current-folder}.
-
-@findex mh-copy-msg
-@kindex c
-@kindex o
-
-If you wish to copy a message to another folder, you can use the
-command @kbd{c} (@code{mh-copy-msg}) (see the @option{-link} argument
-to @command{refile}(1)). Like the command @kbd{o}, this command
-prompts you for the name of the target folder and you can specify a
-range (@pxref{Ranges}). Note that unlike the command @kbd{o}, the copy
-takes place immediately. The original copy remains in the current
-folder.
-
-@cindex junk mail
-@cindex MH-Folder mode
-@cindex MH-Folder Show mode
-@cindex modes, MH-Folder
-@cindex modes, MH-Folder Show
-@cindex spam
-@findex mh-toggle-showing
-@kindex t
-
-The command @kbd{t} (@code{mh-toggle-showing}) switches between
-MH-Folder mode and MH-Folder Show mode@footnote{For you Emacs wizards,
-this is implemented as an Emacs minor mode.}. MH-Folder mode turns off
-the associated show buffer so that you can perform operations on the
-messages quickly without reading them. This is an excellent way to
-prune out your junk mail or to refile a group of messages to another
-folder for later examination.
-
-@cindex MH-Folder mode
-@cindex MH-Show mode
-@cindex modes, MH-Folder
-@cindex modes, MH-Show
-@cindex moving between messages
-@kindex t
-@vindex mh-recenter-summary-flag
-
-When you use @kbd{t} to toggle from MH-Folder Show mode to MH-Folder
-mode, the MH-Show buffer is hidden and the MH-Folder buffer is left
-alone. Setting @code{mh-recenter-summary-flag} to a non-@code{nil}
-value causes the toggle to display as many scan lines as possible,
-with the cursor at the middle. The effect of
-@code{mh-recenter-summary-flag} is rather useful, but it can be
-annoying on a slow network connection.
-
-@findex mh-visit-folder
-@kindex F v
-@vindex mh-large-folder
-
-When you want to read the messages that you have refiled into folders,
-use the command @kbd{F v} (@code{mh-visit-folder}) to visit the
-folder. You are prompted for the folder name. The folder buffer will
-show just unseen messages if there are any; otherwise, it will show
-all the messages in the buffer as long there are fewer than
-@code{mh-large-folder} messages. If there are more, then you are
-prompted for a range of messages to scan. You can provide a prefix
-argument in order to specify a range of messages to show when you
-visit the folder (@pxref{Ranges}). In this case, regions are not used
-to specify the range and @code{mh-large-folder} is ignored. Note that
-this command can also be used to create folders. If you specify a
-folder that does not exist, you will be prompted to create it.
-
-@findex mh-search
-@kindex F s
-
-If you forget where you've refiled your messages, you can find them
-using @kbd{F s} (@code{mh-search}). @xref{Searching}.
-
-@cindex @command{procmail}
-@cindex @samp{unseen} sequence
-@cindex sequence, @samp{unseen}
-@cindex Unix commands, @command{procmail}
-@cindex unseen messages, viewing
-@findex mh-index-new-messages
-@kindex F n
-@vindex mh-new-messages-folders
-
-If you use a program such as @command{procmail} to file your incoming
-mail automatically, you can display new, unseen, messages using the
-command @kbd{F n} (@code{mh-index-new-messages}). All messages in the
-@samp{unseen} sequence from the folders in
-@code{mh-new-messages-folders} are listed. However, this list of
-folders can be overridden with a prefix argument: with a prefix
-argument, enter a space-separated list of folders, or nothing to
-search all folders.
-
-@cindex @samp{tick} sequence
-@cindex sequence, @samp{tick}
-@cindex ticked messages, viewing
-@findex mh-index-ticked-messages
-@kindex F '
-@vindex mh-ticked-messages-folders
-
-If you have ticked messages (@pxref{Sequences}), you can display them
-using the command @kbd{F '} (@code{mh-index-ticked-messages}). All
-messages in the @samp{tick} sequence from the folders in
-@code{mh-ticked-messages-folders} are listed. With a prefix argument,
-enter a space-separated list of folders, or nothing to search all
-folders.
-
-@findex mh-index-sequenced-messages
-@kindex F q
-@vindex mh-new-messages-folders
-
-You can display messages in any sequence with the command @kbd{F q}
-(@code{mh-index-sequenced-messages}). All messages from the folders in
-@code{mh-new-messages-folders} in the sequence you provide are listed.
-With a prefix argument, enter a space-separated list of folders at the
-prompt, or nothing to search all folders.
-
-@vindex mh-new-messages-folders
-@vindex mh-recursive-folders-flag
-@vindex mh-ticked-messages-folders
-
-Set the options @code{mh-new-messages-folders} and
-@code{mh-ticked-messages-folders} to @samp{Inbox} to search the
-@samp{+inbox} folder or @samp{All} to search all of the top level
-folders. Otherwise, list the folders that should be searched with the
-@samp{Choose Folders} menu item. See @code{mh-recursive-folders-flag}.
-
-@cindex buffers, @file{*MH-E Folders*}
-@cindex @file{*MH-E Folders*}
-@findex mh-kill-folder
-@findex mh-list-folders
-@findex mh-pack-folder
-@findex mh-rescan-folder
-@findex mh-sort-folder
-@kindex F k
-@kindex F l
-@kindex F p
-@kindex F r
-@kindex F S
-
-Other commands you can perform on folders include: @kbd{F l}
-(@code{mh-list-folders}), to place a listing of all the folders in
-your mail directory in a buffer called @file{*MH-E Folders*}
-(@pxref{Miscellaneous}); @kbd{F k} (@code{mh-kill-folder}), to remove
-a folder; @kbd{F S} (@code{mh-sort-folder}), to sort the messages by
-date (see @command{sortm}(1) to see how to sort by other criteria);
-@kbd{F p} (@code{mh-pack-folder}), to pack a folder, removing gaps
-from the numbering sequence; and @kbd{F r} (@code{mh-rescan-folder}),
-to rescan the folder, which is useful to grab all messages in your
-@samp{+inbox} after processing your new mail for the first time. If
-you don't want to rescan the entire folder, the commands @kbd{F r} or
-@kbd{F p} will accept a range (@pxref{Ranges}).
-
-@kindex F p
-@vindex mh-pack-folder-hook
-
-The command @kbd{F p} runs @code{mh-pack-folder-hook} after
-renumbering the messages. A variable that is useful with this hook
-is @code{mh-current-folder}.
-
-@kindex TAB
-@vindex mh-recursive-folders-flag
-
-By default, operations on folders work only one level at a time. Set
-@code{mh-recursive-folders-flag} to non-@code{nil} to operate on all
-folders. This mostly means that you'll be able to see all your folders
-when you press @key{TAB} when prompted for a folder name.
-
-@findex mh-search-p
-@kindex k
-@vindex mh-kill-folder-suppress-prompt-functions
-
-The hook @code{mh-kill-folder-suppress-prompt-functions} is an abnormal
-hook run at the beginning of the command @kbd{k}. The hook functions
-are called with no arguments and should return a non-@code{nil} value to
-suppress the normal prompt when you remove a folder. This is useful
-for folders that are easily regenerated. The default value of
-@code{mh-search-p} suppresses the prompt on folders generated by
-searching.
-
-@sp 1
-@center @strong{NOTE}
-
-@quotation
-Use this hook with care. If there is a bug in your hook which returns
-@code{t} on @samp{+inbox} and you press @kbd{k} by accident in the
-@code{+inbox} folder, you will not be happy.
-@end quotation
-@sp 1
-
-@cindex @command{sortm}
-@cindex @file{.mh_profile}
-@cindex files, @file{.mh_profile}
-@cindex MH commands, @command{sortm}
-@cindex MH profile component, @samp{sortm}
-@cindex @samp{sortm} MH profile component
-@kindex F S
-@vindex mh-sortm-args
-
-The option @code{mh-sortm-args} holds extra arguments to pass on to
-the command @command{sortm}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/sorsor.html, Sorting Messages: sortm} in the
-MH book.} when a prefix argument is used with @kbd{F S}. Normally
-default arguments to @command{sortm} are specified in the MH profile.
-This option may be used to provide an alternate view. For example,
-@samp{'(\"-nolimit\" \"-textfield\" \"subject\")} is a useful setting.
-
-@cindex exiting
-@cindex quitting
-@findex mh-quit
-@kindex q
-
-When you want to quit using MH-E and go back to editing, you can use
-the @kbd{q} (@code{mh-quit}) command. This buries the buffers of the
-current MH-E folder and restores the buffers that were present when
-you first ran @kbd{M-x mh-rmail}. It also removes any MH-E working
-buffers whose name begins with @samp{ *mh-} or @file{*MH-E }
-(@pxref{Miscellaneous}). You can later restore your MH-E session by
-selecting the @samp{+inbox} buffer or by running @kbd{M-x mh-rmail}
-again.
-
-@findex mh-execute-commands
-@kindex q
-@vindex mh-before-quit-hook
-@vindex mh-before-quit-hook@r{, example}
-@vindex mh-quit-hook
-@vindex mh-quit-hook@r{, example}
-
-The two hooks @code{mh-before-quit-hook} and @code{mh-quit-hook} are
-called by @kbd{q}. The former one is called before the quit occurs, so
-you might use it to perform any MH-E operations; you could perform
-some query and abort the quit or call @code{mh-execute-commands}, for
-example. The latter is not run in an MH-E context, so you might use it
-to modify the window setup. If you find that @kbd{q} buries a lot of
-buffers that you would rather remove, you can use both
-@code{mh-before-quit-hook} and @code{mh-quit-hook} to accomplish that.
-
-@smalllisp
-@group
-(defvar my-mh-folder-buffer-to-delete nil
- "Folder buffer that is being quit.")
-
-(defun my-mh-before-quit-hook ()
- "Save folder buffer that is to be deleted."
- (setq my-mh-folder-buffer-to-delete (current-buffer)))
-
-(defun my-mh-quit-hook ()
- "Kill folder buffer rather than just bury it."
- (set-buffer my-mh-folder-buffer-to-delete)
- (if (get-buffer mh-show-buffer)
- (kill-buffer mh-show-buffer))
- (kill-buffer (current-buffer)))
-
-@i{Kill MH-Folder buffer instead of burying it}
-@end group
-@end smalllisp
-
-@cindex folders, renaming
-@cindex renaming folders
-@findex dired
-@findex dired-do-rename
-
-You can use dired to manipulate the folders themselves. For example, I
-renamed my @samp{+out} folder to the more common @samp{+outbox} by
-running dired on my mail directory (@kbd{M-x dired @key{RET} ~/Mail
-@key{RET}}), moving my cursor to @samp{out} and using the command
-@kbd{R} (@code{dired-do-rename}).
-
-@node Sending Mail
-@chapter Sending Mail
-
-@cindex sending mail
-@findex mh-smail
-
-You can send a mail message in several ways. You can call @kbd{M-x
-mh-smail} directly, or from the command line like this:
-
-@cindex starting from command line
-
-@smallexample
-$ @kbd{emacs -f mh-smail}
-@end smallexample
-
-@findex goto-address-at-point
-@vindex mail-user-agent
-
-There are some commands that need to send a mail message, such as
-@code{goto-address-at-point}. You can configure Emacs to have these
-commands use MH-E by setting the option @code{mail-user-agent} to
-@samp{Emacs interface to MH}.
-
-@cindex @samp{Message} menu
-@cindex menu, @samp{Message}
-
-From within MH-E's MH-Folder mode, other methods of sending mail are
-available as well. These can also be found in the @samp{Message} menu.
-
-@table @kbd
-@cindex @samp{Message > Edit Message Again} menu item
-@cindex menu item, @samp{Message > Edit Message Again}
-@kindex e
-@findex mh-edit-again
-@item e
-Edit a message to send it again (@code{mh-edit-again}).
-@c -------------------------
-@cindex @samp{Message > Re-edit a Bounced Message} menu item
-@cindex menu item, @samp{Message > Re-edit a Bounced Message}
-@kindex E
-@findex mh-extract-rejected-mail
-@item E
-Edit a message that was returned by the mail system
-(@code{mh-extract-rejected-mail}).
-@c -------------------------
-@cindex @samp{Message > Forward Message...} menu item
-@cindex menu item, @samp{Message > Forward Message...}
-@kindex f
-@findex mh-forward
-@item f
-Forward message (@code{mh-forward}).
-@c -------------------------
-@cindex @samp{Message > Reply to Message...} menu item
-@cindex menu item, @samp{Message > Reply to Message...}
-@kindex r
-@findex mh-reply
-@item r
-Reply to a message (@code{mh-reply}).
-@c -------------------------
-@cindex @samp{Message > Compose a New Message} menu item
-@cindex menu item, @samp{Message > Compose a New Message}
-@kindex s
-@findex mh-send
-@item s
-Compose a message (@code{mh-send}).
-@c -------------------------
-@cindex @samp{Message > Redistribute Message...} menu item
-@cindex menu item, @samp{Message > Redistribute Message...}
-@kindex M-d
-@findex mh-redistribute
-@item M-d
-Redistribute a message (@code{mh-redistribute}).
-@c -------------------------
-@findex mh-smail
-@item M-x mh-smail
-Compose a message with the MH mail system.
-@c -------------------------
-@findex mh-smail-other-window
-@item M-x mh-smail-other-window
-Compose a message with the MH mail system in other window.
-@end table
-
-@cindex @samp{mh-sending-mail} customization group
-@cindex customization group, @samp{mh-sending-mail}
-
-In addition, several options from the @samp{mh-sending-mail}
-customization group are useful when sending mail or replying to mail.
-They are summarized in the following table.
-
-@vtable @code
-@item mh-compose-forward-as-mime-flag
-On means that messages are forwarded as attachments (default:
-@samp{on}).
-@c -------------------------
-@item mh-compose-letter-function
-Hook run when starting a new draft (default: @code{nil}).
-@c -------------------------
-@item mh-compose-prompt-flag
-On means prompt for header fields when composing a new draft (default:
-@samp{off}).
-@c -------------------------
-@item mh-forward-subject-format
-Format string for forwarded message subject (default: @code{"%s:
-%s"}).
-@c -------------------------
-@item mh-insert-x-mailer-flag
-On means append an @samp{X-Mailer:} header field to the header
-(default: @samp{on}).
-@c -------------------------
-@item mh-redist-full-contents-flag
-On means the @command{dist} command needs entire letter for
-redistribution (default: @samp{off}).
-@c -------------------------
-@item mh-reply-default-reply-to
-Sets the person or persons to whom a reply will be sent (default:
-@samp{Prompt}).
-@c -------------------------
-@item mh-reply-show-message-flag
-On means the MH-Show buffer is displayed using @kbd{r}
-(@code{mh-reply}) (default: @samp{on}).
-@end vtable
-
-The following hooks are available.
-
-@vtable @code
-@item mh-annotate-msg-hook
-Hook run by @code{mh-annotate-msg} after annotation (default:
-@code{nil}).
-@c -------------------------
-@item mh-forward-hook
-Hook run by @code{mh-forward} on a forwarded letter (default:
-@code{nil}).
-@c -------------------------
-@item mh-letter-mode-hook
-Hook run by @code{mh-letter-mode} on a new letter (default:
-@code{nil}).
-@end vtable
-
-@findex mh-annotate-msg
-@vindex mh-annotate-list
-@vindex mh-annotate-msg-hook
-@vindex mh-current-folder
-
-A hook that is called whenever a message is sent and after the scan
-lines and message are annotated is @code{mh-annotate-msg-hook}. Hook
-functions can access the current folder name with
-@code{mh-current-folder} and obtain the message numbers of the
-annotated messages with @code{mh-annotate-list}.
-
-The rest of the functions and options introduced here are explained in
-more detail in the following sections.
-
-@menu
-* Composing::
-* Replying::
-* Forwarding::
-* Redistributing::
-* Editing Again::
-@end menu
-
-@node Composing
-@section Composing
-
-@cindex @file{.emacs}
-@cindex MH-Folder mode
-@cindex composing mail
-@cindex draft
-@cindex files, @file{.emacs}
-@cindex modes, MH-Folder
-@cindex sending mail
-@findex mh-smail
-@findex mh-smail-other-window
-
-Outside of an MH-Folder buffer, you must call either @kbd{M-x
-mh-smail} or @kbd{M-x mh-smail-other-window} to compose a new message.
-The former command always creates a two-window layout with the current
-buffer on top and the draft on the bottom. Use the latter command if
-you would rather preserve the window layout. You may find adding the
-following key bindings to @file{~/.emacs} useful:
-
-@smalllisp
-(global-set-key "\C-xm" 'mh-smail)
-(global-set-key "\C-x4m" 'mh-smail-other-window)
-@end smalllisp
-
-@cindex draft folder
-@cindex MH-Letter mode
-@cindex modes, MH-Letter
-@findex mh-send
-@kindex m
-
-From within a MH-Folder buffer, you can simply use the command @kbd{m}
-(@code{mh-send}). However you invoke @code{mh-send}, your letter
-appears in an Emacs buffer whose mode is MH-Letter (to see what the
-buffer looks like, @pxref{Sending Mail Tour}). MH-Letter mode allows
-you to edit your message, to check the validity of the recipients, to
-insert attachments and other messages into your message, and to send
-the message. We'll go more into depth about editing a
-@dfn{draft}@footnote{I highly recommend that you use a @dfn{draft
-folder} so that you can edit several drafts in parallel. To do so,
-create a folder named @samp{+drafts} for example, and add the profile
-component @samp{Draft-Folder: drafts} (see @code{mh-profile}(5)).} (a
-message you're composing) in just a moment (@pxref{Editing Drafts}).
-
-@vindex mh-compose-prompt-flag
-
-If you prefer to be prompted for the recipient and subject fields
-before the MH-Letter buffer appears, turn on the option
-@code{mh-compose-prompt-flag}.
-
-@cindex header field, @samp{X-Mailer}
-@cindex @samp{X-Mailer} header field
-@vindex mh-insert-x-mailer-flag
-
-MH-E adds an @samp{X-Mailer:} header field to the header that includes
-the version of MH-E and Emacs that you are using. If you don't want to
-participate in our marketing, you can turn off the option
-@code{mh-insert-x-mailer-flag}.
-
-@cindex @command{repl}
-@cindex @file{components}
-@cindex MH commands, @command{repl}
-@cindex MH-Letter mode
-@cindex Mail mode
-@cindex files, @file{components}
-@cindex modes, MH-Letter
-@cindex modes, Mail
-@vindex mail-mode-hook
-@vindex mh-letter-mode-hook
-@vindex text-mode-hook
-
-Two hooks are provided to run commands on your freshly created draft.
-The first hook, @code{mh-letter-mode-hook}, allows you to do some
-processing before editing a letter@footnote{Actually, because
-MH-Letter mode inherits from Mail mode, the hooks
-@code{text-mode-hook} and @code{mail-mode-hook} are run (in that
-order) before @code{mh-letter-mode-hook}.}. For example, you may wish
-to modify the header after @command{repl} has done its work, or you
-may have a complicated @file{components} file and need to tell MH-E
-where the cursor should go. Here's an example of how you would use
-this hook.
-
-@findex mh-insert-signature@r{, example}
-
-@smalllisp
-@group
-(defvar letter-mode-init-done-flag nil
- "Non-nil means one-time MH-E settings have been made.")
-
-(defun my-mh-letter-mode-hook ()
- "Prepare letter for editing."
- (when (not letter-mode-init-done) ; @r{only need to bind the keys once}
- (local-set-key "\C-ctb" 'add-enriched-text)
- (local-set-key "\C-cti" 'add-enriched-text)
- (local-set-key "\C-ctf" 'add-enriched-text)
- (local-set-key "\C-cts" 'add-enriched-text)
- (local-set-key "\C-ctB" 'add-enriched-text)
- (local-set-key "\C-ctu" 'add-enriched-text)
- (local-set-key "\C-ctc" 'add-enriched-text)
- (setq letter-mode-init-done t))
- (save-excursion
- (goto-char (point-max)) ; @r{go to end of message to}
- (mh-insert-signature))) ; @r{insert signature}
-
-@i{Prepare draft for editing via mh-letter-mode-hook}
-
-@end group
-@end smalllisp
-
-The function, @code{add-enriched-text} is defined in the example in
-@ref{Adding Attachments}.
-
-@vindex mh-compose-letter-function
-@vindex mh-letter-mode-hook
-
-The second hook, a function really, is
-@code{mh-compose-letter-function}. Like @code{mh-letter-mode-hook}, it
-is called just before editing a new message; however, it is the last
-function called before you edit your message. The consequence of this
-is that you can write a function to write and send the message for
-you. This function is passed three arguments: the contents of the
-@samp{To:}, @samp{Subject:}, and @samp{Cc:} header fields.
-
-@node Replying
-@section Replying to Mail
-
-@cindex @command{mhl}
-@cindex @file{mhl.reply}
-@cindex MH commands, @command{mhl}
-@cindex files, @file{mhl.reply}
-@cindex replying
-@findex mh-reply
-@kindex r
-
-To compose a reply to a message, use the @kbd{r} (@code{mh-reply})
-command.
-
-When you reply to a message, you are first prompted with @samp{Reply
-to whom?}. You have several choices here.
-
-@quotation
-@multitable @columnfractions .20 .80
-@c @headitem Response @tab Reply Goes To
-@c XXX @headitem not yet supported by SourceForge's texi2pdf.
-@item @b{Response} @tab @b{Reply Goes To}
-@c -------------------------
-@item @kbd{from}
-@tab
-The person who sent the message. This is the default, so @key{RET} is
-sufficient.
-@c -------------------------
-@item @kbd{to}
-@tab
-Replies to the sender, plus all recipients in the @samp{To:} header field.
-@c -------------------------
-@item @kbd{cc}@*@kbd{all}
-@tab
-Forms a reply to the addresses in the @samp{Mail-Followup-To:} header
-field if one exists; otherwise forms a reply to the sender, plus all
-recipients.
-@end multitable
-@end quotation
-
-@cindex @command{repl}
-@cindex MH commands, @command{repl}
-@vindex mh-reply-default-reply-to
-
-Depending on your answer, @command{repl}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/reprep.html, Replying to Messages: repl} in
-the MH book.} is given a different argument to form your reply.
-Specifically, a choice of @kbd{from} or none at all runs @samp{repl
--nocc all}, and a choice of @kbd{to} runs @samp{repl -cc to}. Finally,
-either @kbd{cc} or @kbd{all} runs @samp{repl -cc all -nocc me}. If you
-find that most of the time you specify one of these choices when you
-reply to a message, you can change the option
-@code{mh-reply-default-reply-to} from its default value of
-@samp{Prompt} to one of the choices listed above. You can always edit
-the recipients in the draft.
-
-@cindex @samp{repl} MH profile component
-@cindex MH profile component, @samp{repl}
-@cindex MH-Letter mode
-@cindex MH-Show mode
-@cindex draft
-@cindex modes, MH-Letter
-@cindex modes, MH-Show
-
-Two windows are then created. One window contains the message to which
-you are replying in an MH-Show buffer. Your draft, in MH-Letter mode
-(@pxref{Editing Drafts}), is in the other window. If the reply draft
-was not one that you expected, check the things that affect the
-behavior of @command{repl} which include the @samp{repl:} profile
-component and the @file{replcomps} and @file{replgroupcomps} files.
-
-If you supply a prefix argument (as in @kbd{C-u r}), the message you
-are replying to is inserted in your reply after having first been run
-through @command{mhl} with the format file @file{mhl.reply}. See
-@command{mhl}(1) or the section
-@uref{@value{MH-BOOK-HOME}/shomes.html#Usisho, Using mhl} in the MH
-book to see how you can modify the default @file{mhl.reply} file.
-
-@vindex mh-yank-behavior
-
-Alternatively, you can customize the option @code{mh-yank-behavior}
-and choose one of its @samp{Automatically} variants to do the same
-thing. @xref{Inserting Letter}. If you do so, the prefix argument has
-no effect.
-
-Another way to include the message automatically in your draft is to
-use @samp{repl: -filter repl.filter} in your MH profile.
-
-@vindex mh-reply-show-message-flag
-
-If you include the message automatically, you can hide the MH-Show
-buffer by turning off the option @code{mh-reply-show-message-flag}.
-
-If you wish to customize the header or other parts of the reply draft,
-please see @command{repl}(1) and @code{mh-format}(5).
-
-@node Forwarding
-@section Forwarding Mail
-
-@cindex @command{forw}
-@cindex draft
-@cindex forwarding
-@cindex MH commands, @command{forw}
-@findex mh-forward
-@kindex f
-@vindex mh-forward-hook
-
-To forward a message, use the @kbd{f} (@code{mh-forward}) command. You
-are prompted for the @samp{To:} and @samp{cc:} recipients. You are
-given a draft to edit that looks like it would if you had run the MH
-command @command{forw}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/forfor.html, Forwarding Messages: forw} in
-the MH book.}. You can then add some text (@pxref{Editing Drafts}).
-You can forward several messages by using a range (@pxref{Ranges}).
-All of the messages in the range are inserted into your draft. The
-hook @code{mh-forward-hook} is called on the draft.
-
-@cindex @file{.mh_profile}
-@cindex files, @file{.mh_profile}
-@cindex MH profile component, @samp{forw}
-@cindex @samp{forw} MH profile component
-@vindex mh-compose-forward-as-mime-flag
-
-By default, the option @code{mh-compose-forward-as-mime-flag} is on
-which means that the forwarded messages are included as attachments.
-These are inline attachments so the forwarded message should appear in
-the body of your recipient's mail program. If you would prefer to
-forward your messages verbatim (as text, inline), then turn off this
-option. Forwarding messages verbatim works well for short, textual
-messages, but your recipient won't be able to view any non-textual
-attachments that were in the forwarded message. Be aware that if you
-have @samp{forw: -mime} in your MH profile, then forwarded messages
-will always be included as attachments regardless of the settings of
-@code{mh-compose-forward-as-mime-flag}.
-
-@vindex mh-forward-subject-format
-
-The format of the @samp{Subject:} header field for forwarded messages
-is controlled by the option @code{mh-forward-subject-format}. This
-option is a string which includes two escapes (@samp{%s}). The first
-@samp{%s} is replaced with the sender of the original message, and the
-second one is replaced with the original @samp{Subject:}. The default
-value of @code{"%s: %s"} takes a message with the header:
-
-@smallexample
-@group
-To: Bill Wohler <wohler@@stop.mail-abuse.org>
-Subject: Re: 49er football
-From: Greg DesBrisay <gd@@stop.mail-abuse.org>
-@end group
-@end smallexample
-
-and creates a subject header field of:
-
-@smallexample
-Subject: Greg DesBrisay: Re: 49er football
-@end smallexample
-
-@node Redistributing
-@section Redistributing Your Mail
-
-@cindex @command{dist}
-@cindex MH commands, @command{dist}
-@cindex redistributing
-@findex mh-redistribute
-@kindex M-d
-
-The command @kbd{M-d} (@code{mh-redistribute}) is similar in function
-to forwarding mail, but it does not allow you to edit the message, nor
-does it add your name to the @samp{From:} header field. It appears to
-the recipient as if the message had come from the original sender.
-When you run this command, you are prompted for the recipients.
-
-@findex mh-edit-again
-@kindex e
-
-For more information on redistributing messages, see
-@command{dist}(1). Also investigate the command @kbd{e}
-(@code{mh-edit-again}) for another way to redistribute messages
-(@pxref{Editing Again}).
-
-@cindex @command{send}
-@cindex MH commands, @command{send}
-@vindex mh-redist-full-contents-flag
-
-The option @code{mh-redist-full-contents-flag} must be turned on if
-@command{dist}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/disdis.html, Distributing Messages with
-dist} in the MH book.} requires the whole letter for redistribution,
-which is the case if @command{send}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/sensen.html, Sending Some Mail: comp send}
-in the MH book.} is compiled with the @sc{berk} option (which many
-people abhor). If you find that MH will not allow you to redistribute
-a message that has been redistributed before, turn off this option.
-
-The hook @code{mh-annotate-msg-hook} is run after annotating the
-message and scan line (@pxref{Sending Mail}).
-
-@node Editing Again
-@section Editing Old Drafts and Bounced Messages
-
-@cindex @file{draft}
-@cindex files, @file{draft}
-@cindex re-editing drafts
-@findex mh-edit-again
-@kindex F v drafts
-@kindex e
-@kindex n
-
-If you don't complete a draft for one reason or another, and if the
-draft buffer is no longer available, you can pick your draft up again
-with @kbd{e} (@code{mh-edit-again}). If you don't use a draft
-folder, your last @file{draft} file will be used. If you use draft
-folders, you'll need to visit the draft folder with @kbd{F v drafts
-@key{RET}}, use @kbd{n} to move to the appropriate message, and then
-use @kbd{e} to prepare the message for editing.
-
-@kindex e
-
-The @kbd{e} command can also be used to take messages that were sent
-to you and to send them to more people.
-
-@cindex Mailer-Daemon
-@findex mh-extract-rejected-mail
-@kindex C-c C-c
-@kindex E
-
-Don't use @kbd{e} to re-edit a message from a @i{Mailer-Daemon} who
-complained that your mail wasn't posted for some reason or another. In
-this case, use @kbd{E} (@code{mh-extract-rejected-mail}) to prepare
-the message for editing by removing the @i{Mailer-Daemon} envelope and
-unneeded header fields. Fix whatever addressing problem you had, and
-send the message again with @kbd{C-c C-c}.
-
-@node Editing Drafts
-@chapter Editing a Draft
-
-@cindex @samp{Letter} menu
-@cindex MH-Letter mode
-@cindex draft
-@cindex editing draft
-@cindex menu, @samp{Letter}
-@cindex modes, MH-Letter
-
-When you edit a message that you want to send (called a @dfn{draft} in
-this case), the mode used is MH-Letter. This mode provides several
-commands in addition to the normal Emacs editing commands to help you
-edit your draft. These can also be found in the @samp{Letter} menu.
-
-@table @kbd
-@kindex SPC
-@findex mh-letter-complete-or-space
-@item @key{SPC}
-Perform completion or insert space (@code{mh-letter-complete-or-space}).
-@c -------------------------
-@kindex M-TAB
-@findex mh-letter-complete
-@item M-@key{TAB}
-Perform completion on header field or word preceding point
-(@code{mh-letter-complete}).
-@c -------------------------
-@kindex , @r{(comma)}
-@findex mh-letter-confirm-address
-@item , (comma)
-Flash alias expansion (@code{mh-letter-confirm-address}).
-@c -------------------------
-@kindex TAB
-@findex mh-letter-next-header-field-or-indent
-@item @key{TAB}
-Cycle to next field (@code{mh-letter-next-header-field-or-indent}).
-@c -------------------------
-@kindex S-TAB
-@findex mh-letter-previous-header-field
-@item S-@key{TAB}
-Cycle to the previous header field
-(@code{mh-letter-previous-header-field}).
-@c -------------------------
-@kindex C-c ?
-@findex mh-help
-@item C-c ?
-Display cheat sheet for the MH-E commands (@code{mh-help}).
-@c -------------------------
-@cindex @samp{Letter > Send This Draft} menu item
-@cindex menu item, @samp{Letter > Send This Draft}
-@kindex C-c C-c
-@findex mh-send-letter
-@item C-c C-c
-Save draft and send message (@code{mh-send-letter}).
-@c -------------------------
-@kindex C-c C-d
-@findex mh-insert-identity
-@item C-c C-d
-Insert fields specified by the given identity
-(@code{mh-insert-identity}). @xref{Identities}.
-@c -------------------------
-@cindex @samp{Letter > Pull in All Compositions (MH)} menu item
-@cindex menu item, @samp{Letter > Pull in All Compositions (MH)}
-@kindex C-c C-e
-@findex mh-mh-to-mime
-@item C-c C-e
-Compose @sc{mime} message from MH-style directives
-(@code{mh-mh-to-mime}).
-@c -------------------------
-@kindex C-c C-f C-a
-@kindex C-c C-f a
-@findex mh-to-field
-@item C-c C-f C-a
-@itemx C-c C-f a
-Move to @samp{Mail-Reply-To:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-b
-@kindex C-c C-f b
-@item C-c C-f C-b
-@itemx C-c C-f b
-Move to @samp{Bcc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-c
-@kindex C-c C-f c
-@item C-c C-f C-c
-@itemx C-c C-f c
-Move to @samp{Cc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-d
-@kindex C-c C-f d
-@item C-c C-f C-d
-@itemx C-c C-f d
-Move to @samp{Dcc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-f
-@kindex C-c C-f f
-@findex mh-to-fcc
-@item C-c C-f C-f
-@itemx C-c C-f f
-Move to @samp{Fcc:} header field (@code{mh-to-fcc}).
-@c -------------------------
-@kindex C-c C-f C-l
-@kindex C-c C-f l
-@item C-c C-f C-l
-@itemx C-c C-f l
-Move to @samp{Mail-Followup-To:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-m
-@kindex C-c C-f m
-@item C-c C-f C-m
-@itemx C-c C-f m
-Move to @samp{From:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-r
-@kindex C-c C-f r
-@item C-c C-f C-r
-@itemx C-c C-f r
-Move to @samp{Reply-To:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-s
-@kindex C-c C-f s
-@item C-c C-f C-s
-@itemx C-c C-f s
-Move to @samp{Subject:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-t
-@kindex C-c C-f t
-@item C-c C-f C-t
-@itemx C-c C-f t
-Move to @samp{To:} header field (@code{mh-to-field}).
-@c -------------------------
-@cindex @samp{Letter > Insert a Message...} menu item
-@cindex menu item, @samp{Letter > Insert a Message...}
-@kindex C-c C-i
-@findex mh-insert-letter
-@item C-c C-i
-Insert a message (@code{mh-insert-letter}).
-@c -------------------------
-@kindex C-c C-m C-e
-@findex mh-mml-secure-message-encrypt
-@item C-c C-m C-e
-Add tag to encrypt the message (@code{mh-mml-secure-message-encrypt}).
-@c -------------------------
-@cindex @samp{Letter > Compose Forward...} menu item
-@cindex menu item, @samp{Letter > Compose Forward...}
-@kindex C-c C-m C-f
-@kindex C-c C-m f
-@findex mh-compose-forward
-@item C-c C-m C-f
-@itemx C-c C-m f
-Add tag to forward a message (@code{mh-compose-forward}).
-@c -------------------------
-@cindex @samp{Letter > Compose Get File (MH)...} menu item
-@cindex menu item, @samp{Letter > Compose Get File (MH)...}
-@kindex C-c C-m C-g
-@kindex C-c C-m g
-@findex mh-mh-compose-anon-ftp
-@item C-c C-m C-g
-@itemx C-c C-m g
-Add tag to include anonymous ftp reference to a file
-(@code{mh-mh-compose-anon-ftp}).
-@c -------------------------
-@cindex @samp{Letter > Compose Insertion...} menu item
-@cindex menu item, @samp{Letter > Compose Insertion...}
-@kindex C-c C-m C-i
-@kindex C-c C-m i
-@findex mh-compose-insertion
-@item C-c C-m C-i
-@itemx C-c C-m i
-Add tag to include a file such as an image or sound
-(@code{mh-compose-insertion}).
-@c -------------------------
-@cindex @samp{Letter > Pull in All Compositions (MML)} menu item
-@cindex menu item, @samp{Letter > Pull in All Compositions (MML)}
-@kindex C-c C-m C-m
-@kindex C-c C-m m
-@findex mh-mml-to-mime
-@item C-c C-m C-m
-@itemx C-c C-m m
-Compose @sc{mime} message from MML tags (@code{mh-mml-to-mime}).
-@c -------------------------
-@kindex C-c C-m C-n
-@kindex C-c C-m n
-@findex mh-mml-unsecure-message
-@item C-c C-m C-n
-@itemx C-c C-m n
-Remove any secure message tags (@code{mh-mml-unsecure-message}).
-@c -------------------------
-@kindex C-c C-m C-s
-@findex mh-mml-secure-message-sign
-@item C-c C-m C-s
-Add tag to sign the message (@code{mh-mml-secure-message-sign}).
-@c -------------------------
-@cindex @samp{Letter > Compose Compressed tar (MH)...} menu item
-@cindex menu item, @samp{Letter > Compose Compressed tar (MH)...}
-@kindex C-c C-m C-t
-@kindex C-c C-m t
-@findex mh-mh-compose-external-compressed-tar
-@item C-c C-m C-t
-@itemx C-c C-m t
-Add tag to include anonymous ftp reference to a compressed tar file
-(@code{mh-mh-compose-external-compressed-tar}).
-@c -------------------------
-@cindex @samp{Letter > Revert to Non-MIME Edit (MH)} menu item
-@cindex menu item, @samp{Letter > Revert to Non-MIME Edit (MH)}
-@kindex C-c C-m C-u
-@kindex C-c C-m u
-@findex mh-mh-to-mime-undo
-@item C-c C-m C-u
-@itemx C-c C-m u
-Undo effects of @kbd{C-c C-e} (@code{mh-mh-to-mime-undo}).
-@c -------------------------
-@kindex C-c C-m C-x
-@kindex C-c C-m x
-@findex mh-mh-compose-external-type
-@item C-c C-m C-x
-@itemx C-c C-m x
-Add tag to refer to a remote file
-(@code{mh-mh-compose-external-type}).
-@c -------------------------
-@kindex C-c C-m e e
-@findex mh-mml-secure-message-encrypt
-@item C-c C-m e e
-Add tag to encrypt the message (@code{mh-mml-secure-message-encrypt}).
-@c -------------------------
-@kindex C-c C-m e s
-@findex mh-mml-secure-message-signencrypt
-@item C-c C-m e s
-Add tag to encrypt and sign the message@*
-(@code{mh-mml-secure-message-signencrypt}).
-@c -------------------------
-@kindex C-c C-m s e
-@findex mh-mml-secure-message-signencrypt
-@item C-c C-m s e
-Add tag to encrypt and sign the message@*
-(@code{mh-mml-secure-message-signencrypt}).
-@c -------------------------
-@kindex C-c C-m s s
-@findex mh-mml-secure-message-sign
-@item C-c C-m s s
-Add tag to sign the message (@code{mh-mml-secure-message-sign}).
-@c -------------------------
-@cindex @samp{Letter > Split Current Line} menu item
-@cindex menu item, @samp{Letter > Split Current Line}
-@kindex C-c C-o
-@findex mh-open-line
-@item C-c C-o
-Insert a newline and leave point before it (@code{mh-open-line}).
-@c -------------------------
-@cindex @samp{Letter > Kill This Draft} menu item
-@cindex menu item, @samp{Letter > Kill This Draft}
-@kindex C-c C-q
-@findex mh-fully-kill-draft
-@item C-c C-q
-Quit editing and delete draft message (@code{mh-fully-kill-draft}).
-@c -------------------------
-@cindex @samp{Letter > Insert Signature} menu item
-@cindex menu item, @samp{Letter > Insert Signature}
-@kindex C-c C-s
-@findex mh-insert-signature
-@item C-c C-s
-Insert signature in message (@code{mh-insert-signature}).
-@c -------------------------
-@kindex C-c C-t
-@findex mh-letter-toggle-header-field-display
-@item C-c C-t
-Toggle display of header field at point
-(@code{mh-letter-toggle-header-field-display}).
-@c -------------------------
-@cindex @samp{Letter > Check Recipient} menu item
-@cindex menu item, @samp{Letter > Check Recipient}
-@kindex C-c C-w
-@findex mh-check-whom
-@item C-c C-w
-Verify recipients, showing expansion of any aliases
-(@code{mh-check-whom}).
-@c -------------------------
-@cindex @samp{Letter > Yank Current Message} menu item
-@cindex menu item, @samp{Letter > Yank Current Message}
-@kindex C-c C-y
-@findex mh-yank-cur-msg
-@item C-c C-y
-Insert the current message into the draft buffer
-(@code{mh-yank-cur-msg}).
-@c -------------------------
-@kindex C-c M-d
-@findex mh-insert-auto-fields
-@item C-c M-d
-Insert custom fields if recipient is found in
-@code{mh-auto-fields-list} (@code{mh-insert-auto-fields}).
-@xref{Identities}.
-@end table
-
-@cindex @samp{mh-letter} customization group
-@cindex customization group, @samp{mh-letter}
-
-Several options from the @samp{mh-letter} customization group are used
-while editing a draft.
-
-@vtable @code
-@item mh-compose-insertion
-Type of @sc{mime} message tags in messages (default: @samp{MML} if
-available; otherwise @samp{MH}).
-@c -------------------------
-@item mh-compose-skipped-header-fields
-List of header fields to skip over when navigating in draft (default:
-@code{'("From"} @code{"Organization"} @code{"References"}
-@code{"In-Reply-To"} @code{"X-Face"} @code{"Face"}
-@code{"X-Image-URL"} @code{"X-Mailer")}.
-@c -------------------------
-@item mh-compose-space-does-completion-flag
-On means @key{SPC} does completion in message header (default:
-@samp{off}).
-@c -------------------------
-@item mh-delete-yanked-msg-window-flag
-On means delete any window displaying the message (default: @samp{off}).
-@c -------------------------
-@item mh-extract-from-attribution-verb
-Verb to use for attribution when a message is yanked by @kbd{C-c C-y}
-(default: @code{"wrote:"}).
-@c -------------------------
-@item mh-ins-buf-prefix
-String to put before each line of a yanked or inserted message
-(default: @code{"> "}).
-@c -------------------------
-@item mh-letter-complete-function
-Function to call when completing outside of address or folder fields
-(default: @code{ispell-complete-word}).
-@c -------------------------
-@item mh-letter-fill-column
-Fill column to use in MH-Letter mode (default: 72).
-@c -------------------------
-@item mh-mml-method-default
-Default method to use in security tags (default: @samp{PGP (MIME)} if
-support for it is available; otherwise @samp{None}).
-@c -------------------------
-@item mh-signature-file-name
-Source of user's signature (default: @code{"~/.signature"}).
-@c -------------------------
-@item mh-signature-separator-flag
-On means a signature separator should be inserted (default:
-@samp{on}).
-@c -------------------------
-@item mh-x-face-file
-File containing X-Face or Face header field to insert in outgoing mail.
-(default: @code{"~/.face"}).
-@c -------------------------
-@item mh-yank-behavior
-Controls which part of a message is yanked by @kbd{C-c C-y} (default:
-@samp{Body With Attribution}).
-@end vtable
-
-The following hooks are available.
-
-@vtable @code
-@item mail-citation-hook
-Hook for modifying a citation just inserted in the mail buffer
-(default: @code{nil}).
-@c -------------------------
-@item mh-before-send-letter-hook
-Hook run at the beginning of the @kbd{C-c C-c} command (default:
-@samp{nil}).
-@c -------------------------
-@item mh-mh-to-mime-hook
-Hook run on the formatted letter by @kbd{C-c C-e} (default:
-@samp{nil}).
-@c -------------------------
-@item mh-insert-signature-hook
-Hook run by @kbd{C-c C-s} after signature has been inserted (default:
-@code{nil}).
-@end vtable
-
-The following face is available.
-
-@vtable @code
-@item mh-letter-header-field
-Editable header field value face in draft buffers.
-@end vtable
-
-The commands and options introduced here are explained in more
-detail in the following sections.
-
-@menu
-* Editing Message::
-* Inserting Letter::
-* Inserting Messages::
-* Signature::
-* Picture::
-* Adding Attachments::
-* Sending PGP::
-* Checking Recipients::
-* Sending Message::
-* Killing Draft::
-@end menu
-
-@node Editing Message
-@section Editing the Message
-
-@cindex @samp{Bcc} header field
-@cindex @samp{Cc} header field
-@cindex @samp{Dcc} header field
-@cindex @samp{From} header field
-@cindex @samp{Mail-Followup-To} header field
-@cindex @samp{Mail-Reply-To} header field
-@cindex @samp{Reply-To} header field
-@cindex @samp{Subject} header field
-@cindex @samp{To} header field
-@cindex editing header
-@cindex header field, @samp{Bcc}
-@cindex header field, @samp{Cc}
-@cindex header field, @samp{Dcc}
-@cindex header field, @samp{From}
-@cindex header field, @samp{Mail-Followup-To}
-@cindex header field, @samp{Mail-Reply-To}
-@cindex header field, @samp{Reply-To}
-@cindex header field, @samp{Subject}
-@cindex header field, @samp{To}
-@findex mh-to-field
-@kindex C-c C-f C-t
-@kindex C-c C-f t
-
-Because the header is part of the message, you can edit the header
-fields as you wish. However, several convenience commands exist to
-help you create and edit them. For example, the command @kbd{C-c C-f
-C-t} (@code{mh-to-field}; alternatively, @kbd{C-c C-f t}) moves the
-cursor to the @samp{To:} header field, creating it if necessary. The
-commands for moving to the @samp{Cc:}, @samp{Subject:}, @samp{From:},
-@samp{Reply-To:}, @samp{Mail-Reply-To:}, @samp{Mail-Followup-To},
-@samp{Bcc:}, and @samp{Dcc:} header fields are similar.
-
-@findex mh-to-fcc
-@kindex C-c C-f C-f
-@kindex C-c C-f f
-
-One command behaves differently from the others, namely, @kbd{C-c C-f
-C-f} (@code{mh-to-fcc}; alternatively, @kbd{C-c C-f f}). This command
-will prompt you for the folder name in which to file a copy of the
-draft. @xref{Folder Selection}.
-
-@findex indent-relative
-@findex mh-letter-next-header-field-or-indent
-@findex mh-letter-previous-header-field
-@kindex TAB
-@kindex S-TAB
-@vindex mh-compose-skipped-header-fields
-@vindex mh-letter-header-field
-
-Within the header of the message, the command@* @key{TAB}
-(@code{mh-letter-next-header-field-or-indent}) moves between fields
-that are highlighted with the face @code{mh-letter-header-field},
-skipping those fields listed in
-@code{mh-compose-skipped-header-fields}. After the last field, this
-command then moves point to the message body before cycling back to
-the first field. If point is already past the first line of the
-message body, then this command indents by calling
-@code{indent-relative} with the given prefix argument. The command
-@kbd{S-@key{TAB}} (@code{mh-letter-previous-header-field}) moves
-backwards between the fields and cycles to the body of the message
-after the first field. Unlike the command @key{TAB}, it will always
-take point to the last field from anywhere in the body.
-
-@cindex alias completion
-@cindex completion
-@cindex spell check
-@findex ispell-complete-word
-@findex mh-letter-complete
-@findex mh-letter-complete-or-space
-@findex mh-letter-confirm-address
-@kindex , @r{(comma)}
-@kindex SPC
-@kindex M-TAB
-@vindex mh-alias-flash-on-comma
-@vindex mh-compose-space-does-completion-flag
-@vindex mh-letter-complete-function
-
-If the field contains addresses (for example, @samp{To:} or
-@samp{Cc:}) or folders (for example, @samp{Fcc:}) then the command
-@kbd{M-@key{TAB}} (@code{mh-letter-complete}) will provide alias
-completion (@pxref{Aliases}). In the body of the message,
-@kbd{M-@key{TAB}} runs @code{mh-letter-complete-function} instead,
-which is set to @samp{'ispell-complete-word} by default. The command
-@kbd{M-@key{TAB}} (@code{mh-letter-complete}) takes a prefix argument
-that is passed to the @code{mh-letter-complete-function}. In addition,
-turn on the option @code{mh-compose-space-does-completion-flag} to use
-the command @key{SPC} (@code{mh-letter-complete-or-space}) to perform
-completion in the header as well; use a prefix argument to specify
-more than one space. Addresses are separated by a comma; when you
-press the comma, the command @code{mh-letter-confirm-address} flashes
-the alias expansion in the minibuffer if
-@code{mh-alias-flash-on-comma} is turned on.
-
-@c XXX Document the replacement for the inaccessible 'long argument.
-
-@findex mh-letter-toggle-header-field-display
-@kindex C-c C-t
-
-Use the command @kbd{C-c C-t}
-@code{mh-letter-toggle-header-field-display} to display truncated
-header fields. This command is a toggle so entering it again will hide
-the field. This command takes a prefix argument: if negative then the
-field is hidden, if positive then the field is displayed (for example,
-@kbd{C-u C-c C-t}).
-
-Be sure to leave a row of dashes or a blank line between the header
-and the body of the message.
-
-@vindex mh-letter-fill-column
-
-The body of the message is edited as you would edit any Emacs buffer
-although there are a few commands and options to assist you. You can
-change the fill column in MH-Letter mode with the option
-@code{mh-letter-fill-column}. By default, this option is 72 to allow
-others to quote your message without line wrapping.
-
-@cindex filling paragraphs
-@cindex paragraphs, filling
-@findex fill-paragraph
-@kindex M-q
-@vindex mh-ins-buf-prefix
-
-You'll often include messages that were sent from user agents that
-haven't yet realized that paragraphs consist of more than a single
-line. This makes for long lines that wrap in an ugly fashion. You'll
-find that @kbd{M-q} (@code{fill-paragraph}) works well even on these
-quoted messages, even if they are nested, just as long as all of the
-quotes match the value of @code{mh-ins-buf-prefix} (@pxref{Inserting
-Letter}). For example, let's assume you have the following in your
-draft:
-
-@smallexample
-@group
-> Hopefully this gives you an idea of what I'm currently doing. I'm \
-not sure yet whether I'm completely satisfied with my setup, but \
-it's worked okay for me so far.
-@end group
-@end smallexample
-
-Running @kbd{M-q} on this paragraph produces:
-
-@smallexample
-@group
-> Hopefully this gives you an idea of what I'm currently doing. I'm not
-> sure yet whether I'm completely satisfied with my setup, but it's
-> worked okay for me so far.
-@end group
-@end smallexample
-
-@findex mh-open-line
-@findex open-line
-@kindex C-c C-o
-@kindex C-o
-
-The command @kbd{C-c C-o} (@code{mh-open-line}) is similar to the
-command @kbd{C-o} (@code{open-line}) in that it inserts a newline
-after point. It differs in that it also inserts the right number of
-quoting characters and spaces so that the next line begins in the same
-column as it was. This is useful when breaking up paragraphs in
-replies. For example, if this command was used when point was after
-the first period in the paragraph above, the result would be this:
-
-@smallexample
-@group
-> Hopefully this gives you an idea of what I'm currently doing.
-
-> I'm not
-> sure yet whether I'm completely satisfied with my setup, but it's
-> worked okay for me so far.
-@end group
-@end smallexample
-
-@node Inserting Letter
-@section Inserting Letter to Which You're Replying
-
-@cindex inserting messages
-@cindex replying to messages
-@cindex yanking messages
-@findex mh-yank-cur-msg
-@kindex C-c C-y
-@vindex mh-ins-buf-prefix
-
-It is often useful to insert a snippet of text from a letter that
-someone mailed to provide some context for your reply. The command
-@kbd{C-c C-y} (@code{mh-yank-cur-msg}) does this by adding an
-attribution, yanking a portion of text from the message to which
-you're replying, and inserting @code{mh-ins-buf-prefix} (@samp{> })
-before each line.
-
-@smallexample
-@group
-Michael W Thelen <thelenm@@stop.mail-abuse.org> wrote:
-
-> Hopefully this gives you an idea of what I'm currently doing. I'm not
-> sure yet whether I'm completely satisfied with my setup, but it's
-> worked okay for me so far.
-@end group
-@end smallexample
-
-@vindex mh-extract-from-attribution-verb
-
-The attribution consists of the sender's name and email address
-followed by the content of the option
-@code{mh-extract-from-attribution-verb}. This option can be set to
-@samp{wrote:}, @samp{a écrit:}, and @samp{schrieb:}. You can also use
-the @samp{Custom String} menu item to enter your own verb.
-
-@vindex mail-citation-hook
-@vindex mh-ins-buf-prefix
-@vindex mh-yank-behavior
-
-The prefix @code{"> "} is the default setting for the option
-@code{mh-ins-buf-prefix}. I suggest that you not modify this option
-since it is used by many mailers and news readers: messages are far
-easier to read if several included messages have all been indented by
-the same string. This prefix is not inserted if you use one of the
-supercite flavors of @code{mh-yank-behavior} or you have added a
-@code{mail-citation-hook} as described below.
-
-@vindex mh-delete-yanked-msg-window-flag
-
-You can also turn on the @code{mh-delete-yanked-msg-window-flag}
-option to delete the window containing the original message after
-yanking it to make more room on your screen for your reply.
-
-@cindex Emacs, packages, @samp{supercite}
-@cindex @samp{supercite} package
-@kindex r
-@vindex mail-citation-hook
-@vindex mh-yank-behavior
-
-You can control how the message to which you are replying is yanked
-into your reply using @code{mh-yank-behavior}. To include the entire
-message, including the entire header, use @samp{Body and
-Header}@footnote{If you'd rather have the header cleaned up, use
-@kbd{C-u r} instead of @kbd{r} when replying
-(@pxref{Replying}).}@footnote{In the past you would use this setting
-and set @code{mail-citation-hook} to @samp{supercite}, but this usage
-is now deprecated in favor of the @samp{Invoke supercite} setting.}.
-Use @samp{Body} to yank just the body without the header. To yank only
-the portion of the message following the point, set this option to
-@samp{Below Point}.
-
-Choose @samp{Invoke supercite}@footnote{@emph{Supercite} is a
-full-bodied, full-featured, citation package that comes standard with
-Emacs.} to pass the entire message and header through supercite.
-
-@vindex mh-extract-from-attribution-verb
-
-If the @samp{Body With Attribution} setting is used, then the message
-minus the header is yanked and a simple attribution line is added at
-the top using the value of the option
-@code{mh-extract-from-attribution-verb}. This is the default.
-
-@kindex C-c C-y
-@vindex mh-delete-yanked-msg-window-flag
-
-If the @samp{Invoke supercite} or @samp{Body With Attribution}
-settings are used, the @samp{-noformat} argument is passed to the
-@command{repl} program to override a @samp{-filter} or @samp{-format}
-argument. These settings also have @samp{Automatically} variants that
-perform the action automatically when you reply so that you don't need
-to use @kbd{C-c C-y} at all. Note that this automatic action is only
-performed if the show buffer matches the message being replied to.
-People who use the automatic variants tend to turn on the option
-@code{mh-delete-yanked-msg-window-flag} as well so that the show
-window is never displayed.
-
-@vindex mh-yank-behavior
-
-If the show buffer has a region, the option @code{mh-yank-behavior} is
-ignored unless its value is one of @samp{Attribution} variants in
-which case the attribution is added to the yanked region.
-
-@findex trivial-cite
-@vindex mail-citation-hook
-@vindex mh-ins-buf-prefix
-@vindex mh-yank-behavior
-
-If this isn't enough, you can gain full control over the appearance of
-the included text by setting @code{mail-citation-hook} to a function
-that modifies it. This hook is ignored if the option
-@code{mh-yank-behavior} is set to one of the supercite flavors.
-Otherwise, this option controls how much of the message is passed to
-the hook. The function can find the citation between point and mark
-and it should leave point and mark around the modified citation text
-for the next hook function. The standard prefix
-@code{mh-ins-buf-prefix} is not added if this hook is set.
-
-@cindex Emacs, packages, @samp{trivial-cite}
-@cindex @samp{trivial-cite} package
-@vindex mh-yank-behavior
-
-For example, if you use the hook function
-@uref{https://www.emacswiki.org/emacs/TrivialCite,
-@code{trivial-cite}} (which is NOT part of Emacs), set
-@code{mh-yank-behavior} to @samp{Body and Header}.
-
-@node Inserting Messages
-@section Inserting Messages
-
-@cindex inserting messages
-@findex mh-insert-letter
-@findex mh-yank-behavior
-@kindex C-c C-i
-@vindex mh-ins-buf-prefix
-@vindex mh-invisible-header-fields-compiled
-@vindex mh-yank-behavior
-
-Messages can be inserted with @kbd{C-c C-i} (@code{mh-insert-letter}).
-This command prompts you for the folder and message number, which
-defaults to the current message in that folder. It then inserts the
-messages, indented by @code{mh-ins-buf-prefix} (@samp{> }) unless
-@code{mh-yank-behavior} is set to one of the supercite flavors in
-which case supercite is used to format the message. Certain
-undesirable header fields (see
-@code{mh-invisible-header-fields-compiled}) are removed before
-insertion.
-
-If given a prefix argument (like @kbd{C-u C-c C-i}), the header is
-left intact, the message is not indented, and @samp{> } is not
-inserted before each line. This command leaves the mark before the
-letter and point after it.
-
-@node Signature
-@section Inserting Your Signature
-
-@cindex signature
-@findex mh-insert-signature
-@kindex C-c C-s
-
-You can insert your signature at the current cursor location with the
-command @kbd{C-c C-s} (@code{mh-insert-signature}).
-
-@cindex files, @file{.signature}
-@cindex @file{.signature}
-@cindex vCard
-@vindex mh-signature-file-name
-
-By default, the text of your signature is taken from the file
-@file{~/.signature}. You can read from other sources by changing the
-option @code{mh-signature-file-name}. This file may contain a
-@dfn{vCard} in which case an attachment is added with the vCard.
-
-@findex mh-signature-separator-p
-@vindex mh-signature-file-name
-@vindex mh-signature-separator
-@vindex mh-signature-separator-regexp
-
-The option @code{mh-signature-file-name} may also be a symbol, in
-which case that function is called. You may not want a signature
-separator to be added for you; instead you may want to insert one
-yourself. Options that you may find useful to do this include
-@code{mh-signature-separator} (when inserting a signature separator)
-and @code{mh-signature-separator-regexp} (for finding said separator).
-The function @code{mh-signature-separator-p}, which reports @code{t}
-if the buffer contains a separator, may be useful as well.
-
-@cindex signature separator
-@vindex mh-signature-separator-flag
-
-A signature separator (@code{"-- "}) will be added if the signature
-block does not contain one and @code{mh-signature-separator-flag} is
-on. It is not recommended that you change this option since various
-mail user agents, including MH-E, use the separator to present the
-signature differently, and to suppress the signature when replying or
-yanking a letter into a draft.
-
-@vindex mh-insert-signature-hook
-@vindex mh-signature-file-name
-
-The hook @code{mh-insert-signature-hook} is run after the signature is
-inserted. Hook functions may access the actual name of the file or the
-function used to insert the signature with
-@code{mh-signature-file-name}.
-
-The signature can also be inserted using Identities.
-@xref{Identities}.
-
-@node Picture
-@section Inserting Your Picture
-
-@cindex @file{.face}
-@cindex files, @file{.face}
-@vindex mh-x-face-file
-
-You can insert your picture in the header of your mail message so that
-recipients see your face in the @samp{From:} header field if their
-mail user agent is sophisticated enough. In MH-E, this is done by
-placing your image in the file named by the option
-@code{mh-x-face-file} which is @file{~/.face} by default.
-
-@cindex @samp{Face} header field
-@cindex @samp{X-Face} header field
-@cindex @samp{X-Image-URL} header field
-@cindex header field, @samp{Face}
-@cindex header field, @samp{X-Face}
-@cindex header field, @samp{X-Image-URL}
-
-If the file starts with either of the strings @samp{X-Face:},
-@samp{Face:} or @samp{X-Image-URL:} then the contents are added to the
-message header verbatim. Otherwise it is assumed that the file
-contains the value of the @samp{X-Face:} header field.
-
-@cindex @command{compface}
-@cindex Unix commands, @command{compface}
-
-The @samp{X-Face:} header field, which is a low-resolution, black and
-white image, can be generated using the
-@uref{ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z,
-@command{compface}} command. The @uref{https://www.dairiki.org/xface/,
-@cite{Online X-Face Converter}} is a useful resource for quick
-conversion of images into @samp{X-Face:} header fields.
-
-Use the @uref{https://quimby.gnus.org/circus/face/make-face,
-@command{make-face}} script to convert a JPEG image to the higher
-resolution, color, @samp{Face:} header field.
-
-The URL of any image can be used for the @samp{X-Image-URL:} field and
-no processing of the image is required.
-
-@vindex mh-x-face-file
-
-To prevent the setting of any of these header fields, either set
-@code{mh-x-face-file} to @code{nil}, or simply ensure that the file
-defined by this option doesn't exist.
-
-@xref{Viewing}, to see how these header fields are displayed in MH-E.
-
-@node Adding Attachments
-@section Adding Attachments
-
-@cindex @command{mhbuild}
-@cindex @command{mhn}
-@cindex MH commands, @command{mhbuild}
-@cindex MH commands, @command{mhn}
-@cindex MIME
-@cindex multimedia mail
-
-MH-E has the capability to create multimedia messages. It uses the
-@sc{mime} (Multipurpose Internet Mail Extensions)
-protocol@footnote{@sc{mime} is defined in
-@uref{https://www.rfc-editor.org/rfc/rfc2045.txt, RFC 2045}.} The
-@sc{mime} protocol allows you to incorporate images, sound, video,
-binary files, and even commands that fetch a file with @samp{ftp} when
-your recipient reads the message!
-
-@kindex C-c C-m
-
-If you were to create a multimedia message with plain MH commands, you
-would insert @command{mhbuild} or @command{mhn} directives (henceforth
-called @dfn{MH-style directives} into your draft and use the
-@command{mhbuild} command in nmh or @command{mhn} command in MH and
-GNU mailutils to expand them. MH-E works in much the same way,
-although it provides a handful of commands prefixed with @kbd{C-c C-m}
-to insert the directives so you don't need to remember the syntax of
-them. Remember: you can always add MH-style directives by
-hand@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/usimim.html#SeMIMa, Sending MIME Mail} in
-the MH book.}.
-
-@cindex MIME Meta Language (MML)
-@cindex MML
-@vindex mh-compose-insertion
-
-In addition to MH-style directives, MH-E also supports MML (@sc{mime}
-Meta Language) tags@footnote{
-@ifinfo
-@c Although the third argument should default to the
-@c first, makeinfo goes to the wrong Info file without it being
-@c different--it seems to be getting our own Composing node.
-@xref{Composing,,Composing with MML,emacs-mime}.
-@end ifinfo
-@ifnotinfo
-See the section Composing in
-@uref{https://www.gnus.org/manual/emacs-mime.html, @cite{The Emacs MIME
-Manual}}.
-@end ifnotinfo
-}. The option @code{mh-compose-insertion} can be used to choose
-between them. By default, this option is set to @samp{MML} if it is
-supported since it provides a lot more functionality. This option can
-also be set to @samp{MH} if MH-style directives are preferred.
-
-@cindex media types
-@cindex MIME, media types
-
-The MH-E @sc{mime} commands require a @dfn{media type} for each body
-part or attachment. For example, a PDF document is of type
-@samp{application/pdf} and an HTML document is of type
-@samp{text/html}. Some commands fill in the media type for you,
-whereas others require you to enter one.
-
-@cindex @command{file}
-@cindex @file{/etc/mime.types}
-@cindex files, @file{/etc/mime.types}
-@cindex Unix commands, @command{file}
-@findex mailcap-mime-types
-
-In the cases where MH-E can do so, it will determine the media type
-automatically. It uses the @command{file} command to do this. Failing
-that, the Emacs function @code{mailcap-mime-types} is used to provide
-a list from which to choose. This function usually reads the file
-@file{/etc/mime.types}.
-
-Whether the media type is chosen automatically, or you choose it from
-a list, use the type that seems to match best the file that you are
-including. In the case of binaries, the media type
-@samp{application/x-executable} can be useful. If you can't find an
-appropriate media type, use @samp{text/plain} for text messages and
-@samp{application/octet-stream} for everything else.
-
-@cindex content description
-@cindex MIME, content description
-
-You are also sometimes asked for a @dfn{content description}. This is
-simply an optional brief phrase, in your own words, that describes the
-object. If you don't care to enter a content description, just press
-return and none will be included; however, a reader may skip over
-multimedia fields unless the content description is compelling.
-
-You can also create your own @sc{mime} body parts. In the following
-example, I describe how you can create and edit a @samp{text/enriched}
-body part to liven up your plain text messages with boldface,
-underlining, and italics. I include an Emacs function which inserts
-enriched text tags.
-
-@smalllisp
-@group
-(defvar enriched-text-types '(("b" . "bold") ("i" . "italic")
- ("u" . "underline")
- ("s" . "smaller") ("B" . "bigger")
- ("f" . "fixed")
- ("c" . "center"))
- "Alist of (final-character . tag) choices for add-enriched-text.
-Additional types can be found in RFC 1563.")
-
-(defun add-enriched-text (begin end)
- "Add enriched text tags around region.
-The tag used comes from the list enriched-text-types and is
-specified by the last keystroke of the command. When called from Lisp,
-arguments are BEGIN and END@."
- (interactive "r")
- ;; @r{Set type to the tag indicated by the last keystroke.}
- (let ((type (cdr (assoc (char-to-string (logior last-input-char ?@w{`}))
- enriched-text-types))))
- (save-restriction ; @r{restores state from narrow-to-region}
- (narrow-to-region begin end) ; @r{narrow view to region}
- (goto-char (point-min)) ; @r{move to beginning of text}
- (insert "<" type ">") ; @r{insert beginning tag}
- (goto-char (point-max)) ; @r{move to end of text}
- (insert "</" type ">")))) ; @r{insert terminating tag}
-@i{Emacs function for entering enriched text}
-
-@end group
-@end smalllisp
-
-To use the function @code{add-enriched-text}, first add it to
-@file{~/.emacs} and create key bindings for it (@pxref{Composing}).
-
-Then, in your plain text message, set the mark with @kbd{C-@@} or
-@kbd{C-@key{SPC}}, type in the text to be highlighted, and type @kbd{C-c t
-b}. This adds @samp{<bold>} where you set the mark and adds
-@samp{</bold>} at the location of your cursor, giving you something
-like: @samp{You should be <bold>very</bold>}.
-
-Before sending this message, use @kbd{C-c C-m C-m}
-(@code{mh-mml-to-mime})@footnote{Use @kbd{C-c C-e}
-(@code{mh-mh-to-mime}) if you're using MH-style directives.} to add
-MIME header fields. Then replace @samp{text/plain} with
-@samp{text/enriched} in the @samp{Content-Type:} header field.
-
-You may also be interested in investigating @code{sgml-mode}.
-
-@subheading Including Files
-
-@cindex attachments, inserting
-@cindex images
-@cindex MIME, images
-@cindex MIME, sound
-@cindex MIME, video
-@cindex sound
-@cindex video
-@findex mh-compose-insertion
-@kindex C-c C-m C-i
-@kindex C-c C-m i
-@vindex mh-compose-insertion
-
-Binaries, images, sound, and video can be inserted in your message
-with the command @kbd{C-c C-m C-i} (@code{mh-compose-insertion}). You
-are prompted for the filename containing the object, the media type if
-it cannot be determined automatically, and a content description. If
-you're using MH-style directives, you will also be prompted for
-additional attributes.
-
-@subheading Forwarding Multimedia Messages
-
-@findex mh-compose-forward
-@kindex C-c C-m C-f
-@kindex C-c C-m f
-
-Mail may be forwarded with @sc{mime} using the command @kbd{C-c C-m
-C-f} (@code{mh-compose-forward}). You are prompted for a content
-description, the name of the folder in which the messages to forward
-are located, and a range of messages, which defaults to the current
-message in that folder. @xref{Ranges}.
-
-@subheading Including an FTP Reference
-
-@cindex @command{ftp}
-@cindex MIME, @command{ftp}
-@cindex Unix commands, @command{ftp}
-@findex mh-mh-compose-anon-ftp
-@kindex C-c C-m C-g
-@kindex C-c C-m g
-
-You can have your message initiate an @command{ftp} transfer when the
-recipient reads the message. To do this, use the command @kbd{C-c C-m
-C-g} (@code{mh-mh-compose-anon-ftp}). You are prompted for the remote
-host and filename, the media type, and the content description.
-
-@subheading Including tar Files
-
-@cindex @command{ftp}
-@cindex @command{tar}
-@cindex MIME, @command{ftp}
-@cindex MIME, @command{tar}
-@cindex Unix commands, @command{ftp}
-@cindex Unix commands, @command{tar}
-@findex mh-mh-compose-anon-ftp
-@findex mh-mh-compose-external-compressed-tar
-@kindex C-c C-m C-g
-@kindex C-c C-m C-t
-@kindex C-c C-m t
-
-If the remote file is a compressed tar file, you can use @kbd{C-c C-m
-C-t} (@code{mh-mh-compose-external-compressed-tar}). Then, in addition
-to retrieving the file via anonymous @emph{ftp} as per the command
-@kbd{C-c C-m C-g} (@code{mh-mh-compose-anon-ftp}), the file will also
-be uncompressed and untarred. You are prompted for the remote host and
-filename and the content description.
-
-@subheading Including Other External Files
-
-@findex mh-mh-compose-external-type
-@kindex C-c C-m C-x
-@kindex C-c C-m x
-
-The command @kbd{C-c C-m C-x} (@code{mh-mh-compose-external-type}) is
-a general utility for referencing external files. In fact, all of the
-other commands that insert tags to access external files call this
-command. You are prompted for the access type, remote host and
-filename, and content type. If you provide a prefix argument, you are
-also prompted for a content description, attributes, parameters, and a
-comment.
-
-@subheading Previewing Multimedia Messages
-
-When you are finished editing a @sc{mime} message, it might look like this:
-
-@cartouche
-@smallexample
-3 t08/24 root received fax files on Wed Aug 24 11:00:
-4+t08/24 To:wohler Test<<This is a test message to get the
-
-
-
-
-
---:%% @{+inbox@} 4 msgs (1-4) Bot L4 (MH-Folder Show)---------------
-To: wohler
-cc:
-Subject: Test of MIME
---------
-Here is the SETI@@Home logo:
-
-<#part type="image/x-xpm" filename="~/lib/images/setiathome.xpm"
-disposition=inline description="SETI@@home logo">
-<#/part>
---:** @{draft@} All L8 (MH-Letter)----------------------------------
-
-@end smallexample
-@end cartouche
-@i{MH-E @sc{mime} draft}
-
-@findex mh-mml-to-mime
-@kindex C-c C-m C-m
-@kindex C-c C-m m
-
-Typically, you send a message with attachments just like any other
-message (@pxref{Sending Message}).
-
-@findex mh-mml-to-mime
-@kindex C-c C-m C-m
-
-However, you may take a sneak preview of the @sc{mime} encoding if you
-wish by running the command @kbd{C-c C-m C-m} (@code{mh-mml-to-mime}).
-The following screen shows the @sc{mime} encoding specified by the
-tags. You can see why mail user agents are usually built to hide these
-details from the user.
-
-@cartouche
-@smallexample
-To: wohler
-cc:
-Subject: Test of MIME
-X-Mailer: MH-E 8.1; nmh 1.1; GNU Emacs 23.1
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary="=-=-="
---------
---=-=-=
-
-Here is the SETI@@Home logo:
-
-
---=-=-=
-Content-Type: image/x-xpm
-Content-Disposition: inline; filename=setiathome.xpm
-Content-Transfer-Encoding: base64
-Content-Description: SETI@@home logo
-
-LyogWFBNICovCnN0YXRpYyBjaGFyICogc2V0aWF0aG9tZV94cG1bXSA9IHsKIjQ1IDQ1IDc2N
---:-- @{draft@} Top L1 (MH-Letter)----------------------------------
-
-@end smallexample
-@end cartouche
-@i{MH-E @sc{mime} draft ready to send}
-
-@cindex undo effects of @code{mh-mml-to-mime}
-
-This action can be undone by running @kbd{C-_} (@code{undo}).
-
-@cindex @command{mhbuild}
-@cindex @command{mhn}
-@cindex MH commands, @command{mhbuild}
-@cindex MH commands, @command{mhn}
-@cindex undo effects of @code{mh-mh-to-mime}
-@findex mh-mh-to-mime
-@findex mh-mh-to-mime-undo
-@kindex C-c C-e
-@kindex C-c C-m C-m
-@kindex C-c C-m C-u
-@kindex C-c C-m u
-
-If you're using MH-style directives, use @kbd{C-c C-e}
-(@code{mh-mh-to-mime}) instead of @kbd{C-c C-m C-m}. This runs the
-command @command{mhbuild} (@command{mhn}) on the message which expands
-the tags@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/usimim.html#SeMIMa, Sending MIME Mail} in
-the MH book.}. This action can be undone by running @kbd{C-c C-m C-u}
-(@code{mh-mh-to-mime-undo}), which works by reverting to a backup
-file. You are prompted to confirm this action, but you can avoid the
-confirmation by adding an argument (for example, @kbd{C-u C-c C-m
-C-u}).
-
-@kindex C-c C-e
-@vindex mh-mh-to-mime-args
-
-If you wish to pass additional arguments to @command{mhbuild}
-(@command{mhn}) to affect how it builds your message, use the option
-@code{mh-mh-to-mime-args}. For example, you can build a consistency
-check into the message by setting @code{mh-mh-to-mime-args} to
-@samp{-check}. The recipient of your message can then run
-@samp{mhbuild -check} on the message---@command{mhbuild}
-(@command{mhn}) will complain if the message has been corrupted on the
-way. The command @kbd{C-c C-e} only consults this option when given a
-prefix argument (as in @kbd{C-u C-c C-e}).
-
-@kindex C-c C-e
-@vindex mh-mh-to-mime-hook
-
-The hook @code{mh-mh-to-mime-hook} is called after the message has
-been formatted by @kbd{C-c C-e}.
-
-@node Sending PGP
-@section Signing and Encrypting Messages
-
-@cindex signing messages
-@cindex encrypting messages
-@cindex RFC 3156
-
-MH-E can sign and encrypt messages as defined in
-@uref{https://www.rfc-editor.org/rfc/rfc3156.txt, RFC 3156}. If you
-should choose to sign or encrypt your message, use one of the
-following commands to do so any time before sending your message.
-
-@findex mh-mml-secure-message-encrypt
-@findex mh-mml-secure-message-sign
-@findex mh-mml-secure-message-signencrypt
-@kindex C-c C-m C-e
-@kindex C-c C-m C-s
-@kindex C-c C-m e e
-@kindex C-c C-m e s
-@kindex C-c C-m s e
-@kindex C-c C-m s s
-
-The command @kbd{C-c C-m C-s} (@code{mh-mml-secure-message-sign})
-inserts the following tag:
-
-@smallexample
-<#secure method=pgpmime mode=sign>
-@end smallexample
-
-This is used to sign your message digitally. Likewise, the command
-@kbd{C-c C-m C-e} (@code{mh-mml-secure-message-encrypt}) inserts the
-following tag:
-
-@smallexample
-<#secure method=pgpmime mode=encrypt>
-@end smallexample
-
-This is used to encrypt your message. Finally, the command @kbd{C-c
-C-m s e} (@code{mh-mml-secure-message-signencrypt}) inserts the
-following tag:
-
-@smallexample
-<#secure method=pgpmime mode=signencrypt>
-@end smallexample
-
-@findex mh-mml-unsecure-message
-@kindex C-c C-m C-n
-@kindex C-c C-m n
-@vindex mh-mml-method-default
-
-This is used to sign and encrypt your message. In each of these cases,
-a proper multipart message is created for you when you send the
-message. Use the command @kbd{C-c C-m C-n}
-(@code{mh-mml-unsecure-message}) to remove these tags. Use a prefix
-argument (as in @kbd{C-u C-c C-m s e}) to be prompted for one of the
-possible security methods (see @code{mh-mml-method-default}).
-
-@vindex mh-mml-method-default
-
-The option @code{mh-mml-method-default} is used to select between a
-variety of mail security mechanisms. The default is @samp{PGP (MIME)}
-if it is supported; otherwise, the default is @samp{None}. Other
-mechanisms include vanilla @samp{PGP} and @samp{S/MIME}.
-
-@node Checking Recipients
-@section Checking Recipients
-
-@cindex @file{*MH-E Recipients*}
-@cindex @command{whom}
-@cindex MH commands, @command{whom}
-@cindex buffers, @file{*MH-E Recipients*}
-@cindex checking recipients
-@cindex recipients, checking
-@findex mh-check-whom
-@kindex C-c C-w
-
-The command @kbd{C-c C-w} (@code{mh-check-whom}) expands aliases so
-you can check the actual address(es) in the alias. A new buffer named
-@file{*MH-E Recipients*} is created with the output of @command{whom}
-(@pxref{Miscellaneous})@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/senove.html#WhaPro, What now?---and the
-whatnow Program} in the MH book.}.
-
-@node Sending Message
-@section Sending a Message
-
-@cindex buffers, @file{*MH-E Mail Delivery*}
-@cindex @file{*MH-E Mail Delivery*}
-@cindex sending mail
-@findex mh-send-letter
-@kindex C-c C-c
-
-When you are all through editing a message, you send it with the
-command @kbd{C-c C-c} (@code{mh-send-letter}). You can give a prefix
-argument (as in @kbd{C-u C-c C-c}) to monitor the first stage of the
-delivery; this output can be found in a buffer called @file{*MH-E Mail
-Delivery*} (@pxref{Miscellaneous}).
-
-@cindex sending mail
-@cindex spell check
-@findex ispell-message
-@kindex C-c C-c
-@vindex mh-before-send-letter-hook
-
-The hook @code{mh-before-send-letter-hook} is run at the beginning of
-the command @kbd{C-c C-c}. For example, if you want to check your
-spelling in your message before sending, add the function
-@code{ispell-message}.
-
-@cindex @command{send}
-@cindex MH commands, @command{send}
-@vindex mh-send-prog
-
-In case the MH @command{send} program@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/sensen.html, Sending Some Mail: comp send}
-in the MH book.} is installed under a different name, use
-@code{mh-send-prog} to tell MH-E the name.
-
-The hook @code{mh-annotate-msg-hook} is run after annotating the
-message and scan line (@pxref{Sending Mail}).
-
-@node Killing Draft
-@section Killing the Draft
-
-@cindex killing draft
-@findex kill-buffer
-@findex mh-fully-kill-draft
-@kindex C-c C-q
-@kindex C-x k
-
-If for some reason you are not happy with the draft, you can use the
-command @kbd{C-c C-q} (@code{mh-fully-kill-draft}) to kill the draft
-buffer and delete the draft message. Use the command @kbd{C-x k}
-(@code{kill-buffer}) if you don't want to delete the draft message.
-
-@node Aliases
-@chapter Aliases
-
-@cindex aliases
-
-MH aliases are used in the same way in MH-E as they are in MH@. Any
-alias listed as a recipient will be expanded when the message is sent.
-This chapter discusses other things you can do with aliases in MH-E.
-
-@cindex MH-Letter mode
-@cindex modes, MH-Letter
-
-The following commands are available in MH-Letter mode with the
-exception of @code{mh-alias-reload} which can be called from anywhere.
-
-@table @kbd
-@kindex SPC
-@findex mh-letter-complete-or-space
-@item @key{SPC}
-Perform completion or insert space (@code{mh-letter-complete-or-space}).
-@c -------------------------
-@kindex M-TAB
-@findex mh-letter-complete
-@item M-@key{TAB}
-Perform completion on header field or word preceding point
-(@code{mh-letter-complete}).
-@c -------------------------
-@findex mh-alias-apropos
-@item mh-alias-apropos
-Show all aliases or addresses that match a regular expression.
-@c -------------------------
-@findex mh-alias-grab-from-field
-@item mh-alias-grab-from-field
-Add alias for the sender of the current message
-@c -------------------------
-@findex mh-alias-reload
-@item mh-alias-reload
-Reload MH aliases.
-@end table
-
-@cindex @samp{mh-alias} customization group
-@cindex customization group, @samp{mh-alias}
-
-The @samp{mh-alias} customization group contains options associated
-with aliases.
-
-@vtable @code
-@item mh-alias-completion-ignore-case-flag
-On means don't consider case significant in MH alias completion
-(default: @samp{on}).
-@c -------------------------
-@item mh-alias-expand-aliases-flag
-On means to expand aliases entered in the minibuffer (default:
-@samp{off}).
-@c -------------------------
-@item mh-alias-flash-on-comma
-Specify whether to flash address or warn on translation (default: @samp{Flash
-but Don't Warn If No Alias}).
-@c -------------------------
-@item mh-alias-insert-file
-Filename used to store a new MH-E alias (default: @samp{Use Aliasfile
-Profile Component}).
-@c -------------------------
-@item mh-alias-insertion-location
-Specifies where new aliases are entered in alias files (default:
-@samp{Alphabetical}).
-@c -------------------------
-@item mh-alias-local-users
-If @samp{on}, local users are added to alias completion (default:
-@samp{on}).
-@c -------------------------
-@item mh-alias-local-users-prefix
-String prefixed to the real names of users from the password file
-(default: @code{"local."}.
-@c -------------------------
-@item mh-alias-passwd-gecos-comma-separator-flag
-On means the GECOS field in the password file uses a comma separator
-(default: @samp{on}).
-@end vtable
-
-The following hook is available.
-
-@vtable @code
-@item mh-alias-reloaded-hook
-Hook run by @code{mh-alias-reload} after loading aliases (default:
-@code{nil}).
-@end vtable
-
-@subheading Adding Addresses to Draft
-
-You can use aliases when you are adding recipients to a message.
-
-@findex minibuffer-complete
-@kindex TAB
-@vindex mh-alias-expand-aliases-flag
-@vindex mh-compose-prompt-flag
-
-In order to use minibuffer prompting for recipients and the subject
-line in the minibuffer, turn on the option
-@code{mh-compose-prompt-flag} (@pxref{Composing}), and use the
-@key{TAB} (@code{minibuffer-complete}) command to complete aliases
-(and optionally local logins) when prompted for the recipients. Turn
-on the option @code{mh-alias-expand-aliases-flag} if you want these
-aliases to be expanded to their respective addresses in the draft.
-
-@findex mh-letter-complete
-@findex mh-letter-complete-or-space
-@kindex SPC
-@kindex M-TAB
-
-Otherwise, you can complete aliases in the header of the draft with
-@kbd{M-@key{TAB}} (@code{mh-letter-complete}) or @key{SPC}
-(@code{mh-letter-complete-or-space}).
-
-@vindex mh-alias-completion-ignore-case-flag
-
-As MH ignores case in the aliases, so too does MH-E@. However, you may
-turn off the option @code{mh-alias-completion-ignore-case-flag} to
-make case significant which can be used to segregate completion of
-your aliases. You might use uppercase for mailing lists and lowercase
-for people. For example, you might have:
-
-@smallexample
-mark.baushke: Mark Baushke <mdb@@stop.mail-abuse.org>
-MH-E: MH-E Mailing List <mh-e-devel@@stop.mail-abuse.org>
-@end smallexample
-
-When this option is turned off, if you were to type @kbd{M} in the
-@samp{To:} field and then @kbd{M-@key{TAB}}, then you'd get the list;
-if you started with @kbd{m} and then entered @kbd{M-@key{TAB}}, then
-you'd get Mark's address. Note that this option affects completion
-only. If you were to enter @kbd{Mark.Baushke}, it would still be
-identified with your @samp{mark.baushke} alias.
-
-@findex mh-alias-minibuffer-confirm-address
-@findex mh-letter-confirm-address
-@vindex mh-alias-flash-on-comma
-@vindex mh-compose-prompt-flag
-
-To verify that the alias you've entered is valid, the alias will be
-displayed in the minibuffer when you type a comma
-(@code{mh-letter-confirm-address} or
-@code{mh-alias-minibuffer-confirm-address} if the option
-@code{mh-compose-prompt-flag} is turned on). @xref{Composing}. This
-behavior can be controlled with the option
-@code{mh-alias-flash-on-comma} which provides three choices:
-@samp{Flash but Don't Warn If No Alias}, @samp{Flash and Warn If No
-Alias}, and @samp{Don't Flash Nor Warn If No Alias}.
-
-For another way to verify the alias expansion, see @ref{Checking
-Recipients}.
-
-@subheading Loading Aliases
-
-@cindex @command{ali}
-@cindex @file{/etc/nmh/MailAliases}
-@cindex @samp{Aliasfile} MH profile component
-@cindex MH commands, @command{ali}
-@cindex MH profile component, @samp{Aliasfile}
-@cindex files, @file{/etc/nmh/MailAliases}
-
-MH-E loads aliases for completion and folder name hints from various
-places. It uses the MH command @command{ali}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/mh.html, MH Aliases} in the MH book.} to
-read aliases from the files listed in the profile component
-@samp{Aliasfile:} as well as system-wide aliases (for example,
-@file{/etc/nmh/MailAliases}).
-
-@cindex @file{/etc/passwd}
-@cindex files, @file{/etc/passwd}
-
-In addition, aliases are created from @file{/etc/passwd} entries with
-a user ID larger than a magical number, typically 200. This can be a
-handy tool on a machine where you and co-workers exchange messages.
-These aliases have the form @samp{local.@var{first.last}} if a real
-name is present in the password file. Otherwise, the alias will have
-the form @samp{local.@var{login}}.
-
-@vindex mh-alias-local-users-prefix
-
-The prefix @samp{local.} can be modified via the option
-@code{mh-alias-local-users-prefix}. This option can also be set to
-@samp{Use Login}.
-
-For example, consider the following password file entry:
-
-@smallexample
-psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh
-@end smallexample
-
-@vindex mh-alias-local-users-prefix
-
-The following settings of option @code{mh-alias-local-users-prefix}
-will produce the associated aliases:
-
-@table @code
-@item "local."
-local.peter.galbraith
-@c -------------------------
-@item ""
-peter.galbraith
-@c -------------------------
-@item Use Login
-psg
-@end table
-
-@vindex mh-alias-passwd-gecos-comma-separator-flag
-
-In the example above, commas are used to separate different values
-within the so-called GECOS field. This is a fairly common usage.
-However, in the rare case that the GECOS field in your password file
-is not separated by commas and whose contents may contain commas, you
-can turn the option @code{mh-alias-passwd-gecos-comma-separator-flag}
-off.
-
-@cindex NIS, obtaining local aliases from
-@cindex @samp{ypcat passwd}
-@vindex mh-alias-local-users
-
-If you're on a system with thousands of users you don't know, and the
-loading of local aliases slows MH-E down noticeably, then the local
-alias feature can be disabled by turning off the option
-@code{mh-alias-local-users}. This option also takes a string which is
-executed to generate the password file. For example, use @samp{ypcat
-passwd} to obtain the NIS password file.
-
-@findex mh-alias-reload
-@vindex mh-alias-reloaded-hook
-
-Since aliases are updated frequently, MH-E reloads aliases
-automatically whenever an alias lookup occurs if an alias source has
-changed. However, you can reload your aliases manually by calling the
-command @kbd{M-x mh-alias-reload} directly. This command runs
-@code{mh-alias-reloaded-hook} after the aliases have been loaded.
-
-@subheading Adding Aliases
-
-In the past, you have manually added aliases to your alias file(s)
-listed in your @samp{Aliasfile:} profile component. MH-E provides
-other methods for maintaining your alias file(s).
-
-@findex mh-alias-add-alias
-
-You can use the @kbd{M-x mh-alias-add-alias} command which will prompt
-you for the alias and address that you would like to add. 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
-(@pxref{Folder Selection}).
-
-Earlier, the alias prefix @samp{local} was presented. You can use
-other prefixes to organize your aliases or disambiguate entries. You
-might use prefixes for locales, jobs, or activities. For example, I
-have:
-
-@smallexample
-@group
-; Work
-attensity.don.mitchell: Don Mitchell <dmitchell@@stop.mail-abuse.com>
-isharp.don.mitchell: Don Mitchell <donaldsmitchell@@stop.mail-abuse.com>
-...
-; Sport
-diving.ken.mayer: Ken Mayer <kmayer@@stop.mail-abuse.com>
-sailing.mike.maloney: Mike Maloney <mmaloney@@stop.mail-abuse.com>
-...
-; Personal
-ariane.kolkmann: Ariane Kolkmann <ArianeKolkmann@@stop.mail-abuse.com>
-...
-@end group
-@end smallexample
-
-Using prefixes instead of postfixes helps you explore aliases during
-completion. If you forget the name of an old dive buddy, you can enter
-@samp{div} and then @key{SPC} to get a listing of all your dive buddies.
-
-@findex mh-alias-add-address-under-point
-@findex mh-alias-grab-from-field
-
-An alias for the sender of the current message is added automatically
-by clicking on the @samp{Grab From alias} tool bar button or by running
-the @kbd{M-x mh-alias-grab-from-field} command. Aliases for other
-recipients of the current message are added by placing your cursor
-over the desired recipient and giving the @kbd{M-x
-mh-alias-add-address-under-point} command.
-
-@vindex mh-alias-insert-file
-@vindex mh-alias-insertion-location
-
-The options @code{mh-alias-insert-file} and
-@code{mh-alias-insertion-location} controls how and where these aliases
-are inserted.
-
-@vindex mh-alias-insert-file
-
-The default setting of option @code{mh-alias-insert-file} is @samp{Use
-Aliasfile Profile Component}. This option can also hold the name of a
-file or a list a file names. If this option is set to a list of file
-names, or the @samp{Aliasfile:} profile component contains more than
-one file name, MH-E will prompt for one of them.
-
-@vindex mh-alias-insertion-location
-
-The option @code{mh-alias-insertion-location} is set to
-@samp{Alphabetical} by default. If you organize your alias file in
-other ways, then the settings @samp{Top} and @samp{Bottom} might be
-more appropriate.
-
-@subheading Querying Aliases
-
-@cindex regular expressions, @code{mh-alias-apropos}
-@findex mh-alias-apropos
-
-If you can't quite remember an alias, you can use @kbd{M-x
-mh-alias-apropos} to show all aliases or addresses that match a
-regular expression
-@ifnothtml
-(@pxref{Regexps, , Syntax of Regular Expressions, emacs, The
-GNU Emacs Manual}).
-@end ifnothtml
-@ifhtml
-(see the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Regexps.html,
-Syntax of Regular Expressions} in
-@cite{The GNU Emacs Manual}).
-@end ifhtml
-
-@node Identities
-@chapter Identities
-
-@cindex identities
-@cindex multiple personalities
-
-MH-E supports the concept of multiple personalities or identities.
-This means that you can easily have a different header and signature
-at home and at work.
-
-@cindex @samp{Identity} menu
-@cindex menu, @samp{Identity}
-
-A couple of commands are used to insert identities in MH-Letter mode
-which are also found in the @samp{Identity} menu.
-
-@table @kbd
-@kindex C-c C-d
-@findex mh-insert-identity
-@item C-c C-d
-Insert fields specified by given identity (@code{mh-insert-identity}).
-@c -------------------------
-@cindex @samp{Identity > Insert Auto Fields} menu item
-@cindex menu item, @samp{Identity > Insert Auto Fields}
-@kindex C-c M-d
-@findex mh-insert-auto-fields
-@item C-c M-d
-Insert custom fields if recipient found in @code{mh-auto-fields-list}
-(@code{mh-insert-auto-fields}).
-@end table
-
-@cindex @samp{mh-identity} customization group
-@cindex customization group, @samp{mh-identity}
-
-The @samp{mh-identity} customization group contains the following
-options.
-
-@vtable @code
-@item mh-auto-fields-list
-List of recipients for which header lines are automatically inserted
-(default: @code{nil}).
-@c -------------------------
-@item mh-auto-fields-prompt-flag
-On means to prompt before sending if fields inserted (default:
-@samp{on})
-@c -------------------------
-@item mh-identity-default
-Default identity to use when @code{mh-letter-mode} is called (default:
-@samp{None}).
-@c -------------------------
-@item mh-identity-handlers
-Handler functions for fields in @code{mh-identity-list}.
-@c -------------------------
-@item mh-identity-list
-List of identities (default: @code{nil}).
-@end vtable
-
-Some of the common header fields that people change depending on the
-context are the @samp{From:} and @samp{Organization:} fields, as well
-as the signature.
-
-@vindex mh-identity-list
-
-This is done by customizing the option @code{mh-identity-list}. In the
-customization buffer for this option, click on the @samp{INS} button
-and enter a label such as @samp{Home} or @samp{Work}. Then click on
-the @samp{INS} button with the label @samp{Add at least one item
-below}. The @samp{Value Menu} has the following menu items:
-
-@table @samp
-@cindex header field, @samp{From}
-@cindex @samp{From} header field
-@item From Field
-Specify an alternate @samp{From:} header field. You must include a
-valid email address. A standard format is @samp{First Last
-<login@@host.domain>}. If you use an initial with a period, then you
-must quote your name as in @samp{"First I. Last"
-<login@@host.domain>}.
-@c -------------------------
-@cindex header field, @samp{Organization}
-@cindex @samp{Organization} header field
-@item Organization Field
-People usually list the name of the company where they work here.
-@c -------------------------
-@item Other Field
-Set any arbitrary header field and value here. Unless the header field
-is a standard one, precede the name of your field's label with
-@samp{X-}, as in @samp{X-Fruit-of-the-Day:}.
-@c -------------------------
-@item Attribution Verb
-This value overrides the setting of
-@code{mh-extract-from-attribution-verb}. @xref{Inserting Letter}.
-@c -------------------------
-@cindex signature
-@vindex mh-signature-file-name
-@item Signature
-Set your signature with this item. You can specify the contents of
-@code{mh-signature-file-name}, a file, or a function.
-@xref{Signature}.
-@c -------------------------
-@item GPG Key ID
-Specify a different key to sign or encrypt messages.
-@end table
-
-@cindex Identity menu
-@cindex menu, Identity
-@findex mh-insert-identity
-@kindex C-c C-d
-
-You can select the identities you have added via the menu called
-@samp{Identity} in the MH-Letter buffer. You can also use @kbd{C-c
-C-d} (@code{mh-insert-identity}). To clear the fields and signature
-added by the identity, select the @samp{None} identity.
-
-@cindex menu item, @samp{Identity > Customize Identities}
-@cindex menu item, @samp{Identity > Save as Default}
-@cindex menu item, @samp{Identity > Set Default for Session}
-@cindex @samp{Identity > Customize Identities} menu item
-@cindex @samp{Identity > Save as Default} menu item
-@cindex @samp{Identity > Set Default for Session} menu item
-@vindex mh-identity-default
-
-The @samp{Identity} menu contains two other items to save you from
-having to set the identity on every message. The menu item @samp{Set
-Default for Session} can be used to set the default identity to the
-current identity until you exit Emacs. The menu item @samp{Save as
-Default} sets the option @code{mh-identity-default} to the current
-identity setting. You can also customize the option
-@code{mh-identity-default} in the usual fashion. If you find that you
-need to add another identity, the menu item @samp{Customize
-Identities} is available for your convenience.
-
-@cindex regular expressions, @code{mh-auto-fields-list}
-@vindex mh-auto-fields-list
-
-The option @code{mh-auto-fields-list} can also be used to set the
-identity depending on the recipient to provide even more control. To
-customize @code{mh-auto-fields-list}, click on the @samp{INS} button
-and enter a regular expression for the recipient's address
-@ifnothtml
-(@pxref{Regexps, , Syntax of Regular Expressions, emacs, The
-GNU Emacs Manual}).
-@end ifnothtml
-@ifhtml
-(see the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Regexps.html,
-Syntax of Regular Expressions} in
-@cite{The GNU Emacs Manual}).
-@end ifhtml
-Click on the @samp{INS} button with the @samp{Add at least one item
-below} label. The @samp{Value Menu} contains the following menu items:
-
-@table @samp
-@item Identity
-Select an identity from those configured in @code{mh-identity-list}.
-All of the information for that identity will be added if the
-recipient matches.
-@c -------------------------
-@cindex @samp{Fcc} header field
-@cindex header field, @samp{Fcc}
-@item Fcc Field
-Insert an @samp{Fcc:} header field with the folder you provide. When
-you send the message, MH will put a copy of your message in this
-folder.
-@c -------------------------
-@cindex @samp{Mail-Followup-To} header field
-@cindex header field, @samp{Mail-Followup-To}
-@item Mail-Followup-To Field
-Insert an @samp{Mail-Followup-To:} header field with the recipients
-you provide. If the recipient's mail user agent supports this header
-field@footnote{@samp{Mail-Followup-To:} is supported by nmh.}, then
-their replies will go to the addresses listed. This is useful if their
-replies go both to the list and to you and you don't have a mechanism
-to suppress duplicates. If you reply to someone not on the list, you
-must either remove the @samp{Mail-Followup-To:} field, or ensure the
-recipient is also listed there so that he receives replies to your
-reply.
-@c -------------------------
-@item Other Field
-Other header fields may be added using this menu item.
-@end table
-
-@findex mh-insert-auto-fields
-@kindex C-c M-d
-@vindex mh-auto-fields-prompt-flag
-
-These fields can only be added after the recipient is known. Because
-you can continue to add recipients as you edit the draft, MH-E waits
-until the message is sent to perform the auto-insertions. This seems
-strange at first, but you'll get used to it. There are two ways to
-help you feel that the desired fields are added. The first is the
-action when the message is sent: if any fields are added
-automatically, you are given a chance to see and to confirm these
-fields before the message is actually sent. You can do away with this
-confirmation by turning off the option
-@code{mh-auto-fields-prompt-flag}. The second method is manual: once
-the header contains one or more recipients, you may run the command
-@kbd{C-c M-d} (@code{mh-insert-auto-fields}) or choose the
-@samp{Identity -> Insert Auto Fields} menu item to insert these fields
-manually. However, if you use this command, the automatic insertion
-when the message is sent is disabled.
-
-@vindex mh-auto-fields-list
-@vindex mh-identity-list
-
-You should avoid using the same header field in
-@code{mh-auto-fields-list} and @code{mh-identity-list} definitions
-that may apply to the same message as the result is undefined.
-
-@vindex mh-identity-handlers
-@vindex mh-identity-list
-
-The option @code{mh-identity-handlers} is used to change the way that
-fields, signatures, and attributions in @code{mh-identity-list} are
-added. To customize @code{mh-identity-handlers}, replace the name of
-an existing handler function associated with the field you want to
-change with the name of a function you have written. You can also
-click on an @samp{INS} button and insert a field of your choice and
-the name of the function you have written to handle it.
-
-@vindex mh-identity-list
-
-The @samp{Field} field can be any field that you've used in your
-@code{mh-identity-list}. The special fields @samp{:attribution-verb},
-@samp{:signature}, or @samp{:pgg-default-user-id} are used for the
-@code{mh-identity-list} choices @samp{Attribution Verb},
-@samp{Signature}, and @samp{GPG Key ID} respectively.
-
-The handler associated with the @samp{:default} field is used when no
-other field matches.
-
-The handler functions are passed two or three arguments: the field
-itself (for example, @samp{From}), or one of the special fields (for
-example, @samp{:signature}), and the action @samp{'remove} or
-@samp{'add}. If the action is @samp{'add}, an additional argument
-containing the value for the field is given.
-
-@node Speedbar
-@chapter The Speedbar
-
-@cindex folder navigation
-@cindex speedbar
-@findex mh-visit-folder
-@findex speedbar
-@kindex F v
-@kindex mouse-2
-
-You can also use the speedbar
-@ifnothtml
-(@pxref{Speedbar, , Speedbar Frames, emacs, The GNU Emacs Manual},)
-@end ifnothtml
-@ifhtml
-(see the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Speedbar.html,
-Speedbar Frames} in @cite{The GNU Emacs Manual})
-@end ifhtml
-to view your folders. To bring up the speedbar, run @kbd{M-x speedbar
-@key{RET}}. You will see a new frame appear with all of your MH
-folders. Folders with unseen messages appear in boldface. Click on a
-folder name with @kbd{mouse-2} to visit that folder in a similar
-fashion to the command @kbd{F v} (@code{mh-visit-folder})
-(@pxref{Folders}). Click on the @samp{+} icon to expand and view the
-sub-folders of that folder.
-
-The speedbar can be manipulated with the keyboard as well. Use the
-Emacs navigational keys (like the arrow keys, or @kbd{C-n}) to move
-the cursor over the desired folder and then use the shortcuts for the
-menu items listed in the table below.
-
-@table @asis
-@findex mh-speed-view
-@item @samp{Visit Folder} (@key{RET})
-Visits the selected folder just as if you had used @kbd{F v}
-(@code{mh-speed-view}).
-@c -------------------------
-@findex mh-speed-expand-folder
-@item @samp{Expand Nested Folders} (@kbd{+})
-Expands the selected folder in the speedbar, exposing the children
-folders inside it (@code{mh-speed-expand-folder}).
-@c -------------------------
-@findex mh-speed-contract-folder
-@item @samp{Contract Nested Folders} (@kbd{-})
-Contracts or collapses the selected folder in the speedbar, hiding the
-children folders inside it (@code{mh-speed-contract-folder}).
-@c -------------------------
-@findex mh-speed-refresh
-@item @samp{Refresh Speedbar} (@kbd{r})
-Regenerates the list of folders in the speedbar. Run this command if
-you've added or deleted a folder, or want to update the unseen message
-count before the next automatic update (@code{mh-speed-refresh}).
-@end table
-
-@findex delete-frame
-@kindex C-x 5 0
-@kindex mouse-3
-
-You can click on @kbd{mouse-3} to bring up a context menu that
-contains these items. Dismiss the speedbar with @kbd{C-x 5 0}
-(@code{delete-frame}).
-
-@cindex @command{flists}
-@cindex MH commands, @command{flists}
-@cindex @samp{mh-speedbar} customization group
-@cindex customization group, @samp{mh-speedbar}
-
-The MH-E speedbar uses the MH command @command{flists}@footnote{See
-the section @uref{@value{MH-BOOK-HOME}/morseq.html#flist, Searching for
-Sequences with flist} in the MH book.} to generate the list of
-folders. The @samp{mh-speedbar} customization group contains the
-following option which controls how often the speedbar calls
-@command{flists}.
-
-@vtable @code
-@item mh-speed-update-interval
-Time between speedbar updates in seconds (default: 60). Set to 0 to
-disable automatic update.
-@end vtable
-
-You can modify the appearance of the folders in the speedbar by
-customizing the following faces.
-
-@vtable @code
-@item mh-speedbar-folder
-Basic folder face.
-@c -------------------------
-@item mh-speedbar-folder-with-unseen-messages
-Folder face when folder contains unread messages.
-@c -------------------------
-@item mh-speedbar-selected-folder
-Selected folder face.
-@c -------------------------
-@item mh-speedbar-selected-folder-with-unseen-messages
-Selected folder face when folder contains unread messages.
-@end vtable
-
-@node Menu Bar
-@chapter The Menu Bar
-
-@cindex @samp{Folder} menu
-@cindex @samp{Identity} menu
-@cindex @samp{Letter} menu
-@cindex @samp{Message} menu
-@cindex @samp{Search} menu
-@cindex @samp{Sequence} menu
-@cindex Folder menu
-@cindex Identity menu
-@cindex Letter menu
-@cindex MH-Folder mode
-@cindex MH-Letter mode
-@cindex MH-Search mode
-@cindex Message menu
-@cindex Search menu
-@cindex Sequence menu
-@cindex menu bar
-@cindex menu, Folder
-@cindex menu, Identity
-@cindex menu, Letter
-@cindex menu, Message
-@cindex menu, Search
-@cindex menu, Sequence
-@cindex menu, @samp{Folder}
-@cindex menu, @samp{Identity}
-@cindex menu, @samp{Letter}
-@cindex menu, @samp{Message}
-@cindex menu, @samp{Search}
-@cindex menu, @samp{Sequence}
-@cindex modes, MH-Folder
-@cindex modes, MH-Letter
-@cindex modes, MH-Search
-
-For those of you who prefer to mouse and menu instead of using the
-meta-coke-bottle-bucky keys, MH-E provides menu items for most of its
-functions. The MH-Folder buffer adds the @samp{Folder},
-@samp{Message}, and @samp{Sequence} menus. The MH-Letter buffer adds
-the @samp{Identity} and @samp{Letter} menus. The MH-Search buffer adds
-the @samp{Search} menu. There's no need to list the actual items here,
-as you can more easily see them for yourself, and the functions are
-already described elsewhere in this manual.
-
-For a description of the menu bar, please
-@ifnothtml
-@xref{Menu Bar, , The Menu Bar, emacs, The GNU Emacs Manual}.
-@end ifnothtml
-@ifhtml
-see the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Menu-Bar.html,
-The Menu Bar} in @cite{The GNU Emacs Manual}.
-@end ifhtml
-
-The Emacs manual describes how to get help for a particular
-menu item. You can also look up a menu item in the index of this
-manual in two ways: all of the menu items are listed alphabetically,
-and you can also browse all of the items under the index entry
-@samp{menu item}.
-
-@node Tool Bar
-@chapter The Tool Bar
-
-@cindex tool bar
-
-Emacs also provides a graphical tool bar. For a description of the
-tool bar, please
-@ifnothtml
-@xref{Tool Bars, , Tool Bars, emacs, The GNU Emacs Manual}.
-@end ifnothtml
-@ifhtml
-see the section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Tool-Bars.html,
-Tool Bars} in @cite{The GNU Emacs Manual}.
-@end ifhtml
-
-@cindex @samp{mh-tool-bar} customization group
-@cindex customization group, @samp{mh-tool-bar}
-
-MH-E adds several icons to this tool bar; you can modify the MH-E
-aspects of the tool bar via the @samp{mh-tool-bar} customization group.
-
-@vtable @code
-@item mh-tool-bar-folder-buttons
-List of buttons to include in MH-Folder tool bar (default: a checklist
-too long to list here).
-@c -------------------------
-@item mh-tool-bar-letter-buttons
-List of buttons to include in MH-Letter tool bar (default: a checklist
-too long to list here).
-@c -------------------------
-@item mh-tool-bar-search-function
-Function called by the tool bar search button (default:
-@code{mh-search}).
-@end vtable
-
-Icons for some of MH-E's functions are added to the tool bar.
-
-@vindex mh-tool-bar-folder-buttons
-@vindex mh-tool-bar-letter-buttons
-
-In either case, you can select which of these functions you'd like to
-see by customizing the options @code{mh-tool-bar-folder-buttons} and
-@code{mh-tool-bar-letter-buttons}. As you probably guessed, the former
-customizes the tool bar in MH-Folder mode and the latter in MH-Letter
-mode. Both of these options present you with a list of functions;
-check the functions whose icons you want to see and clear the check
-boxes for those you don't.
-
-@findex mh-search
-@vindex mh-tool-bar-search-function
-
-The function associated with the searching icon can be set via the
-option @code{mh-tool-bar-search-function}. By default, this is set to
-@code{mh-search}. @xref{Searching}. You can also choose @samp{Other
-Function} from the @samp{Value Menu} and enter a function of your own
-choosing.
-
-@node Searching
-@chapter Searching Through Messages
-
-@cindex @samp{Search} menu
-@cindex menu, @samp{Search}
-@cindex searching
-@findex mh-search
-@kindex F s
-
-Earlier, the command @kbd{F s} (@code{mh-search}) was introduced which
-helps you find messages that lie buried in your folders
-(@pxref{Folders}). This chapter covers this command in more detail.
-Several commands are used to compose the search criteria and to start
-searching. A couple of them can be found in the @samp{Search} menu.
-
-@table @kbd
-@kindex C-c ?
-@findex mh-help
-@item C-c ?
-Display cheat sheet for the MH-E commands (@code{mh-help}).
-@c -------------------------
-@cindex @samp{Search > Perform Search} menu item
-@cindex menu item, @samp{Search > Perform Search}
-@kindex C-c C-c
-@findex mh-index-do-search
-@item C-c C-c
-Find messages using @code{mh-search-program}
-(@code{mh-index-do-search}).
-@c -------------------------
-@cindex @samp{Search > Search with pick} menu item
-@cindex menu item, @samp{Search > Search with pick}
-@kindex C-c C-p
-@findex mh-pick-do-search
-@item C-c C-p
-Find messages using @command{pick} (@code{mh-pick-do-search}).
-@c -------------------------
-@kindex C-c ?
-@findex mh-help
-@item C-c ?
-Display cheat sheet for the MH-E commands (@code{mh-help}).
-@c -------------------------
-@kindex C-c C-f C-a
-@kindex C-c C-f a
-@findex mh-to-field
-@item C-c C-f a
-@itemx C-c C-f C-a
-Move to @samp{Mail-Reply-To:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-b
-@kindex C-c C-f b
-@item C-c C-f b
-@itemx C-c C-f C-b
-Move to @samp{Bcc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-c
-@kindex C-c C-f c
-@item C-c C-f c
-@itemx C-c C-f C-c
-Move to @samp{Cc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-d
-@kindex C-c C-f d
-@item C-c C-f d
-@itemx C-c C-f C-d
-Move to @samp{Dcc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-f
-@kindex C-c C-f f
-@item C-c C-f f
-@itemx C-c C-f C-f
-Move to @samp{Fcc:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-l
-@kindex C-c C-f l
-@item C-c C-f l
-@itemx C-c C-f C-l
-Move to @samp{Mail-Followup-To:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-m
-@kindex C-c C-f m
-@item C-c C-f m
-@itemx C-c C-f C-m
-Move to @samp{From:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-r
-@kindex C-c C-f r
-@item C-c C-f r
-@itemx C-c C-f C-r
-Move to @samp{Reply-To:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-s
-@kindex C-c C-f s
-@item C-c C-f s
-@itemx C-c C-f C-s
-Move to @samp{Subject:} header field (@code{mh-to-field}).
-@c -------------------------
-@kindex C-c C-f C-t
-@kindex C-c C-f t
-@item C-c C-f t
-@itemx C-c C-f C-t
-Move to @samp{To:} header field (@code{mh-to-field}).
-@end table
-
-Another few commands are available in the MH-Folder buffer resulting
-from a search.
-
-@table @kbd
-@kindex TAB
-@findex mh-index-next-folder
-@item @key{TAB}
-Jump to the next folder marker (@code{mh-index-next-folder}).
-@c -------------------------
-@kindex S-TAB
-@findex mh-index-previous-folder
-@item S-@key{TAB}
-Jump to the previous folder marker (@code{mh-index-previous-folder}).
-@c -------------------------
-@kindex v
-@findex mh-index-visit-folder
-@item v
-Visit original folder from where the message at point was found
-(@code{mh-index-visit-folder}).
-@end table
-
-@cindex @samp{mh-search} customization group
-@cindex customization group, @samp{mh-search}
-
-There is one option from the @samp{mh-search} customization group used
-in searching.
-
-@vtable @code
-@item mh-search-program
-Search program that MH-E shall use (default: @samp{Auto-detect}).
-@end vtable
-
-The following hook is available.
-
-@vtable @code
-@item mh-search-mode-hook
-Hook run upon entry to @code{mh-search-mode} (default: @code{nil}).
-@end vtable
-
-The following face is available.
-
-@vtable @code
-@item mh-search-folder
-Folder heading face in MH-Folder buffers created by searches.
-@end vtable
-
-@findex mh-search-folder
-@kindex F s
-
-The command @kbd{F s} (@code{mh-search-folder}) helps you find
-messages in your entire corpus of mail. You can search for messages to
-or from a particular person or about a particular subject. In fact,
-you can also search for messages containing selected strings in any
-arbitrary header field or any string found within the messages.
-
-@cindex @command{pick}
-@cindex MH commands, @command{pick}
-
-Out of the box, MH-E uses @command{pick} to find messages. With a
-little extra effort, you can set an indexing program which rewards you
-with extremely quick results. The drawback is that sometimes the index
-does not contain the words you're looking for. You can still use
-@command{pick} in these situations.
-
-You are prompted for the folder to search. This can be @samp{all} to
-search all folders. Note that the search works recursively on the
-listed folder.
-
-@cindex MH-Search mode
-@cindex modes, MH-Search
-
-Next, an MH-Search buffer appears where you can enter search criteria.
-
-@cartouche
-@smallexample
-From:
-To:
-Cc:
-Date:
-Subject:
---------
-#
-
-
-
-
-
-
-
-
---:** search-pattern All L7 (MH-Search)---------------------------
-Type C-c C-c to search messages, C-c C-p to use pick, C-c ? for help
-@end smallexample
-@end cartouche
-@i{Search window}
-
-@cindex @command{pick}
-@cindex MH commands, @command{pick}
-
-Edit this template by entering your search criteria in an appropriate
-header field that is already there, or create a new field yourself. If
-the string you're looking for could be anywhere in a message, then
-place the string underneath the row of dashes.
-
-As an example, let's say that we want to find messages from Ginnean
-about horseback riding in the Kosciusko National Park (Australia)
-during January, 1994. Normally we would start with a broad search and
-narrow it down if necessary to produce a manageable amount of data,
-but we'll cut to the chase and create a fairly restrictive set of
-criteria as follows:
-
-@smallexample
-@group
-From: ginnean
-To:
-Cc:
-Date: Jan 1994
-Subject:
---------
-horse
-kosciusko
-@end group
-@end smallexample
-
-@findex mh-to-field
-@kindex C-c C-f C-t
-
-As with MH-Letter mode, MH-Search provides commands like @kbd{C-c C-f
-C-t} (@code{mh-to-field}) to help you fill in the blanks.
-@xref{Editing Message}.
-
-@kindex F s
-@vindex mh-search-mode-hook
-
-If you find that you do the same thing over and over when editing the
-search template, you may wish to bind some shortcuts to keys. This can
-be done with the variable @code{mh-search-mode-hook}, which is called
-when @kbd{F s} is run on a new pattern.
-
-@findex mh-index-do-search
-@findex mh-pick-do-search
-@kindex C-c C-c
-@kindex C-c C-p
-
-To perform the search, type @kbd{C-c C-c} (@code{mh-index-do-search}).
-Sometimes you're searching for text that is either not indexed, or
-hasn't been indexed yet. In this case you can override the default
-method with the pick method by running the command @kbd{C-c C-p}
-(@code{mh-pick-do-search}).
-
-@cindex folders, @samp{+mhe-index}
-@cindex @samp{+mhe-index}
-@findex mh-index-next-folder
-@findex mh-index-previous-folder
-@kindex TAB
-@kindex S-TAB
-@vindex mh-search-folder
-
-The messages that are found are put in a temporary sub-folder of
-@samp{+mhe-index} and are displayed in an MH-Folder buffer. This
-buffer is special because it displays messages from multiple folders;
-each set of messages from a given folder has a heading with the folder
-name. The appearance of the heading can be modified by customizing the
-face @code{mh-search-folder}. You can jump back and forth between the
-headings using the commands @kbd{@key{TAB}}
-(@code{mh-index-next-folder}) and @kbd{S-@key{TAB}}
-(@code{mh-index-previous-folder}).
-
-@findex mh-index-visit-folder
-@findex mh-rescan-folder
-@kindex F r
-@kindex v
-
-In addition, the command @kbd{v} (@code{mh-index-visit-folder}) can be
-used to visit the folder of the message at point. Initially, only the
-messages that matched the search criteria are displayed in the folder.
-While the temporary buffer has its own set of message numbers, the
-actual messages numbers are shown in the visited folder. Thus, the
-command @kbd{v} is useful to find the actual message number of an
-interesting message, or to view surrounding messages with the command
-@kbd{F r} @code{mh-rescan-folder}. @xref{Folders}.
-
-@findex mh-kill-folder
-@kindex F k
-
-Because this folder is temporary, you'll probably get in the habit of
-killing it when you're done with @kbd{F k} (@code{mh-kill-folder}).
-@xref{Folders}.
-
-@kindex F s
-
-You can regenerate the results by running @kbd{F s} with a prefix
-argument.
-
-@cindex @command{procmail}
-@cindex Unix commands, @command{procmail}
-@cindex @samp{X-MHE-Checksum} header field
-@cindex header field, @samp{X-MHE-Checksum}
-
-Note: This command uses an @samp{X-MHE-Checksum:} header field to
-cache the MD5 checksum of a message. This means that if an incoming
-message already contains an @samp{X-MHE-Checksum:} field, that message
-might not be found by this command. The following @command{procmail}
-recipe avoids this problem by renaming the existing header field:
-
-@smallexample
-@group
-:0 wf
-| formail -R "X-MHE-Checksum" "X-Old-MHE-Checksum"
-@end group
-@end smallexample
-
-@xref{Limits}, for an alternative interface to searching.
-
-@section Configuring Indexed Searches
-
-@cindex @command{grep}
-@cindex @command{mairix}
-@cindex @command{namazu}
-@cindex @command{pick}
-@cindex @command{swish++}
-@cindex @command{swish-e}
-@cindex Unix commands, @command{grep}
-@cindex Unix commands, @command{mairix}
-@cindex Unix commands, @command{namazu}
-@cindex Unix commands, @command{pick}
-@cindex Unix commands, @command{swish++}
-@cindex Unix commands, @command{swish-e}
-@findex mh-search
-@kindex F s
-@vindex mh-search-program
-
-The command @kbd{F s} (@code{mh-search}) runs the command defined by
-the option @code{mh-search-program}. The default value is
-@samp{Auto-detect} which means that MH-E will automatically choose one
-of @command{swish++}, @command{swish-e}, @command{mairix},
-@command{namazu}, @command{pick} and @command{grep} in that order. If,
-for example, you have both @command{swish++} and @command{mairix}
-installed and you want to use @command{mairix}, then you can set this
-option to @samp{mairix}.
-
-The following sub-sections describe how to set up the various indexing
-programs to use with MH-E.
-
-@subsection swish++
-
-@cindex @command{swish++}
-@cindex Unix commands, @command{swish++}
-
-In the examples below, replace @file{/home/user/Mail} with the path to
-your MH directory.
-
-First create the directory @file{/home/user/Mail/.swish++}. Then
-create the file @file{/home/user/Mail/.swish++/swish++.conf} with the
-following contents:
-
-@smallexample
-@group
-IncludeMeta Bcc Cc Comments Content-Description From Keywords
-IncludeMeta Newsgroups Resent-To Subject To
-IncludeMeta Message-Id References In-Reply-To
-IncludeFile Mail *
-IndexFile /home/user/Mail/.swish++/swish++.index
-@end group
-@end smallexample
-
-Use the following command line to generate the swish index. Run this
-daily from cron:
-
-@smallexample
-@group
-find /home/user/Mail -path /home/user/Mail/mhe-index -prune \
- -o -path /home/user/Mail/.swish++ -prune \
- -o -name "[0-9]*" -print \
- | index -c /home/user/Mail/.swish++/swish++.conf -
-@end group
-@end smallexample
-
-This command does not index the folders that hold the results of your
-searches in @samp{+mhe-index} since they tend to be ephemeral and the
-original messages are indexed anyway.
-
-@cindex @command{index}
-@cindex Unix commands, @command{index}
-@cindex @command{index++}
-@cindex Unix commands, @command{index++}
-
-On some systems (Debian GNU/Linux, for example), use @command{index++}
-instead of @command{index}.
-
-@subsection swish
-
-@cindex @command{swish-e}
-@cindex Unix commands, @command{swish-e}
-
-In the examples below, replace @file{/home/user/Mail} with the path to
-your MH directory.
-
-First create the directory @file{/home/user/Mail/.swish}. Then create
-the file @file{/home/user/Mail/.swish/config} with the following
-contents:
-
-@smallexample
-@group
-DefaultContents TXT*
-IndexDir /home/user/Mail
-IndexFile /home/user/Mail/.swish/index
-IndexName "Mail Index"
-IndexDescription "Mail Index"
-IndexPointer "https://nowhere"
-IndexAdmin "nobody"
-#MetaNames automatic
-IndexReport 3
-FollowSymLinks no
-UseStemming no
-IgnoreTotalWordCountWhenRanking yes
-WordCharacters abcdefghijklmnopqrstuvwxyz0123456789-
-BeginCharacters abcdefghijklmnopqrstuvwxyz
-EndCharacters abcdefghijklmnopqrstuvwxyz0123456789
-IgnoreLimit 50 1000
-IndexComments 0
-FileRules filename contains \D
-FileRules pathname contains /home/user/Mail/.swish
-FileRules pathname contains /home/user/Mail/mhe-index
-FileRules filename is index
-@end group
-@end smallexample
-
-This configuration does not index the folders that hold the results of
-your searches in @samp{+mhe-index} since they tend to be ephemeral and
-the original messages are indexed anyway.
-
-If there are any directories you would like to ignore, append lines
-like the following to @file{config}:
-
-@smallexample
-FileRules pathname contains /home/user/Mail/scripts
-@end smallexample
-
-@cindex @command{swish-e}
-@cindex Unix commands, @command{swish-e}
-
-Use the following command line to generate the swish index. Run this
-daily from cron:
-
-@smallexample
-swish-e -c /home/user/Mail/.swish/config
-@end smallexample
-
-@subsection mairix
-
-@cindex @command{mairix}
-@cindex Unix commands, @command{mairix}
-
-In the examples below, replace @file{~/Mail} with the path to your MH
-directory.
-
-First create the directory @file{~/Mail/.mairix}. Then create the file
-@file{~/Mail/.mairix/config} with the following contents:
-
-@smallexample
-@group
-base=~/Mail
-
-# List of folders that should be indexed. 3 dots at the end means there
-# are subfolders within the folder
-mh=archive...:inbox:drafts:news:sent:trash
-
-mformat=mh
-database=~/Mail/.mairix/database
-@end group
-@end smallexample
-
-Use the following command line to generate the mairix index. Run this daily
-from cron:
-
-@smallexample
-mairix -f ~/Mail/.mairix/config
-@end smallexample
-
-@subsection namazu
-
-@cindex @command{namazu}
-@cindex Unix commands, @command{namazu}
-
-In the examples below, replace @file{/home/user/Mail} with the path to
-your MH directory.
-
-First create the directory @file{/home/user/Mail/.namazu}. Then create
-the file @file{/home/user/Mail/.namazu/mknmzrc} with the following
-contents:
-
-@smallexample
-@group
-package conf; # Don't remove this line!
-$ADDRESS = 'user@@localhost';
-$ALLOW_FILE = "[0-9]*";
-$EXCLUDE_PATH = "^/home/user/Mail/(mhe-index|spam)";
-@end group
-@end smallexample
-
-This configuration does not index the folders that hold the results of
-your searches in @samp{+mhe-index} since they tend to be ephemeral and
-the original messages are indexed anyway.
-
-Use the following command line to generate the namazu index. Run this
-daily from cron:
-
-@smallexample
-mknmz -f /home/user/Mail/.namazu/mknmzrc -O /home/user/Mail/.namazu \
- -q /home/user/Mail
-@end smallexample
-
-@subsection pick
-
-@cindex @command{pick}
-@cindex MH commands, @command{pick}
-
-This search method does not require any setup.
-
-Read @command{pick}(1) or the section
-@uref{@value{MH-BOOK-HOME}/finpic.html, Finding Messages with pick} in
-the MH book to find out more about how to enter the criteria.
-
-@subsection grep
-
-@cindex @command{grep}
-@cindex Unix commands, @command{grep}
-
-This search method does not require any setup.
-
-Unlike the other search methods, this method does not use the
-MH-Search buffer. Instead, you simply enter a regular expression in
-the minibuffer. For help in constructing regular expressions, see your
-man page for @command{grep}.
-
-@node Threading
-@chapter Viewing Message Threads
-
-@cindex threading
-
-MH-E groups messages by @dfn{threads} which are messages that are part
-of the same discussion and usually all have the same @samp{Subject:}
-header field. Other ways to organize messages in a folder include
-limiting (@pxref{Limits}) or using full-text indexed searches
-(@pxref{Searching}).
-
-@cindex root, in threads
-@cindex siblings, in threads
-@cindex ancestor, in threads
-
-A thread begins with a single message called a @dfn{root}. All replies
-to the same message are @dfn{siblings} of each other. Any message that
-has replies to it is an @dfn{ancestor} of those replies.
-
-There are several commands that you can use to navigate and operate on
-threads.
-
-@table @kbd
-@kindex T ?
-@findex mh-prefix-help
-@item T ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@kindex T o
-@findex mh-thread-refile
-@item T o
-Refile (output) thread into folder (@code{mh-thread-refile}).
-@c -------------------------
-@kindex T d
-@findex mh-thread-delete
-@item T d
-Delete thread (@code{mh-thread-delete}).
-@c -------------------------
-@kindex T t
-@findex mh-toggle-threads
-@item T t
-Toggle threaded view of folder (@code{mh-toggle-threads}).
-@c -------------------------
-@kindex T n
-@findex mh-thread-next-sibling
-@item T n
-Display next sibling (@code{mh-thread-next-sibling}).
-@c -------------------------
-@kindex T p
-@findex mh-thread-previous-sibling
-@item T p
-Display previous sibling (@code{mh-thread-previous-sibling}).
-@c -------------------------
-@kindex T u
-@findex mh-thread-ancestor
-@item T u
-Display ancestor of current message (@code{mh-thread-ancestor}).
-@end table
-
-@cindex @samp{mh-thread} customization group
-@cindex customization group, @samp{mh-thread}
-
-The @samp{mh-thread} customization group contains one option.
-
-@vtable @code
-@item mh-show-threads-flag
-On means new folders start in threaded mode (default: @samp{off}).
-@end vtable
-
-@findex mh-toggle-threads
-@kindex T t
-@vindex mh-large-folder
-@vindex mh-show-threads-flag
-
-Threading large number of messages can be time consuming so the option
-@code{mh-show-threads-flag} is turned off by default. If you turn on
-this option, then threading will be done only if the number of
-messages being threaded is less than @code{mh-large-folder}. In any
-event, threading can be turned on (and off) with the command @kbd{T t}
-(@code{mh-toggle-threads}).
-
-@findex mh-thread-ancestor
-@findex mh-thread-next-sibling
-@findex mh-thread-previous-sibling
-@kindex T n
-@kindex T p
-@kindex T u
-
-There are a few commands to help you navigate threads. If you do not
-care for the way a particular thread has turned, you can move up the
-chain of messages with the command @kbd{T u}
-(@code{mh-thread-ancestor}. At any point you can use @kbd{T n}
-(@code{mh-thread-next-sibling} or @kbd{T p}
-(@code{mh-thread-previous-sibling}) to jump to the next or previous
-sibling, skipping the sub-threads. The command @kbd{T u} can also take
-a prefix argument to jump to the message that started everything.
-
-@findex mh-delete-subject-or-thread
-@findex mh-thread-delete
-@findex mh-thread-refile
-@kindex k
-@kindex T d
-@kindex T o
-
-There are threaded equivalents for the commands that delete and refile
-messages. For example, @kbd{T o} (@code{mh-thread-refile}) refiles the
-current message and all its children. Similarly, the command @kbd{T d}
-(@code{mh-thread-delete}) deletes the current message and all its
-children. These commands do not refile or delete sibling messages.
-@xref{Navigating}, for a description of the similar command @kbd{k}
-(@code{mh-delete-subject-or-thread}).
-
-@vindex mh-large-folder
-
-If you find that threading is too slow, it may be that you have
-@code{mh-large-folder} set too high. Also, threading is one of the few
-features of MH-E that really benefits from compiling. If you haven't
-compiled MH-E, I encourage you to do so@footnote{If you're not sure if
-MH-E has been byte-compiled, you could try running @samp{locate
-mh-thread.elc} or otherwise find MH-E on your system and ensure that
-@file{mh-thread.elc} exists. If you have multiple versions and you
-find that one is compiled but the other is not, then go into your
-@file{*scratch*} buffer in Emacs, enter @kbd{load-path C-j}, and
-ensure that the byte-compiled version appears first in the
-@code{load-path}. If you find that MH-E is not compiled and you
-installed MH-E yourself, please refer to the installation directions
-in the file @file{README} in the distribution.}.
-
-@node Limits
-@chapter Limiting Display
-
-@cindex limits
-@cindex filters
-
-Another way to organize messages in a folder besides threading
-(@pxref{Threading}) or using full-text indexed searches
-(@pxref{Searching}) is by limiting the folder display to messages that
-are similar to the current message.
-
-@table @kbd
-@kindex / ?
-@findex mh-prefix-help
-@item / ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@cindex @samp{Sequence > Narrow to Tick Sequence} menu item
-@cindex menu item, @samp{Sequence > Narrow to Tick Sequence}
-@kindex / '
-@findex mh-narrow-to-tick
-@item / '
-Limit to messages in the @samp{tick} sequence
-(@code{mh-narrow-to-tick}).
-@c -------------------------
-@kindex / c
-@findex mh-narrow-to-cc
-@item / c
-Limit to messages with the same @samp{Cc:} field
-(@code{mh-narrow-to-cc}).
-@c -------------------------
-@kindex / m
-@findex mh-narrow-to-from
-@item / m
-Limit to messages with the same @samp{From:} field
-(@code{mh-narrow-to-from}).
-@c -------------------------
-@kindex / g
-@findex mh-narrow-to-range
-@item / g
-Limit to range (@code{mh-narrow-to-range}).
-@c -------------------------
-@cindex @samp{Sequence > Narrow to Subject Sequence} menu item
-@cindex menu item, @samp{Sequence > Narrow to Subject Sequence}
-@kindex / s
-@findex mh-narrow-to-subject
-@item / s
-Limit to messages with the same @samp{Subject:} field
-(@code{mh-narrow-to-subject}).
-@c -------------------------
-@kindex / t
-@findex mh-narrow-to-to
-@item / t
-Limit to messages with the same @samp{To:} field
-(@code{mh-narrow-to-to}).
-@c -------------------------
-@cindex @samp{Sequence > Widen from Sequence} menu item
-@cindex menu item, @samp{Sequence > Widen from Sequence}
-@kindex / w
-@findex mh-widen
-@item / w
-Remove last restriction (@code{mh-widen}).
-@end table
-
-All of the limiting commands above refine the display in some way.
-
-@cindex @command{pick}
-@cindex MH commands, @command{pick}
-@findex mh-narrow-to-cc
-@findex mh-narrow-to-from
-@findex mh-narrow-to-subject
-@findex mh-narrow-to-to
-@kindex / c
-@kindex / m
-@kindex / s
-@kindex / t
-
-The commands @kbd{/ c} (@code{mh-narrow-to-cc}), @kbd{/ m}
-(@code{mh-narrow-to-from}), @kbd{/ s} (@code{mh-narrow-to-subject}),
-and @kbd{/ t} (@code{mh-narrow-to-to}) restrict the display to
-messages matching the content of the respective field in the current
-message. However, you can give any of these a prefix argument to edit
-the @command{pick} expression used to narrow the view@footnote{See
-@command{pick}(1) or the section
-@uref{@value{MH-BOOK-HOME}/finpic.html, Finding Messages with pick} in
-the MH book.}.
-
-@cindex @samp{tick} sequence
-@cindex sequence, @samp{tick}
-@cindex ticked messages, viewing
-@findex mh-narrow-to-range
-@findex mh-narrow-to-tick
-@kindex / '
-@kindex / g
-
-You can also limit the display to messages in the @samp{tick} sequence
-with the command @kbd{/ '} (@code{mh-narrow-to-tick}).
-@xref{Sequences}, for information on putting message into the
-@samp{tick} sequence. Use the @kbd{/ g} (@code{mh-narrow-to-range})
-command to limit the display to messages in a range (@pxref{Ranges}).
-
-@findex mh-widen
-@kindex / w
-
-Each limit can be undone in turn with the @kbd{/ w} (@code{mh-widen})
-command. Give this command a prefix argument to remove all limits.
-
-@node Sequences
-@chapter Using Sequences
-
-@cindex @samp{Sequence} menu
-@cindex menu, @samp{Sequence}
-@cindex sequences
-
-For the whole scoop on MH sequences, refer to
-@samp{mh-sequence}(5)@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/morseq.html, More About Sequences} in the MH
-book.}. As you've read, several of the MH-E commands can operate on a
-sequence, which is a shorthand for a range or group of messages. For
-example, you might want to forward several messages to a friend or
-colleague. Here's how to manipulate sequences. These commands are also
-available in the @samp{Sequence} menu.
-
-@table @kbd
-@cindex @samp{Sequence > Toggle Tick Mark} menu item
-@cindex menu item, @samp{Sequence > Toggle Tick Mark}
-@kindex '
-@findex mh-toggle-tick
-@item '
-Toggle tick mark of range (@code{mh-toggle-tick}).
-@c -------------------------
-@kindex S ?
-@findex mh-prefix-help
-@item S ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@cindex @samp{Sequence > Narrow to Tick Sequence} menu item
-@cindex menu item, @samp{Sequence > Narrow to Tick Sequence}
-@kindex S '
-@findex mh-narrow-to-tick
-@item S '
-Limit to ticked messages (@code{mh-narrow-to-tick}).
-@c -------------------------
-@cindex @samp{Sequence > Delete Message from Sequence...} menu item
-@cindex menu item, @samp{Sequence > Delete Message from Sequence...}
-@kindex S d
-@findex mh-delete-msg-from-seq
-@item S d
-Delete range from sequence (@code{mh-delete-msg-from-seq}).
-@c -------------------------
-@cindex @samp{Sequence > Delete Sequence...} menu item
-@cindex menu item, @samp{Sequence > Delete Sequence...}
-@kindex S k
-@findex mh-delete-seq
-@item S k
-Delete sequence (@code{mh-delete-seq}).
-@c -------------------------
-@cindex @samp{Sequence > List Sequences in Folder...} menu item
-@cindex menu item, @samp{Sequence > List Sequences in Folder...}
-@kindex S l
-@findex mh-list-sequences
-@item S l
-List all sequences in folder (@code{mh-list-sequences}).
-@c -------------------------
-@cindex @samp{Sequence > Narrow to Sequence...} menu item
-@cindex menu item, @samp{Sequence > Narrow to Sequence...}
-@kindex S n
-@findex mh-narrow-to-seq
-@item S n
-Restrict display to messages in sequence (@code{mh-narrow-to-seq}).
-@c -------------------------
-@cindex @samp{Sequence > Add Message to Sequence...} menu item
-@cindex menu item, @samp{Sequence > Add Message to Sequence...}
-@kindex S p
-@findex mh-put-msg-in-seq
-@item S p
-Add range to sequence (@code{mh-put-msg-in-seq}).
-@c -------------------------
-@cindex @samp{Sequence > List Sequences for Message} menu item
-@cindex menu item, @samp{Sequence > List Sequences for Message}
-@kindex S s
-@findex mh-msg-is-in-seq
-@item S s
-Display the sequences in which the current message appears
-(@code{mh-msg-is-in-seq}).
-@c -------------------------
-@cindex @samp{Sequence > Widen from Sequence} menu item
-@cindex menu item, @samp{Sequence > Widen from Sequence}
-@kindex S w
-@findex mh-widen
-@item S w
-Remove last restriction (@code{mh-widen}).
-@c -------------------------
-@findex mh-update-sequences
-@item M-x mh-update-sequences
-Flush MH-E's state out to MH@.
-@end table
-
-@cindex @samp{mh-sequences} customization group
-@cindex customization group, @samp{mh-sequences}
-
-The @samp{mh-sequences} customization group contains the options
-associated with sequences.
-
-@vtable @code
-@item mh-refile-preserves-sequences-flag
-On means that sequences are preserved when messages are refiled
-(default: @samp{on}).
-@c -------------------------
-@item mh-tick-seq
-The name of the MH sequence for ticked messages (default: @samp{'tick}).
-@c -------------------------
-@item mh-update-sequences-after-mh-show-flag
-On means flush MH sequences to disk after message is shown (default:
-@samp{on}).
-@item mh-allowlist-preserves-sequences-flag
-On means that sequences are preserved when messages are allowlisted
-(default: @samp{on}).
-@end vtable
-
-The following hook is available.
-
-@vtable @code
-@item mh-unseen-updated-hook
-Hook run after the unseen sequence has been updated (default: @code{nil}).
-@end vtable
-
-@cindex @command{pick}
-@cindex MH commands, @command{pick}
-@findex mh-put-msg-in-seq
-@kindex S p
-
-To place a message in a sequence, use @kbd{S p}
-(@code{mh-put-msg-in-seq}). Give @kbd{S p} a range and you can add all
-the messages in a sequence to another sequence (for example, @kbd{C-u
-S p SourceSequence @key{RET} DestSequence @key{RET}}, @pxref{Ranges}).
-
-@cindex @samp{tick} sequence
-@cindex sequence, @samp{tick}
-@cindex ticking messages
-@findex mh-index-ticked-messages
-@findex mh-toggle-tick
-@kindex '
-@kindex F '
-@kindex S p
-
-One specific use of the @kbd{S p} command is @kbd{'}
-(@code{mh-toggle-tick}) which adds messages to the @samp{tick}
-sequence. This sequence can be viewed later with the @kbd{F '}
-(@code{mh-index-ticked-messages}) command (@pxref{Folders}).
-
-@vindex mh-tick-seq
-
-You can customize the option @code{mh-tick-seq} if you already use the
-@samp{tick} sequence for your own use. You can also disable all of the
-ticking functions by choosing the @samp{Disable Ticking} item but
-there isn't much advantage to that.
-
-@cindex MH-Folder mode
-@cindex modes, MH-Folder
-@findex mh-narrow-to-seq
-@findex mh-narrow-to-tick
-@findex mh-widen
-@kindex S '
-@kindex S n
-@kindex S w
-
-Once you've placed some messages in a sequence, you may wish to narrow
-the field of view to just those messages in the sequence you've
-created. To do this, use @kbd{S n} (@code{mh-narrow-to-seq}). You are
-prompted for the name of the sequence. What this does is show only
-those messages that are in the selected sequence in the MH-Folder
-buffer. In addition, it limits further MH-E searches to just those
-messages. To narrow the view to the messages in the @samp{tick}
-sequence, use @kbd{S '} (@code{mh-narrow-to-tick}). When you want to
-widen the view to all your messages again, use @kbd{S w}
-(@code{mh-widen}).
-
-@cindex buffers, @file{*MH-E Sequences*}
-@cindex @file{*MH-E Sequences*}
-@findex mh-list-sequences
-@findex mh-msg-is-in-seq
-@kindex S l
-@kindex S s
-
-You can see which sequences in which a message appears with the
-command @kbd{S s} (@code{mh-msg-is-in-seq}). Use a prefix argument to
-display the sequences in which another message appears (as in @kbd{C-u
-42 S s @key{RET}}). Or, you can list all sequences in a selected
-folder (default is current folder) with @kbd{S l}
-(@code{mh-list-sequences}). The list appears in a buffer named
-@file{*MH-E Sequences*} (@pxref{Miscellaneous}).
-
-@cindex MH profile component, @samp{Previous-Sequence}
-@cindex @samp{cur} sequence
-@cindex @samp{Previous-Sequence} MH profile component
-@cindex sequence, @samp{cur}
-@cindex sequence, @samp{Previous-Sequence}
-@vindex mh-refile-preserves-sequences-flag
-
-If a message is in any sequence (except
-@samp{Previous-Sequence:}@footnote{See @samp{mh-profile}(5)).} and
-@samp{cur}) when it is refiled, then it will still be in those
-sequences in the destination folder. If this behavior is not desired,
-then turn off the option @code{mh-refile-preserves-sequences-flag}.
-
-@findex mh-delete-msg-from-seq
-@findex mh-delete-seq
-@kindex d
-@kindex S d
-@kindex S k
-
-If you want to remove a message (or range, @pxref{Ranges}) from a
-sequence, use @kbd{S d} (@code{mh-delete-msg-from-seq}). If you want
-to delete an entire sequence, use @kbd{S k} (@code{mh-delete-seq}). In
-the latter case you are prompted for the sequence to delete. Note that
-this deletes only the sequence, not the messages in the sequence. If
-you want to delete the messages, use @kbd{C-u d} (@pxref{Reading
-Mail}).
-
-@cindex @samp{Unseen-Sequence} MH profile component
-@cindex @samp{cur} sequence
-@cindex @samp{tick} sequence
-@cindex MH profile component, @samp{Unseen-Sequence}
-@cindex sequence, @samp{Unseen-Sequence}
-@cindex sequence, @samp{cur}
-@cindex sequence, @samp{tick}
-@findex mh-update-sequences
-@kindex q
-@kindex x
-@vindex mh-tick-seq
-@vindex mh-update-sequences-after-mh-show-flag
-
-Three sequences are maintained internally by MH-E and pushed out to MH
-when a message is shown. They include the sequence specified by your
-@samp{Unseen-Sequence:} profile component, @samp{cur}, and the
-sequence listed by the option @code{mh-tick-seq} which is @samp{tick}
-by default. If you do not like this behavior, turn off the option
-@code{mh-update-sequences-after-mh-show-flag}. You can then update the
-state manually with the @kbd{x}, @kbd{q}, or @kbd{M-x
-mh-update-sequences} commands.
-
-@vindex mh-seen-list
-@vindex mh-unseen-updated-hook
-
-The hook @code{mh-unseen-updated-hook} is run after the unseen
-sequence has been updated. The variable @code{mh-seen-list} can be
-used by this hook to obtain the list of messages which were removed
-from the unseen sequence.
-
-@cindex @command{mark}
-@cindex MH commands, @command{mark}
-@kindex S n
-@kindex S w
-
-With the exceptions of @kbd{S n} and @kbd{S w}, the underlying MH
-command dealing with sequences is @command{mark}@footnote{See the
-section @uref{@value{MH-BOOK-HOME}/mmbwm.html, Make Message Bookmarks
-with mark} in the MH book.}.
-
-@node Junk
-@chapter Dealing With Junk Mail
-
-@cindex Marshall Rose
-@cindex junk mail
-@cindex spam
-
-Marshall Rose once wrote a paper on MH entitled, @cite{How to process
-200 messages a day and still get some real work done}. This chapter
-could be entitled, @cite{How to process 1000 spams a day and still get
-some real work done}.
-
-@cindex blocklisting
-@cindex ham
-@cindex viruses
-@cindex allowlisting
-@cindex worms
-
-We use the terms @dfn{junk mail} and @dfn{spam} interchangeably for
-any unwanted message which includes spam, @dfn{viruses}, and
-@dfn{worms}. The opposite of spam is @dfn{ham}. The act of classifying
-a sender as one who sends junk mail is called @dfn{blocklisting}; the
-opposite is called @dfn{allowlisting}.
-
-@table @kbd
-@kindex J ?
-@findex mh-prefix-help
-@item J ?
-Display cheat sheet for the commands of the current prefix in
-minibuffer (@code{mh-prefix-help}).
-@c -------------------------
-@kindex J b
-@findex mh-junk-blocklist
-@item J b
-Blocklist range as spam (@code{mh-junk-blocklist}).
-@c -------------------------
-@kindex J a
-@findex mh-junk-allowlist
-@item J a
-Allowlist range as ham (@code{mh-junk-allowlist}).
-@c -------------------------
-@item @code{mh-spamassassin-identify-spammers}
-Identify spammers who are repeat offenders.
-@end table
-
-@cindex @samp{mh-junk} customization group
-@cindex customization group, @samp{mh-junk}
-
-The following table lists the options from the @samp{mh-junk}
-customization group.
-
-@vtable @code
-@item mh-junk-background
-If on, spam programs are run in background (default: @samp{off}).
-@c -------------------------
-@item mh-junk-disposition
-Disposition of junk mail (default: @samp{Delete Spam}).
-@c -------------------------
-@item mh-junk-program
-Spam program that MH-E should use (default: @samp{Auto-detect}).
-@end vtable
-
-@cindex @samp{mh-sequences} customization group
-@cindex customization group, @samp{mh-sequences}
-
-The following option in the @samp{mh-sequences} customization group is
-also available.
-
-@vtable @code
-@item mh-allowlist-preserves-sequences-flag
-On means that sequences are preserved when messages are allowlisted
-(default: @samp{on}).
-@end vtable
-
-The following hooks are available.
-
-@vtable @code
-@item mh-blocklist-msg-hook
-Hook run by @kbd{J b} (@code{mh-junk-blocklist}) after marking each
-message for blocklisting (default: @code{nil}).
-@c -------------------------
-@item mh-allowlist-msg-hook
-Hook run by @kbd{J a} (@code{mh-junk-allowlist}) after marking each
-message for allowlisting (default @samp{nil}).
-@end vtable
-
-The following faces are available.
-
-@vtable @code
-@item mh-folder-blocklisted
-Blocklisted message face.
-@c -------------------------
-@item mh-folder-allowlisted
-Allowlisted message face
-@end vtable
-
-@cindex SpamProbe
-@cindex SpamAssassin
-@cindex bogofilter
-@cindex spam filters, SpamProbe
-@cindex spam filters, SpamAssassin
-@cindex spam filters, bogofilter
-
-MH-E depends on @uref{https://spamassassin.apache.org/, SpamAssassin},
-@uref{https://bogofilter.sourceforge.net/, bogofilter}, or
-@uref{https://spamprobe.sourceforge.net/, SpamProbe} to throw the dreck
-away. This chapter describes briefly how to configure these programs
-to work well with MH-E and how to use MH-E's interface that provides
-continuing education for these programs.
-
-@vindex mh-junk-program
-
-The default setting of the option @code{mh-junk-program} is
-@samp{Auto-detect} which means that MH-E will automatically choose one
-of SpamAssassin, bogofilter, or SpamProbe in that order. If, for
-example, you have both SpamAssassin and bogofilter installed and you
-want to use bogofilter, then you can set this option to
-@samp{Bogofilter}.
-
-@findex mh-junk-blocklist
-@kindex J b
-@vindex mh-junk-disposition
-
-The command @kbd{J b} (@code{mh-junk-blocklist}) trains the spam
-program in use with the content of the range (@pxref{Ranges}) and then
-handles the message(s) as specified by the option
-@code{mh-junk-disposition}. By default, this option is set to
-@samp{Delete Spam} but you can also specify the name of the folder
-which is useful for building a corpus of spam for training purposes.
-
-@findex mh-junk-allowlist
-@kindex J a
-
-In contrast, the command @kbd{J a} (@code{mh-junk-allowlist})
-reclassifies a range of messages (@pxref{Ranges}) as ham if it were
-incorrectly classified as spam. It then refiles the message into the
-@file{+inbox} folder.
-
-@cindex MH profile component, @samp{Previous-Sequence}
-@cindex @samp{cur} sequence
-@cindex @samp{Previous-Sequence} MH profile component
-@cindex sequence, @samp{cur}
-@cindex sequence, @samp{Previous-Sequence}
-@vindex mh-allowlist-preserves-sequences-flag
-
-If a message is in any sequence (except @samp{Previous-Sequence:} and
-@samp{cur}) when it is allowlisted, then it will still be in those
-sequences in the destination folder. If this behavior is not desired,
-then turn off the option @code{mh-allowlist-preserves-sequences-flag}.
-
-@cindex @file{*MH-E Log*}
-@cindex buffers, @file{*MH-E Log*}
-@findex call-process
-@vindex mh-junk-background
-
-By default, the programs are run in the foreground, but this can be
-slow when junking large numbers of messages. If you have enough memory
-or don't junk that many messages at the same time, you might try
-turning on the option @code{mh-junk-background}. @footnote{Note that
-the option @code{mh-junk-background} is used as the @code{destination}
-argument in the call to @code{call-process}. Therefore, turning on
-this option means setting its value to @samp{0}. You can also set its
-value to @samp{t} to direct the programs' output to the @file{*MH-E
-Log*} buffer; this may be useful for debugging.}
-
-The following sections discuss the various counter-spam measures that
-MH-E can work with.
-
-@cindex @file{.procmailrc}
-@cindex files, @file{.procmailrc}
-
-@subheading SpamAssassin
-
-@cindex SpamAssassin
-@cindex spam filters, SpamAssassin
-
-SpamAssassin is one of the more popular spam filtering programs. Get
-it from your local distribution or from the
-@uref{https://spamassassin.apache.org/, SpamAssassin web site}.
-
-To use SpamAssassin, add the following recipes to @file{~/.procmailrc}:
-
-@cindex @command{spamc}
-@cindex @samp{X-Spam-Level} header field
-@cindex @samp{X-Spam-Status} header field
-@cindex header field, @samp{X-Spam-Level}
-@cindex header field, @samp{X-Spam-Status}
-
-@smallexample
-PATH=$PATH:/usr/bin/mh
-MAILDIR=$HOME/`mhparam Path`
-
-# Fight spam with SpamAssassin.
-:0fw
-| spamc
-
-# Anything with a spam level of 10 or more is junked immediately.
-:0:
-* ^X-Spam-Level: ..........
-/dev/null
-
-:0:
-* ^X-Spam-Status: Yes
-spam/.
-@end smallexample
-
-If you don't use @command{spamc}, use @samp{spamassassin -P -a}.
-
-Note that one of the recipes above throws away messages with a score
-greater than or equal to 10. Here's how you can determine a value that
-works best for you.
-
-First, run @samp{spamassassin -t} on every mail message in your
-archive and use @command{gnumeric} to verify that the average plus the
-standard deviation of good mail is under 5, the SpamAssassin default
-for ``spam''.
-
-Using @command{gnumeric}, sort the messages by score and view the
-messages with the highest score. Determine the score which encompasses
-all of your interesting messages and add a couple of points to be
-conservative. Add that many dots to the @samp{X-Spam-Level:} header
-field above to send messages with that score down the drain.
-
-In the example above, messages with a score of 5--9 are set aside in
-the @samp{+spam} folder for later review. The major weakness of
-rules-based filters is a plethora of false positives so it is
-worthwhile to check.
-
-@findex mh-junk-blocklist
-@findex mh-junk-allowlist
-@kindex J b
-@kindex J a
-
-If SpamAssassin classifies a message incorrectly, or is unsure, you can
-use the MH-E commands @kbd{J b} (@code{mh-junk-blocklist}) and
-@kbd{J a} (@code{mh-junk-allowlist}).
-
-@cindex @command{sa-learn}
-@cindex @file{.spamassassin/user_prefs}
-@cindex files, @file{.spamassassin/user_prefs}
-
-The command @kbd{J b} (@code{mh-junk-blocklist}) adds a
-@samp{blacklist_from} entry to @file{~/spamassassin/user_prefs},
-deletes the message, and sends the message to the Razor, so that
-others might not see this spam. If the @command{sa-learn} command is
-available, the message is also recategorized as spam.
-
-The command@kbd{J a} (@code{mh-junk-allowlist}) adds a
-@samp{whitelist_from} rule to @samp{~/.spamassassin/user_prefs}. If
-the @command{sa-learn} command is available, the message is also
-recategorized as ham.
-
-Over time, you'll observe that the same host or domain occurs
-repeatedly in the @samp{blacklist_from} entries, so you might think
-that you could avoid future spam by blocklisting all mail from a
-particular domain. The utility function
-@code{mh-spamassassin-identify-spammers} helps you do precisely that.
-This function displays a frequency count of the hosts and domains in
-the @samp{blacklist_from} entries from the last blank line in
-@file{~/.spamassassin/user_prefs} to the end of the file. This
-information can be used so that you can replace multiple
-@samp{blacklist_from} entries with a single wildcard entry such as:
-
-@smallexample
-blacklist_from *@@*amazingoffersdirect2u.com
-@end smallexample
-
-In versions of SpamAssassin (2.50 and on) that support a Bayesian
-classifier, @kbd{J b} @code{(mh-junk-blocklist}) uses the program
-@command{sa-learn} to recategorize the message as spam. Neither MH-E,
-nor SpamAssassin, rebuilds the database after adding words, so you
-will need to run @samp{sa-learn --rebuild} periodically. This can be
-done by adding the following to your @file{crontab}:
-
-@smallexample
-0 * * * * sa-learn --rebuild > /dev/null 2>&1
-@end smallexample
-
-@subheading Bogofilter
-
-@cindex bogofilter
-@cindex spam filters, bogofilter
-
-Bogofilter is a Bayesian spam filtering program. Get it from your
-local distribution or from the
-@uref{https://bogofilter.sourceforge.net/, bogofilter web site}.
-
-Bogofilter is taught by running:
-
-@smallexample
-bogofilter -n < good-message
-@end smallexample
-
-on every good message, and
-
-@smallexample
-bogofilter -s < spam-message
-@end smallexample
-
-@cindex full training
-
-on every spam message. This is called a @dfn{full training}; three
-other training methods are described in the FAQ that is distributed
-with bogofilter. Note that most Bayesian filters need 1000 to 5000 of
-each type of message to start doing a good job.
-
-To use bogofilter, add the following recipes to @file{~/.procmailrc}:
-
-@cindex @samp{X-Bogosity} header field
-@cindex header field, @samp{X-Bogosity}
-
-@smallexample
-PATH=$PATH:/usr/bin/mh
-MAILDIR=$HOME/`mhparam Path`
-
-# Fight spam with Bogofilter.
-:0fw
-| bogofilter -3 -e -p
-
-:0:
-* ^X-Bogosity: Yes, tests=bogofilter
-spam/.
-
-:0:
-* ^X-Bogosity: Unsure, tests=bogofilter
-spam/unsure/.
-@end smallexample
-
-@findex mh-junk-blocklist
-@findex mh-junk-allowlist
-@kindex J b
-@kindex J a
-
-If bogofilter classifies a message incorrectly, or is unsure, you can
-use the MH-E commands @kbd{J b} (@code{mh-junk-blocklist}) and
-@kbd{J a} (@code{mh-junk-allowlist}) to update bogofilter's training.
-
-The @cite{Bogofilter FAQ} suggests that you run the following
-occasionally to shrink the database:
-
-@smallexample
-bogoutil -d wordlist.db | bogoutil -l wordlist.db.new
-mv wordlist.db wordlist.db.prv
-mv wordlist.db.new wordlist.db
-@end smallexample
-
-The @cite{Bogofilter tuning HOWTO} describes how you can fine-tune
-bogofilter.
-
-@subheading SpamProbe
-
-@cindex SpamProbe
-@cindex spam filters, SpamProbe
-
-SpamProbe is a Bayesian spam filtering program. Get it from your local
-distribution or from the @uref{https://spamprobe.sourceforge.net,
-SpamProbe web site}.
-
-To use SpamProbe, add the following recipes to @file{~/.procmailrc}:
-
-@cindex @command{formail}
-@cindex @samp{X-SpamProbe} header field
-@cindex header field, @samp{X-SpamProbe}
-
-@smallexample
-PATH=$PATH:/usr/bin/mh
-MAILDIR=$HOME/`mhparam Path`
-
-# Fight spam with SpamProbe.
-:0
-SCORE=| spamprobe receive
-
-:0 wf
-| formail -I "X-SpamProbe: $SCORE"
-
-:0:
-*^X-SpamProbe: SPAM
-spam/.
-@end smallexample
-
-@findex mh-junk-blocklist
-@findex mh-junk-allowlist
-@kindex J b
-@kindex J a
-
-If SpamProbe classifies a message incorrectly, you can use the MH-E
-commands @kbd{J b} (@code{mh-junk-blocklist}) and @kbd{J a}
-(@code{mh-junk-allowlist}) to update SpamProbe's training.
-
-@subheading Other Things You Can Do
-
-There are a couple of things that you can add to @file{~/.procmailrc}
-in order to filter out a lot of spam and viruses. The first is to
-eliminate any message with a Windows executable (which is most likely
-a virus). The second is to eliminate mail in character sets that you
-can't read.
-
-@cindex @samp{Content-Transfer-Encoding} header field
-@cindex @samp{Content-Type} header field
-@cindex @samp{Subject} header field
-@cindex header field, @samp{Content-Transfer-Encoding}
-@cindex header field, @samp{Content-Type}
-@cindex header field, @samp{Subject}
-
-@smallexample
-PATH=$PATH:/usr/bin/mh
-MAILDIR=$HOME/`mhparam Path`
-
-#
-# Filter messages with w32 executables/virii.
-#
-# These attachments are base64 and have a TVqQAAMAAAAEAAAA//8AALg
-# pattern. The string "this program cannot be run in MS-DOS mode"
-# encoded in base64 is 4fug4AtAnNIbg and helps to avoid false
-# positives (Roland Smith via Pete from the bogofilter mailing list).
-#
-:0 B:
-* ^Content-Transfer-Encoding:.*base64
-* ^TVqQAAMAAAAEAAAA//8AALg
-* 4fug4AtAnNIbg
-spam/exe/.
-
-#
-# Filter mail in unreadable character sets (from the Bogofilter FAQ).
-#
-UNREADABLE='[^?"]*big5|iso-2022-jp|ISO-2022-KR|euc-kr|gb2312|ks_c_5601-1987'
-
-:0:
-* 1^0 $ ^Subject:.*=\?($UNREADABLE)
-* 1^0 $ ^Content-Type:.*charset="?($UNREADABLE)
-spam/unreadable/.
-
-:0:
-* ^Content-Type:.*multipart
-* B ?? $ ^Content-Type:.*^?.*charset="?($UNREADABLE)
-spam/unreadable/.
-@end smallexample
-
-@node Miscellaneous
-@chapter Miscellaneous Commands, Variables, and Buffers
-
-This chapter covers the following command and the various MH-E
-buffers,
-
-@ftable @code
-@item mh-version
-Display version information about MH-E and the MH mail handling
-system.
-@end ftable
-
-@cindex buffers, @file{*MH-E Info*}
-@cindex MH-E version
-@cindex @file{*MH-E Info*}
-@cindex version
-@findex mh-version
-
-One command worth noting is @kbd{M-x mh-version}. You can compare the
-version this command prints to the latest release (@pxref{Getting
-MH-E}). The output of @kbd{M-x mh-version}, found in a buffer named
-@file{*MH-E Info*}, should usually be included with any bug report you
-submit (@pxref{Bug Reports}).
-
-@subheading MH-E Buffers
-
-Besides the MH-Folder, MH-Show, and MH-Letter buffers, MH-E creates
-several other buffers. They are:
-
-@table @samp
-@cindex @file{*MH-E Folders*}
-@cindex buffers, @file{*MH-E Folders*}
-@findex mh-list-folders
-@item *MH-E Folders*
-@kindex F l
-This buffer contains the output of @kbd{F l} (@code{mh-list-folders}).
-@xref{Folders}.
-@c -------------------------
-@cindex @file{*MH-E Help*}
-@cindex buffers, @file{*MH-E Help*}
-@findex mh-help
-@item *MH-E Help*
-@kindex ?
-@kindex C-c ?
-This buffer contains the output of @kbd{?} (@code{mh-help}) and
-@kbd{C-c ?} in MH-Letter mode. @xref{Using This Manual}.
-@c -------------------------
-@cindex @file{*MH-E Info*}
-@cindex buffers, @file{*MH-E Info*}
-@item *MH-E Info*
-This buffer contains the output of @kbd{M-x mh-version @key{RET}}.
-@c -------------------------
-@cindex @file{*MH-E Log*}
-@cindex buffers, @file{*MH-E Log*}
-@item *MH-E Log*
-This buffer contains the last 100 lines of the output of the various
-MH commands.
-@c -------------------------
-@cindex @file{*MH-E Mail Delivery*}
-@cindex buffers, @file{*MH-E Mail Delivery*}
-@item *MH-E Mail Delivery*
-This buffer contains the transcript of a mail delivery. @xref{Sending
-Message}.
-@c -------------------------
-@cindex @file{*MH-E Recipients*}
-@cindex buffers, @file{*MH-E Recipients*}
-@findex mh-check-whom
-@item *MH-E Recipients*
-@kindex C-c C-w
-This buffer contains the output of @kbd{C-c C-w}
-(@code{mh-check-whom}) and is killed when draft is sent.
-@xref{Checking Recipients}.
-@c -------------------------
-@cindex @file{*MH-E Sequences*}
-@cindex buffers, @file{*MH-E Sequences*}
-@item *MH-E Sequences*
-This buffer contains the output of @kbd{S l}
-(@code{mh-list-sequences}). @xref{Sequences}.
-@c -------------------------
-@cindex @file{*mh-temp*}
-@cindex buffers, @file{*mh-temp*}
-@item *mh-temp*
-This is a scratch, ephemeral, buffer used by MH-E functions. Note that
-it is hidden because the first character in the name is a space.
-You'll generally not have any need for this buffer.
-@end table
-
-@node Scan Line Formats
-@appendix Scan Line Formats
-
-@cindex scan line formats
-
-This appendix discusses how MH-E creates, parses, and manipulates scan
-lines. If you have your own MH scan or inc format files, you
-@strong{can} teach MH-E how to handle them, but it isn't easy as
-you'll see.
-
-@cindex @samp{mh-scan-line-formats} customization group
-@cindex customization group, @samp{mh-scan-line-formats}
-
-This table lists the options in the @samp{mh-scan-line-formats}
-customization group.
-
-@vtable @code
-@item mh-adaptive-cmd-note-flag
-On means that the message number width is determined dynamically
-(default: @samp{on}).
-@c -------------------------
-@item mh-scan-format-file
-Specifies the format file to pass to the scan program (default:
-@samp{Use MH-E scan Format}).
-@c -------------------------
-@item mh-scan-prog
-Program used to scan messages (default: @code{"scan"}).
-@end vtable
-
-@vindex mh-adaptive-cmd-note-flag
-
-There are a couple of caveats when creating your own scan format file.
-First, MH-E will not work if your scan lines do not include message
-numbers. It will work poorly if you don't dedicate a column for
-showing the current message and notations. It is also best to keep the
-first column empty to make room for the cursor and so that text isn't
-obscured by the current message's overlay arrow when running in a
-terminal. You won't be able to use the option
-@code{mh-adaptive-cmd-note-flag} or the threading features
-(@pxref{Threading}).
-
-@cindex message numbers
-@findex mh-set-cmd-note
-@vindex mh-adaptive-cmd-note-flag
-@vindex mh-scan-format-file
-
-If you've created your own format to handle long message numbers,
-you'll be pleased to know you no longer need it since MH-E adapts its
-internal format based upon the largest message number if
-@code{mh-adaptive-cmd-note-flag} is on (the default). If you prefer
-fixed-width message numbers, turn off @code{mh-adaptive-cmd-note-flag}
-and call @code{mh-set-cmd-note} with the width specified by your
-format file (see @code{mh-scan-format-file}). For example, the default
-width is 4, so you would use @samp{(mh-set-cmd-note 4)}.
-
-@vindex mh-adaptive-cmd-note-flag
-@vindex mh-scan-format-file
-@vindex mh-scan-format-mh
-@vindex mh-scan-format-nmh
-
-The default setting for @code{mh-scan-format-file} is @samp{Use MH-E
-scan Format}. This means that the format string will be taken from
-either @code{mh-scan-format-mh} or @code{mh-scan-format-nmh} depending
-on whether MH or nmh (or GNU mailutils MH) is in use. This setting
-also enables you to turn on the option
-@code{mh-adaptive-cmd-note-flag}. You can also set this option to
-@samp{Use Default scan Format} to get the same output as you would get
-if you ran @command{scan} from the shell. If you have a format file
-that you want MH-E to use but not MH, you can set this option to
-@samp{Specify a scan Format File} and enter the name of your format
-file.
-
-@vindex mh-scan-format-file
-@vindex mh-scan-format-mh
-@vindex mh-scan-format-nmh
-
-The scan format that MH-E uses when @code{mh-scan-format-file} is set
-to its default of @samp{Use MH-E scan Format} is held in the variables
-@code{mh-scan-format-nmh} and @code{mh-scan-format-mh} depending on
-whether you are using nmh (or GNU mailutils MH) or not. Typically, you
-create your own format files rather than modifying these variables.
-The value of @code{mh-scan-format-nmh} is:
-
-@smallexample
-(concat
- "%4(msg)"
- "%<(cur)+%| %>"
- "%<@{replied@}-"
- "%?(nonnull(comp@{to@}))%<(mymbox@{to@})t%>"
- "%?(nonnull(comp@{cc@}))%<(mymbox@{cc@})c%>"
- "%?(nonnull(comp@{bcc@}))%<(mymbox@{bcc@})b%>"
- "%?(nonnull(comp@{newsgroups@}))n%>"
- "%<(zero) %>"
- "%02(mon@{date@})/%02(mday@{date@})%<@{date@} %|*%>"
- "%<(mymbox@{from@})%<@{to@}To:%14(decode(friendly@{to@}))%>%>"
- "%<(zero)%17(decode(friendly@{from@}))%> "
- "%(decode@{subject@})%<@{body@}<<%@{body@}%>")
-@end smallexample
-
-@cindex decoding RFC 2047
-@cindex RFC 2047, decoding
-@vindex mh-scan-format-mh
-
-The setting for @code{mh-scan-format-mh} is similar, except that MH
-doesn't have the function @code{decode} (which is used to decode RFC
-2047 encodings).
-
-@cindex notations, scan line
-@cindex scan line notations
-
-These strings are passed to the @command{scan} program via the
-@option{-format} argument. The formats are identical to the defaults
-except that additional hints for fontification have been added to the
-existing notations in the fifth column (remember that in Emacs, the
-columns start at 0). The values of the fifth column, in priority
-order, are: @samp{-} if the message has been replied to, @samp{t} if
-an address in the @samp{To:} field matches one of the mailboxes of the
-current user, @samp{c} if the @samp{Cc:} field matches, @samp{b} if
-the @samp{Bcc:} field matches, and @samp{n} if a non-empty
-@samp{Newsgroups:} field is present.
-
-@cindex @command{scan}
-@cindex MH commands, @command{scan}
-@vindex mh-progs
-@vindex mh-scan-prog
-
-The name of the program that generates a listing of one line per
-message is held in @code{mh-scan-prog} (default: @code{"scan"}).
-Unless this variable contains an absolute pathname, it is assumed to
-be in the @code{mh-progs} directory (@pxref{Getting Started}). You may
-link another program to @command{scan} (see @samp{mh-profile}(5)) to
-produce a different type of listing@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/faswsprs.html, Find and Specify with scan
-pick Ranges Sequences} in the MH book.}.
-
-@cindex regular expressions, scan line formats
-@findex mh-set-cmd-note
-@findex setq
-
-If you change the format of the scan lines you'll need to tell MH-E
-how to parse the new format. As you will see, quite a lot of variables
-are involved to do that. Use @kbd{M-x apropos @key{RET}
-mh-scan.*regexp @key{RET}} to obtain a list of these variables. You
-will also have to call @code{mh-set-cmd-note} if your notations are
-not in column 4 (columns in Emacs start with 0). Note that unlike most
-of the user options described in this manual, these are variables and
-must be set with @code{setq} instead of in a customization buffer. For
-help with regular expressions, see
-@ifnothtml
-@ref{Regexps, , Syntax of Regular Expressions, emacs, The
-GNU Emacs Manual}.
-@end ifnothtml
-@ifhtml
-section
-@uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Regexps.html,
-Syntax of Regular Expressions} in @cite{The GNU Emacs Manual}.
-@end ifhtml
-
-The first variable has to do with pruning out garbage.
-
-@vtable @code
-@cindex @command{inc}
-@cindex MH commands, @command{inc}
-@cindex @command{scan}
-@cindex MH commands, @command{scan}
-@item mh-scan-valid-regexp
-This regular expression describes a valid scan line. This is used to
-eliminate error messages that are occasionally produced by
-@command{inc}@footnote{See the section
-@uref{@value{MH-BOOK-HOME}/reapre.html, Reading Mail: inc show next
-prev} in the MH book.} or @command{scan} (default: @code{"^ *[0-9]"}).
-@end vtable
-
-Next, many variables control how the scan lines are parsed.
-
-@vtable @code
-@vindex mh-folder-body
-@vindex mh-folder-font-lock-keywords
-@item mh-scan-body-regexp
-This regular expression matches the message body fragment. Note that
-the default setting of @code{mh-folder-font-lock-keywords} expects
-this expression to contain at least one parenthesized expression which
-matches the body text as in the default of
-@code{"\\(<<\\([^\n]+\\)?\\)"}. If this regular expression is not
-correct, the body fragment will not be highlighted with the face
-@code{mh-folder-body}.
-@c -------------------------
-@vindex mh-folder-cur-msg-number
-@vindex mh-folder-font-lock-keywords
-@vindex mh-note-cur
-@item mh-scan-cur-msg-number-regexp
-This regular expression matches the current message. It must match
-from the beginning of the line. Note that the default setting of
-@code{mh-folder-font-lock-keywords} expects this expression to contain
-at least one parenthesized expression which matches the message number
-as in the default of @w{@code{"^\\( *[0-9]+\\+\\).*"}}. This
-expression includes the leading space and current message marker
-@samp{+} within the parenthesis since it looks better to highlight
-these items as well. The highlighting is done with the face
-@code{mh-folder-cur-msg-number}. This regular expression should be
-correct as it is needed by non-fontification functions. See also
-@code{mh-note-cur}.
-@c -------------------------
-@vindex mh-folder-date
-@vindex mh-folder-font-lock-keywords
-@vindex mh-scan-sent-to-me-sender-regexp
-@item mh-scan-date-regexp
-This regular expression matches a valid date. It must @strong{not} be
-anchored to the beginning or the end of the line. Note that the
-default setting of @code{mh-folder-font-lock-keywords} expects this
-expression to contain only one parenthesized expression which matches
-the date field as in the default of
-@code{"\\([0-9][0-9]/[0-9][0-9]\\)"}. If this regular expression is
-not correct, the date will not be highlighted with the face
-@code{mh-folder-date}.
-@c -------------------------
-@vindex mh-folder-deleted
-@vindex mh-folder-font-lock-keywords
-@vindex mh-note-deleted
-@item mh-scan-deleted-msg-regexp
-This regular expression matches deleted messages. It must match from
-the beginning of the line. Note that the default setting of
-@code{mh-folder-font-lock-keywords} expects this expression to contain
-at least one parenthesized expression which matches the message number
-as in the default of @code{"^\\( *[0-9]+\\)D"}. This expression
-includes the leading space within the parenthesis since it looks
-better to highlight it as well. The highlighting is done with the face
-@code{mh-folder-deleted}. This regular expression should be correct as
-it is needed by non-fontification functions. See also
-@code{mh-note-deleted}.
-@c -------------------------
-@vindex mh-folder-font-lock-keywords
-@vindex mh-folder-msg-number
-@item mh-scan-good-msg-regexp
-This regular expression matches ``good'' messages. It must match from
-the beginning of the line. Note that the default setting of
-@code{mh-folder-font-lock-keywords} expects this expression to contain
-at least one parenthesized expression which matches the message number
-as in the default of @w{@code{"^\\( *[0-9]+\\)[^D^0-9]"}}. This
-expression includes the leading space within the parenthesis since it
-looks better to highlight it as well. The highlighting is done with
-the face @code{mh-folder-msg-number}. This regular expression should
-be correct as it is needed by non-fontification functions.
-@c -------------------------
-@vindex mh-scan-format-file
-@item mh-scan-msg-format-regexp
-This regular expression finds the message number width in a scan
-format. Note that the message number must be placed in a parenthesized
-expression as in the default of @code{"%\\([0-9]*\\)(msg)"}. This
-variable is only consulted if @code{mh-scan-format-file} is set to
-@samp{Use MH-E scan Format}.
-@c -------------------------
-@vindex mh-scan-format-file
-@item mh-scan-msg-format-string
-This is a format string for the width of the message number in a scan
-format. Use @samp{0%d} for zero-filled message numbers. This variable
-is only consulted if @code{mh-scan-format-file} is set to @samp{Use
-MH-E scan Format} (default: @code{"%d"}).
-@c -------------------------
-@item mh-scan-msg-number-regexp
-This regular expression extracts the message number. It must match
-from the beginning of the line. Note that the message number must be
-placed in a parenthesized expression as in the default of @w{@code{"^
-*\\([0-9]+\\)"}}.
-@c -------------------------
-@item mh-scan-msg-overflow-regexp
-This regular expression matches overflowed message numbers (default:
-@code{"^[?0-9][0-9]"}).
-@c -------------------------
-@item mh-scan-msg-search-regexp
-This regular expression matches a particular message. It is a format
-string; use @samp{%d} to represent the location of the message number
-within the expression as in the default of @code{"^[^0-9]*%d[^0-9]"}.
-@c -------------------------
-@vindex mh-folder-address
-@vindex mh-folder-font-lock-keywords
-@vindex mh-folder-to
-@item mh-scan-rcpt-regexp
-This regular expression specifies the recipient in messages you sent.
-Note that the default setting of @code{mh-folder-font-lock-keywords}
-expects this expression to contain two parenthesized expressions. The
-first is expected to match the @samp{To:} that the default scan format
-file generates. The second is expected to match the recipient's name
-as in the default of @code{"\\(To:\\)\\(..............\\)"}. If this
-regular expression is not correct, the @samp{To:} string will not be
-highlighted with the face @code{mh-folder-to} and the recipient will not be
-highlighted with the face @code{mh-folder-address}.
-@c -------------------------
-@vindex mh-folder-font-lock-keywords
-@vindex mh-folder-refiled
-@vindex mh-note-refiled
-@item mh-scan-refiled-msg-regexp
-This regular expression matches refiled messages. It must match from
-the beginning of the line. Note that the default setting of
-@code{mh-folder-font-lock-keywords} expects this expression to contain
-at least one parenthesized expression which matches the message number
-as in the default of @w{@code{"^\\( *[0-9]+\\)\\^"}}. This expression
-includes the leading space within the parenthesis since it looks
-better to highlight it as well. The highlighting is done with the face
-@code{mh-folder-refiled}. This regular expression should be correct as
-it is needed by non-fontification functions. See also
-@code{mh-note-refiled}.
-@c -------------------------
-@vindex mh-folder-font-lock-keywords
-@vindex mh-folder-sent-to-me-sender
-@vindex mh-mh-folder-sent-to-me-hint
-@vindex mh-scan-format-nmh
-@item mh-scan-sent-to-me-sender-regexp
-This regular expression matches messages sent to us. Note that the
-default setting of @code{mh-folder-font-lock-keywords} expects this
-expression to contain at least two parenthesized expressions. The
-first should match the fontification hint (see
-@code{mh-scan-format-nmh}) and the second should match the user name
-as in the default of
-@w{@code{"^ *[0-9]+.\\([bct]\\).....[ ]*\\(..................\\)"}}.
-If this regular expression is not correct, the notation hints will not
-be highlighted with the face @code{mh-mh-folder-sent-to-me-hint} and
-the sender will not be highlighted with the face
-@code{mh-folder-sent-to-me-sender}.
-@c -------------------------
-@vindex mh-folder-followup
-@vindex mh-folder-font-lock-keywords
-@vindex mh-folder-subject
-@item mh-scan-subject-regexp
-This regular expression matches the subject. It must match from the
-beginning of the line. Note that the default setting of
-@samp{mh-folder-font-lock-keywords} expects this expression to contain
-at least three parenthesized expressions. The first is expected to
-match the @samp{Re:} string, if any, and is highlighted with the face
-@code{mh-folder-followup}. The second matches an optional bracketed
-number after @samp{Re:}, such as in @samp{Re[2]:} (and is thus a
-sub-expression of the first expression). The third is expected to
-match the subject line itself which is highlighted with the face
-@code{mh-folder-subject}. For example, the default is
-@w{@code{"^ *[0-9]+........[ ]*...................}}@*
-@w{@code{\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)"}}.
-This regular expression should be correct as it is needed by
-non-fontification functions. Note that this example is broken up on
-two lines for readability, but is actually a single string.
-@end vtable
-
-Finally, there are a slew of variables that control how MH-E annotates
-the scan lines.
-
-@vtable @code
-@findex mh-set-cmd-note
-@vindex mh-adaptive-cmd-note-flag
-@item mh-cmd-note
-Column for notations (default: 4). This variable should be set with
-the function @code{mh-set-cmd-note}. This variable may be updated
-dynamically if @code{mh-adaptive-cmd-note-flag} is on. The following
-variables contain the notational characters. Note that columns in
-Emacs start with 0.
-@c -------------------------
-@item mh-note-copied
-Messages that have been copied are marked by this character (default:
-@code{?C}).
-@c -------------------------
-@vindex mh-scan-cur-msg-number-regexp
-@item mh-note-cur
-The current message (in MH, not in MH-E) is marked by this character
-(default: @code{?+}). See also @code{mh-scan-cur-msg-number-regexp}.
-@c -------------------------
-@vindex mh-scan-deleted-msg-regexp
-@item mh-note-deleted
-Messages that have been deleted are marked by this character (default:
-@code{?D}). See also @code{mh-scan-deleted-msg-regexp}.
-@c -------------------------
-@item mh-note-dist
-Messages that have been redistributed are marked by this character
-(default: @code{?R}).
-@c -------------------------
-@item mh-note-forw
-Messages that have been forwarded are marked by this character
-(default: @code{?F}).
-@c -------------------------
-@item mh-note-printed
-Messages that have been printed are marked by this character (default:
-@code{?P}).
-@c -------------------------
-@vindex mh-scan-refiled-msg-regexp
-@item mh-note-refiled
-Messages that have been refiled are marked by this character (default:
-@code{?^}). See also @code{mh-scan-refiled-msg-regexp}.
-@c -------------------------
-@item mh-note-repl
-Messages that have been replied to are marked by this character
-(default: @code{?-}).
-@c -------------------------
-@item mh-note-seq
-Messages in a user-defined sequence are marked by this character
-(default: @code{?%}). Messages in the @samp{search} sequence are
-marked by this character as well.
-@end vtable
-
-For example, let's say I have the following in @file{scan.format}
-which displays the sender, the subject, and the message number. This
-format places a @samp{+} after the message number for the current
-message according to MH; it also uses that column for notations.
-
-@smallexample
-%20(decode(friendly@{from@})) %50(decode@{subject@}) %4(msg)%<(cur)+%| %>
-@end smallexample
-
-@vindex mh-adaptive-cmd-note-flag
-@vindex mh-scan-format-file
-@vindex mh-scan-format-file@r{, example}
-
-The first thing you have to do is tell MH-E to use this file.
-Customize @code{mh-scan-format-file} and set its value to @samp{Use
-Default scan Format}. If you didn't get already turn off
-@code{mh-adaptive-cmd-note-flag}, you'll need to do that first.
-
-Next, tell MH-E what a valid scan line looks like so that you can at
-least display the output of scan in your MH-Folder buffer.
-
-@vindex mh-scan-valid-regexp@r{, example}
-
-@smalllisp
-(setq mh-scan-valid-regexp "[0-9]+[+D^ ]$")
-@end smalllisp
-
-Now, in order to get rid of the @samp{Cursor not pointing to message}
-message, you need to tell MH-E how to access the message number. You
-should also see why MH-E requires that you include a message number in
-the first place.
-
-@vindex mh-scan-msg-number-regexp@r{, example}
-@vindex mh-scan-msg-search-regexp@r{, example}
-
-@smalllisp
-(setq mh-scan-msg-number-regexp "^.* \\([0-9]+\\)[+D^ ]$")
-(setq mh-scan-msg-search-regexp " %d[+D^ ]$")
-@end smalllisp
-
-In order to get the next and previous commands working, add this.
-
-@vindex mh-scan-good-msg-regexp@r{, example}
-
-@smalllisp
-(setq mh-scan-good-msg-regexp "^.* \\([0-9]+\\)[+D^ ]$")
-@end smalllisp
-
-Note that the current message isn't marked with a @samp{+} when moving
-between the next and previous messages. Here is the code required to
-get this working.
-
-@vindex set-mh-cmd-note@r{, example}
-@vindex mh-scan-cur-msg-number-regexp@r{, example}
-
-@smalllisp
-(set-mh-cmd-note 76)
-(setq mh-scan-cur-msg-number-regexp "^.* \\([0-9]+\\)\\+$")
-@end smalllisp
-
-Finally, add the following to delete and refile messages.
-
-@vindex mh-scan-deleted-msg-regexp@r{, example}
-@vindex mh-scan-refiled-msg-regexp@r{, example}
-
-@smalllisp
-(setq mh-scan-deleted-msg-regexp "^.* \\([0-9]+\\)D$")
-(setq mh-scan-refiled-msg-regexp "^.* \\([0-9]+\\)\\^$")
-@end smalllisp
-
-This is just a bare minimum; it's best to adjust all of the regular
-expressions to ensure that MH-E and highlighting perform well.
-
-@node Procmail
-@appendix Reading Mailing Lists Effectively
-
-@cindex @command{procmail}
-@cindex @command{slocal}
-@cindex Gnus
-@cindex MH commands, @command{slocal}
-@cindex Unix commands, @command{procmail}
-@cindex mailing lists, reading
-
-This appendix explains how to use procmail, which can
-file mail from mailing lists into folders which can then
-be read easily with MH-E@footnote{The MH equivalent, @command{slocal},
-can be used as well, but procmail was more flexible and more packages
-exist for procmail than for slocal.}. Unfortunately, procmail is no
-longer recommended due to its security vulnerabilities.
-Some mailing lists have such
-high traffic that Gnus must be used and I discuss how to use Gnus
-side-by-side with MH-E.
-
-@cindex @file{.procmailrc}
-@cindex files, @file{.procmailrc}
-
-First, I'll describe how to put mail from your mailing lists directly
-into an MH folder using @command{procmail}. First, add the following
-to @file{~/.procmailrc}. While the logging variables aren't strictly
-necessary, they are extremely useful.
-
-@smallexample
-[1] # Update PATH so procmail can find myrcvstore, rcvstore and mhparam.
-[2] PATH=$PATH:/usr/lib/mh:/usr/bin/mh:$HOME/bin
-[3]
-[4] # Point LOGFILE at the actual log file.
-[5] LOGFILE=$HOME/.procmail.log
-[6]
-[7] # This setting provides just the right amount of information.
-[8] LOGABSTRACT=all
-[9]
-[10] # Uncomment the following line to see how your patterns match.
-[11] #VERBOSE=yes
-[12]
-[13] # Place mail sent to any MH-E mailing list in +mh-e.
-[14] :0 w: mh-e$LOCKEXT
-[15] * ^TO.*mh-e-.*@@.*sourceforge.net
-[16] | myrcvstore -create +mh-e
-@end smallexample
-
-@cindex @command{rcvstore}
-@cindex MH commands, @command{rcvstore}
-
-Line 14 creates a lock file in your mail directory based upon the name
-of the folder. This is done because @command{rcvstore} does not
-perform locking. While this lock file will prevent @command{procmail}
-from writing to a folder concurrently, there is a slight chance that
-you might lose a message if you're performing operations on a folder
-at the same time @command{rcvstore} is placing a message there. You
-have been warned. Now that that disclaimer is out of the way, note
-that I've been using this set-up for over a decade and haven't lost
-anything to my knowledge@footnote{See
-@uref{https://savannah.nongnu.org/bugs/?func=detailbug&bug_id=4361&group_id=2166,
-Savannah issue #4361} to see if @command{rcvstore} locking is still an
-issue.}.
-
-@cindex @samp{Unseen-Sequence} MH profile component
-@cindex MH profile component, @samp{Unseen-Sequence}
-
-Line 16 uses the following script, @code{myrcvstore}, to massage the
-message as described in the comment and file the message in the given
-folder@footnote{The @samp{-create} argument wasn't always the default
-to @command{rcvstore}.}.
-
-@smallexample
-#! /bin/sh
-
-# Accepts a message on standard input and passes it through rcvstore
-# after first passing it through any filters. All arguments are passed
-# on to rcvstore.
-
-# Force the "From user date" to become part of header. One reason this
-# is done is because the presence of the From field confuses dist so
-# that dist adds a new header, rather than using the existing header.
-# Note that this should not be done for any message that goes into a
-# Gnus incoming file (Gnus will thrown an error) nor should it be
-# applied to any message that goes to the system mailbox because the
-# entire mailbox will be incorporated as a single message.
-formail -c -z -R 'From ' X-Envelope-From: |
-rcvstore $@@
-@end smallexample
-
-If your version of @command{rcvstore} doesn't add messages to the
-@samp{unseen} sequence by default, add the following line to your MH
-profile:
-
-@smallexample
-Unseen-Sequence: unseen
-@end smallexample
-
-Now view your new messages with the speedbar (@pxref{Speedbar}) or with
-@kbd{F n} (@code{mh-index-new-messages}). @xref{Folders}.
-
-If you're on a mailing list that is so voluminous that it is
-impossible to read every message, it usually better to read the
-mailing list like a newsgroup in a news reader. Emacs has a built-in
-newsreader called Gnus. The remainder of this appendix talks about how
-to use Gnus with an MH message store.
-
-This table contains a list of Gnus options that you will have to
-modify. Note that for them to become accessible, you'll have to load
-@file{nnml.el} first. This can be done with @kbd{M-x load-library
-@key{RET} nnml @key{RET}}.
-
-@vtable @code
-@item gnus-secondary-select-methods
-Select the @samp{nnml} value. This select method uses directories for
-folders and individual files for messages, just like MH@. You do not
-have to set an address.
-@c -------------------------
-@item mail-sources
-Select the @samp{Several files in a directory} value, check the
-@samp{Path} box and enter @file{~/Mail} to tell Gnus where to find
-your mail.
-@c -------------------------
-@vindex mail-user-agent
-@item message-mail-user-agent
-In order to send mail within Gnus using MH-E, set this option to
-@samp{mail-user-agent} and set the @code{mail-user-agent} option to
-@samp{Emacs interface to MH}.
-@c -------------------------
-@item nnmail-keep-last-article
-Since Gnus keeps track of which messages you have read, it would be
-bad if Gnus expired the last message, for example, message 100, and
-@command{rcvstore} gave the next new message number 1. Gnus would then
-ignore it since it thinks that you've read messages 1--100. Turning on
-this option ensures that the last message is never removed thereby
-eliminating this problem.
-@end vtable
-
-Next add the following to @file{~/.procmailrc}. If you don't subscribe
-to the GnuCash mailing list, substitute one to which you are
-subscribed.
-
-@smallexample
-PATH=$PATH:/usr/bin/mh
-MAILDIR=$HOME/`mhparam Path`
-# Place mail sent to the GnuCash mailing list in gnucash.spool, where
-# Gnus will pick it up.
-:0:
-* ^TO.*gnucash.*@@.*gnucash.org
-gnucash.spool
-@end smallexample
-
-Wait for some messages to appear in @file{gnucash.spool} and run Gnus
-with @kbd{M-x gnus @key{RET}}. To view the folder created in the
-example above, you would tell Gnus about it the first time only with
-@kbd{G m gnucash @key{RET} nnml @key{RET}}. In MH-E, this folder is
-known as @samp{+gnucash}.
-
-@node Odds and Ends
-@appendix Odds and Ends
-
-This appendix covers a few topics that don't fit elsewhere. Here I
-tell you how to report bugs and how to get on the MH-E mailing lists.
-I also point out some additional sources of information.
-
-@menu
-* Bug Reports::
-* Mailing Lists::
-* MH FAQ and Support::
-* Getting MH-E::
-@end menu
-
-@node Bug Reports
-@appendixsec Bug Reports
-
-@cindex bugs
-@cindex SourceForge
-@findex mh-version
-
-Bug reports should be filed at
-@uref{https://sourceforge.net/p/mh-e/bugs/, SourceForge}. You need to
-be a SourceForge user to submit bug reports, but this is easy enough
-to do that it shouldn't be a restriction for you. Please include the
-output of @kbd{M-x mh-version} (@pxref{Miscellaneous}) in any bug
-report you send unless you're 110% positive we won't ask for it.
-
-@node Mailing Lists
-@appendixsec MH-E Mailing Lists
-
-@cindex SourceForge
-@cindex mailing lists
-
-There are several mailing lists for MH-E@. They are @i{mh-e-users at
-lists.sourceforge.net}, @i{mh-e-announce at lists.sourceforge.net},
-and @i{mh-e-devel at lists.sourceforge.net}. You can subscribe or view
-the archives at @uref{https://sourceforge.net/p/mh-e/mailman/,
-SourceForge}. Do not report bugs on these lists; please submit them
-via SourceForge (@pxref{Bug Reports}).
-
-@node MH FAQ and Support
-@appendixsec MH FAQ and Support
-
-@cindex FAQ
-@cindex MH FAQ
-
-The article @uref{https://www.newt.com/faq/mh.html, @cite{MH Frequently
-Asked Questions (FAQ) with Answers}} appears monthly in the newsgroup
-@samp{comp.mail.mh}. While very little is there that deals with MH-E
-specifically, there is an incredible wealth of material about MH
-itself which you will find useful.
-
-@cindex support
-
-You can find FAQs on MH-E by searching for @i{labels:support} on the
-@uref{https://sourceforge.net/p/mh-e/bugs/search/?q=labels%3Asupport,
-Tickets} page on SourceForge. If you don't find the answer to your
-question, file a ticket and your question will become a new FAQ!
-
-@node Getting MH-E
-@appendixsec Getting MH-E
-
-@cindex MH-E, obtaining
-@cindex getting MH-E
-@cindex obtaining MH-E
-
-Since MH-E 8.6 was released in 2016, its development migrated to the
-Emacs repository. MH-E is now only supported in the version of Emacs
-in which it appears. Old releases of MH-E are still available for
-download at @uref{https://sourceforge.net/projects/mh-e/files/,
-SourceForge}.
-
-@cindex files, @samp{MH-E-NEWS}
-@cindex files, @samp{README}
-@cindex news
-@cindex @samp{MH-E-NEWS}
-@cindex @samp{README}
-@findex mh-version
-
-After you download and extract the MH-E tarball, read the
-@file{README} file and @file{MH-E-NEWS}. These correspond to the
-release notes and change log mentioned above. The file @file{README}
-contains instructions on installing MH-E@. If you're already running
-Emacs, please quit that session and start again to load in the new
-MH-E@. Check that you're running the new version with the command
-@kbd{M-x mh-version}.
-
-@cindex contributed software
-@cindex manual
-@cindex documentation
-
-In addition to the mh-e package, the
-@uref{https://sourceforge.net/projects/mh-e/files/, SourceForge} site
-also contains doc and contrib packages. The former is the latest
-release of this manual, and the latter contains a few contributed
-packages you might find useful.
-
-@node History
-@appendix History of MH-E
-
-@cindex Bill Wohler
-@cindex Brian Reid
-@cindex Gildea, Stephen
-@cindex Jim Larus
-@cindex Larus, Jim
-@cindex MH-E, versions
-@cindex Reid, Brian
-@cindex SourceForge
-@cindex Stephen Gildea
-@cindex Wohler, Bill
-@cindex history of MH-E
-@cindex versions of MH-E
-
-MH-E was originally written by Brian Reid in 1983 and has changed
-hands several times since then. Jim Larus wanted to do something
-similar for GNU Emacs, and ended up completely rewriting it that same
-year. In 1989, Stephen Gildea picked it up and added many
-improvements. Bill Wohler then took over in 2000 and moved its
-development to @uref{https://sourceforge.net/, SourceForge}.
-Since 2016, MH-E development occurs within the Emacs repository.
-
-@menu
-* From Brian Reid::
-* From Jim Larus::
-* From Stephen Gildea::
-* From Bill Wohler::
-@end menu
-
-@node From Brian Reid
-@appendixsec From Brian Reid
-
-@cindex Brian Reid
-@cindex Reid, Brian
-
-One day in 1983 I got the flu and had to stay home from work for three
-days with nothing to do. I used that time to write MHE@. The
-fundamental idea behind MHE was that it was a ``puppeteer'' driving
-the MH programs underneath it. MH had a model that the editor was
-supposed to run as a sub-process of the mailer, which seemed to me at
-the time to be the tail wagging the dog. So I turned it around and
-made the editor drive the MH programs. I made sure that the UCI people
-(who were maintaining MH at the time) took in my changes and made them
-stick.
-
-Today, I still use my own version of MHE because I don't at all like
-the way that GNU MH-E works and I've never gotten to be good enough at
-hacking Emacs Lisp to make GNU MH-E do what I want. The Gosling-emacs
-version of MHE and the GNU Emacs version of MH-E have almost nothing
-in common except similar names. They work differently, have different
-conceptual models, and have different key bindings@footnote{After
-reading this article, I questioned Brian about his version of MHE, and
-received some great ideas for improving MH-E such as a dired-like
-method of selecting folders; and removing the prompting when sending
-mail, filling in the blanks in the draft buffer instead. I passed them
-on to Stephen Gildea, the current maintainer, and he was excited about
-the ideas as well. Perhaps one day, MH-E will again resemble MHE
-(draft form editing was introduced in version 7.4).}.
-
-Brian Reid, June 1994
-
-@node From Jim Larus
-@appendixsec From Jim Larus
-
-@cindex Jim Larus
-@cindex Larus, Jim
-
-Brian Reid, while at CMU or shortly after going to Stanford wrote a
-mail reading program called MHE for Gosling Emacs. It had much the
-same structure as MH-E (i.e., invoked MH programs), though it was
-simpler and the commands were slightly different. Unfortunately, I no
-longer have a copy so the differences are lost in the mists of time.
-
-In '82--83, I was working at BBN and wrote a lot of mlisp code in
-Gosling Emacs to make it look more like Tennex Emacs. One of the
-packages that I picked up and improved was Reid's mail system. In '83,
-I went back to Berkeley. About that time, Stallman's first version of
-GNU Emacs came out and people started to move to it from Gosling Emacs
-(as I recall, the transition took a year or two). I decided to port
-Reid's MHE and used the mlisp to Emacs Lisp translator that came with
-GNU Emacs. It did a lousy job and the resulting code didn't work, so I
-bit the bullet and rewrote the code by hand (it was a lot smaller and
-simpler then, so it took only a day or two).
-
-Soon after that, MH-E became part of the standard Emacs distribution
-and suggestions kept dribbling in for improvements. MH-E soon reached
-sufficient functionality to keep me happy, but I kept on improving it
-because I was a graduate student with plenty of time on my hands and
-it was more fun than my dissertation. In retrospect, the one thing
-that I regret is not writing any documentation, which seriously
-limited the use and appeal of the package.
-
-@cindex @command{xmh}, in MH-E history
-
-In '89, I came to Wisconsin as a professor and decided not to work on
-MH-E@. It was stable, except for minor bugs, and had enough
-functionality, so I let it be for a few years. Stephen Gildea of BBN
-began to pester me about the bugs, but I ignored them. In 1990, he
-went off to the X Consortium, said good bye, and said that he would
-now be using @command{xmh}. A few months later, he came back and said
-that he couldn't stand @command{xmh} and could I put a few more bug fixes
-into MH-E@. At that point, I had no interest in fixing MH-E, so I gave
-the responsibility of maintenance to him and he has done a fine job
-since then.
-
-Jim Larus, June 1994
-
-@node From Stephen Gildea
-@appendixsec From Stephen Gildea
-
-@cindex Gildea, Stephen
-@cindex Stephen Gildea
-
-In 1987 I went to work for Bolt Beranek and Newman, as Jim had before
-me. In my previous job, I had been using RMAIL, but as my folders tend
-to run large, I was frustrated with the speed of RMAIL@. However, I
-stuck with it because I wanted the GNU Emacs interface. I am very
-familiar and comfortable with the Emacs interface (with just a few
-modifications of my own) and dislike having to use applications with
-embedded editors; they never live up to Emacs.
-
-MH is the mail reader of choice at BBN, so I converted to it. Since I
-didn't want to give up using an Emacs interface, I started using MH-E@.
-As is my wont, I started hacking on it almost immediately. I first
-used version 3.4m. One of the first features I added was to treat the
-folder buffer as a file-visiting buffer: you could lock it, save it,
-and be warned of unsaved changes when killing it. I also worked to
-bring its functionality a little closer to RMAIL@. Jim Larus was very
-cooperative about merging in my changes, and my efforts first appeared
-in version 3.6, distributed with Emacs 18.52 in 1988. Next I decided
-MH-E was too slow and optimized it a lot. Version, 3.7, distributed
-with Emacs 18.56 in 1990, was noticeably faster.
-
-When I moved to the X Consortium I became the first person there to
-not use xmh. (There is now one other engineer there using MH-E@.) About
-this point I took over maintenance of MH-E from Jim and was finally
-able to add some features Jim hadn't accepted, such as the backward
-searching undo. My first release was 3.8 (Emacs 18.58) in 1992.
-
-Now, in 1994, we see a flurry of releases, with both 4.0 and 5.0.
-Version 4.0 added many new features, including background folder
-collection and support for composing @sc{mime} messages. (Reading
-@sc{mime} messages remains to be done, alas.) While writing this book,
-Bill Wohler gave MH-E its closest examination ever, uncovering bugs
-and inconsistencies that required a new major version to fix, and so
-version 5 was released.
-
-Stephen Gildea, June 1994
-
-@node From Bill Wohler
-@appendixsec From Bill Wohler
-
-@cindex Wohler, Bill
-@cindex Bill Wohler
-
-The preface originally included the following text which I use to
-begin my story:
-
-@quotation
-But it's important to note a brief history of MH-E.
-
-@w{Version 3} was prevalent through the @w{Emacs 18} and early
-@w{Emacs 19} years. Then @w{Version 4} came out (@w{Emacs 19.23}),
-which introduced several new and changed commands. Next, @w{Version
-5.0} was released, which fixed some bugs and incompatibilities, and
-was incorporated into @w{Emacs 19.29}.
-@end quotation
-
-After a long break, Stephen handed the reins over to me in 2000. I
-moved the project to a new site called SourceForge and organized a
-great team of developers. Our first release in late 2001 was version
-6. It appeared around the time of Emacs 21.2 and had menus and tool
-bar buttons.
-
-Then, indexed searches, improved MIME handling, a speedbar, multiple
-identities, alias completion, an index view of unseen messages, spam
-software support, Face and X-Image-URL header field support, Fcc
-completion, arbitrary range handling, and draft form editing were
-introduced in the version 7 series around the time of Emacs 21.4
-(2004). Still, Emacs itself contained version 5 of MH-E released back
-in 1994.
-
-Version 8 development was mostly driven by the rewrite of the manual.
-It also brought GNU mailutils MH support, S/MIME support, picon
-support, and an improved interface for hiding header fields. The CVS
-repository was migrated from SourceForge to Savannah (only for those
-files that were already part of Emacs) and the software was completely
-reorganized to push back two decades of entropy. Version 8 appeared in
-Emacs 22.1 in 2006.
-
-Development was then quiet for a couple of years. Emacs 23.1, which is
-due out in 2009, will contain version 8.1. This version includes a few
-new features and several bug fixes.
-
-Bill Wohler, August 2008
-
-@node GFDL
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-@node GPL
-@appendix GNU General Public License
-@include gpl.texi
-
-@node Key Index
-@unnumbered Key (Character) Index
-@printindex ky
-
-@node Command Index
-@unnumbered Command Index
-@printindex fn
-
-@node Option Index
-@unnumbered Option (Variable) Index
-@printindex vr
-
-@node Concept Index
-@unnumbered Concept Index
-@printindex cp
-
-@bye
-
-@c Ispell Helpers
-@c
-@c The following are words that ispell should ignore that would not
-@c normally be in a dictionary (global or personal). Be careful not to
-@c include words here that could potentially be typos of other words
-@c (such as url, elisp, or MHE).
-@c
-@c LocalWords: CTRL ESC SPC f's
-@c LocalWords: addr Aliasfile alist
-@c LocalWords: Baushke Bcc BBN Beranek bogofilter bogofilter's
-@c LocalWords: cmd CMU contrib cron
-@c LocalWords: DesBrisay Dcc devel dir dired docstring filll forw
-@c LocalWords: GECOS Gildea Gildea's Ginnean GnuCash goto htm
-@c LocalWords: ImageMagick inbox ispell keychain
-@c LocalWords: Larus licensor LocalWords lookup lpr
-@c LocalWords: makeinfo mairix mbox mh mhbuild mhl mhpath mlisp
-@c LocalWords: MML msg multipart
-@c LocalWords: Namazu NIS nenscript nnml num
-@c LocalWords: packmbox passphrase pathname prev procmail prog repl
-@c LocalWords: slocal sortm SpamAssassin spammers SpamProbe SpamProbe's
-@c LocalWords: sublicense supercite speedbar
-@c LocalWords: Tennex texi texinfo Thelen thelenm
-@c LocalWords: UCI undeleted whatnow wohler xmh ypcat
-@c
-@c See https://oreillymedia.github.io/production-resources/styleguide/.
-@c See https://en.wikipedia.org/.
-@c
-@c Note the lowercase mh which is needed to avoid hits in the
-@c functions and variables. Occasionally, check for accidental
-@c inclusion of mh in text by uncommenting the following and executing
-@c it with C-x C-e. You want to see "Search failed"
-@c (let ((case-fold-search nil))
-@c (goto-char (point-min))
-@c (search-forward-regexp "^mh\\( \\|$\\)"))
-@c
-@c An extremely useful setting for texinfo-mode-hook is:
-@c (add-to-list
-@c 'ispell-skip-region-alist
-@c (list
-@c (concat "\\(@\\(small\\)?\\(example\\|lisp\\)"
-@c "\\(@\\([irw]\\|code\\|var\\){[^}]+}\\|"
-@c "@[@{}.]\\|"
-@c "[^@]\\|"
-@c "@\\(end \\)?group\\|"
-@c "@\\(end \\)?cartouche\\)+"
-@c "@end \\(small\\)?\\(example\\|lisp\\)\\|"
-@c "@\\(code\\|command\\|file\\|kbd\\|sc\\){[^}]+}\\|"
-@c "^@end [a-z]+$\\|"
-@c "^@\\([fv]\\|print\\)index .*$\\|"
-@c "@uref{[^,]+,\\|"
-@c "@[a-z]+\\|"
-@c "/[a-z.]+[/}]\\)")))))
-@c
-@c Cross References
-@c
-@c See existing cross-references to the Emacs manual and the Emacs
-@c Lisp manual (search for ``GNU Emacs Manual'' and ``GNU
-@c Emacs Lisp Reference Manual'' respectively).
-
-@c @ftable Sorting
-@c
-@c As per index (sort of): Punctuation, keyboard characters (such as
-@c RET and BS) upper and lowercase mixed (lower comes before
-@c uppercase), control characters go with uppercase C, meta characters
-@c go with uppercase M.
-@c In some cases, the sort isn't strictly ASCII.
-@c For example, SPC (mh-page-msg) reads better before BS
-@c (mh-previous-page) and . (mh-show) is better before ,
-@c (mh-header-display).
-
-@c @vtable Sorting
-@c
-@c Alphabetical, pull hooks into their own table.
-
-@c Local Variables:
-@c sentence-end-double-space: nil
-@c End:
+++ /dev/null
-;;; edt-user.el --- Sample user customizations for Emacs EDT emulation -*- lexical-binding: t -*-
-
-;; Copyright (C) 1986, 1992-1993, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Kevin Gallagher <kevin.gal@verizon.net>
-;; Keywords: emulations
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This is an example of the `edt-user.el' file that you can use
-;; to customize the Emacs EDT emulation mode. Copy this file to
-;; somewhere in your `load-path', and edit it as desired.
-;; See Info node `edt' for more details.
-
-;; ====================================================================
-
-\f
-;;; Code:
-
-;;;;
-;;;; Setup user custom EDT key bindings.
-;;;;
-
-(defun edt-setup-user-bindings ()
- "Assigns user custom EDT Emulation keyboard bindings."
-
- ;; PF1 (GOLD), PF2, PF3, PF4
- ;;
- ;; This file MUST contain a binding of PF1 to edt-user-gold-map. So
- ;; DON'T CHANGE OR DELETE THE REGULAR KEY BINDING OF PF1 BELOW!
- ;; (However, you may change the GOLD-PF1 binding, if you wish.)
- (edt-bind-function-key "PF1" 'edt-user-gold-map 'edt-mark-section-wisely)
- (edt-bind-function-key "PF2" 'query-replace 'other-window)
- (edt-bind-function-key "PF4" 'edt-delete-entire-line 'edt-undelete-line)
-
- ;; EDT Keypad Keys
- (edt-bind-function-key "KP1" 'edt-word-forward 'edt-change-case)
- (edt-bind-function-key "KP3" 'edt-word-backward 'edt-copy)
- (edt-bind-function-key "KP6" 'edt-cut-or-copy 'yank)
- (edt-bind-function-key "KP8" 'edt-scroll-window 'fill-paragraph)
- (edt-bind-function-key "KP9" 'open-line 'edt-eliminate-all-tabs)
- (edt-bind-function-key "KPP"
- 'edt-toggle-select 'edt-line-to-middle-of-window)
- (edt-bind-function-key "KPE" 'edt-change-direction 'overwrite-mode)
-
- ;; GOLD bindings for regular keys.
- (edt-bind-gold-key "a" 'edt-append)
- (edt-bind-gold-key "A" 'edt-append)
- (edt-bind-gold-key "h" 'edt-electric-user-keypad-help)
- (edt-bind-gold-key "H" 'edt-electric-user-keypad-help)
-
- ;; Control bindings for regular keys.
- ;;; Leave binding of C-c as original prefix key.
- (edt-bind-key "\C-j" 'edt-duplicate-word)
- (edt-bind-key "\C-k" 'edt-define-key)
- (edt-bind-gold-key "\C-k" 'edt-restore-key)
- (edt-bind-key "\C-l" 'edt-learn)
- ;;; Leave binding of C-m to newline.
- (edt-bind-key "\C-n" 'edt-set-screen-width-80)
- (edt-bind-key "\C-o" 'open-line)
- (edt-bind-key "\C-p" 'fill-paragraph)
- ;;; Leave binding of C-r to isearch-backward.
- ;;; Leave binding of C-s to isearch-forward.
- (edt-bind-key "\C-t" 'edt-display-the-time)
- (edt-bind-key "\C-v" 'redraw-display)
- (edt-bind-key "\C-w" 'edt-set-screen-width-132)
- ;;; Leave binding of C-x as original prefix key.
-)
-\f
-;;;
-;;; LK-201 KEYBOARD USER EDT KEYPAD HELP
-;;;
-
-(defun edt-user-keypad-help ()
- "
- USER EDT Keypad Active
-
- +----------+----------+----------+----------+
- F7: Copy Rectangle |Prev Line |Next Line |Bkwd Char |Frwd Char |
- F8: Cut Rect Overstrike | (UP) | (DOWN) | (LEFT) | (RIGHT) |
- G-F8: Paste Rect Overstrike |Window Top|Window Bot|Bkwd Sent |Frwd Sent |
- F9: Cut Rect Insert +----------+----------+----------+----------+
- G-F9: Paste Rect Insert
- F10: Cut Rectangle
-G-F10: Paste Rectangle
- F11: ESC +----------+----------+----------+----------+
- F12: Beginning of Line | GOLD |Query Repl| FNDNXT |Del Ent L |
-G-F12: Delete Other Windows | (PF1) | (PF2) | (PF3) | (PF4) |
- F13: Delete to Begin of Word |Mark Wisel|Other Wind| FIND | UND L |
- HELP: Keypad Help +----------+----------+----------+----------+
-G-HELP: Emacs Help | PAGE |Scroll Win|Open Line | DEL W |
- DO: Execute extended command | (7) | (8) | (9) | (-) |
- C-a: Beginning of Line |Ex Ext Cmd|Fill Parag|Elim Tabs | UND W |
- C-b: Backward Character +----------+----------+----------+----------+
- C-d: Delete Character | ADVANCE | BACKUP | CUT/COPY | DEL C |
- C-e: End of Line | (4) | (5) | (6) | (,) |
- C-f: Forward Character | BOTTOM | TOP | Yank | UND C |
- C-g: Keyboard Quit +----------+----------+----------+----------+
-G-C-g: Keyboard Quit | Fwd Word | EOL | Bwd Word | Change |
- C-h: Electric Emacs Help | (1) | (2) | (3) | Direction|
-G-C-h: Emacs Help | CHNGCASE | DEL EOL | COPY | |
- C-i: Indent for Tab +---------------------+----------+ (ENTER) |
- C-j: Duplicate Word | LINE |SELECT/RES| |
- C-k: Define Key | (0) | (.) | Toggle |
-G-C-k: Restore Key | Open Line |Center Lin|Insrt/Over|
- C-l: Learn +---------------------+----------+----------+
- C-n: Set Screen Width 80
- C-o: Open Line +----------+----------+----------+
- C-p: Fill Paragraph | FNDNXT | Yank | CUT |
- C-q: Quoted Insert | (FIND)) | (INSERT) | (REMOVE) |
- C-r: Isearch Backward | FIND | | COPY |
- C-s: Isearch Forward +----------+----------+----------+
- C-t: Display the Time |SELECT/RES|SECT BACKW|SECT FORWA|
- C-u: Universal Argument | (SELECT) |(PREVIOUS)| (NEXT) |
- C-v: Redraw Display | | | |
- C-w: Set Screen Width 132 +----------+----------+----------+
- C-z: Suspend Emacs
-G-C-\\: Split Window
-
- G-a: Append to Kill Buffer
- G-b: Buffer Menu
- G-c: Compile
- G-d: Delete Window
- G-e: Exit
- G-f: Find File
- G-g: Find File Other Window
- G-h: Keypad Help
- G-i: Insert File
- G-k: Toggle Capitalization Word
- G-l: Lowercase Word or Region
- G-m: Save Some Buffers
- G-n: Next Error
- G-o: Switch Windows
- G-q: Quit
- G-r: Revert File
- G-s: Save Buffer
- G-u: Uppercase Word or Region
- G-v: Find File Other Window
- G-w: Write file
- G-y: EDT Emulation OFF
- G-z: Switch to Default EDT Key Bindings
- G-2: Split Window
- G-%: Go to Percentage
- G- : Undo (GOLD Spacebar)
- G-=: Go to Line
- G-\\=`: What line
- G-/: Query-Replace"
-
- (interactive)
- (describe-function 'edt-user-keypad-help))
-
-;;; edt-user.el ends here
+++ /dev/null
-;;; calculator.el --- a calculator for Emacs -*- lexical-binding: t -*-
-
-;; Copyright (C) 1998, 2000-2024 Free Software Foundation, Inc.
-
-;; Author: Eli Barzilay <eli@barzilay.org>
-;; Keywords: tools, convenience
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; A calculator for Emacs.
-;; Why should you reach for your mouse to get xcalc (calc.exe, gcalc or
-;; whatever), when you have Emacs running already?
-;;
-;; You can bind this to a key by adding this to your Init file:
-;;
-;; (global-set-key [(control return)] 'calculator)
-;;
-;; Written by Eli Barzilay, eli@barzilay.org
-
-;;; Customization:
-
-(defgroup calculator nil
- "Simple Emacs calculator."
- :prefix "calculator"
- :version "21.1"
- :group 'tools
- :group 'applications)
-
-(defcustom calculator-electric-mode nil
- "Run `calculator' electrically, in the echo area.
-Electric mode saves some place but changes the way you interact with the
-calculator."
- :type 'boolean)
-
-(defcustom calculator-use-menu t
- "Make `calculator' create a menu.
-Note that this requires easymenu. Must be set before loading."
- :type 'boolean)
-
-(defcustom calculator-bind-escape nil
- "If non-nil, set escape to exit the calculator."
- :type 'boolean)
-
-(defcustom calculator-unary-style 'postfix
- "Value is either `prefix' or `postfix'.
-This determines the default behavior of unary operators."
- :type '(choice (const prefix) (const postfix))
- :group 'calculator)
-
-(defcustom calculator-prompt "Calc=%s> "
- "The prompt used by the Emacs calculator.
-It should contain a \"%s\" somewhere that will indicate the i/o radixes;
-this will be a two-character string as described in the documentation
-for `calculator-mode'."
- :type 'string)
-
-(defcustom calculator-number-digits 3
- "The calculator's number of digits used for standard display.
-Used by the `calculator-standard-display' function - it will use the
-format string \"%.NC\" where this number is N and C is a character given
-at runtime."
- :type 'integer)
-
-(defcustom calculator-radix-grouping-mode t
- "Use digit grouping in radix output mode.
-If this is set, chunks of `calculator-radix-grouping-digits' characters
-will be separated by `calculator-radix-grouping-separator' when in radix
-output mode is active (determined by `calculator-output-radix')."
- :type 'boolean)
-
-(defcustom calculator-radix-grouping-digits 4
- "The number of digits used for grouping display in radix modes.
-See `calculator-radix-grouping-mode'."
- :type 'integer)
-
-(defcustom calculator-radix-grouping-separator "'"
- "The separator used in radix grouping display.
-See `calculator-radix-grouping-mode'."
- :type 'string)
-
-(defcustom calculator-remove-zeros t
- "Non-nil value means delete all redundant zero decimal digits.
-If this value is not t and not nil, redundant zeros are removed except
-for one.
-Used by the `calculator-remove-zeros' function."
- :type '(choice (const t) (const leave-decimal) (const nil)))
-
-(defcustom calculator-displayer '(std ?n)
- "A displayer specification for numerical values.
-This is the displayer used to show all numbers in an expression. Result
-values will be displayed according to the first element of
-`calculator-displayers'.
-
-The displayer is a symbol, a string or an expression. A symbol should
-be the name of a one-argument function, a string is used with a single
-argument and an expression will be evaluated with the variable `num'
-bound to whatever should be displayed. If it is a function symbol, it
-should be able to handle special symbol arguments, currently `left' and
-`right' which will be sent by special keys to modify display parameters
-associated with the displayer function (for example to change the number
-of digits displayed).
-
-An exception to the above is the case of the list (std C [G]) where C is
-a character and G is an optional boolean, in this case the
-`calculator-standard-displayer' function will be used with these as
-arguments."
- :type '(choice (function) (string) (sexp)
- (list (const std) character)
- (list (const std) character boolean)))
-
-(defcustom calculator-displayers
- '(((std ?n) "Standard display, decimal point or scientific")
- (calculator-eng-display "Eng display")
- ((std ?f t) "Standard display, decimal point with grouping")
- ((std ?e) "Standard display, scientific")
- ("%S" "Emacs printer"))
- "A list of displayers.
-Each element is a list of a displayer and a description string. The
-first element is the one which is currently used, this is for the
-display of result values not values in expressions. A displayer
-specification is the same as the values that can be stored in
-`calculator-displayer'.
-
-`calculator-rotate-displayer' rotates this list."
- :type 'sexp)
-
-(defcustom calculator-paste-decimals t
- "If non-nil, convert pasted integers so they have a decimal point.
-This makes it possible to paste big integers since they will be read as
-floats, otherwise the Emacs reader will fail on them."
- :type 'boolean)
-(make-obsolete-variable 'calculator-paste-decimals
- "it is no longer used." "26.1")
-
-(defcustom calculator-copy-displayer nil
- "If non-nil, this is any value that can be used for
-`calculator-displayer', to format a string before copying it with
-`calculator-copy'. If nil, then `calculator-displayer's normal value is
-used."
- :type 'boolean)
-
-(defcustom calculator-2s-complement nil
- "If non-nil, show negative numbers in 2s complement in radix modes.
-Otherwise show as a negative number."
- :type 'boolean)
-
-(defcustom calculator-mode-hook nil
- "List of hook functions for `calculator-mode' to run.
-Note: if `calculator-electric-mode' is on, then this hook will get
-activated in the minibuffer -- in that case it should not do much more
-than local key settings and other effects that will change things
-outside the scope of calculator related code."
- :type 'hook)
-
-(defcustom calculator-user-registers nil
- "An association list of user-defined register bindings.
-Each element in this list is a list of a character and a number that
-will be stored in that character's register.
-
-For example, use this to define the golden ratio number:
- (setq calculator-user-registers \\='((?g . 1.61803398875)))
-before you load calculator."
- :type '(repeat (cons character number))
- :set (lambda (_ val)
- (when (boundp 'calculator-registers)
- (setq calculator-registers
- (append val calculator-registers)))
- (setq calculator-user-registers val)))
-
-(defcustom calculator-user-operators nil
- "A list of additional operators.
-This is a list in the same format as specified in the documentation for
-`calculator-operators', that you can use to bind additional calculator
-operators. It is probably not a good idea to modify this value with
-`customize' since it is too complex...
-
-Examples:
-
-* A very simple one, adding a postfix \"x-to-y\" conversion keys, using
- t as a prefix key:
-
- (setq calculator-user-operators
- \\='((\"tf\" cl-to-fr (+ 32 (/ (* X 9) 5)) 1)
- (\"tc\" fr-to-cl (/ (* (- X 32) 5) 9) 1)
- (\"tp\" kg-to-lb (/ X 0.453592) 1)
- (\"tk\" lb-to-kg (* X 0.453592) 1)
- (\"tF\" mt-to-ft (/ X 0.3048) 1)
- (\"tM\" ft-to-mt (* X 0.3048) 1)))
-
-* Using a function-like form is simple: use `X' for the argument (`Y'
- for a second one in case of a binary operator), `TX' is a truncated
- version of `X' and `F' for a recursive call. Here is a [very
- inefficient] Fibonacci number operator:
-
- (add-to-list \\='calculator-user-operators
- \\='(\"F\" fib
- (if (<= TX 1) 1 (+ (F (- TX 1)) (F (- TX 2))))))
-
- Note that this will be either postfix or prefix, according to
- `calculator-unary-style'."
- :type '(repeat (list string symbol sexp integer integer)))
-
-;;;=====================================================================
-;;; Code:
-
-(require 'cl-lib)
-
-;;;---------------------------------------------------------------------
-;;; Variables
-
-(defvar calculator-initial-operators
- '(;; "+"/"-" have keybindings of their own, not calculator-ops
- ("=" = identity 1 -1)
- (nobind "+" + + 2 4)
- (nobind "-" - - 2 4)
- (nobind "+" + + -1 9)
- (nobind "-" - - -1 9)
- ("(" \( identity -1 -1)
- (")" \) identity +1 10)
- ;; normal keys
- ("|" or (logior TX TY) 2 2)
- ("#" xor (logxor TX TY) 2 2)
- ("&" and (logand TX TY) 2 3)
- ("*" * * 2 5)
- ("/" / / 2 5)
- ("\\" div (/ TX TY) 2 5)
- ("%" rem (% TX TY) 2 5)
- ("L" log log 2 6)
- ("S" sin (sin DX) x 6)
- ("C" cos (cos DX) x 6)
- ("T" tan (tan DX) x 6)
- ("IS" asin (D (asin X)) x 6)
- ("IC" acos (D (acos X)) x 6)
- ("IT" atan (D (atan X)) x 6)
- ("Q" sqrt sqrt x 7)
- ("^" ^ calculator-expt 2 7)
- ("!" ! calculator-fact x 7)
- (";" 1/ (/ 1 X) 1 7)
- ("_" - - 1 8)
- ("~" ~ (lognot TX) x 8)
- (">" repR calculator-repR 1 8)
- ("<" repL calculator-repL 1 8)
- ("v" avg (/ (apply '+ L) (length L)) 0 8)
- ("l" tot (apply '+ L) 0 8)
- )
- "A list of initial operators.
-This is a list in the same format as `calculator-operators'. Whenever
-`calculator' starts, it looks at the value of this variable, and if it
-is not empty, its contents is prepended to `calculator-operators' and
-the appropriate key bindings are made.
-
-This variable is then reset to nil. Don't use this if you want to add
-user-defined operators, use `calculator-user-operators' instead.")
-
-(defvar calculator-operators nil
- "The calculator operators, each a list with:
-
-1. The key(s) that is bound to for this operation, a string that is
- used with `kbd';
-
-2. The displayed symbol for this function;
-
-3. The function symbol, or a form that uses the variables `X' and `Y',
- (if it is a binary operator), `TX' and `TY' (truncated integer
- versions), `DX' (converted to radians if degrees mode is on), `D'
- (function for converting radians to degrees if deg mode is on), `L'
- (list of saved values), `F' (function for recursive iteration calls)
- and evaluates to the function value -- these variables are capital;
-
-4. The function's arity, optional, one of: 2 => binary, -1 => prefix
- unary, +1 => postfix unary, 0 => a 0-arg operator func (note that
- using such a function replaces the currently entered number, if any),
- non-number (the default) => postfix or prefix as determined by
- `calculator-unary-style';
-
-5. The function's precedence -- should be in the range of 1 (lowest) to
- 9 (highest) (optional, defaults to 1);
-
-It is possible have a unary prefix version of a binary operator if it
-comes later in this list. If the list begins with the symbol `nobind',
-then no key binding will take place -- this is only used for predefined
-keys.
-
-Use `calculator-user-operators' to add operators to this list, see its
-documentation for an example.")
-
-(defvar calculator-stack nil
- "Stack contents -- operations and operands.")
-
-(defvar calculator-curnum nil
- "Current number being entered (as a string).")
-
-(defvar calculator-stack-display nil
- "Cons of the stack and its string representation.")
-
-(defvar calculator-char-radix
- '((?D . nil) (?B . bin) (?O . oct) (?H . hex) (?X . hex))
- "A table to convert input characters to corresponding radix symbols.")
-
-(defvar calculator-output-radix nil
- "The mode for display, one of: nil (decimal), `bin', `oct' or `hex'.")
-
-(defvar calculator-input-radix nil
- "The mode for input, one of: nil (decimal), `bin', `oct' or `hex'.")
-
-(defvar calculator-deg nil
- "Non-nil if trig functions operate on degrees instead of radians.")
-
-(defvar calculator-saved-list nil
- "A list of saved values collected.")
-
-(defvar calculator-saved-ptr 0
- "The pointer to the current saved number.")
-
-(defvar calculator-add-saved nil
- "Bound to t when a value should be added to the saved-list.")
-
-(defvar calculator-display-fragile nil
- "When non-nil, we see something that the next digit should replace.")
-
-(defvar calculator-buffer nil
- "The current calculator buffer.")
-
-(defvar calculator-eng-extra nil
- "Internal value used by `calculator-eng-display'.")
-
-(defvar calculator-eng-tmp-show nil
- "Internal value used by `calculator-eng-display'.")
-
-(defvar calculator-last-opXY nil
- "The last binary operation and its arguments.
-Used for repeating operations in calculator-repR/L.")
-
-(defvar calculator-registers ; use user-bindings first
- (append calculator-user-registers
- (list (cons ?e float-e) (cons ?p float-pi)))
- "The association list of calculator register values.")
-
-(defvar calculator-restart-other-mode nil
- "Used to hack restarting with the electric mode changed.")
-
-;;;---------------------------------------------------------------------
-;;; Key bindings
-
-(defun calculator-define-key (key cmd map)
- ;; Arranges for unbound alphabetic keys to be used as their un/shifted
- ;; versions if those are bound (mimics the usual Emacs global bindings).
- ;; FIXME: We should adjust Emacs's native "fallback to unshifted binding"
- ;; such that it can also be used here, rather than having to use a hack like
- ;; this one.
- (let* ((key (if (stringp key) (kbd key) key))
- (omap (keymap-parent map)))
- (define-key map key cmd)
- ;; "other" map, used for case-flipped bindings
- (unless omap
- (setq omap (make-sparse-keymap))
- (suppress-keymap omap t)
- (set-keymap-parent map omap))
- (let ((m omap))
- ;; Bind all case-flipped versions.
- (dotimes (i (length key))
- (let* ((c (aref key i))
- (k (vector c))
- (b (lookup-key m k))
- (defkey (lambda (x)
- (define-key m k x)
- (when (and (characterp c)
- (or (<= ?A c ?Z) (<= ?a c ?z)))
- (define-key m (vector (logxor 32 c)) x)))))
- (cond ((= i (1- (length key)))
- ;; Prefer longer sequences.
- (unless (keymapp b) (funcall defkey cmd)))
- ((keymapp b) (setq m b))
- (t (let ((sub (make-sparse-keymap)))
- (funcall defkey sub)
- (setq m sub)))))))))
-
-(defvar calculator-mode-map
- (let ((map (make-sparse-keymap)))
- (suppress-keymap map t)
- (dolist (x '((calculator-digit
- "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c"
- "d" "f" "<kp-0>" "<kp-1>" "<kp-2>" "<kp-3>" "<kp-4>"
- "<kp-5>" "<kp-6>" "<kp-7>" "<kp-8>" "<kp-9>")
- (calculator-open-paren "[")
- (calculator-close-paren "]")
- (calculator-op-or-exp "+" "-"
- "<kp-add>" "<kp-subtract>")
- (calculator-op "<kp-divide>" "<kp-multiply>")
- (calculator-decimal "." "<kp-decimal>")
- (calculator-exp "e")
- (calculator-dec/deg-mode "D")
- (calculator-set-register "s")
- (calculator-get-register "g")
- (calculator-radix-mode "H" "X" "O" "B")
- (calculator-radix-input-mode "iD" "iH" "iX" "iO" "iB")
- (calculator-radix-output-mode "oD" "oH" "oX" "oO" "oB")
- (calculator-rotate-displayer "'")
- (calculator-rotate-displayer-back "\"")
- (calculator-displayer-prev "{")
- (calculator-displayer-next "}")
- (calculator-saved-up "<up>" "C-p")
- (calculator-saved-down "<down>" "C-n")
- (calculator-quit "q" "C-g")
- (calculator-enter "<enter>" "<linefeed>"
- "<kp-enter>" "<return>"
- "RET" "LFD")
- (calculator-save-on-list "SPC" "<space>")
- (calculator-clear-saved "C-c" "<C-delete>")
- (calculator-save-and-quit "<C-return>" "<C-kp-enter>")
- (calculator-paste "<insert>" "<S-insert>"
- "<paste>" "<mouse-2>" "C-y")
- (calculator-clear "<delete>" "DEL" "C-d")
- (calculator-help "h" "?" "<f1>" "<help>")
- (calculator-copy "<C-insert>" "<copy>")
- (calculator-backspace "<backspace>")
- ))
- ;; reverse the keys so earlier definitions come last -- makes the
- ;; more sensible bindings visible in the menu
- (dolist (k (reverse (cdr x)))
- (calculator-define-key k (car x) map)))
- (if calculator-bind-escape
- (progn (calculator-define-key "ESC" 'calculator-quit map)
- (calculator-define-key "<escape>" 'calculator-quit map))
- (calculator-define-key "ESC ESC ESC" 'calculator-quit map))
- ;; make C-h work in text-mode
- (unless window-system
- (calculator-define-key "C-h" 'calculator-backspace map))
- ;; set up a menu
- (when (and calculator-use-menu (not (boundp 'calculator-menu)))
- (let ((radix-selectors
- (mapcar (lambda (x)
- `([,(nth 0 x)
- (calculator-radix-mode ,(nth 2 x))
- :style radio
- :keys ,(nth 2 x)
- :selected
- (and
- (eq calculator-input-radix ',(nth 1 x))
- (eq calculator-output-radix ',(nth 1 x)))]
- [,(concat (nth 0 x) " Input")
- (calculator-radix-input-mode ,(nth 2 x))
- :keys ,(concat "i" (downcase (nth 2 x)))
- :style radio
- :selected
- (eq calculator-input-radix ',(nth 1 x))]
- [,(concat (nth 0 x) " Output")
- (calculator-radix-output-mode ,(nth 2 x))
- :keys ,(concat "o" (downcase (nth 2 x)))
- :style radio
- :selected
- (eq calculator-output-radix ',(nth 1 x))]))
- '(("Decimal" nil "D")
- ("Binary" bin "B")
- ("Octal" oct "O")
- ("Hexadecimal" hex "H"))))
- (op (lambda (name key)
- `[,name (calculator-op ,key) :keys ,key])))
- (easy-menu-define
- calculator-menu map "Calculator menu."
- `("Calculator"
- ["Help"
- (let ((last-command 'calculator-help)) (calculator-help))
- :keys "?"]
- "---"
- ["Copy" calculator-copy]
- ["Paste" calculator-paste]
- "---"
- ["Electric mode"
- (progn (calculator-quit)
- (setq calculator-restart-other-mode t)
- (run-with-timer 0.1 nil (lambda () (message nil)))
- ;; the message from the menu will be visible,
- ;; couldn't make it go away...
- (calculator))
- :active (not calculator-electric-mode)]
- ["Normal mode"
- (progn (setq calculator-restart-other-mode t)
- (calculator-quit))
- :active calculator-electric-mode]
- "---"
- ("Functions"
- ,(funcall op "Repeat-right" ">")
- ,(funcall op "Repeat-left" "<")
- "------General------"
- ,(funcall op "Reciprocal" ";")
- ,(funcall op "Log" "L")
- ,(funcall op "Square-root" "Q")
- ,(funcall op "Factorial" "!")
- "------Trigonometric------"
- ,(funcall op "Sinus" "S")
- ,(funcall op "Cosine" "C")
- ,(funcall op "Tangent" "T")
- ,(funcall op "Inv-Sinus" "IS")
- ,(funcall op "Inv-Cosine" "IC")
- ,(funcall op "Inv-Tangent" "IT")
- "------Bitwise------"
- ,(funcall op "Or" "|")
- ,(funcall op "Xor" "#")
- ,(funcall op "And" "&")
- ,(funcall op "Not" "~"))
- ("Saved List"
- ["Eval+Save" calculator-save-on-list]
- ["Prev number" calculator-saved-up]
- ["Next number" calculator-saved-down]
- ["Delete current" calculator-clear
- :active (and calculator-display-fragile
- calculator-saved-list
- (= (car calculator-stack)
- (nth calculator-saved-ptr
- calculator-saved-list)))]
- ["Delete all" calculator-clear-saved]
- "---"
- ,(funcall op "List-total" "l")
- ,(funcall op "List-average" "v"))
- ("Registers"
- ["Get register" calculator-get-register]
- ["Set register" calculator-set-register])
- ("Modes"
- ["Radians"
- (progn
- (when (or calculator-input-radix calculator-output-radix)
- (calculator-radix-mode "D"))
- (when calculator-deg (calculator-dec/deg-mode)))
- :keys "D"
- :style radio
- :selected (not (or calculator-input-radix
- calculator-output-radix
- calculator-deg))]
- ["Degrees"
- (progn
- (when (or calculator-input-radix calculator-output-radix)
- (calculator-radix-mode "D"))
- (unless calculator-deg (calculator-dec/deg-mode)))
- :keys "D"
- :style radio
- :selected (and calculator-deg
- (not (or calculator-input-radix
- calculator-output-radix)))]
- "---"
- ,@(mapcar 'car radix-selectors)
- ("Separate I/O"
- ,@(mapcar (lambda (x) (nth 1 x)) radix-selectors)
- "---"
- ,@(mapcar (lambda (x) (nth 2 x)) radix-selectors)))
- ("Decimal Display"
- ,@(mapcar (lambda (d)
- (vector (cadr d)
- ;; Note: inserts actual object here
- `(calculator-rotate-displayer ',d)))
- calculator-displayers)
- "---"
- ["Change Prev Display" calculator-displayer-prev]
- ["Change Next Display" calculator-displayer-next])
- "---"
- ["Copy+Quit" calculator-save-and-quit]
- ["Quit" calculator-quit]))))
- map)
- "The calculator key map.")
-
-;;;---------------------------------------------------------------------
-;;; Startup and mode stuff
-
-(define-derived-mode calculator-mode fundamental-mode "Calculator"
- ;; this help is also used as the major help screen
- "A [not so] simple calculator for Emacs.
-
-This calculator is used in the same way as other popular calculators
-like xcalc or calc.exe -- but using an Emacs interface.
-
-Expressions are entered using normal infix notation, parens are used as
-normal. Unary functions are usually postfix, but some depends on the
-value of `calculator-unary-style' (if the style for an operator below is
-specified, then it is fixed, otherwise it depends on this variable).
-`+' and `-' can be used as either binary operators or prefix unary
-operators. Numbers can be entered with exponential notation using `e',
-except when using a non-decimal radix mode for input (in this case `e'
-will be the hexadecimal digit).
-
-Here are the editing keys:
-* \\`RET' \\`=' evaluate the current expression
-* \\`C-<insert>' copy the whole current expression to the `kill-ring'
-* \\`C-<return>' evaluate, save result the `kill-ring' and exit
-* \\`<insert>' paste a number if the one was copied (normally)
-* \\`<delete>' \\`C-d' clear last argument or whole expression (hit twice)
-* \\`<backspace>' delete a digit or a previous expression element
-* \\`h' \\`?' pop-up a quick reference help
-* \\`ESC' \\`q' exit (\\`ESC' can be used if `calculator-bind-escape' is
- non-nil, otherwise use three consecutive \\`ESC's)
-
-These operators are pre-defined:
-* `+' `-' `*' `/' the common binary operators
-* `\\' `%' integer division and remainder
-* `_' `;' postfix unary negation and reciprocal
-* `^' `L' binary operators for x^y and log(x) in base y
-* `Q' `!' unary square root and factorial
-* `S' `C' `T' unary trigonometric operators: sin, cos and tan
-* `|' `#' `&' `~' bitwise operators: or, xor, and, not
-
-The trigonometric functions can be inverted if prefixed with an `I', see
-below for the way to use degrees instead of the default radians.
-
-Two special postfix unary operators are `>' and `<': whenever a binary
-operator is performed, it is remembered along with its arguments; then
-`>' (`<') will apply the same operator with the same right (left)
-argument.
-
-hex/oct/bin modes can be set for input and for display separately.
-Another toggle-able mode is for using degrees instead of radians for
-trigonometric functions.
-The keys to switch modes are (both \\`H' and \\`X' are for hex):
-* \\`D' switch to all-decimal mode, or toggle degrees/radians
-* \\`B' \\`O' \\`H' \\`X' binary/octal/hexadecimal modes for input & display
-* \\`i' \\`o' followed by one of \\`D' \\`B' \\`O' \\`H' \\`X' (case
- insensitive) sets only the input or display radix mode
-The prompt indicates the current modes:
-* \"==\": decimal mode (using radians);
-* \"D=\": decimal mode using degrees;
-* \"?=\": ? is B/O/H, the radix for both input and output;
-* \"=?\": ? is B/O/H, the display radix (with decimal input);
-* \"??\": ? is D/B/O/H, 1st char for input radix, 2nd for display.
-
-Also, the quote key can be used to switch display modes for decimal
-numbers (double-quote rotates back), and the two brace characters
-\(\"{\" and \"}\" change display parameters that these displayers use,
-if they handle such). If output is using any radix mode, then these
-keys toggle digit grouping mode and the chunk size.
-
-Values can be saved for future reference in either a list of saved
-values, or in registers.
-
-The list of saved values is useful for statistics operations on some
-collected data. It is possible to navigate in this list, and if the
-value shown is the current one on the list, an indication is displayed
-as \"[N]\" if this is the last number and there are N numbers, or
-\"[M/N]\" if the M-th value is shown.
-* \\`SPC' evaluate the current value as usual, but also adds
- the result to the list of saved values
-* \\`l' \\`v' computes total / average of saved values
-* \\`<up>' \\`C-p' browse to the previous value in the list
-* \\`<down>' \\`C-n' browse to the next value in the list
-* \\`<delete>' \\`C-d' remove current value from the list (if it is on it)
-* \\`C-<delete>' \\`C-c' delete the whole list
-
-Registers are variable-like place-holders for values:
-* \\`s' followed by a character attach the current value to that character
-* \\`g' followed by a character fetches the attached value
-
-There are many variables that can be used to customize the calculator.
-Some interesting customization variables are:
-* `calculator-electric-mode' use only the echo-area electrically.
-* `calculator-unary-style' set most unary ops to pre/postfix style.
-* `calculator-user-registers' to define user-preset registers.
-* `calculator-user-operators' to add user-defined operators.
-See the documentation for these variables, and \"calculator.el\" for
-more information.
-
-\\{calculator-mode-map}")
-
-(declare-function Electric-command-loop "electric"
- (return-tag &optional prompt inhibit-quitting
- loop-function loop-state))
-
-;;;###autoload
-(defun calculator ()
- "Run the Emacs calculator.
-See the documentation for `calculator-mode' for more information."
- (interactive)
- (when calculator-restart-other-mode
- (setq calculator-electric-mode (not calculator-electric-mode)))
- (when calculator-initial-operators
- (calculator-add-operators calculator-initial-operators)
- (setq calculator-initial-operators nil)
- ;; don't change this since it is a customization variable,
- ;; its set function will add any new operators
- (calculator-add-operators calculator-user-operators))
- (setq calculator-buffer (get-buffer-create "*calculator*"))
- (if calculator-electric-mode
- (save-window-excursion
- (require 'electric) (message nil) ; hide load message
- (let ((old-buf (window-buffer (minibuffer-window)))
- (echo-keystrokes 0)
- (garbage-collection-messages nil)) ; no gc msg when electric
- (set-window-buffer (minibuffer-window) calculator-buffer)
- (select-window (minibuffer-window))
- (calculator-reset)
- (calculator-update-display)
- (use-local-map calculator-mode-map)
- (run-hooks 'calculator-mode-hook)
- (unwind-protect
- (catch 'calculator-done
- (Electric-command-loop
- 'calculator-done
- ;; can't use 'noprompt, bug in electric.el
- (lambda () 'noprompt)
- nil
- (lambda (_x _y) (calculator-update-display))))
- (set-window-buffer (minibuffer-window) old-buf)
- (kill-buffer calculator-buffer))))
- (progn
- (cond
- ((not (get-buffer-window calculator-buffer))
- (let ((window-min-height 2))
- ;; maybe leave two lines for our window because of the
- ;; normal `raised' mode line
- (select-window (split-window-below
- (if (calculator-need-3-lines) -3 -2)))
- (switch-to-buffer calculator-buffer)))
- ((not (eq (current-buffer) calculator-buffer))
- (select-window (get-buffer-window calculator-buffer))))
- (calculator-mode)
- (setq buffer-read-only t)
- (calculator-reset)
- (message "Hit `?' For a quick help screen.")))
- (when (and calculator-restart-other-mode calculator-electric-mode)
- (calculator)))
-
-(defun calculator-need-3-lines ()
- ;; If the mode line might interfere with the calculator buffer, use 3
- ;; lines instead.
- (let* ((dh (face-attribute 'default :height))
- (mh (face-attribute 'mode-line :height)))
- ;; if the mode line is shorter than the default, stick with 2 lines
- ;; (it may be necessary to check how much shorter)
- (and (not (or (and (integerp dh) (integerp mh) (< mh dh))
- (and (numberp mh) (not (integerp mh)) (< mh 1))))
- (or ;; if the mode line is taller than the default, use 3 lines
- (and (integerp dh) (integerp mh) (> mh dh))
- (and (numberp mh) (not (integerp mh)) (> mh 1))
- ;; if the mode line has a box with non-negative line-width,
- ;; use 3 lines
- (let* ((bx (face-attribute 'mode-line :box))
- (lh (plist-get bx :line-width)))
- ;; Value of `:line-width' can be either a number or a cons.
- (and bx (or (not lh) (> (if (consp lh) (cdr lh) lh) 0))))
- ;; if the mode line has an overline, use 3 lines
- (not (memq (face-attribute 'mode-line :overline)
- '(nil unspecified)))))))
-
-(defun calculator-message (string &rest arguments)
- "Same as `message', but also handle electric mode."
- (apply 'message string arguments)
- (when calculator-electric-mode (sit-for 1) (message nil)))
-
-;;;---------------------------------------------------------------------
-;;; Operators
-
-(defun calculator-op-arity (op)
- "Return OP's arity.
-Current results are one of 2 (binary), +1 (postfix), -1 (prefix), or
-0 (nullary)."
- (let ((arity (nth 3 op)))
- (cond ((numberp arity) arity)
- ((eq calculator-unary-style 'postfix) +1)
- (t -1))))
-
-(defun calculator-op-prec (op)
- "Return OP's precedence for reducing when inserting into the stack.
-Defaults to 1."
- (or (nth 4 op) 1))
-
-(defun calculator-add-operators (more-ops)
- "This function handles operator addition.
-Adds MORE-OPS to `calculator-operator', called initially to handle
-`calculator-initial-operators' and `calculator-user-operators'."
- (let ((added-ops nil))
- (dolist (op more-ops)
- (unless (eq (car op) 'nobind)
- (calculator-define-key (car op) 'calculator-op calculator-mode-map))
- (push (if (eq (car op) 'nobind) (cdr op) op)
- added-ops))
- ;; added-ops come first, but in correct order
- (setq calculator-operators
- (append (nreverse added-ops) calculator-operators))))
-
-;;;---------------------------------------------------------------------
-;;; Display stuff
-
-(defun calculator-reset ()
- "Reset calculator variables."
- (unless calculator-restart-other-mode
- (setq calculator-stack nil
- calculator-curnum nil
- calculator-stack-display nil
- calculator-display-fragile nil))
- (setq calculator-restart-other-mode nil)
- (calculator-update-display))
-
-(defun calculator-get-display ()
- "Return a string to display.
-The result should not exceed the screen width."
- (let* ((in-r (and calculator-input-radix
- (char-to-string
- (car (rassq calculator-input-radix
- calculator-char-radix)))))
- (out-r (and calculator-output-radix
- (char-to-string
- (car (rassq calculator-output-radix
- calculator-char-radix)))))
- (prompt (format calculator-prompt
- (cond ((or in-r out-r)
- (concat (or in-r "=")
- (if (equal in-r out-r) "="
- (or out-r "D"))))
- (calculator-deg "D=")
- (t "=="))))
- (expr
- (concat (cdr calculator-stack-display)
- (cond
- ;; entering a number
- (calculator-curnum (concat calculator-curnum "_"))
- ;; showing a result
- ((and (= 1 (length calculator-stack))
- calculator-display-fragile)
- nil)
- ;; waiting for a number or an operator
- (t "?"))))
- (trim (+ (length expr) (length prompt) 1 (- (window-width)))))
- (concat prompt (if (<= trim 0) expr (substring expr trim)))))
-
-(defun calculator-string-to-number (str)
- "Convert STR to number according to `calculator-input-radix'."
- (if calculator-input-radix
- (string-to-number str (cadr (assq calculator-input-radix
- '((bin 2) (oct 8) (hex 16)))))
- ;; parse numbers similarly to calculators
- ;; (see tests in test/lisp/calculator-tests.el)
- (let ((str (replace-regexp-in-string "\\.\\([^0-9].*\\)?$" ".0\\1" str)))
- (float (string-to-number str)))))
-
-(defun calculator-push-curnum ()
- "Push the numeric value of the displayed number to the stack."
- (when calculator-curnum
- (push (calculator-string-to-number calculator-curnum)
- calculator-stack)
- (setq calculator-curnum nil)))
-
-(defun calculator-rotate-displayer (&optional new-disp)
- "Switch to the next displayer on the `calculator-displayers' list.
-Can be called with an optional argument NEW-DISP to force rotation to
-that argument.
-If radix output mode is active, toggle digit grouping."
- (interactive)
- (cond
- (calculator-output-radix
- (setq calculator-radix-grouping-mode
- (not calculator-radix-grouping-mode))
- (calculator-message
- "Digit grouping mode %s."
- (if calculator-radix-grouping-mode "ON" "OFF")))
- (t
- (setq calculator-displayers
- (if (and new-disp (memq new-disp calculator-displayers))
- (let ((tmp nil))
- (while (not (eq (car calculator-displayers) new-disp))
- (push (pop calculator-displayers) tmp))
- (setq calculator-displayers
- (nconc calculator-displayers (nreverse tmp))))
- (nconc (cdr calculator-displayers)
- (list (car calculator-displayers)))))
- (calculator-message
- "Using %s." (cadr (car calculator-displayers)))))
- (calculator-enter))
-
-(defun calculator-rotate-displayer-back ()
- "Like `calculator-rotate-displayer', but rotates modes back.
-If radix output mode is active, toggle digit grouping."
- (interactive)
- (calculator-rotate-displayer (car (last calculator-displayers))))
-
-(defun calculator-displayer-prev ()
- "Send the current displayer function a `left' argument.
-This is used to modify display arguments (if the current displayer
-function supports this).
-If radix output mode is active, increase the grouping size."
- (interactive)
- (if calculator-output-radix
- (progn (setq calculator-radix-grouping-digits
- (1+ calculator-radix-grouping-digits))
- (calculator-enter))
- (when (car calculator-displayers)
- (let ((disp (caar calculator-displayers)))
- (cond ((symbolp disp) (funcall disp 'left))
- ((and (consp disp) (eq 'std (car disp)))
- (calculator-standard-displayer 'left)))))))
-
-(defun calculator-displayer-next ()
- "Send the current displayer function a `right' argument.
-This is used to modify display arguments (if the current displayer
-function supports this).
-If radix output mode is active, decrease the grouping size."
- (interactive)
- (if calculator-output-radix
- (progn (setq calculator-radix-grouping-digits
- (max 2 (1- calculator-radix-grouping-digits)))
- (calculator-enter))
- (when (car calculator-displayers)
- (let ((disp (caar calculator-displayers)))
- (cond ((symbolp disp) (funcall disp 'right))
- ((and (consp disp) (eq 'std (car disp)))
- (calculator-standard-displayer 'right)))))))
-
-(defun calculator-remove-zeros (numstr)
- "Get a number string NUMSTR and remove unnecessary zeros.
-The behavior of this function is controlled by
-`calculator-remove-zeros'."
- (let* ((s (if (not (eq calculator-remove-zeros t)) numstr
- ;; remove all redundant zeros leaving an integer
- (replace-regexp-in-string
- "\\.0+\\([eE].*\\)?$" "\\1" numstr)))
- (s (if (not calculator-remove-zeros) s
- ;; remove zeros, except for first after the "."
- (replace-regexp-in-string
- "\\(\\..[0-9]*?\\)0+\\([eE].*\\)?$" "\\1\\2" s))))
- s))
-
-(defun calculator-groupize-number (str n sep &optional fromleft)
- "Return the input string STR with occurrences of SEP that separate
-every N characters starting from the right, or from the left if
-FROMLEFT is true."
- (let* ((len (length str)) (i (/ len n)) (j (% len n))
- (r (if (or (not fromleft) (= j 0)) '()
- (list (substring str (- len j))))))
- (while (> i 0)
- (let* ((e (* i n)) (e (if fromleft e (+ e j))))
- (push (substring str (- e n) e) r))
- (setq i (1- i)))
- (when (and (not fromleft) (> j 0))
- (push (substring str 0 j) r))
- (mapconcat 'identity r sep)))
-
-(defun calculator-standard-displayer (num &optional char group-p)
- "Standard display function, used to display NUM.
-Its behavior is determined by `calculator-number-digits' and the given
-CHAR argument (both will be used to compose a format string). If the
-char is \"n\" then this function will choose one between %f or %e, this
-is a work around %g jumping to exponential notation too fast.
-
-It will also split digit sequences into comma-separated groups
-and/or remove redundant zeros.
-
-The special `left' and `right' symbols will make it change the current
-number of digits displayed (`calculator-number-digits')."
- (if (symbolp num)
- (cond ((eq num 'left)
- (when (> calculator-number-digits 0)
- (setq calculator-number-digits
- (1- calculator-number-digits))
- (calculator-enter)))
- ((eq num 'right)
- (setq calculator-number-digits
- (1+ calculator-number-digits))
- (calculator-enter)))
- (let* ((s (if (eq char ?n)
- (let ((n (abs num)))
- (if (or (and (< 0 n) (< n 0.001)) (< 1e8 n)) ?e ?f))
- char))
- (s (format "%%.%s%c" calculator-number-digits s))
- (s (calculator-remove-zeros (format s num)))
- (s (if (or (not group-p) (string-match-p "[eE]" s)) s
- (replace-regexp-in-string
- "\\([0-9]+\\)\\(?:\\..*\\|$\\)"
- (lambda (_) (calculator-groupize-number
- (match-string 1 s) 3 ","))
- s nil nil 1))))
- s)))
-
-(defun calculator-eng-display (num)
- "Display NUM in engineering notation.
-The number of decimal digits used is controlled by
-`calculator-number-digits', so to change it at runtime you have to use
-the `left' or `right' when one of the standard modes is used."
- (if (symbolp num)
- (cond ((eq num 'left)
- (setq calculator-eng-extra
- (if calculator-eng-extra (1+ calculator-eng-extra) 1))
- (let ((calculator-eng-tmp-show t)) (calculator-enter)))
- ((eq num 'right)
- (setq calculator-eng-extra
- (if calculator-eng-extra (1- calculator-eng-extra) -1))
- (let ((calculator-eng-tmp-show t)) (calculator-enter))))
- (let ((exp 0))
- (unless (= 0 num)
- (while (< (abs num) 1.0)
- (setq num (* num 1000.0)) (setq exp (- exp 3)))
- (while (> (abs num) 999.0)
- (setq num (/ num 1000.0)) (setq exp (+ exp 3)))
- (when (and calculator-eng-tmp-show
- (not (= 0 calculator-eng-extra)))
- (let ((i calculator-eng-extra))
- (while (> i 0)
- (setq num (* num 1000.0)) (setq exp (- exp 3))
- (setq i (1- i)))
- (while (< i 0)
- (setq num (/ num 1000.0)) (setq exp (+ exp 3))
- (setq i (1+ i))))))
- (unless calculator-eng-tmp-show (setq calculator-eng-extra nil))
- (let ((str (format (format "%%.%sf" calculator-number-digits)
- num)))
- (concat (let ((calculator-remove-zeros
- ;; make sure we don't leave integers
- (and calculator-remove-zeros 'x)))
- (calculator-remove-zeros str))
- "e" (number-to-string exp))))))
-
-(defun calculator-number-to-string (num)
- "Convert NUM to a displayable string."
- (cond
- ;; operators are printed here, the rest is for numbers
- ((not (numberp num)) (prin1-to-string (nth 1 num) t))
- ;; %f/%e handle these, but avoid them in radix or in user displayers
- ((and (floatp num) (isnan num)) "NaN")
- ((<= 1.0e+INF num) "Inf")
- ((<= num -1.0e+INF) "-Inf")
- (calculator-output-radix
- ;; print with radix -- for binary, convert the octal number
- (let* ((fmt (if (eq calculator-output-radix 'hex) "%x" "%o"))
- (str (if calculator-2s-complement num (abs num)))
- (str (format fmt (truncate str)))
- (bins '((?0 "000") (?1 "001") (?2 "010") (?3 "011")
- (?4 "100") (?5 "101") (?6 "110") (?7 "111")))
- (str (if (not (eq calculator-output-radix 'bin)) str
- (replace-regexp-in-string
- "^0+\\(.\\)" "\\1"
- (apply 'concat (mapcar (lambda (c)
- (cadr (assq c bins)))
- str)))))
- (str (if (not calculator-radix-grouping-mode) str
- (calculator-groupize-number
- str calculator-radix-grouping-digits
- calculator-radix-grouping-separator))))
- (upcase (if (or calculator-2s-complement (>= num 0)) str
- (concat "-" str)))))
- ((stringp calculator-displayer) (format calculator-displayer num))
- ((symbolp calculator-displayer) (funcall calculator-displayer num))
- ((eq 'std (car-safe calculator-displayer))
- (apply 'calculator-standard-displayer
- num (cdr calculator-displayer)))
- ((listp calculator-displayer)
- (eval `(let ((num ',num)) ,calculator-displayer) t))
- ;; nil (or bad) displayer
- (t (prin1-to-string num t))))
-
-(defun calculator-update-display (&optional force)
- "Update the display.
-If optional argument FORCE is non-nil, don't use the cached string."
- (set-buffer calculator-buffer)
- ;; update calculator-stack-display
- (when (or force (not (eq (car calculator-stack-display)
- calculator-stack)))
- (setq calculator-stack-display
- (cons calculator-stack
- (if calculator-stack
- (concat
- (let ((calculator-displayer
- (if (and calculator-displayers
- (= 1 (length calculator-stack)))
- ;; customizable display for a single value
- (caar calculator-displayers)
- calculator-displayer)))
- (mapconcat 'calculator-number-to-string
- (reverse calculator-stack)
- " "))
- " "
- (and calculator-display-fragile
- calculator-saved-list
- ;; Hack: use `eq' to compare the number: it's a
- ;; flonum, so `eq' means that its the actual
- ;; number rather than a computation that had an
- ;; equal result (eg, enter 1,3,2, use "v" to see
- ;; the average -- it now shows "2" instead of
- ;; "2 [3]").
- (eq (car calculator-stack)
- (nth calculator-saved-ptr
- calculator-saved-list))
- (if (= 0 calculator-saved-ptr)
- (format "[%s]" (length calculator-saved-list))
- (format "[%s/%s]"
- (- (length calculator-saved-list)
- calculator-saved-ptr)
- (length calculator-saved-list)))))
- ""))))
- (let ((inhibit-read-only t))
- (erase-buffer)
- (insert (calculator-get-display)))
- (set-buffer-modified-p nil)
- (goto-char (if calculator-display-fragile
- (1+ (length calculator-prompt))
- (1- (point)))))
-
-;;;---------------------------------------------------------------------
-;;; Stack computations
-
-(defun calculator-reduce-stack-once (prec)
- "Worker for `calculator-reduce-stack'."
- (cl-flet ((check (ar op) (and (listp op)
- (<= prec (calculator-op-prec op))
- (= ar (calculator-op-arity op))))
- (call (op &rest args) (apply 'calculator-funcall
- (nth 2 op) args)))
- (pcase calculator-stack
- ;; reduce "... ( x )" --> "... x"
- (`((,_ \) . ,_) ,(and X (pred numberp)) (,_ \( . ,_) . ,rest)
- (cons X rest))
- ;; reduce "... x op y" --> "... r", r is the result
- (`(,(and Y (pred numberp))
- ,(and O (pred (check 2)))
- ,(and X (pred numberp))
- . ,rest)
- (cons (call O X Y) rest))
- ;; reduce "... op x" --> "... r" for prefix op
- (`(,(and X (pred numberp)) ,(and O (pred (check -1))) . ,rest)
- (cons (call O X) rest))
- ;; reduce "... x op" --> "... r" for postfix op
- (`(,(and O (pred (check +1))) ,(and X (pred numberp)) . ,rest)
- (cons (call O X) rest))
- ;; reduce "... op" --> "... r" for 0-ary op
- (`(,(and O (pred (check 0))) . ,rest)
- (cons (call O) rest))
- ;; reduce "... y x" --> "... x"
- ;; (needed for 0-ary ops: replace current number with result)
- (`(,(and X (pred numberp)) ,(and _Y (pred numberp)) . ,rest)
- (cons X rest))
- (_ nil)))) ; nil = done
-
-(defun calculator-reduce-stack (prec)
- "Reduce the stack using top operators as long as possible.
-PREC is a precedence -- reduce everything with higher precedence."
- (let ((new nil))
- (while (setq new (calculator-reduce-stack-once prec))
- (setq calculator-stack new))))
-
-(defun calculator-funcall (f &optional X Y)
- "If F is a symbol, evaluate (F X Y).
-Otherwise, it should be a list, evaluate it with X, Y bound to the
-arguments."
- ;; remember binary ops for calculator-repR/L
- (when Y (setq calculator-last-opXY (list f X Y)))
- (if (symbolp f)
- (cond ((and X Y) (funcall f X Y))
- (X (funcall f X))
- (t (funcall f)))
- ;; f is an expression
- (let ((TX (and X (calculator-truncate X)))
- (TY (and Y (calculator-truncate Y)))
- (DX (if (and X calculator-deg) (degrees-to-radians X) X))
- (L calculator-saved-list)
- (fF `(calculator-funcall ',f x y))
- (fD '(if calculator-deg (radians-to-degrees x) x)))
- (eval `(cl-flet ((F (&optional x y) ,fF) (D (x) ,fD))
- (let ((X ,X) (Y ,Y) (DX ,DX) (TX ,TX) (TY ,TY) (L ',L))
- ,f))
- t))))
-
-;;;---------------------------------------------------------------------
-;;; Input interaction
-
-(defun calculator-last-input (&optional keys)
- "Return the last key sequence used to invoke this command, or the input KEYS.
-Uses the `function-key-map' translate keypad numbers to plain
-ones."
- (let* ((inp (or keys (this-command-keys)))
- (inp (or (and (arrayp inp) (not (stringp inp))
- (lookup-key function-key-map inp))
- inp)))
- (if (or (not inp) (stringp inp) (not (arrayp inp))
- (catch 'done ; any non-chars?
- (dotimes (i (length inp))
- (unless (characterp (aref inp i)) (throw 'done t)))
- nil))
- inp
- (concat inp))))
-
-(defun calculator-clear-fragile (&optional op)
- "Clear the fragile flag if it was set, then maybe reset all.
-OP is the operator (if any) that caused this call."
- (when (and calculator-display-fragile
- (or (not op) (memq (calculator-op-arity op) '(-1 0))))
- ;; reset if last calc finished, and now get a num or prefix or 0-ary
- ;; op
- (calculator-reset))
- (setq calculator-display-fragile nil))
-
-(defun calculator-digit ()
- "Enter a single digit."
- (interactive)
- (let ((inp (aref (calculator-last-input) 0)))
- (when (and (or calculator-display-fragile
- (not (numberp (car calculator-stack))))
- (<= inp (pcase calculator-input-radix
- ('nil ?9) ('bin ?1) ('oct ?7) (_ 999))))
- (calculator-clear-fragile)
- (setq calculator-curnum
- (concat (if (equal calculator-curnum "0") ""
- calculator-curnum)
- (list (upcase inp))))
- (calculator-update-display))))
-
-(defun calculator-decimal ()
- "Enter a decimal period."
- (interactive)
- (when (and (not calculator-input-radix)
- (or calculator-display-fragile
- (not (numberp (car calculator-stack))))
- (not (and calculator-curnum
- (string-match-p "[.eE]" calculator-curnum))))
- ;; enter the period on the same condition as a digit, only if no
- ;; period or exponent entered yet
- (calculator-clear-fragile)
- (setq calculator-curnum (concat (or calculator-curnum "0") "."))
- (calculator-update-display)))
-
-(defun calculator-exp ()
- "Enter an exponent, or an \"E\" digit in hex input mode."
- (interactive)
- (cond
- (calculator-input-radix (calculator-digit))
- ((and (or calculator-display-fragile
- (not (numberp (car calculator-stack))))
- (not (and calculator-curnum
- (string-match-p "[eE]" calculator-curnum))))
- ;; same condition as above, also no E so far
- (calculator-clear-fragile)
- (setq calculator-curnum (concat (or calculator-curnum "1") "e"))
- (calculator-update-display))))
-
-(defun calculator-op (&optional keys)
- "Enter an operator on the stack, doing all necessary reductions.
-Optional string argument KEYS will force using it as the keys entered."
- (interactive)
- (catch 'op-error
- (let* ((last-inp (calculator-last-input keys))
- (op (assoc last-inp calculator-operators)))
- (calculator-clear-fragile op)
- (calculator-push-curnum)
- (when (and (= 2 (calculator-op-arity op))
- (not (numberp (car calculator-stack))))
- ;; we have a binary operator but no number -- search for a
- ;; prefix version
- (setq op (assoc last-inp (cdr (memq op calculator-operators))))
- (unless (and op (= -1 (calculator-op-arity op)))
- (calculator-message "Binary operator without a first operand")
- (throw 'op-error nil)))
- (calculator-reduce-stack
- (cond ((eq (nth 1 op) '\() 10)
- ((eq (nth 1 op) '\)) 0)
- (t (calculator-op-prec op))))
- (when (let ((hasnum (numberp (car calculator-stack))))
- (pcase (calculator-op-arity op)
- (-1 hasnum)
- ((or 1 2) (not hasnum))))
- (calculator-message "Incomplete expression")
- (throw 'op-error nil))
- (push op calculator-stack)
- (calculator-reduce-stack (calculator-op-prec op))
- (when (and (= (length calculator-stack) 1)
- (numberp (car calculator-stack)))
- ;; the display is fragile if it contains only one number
- (setq calculator-display-fragile t)
- (when calculator-add-saved ; add number to the saved-list
- (push (car calculator-stack)
- (nthcdr calculator-saved-ptr calculator-saved-list))))
- (calculator-update-display))))
-
-(defun calculator-op-or-exp ()
- "Either enter an operator or a digit.
-Used with +/- for entering them as digits in numbers like 1e-3 (there is
-no need for negative numbers since these are handled by unary
-operators)."
- (interactive)
- (if (and (not calculator-input-radix)
- (not calculator-display-fragile)
- calculator-curnum
- (string-match-p "[eE]$" calculator-curnum))
- (calculator-digit)
- (calculator-op)))
-
-;;;---------------------------------------------------------------------
-;;; Input/output modes (not display)
-
-(defun calculator-dec/deg-mode ()
- "Set decimal mode for display & input, if decimal, toggle deg mode."
- (interactive)
- (calculator-push-curnum)
- (if (or calculator-input-radix calculator-output-radix)
- (setq calculator-input-radix nil
- calculator-output-radix nil)
- ;; already decimal -- toggle degrees mode
- (setq calculator-deg (not calculator-deg)))
- (calculator-update-display t))
-
-(defun calculator-radix-mode (&optional keys)
- "Set input and display radix modes.
-Optional string argument KEYS will force using it as the keys entered."
- (interactive)
- (calculator-radix-input-mode keys)
- (calculator-radix-output-mode keys))
-
-(defun calculator-radix-input-mode (&optional keys)
- "Set input radix modes.
-Optional string argument KEYS will force using it as the keys entered."
- (interactive)
- (calculator-push-curnum)
- (setq calculator-input-radix
- (let ((inp (calculator-last-input keys)))
- (cdr (assq (upcase (aref inp (1- (length inp))))
- calculator-char-radix))))
- (calculator-update-display))
-
-(defun calculator-radix-output-mode (&optional keys)
- "Set display radix modes.
-Optional string argument KEYS will force using it as the keys entered."
- (interactive)
- (calculator-push-curnum)
- (setq calculator-output-radix
- (let ((inp (calculator-last-input keys)))
- (cdr (assq (upcase (aref inp (1- (length inp))))
- calculator-char-radix))))
- (calculator-update-display t))
-
-;;;---------------------------------------------------------------------
-;;; Saved values list
-
-(defun calculator-save-on-list ()
- "Evaluate current expression, put result on the saved values list."
- (interactive)
- (let ((calculator-add-saved t)) ; marks the result to be added
- (calculator-enter)))
-
-(defun calculator-clear-saved ()
- "Clear the list of saved values in `calculator-saved-list'."
- (interactive)
- (setq calculator-saved-list nil
- calculator-saved-ptr 0)
- (calculator-update-display t))
-
-(defun calculator-saved-move (n)
- "Go N elements up the list of saved values.
-Interactively, N is the prefix numeric argument and defaults to 1."
- (interactive "p")
- (when (and calculator-saved-list
- (or (null calculator-stack) calculator-display-fragile))
- (setq calculator-saved-ptr
- (max (min (+ n calculator-saved-ptr)
- (length calculator-saved-list))
- 0))
- (if (nth calculator-saved-ptr calculator-saved-list)
- (setq calculator-stack (list (nth calculator-saved-ptr
- calculator-saved-list))
- calculator-display-fragile t)
- (calculator-reset))
- (calculator-update-display)))
-
-(defun calculator-saved-up ()
- "Go up the list of saved values."
- (interactive)
- (calculator-saved-move +1))
-
-(defun calculator-saved-down ()
- "Go down the list of saved values."
- (interactive)
- (calculator-saved-move -1))
-
-;;;---------------------------------------------------------------------
-;;; Misc functions
-
-(defun calculator-open-paren ()
- "Equivalents of `(' use this."
- (interactive)
- (calculator-op "("))
-
-(defun calculator-close-paren ()
- "Equivalents of `)' use this."
- (interactive)
- (calculator-op ")"))
-
-(defun calculator-enter ()
- "Evaluate current expression."
- (interactive)
- (calculator-op "="))
-
-(defun calculator-backspace ()
- "Backward delete a single digit or a stack element."
- (interactive)
- (if calculator-curnum
- (setq calculator-curnum
- (if (> (length calculator-curnum) 1)
- (substring calculator-curnum
- 0 (1- (length calculator-curnum)))
- nil))
- (setq calculator-stack (cdr calculator-stack)))
- (calculator-update-display))
-
-(defun calculator-clear ()
- "Clear current number."
- (interactive)
- (setq calculator-curnum nil)
- (cond
- ;; if the current number is from the saved-list remove it
- ((and calculator-display-fragile
- calculator-saved-list
- (= (car calculator-stack)
- (nth calculator-saved-ptr calculator-saved-list)))
- (if (= 0 calculator-saved-ptr)
- (setq calculator-saved-list (cdr calculator-saved-list))
- (let ((p (nthcdr (1- calculator-saved-ptr)
- calculator-saved-list)))
- (setcdr p (cddr p))
- (setq calculator-saved-ptr (1- calculator-saved-ptr))))
- (if calculator-saved-list
- (setq calculator-stack
- (list (nth calculator-saved-ptr calculator-saved-list)))
- (calculator-reset)))
- ;; reset if fragile or double clear
- ((or calculator-display-fragile (eq last-command this-command))
- (calculator-reset)))
- (calculator-update-display))
-
-(defun calculator-copy ()
- "Copy current number to the `kill-ring'."
- (interactive)
- (let ((calculator-displayer
- (or calculator-copy-displayer calculator-displayer))
- (calculator-displayers
- (if calculator-copy-displayer nil calculator-displayers)))
- (calculator-enter)
- ;; remove trailing spaces and an index
- (let ((s (cdr calculator-stack-display)))
- (when s
- (kill-new (replace-regexp-in-string
- "^\\([^ ]+\\) *\\(\\[[0-9/]+\\]\\)? *$" "\\1" s))))))
-
-(defun calculator-put-value (val)
- "Paste VAL as if entered.
-Used by `calculator-paste' and `get-register'."
- (when (and (numberp val)
- ;; (not calculator-curnum)
- (or calculator-display-fragile
- (not (numberp (car calculator-stack)))))
- (calculator-clear-fragile)
- (setq calculator-curnum
- (let ((calculator-displayer "%S")
- (calculator-radix-grouping-mode nil)
- (calculator-output-radix calculator-input-radix))
- (calculator-number-to-string val)))
- (calculator-update-display)))
-
-(defun calculator-paste (arg)
- "Paste a value from the `kill-ring'.
-
-With a prefix argument, paste the raw string as a sequence of key
-presses, which can be used to paste expressions. Note that this
-is literal; examples: spaces will store values, pasting \"1+2\"
-will not produce 3 if it's done you're entering a number or after
-a multiplication."
- (interactive "P")
- (let ((str (current-kill 0)))
- (if arg
- (setq unread-command-events
- `(,@(listify-key-sequence str) ,@unread-command-events))
- (calculator-put-value (calculator-string-to-number str)))))
-
-(defun calculator-register-read-with-preview (prompt)
- "Similar to `register-read-with-preview' but for calculator registers."
- (let ((register-alist calculator-registers)
- (register-preview-delay 1)
- (register-preview-function
- (lambda (r)
- (format "%s: %s\n"
- (single-key-description (car r))
- (calculator-number-to-string (cdr r))))))
- (register-read-with-preview prompt)))
-
-(defun calculator-set-register (reg)
- "Set a register value for REG."
- (interactive (list (calculator-register-read-with-preview
- "Register to store value into: ")))
- (let* ((as (assq reg calculator-registers))
- (val (progn (calculator-enter) (car calculator-stack))))
- (if as
- (setcdr as val)
- (push (cons reg val) calculator-registers))
- (calculator-message "[%c] := %S" reg val)))
-
-(defun calculator-get-register (reg)
- "Get a value from a register REG."
- (interactive (list (calculator-register-read-with-preview
- "Register to get value from: ")))
- (calculator-put-value (cdr (assq reg calculator-registers))))
-
-(declare-function electric-describe-mode "ehelp" ())
-
-(defun calculator-help ()
- ;; this is used as the quick reference screen you get with `h'
- "Quick reference:
-* numbers/operators/parens/./e - enter expressions
- + - * / \\(div) %(rem) _(-X,postfix) ;(1/X,postfix) ^(exp) L(og)
- Q(sqrt) !(fact) S(in) C(os) T(an) |(or) #(xor) &(and) ~(not)
-* >/< repeats last binary operation with its 2nd (1st) arg as postfix op
-* I inverse the next trig function \
-* \\='/\"/{/} - display/display args
-* D - switch to all-decimal, or toggle deg/rad mode
-* B/O/H/X - binary/octal/hex mode for i/o (both H and X are for hex)
-* i/o - prefix for D/B/O/X - set only input/output modes
-* enter/= - evaluate current expr. * s/g - set/get a register
-* space - evaluate & save on list * l/v - list total/average
-* up/down/C-p/C-n - browse saved * C-delete - clear all saved
-* C-insert - copy whole expr. * C-return - evaluate, copy, exit
-* insert - paste a number * backspace- delete backwards
-* delete - clear argument or list value or whole expression (twice)
-* escape/q - exit."
- (interactive)
- (if (eq last-command 'calculator-help)
- (let ((mode-name "Calculator")
- (major-mode 'calculator-mode)
- (win (selected-window)))
- (require 'ehelp)
- (if (not calculator-electric-mode)
- (describe-mode)
- (electric-describe-mode))
- (select-window win)
- (message nil))
- (let ((one (one-window-p t))
- (win (selected-window))
- (help-buf (get-buffer-create "*Help*")))
- (save-window-excursion
- (with-output-to-temp-buffer "*Help*"
- (princ (documentation 'calculator-help)))
- (when one (shrink-window-if-larger-than-buffer
- (get-buffer-window help-buf)))
- (message "`%s' again for more help, %s."
- (calculator-last-input)
- "any other key continues normally")
- (select-window win)
- (sit-for 360))
- (select-window win))))
-
-(defun calculator-quit ()
- "Quit calculator."
- (interactive)
- (set-buffer calculator-buffer)
- (let ((inhibit-read-only t)) (erase-buffer))
- (unless calculator-electric-mode
- (ignore-errors
- (while (get-buffer-window calculator-buffer)
- (delete-window (get-buffer-window calculator-buffer)))))
- (kill-buffer calculator-buffer)
- (message "Calculator done.")
- (if calculator-electric-mode
- (throw 'calculator-done nil) ; will kill the buffer
- (setq calculator-buffer nil)))
-
-(defun calculator-save-and-quit ()
- "Quit the calculator, saving the result on the `kill-ring'."
- (interactive)
- (calculator-enter)
- (calculator-copy)
- (calculator-quit))
-
-(defun calculator-repR (x)
- "Repeat the last binary operation with its second argument and X.
-To use this, apply a binary operator (evaluate it), then call this."
- (if calculator-last-opXY
- ;; avoid rebinding calculator-last-opXY
- (let ((calculator-last-opXY calculator-last-opXY))
- (calculator-funcall
- (car calculator-last-opXY) x (nth 2 calculator-last-opXY)))
- x))
-
-(defun calculator-repL (x)
- "Repeat the last binary operation with its first argument and X.
-To use this, apply a binary operator (evaluate it), then call this."
- (if calculator-last-opXY
- ;; avoid rebinding calculator-last-opXY
- (let ((calculator-last-opXY calculator-last-opXY))
- (calculator-funcall
- (car calculator-last-opXY) (nth 1 calculator-last-opXY) x))
- x))
-
-(defun calculator-expt (x y)
- "Compute X^Y, dealing with errors appropriately."
- (condition-case nil
- (expt x y)
- (overflow-error
- ;; X and Y must be integers, as expt silently returns floating-point
- ;; infinity on floating-point overflow.
- (if (or (natnump x) (zerop (logand y 1)))
- 1.0e+INF
- -1.0e+INF))))
-
-(defun calculator-fact (x)
- "Simple factorial of X."
- (cond ((>= x 1.0e+INF) x)
- ((or (and (floatp x) (isnan x)) (< x 0)) 0.0e+NaN)
- ((>= (calculator-expt (/ x 3.0) x) 1.0e+INF) 1.0e+INF)
- (t (let ((x (truncate x)) (r 1.0))
- (while (> x 0) (setq r (* r x) x (1- x)))
- r))))
-
-(defun calculator-truncate (n)
- "Truncate N, return 0 in case of overflow."
- (condition-case nil (truncate n) (range-error 0)))
-
-
-(provide 'calculator)
-
-;;; calculator.el ends here
(require 'loaddefs-gen)
-;; Hack workaround for bug#14384.
-;; Define defcustom-mh as an alias for defcustom, etc.
-;; Only do this in batch mode to avoid messing up a normal Emacs session.
-;; Alternative would be to load mh-e when making cus-load.
-;; (Would be better to split just the necessary parts of mh-e into a
-;; separate file and only load that.)
-(when (and noninteractive)
- (mapc (lambda (e) (let ((sym (intern (format "%s-mh" e))))
- (or (fboundp sym)
- (defalias sym e))))
- '(defcustom defface defgroup)))
-
(defun custom--get-def (expr)
(if (not (memq (car-safe expr)
'( define-minor-mode define-globalized-minor-mode)))
+++ /dev/null
-;;; ebuff-menu.el --- electric-buffer-list mode -*- lexical-binding: t -*-
-
-;; Copyright (C) 1985-1986, 1994, 2001-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Richard Mlynarik <mly@ai.mit.edu>
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: convenience
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Who says one can't have typeout windows in GNU Emacs? The entry
-;; point, `electric-buffer-list' works like ^r select buffer from the
-;; ITS Emacs lunar or tmacs libraries.
-
-;;; Code:
-
-(require 'electric)
-
-(defvar electric-buffer-menu-mode-map
- (let ((map (make-keymap)))
- (fillarray (car (cdr map)) #'Electric-buffer-menu-undefined)
- (define-key map "\e" nil)
- (define-key map "\C-z" #'suspend-frame)
- (define-key map "v" #'Electric-buffer-menu-mode-view-buffer)
- (define-key map "\C-c" nil)
- (define-key map "\C-c\C-c" #'Electric-buffer-menu-quit)
- (define-key map "\C-]" #'Electric-buffer-menu-quit)
- (define-key map "q" #'Electric-buffer-menu-quit)
- (define-key map " " #'Electric-buffer-menu-select)
- (define-key map "\C-m" #'Electric-buffer-menu-select)
- (define-key map "\C-l" #'recenter)
- (define-key map "s" #'Buffer-menu-save)
- (define-key map "S" #'tabulated-list-sort)
- (define-key map "d" #'Buffer-menu-delete)
- (define-key map "k" #'Buffer-menu-delete)
- (define-key map "\C-d" #'Buffer-menu-delete-backwards)
- ;; (define-key map "\C-k" #'Buffer-menu-delete)
- (define-key map "\177" #'Buffer-menu-backup-unmark)
- (define-key map "~" #'Buffer-menu-not-modified)
- (define-key map "u" #'Buffer-menu-unmark)
- (define-key map "\M-\177" #'Buffer-menu-unmark-all-buffers)
- (define-key map "U" #'Buffer-menu-unmark-all)
- (dotimes (i 10)
- (define-key map (char-to-string i) #'digit-argument)
- (define-key map (concat "\e" (char-to-string i)) #'digit-argument))
- (define-key map "-" #'negative-argument)
- (define-key map "\e-" #'negative-argument)
- (define-key map "m" #'Buffer-menu-mark)
- (define-key map "\C-u" #'universal-argument)
- (define-key map "\C-p" #'previous-line)
- (define-key map "\C-n" #'next-line)
- (define-key map "p" #'previous-line)
- (define-key map "n" #'next-line)
- (define-key map "\C-v" #'scroll-up-command)
- (define-key map "\ev" #'scroll-down-command)
- (define-key map ">" #'scroll-right)
- (define-key map "<" #'scroll-left)
- (define-key map "\e\C-v" #'scroll-other-window)
- (define-key map "\e>" #'end-of-buffer)
- (define-key map "\e<" #'beginning-of-buffer)
- (define-key map "\e\e" nil)
- (define-key map "\e\e\e" #'Electric-buffer-menu-quit)
- ;; This binding prevents the "escape => ESC" function-key-map mapping from
- ;; kicking in!
- ;; (define-key map [escape escape escape] #'Electric-buffer-menu-quit)
- (define-key map [mouse-2] #'Electric-buffer-menu-mouse-select)
- map))
-
-(put 'Electric-buffer-menu-quit :advertised-binding "\C-c\C-c")
-(put 'Electric-buffer-menu-select :advertised-binding " ")
-
-(defvar electric-buffer-menu-mode-hook nil
- "Normal hook run by `electric-buffer-menu-mode'.")
-
-;;;###autoload
-(defun electric-buffer-list (arg)
- "Pop up the Buffer Menu in an \"electric\" window.
-If you type SPC or RET (`Electric-buffer-menu-select'), that
-selects the buffer at point and quits the \"electric\" window.
-Otherwise, you can move around in the Buffer Menu, marking
-buffers to be selected, saved or deleted; these other commands
-are much like those of `Buffer-menu-mode'.
-
-Run hooks in `electric-buffer-menu-mode-hook' on entry.
-
-\\<electric-buffer-menu-mode-map>
-\\[keyboard-quit] or \\[Electric-buffer-menu-quit] -- exit buffer menu, returning to previous window and buffer
- configuration. If the very first character typed is a space, it
- also has this effect.
-\\[Electric-buffer-menu-select] -- select buffer of line point is on.
- Also show buffers marked with m in other windows,
- deletes buffers marked with \"D\", and saves those marked with \"S\".
-\\[Buffer-menu-mark] -- mark buffer to be displayed.
-\\[Buffer-menu-not-modified] -- clear modified-flag on that buffer.
-\\[Buffer-menu-save] -- mark that buffer to be saved.
-\\[Buffer-menu-delete] or \\[Buffer-menu-delete-backwards] -- mark that buffer to be deleted.
-\\[Buffer-menu-unmark] -- remove all kinds of marks from current line.
-\\[Buffer-menu-unmark-all] -- remove all kinds of marks from all lines.
-\\[Electric-buffer-menu-mode-view-buffer] -- view buffer, returning when done.
-\\[Buffer-menu-backup-unmark] -- back up a line and remove marks."
- (interactive "P")
- (let (select buffer)
- (save-window-excursion
- (setq buffer (list-buffers-noselect arg))
- (Electric-pop-up-window buffer)
- (unwind-protect
- (let ((header header-line-format))
- (set-buffer buffer)
- (electric-buffer-menu-mode)
- (setq header-line-format header)
- (goto-char (point-min))
- (if (search-forward "\n." nil t)
- (forward-char -1))
- (electric-buffer-update-highlight)
- (setq select
- (catch 'electric-buffer-menu-select
- (message "<<< Type SPC or RET to bury the buffer list >>>")
- (push (read-event) unread-command-events)
- (let ((start-point (point))
- (first (progn (goto-char (point-min))
- (unless Buffer-menu-use-header-line
- (forward-line 2))
- (point)))
- (last (progn (goto-char (point-max))
- (forward-line -1)
- (point)))
- (goal-column 0))
- ;; Use start-point if it is meaningful.
- (goto-char (if (or (< start-point first)
- (> start-point last))
- first
- start-point))
- (Electric-command-loop 'electric-buffer-menu-select
- nil
- t
- 'electric-buffer-menu-looper
- (cons first last))))))
- (set-buffer buffer)
- (Buffer-menu-mode)
- (bury-buffer) ;Get rid of window, if dedicated.
- (message "")))
- (when select
- (set-buffer buffer)
- (goto-char select)
- (let ((opoint (point-marker)))
- (Buffer-menu-execute)
- (goto-char (point-min))
- (if (prog1 (search-forward "\n>" nil t)
- (goto-char opoint)
- (set-marker opoint nil))
- (Buffer-menu-select)
- (switch-to-buffer (Buffer-menu-buffer t)))))))
-
-(defun electric-buffer-menu-looper (state condition)
- (cond ((and condition
- (not (memq (car condition) '(buffer-read-only
- end-of-buffer
- beginning-of-buffer))))
- (signal (car condition) (cdr condition)))
- ((< (point) (car state))
- (goto-char (point-min))
- (unless Buffer-menu-use-header-line
- (forward-line 2)))
- ((> (point) (cdr state))
- (goto-char (point-max))
- (forward-line -1)
- (if (pos-visible-in-window-p (point-max))
- (recenter -1))))
- (electric-buffer-update-highlight))
-
-(define-derived-mode electric-buffer-menu-mode Buffer-menu-mode
- "Electric Buffer Menu"
- "Toggle Electric Buffer Menu mode in this buffer.
-With a prefix argument ARG, enable Long Lines mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-Electric Buffer Menu mode is a minor mode which is automatically
-enabled and disabled by the \\[electric-buffer-list] command.
-See the documentation of `electric-buffer-list' for details."
- (setq mode-line-buffer-identification "Electric Buffer List"))
-
-;; generally the same as Buffer-menu-mode-map
-;; (except we don't indirect to global-map)
-(put 'Electric-buffer-menu-undefined 'suppress-keymap t)
-
-(defun Electric-buffer-menu-exit ()
- (interactive)
- (setq unread-command-events
- (nconc (listify-key-sequence (this-command-keys))
- unread-command-events))
- ;; for robustness
- (condition-case ()
- (throw 'electric-buffer-menu-select nil)
- (error (Buffer-menu-mode)
- (other-buffer))))
-
-(defun Electric-buffer-menu-select ()
- "Leave Electric Buffer Menu, selecting buffers and executing changes.
-Save buffers marked \"S\". Delete buffers marked \"K\".
-Select buffer at point and display buffers marked \">\" in other windows."
- (interactive)
- (throw 'electric-buffer-menu-select (point)))
-
-(defun Electric-buffer-menu-mouse-select (event)
- (interactive "e")
- (select-window (posn-window (event-end event)))
- (set-buffer (window-buffer))
- (goto-char (posn-point (event-end event)))
- (throw 'electric-buffer-menu-select (point)))
-
-(defun Electric-buffer-menu-quit ()
- "Leave Electric Buffer Menu, restoring previous window configuration.
-Skip execution of select, save, and delete commands."
- (interactive)
- (throw 'electric-buffer-menu-select nil))
-
-(defun Electric-buffer-menu-undefined ()
- (interactive)
- (ding)
- (message "%s"
- (substitute-command-keys "\
-Type \\[Electric-buffer-menu-quit] to exit, \
-\\[Electric-buffer-menu-select] to select."))
- (sit-for 4))
-
-(defun Electric-buffer-menu-mode-view-buffer ()
- "View buffer on current line in Electric Buffer Menu.
-Return to Electric Buffer Menu when done."
- (interactive)
- (let ((bufnam (Buffer-menu-buffer nil)))
- (if bufnam
- (view-buffer bufnam)
- (ding)
- (message "Buffer %s does not exist!" bufnam)
- (sit-for 4))))
-
-(defvar electric-buffer-overlay nil)
-
-(defun electric-buffer-update-highlight ()
- (when (derived-mode-p 'electric-buffer-menu-mode)
- ;; Make sure we have an overlay to use.
- (or electric-buffer-overlay
- (setq-local electric-buffer-overlay
- (make-overlay (point) (point))))
- (move-overlay electric-buffer-overlay
- (line-beginning-position)
- (line-end-position))
- (overlay-put electric-buffer-overlay 'face 'highlight)))
-
-(provide 'ebuff-menu)
-
-;;; ebuff-menu.el ends here
+++ /dev/null
-;;; ehelp.el --- bindings for electric-help mode -*- lexical-binding: t -*-
-
-;; Copyright (C) 1986, 1995, 2000-2024 Free Software Foundation, Inc.
-
-;; Author: Richard Mlynarik
-;; (according to ack.texi and authors.el)
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: help, extensions
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This package provides a pre-packaged `Electric Help Mode' for
-;; browsing Emacs help screens. There is one entry point,
-;; `with-electric-help'; all you have to give it is a no-argument
-;; function that generates the actual text of the help into the current
-;; buffer.
-
-;; To make this the default, you must do
-;; (define-key global-map "\C-h" 'ehelp-command)
-;; (define-key global-map [help] 'ehelp-command)
-;; (define-key global-map [f1] 'ehelp-command)
-
-;;; Code:
-
-(require 'electric)
-
-(defvar electric-help-form-to-execute nil)
-
-(defgroup electric-help ()
- "Electric help facility."
- :version "21.1"
- :group 'help)
-
-(defcustom electric-help-shrink-window t
- "If set, adjust help window sizes to buffer sizes when displaying help."
- :type 'boolean
- :group 'electric-help)
-
-(defcustom electric-help-mode-hook nil
- "Hook run by `with-electric-help' after initializing the buffer."
- :type 'hook
- :group 'electric-help)
-
-(put 'electric-help-undefined 'suppress-keymap t)
-
-(defvar electric-help-map
- (let ((map (make-keymap)))
- ;; FIXME fragile. Should derive from help-mode-map in a smarter way.
- (set-keymap-parent map button-buffer-map)
- ;; allow all non-self-inserting keys - search, scroll, etc, but
- ;; let M-x and C-x exit ehelp mode and retain buffer:
- (suppress-keymap map)
- (define-key map "\C-u" 'electric-help-undefined)
- (define-key map [?\C-0] 'electric-help-undefined)
- (define-key map [?\C-1] 'electric-help-undefined)
- (define-key map [?\C-2] 'electric-help-undefined)
- (define-key map [?\C-3] 'electric-help-undefined)
- (define-key map [?\C-4] 'electric-help-undefined)
- (define-key map [?\C-5] 'electric-help-undefined)
- (define-key map [?\C-6] 'electric-help-undefined)
- (define-key map [?\C-7] 'electric-help-undefined)
- (define-key map [?\C-8] 'electric-help-undefined)
- (define-key map [?\C-9] 'electric-help-undefined)
- (define-key map (if (characterp help-char)
- (char-to-string help-char)
- (vector help-char))
- 'electric-help-help)
- (define-key map "?" 'electric-help-help)
- (define-key map " " 'scroll-up)
- (define-key map [?\S-\ ] 'scroll-down)
- (define-key map "\^?" 'scroll-down)
- (define-key map "." 'beginning-of-buffer)
- (define-key map "<" 'beginning-of-buffer)
- (define-key map ">" 'end-of-buffer)
- ;(define-key map "\C-g" 'electric-help-exit)
- (define-key map "Q" 'electric-help-exit)
- (define-key map "q" 'electric-help-exit)
- ;;a better key than this?
- (define-key map "R" 'electric-help-retain)
- (define-key map "r" 'electric-help-retain)
- (define-key map "\ex" 'electric-help-execute-extended)
- (define-key map "\C-x" 'electric-help-ctrl-x-prefix)
- map)
- "Keymap defining commands available in `electric-help-mode'.")
-
-(defvar-local electric-help-orig-major-mode nil)
-
-(defun electric-help-mode ()
- "`with-electric-help' temporarily places its buffer in this mode.
-\(On exit from `with-electric-help', the original `major-mode' is restored.)"
- (setq buffer-read-only t)
- (setq electric-help-orig-major-mode major-mode)
- (setq mode-name "Help")
- (setq major-mode 'help-mode)
- (setq mode-line-buffer-identification '(" Help: %b"))
- (use-local-map electric-help-map)
- (add-hook 'mouse-leave-buffer-hook 'electric-help-retain)
- (view-mode -1)
- ;; this is done below in with-electric-help
- ;(run-hooks 'electric-help-mode-hook)
- )
-
-;;;###autoload
-(defun with-electric-help (thunk &optional buffer noerase minheight)
- "Pop up an \"electric\" help buffer.
-THUNK is a function of no arguments which is called to initialize the
-contents of BUFFER. BUFFER defaults to `*Help*'. BUFFER will be
-erased before THUNK is called unless NOERASE is non-nil. THUNK will
-be called while BUFFER is current and with `standard-output' bound to
-the buffer specified by BUFFER.
-
-If THUNK returns nil, we display BUFFER starting at the top, and shrink
-the window to fit. If THUNK returns non-nil, we don't do those things.
-
-After THUNK has been called, this function \"electrically\" pops up a
-window in which BUFFER is displayed and allows the user to scroll
-through that buffer in `electric-help-mode'. The window's height will
-be at least MINHEIGHT if this value is non-nil.
-
-If THUNK returns nil, we display BUFFER starting at the top, and
-shrink the window to fit if `electric-help-shrink-window' is non-nil.
-If THUNK returns non-nil, we don't do those things.
-
-When the user exits (with `electric-help-exit', or otherwise), the help
-buffer's window disappears (i.e., we use `save-window-excursion'), and
-BUFFER is put back into its original major mode."
- (setq buffer (get-buffer-create (or buffer "*Help*")))
- (let ((one (one-window-p t))
- (config (current-window-configuration))
- (bury nil)
- (electric-help-form-to-execute nil))
- (unwind-protect
- (save-excursion
- (when one
- (goto-char (window-start)))
- (let ((pop-up-windows t))
- (pop-to-buffer buffer))
- (with-current-buffer buffer
- (when (and minheight (< (window-height) minheight))
- (enlarge-window (- minheight (window-height))))
- (electric-help-mode)
- (setq buffer-read-only nil)
- (unless noerase
- (erase-buffer)))
- (let ((standard-output buffer))
- (unless (funcall thunk)
- (set-buffer buffer)
- (set-buffer-modified-p nil)
- (goto-char (point-min))
- (when (and one electric-help-shrink-window)
- (shrink-window-if-larger-than-buffer))))
- (set-buffer buffer)
- (run-hooks 'electric-help-mode-hook)
- (setq buffer-read-only t)
- (if (eq (car-safe (electric-help-command-loop)) 'retain)
- (setq config (current-window-configuration))
- (setq bury t))
- ;; Remove the hook.
- (when (memq 'electric-help-retain mouse-leave-buffer-hook)
- (remove-hook 'mouse-leave-buffer-hook 'electric-help-retain)))
- (message "")
- (set-buffer buffer)
- (setq buffer-read-only nil)
-
- ;; Restore the original major mode saved by `electric-help-mode'.
- ;; We should really get a usable *Help* buffer when retaining
- ;; the electric one with `r'. The problem is that a simple
- ;; call to `help-mode' won't cut it; e.g. RET is bound wrong
- ;; afterwards (`View-scroll-line-forward' instead of `help-follow').
- ;; That's because Help mode should be set with `with-help-window'
- ;; instead of the direct call to `help-mode'. But at least
- ;; RET works correctly on links after using `help-mode'.
- ;; This is satisfactory enough.
- (condition-case ()
- (funcall (or electric-help-orig-major-mode 'fundamental-mode))
- (error nil))
-
- (set-window-configuration config)
- (when bury
- ;;>> Perhaps this shouldn't be done,
- ;; so that when we say "Press space to bury" we mean it
- (replace-buffer-in-windows buffer)
- ;; must do this outside of save-window-excursion
- (bury-buffer buffer))
- (if (functionp electric-help-form-to-execute)
- (funcall electric-help-form-to-execute)
- (eval electric-help-form-to-execute)))))
-
-(defun electric-help-command-loop ()
- (catch 'exit
- (if (pos-visible-in-window-p (point-max))
- (progn (message "%s" (substitute-command-keys "<<< Press Space to bury the help buffer, Press \\[electric-help-retain] to retain it >>>"))
- (let ((ev (read-event)))
- (if (equal ev ?\s)
- (throw 'exit t)
- (push ev unread-command-events)))))
- (let (up down both neither
- (standard (and (eq (key-binding " " nil t)
- 'scroll-up)
- (eq (key-binding "\^?" nil t)
- 'scroll-down)
- (eq (key-binding "q" nil t)
- 'electric-help-exit)
- (eq (key-binding "r" nil t)
- 'electric-help-retain))))
- (Electric-command-loop
- 'exit
- (lambda ()
- (sit-for 0) ;necessary if last command was end-of-buffer or
- ;beginning-of-buffer - otherwise pos-visible-in-window-p
- ;will yield a wrong result.
- (let ((min (pos-visible-in-window-p (point-min)))
- (max (pos-visible-in-window-p (1- (point-max)))))
- (cond (isearch-mode 'noprompt)
- ((and min max)
- (cond (standard "Press q to exit, r to retain ")
- (neither)
- (t (setq neither (substitute-command-keys "Press \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))
- (min
- (cond (standard "Press SPC to scroll, q to exit, r to retain ")
- (up)
- (t (setq up (substitute-command-keys "Press \\[scroll-up] to scroll, \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))
- (max
- (cond (standard "Press DEL to scroll back, q to exit, r to retain ")
- (down)
- (t (setq down (substitute-command-keys "Press \\[scroll-down] to scroll back, \\[electric-help-exit] to exit, \\[electric-help-retain] to retain ")))))
- (t
- (cond (standard "Press SPC to scroll, DEL to scroll back, q to exit, r to retain ")
- (both)
- (t (setq both (substitute-command-keys "Press \\[scroll-up] to scroll, \\[scroll-down] to scroll back, \\[electric-help-exit] to exit, \\[electric-help-retain] to retain "))))))))
- t))))
-
-
-\f
-;(defun electric-help-scroll-up (arg)
-; ">>>Doc"
-; (interactive "P")
-; (if (and (null arg) (pos-visible-in-window-p (point-max)))
-; (electric-help-exit)
-; (scroll-up arg)))
-
-(defun electric-help-exit ()
- "Exit `with-electric-help', restoring the previous window/buffer configuration.
-\(The *Help* buffer will be buried.)"
- (interactive)
- ;; Make sure that we don't throw twice, even if two events cause
- ;; calling this function:
- (if (memq 'electric-help-retain mouse-leave-buffer-hook)
- (progn
- (remove-hook 'mouse-leave-buffer-hook 'electric-help-retain)
- (throw 'exit t))))
-
-(defun electric-help-retain ()
- "Exit `with-electric-help', retaining the current window/buffer configuration.
-\(The *Help* buffer will not be selected, but \\[switch-to-buffer-other-window] RET
-will select it.)"
- (interactive)
- ;; Make sure that we don't throw twice, even if two events cause
- ;; calling this function:
- (if (memq 'electric-help-retain mouse-leave-buffer-hook)
- (progn
- (remove-hook 'mouse-leave-buffer-hook 'electric-help-retain)
- (throw 'exit '(retain)))))
-
-
-(defun electric-help-undefined ()
- (interactive)
- (error "%s is undefined -- Press %s to exit"
- (mapconcat 'single-key-description (this-command-keys) " ")
- (if (eq (key-binding "q" nil t) 'electric-help-exit)
- "q"
- (substitute-command-keys "\\[electric-help-exit]"))))
-
-
-;>>> this needs to be hairified (recursive help, anybody?)
-(defun electric-help-help ()
- (interactive)
- (if (and (eq (key-binding "q" nil t) 'electric-help-exit)
- (eq (key-binding " " nil t) 'scroll-up)
- (eq (key-binding "\^?" nil t) 'scroll-down)
- (eq (key-binding "r" nil t) 'electric-help-retain))
- (message "SPC scrolls up, DEL scrolls down, q exits burying help buffer, r exits")
- (message "%s" (substitute-command-keys "\\[scroll-up] scrolls up, \\[scroll-down] scrolls down, \\[electric-help-exit] exits burying help buffer, \\[electric-help-retain] exits")))
- (sit-for 2))
-
-\f
-;;;###autoload
-(defun electric-helpify (fun &optional name)
- (let ((name (or name "*Help*")))
- (if (save-window-excursion
- ;; kludge-o-rama
- (let* ((p (symbol-function 'help-print-return-message))
- (b (get-buffer name))
- (m (buffer-modified-p b)))
- (and b (not (get-buffer-window b))
- (setq b nil))
- (unwind-protect
- (progn
- (message "%s..." (capitalize (symbol-name fun)))
- ;; with-output-to-temp-buffer marks the buffer as unmodified.
- ;; kludging excessively and relying on that as some sort
- ;; of indication leads to the following abomination...
- ;;>> This would be doable without such icky kludges if either
- ;;>> (a) there were a function to read the interactive
- ;;>> args for a command and return a list of those args.
- ;;>> (To which one would then just apply the command)
- ;;>> (The only problem with this is that interactive-p
- ;;>> would break, but that is such a misfeature in
- ;;>> any case that I don't care)
- ;;>> It is easy to do this for emacs-lisp functions;
- ;;>> the only problem is getting the interactive spec
- ;;>> for subrs
- ;;>> (b) there were a function which returned a
- ;;>> modification-tick for a buffer. One could tell
- ;;>> whether a buffer had changed by whether the
- ;;>> modification-tick were different.
- ;;>> (Presumably there would have to be a way to either
- ;;>> restore the tick to some previous value, or to
- ;;>> suspend updating of the tick in order to allow
- ;;>> things like momentary-string-display)
- (and b
- (with-current-buffer b
- (set-buffer-modified-p t)))
- (fset 'help-print-return-message 'ignore)
- (call-interactively fun)
- (and (get-buffer name)
- (get-buffer-window (get-buffer name))
- (or (not b)
- (not (eq b (get-buffer name)))
- (not (buffer-modified-p b)))))
- (fset 'help-print-return-message p)
- (and b (buffer-name b)
- (with-current-buffer b
- (set-buffer-modified-p m))))))
- (with-electric-help 'ignore name t))))
-
-\f
-
-;; This is to be bound to M-x in ehelp mode. Retains ehelp buffer and then
-;; continues with execute-extended-command.
-(defun electric-help-execute-extended (_prefixarg)
- (interactive "p")
- (setq electric-help-form-to-execute
- (lambda ()
- (with-suppressed-warnings ((interactive-only
- execute-extended-command))
- (execute-extended-command nil))))
- (electric-help-retain))
-
-;; This is to be buond to C-x in ehelp mode. Retains ehelp buffer and then
-;; continues with ctrl-x prefix.
-(defun electric-help-ctrl-x-prefix (_prefixarg)
- (interactive "p")
- (setq electric-help-form-to-execute
- (lambda ()
- (message nil)
- (setq unread-command-events
- (append unread-command-events '(?\C-x)))))
- (electric-help-retain))
-
-\f
-(defun electric-describe-key ()
- (interactive)
- (electric-helpify 'describe-key))
-
-(defun electric-describe-mode ()
- (interactive)
- (electric-helpify 'describe-mode))
-
-(defun electric-view-lossage ()
- (interactive)
- (electric-helpify 'view-lossage))
-
-(defun electric-describe-function ()
- (interactive)
- (electric-helpify 'describe-function))
-
-(defun electric-describe-variable ()
- (interactive)
- (electric-helpify 'describe-variable))
-
-(defun electric-describe-bindings ()
- (interactive)
- (electric-helpify 'describe-bindings))
-
-(defun electric-describe-syntax ()
- (interactive)
- (electric-helpify 'describe-syntax))
-
-(defun electric-command-apropos ()
- (interactive)
- (electric-helpify 'command-apropos "*Apropos*"))
-
-;(define-key help-map "a" 'electric-command-apropos)
-
-(defun electric-apropos ()
- (interactive)
- (electric-helpify 'apropos))
-
-\f
-;;;; ehelp-map
-
-(defvar ehelp-map
- (let ((map (copy-keymap help-map)))
- (substitute-key-definition 'apropos 'electric-apropos map)
- (substitute-key-definition 'command-apropos 'electric-command-apropos map)
- (substitute-key-definition 'describe-key 'electric-describe-key map)
- (substitute-key-definition 'describe-mode 'electric-describe-mode map)
- (substitute-key-definition 'view-lossage 'electric-view-lossage map)
- (substitute-key-definition 'describe-function 'electric-describe-function map)
- (substitute-key-definition 'describe-variable 'electric-describe-variable map)
- (substitute-key-definition 'describe-bindings 'electric-describe-bindings map)
- (substitute-key-definition 'describe-syntax 'electric-describe-syntax map)
- map))
-
-;;;###(autoload 'ehelp-command "ehelp" "Prefix command for ehelp." t 'keymap)
-(defalias 'ehelp-command ehelp-map)
-(put 'ehelp-command 'documentation "Prefix command for ehelp.")
-
-(provide 'ehelp)
-
-;;; ehelp.el ends here
;;; Code:
-;; This loop is the guts for non-standard modes which retain control
-;; until some event occurs. It is a `do-forever', the only way out is
-;; to throw. It assumes that you have set up the keymap, window, and
-;; everything else: all it does is read commands and execute them -
-;; providing error messages should one occur (if there is no loop
-;; function - which see). The required argument is a tag which should
-;; expect a value of nil if the user decides to punt. The second
-;; argument is the prompt to be used: if nil, use "->", if 'noprompt,
-;; don't use a prompt, if a string, use that string as prompt, and if
-;; a function of no variable, it will be evaluated in every iteration
-;; of the loop and its return value, which can be nil, 'noprompt or a
-;; string, will be used as prompt. Given third argument non-nil, it
-;; INHIBITS quitting unless the user types C-g at toplevel. This is
-;; so user can do things like C-u C-g and not get thrown out. Fourth
-;; argument, if non-nil, should be a function of two arguments which
-;; is called after every command is executed. The fifth argument, if
-;; provided, is the state variable for the function. If the
-;; loop-function gets an error, the loop will abort WITHOUT throwing
-;; (moral: use unwind-protect around call to this function for any
-;; critical stuff). The second argument for the loop function is the
-;; conditions for any error that occurred or nil if none.
-
-(defun Electric-command-loop (return-tag
- &optional prompt inhibit-quitting
- loop-function loop-state)
-
- (let (cmd
- (err nil)
- (inhibit-quit inhibit-quitting)
- (prompt-string prompt))
- (while t
- (if (functionp prompt)
- (setq prompt-string (funcall prompt)))
- (if (not (stringp prompt-string))
- (setq prompt-string (unless (eq prompt-string 'noprompt) "->")))
- (setq cmd (read-key-sequence prompt-string))
- (setq last-command-event (aref cmd (1- (length cmd)))
- this-command (key-binding cmd t)
- cmd this-command)
- (if (or (prog1 quit-flag (setq quit-flag nil))
- (eq last-input-event ?\C-g))
- (progn (setq unread-command-events nil
- prefix-arg nil)
- ;; If it wasn't canceling a prefix character, then quit.
- (if (or (= (length (this-command-keys)) 1)
- (not inhibit-quit)) ; safety
- (progn (ding)
- (message "Quit")
- (throw return-tag nil))
- (setq cmd nil))))
- (setq current-prefix-arg prefix-arg)
- (if cmd
- (condition-case conditions
- (progn (command-execute cmd)
- (setq last-command this-command)
- (if (or (prog1 quit-flag (setq quit-flag nil))
- (eq last-input-event ?\C-g))
- (progn (setq unread-command-events nil)
- (if (not inhibit-quit)
- (progn (ding)
- (message "Quit")
- (throw return-tag nil))
- (ding)))))
- (buffer-read-only (if loop-function
- (setq err conditions)
- (ding)
- (message "Buffer is read-only")
- (sit-for 2)))
- (beginning-of-buffer (if loop-function
- (setq err conditions)
- (ding)
- (message "Beginning of Buffer")
- (sit-for 2)))
- (end-of-buffer (if loop-function
- (setq err conditions)
- (ding)
- (message "End of Buffer")
- (sit-for 2)))
- (error (if loop-function
- (setq err conditions)
- (ding)
- (message "Error: %s"
- (if (eq (car conditions) 'error)
- (car (cdr conditions))
- (prin1-to-string conditions)))
- (sit-for 2))))
- (ding))
- (if loop-function (funcall loop-function loop-state err))))
- (ding)
- (throw return-tag nil))
-
-;; This function is like pop-to-buffer, sort of.
-;; The algorithm is
-;; If there is a window displaying buffer
-;; Select it
-;; Else if there is only one window
-;; Split it, selecting the window on the bottom with height being
-;; the lesser of max-height (if non-nil) and the number of lines in
-;; the buffer to be displayed subject to window-min-height constraint.
-;; Else
-;; Switch to buffer in the current window.
-;;
-;; Then if max-height is nil, and not all of the lines in the buffer
-;; are displayed, grab the whole frame.
-;;
-;; Returns selected window on buffer positioned at point-min.
-
-(defun Electric-pop-up-window (buffer &optional max-height)
- (let* ((win (or (get-buffer-window buffer) (selected-window)))
- (buf (get-buffer buffer))
- (one-window (one-window-p t))
- (pop-up-windows t)
- (pop-up-frames nil))
- (if (not buf)
- (error "Buffer %s does not exist" buffer)
- (cond ((and (eq (window-buffer win) buf))
- (select-window win))
- (one-window
- (pop-to-buffer buffer)
- (setq win (selected-window)))
- (t
- (switch-to-buffer buf)))
- ;; Don't shrink the window, but expand it if necessary.
- (goto-char (point-min))
- (unless (= (point-max) (window-end win t))
- ;; This call is executed even if the window existed before, was
- ;; reused, ... contradicting a claim in the comment before this
- ;; function.
- (fit-window-to-buffer win max-height nil nil nil t))
- win)))
-
;;; Electric keys.
(defgroup electricity ()
+++ /dev/null
-;;; edt-lk201.el --- enhanced EDT keypad mode emulation for LK-201 keyboards -*- lexical-binding: t -*-
-
-;; Copyright (C) 1986, 1992-1993, 1995, 2001-2024 Free Software
-;; Foundation, Inc.
-
-;; Author: Kevin Gallagher <kevin.gal@verizon.net>
-;; Keywords: emulations
-;; Package: edt
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; See Info node `edt' for more details.
-
-;; ====================================================================
-\f
-;;;;
-;;;; KEY TRANSLATIONS
-;;;;
-
-;; Associate EDT keynames with Emacs terminal function vector names.
-;; (Function key vector names for LK-201 are found in lisp/term/lk201.el.)
-;;
-;; F1 - F5 are not available on many DEC VT series terminals.
-;; However, this is not always the case. So support for F1 - F5 is
-;; provided here and in lisp/term/lk201.el.
-
-;;; Code:
-
-(defconst *EDT-keys*
- '(("KP0" . [kp-0]) ("KP1" . [kp-1]) ("KP2" . [kp-2]) ("KP3" . [kp-3])
- ("KP4" . [kp-4]) ("KP5" . [kp-5]) ("KP6" . [kp-6]) ("KP7" . [kp-7])
- ("KP8" . [kp-8]) ("KP9" . [kp-9]) ("KP," . [kp-separator])
- ("KP-" . [kp-subtract]) ("KPP" . [kp-decimal]) ("KPE" . [kp-enter])
- ("PF1" . [kp-f1]) ("PF2" . [kp-f2]) ("PF3" . [kp-f3]) ("PF4" . [kp-f4])
- ("UP" . [up]) ("DOWN" . [down]) ("RIGHT" . [right]) ("LEFT" . [left])
- ("FIND" . [find]) ("INSERT" . [insert]) ("REMOVE" . [delete])
- ("SELECT" . [select]) ("PREVIOUS" . [prior]) ("NEXT" . [next])
- ("F1" . [f1]) ("F2" . [f2]) ("F3" . [f3]) ("F4" . [f4]) ("F5" . [f5])
- ("F6" . [f6]) ("F7" . [f7]) ("F8" . [f8]) ("F9" . [f9]) ("F10" . [f10])
- ("F11" . [f11]) ("F12" . [f12]) ("F13" . [f13]) ("F14" . [f14])
- ("HELP" . [help]) ("DO" . [menu]) ("F17" . [f17]) ("F18" . [f18])
- ("F19" . [f19]) ("F20" . [f20])))
-
-;;; edt-lk201.el ends here
+++ /dev/null
-;;; edt-mapper.el --- create an EDT LK-201 map file for X-Windows Emacs -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1994-1995, 2000-2024 Free Software Foundation, Inc.
-
-;; Author: Kevin Gallagher <kevin.gal@verizon.net>
-;; Keywords: emulations
-;; Package: edt
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-
-;; [Part of the GNU Emacs EDT Emulation.]
-
-;; This Emacs Lisp program can be used to create an Emacs Lisp file
-;; that defines the mapping of the user's keyboard to the LK-201
-;; keyboard function keys and keypad keys (around which EDT has been
-;; designed). Please read the "Usage" AND "Known Problems" sections
-;; below before attempting to run this program. (The design of this
-;; file, edt-mapper.el, was heavily influenced by tpu-mapper.el.)
-
-;; Version 4.0 contains the following enhancements:
-
-;; 1. If you access a workstation using an X Server, note that the
-;; initialization file generated by edt-mapper.el will now
-;; contain the name of the X Server vendor. This is a
-;; convenience for those who have access to their Unix account
-;; from more than one type of X Server. Since different X
-;; Servers typically require different EDT emulation
-;; initialization files, edt-mapper.el will now generate these
-;; different initialization files and save them with different
-;; names.
-
-;; 2. Also, edt-mapper.el is now capable of binding an ASCII key
-;; sequence, providing the ASCII key sequence prefix is already
-;; known by Emacs to be a prefix. As a result, some
-;; terminal/keyboard/window system configurations, which don't
-;; have a complete set of sensible function key map bindings, can
-;; still be configured for EDT Emulation.
-
-
-;; Usage:
-
-;; Simply load this file into Emacs and run the function edt-mapper,
-;; using the following command.
-
-;; emacs -q -l edt-mapper -f edt-mapper
-
-;; The "-q" option prevents loading of your init file (commands
-;; therein might confuse this program).
-
-;; An instruction screen showing the typical LK-201 terminal
-;; functions keys will be displayed, and you will be prompted to
-;; press the keys on your keyboard which you want to emulate the
-;; corresponding LK-201 keys.
-
-;; Finally, you will be prompted for the name of the file to store
-;; the key definitions. If you chose the default, it will be found
-;; and loaded automatically when the EDT emulation is started. If
-;; you specify a different file name, you will need to set the
-;; variable "edt-keys-file" before starting the EDT emulation.
-;; Here's how you might go about doing that in your init file:
-
-;; (setq edt-keys-file (expand-file-name "~/.my-emacs-keys"))
-
-
-;; Known Problems:
-
-;; Sometimes, edt-mapper will ignore a key you press, and just
-;; continue to prompt for the same key. This can happen when your
-;; window manager sucks up the key and doesn't pass it on to Emacs,
-;; or it could be an Emacs bug. Either way, there's nothing that
-;; edt-mapper can do about it. You must press RETURN, to skip the
-;; current key and continue. Later, you and/or your local Emacs guru
-;; can try to figure out why the key is being ignored.
-
-;;; History:
-;;
-
-;; Version 4.0 2000 Added 2 New Features
-
-;;; Code:
-
-;;;
-;;; Determine Window System, and X Server Vendor (if appropriate).
-;;;
-(define-obsolete-variable-alias 'edt-window-system 'window-system "27.1")
-
-(defconst edt-xserver (when (eq window-system 'x)
- (declare-function x-server-vendor "xfns.c"
- (&optional terminal))
- ;; The Cygwin window manager has a `/' in its
- ;; name, which breaks the generated file name of
- ;; the custom key map file. Replace `/' with a
- ;; `-' to work around that.
- (replace-regexp-in-string "[ /]" "-"
- (x-server-vendor)))
- "Indicates X server vendor name, if applicable.")
-
-
-;;;
-;;; Key variables
-;;;
-
-;; FIXME some/all of these should be let-bound, not global.
-(defvar edt-key nil)
-(defvar edt-enter nil)
-(defvar edt-return nil)
-(defvar edt-key-seq nil)
-(defvar edt-enter-seq nil)
-(defvar edt-return-seq nil)
-(defvar edt-term nil)
-
-;; To silence the byte-compiler
-(defvar EDT-key-name)
-(defvar edt-save-function-key-map)
-
-;;;
-;;; Key mapping functions
-;;;
-(defun edt-map-key (ident descrip)
- (interactive)
- (setq edt-key (read-key-sequence (format "Press %s%s: " ident descrip)))
- (cond ((not (equal edt-key edt-return))
- (set-buffer "Keys")
- (insert (if (vectorp edt-key)
- (format " (\"%s\" . %s)\n" ident edt-key)
- (format " (\"%s\" . \"%s\")\n" ident edt-key)))
- (set-buffer "Directions"))
- ;; bogosity to get next prompt to come up, if the user hits <CR>!
- ;; check periodically to see if this is still needed...
- (t
- (set-buffer "Keys")
- (insert (format " (\"%s\" . \"\" )\n" ident))
- (set-buffer "Directions")))
- edt-key)
-
-(defun edt-mapper ()
- (if noninteractive
- (user-error "edt-mapper cannot be loaded in batch mode"))
- ;; Determine Terminal Type (if appropriate).
- (if (and window-system (not (eq window-system 'tty)))
- (setq edt-term nil)
- (setq edt-term (getenv "TERM")))
- ;;
- ;; Implements a workaround for a feature that was added to simple.el.
- ;;
- ;; Many function keys have no Emacs functions assigned to them by
- ;; default. A subset of these are typically assigned functions in the
- ;; EDT emulation. This includes all the keypad keys and a some others
- ;; like Delete.
- ;;
- ;; Logic in simple.el maps some of these unassigned function keys to
- ;; ordinary typing keys. Where this is the case, a call to
- ;; read-key-sequence, below, does not return the name of the function
- ;; key pressed by the user but, instead, it returns the name of the
- ;; key to which it has been mapped. It needs to know the name of the
- ;; key pressed by the user. As a workaround, we assign a function to
- ;; each of the unassigned function keys of interest, here. These
- ;; assignments override the mapping to other keys and are only
- ;; temporary since, when edt-mapper is finished executing, it causes
- ;; Emacs to exit.
- ;;
- (mapc
- (lambda (function-key)
- (if (not (lookup-key (current-global-map) function-key))
- (define-key (current-global-map) function-key #'forward-char)))
- '([kp-0] [kp-1] [kp-2] [kp-3] [kp-4]
- [kp-5] [kp-6] [kp-7] [kp-8] [kp-9]
- [kp-space]
- [kp-tab]
- [kp-enter]
- [kp-multiply]
- [kp-add]
- [kp-separator]
- [kp-subtract]
- [kp-decimal]
- [kp-divide]
- [kp-equal]
- [backspace]
- [delete]
- [tab]
- [linefeed]
- [clear]))
- ;;
- ;; Make sure the window is big enough to display the instructions,
- ;; except where window cannot be re-sized.
- ;;
- (if (and window-system (not (eq window-system 'tty)))
- (set-frame-size (selected-frame) 80 36))
- ;;
- ;; Create buffers - Directions and Keys
- ;;
- (if (not (get-buffer "Directions")) (generate-new-buffer "Directions"))
- (if (not (get-buffer "Keys")) (generate-new-buffer "Keys"))
- ;;
- ;; Put header in the Keys buffer
- ;;
- (set-buffer "Keys")
- (insert "\
-;;
-;; Key definitions for the EDT emulation within GNU Emacs
-;;
-
-\(defconst *EDT-keys*
- '(
- ")
-
- ;;
- ;; Display directions
- ;;
- (switch-to-buffer "Directions")
- (if (and window-system (not (eq window-system 'tty)))
- (insert "
- EDT MAPPER
-
- You will be asked to press keys to create a custom mapping (under a
- Window Manager) of your keypad keys and function keys so that they can
- emulate the LK-201 keypad and function keys or the subset of keys found
- on a VT-100 series terminal keyboard. (The LK-201 keyboard is the
- standard keyboard attached to VT-200 series terminals, and above.)
-
- Sometimes, edt-mapper will ignore a key you press, and just continue to
- prompt for the same key. This can happen when your window manager sucks
- up the key and doesn't pass it on to Emacs, or it could be an Emacs bug.
- Either way, there's nothing that edt-mapper can do about it. You must
- press RETURN, to skip the current key and continue. Later, you and/or
- your local system guru can try to figure out why the key is being ignored.
-
- Start by pressing the RETURN key, and continue by pressing the keys
- specified in the mini-buffer. If you want to entirely omit a key,
- because your keyboard does not have a corresponding key, for example,
- just press RETURN at the prompt.
-
-")
- (insert "
- EDT MAPPER
-
- You will be asked to press keys to create a custom mapping of your
- keypad keys and function keys so that they can emulate the LK-201
- keypad and function keys or the subset of keys found on a VT-100
- series terminal keyboard. (The LK-201 keyboard is the standard
- keyboard attached to VT-200 series terminals, and above.)
-
- If you are using a real LK-201 keyboard, you should map the keys
- exactly as they are on the keyboard.
-
- Start by pressing the RETURN key, and continue by pressing the keys
- specified in the mini-buffer. If you want to entirely omit a key,
- because your keyboard does not have a corresponding key, for example,
- just press RETURN at the prompt.
-
-"))
-
- (delete-other-windows)
-
- ;;
- ;; Save <CR> for future reference.
- ;;
- ;; For Emacs running in a Window System, first hide bindings in
- ;; function-key-map.
- ;;
- (if window-system
- (progn
- (setq edt-save-function-key-map function-key-map)
- (setq function-key-map (make-sparse-keymap))))
- (setq edt-return (read-key-sequence "Hit carriage-return <CR> to continue "))
-
- ;;
- ;; Remove prefix-key bindings to F1 and F2 in global-map so they can be
- ;; bound in the EDT Emulation mode.
- ;;
- (global-unset-key [f1])
- (global-unset-key [f2])
-
- ;;
- ;; Display Keypad Diagram and Begin Prompting for Keys
- ;;
- (set-buffer "Directions")
- (delete-region (point-min) (point-max))
- (if (and window-system (not (eq window-system 'tty)))
- (insert "
-
- PRESS THE KEY SPECIFIED IN THE MINIBUFFER BELOW.
-
- Here's a picture of the standard LK-201 keypad for reference:
-
- ________________________ _______________________________
- | HELP | DO | | F17 | F18 | F19 | F20 |
- | | | | | | | |
- |_______|________________| |_______|_______|_______|_______|
- ________________________ _______________________________
- | FIND |INSERT |REMOVE | | PF1 | PF2 | PF3 | PF4 |
- | | | | | | | | |
- |_______|________|_______| |_______|_______|_______|_______|
- |SELECT |PREVIOUS|NEXT | | KP7 | KP8 | KP9 | KP- |
- | | | | | | | | |
- |_______|________|_______| |_______|_______|_______|_______|
- | UP | | KP4 | KP5 | KP6 | KP, |
- | | | | | | |
- _______|________|_______ |_______|_______|_______|_______|
- | LEFT | DOWN | RIGHT | | KP1 | KP2 | KP3 | |
- | | | | | | | | |
- |_______|________|_______| |_______|_______|_______| KPE |
- | KP0 | KPP | |
- | | | |
- |_______________|_______|_______|
-
- REMEMBER: JUST PRESS RETURN TO SKIP MAPPING A KEY.
-
-")
- (progn
- (insert "
- GENERATING A CUSTOM CONFIGURATION FILE FOR TERMINAL TYPE: ")
- (insert (format "%s." edt-term))
- (insert "
-
- PRESS THE KEY SPECIFIED IN THE MINIBUFFER BELOW.
-
- ________________________ _______________________________
- | HELP | DO | | F17 | F18 | F19 | F20 |
- |_______|________________| |_______|_______|_______|_______|
- ________________________ _______________________________
- | FIND |INSERT |REMOVE | | PF1 | PF2 | PF3 | PF4 |
- |_______|________|_______| |_______|_______|_______|_______|
- |SELECT |PREVIOUS| NEXT | | KP7 | KP8 | KP9 | KP- |
- |_______|________|_______| |_______|_______|_______|_______|
- | UP | | KP4 | KP5 | KP6 | KP, |
- _______|________|_______ |_______|_______|_______|_______|
- | LEFT | DOWN | RIGHT | | KP1 | KP2 | KP3 | |
- |_______|________|_______| |_______|_______|_______| KPE |
- | KP0 | KPP | |
- |_______________|_______|_______|
-
- REMEMBER: JUST PRESS RETURN TO SKIP MAPPING A KEY.")))
-
-
-
- (set-buffer "Keys")
- (insert "
-;;
-;; Arrows
-;;
-")
- (set-buffer "Directions")
-
- (edt-map-key "UP" " - The Up Arrow Key")
- (edt-map-key "DOWN" " - The Down Arrow Key")
- (edt-map-key "LEFT" " - The Left Arrow Key")
- (edt-map-key "RIGHT" " - The Right Arrow Key")
-
-
- (set-buffer "Keys")
- (insert "
-;;
-;; PF keys
-;;
-")
- (set-buffer "Directions")
-
- (edt-map-key "PF1" " - The PF1 (GOLD) Key")
- (edt-map-key "PF2" " - The Keypad PF2 Key")
- (edt-map-key "PF3" " - The Keypad PF3 Key")
- (edt-map-key "PF4" " - The Keypad PF4 Key")
-
- (set-buffer "Keys")
- (insert "
-;;
-;; KP0-9 KP- KP, KPP and KPE
-;;
-")
- (set-buffer "Directions")
-
- (edt-map-key "KP0" " - The Keypad 0 Key")
- (edt-map-key "KP1" " - The Keypad 1 Key")
- (edt-map-key "KP2" " - The Keypad 2 Key")
- (edt-map-key "KP3" " - The Keypad 3 Key")
- (edt-map-key "KP4" " - The Keypad 4 Key")
- (edt-map-key "KP5" " - The Keypad 5 Key")
- (edt-map-key "KP6" " - The Keypad 6 Key")
- (edt-map-key "KP7" " - The Keypad 7 Key")
- (edt-map-key "KP8" " - The Keypad 8 Key")
- (edt-map-key "KP9" " - The Keypad 9 Key")
- (edt-map-key "KP-" " - The Keypad - Key")
- (edt-map-key "KP," " - The Keypad , Key")
- (edt-map-key "KPP" " - The Keypad . Key")
- (edt-map-key "KPE" " - The Keypad Enter Key")
- ;; Save the enter key
- (setq edt-enter edt-key)
- (setq edt-enter-seq edt-key-seq)
-
-
- (set-buffer "Keys")
- (insert "
-;;
-;; Editing keypad (FIND, INSERT, REMOVE)
-;; (SELECT, PREVIOUS, NEXT)
-;;
-")
- (set-buffer "Directions")
-
- (edt-map-key "FIND" " - The Find key on the editing keypad")
- (edt-map-key "INSERT" " - The Insert key on the editing keypad")
- (edt-map-key "REMOVE" " - The Remove key on the editing keypad")
- (edt-map-key "SELECT" " - The Select key on the editing keypad")
- (edt-map-key "PREVIOUS" " - The Prev Scr key on the editing keypad")
- (edt-map-key "NEXT" " - The Next Scr key on the editing keypad")
-
- (set-buffer "Keys")
- (insert "
-;;
-;; F1-14 Help Do F17-F20
-;;
-")
- (set-buffer "Directions")
-
- (edt-map-key "F1" " - F1 Function Key")
- (edt-map-key "F2" " - F2 Function Key")
- (edt-map-key "F3" " - F3 Function Key")
- (edt-map-key "F4" " - F4 Function Key")
- (edt-map-key "F5" " - F5 Function Key")
- (edt-map-key "F6" " - F6 Function Key")
- (edt-map-key "F7" " - F7 Function Key")
- (edt-map-key "F8" " - F8 Function Key")
- (edt-map-key "F9" " - F9 Function Key")
- (edt-map-key "F10" " - F10 Function Key")
- (edt-map-key "F11" " - F11 Function Key")
- (edt-map-key "F12" " - F12 Function Key")
- (edt-map-key "F13" " - F13 Function Key")
- (edt-map-key "F14" " - F14 Function Key")
- (edt-map-key "HELP" " - HELP Function Key")
- (edt-map-key "DO" " - DO Function Key")
- (edt-map-key "F17" " - F17 Function Key")
- (edt-map-key "F18" " - F18 Function Key")
- (edt-map-key "F19" " - F19 Function Key")
- (edt-map-key "F20" " - F20 Function Key")
-
- (set-buffer "Directions")
- (delete-region (point-min) (point-max))
- (insert "
- ADDITIONAL FUNCTION KEYS
-
- Your keyboard may have additional function keys which do not correspond
- to any LK-201 keys. The EDT Emulation can be configured to recognize
- those keys, since you may wish to add your own key bindings to those keys.
-
- For example, suppose your keyboard has a keycap marked \"Line Del\" and
- you wish to add it to the list of keys which can be customized by the EDT
- Emulation. First, assign a unique single-word name to the key for use by
- the EDT Emulation, for example, \"linedel\". Then, at the \"EDT Key
- Name:\" prompt, enter \"linedel\", followed by a press of the RETURN key.
- Finally, when prompted, press the \"Line Del\" key. You now will be able
- to bind functions to \"linedel\" and \"Gold-linedel\" in edt-user.el in
- just the same way you can customize bindings of the LK-201 function and
- keypad keys.
-
- When you are done, just press RETURN at the \"EDT Key Name:\" prompt.
-")
- (switch-to-buffer "Directions")
- ;;
- ;; Add support for extras keys
- ;;
- (set-buffer "Keys")
- (insert "\
-;;
-;; Extra Keys
-;;
-")
- ;;
- ;; Restore function-key-map.
- ;;
- (if window-system
- (setq function-key-map edt-save-function-key-map))
- (setq EDT-key-name "")
- (while (not
- (string-equal (setq EDT-key-name (read-string "EDT Key Name: ")) ""))
- (edt-map-key EDT-key-name ""))
-
- ;;
- ;; No more keys to add, so wrap up.
- ;;
- (set-buffer "Keys")
- (insert "\
- )
- )
-")
-
- ;;
- ;; Save the key mapping program
- ;;
- ;;
- ;; Save the key mapping file
- ;;
- (let ((file (concat
- "~/.edt-gnu"
- (if edt-term (concat "-" edt-term))
- (if edt-xserver (concat "-" edt-xserver))
- (if window-system (concat "-" (upcase (symbol-name window-system))))
- "-keys")))
- (set-visited-file-name
- (read-file-name (format-prompt "Save key mapping to file" file)
- nil file)))
- (save-buffer)
-
- (message "That's it! Press any key to exit")
- (sit-for 600)
- (kill-emacs t))
-
-;;; edt-mapper.el ends here
+++ /dev/null
-;;; edt-pc.el --- enhanced EDT keypad mode emulation for PC 101 keyboards -*- lexical-binding: t -*-
-
-;; Copyright (C) 1986, 1994-1995, 2001-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Kevin Gallagher <kevin.gal@verizon.net>
-;; Keywords: emulations
-;; Package: edt
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; See Info node `edt' for more details.
-
-;; ====================================================================
-\f
-;;;;
-;;;; KEY TRANSLATIONS
-;;;;
-
-;; Associate EDT keynames with Emacs terminal function vector names.
-;;
-;; To emulate the DEC LK-201 keypad keys on the PC 101 keyboard,
-;; NumLock must be ON.
-;;
-;; The PC keypad keys are mapped to the corresponding DEC LK-201
-;; keypad keys according to the corresponding physical position on
-;; the keyboard. Thus, the physical position of the PC keypad key
-;; determines its function, not the PC keycap name.
-;;
-;; There are two LK-201 keypad keys needing special handling: PF1 and
-;; the keypad comma key.
-;;
-;; PF1:
-;; Most PC software does not see a press of the NumLock key. A TSR
-;; program distributed with MS-Kermit to support its VT-100 emulation
-;; solves this problem. The TSR, called GOLD, causes a press of the
-;; keypad NumLock key to look as if the PC F1 key were pressed. So
-;; the PC F1 key is mapped here to behave as the PF1 (GOLD) key.
-;; Then with GOLD loaded, the NumLock key will behave as the GOLD key.
-;;
-;; By the way, with GOLD loaded, you can still toggle numlock on/off.
-;; GOLD binds this to Shift-NumLock.
-;;
-;; Keypad Comma:
-;; There is no physical PC keypad key to correspond to the LK-201
-;; keypad comma key. So, the EDT Emulation is configured below to
-;; ignore attempts to bind functions to the keypad comma key.
-;;
-;; Finally, F2 through F12 are also available for making key bindings
-;; in the EDT Emulation on the PC. F1 is reserved for the GOLD key,
-;; so don't attempt to bind anything to it. Also, F13, F14, HELP, DO,
-;; and F17 through F20 do not exist on the PC, so the EDT emulation is
-;; configured below to ignore attempts to bind functions to those keys.
-;;
-
-;;; Code:
-
-(defconst *EDT-keys*
- '(("KP0" . [kp-0]) ("KP1" . [kp-1]) ("KP2" . [kp-2]) ("KP3" . [kp-3])
- ("KP4" . [kp-4]) ("KP5" . [kp-5]) ("KP6" . [kp-6]) ("KP7" . [kp-7])
- ("KP8" . [kp-8]) ("KP9" . [kp-9]) ("KP," . "" )
- ("KP-" . [kp-add]) ("KPP" . [kp-decimal]) ("KPE" . [kp-enter])
- ("PF1" . [f1]) ("PF2" . [kp-divide]) ("PF3" . [kp-multiply])
- ("PF4" . [kp-subtract])
- ("UP" . [up]) ("DOWN" . [down]) ("RIGHT" . [right]) ("LEFT" . [left])
- ("FIND" . [insert]) ("INSERT" . [home]) ("REMOVE" . [prior])
- ("SELECT" . [delete]) ("PREVIOUS" . [end]) ("NEXT" . [next])
- ("F1" . "" ) ("F2" . [f2]) ("F3" . [f3]) ("F4" . [f4]) ("F5" . [f5])
- ("F6" . [f6]) ("F7" . [f7]) ("F8" . [f8]) ("F9" . [f9]) ("F10" . [f10])
- ("F11" . [f11]) ("F12" . [f12]) ("F13" . "" ) ("F14" . "" )
- ("HELP" . "" ) ("DO" . "" ) ("F17" . "" ) ("F18" . "" )
- ("F19" . "" ) ("F20" . "" )))
-
-;;; edt-pc.el ends here
+++ /dev/null
-;;; edt-vt100.el --- enhanced EDT keypad mode emulation for VT series terminals -*- lexical-binding: t -*-
-
-;; Copyright (C) 1986, 1992-1993, 1995, 2002-2024 Free Software
-;; Foundation, Inc.
-
-;; Author: Kevin Gallagher <kevin.gal@verizon.net>
-;; Keywords: emulations
-;; Package: edt
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; See Info node `edt' for more details.
-
-;; ====================================================================
-\f
-
-;;; Code:
-
-;; Get keyboard function key mapping to EDT keys.
-(load "edt-lk201" nil t)
-
-;; The following functions are called by the EDT screen width commands defined
-;; in edt.el.
-
-(declare-function vt100-wide-mode "../term/vt100" (&optional arg))
-
-(defun edt-set-term-width-80 ()
- "Set terminal width to 80 columns."
- (vt100-wide-mode -1))
-
-(defun edt-set-term-width-132 ()
- "Set terminal width to 132 columns."
- (vt100-wide-mode 1))
-
-;;; edt-vt100.el ends here
+++ /dev/null
-;;; edt.el --- enhanced EDT keypad mode emulation for GNU Emacs -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1986, 1992-1995, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Kevin Gallagher <kevin.gal@verizon.net>
-;; Keywords: emulations
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-
-\f
-;;; Commentary:
-;;
-
-;; This is Version 4.0 of the EDT Emulation for Emacs.
-;; It comes with special functions which replicate nearly all of EDT's
-;; keypad mode behavior. It sets up default keypad and function key
-;; bindings which closely match those found in EDT. Support is
-;; provided so that users may reconfigure most keypad and function key
-;; bindings to their own liking.
-
-;; NOTE: Version 4.0 contains several enhancements. See the
-;; Enhancement section below for the details.
-
-;; Getting Started:
-
-;; To start the EDT Emulation, first start Emacs and then enter
-;;
-;; M-x edt-emulation-on
-;;
-;; to begin the emulation. After initialization is complete, the
-;; following message will appear below the status line informing you
-;; that the emulation has been enabled: "Default EDT keymap active".
-
-;; You can have the EDT Emulation start up automatically, each time
-;; you initiate a GNU Emacs session, by adding the following line to
-;; your init file:
-;;
-;; (add-hook 'emacs-startup-hook 'edt-emulation-on)
-
-;; IMPORTANT: Be sure to read the Info node `edt' for more details.
-;; It contains very helpful user information.
-
-;; The EDT emulation consists of the following files:
-;;
-;; edt.texi - User manual
-;; edt-user.el - Sample Customization File (located in Emacs
-;; distribution etc directory)
-;; edt.el - EDT Emulation Functions and Default Configuration
-;; edt-lk201.el - Built-in support for DEC LK-201 Keyboards
-;; edt-vt100.el - Built-in support for DEC VT-100 (and above) terminals
-;; edt-pc.el - Built-in support for PC 101 Keyboards under MS-DOS
-;; edt-mapper.el - Create an EDT LK-201 Map File for Keyboards Without
-;; Built-in Support
-
-;; Enhancements:
-
-;; Version 4.0 contains the following enhancements:
-
-;; 1. Scroll margins at the top and bottom of the window are now
-;; supported. (The design was copied from tpu-extras.el.) By
-;; default, this feature is enabled, with the top margin set to
-;; 10% of the window and the bottom margin set to 15% of the
-;; window. To change these settings, you can invoke the function
-;; edt-set-scroll-margins in your init file. For example, the
-;; following line
-;;
-;; (edt-set-scroll-margins "20%" "25%")
-;;
-;; sets the top margin to 20% of the window and the bottom margin
-;; to 25% of the window. To disable this feature, set each
-;; margin to 0%. You can also invoke edt-set-scroll-margins
-;; interactively while EDT Emulation is active to change the
-;; settings for that session.
-;;
-;; NOTE: Another way to set the scroll margins is to use the
-;; Emacs customization feature to set the following two variables
-;; directly:
-;;
-;; edt-top-scroll-margin and edt-bottom-scroll-margin
-;;
-;; Enter the Emacs `customize' command. First select the Editing
-;; group and then select the Emulations group. Finally, select
-;; the Edt group and follow the directions.
-;;
-;; 2. The SUBS command is now supported and bound to GOLD-Enter by
-;; default. (This design was copied from tpu-edt.el.) Note, in
-;; earlier versions of EDT Emulation, GOLD-Enter was assigned to
-;; the Emacs function `query-replace'. The binding of
-;; `query-replace' has been moved to GOLD-/. If you prefer to
-;; restore `query-replace' to GOLD-Enter, then use an EDT user
-;; customization file, edt-user.el, to do this.
-;; See Info node `edt' for more details.
-
-;; 3. If you access a workstation using an X Server, observe that
-;; the initialization file generated by edt-mapper.el will now
-;; contain the name of the X Server vendor. This is a
-;; convenience for those who have access to their Unix account
-;; from more than one type of X Server. Since different X
-;; Servers typically require different EDT emulation
-;; initialization files, edt-mapper.el will now generate these
-;; different initialization files and save them with different
-;; names. Then, the correct initialization file for the
-;; particular X server in use is loaded correctly automatically.
-
-;; 4. Also, edt-mapper.el is now capable of binding an ASCII key
-;; sequence, providing the ASCII key sequence prefix is already
-;; known by Emacs to be a prefix. As a result of providing this
-;; support, some terminal/keyboard/window system configurations,
-;; which don't have a complete set of sensible function key
-;; bindings built into Emacs in `function-key-map', can still be
-;; configured for use with EDT Emulation. (Note: In a few rare
-;; circumstances this does not work properly. In particular, it
-;; does not work if a subset of the leading ASCII characters in a
-;; key sequence are recognized by Emacs as having an existing
-;; binding. For example, if the keypad 7 (KP-7) key generates
-;; the sequence \"<ESC>Ow\" and \"<ESC>O\" is already bound to a
-;; function, pressing KP-7 when told to do so by edt-mapper.el
-;; will result in edt-mapper.el incorrectly mapping \"<ESC>O\" to
-;; KP-7 and \"w\" to KP-8. If something like this happens to
-;; you, it is probably a bug in the support for your keyboard
-;; within Emacs OR a bug in the Unix termcap/terminfo support for
-;; your terminal OR a bug in the terminal emulation software you
-;; are using.)
-
-;; 5. The edt-quit function (bound to GOLD-q by default) has been
-;; modified to warn the user when file-related buffer
-;; modifications exist. It now cautions the user that those
-;; modifications will be lost if the user quits without saving
-;; those buffers.
-
-
-;;; History:
-;;
-;; Version 4.0 2000 Added New Features and Fixed a Few Bugs
-;;
-
-\f
-;;; Code:
-
-;;; Electric Help functions are used for keypad help displays. A few
-;;; picture functions are used in rectangular cut and paste commands.
-
-(require 'ehelp)
-(require 'picture)
-
-;;;;
-;;;; VARIABLES and CONSTANTS
-;;;;
-
-(defgroup edt nil
- "Emacs emulating EDT."
- :prefix "edt-"
- :group 'emulations)
-
-;; To silence the byte-compiler
-(defvar *EDT-keys*)
-(defvar edt-default-global-map)
-(defvar edt-last-copied-word)
-(defvar edt-learn-macro-count)
-(defvar edt-orig-page-delimiter)
-(defvar edt-orig-transient-mark-mode)
-(defvar edt-rect-start-point)
-(defvar edt-user-global-map)
-(defvar rect-start-point)
-
-;;;
-;;; User Configurable Variables
-;;;
-
-(defcustom edt-keep-current-page-delimiter nil
- "Emacs MUST be restarted for a change in value to take effect!
-Non-nil leaves Emacs value of `page-delimiter' unchanged within EDT
-Emulation. If set to nil (the default), the `page-delimiter' variable
-is set to \"\\f\" when edt-emulation-on is first invoked. This
-setting replicates EDT's page delimiter behavior. The original value
-is restored when edt-emulation-off is called."
- :type 'boolean)
-
-(defcustom edt-use-EDT-control-key-bindings nil
- "Emacs MUST be restarted for a change in value to take effect!
-Non-nil causes the control key bindings to be replaced with EDT
-bindings. If set to nil (the default), EDT control key bindings are
-not used and the current Emacs control key bindings are retained for
-use within the EDT emulation."
- :type 'boolean)
-
-(defcustom edt-word-entities '(?\t)
- "Specifies the list of EDT word entity characters.
-The default list, (?\\t), contains just the TAB character, which
-emulates EDT. Characters are specified in the list using their
-decimal ASCII values. A question mark, followed by the actual
-character, can be used to indicate the numerical value of the
-character, instead of the actual decimal value. So, ?A means the
-numerical value for the letter A, ?/ means the numerical value for /,
-etc. Several unprintable and special characters have special
-representations, which you can also use:
-
- ?\\b specifies BS, C-h
- ?\\t specifies TAB, C-i
- ?\\n specifies LFD, C-j
- ?\\v specifies VTAB, C-k
- ?\\f specifies FF, C-l
- ?\\r specifies CR, C-m
- ?\\e specifies ESC, C-[
- ?\\\\ specifies \\
-
-In EDT Emulation movement-by-word commands, each character in the list
-will be treated as if it were a separate word."
- :type '(repeat integer))
-
-(defcustom edt-top-scroll-margin 10
- "Scroll margin at the top of the screen.
-Interpreted as a percent of the current window size with a default
-setting of 10%. If set to 0, top scroll margin is disabled."
- :type 'integer)
-
-(defcustom edt-bottom-scroll-margin 15
- "Scroll margin at the bottom of the screen.
-Interpreted as a percent of the current window size with a default
-setting of 15%. If set to 0, bottom scroll margin is disabled."
- :type 'integer)
-
-;;;
-;;; Internal Variables
-;;;
-
-(defvar edt-last-deleted-lines ""
- "Last text deleted by the EDT emulation DEL L command.")
-
-(defvar edt-last-deleted-words ""
- "Last text deleted by the EDT emulation DEL W command.")
-
-(defvar edt-last-deleted-chars ""
- "Last text deleted by the EDT emulation DEL C command.")
-
-(defvar edt-find-last-text ""
- "Last text found by the EDT emulation FIND command.")
-
-(defvar edt-match-beginning-mark (make-marker)
- "Used internally by the EDT emulation SUBS command.")
-
-(defvar edt-match-end-mark (make-marker)
- "Used internally by the EDT emulation SUBS command.")
-
-(defvar edt-last-replaced-key-definition nil
- "Key definition replaced with `edt-define-key' or `edt-learn' command.")
-
-(defvar edt-direction-string ""
- "String indicating current direction of movement.")
-
-(defvar edt-select-mode nil
- "Non-nil means select mode is active.")
-
-(defvar edt-select-mode-current ""
- "Text displayed in mode line to indicate the state of EDT select mode.
-When select mode is inactive, it is set to an empty string.")
-
-(defconst edt-select-mode-string " Select"
- "Used in mode line to indicate select mode is active.")
-
-(defconst edt-forward-string " ADVANCE"
- "Direction string in mode line to indicate forward movement.")
-
-(defconst edt-backward-string " BACKUP"
- "Direction string in mode line to indicate backward movement.")
-
-(defvar edt-default-map-active nil
- "Non-nil indicates that default EDT emulation key bindings are active.
-nil means user-defined custom bindings are active.")
-
-(defvar edt-user-map-configured nil
- "Non-nil indicates that user custom EDT key bindings are configured.
-This means that an edt-user.el file was found in the user's `load-path'.")
-
-(defvar edt-term nil
- "Specifies the terminal type, if applicable.")
-
-;;;
-;;; Emacs version identifiers - currently referenced by
-;;;
-;;; o edt-emulation-on o edt-load-keys
-;;;
-(defconst edt-xserver (when (eq window-system 'x)
- (declare-function x-server-vendor "xfns.c"
- (&optional terminal))
- ;; The Cygwin window manager has a `/' in its
- ;; name, which breaks the generated file name of
- ;; the custom key map file. Replace `/' with a
- ;; `-' to work around that.
- (replace-regexp-in-string "[ /]" "-"
- (x-server-vendor)))
- "Indicates X server vendor name, if applicable.")
-
-(defvar edt-keys-file nil
- "User's custom keypad and function keys mappings to emulate LK-201 keyboard.")
-
-(defvar edt-last-copied-word nil
- "Last word that the user copied.")
-
-\f
-;;;;
-;;;; EDT Emulation Commands
-;;;;
-
-;; Almost all of EDT's keypad mode commands have equivalent Emacs
-;; function counterparts. But many of these counterparts behave
-;; somewhat differently in Emacs.
-;;
-;; So, the following Emacs functions emulate, where practical, the
-;; exact behavior of the corresponding EDT keypad mode commands. In
-;; a few cases, the emulation is not exact, but it should be close
-;; enough for most EDT die-hards.
-;;
-
-;;;
-;;; PAGE
-;;;
-;; Emacs uses the regexp assigned to page-delimiter to determine what
-;; marks a page break. This is normally "^\f", which causes the
-;; edt-page command to ignore form feeds not located at the beginning
-;; of a line. To emulate the EDT PAGE command exactly,
-;; page-delimiter is set to "\f" when EDT emulation is turned on, and
-;; restored to its original value when EDT emulation is turned off.
-;; But this can be overridden if the EDT definition is not desired by
-;; placing
-;;
-;; (setq edt-keep-current-page-delimiter t)
-;;
-;; in your init file.
-
-(defun edt-page-forward (num)
- "Move forward to just after next page delimiter.
-Argument NUM is the number of page delimiters to move."
- (interactive "p")
- (edt-check-prefix num)
- (if (eobp)
- (error "End of buffer")
- (progn
- (forward-page num)
- (if (eobp)
- (edt-line-to-bottom-of-window)
- (edt-line-to-top-of-window)))))
-
-(defun edt-page-backward (num)
- "Move backward to just after previous page delimiter.
-Argument NUM is the number of page delimiters to move."
- (interactive "p")
- (edt-check-prefix num)
- (if (bobp)
- (error "Beginning of buffer")
- (progn
- (backward-page num)
- (edt-line-to-top-of-window))))
-
-(defun edt-page (num)
- "Move in current direction to next page delimiter.
-Argument NUM is the number of page delimiters to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-page-forward num)
- (edt-page-backward num)))
-
-;;;
-;;; SECT
-;;;
-;; EDT defaults a section size to be 16 lines of its one and only
-;; 24-line window. That's two-thirds of the window at a time. The
-;; EDT SECT commands moves the cursor, not the window.
-;;
-;; This emulation of EDT's SECT moves the cursor approximately
-;; two-thirds of the current window at a time.
-
-(defun edt-sect-forward (num)
- "Move cursor forward two-thirds of a window's number of lines.
-Argument NUM is the number of sections to move."
- (interactive "p")
- (edt-check-prefix num)
- (edt-line-forward (* (* (/ (- (window-height) 1) 3) 2) num)))
-
-
-(defun edt-sect-backward (num)
- "Move cursor backward two-thirds of a window.
-Argument NUM is the number of sections to move."
- (interactive "p")
- (edt-check-prefix num)
- (edt-line-backward (* (* (/ (- (window-height) 1) 3) 2) num)))
-
-(defun edt-sect (num)
- "Move in current direction a full window.
-Argument NUM is the number of sections to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-sect-forward num)
- (edt-sect-backward num)))
-
-;;;
-;;; BEGINNING OF LINE
-;;;
-;; EDT's beginning-of-line command is not affected by current
-;; direction, for some unknown reason.
-
-(defun edt-beginning-of-line (num)
- "Move backward to next beginning of line mark.
-Argument NUM is the number of BOL marks to move."
- (interactive "p")
- (edt-check-prefix num)
- (let ((beg (edt-current-line)))
- (if (bolp)
- (forward-line (* -1 num))
- (progn
- (setq num (1- num))
- (forward-line (* -1 num))))
- (edt-top-check beg num)))
-
-
-;;;
-;;; EOL (End of Line)
-;;;
-
-(defun edt-end-of-line-forward (num)
- "Move forward to next end of line mark.
-Argument NUM is the number of EOL marks to move."
- (interactive "p")
- (edt-check-prefix num)
- (let ((beg (edt-current-line)))
- (forward-char)
- (end-of-line num)
- (edt-bottom-check beg num)))
-
-
-(defun edt-end-of-line-backward (num)
- "Move backward to next end of line mark.
-Argument NUM is the number of EOL marks to move."
- (interactive "p")
- (edt-check-prefix num)
- (let ((beg (edt-current-line)))
- (end-of-line (1- num))
- (edt-top-check beg num)))
-
-
-(defun edt-end-of-line (num)
- "Move in current direction to next end of line mark.
-Argument NUM is the number of EOL marks to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-end-of-line-forward num)
- (edt-end-of-line-backward num)))
-
-;;;
-;;; WORD
-;;;
-;; This one is a tad messy. To emulate EDT's behavior everywhere in
-;; the file (beginning of file, end of file, beginning of line, end
-;; of line, etc.) it takes a bit of special handling.
-;;
-;; The variable edt-word-entities contains a list of characters which
-;; are to be viewed as distinct words wherever they appear in the
-;; buffer. This emulates the EDT line mode command SET ENTITY WORD.
-
-
-(defun edt-one-word-forward ()
- "Move forward to first character of next word."
- (interactive)
- (if (eobp)
- (error "End of buffer"))
- (if (eolp)
- (forward-char)
- (progn
- (if (memq (following-char) edt-word-entities)
- (forward-char)
- (while (and
- (not (eolp))
- (not (eobp))
- (not (eq ?\ (char-syntax (following-char))))
- (not (memq (following-char) edt-word-entities)))
- (forward-char)))
- (while (and
- (not (eolp))
- (not (eobp))
- (eq ?\ (char-syntax (following-char)))
- (not (memq (following-char) edt-word-entities)))
- (forward-char)))))
-
-(defun edt-one-word-backward ()
- "Move backward to first character of previous word."
- (interactive)
- (if (bobp)
- (error "Beginning of buffer"))
- (if (bolp)
- (backward-char)
- (progn
- (backward-char)
- (while (and
- (not (bolp))
- (not (bobp))
- (eq ?\ (char-syntax (following-char)))
- (not (memq (following-char) edt-word-entities)))
- (backward-char))
- (if (not (memq (following-char) edt-word-entities))
- (while (and
- (not (bolp))
- (not (bobp))
- (not (eq ?\ (char-syntax (preceding-char))))
- (not (memq (preceding-char) edt-word-entities)))
- (backward-char))))))
-
-(defun edt-word-forward (num)
- "Move forward to first character of next word.
-Argument NUM is the number of words to move."
- (interactive "p")
- (edt-check-prefix num)
- (while (> num 0)
- (edt-one-word-forward)
- (setq num (1- num))))
-
-(defun edt-word-backward (num)
- "Move backward to first character of previous word.
-Argument NUM is the number of words to move."
- (interactive "p")
- (edt-check-prefix num)
- (while (> num 0)
- (edt-one-word-backward)
- (setq num (1- num))))
-
-(defun edt-word (num)
- "Move in current direction to first character of next word.
-Argument NUM is the number of words to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-word-forward num)
- (edt-word-backward num)))
-
-;;;
-;;; CHAR
-;;;
-
-(defun edt-character (num)
- "Move in current direction to next character.
-Argument NUM is the number of characters to move."
- (interactive "p")
- (edt-check-prefix num)
- (if (equal edt-direction-string edt-forward-string)
- (forward-char num)
- (backward-char num)))
-
-;;;
-;;; LINE
-;;;
-;; When direction is set to BACKUP, LINE behaves just like BEGINNING
-;; OF LINE in EDT. So edt-line-backward is not really needed as a
-;; separate function.
-
-(defun edt-line-backward (num)
- "Move backward to next beginning of line mark.
-Argument NUM is the number of BOL marks to move."
- (interactive "p")
- (edt-beginning-of-line num))
-
-(defun edt-line-forward (num)
- "Move forward to next beginning of line mark.
-Argument NUM is the number of BOL marks to move."
- (interactive "p")
- (edt-check-prefix num)
- (let ((beg (edt-current-line)))
- (forward-line num)
- (edt-bottom-check beg num)))
-
-(defun edt-line (num)
- "Move in current direction to next beginning of line mark.
-Argument NUM is the number of BOL marks to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-line-forward num)
- (edt-line-backward num)))
-
-;;;
-;;; UP and DOWN Arrows
-;;;
-
-(defun edt-next-line (num)
- "Move cursor down one line.
-Argument NUM is the number of lines to move."
- (interactive "p")
- (edt-check-prefix num)
- (let ((beg (edt-current-line)))
- ;; We're deliberately using next-line instead of forward-line.
- (with-no-warnings (next-line num))
- (edt-bottom-check beg num)))
-
-(defun edt-previous-line (num)
- "Move cursor up one line.
-Argument NUM is the number of lines to move."
- (interactive "p")
- (edt-check-prefix num)
- (let ((beg (edt-current-line)))
- ;; We're deliberately using previous-line instead of forward-line.
- (with-no-warnings (previous-line num))
- (edt-top-check beg num)))
-
-
-;;;
-;;; TOP
-;;;
-
-(defun edt-top ()
- "Move cursor to the beginning of buffer."
- (interactive)
- (goto-char (point-min)))
-
-;;;
-;;; BOTTOM
-;;;
-
-(defun edt-bottom ()
- "Move cursor to the end of buffer."
- (interactive)
- (goto-char (point-max))
- (edt-line-to-bottom-of-window))
-
-(defmacro edt-with-position (&rest body)
- "Execute BODY with some position-related variables bound."
- `(let* ((beg (edt-current-line))
- (height (window-height))
- (top-percent
- (if (zerop edt-top-scroll-margin) 10 edt-top-scroll-margin))
- (bottom-percent
- (if (zerop edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
- (top-margin (/ (* height top-percent) 100))
- (bottom-up-margin (1+ (/ (* height bottom-percent) 100)))
- (bottom-margin (max beg (- height bottom-up-margin 1)))
- (top (save-excursion (move-to-window-line top-margin) (point)))
- (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
- (far (save-excursion
- (goto-char bottom)
- (line-beginning-position (1- height)))))
- (ignore top far)
- ,@body))
-
-;;;
-;;; FIND
-;;;
-
-(defun edt-find-forward (&optional find)
- "Find first occurrence of a string in forward direction and save it.
-Optional argument FIND is t is this function is called from `edt-find'."
- (interactive)
- (or find
- (setq edt-find-last-text (read-string "Search forward: ")))
- (edt-with-position
- (when (search-forward edt-find-last-text) ; FIXME noerror?
- (search-backward edt-find-last-text)
- (edt-set-match)
- (if (> (point) far)
- (let ((left (save-excursion (forward-line height))))
- (recenter (if (zerop left)
- top-margin
- (- left bottom-up-margin))))
- (and (> (point) bottom) (recenter bottom-margin))))))
-
-(defun edt-find-backward (&optional find)
- "Find first occurrence of a string in the backward direction and save it.
-Optional argument FIND is t if this function is called from `edt-find'."
- (interactive)
- (or find
- (setq edt-find-last-text (read-string "Search backward: ")))
- (edt-with-position
- (if (search-backward edt-find-last-text)
- (edt-set-match))
- (and (< (point) top) (recenter (min beg top-margin)))))
-
-(defun edt-find ()
- "Find first occurrence of string in current direction and save it."
- (interactive)
- (setq edt-find-last-text (read-string "Search: "))
- (if (equal edt-direction-string edt-forward-string)
- (edt-find-forward t)
- (edt-find-backward t)))
-
-
-;;;
-;;; FNDNXT
-;;;
-
-(defun edt-find-next-forward ()
- "Find next occurrence of a string in forward direction."
- (interactive)
- (edt-with-position
- (forward-char 1)
- (if (search-forward edt-find-last-text nil t)
- (progn
- (search-backward edt-find-last-text)
- (edt-set-match)
- (if (> (point) far)
- (let ((left (save-excursion (forward-line height))))
- (recenter (if (zerop left) top-margin
- (- left bottom-up-margin))))
- (and (> (point) bottom) (recenter bottom-margin))))
- (backward-char 1)
- (error "Search failed: \"%s\"" edt-find-last-text))))
-
-(defun edt-find-next-backward ()
- "Find next occurrence of a string in backward direction."
- (interactive)
- (edt-with-position
- (if (not (search-backward edt-find-last-text nil t))
- (error "Search failed: \"%s\"" edt-find-last-text)
- (edt-set-match)
- (and (< (point) top) (recenter (min beg top-margin))))))
-
-(defun edt-find-next ()
- "Find next occurrence of a string in current direction."
- (interactive)
- (if (equal edt-direction-string edt-forward-string)
- (edt-find-next-forward)
- (edt-find-next-backward)))
-
-;;;
-;;; APPEND
-;;;
-
-(defun edt-append ()
- "Append this kill region to last killed region."
- (interactive "*")
- (edt-check-selection)
- (append-next-kill)
- (kill-region (mark) (point))
- (message "Selected text APPENDED to kill ring"))
-
-;;;
-;;; DEL L
-;;;
-
-(defun edt-delete-line (num)
- "Delete from cursor up to and including the end of line mark.
-Argument NUM is the number of lines to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (let ((beg (point)))
- (forward-line num)
- (if (not (eq (preceding-char) ?\n))
- (insert "\n"))
- (setq edt-last-deleted-lines
- (buffer-substring beg (point)))
- (delete-region beg (point))))
-
-;;;
-;;; DEL EOL
-;;;
-
-(defun edt-delete-to-end-of-line (num)
- "Delete from cursor up to but excluding the end of line mark.
-Argument NUM is the number of lines to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (let ((beg (point)))
- (forward-char 1)
- (end-of-line num)
- (setq edt-last-deleted-lines
- (buffer-substring beg (point)))
- (delete-region beg (point))))
-
-;;;
-;;; SELECT
-;;;
-
-(defun edt-select-mode (arg)
- "Turn EDT select mode off if ARG is nil; otherwise, turn EDT select mode on.
-In select mode, selected text is highlighted."
- (if arg
- (progn
- (setq-local edt-select-mode 'edt-select-mode-current)
- (setq rect-start-point (window-point)))
- (progn
- (kill-local-variable 'edt-select-mode)))
- (force-mode-line-update))
-
-(defun edt-select ()
- "Set mark at cursor and start text selection."
- (interactive)
- (set-mark-command nil))
-
-(defun edt-reset ()
- "Cancel text selection."
- (interactive)
- (deactivate-mark))
-
-;;;
-;;; CUT
-;;;
-
-(defun edt-cut ()
- "Deletes selected text but copies to kill ring."
- (interactive "*")
- (edt-check-selection)
- (kill-region (mark) (point))
- (message "Selected text CUT to kill ring"))
-
-;;;
-;;; DELETE TO BEGINNING OF LINE
-;;;
-
-(defun edt-delete-to-beginning-of-line (num)
- "Delete from cursor to beginning of line.
-Argument NUM is the number of lines to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (let ((beg (point)))
- (edt-beginning-of-line num)
- (setq edt-last-deleted-lines
- (buffer-substring (point) beg))
- (delete-region beg (point))))
-
-;;;
-;;; DEL W
-;;;
-
-(defun edt-delete-word (num)
- "Delete from cursor up to but excluding first character of next word.
-Argument NUM is the number of words to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (let ((beg (point)))
- (edt-word-forward num)
- (setq edt-last-deleted-words (buffer-substring beg (point)))
- (delete-region beg (point))))
-
-;;;
-;;; DELETE TO BEGINNING OF WORD
-;;;
-
-(defun edt-delete-to-beginning-of-word (num)
- "Delete from cursor to beginning of word.
-Argument NUM is the number of words to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (let ((beg (point)))
- (edt-word-backward num)
- (setq edt-last-deleted-words (buffer-substring (point) beg))
- (delete-region beg (point))))
-
-;;;
-;;; DEL C
-;;;
-
-(defun edt-delete-character (num)
- "Delete character under cursor.
-Argument NUM is the number of characters to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (setq edt-last-deleted-chars
- (buffer-substring (point) (min (point-max) (+ (point) num))))
- (delete-region (point) (min (point-max) (+ (point) num))))
-
-;;;
-;;; DELETE CHAR
-;;;
-
-(defun edt-delete-previous-character (num)
- "Delete character in front of cursor.
-Argument NUM is the number of characters to delete."
- (interactive "*p")
- (edt-check-prefix num)
- (setq edt-last-deleted-chars
- (buffer-substring (max (point-min) (- (point) num)) (point)))
- (delete-region (max (point-min) (- (point) num)) (point)))
-
-;;;
-;;; UND L
-;;;
-
-(defun edt-undelete-line ()
- "Undelete previous deleted line(s)."
- (interactive "*")
- (point-to-register 1)
- (insert edt-last-deleted-lines)
- (register-to-point 1))
-
-;;;
-;;; UND W
-;;;
-
-(defun edt-undelete-word ()
- "Undelete previous deleted word(s)."
- (interactive "*")
- (point-to-register 1)
- (insert edt-last-deleted-words)
- (register-to-point 1))
-
-;;;
-;;; UND C
-;;;
-
-(defun edt-undelete-character ()
- "Undelete previous deleted character(s)."
- (interactive "*")
- (point-to-register 1)
- (insert edt-last-deleted-chars)
- (register-to-point 1))
-
-;;;
-;;; REPLACE
-;;;
-
-(defun edt-replace ()
- "Replace marked section with last CUT (killed) text."
- (interactive "*")
- (if (edt-check-match)
- (replace-match (car kill-ring-yank-pointer))
- (progn
- (exchange-point-and-mark)
- (let ((beg (point)))
- (exchange-point-and-mark)
- (delete-region beg (point)))
- (yank))))
-
-;;;
-;;; SUBS
-;;;
-
-(defun edt-substitute (num)
- "Replace the selected region with the contents of the CUT buffer and.
-Repeat the most recent FIND command. (The Emacs kill ring is used as
-the CUT buffer.)
-Argument NUM is the repeat count. A positive value indicates the of times
-to repeat the substitution. A negative argument means replace all occurrences
-of the search text."
- (interactive "p")
- (cond ((or edt-select-mode (edt-check-match))
- (while (and (not (= num 0)) (or edt-select-mode (edt-check-match)))
- (edt-replace)
- (edt-find-next)
- (setq num (1- num))))
- (t
- (error "No selection active"))))
-
-(defun edt-set-match nil
- "Set markers at match beginning and end."
- ;; Add one to beginning mark so it stays with the first character of
- ;; the string even if characters are added just before the string.
- (setq edt-match-beginning-mark (copy-marker (1+ (match-beginning 0))))
- (setq edt-match-end-mark (copy-marker (match-end 0))))
-
-(defun edt-unset-match nil
- "Unset match beginning and end markers."
- (set-marker edt-match-beginning-mark nil)
- (set-marker edt-match-end-mark nil))
-
-(defun edt-match-beginning nil
- "Return the location of the last match beginning."
- (1- (marker-position edt-match-beginning-mark)))
-
-(defun edt-match-end nil
- "Return the location of the last match end."
- (marker-position edt-match-end-mark))
-
-(defun edt-check-match nil
- "Return t if point is between edt-match markers.
-Otherwise sets the edt-match markers to nil and returns nil."
- ;; make sure 1- marker is in this buffer
- ;; 2- point is at or after beginning marker
- ;; 3- point is before ending marker, or in the case of
- ;; zero length regions (like bol, or eol) that the
- ;; beginning, end, and point are equal.
- (cond ((and
- (equal (marker-buffer edt-match-beginning-mark) (current-buffer))
- (>= (point) (1- (marker-position edt-match-beginning-mark)))
- (or
- (< (point) (marker-position edt-match-end-mark))
- (and (= (1- (marker-position edt-match-beginning-mark))
- (marker-position edt-match-end-mark))
- (= (marker-position edt-match-end-mark) (point))))) t)
- (t
- (edt-unset-match) nil)))
-
-(defun edt-show-match-markers nil
- "Show the values of the match markers."
- (interactive)
- (if (markerp edt-match-beginning-mark)
- (let ((beg (marker-position edt-match-beginning-mark)))
- (message "(%s, %s) in %s -- current %s in %s"
- (if beg (1- beg) nil)
- (marker-position edt-match-end-mark)
- (marker-buffer edt-match-end-mark)
- (point) (current-buffer)))))
-
-
-;;;
-;;; ADVANCE
-;;;
-
-(defun edt-advance ()
- "Set movement direction forward.
-Also, execute command specified if in Minibuffer."
- (interactive)
- (setq edt-direction-string edt-forward-string)
- (force-mode-line-update)
- (if (string-equal " *Minibuf"
- (substring (buffer-name) 0 (min (length (buffer-name)) 9)))
- (exit-minibuffer)))
-
-
-;;;
-;;; BACKUP
-;;;
-
-(defun edt-backup ()
- "Set movement direction backward.
-Also, execute command specified if in Minibuffer."
- (interactive)
- (setq edt-direction-string edt-backward-string)
- (force-mode-line-update)
- (if (string-equal " *Minibuf"
- (substring (buffer-name) 0 (min (length (buffer-name)) 9)))
- (exit-minibuffer)))
-
-
-;;;
-;;; CHNGCASE
-;;;
-;; This function is based upon Jeff Kowalski's case-flip function in his
-;; tpu.el.
-
-(defun edt-change-case (num)
- "Change the case of specified characters.
-If text selection IS active, then characters between the cursor and mark are
-changed. If text selection is NOT active, there are two cases. First, if the
-current direction is ADVANCE, then the prefix number of character(s) under and
-following cursor are changed. Second, if the current direction is BACKUP, then
-the prefix number of character(s) before the cursor are changed. Accepts a
-positive prefix for the number of characters to change, but the prefix is
-ignored if text selection is active.
-Argument NUM is the numbers of consecutive characters to change."
- (interactive "*p")
- (edt-check-prefix num)
- (if edt-select-mode
- (let ((end (max (mark) (point)))
- (point-save (point)))
- (goto-char (min (point) (mark)))
- (while (not (eq (point) end))
- (funcall (if (<= ?a (following-char))
- 'upcase-region 'downcase-region)
- (point) (1+ (point)))
- (forward-char 1))
- (goto-char point-save))
- (progn
- (if (string= edt-direction-string edt-backward-string)
- (backward-char num))
- (while (> num 0)
- (funcall (if (<= ?a (following-char))
- 'upcase-region 'downcase-region)
- (point) (1+ (point)))
- (forward-char 1)
- (setq num (1- num))))))
-
-;;;
-;;; DEFINE KEY
-;;;
-
-(defun edt-define-key ()
- "Assign an interactively-callable function to a specified key sequence.
-The current key definition is saved in `edt-last-replaced-key-definition'.
-Use `edt-restore-key' to restore last replaced key definition."
- (interactive)
- (let (edt-function
- edt-key-definition)
- (setq edt-key-definition
- (read-key-sequence "Press the key to be defined: "))
- (if (string-equal "\C-m" edt-key-definition)
- (message "Key not defined")
- (progn
- (setq edt-function (read-command "Enter command name: "))
- (if (string-equal "" edt-function)
- (message "Key not defined")
- (progn
- (setq edt-last-replaced-key-definition
- (lookup-key (current-global-map) edt-key-definition))
- (define-key (current-global-map)
- edt-key-definition edt-function)))))))
-
-;;;
-;;; FORM FEED INSERT
-;;;
-
-(defun edt-form-feed-insert (num)
- "Insert form feed character at cursor position.
-Argument NUM is the number of form feeds to insert."
- (interactive "*p")
- (edt-check-prefix num)
- (while (> num 0)
- (insert ?\f)
- (setq num (1- num))))
-
-;;;
-;;; TAB INSERT
-;;;
-
-(defun edt-tab-insert (num)
- "Insert tab character at cursor position.
-Argument NUM is the number of tabs to insert."
- (interactive "*p")
- (edt-check-prefix num)
- (while (> num 0)
- (insert ?\t)
- (setq num (1- num))))
-
-;;;
-;;; Check Prefix
-;;;
-
-(defun edt-check-prefix (num)
- "Indicate error if prefix is not positive.
-Argument NUM is the prefix value tested."
- (if (<= num 0)
- (error "Prefix must be positive")))
-
-;;;
-;;; Check Selection
-;;;
-
-(defun edt-check-selection ()
- "Indicate error if EDT selection is not active."
- (if (not edt-select-mode)
- (error "Selection NOT active")))
-
-;;;
-;;; Scroll Margins
-;;;
-
-(defun edt-top-check (beg lines)
- "Enforce scroll margin at the top of screen.
-Argument BEG is the starting line number before cursor was moved.
-Argument LINES is the number of lines the cursor moved toward the top."
- (let ((margin (/ (* (window-height) edt-top-scroll-margin) 100)))
- (cond ((< beg margin) (recenter beg))
- ((< (- beg lines) margin) (recenter margin)))))
-
-(defun edt-bottom-check (beg lines)
- "Enforce scroll margin at the bottom of screen.
-Argument BEG is the starting line number before cursor was moved.
-Argument LINES is the number of lines the cursor moved toward the bottom."
- (let* ((height (window-height))
- (margin (+ 1 (/ (* height edt-bottom-scroll-margin) 100)))
- ;; subtract 1 from height because it includes mode line
- (difference (- height margin 1)))
- (cond ((> beg difference) (recenter beg))
- ((> (+ beg lines) difference) (recenter (- margin))))))
-
-(defun edt-current-line nil
- "Return the vertical position of point in the selected window.
-Top line is 0. Counts each text line only once, even if it wraps."
- (+ (count-lines (window-start) (point)) (if (= (current-column) 0) 1 0) -1))
-
-;;;###autoload
-(defun edt-set-scroll-margins (top bottom)
- "Set scroll margins.
-Argument TOP is the top margin in number of lines or percent of window.
-Argument BOTTOM is the bottom margin in number of lines or percent of window."
- (interactive
- "sEnter top scroll margin (N lines or N%% or RETURN for current value): \
-\nsEnter bottom scroll margin (N lines or N%% or RETURN for current value): ")
- ;; set top scroll margin
- (or (string= top "")
- (if (string= "%" (substring top -1))
- (setq edt-top-scroll-margin (string-to-number top))
- (setq edt-top-scroll-margin
- (/ (1- (+ (* (string-to-number top) 100) (window-height)))
- (window-height)))))
- ;; set bottom scroll margin
- (or (string= bottom "")
- (if (string= "%" (substring bottom -1))
- (setq edt-bottom-scroll-margin (string-to-number bottom))
- (setq edt-bottom-scroll-margin
- (/ (1- (+ (* (string-to-number bottom) 100) (window-height)))
- (window-height)))))
- ;; report scroll margin settings if running interactively
- (and (called-interactively-p 'interactive)
- (message "Scroll margins set. Top = %s%%, Bottom = %s%%"
- edt-top-scroll-margin edt-bottom-scroll-margin)))
-
-\f
-;;;;
-;;;; ENHANCEMENTS AND ADDITIONS FOR EDT KEYPAD MODE
-;;;;
-
-;;;
-;; Several enhancements and additions to EDT keypad mode commands are
-;; provided here. Some of these have been motivated by similar
-;; TPU/EVE and EVE-Plus commands. Others are new.
-
-;;;
-;;; CHANGE DIRECTION
-;;;
-
-(defun edt-change-direction ()
- "Toggle movement direction."
- (interactive)
- (if (equal edt-direction-string edt-forward-string)
- (edt-backup)
- (edt-advance)))
-
-;;;
-;;; TOGGLE SELECT
-;;;
-
-(defun edt-toggle-select ()
- "Toggle to start (or cancel) text selection."
- (interactive)
- (if edt-select-mode
- (edt-reset)
- (edt-select)))
-
-;;;
-;;; SENTENCE
-;;;
-
-(defun edt-sentence-forward (num)
- "Move forward to start of next sentence.
-Argument NUM is the positive number of sentences to move."
- (interactive "p")
- (edt-check-prefix num)
- (edt-with-position
- (if (eobp)
- (error "End of buffer")
- (forward-sentence num)
- (forward-word 1)
- (backward-sentence))
- (if (> (point) far)
- (let ((left (save-excursion (forward-line height))))
- (recenter (if (zerop left) top-margin (- left bottom-up-margin))))
- (and (> (point) bottom) (recenter bottom-margin)))))
-
-(defun edt-sentence-backward (num)
- "Move backward to next sentence beginning.
-Argument NUM is the positive number of sentences to move."
- (interactive "p")
- (edt-check-prefix num)
- (edt-with-position
- (if (eobp)
- (error "End of buffer")
- (backward-sentence num))
- (and (< (point) top) (recenter (min beg top-margin)))))
-
-(defun edt-sentence (num)
- "Move in current direction to next sentence.
-Argument NUM is the positive number of sentences to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-sentence-forward num)
- (edt-sentence-backward num)))
-
-;;;
-;;; PARAGRAPH
-;;;
-
-(defun edt-paragraph-forward (num)
- "Move forward to beginning of paragraph.
-Argument NUM is the positive number of paragraphs to move."
- (interactive "p")
- (edt-check-prefix num)
- (edt-with-position
- (while (> num 0)
- (forward-paragraph (+ num 1))
- (start-of-paragraph-text)
- (if (eolp)
- (forward-line 1))
- (setq num (1- num)))
- (if (> (point) far)
- (let ((left (save-excursion (forward-line height))))
- (recenter (if (zerop left) top-margin (- left bottom-up-margin))))
- (and (> (point) bottom) (recenter bottom-margin)))))
-
-(defun edt-paragraph-backward (num)
- "Move backward to beginning of paragraph.
-Argument NUM is the positive number of paragraphs to move."
- (interactive "p")
- (edt-check-prefix num)
- (edt-with-position
- (while (> num 0)
- (start-of-paragraph-text)
- (setq num (1- num)))
- (and (< (point) top) (recenter (min beg top-margin)))))
-
-(defun edt-paragraph (num)
- "Move in current direction to next paragraph.
-Argument NUM is the positive number of paragraphs to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-paragraph-forward num)
- (edt-paragraph-backward num)))
-
-;;;
-;;; RESTORE KEY
-;;;
-
-(defun edt-restore-key ()
- "Restore last replaced key definition.
-Definition is stored in `edt-last-replaced-key-definition'."
- (interactive)
- (if edt-last-replaced-key-definition
- (progn
- (let (edt-key-definition)
- (setq edt-key-definition
- (read-key-sequence "Press the key to be restored: "))
- (if (string-equal "\C-m" edt-key-definition)
- (message "Key not restored")
- (progn
- (define-key (current-global-map)
- edt-key-definition edt-last-replaced-key-definition)
- (message "Key definition for %s has been restored."
- edt-key-definition)))))
- (error "No replaced key definition to restore!")))
-
-;;;
-;;; WINDOW TOP
-;;;
-
-(defun edt-window-top ()
- "Move the cursor to the top of the window."
- (interactive)
- (let ((start-column (current-column)))
- (move-to-window-line 0)
- (move-to-column start-column)))
-
-;;;
-;;; WINDOW BOTTOM
-;;;
-
-(defun edt-window-bottom ()
- "Move the cursor to the bottom of the window."
- (interactive)
- (let ((start-column (current-column)))
- (move-to-window-line (- (window-height) 2))
- (move-to-column start-column)))
-
-;;;
-;;; SCROLL WINDOW LINE
-;;;
-
-(defun edt-scroll-window-forward-line ()
- "Move window forward one line leaving cursor at position in window."
- (interactive)
- (scroll-up 1))
-
-(defun edt-scroll-window-backward-line ()
- "Move window backward one line leaving cursor at position in window."
- (interactive)
- (scroll-down 1))
-
-(defun edt-scroll-line ()
- "Move window one line in current direction."
- (interactive)
- (if (equal edt-direction-string edt-forward-string)
- (edt-scroll-window-forward-line)
- (edt-scroll-window-backward-line)))
-
-;;;
-;;; SCROLL WINDOW
-;;;
-;; Scroll a window (less one line) at a time. Leave cursor in center of
-;; window.
-
-(defun edt-scroll-window-forward (num)
- "Scroll forward one window in buffer, less one line.
-Argument NUM is the positive number of windows to move."
- (interactive "p")
- (edt-check-prefix num)
- (scroll-up (- (* (window-height) num) 2))
- (edt-line-forward (/ (- (window-height) 1) 2)))
-
-(defun edt-scroll-window-backward (num)
- "Scroll backward one window in buffer, less one line.
-Argument NUM is the positive number of windows to move."
- (interactive "p")
- (edt-check-prefix num)
- (scroll-down (- (* (window-height) num) 2))
- (edt-line-backward (/ (- (window-height) 1) 2)))
-
-(defun edt-scroll-window (num)
- "Scroll one window in buffer, less one line, in current direction.
-Argument NUM is the positive number of windows to move."
- (interactive "p")
- (if (equal edt-direction-string edt-forward-string)
- (edt-scroll-window-forward num)
- (edt-scroll-window-backward num)))
-
-;;;
-;;; LINE TO BOTTOM OF WINDOW
-;;;
-
-(defun edt-line-to-bottom-of-window ()
- "Move the current line to the bottom of the window."
- (interactive)
- (recenter -1))
-
-;;;
-;;; LINE TO TOP OF WINDOW
-;;;
-
-(defun edt-line-to-top-of-window ()
- "Move the current line to the top of the window."
- (interactive)
- (recenter 0))
-
-;;;
-;;; LINE TO MIDDLE OF WINDOW
-;;;
-
-(defun edt-line-to-middle-of-window ()
- "Move window so line with cursor is in the middle of the window."
- (interactive)
- (recenter '(4)))
-
-;;;
-;;; GOTO PERCENTAGE
-;;;
-
-(defun edt-goto-percentage (num)
- "Move to specified percentage in buffer from top of buffer.
-Argument NUM is the percentage into the buffer to move."
- (interactive "NGoto-percentage: ")
- (if (or (> num 100) (< num 0))
- (error "Percentage %d out of range 0 < percent < 100" num)
- (goto-char (/ (* (point-max) num) 100))))
-
-;;;
-;;; FILL REGION
-;;;
-
-(defun edt-fill-region ()
- "Fill selected text."
- (interactive "*")
- (edt-check-selection)
- (fill-region (point) (mark)))
-
-;;;
-;;; INDENT OR FILL REGION
-;;;
-
-(defun edt-indent-or-fill-region ()
- "Fill region in text modes, indent region in programming language modes."
- (interactive "*")
- (if (string= paragraph-start "$\\|\f")
- (indent-region (point) (mark) nil)
- (fill-region (point) (mark))))
-
-
-(declare-function c-mark-function "cc-cmds" ())
-;;;
-;;; MARK SECTION WISELY
-;;;
-
-(defun edt-mark-section-wisely ()
- "Mark the section in a manner consistent with the `major-mode'.
-Uses `mark-defun' for Emacs-Lisp and Lisp, and for Fortran,
-`c-mark-function' for C,
-and `mark-paragraph' for other modes."
- (interactive)
- (if edt-select-mode
- (progn
- (edt-reset))
- (progn
- (cond ((or (eq major-mode 'emacs-lisp-mode)
- (eq major-mode 'fortran-mode)
- (eq major-mode 'lisp-mode))
- (mark-defun)
- (message "Lisp defun selected"))
- ((eq major-mode 'c-mode)
- (c-mark-function)
- (message "C function selected"))
- (t (mark-paragraph)
- (message "Paragraph selected"))))))
-
-;;;
-;;; COPY
-;;;
-
-(defun edt-copy ()
- "Copy selected region to kill ring, but don't delete it!"
- (interactive)
- (edt-check-selection)
- (copy-region-as-kill (mark) (point))
- (edt-reset)
- (message "Selected text COPIED to kill ring"))
-
-;;;
-;;; CUT or COPY
-;;;
-
-(defun edt-cut-or-copy ()
- "Cuts (or copies) selected text to kill ring.
-Cuts selected text if `buffer-read-only' is nil.
-Copies selected text if `buffer-read-only' is t."
- (interactive)
- (if buffer-read-only
- (edt-copy)
- (edt-cut)))
-
-;;;
-;;; DELETE ENTIRE LINE
-;;;
-
-(defun edt-delete-entire-line ()
- "Delete entire line regardless of cursor position in the line."
- (interactive "*")
- (beginning-of-line)
- (edt-delete-line 1))
-
-;;;
-;;; DUPLICATE LINE
-;;;
-
-(defun edt-duplicate-line (num)
- "Duplicate the line of text containing the cursor.
-Argument NUM is the number of times to duplicate the line."
- (interactive "*p")
- (edt-check-prefix num)
- (let ((old-column (current-column))
- (count num))
- (edt-delete-entire-line)
- (edt-undelete-line)
- (while (> count 0)
- (edt-undelete-line)
- (setq count (1- count)))
- (edt-line-forward num)
- (move-to-column old-column)))
-
-;;;
-;;; DUPLICATE WORD
-;;;
-
-(defun edt-duplicate-word()
- "Duplicate word (or rest of word) found directly above cursor, if any."
- (interactive "*")
- (let ((start (point))
- (start-column (current-column)))
- (forward-line -1)
- (move-to-column start-column)
- (if (and (not (equal start (point)))
- (not (eolp)))
- (progn
- (if (and (equal ?\t (preceding-char))
- (< start-column (current-column)))
- (backward-char))
- (let ((beg (point)))
- (edt-one-word-forward)
- (setq edt-last-copied-word (buffer-substring beg (point))))
- (forward-line)
- (move-to-column start-column)
- (insert edt-last-copied-word))
- (progn
- (if (not (equal start (point)))
- (forward-line))
- (move-to-column start-column)
- (error "Nothing to duplicate!")))))
-
-;;;
-;;; KEY NOT ASSIGNED
-;;;
-
-(defun edt-key-not-assigned ()
- "Displays message that key has not been assigned to a function."
- (interactive)
- (error "Key not assigned"))
-
-;;;
-;;; TOGGLE CAPITALIZATION OF WORD
-;;;
-
-(defun edt-toggle-capitalization-of-word ()
- "Toggle the capitalization of the current word and move forward to next."
- (interactive "*")
- (edt-one-word-forward)
- (edt-one-word-backward)
- (edt-change-case 1)
- (edt-one-word-backward)
- (edt-one-word-forward))
-
-;;;
-;;; ELIMINATE ALL TABS
-;;;
-
-(defun edt-eliminate-all-tabs ()
- "Convert all tabs to spaces in the entire buffer."
- (interactive "*")
- (untabify (point-min) (point-max))
- (message "TABS converted to SPACES"))
-
-;;;
-;;; DISPLAY THE TIME
-;;;
-
-(defun edt-display-the-time ()
- "Display the current time."
- (interactive)
- (message "%s" (current-time-string)))
-
-;;;
-;;; LEARN
-;;;
-
-(defun edt-learn ()
- "Learn a sequence of key strokes to bind to a key."
- (interactive)
- (if (eq defining-kbd-macro t)
- (edt-remember)
- (start-kbd-macro nil)))
-
-;;;
-;;; REMEMBER
-;;;
-
-(defun edt-remember ()
- "Store the sequence of key strokes started by `edt-learn' to a key."
- (interactive)
- (if (eq defining-kbd-macro nil)
- (error "Nothing to remember!")
- (progn
- (end-kbd-macro nil)
- (let (edt-key-definition)
- (setq edt-key-definition
- (read-key-sequence "Enter key for binding: "))
- (if (string-equal "\C-m" edt-key-definition)
- (message "Key sequence not remembered")
- (progn
- (setq edt-learn-macro-count (+ edt-learn-macro-count 1))
- (setq edt-last-replaced-key-definition
- (lookup-key (current-global-map)
- edt-key-definition))
- (define-key (current-global-map) edt-key-definition
- (name-last-kbd-macro
- (intern (concat "last-learned-sequence-"
- (int-to-string edt-learn-macro-count)))))))))))
-
-;;;
-;;; EXIT
-;;;
-
-(defun edt-exit ()
- "Save current buffer, ask to save other buffers, and then exit Emacs."
- (interactive)
- (save-buffer)
- (save-buffers-kill-emacs))
-
-;;;
-;;; QUIT
-;;;
-
-(defun edt-quit ()
- "Quit Emacs without saving buffer modifications.
-Warn user that modifications will be lost."
- (interactive)
- (let ((list (buffer-list))
- (working t))
- (while (and list working)
- (let ((buffer (car list)))
- (if (and (buffer-file-name buffer) (buffer-modified-p buffer))
- (if (edt-y-or-n-p
- "Modifications will not be saved, continue quitting? ")
- (kill-emacs)
- (setq working nil)))
- (setq list (cdr list))))
- (if working (kill-emacs))))
-
-;;;
-;;; SPLIT WINDOW
-;;;
-
-(defun edt-split-window ()
- "Split current window and place cursor in the new window."
- (interactive)
- (split-window)
- (other-window 1))
-
-;;;
-;;; COPY RECTANGLE
-;;;
-
-(defun edt-copy-rectangle ()
- "Copy a rectangle of text between mark and cursor to register."
- (interactive)
- (edt-check-selection)
- (copy-rectangle-to-register 3 (region-beginning) (region-end) nil)
- (edt-reset)
- (message "Selected rectangle COPIED to register"))
-
-;;;
-;;; CUT RECTANGLE
-;;;
-
-(defun edt-cut-rectangle-overstrike-mode ()
- "Cut a rectangle of text between mark and cursor to register.
-Replace cut characters with spaces and moving cursor back to
-upper left corner."
- (interactive "*")
- (edt-check-selection)
- (setq edt-rect-start-point (region-beginning))
- (picture-clear-rectangle-to-register (region-beginning) (region-end) 3)
- (set-window-point (get-buffer-window (window-buffer)) edt-rect-start-point)
- (message "Selected rectangle CUT to register"))
-
-(defun edt-cut-rectangle-insert-mode ()
- "Cut a rectangle of text between mark and cursor to register.
-Move cursor back to upper left corner."
- (interactive "*")
- (edt-check-selection)
- (setq edt-rect-start-point (region-beginning))
- (picture-clear-rectangle-to-register (region-beginning) (region-end) 3 t)
- (fixup-whitespace)
- (set-window-point (get-buffer-window (window-buffer)) edt-rect-start-point)
- (message "Selected rectangle CUT to register"))
-
-(defun edt-cut-rectangle ()
- "Cut a rectangular region of text to register.
-If overwrite mode is active, cut text is replaced with whitespace."
- (interactive "*")
- (if overwrite-mode
- (edt-cut-rectangle-overstrike-mode)
- (edt-cut-rectangle-insert-mode)))
-
-;;;
-;;; PASTE RECTANGLE
-;;;
-
-(defun edt-paste-rectangle-overstrike-mode ()
- "Paste a rectangular region of text from register, replacing text at cursor."
- (interactive "*")
- (picture-yank-rectangle-from-register 3))
-
-(defun edt-paste-rectangle-insert-mode ()
- "Paste previously deleted rectangular region, inserting text at cursor."
- (interactive "*")
- (picture-yank-rectangle-from-register 3 t))
-
-(defun edt-paste-rectangle ()
- "Paste a rectangular region of text.
-If overwrite mode is active, existing text is replace with text from register."
- (interactive)
- (if overwrite-mode
- (edt-paste-rectangle-overstrike-mode)
- (edt-paste-rectangle-insert-mode)))
-
-;;;
-;;; DOWNCASE REGION
-;;;
-
-(defun edt-lowercase ()
- "Change specified characters to lower case.
-If text selection IS active, then characters between the cursor and
-mark are changed. If text selection is NOT active, there are two
-situations. If the current direction is ADVANCE, then the word under
-the cursor is changed to lower case and the cursor is moved to rest at
-the beginning of the next word. If the current direction is BACKUP,
-the word prior to the word under the cursor is changed to lower case
-and the cursor is left to rest at the beginning of that word."
- (interactive "*")
- (if edt-select-mode
- (progn
- (downcase-region (mark) (point)))
- (progn
- ;; Move to beginning of current word.
- (if (and
- (not (bobp))
- (not (eobp))
- (not (bolp))
- (not (eolp))
- (not (eq ?\ (char-syntax (preceding-char))))
- (not (memq (preceding-char) edt-word-entities))
- (not (memq (following-char) edt-word-entities)))
- (edt-one-word-backward))
- (if (equal edt-direction-string edt-backward-string)
- (edt-one-word-backward))
- (let ((beg (point)))
- (edt-one-word-forward)
- (downcase-region beg (point)))
- (if (equal edt-direction-string edt-backward-string)
- (edt-one-word-backward)))))
-
-;;;
-;;; UPCASE REGION
-;;;
-
-(defun edt-uppercase ()
- "Change specified characters to upper case.
-If text selection IS active, then characters between the cursor and
-mark are changed. If text selection is NOT active, there are two
-situations. If the current direction is ADVANCE, then the word under
-the cursor is changed to upper case and the cursor is moved to rest at
-the beginning of the next word. If the current direction is BACKUP,
-the word prior to the word under the cursor is changed to upper case
-and the cursor is left to rest at the beginning of that word."
- (interactive "*")
- (if edt-select-mode
- (progn
- (upcase-region (mark) (point)))
- (progn
- ;; Move to beginning of current word.
- (if (and
- (not (bobp))
- (not (eobp))
- (not (bolp))
- (not (eolp))
- (not (eq ?\ (char-syntax (preceding-char))))
- (not (memq (preceding-char) edt-word-entities))
- (not (memq (following-char) edt-word-entities)))
- (edt-one-word-backward))
- (if (equal edt-direction-string edt-backward-string)
- (edt-one-word-backward))
- (let ((beg (point)))
- (edt-one-word-forward)
- (upcase-region beg (point)))
- (if (equal edt-direction-string edt-backward-string)
- (edt-one-word-backward)))))
-
-;;;
-;;; Functions used in loading LK-201 key mapping file.
-;;;
-(defvar edt-last-answer nil
- "Most recent response to `edt-y-or-n-p'.")
-
-(defun edt-y-or-n-p (prompt &optional not-yes)
- "Prompt for a y or n answer with positive default.
-Like Emacs `y-or-n-p', also accepts space as y and DEL as n.
-Argument PROMPT is the prompt string.
-Optional argument NOT-YES changes the default to negative."
- (message "%s[%s]" prompt (if not-yes "n" "y"))
- (let ((doit t))
- (while doit
- (setq doit nil)
- (let ((ans (read-char)))
- (cond ((or (= ans ?y) (= ans ?Y) (= ans ?\ ))
- (setq edt-last-answer t))
- ((or (= ans ?n) (= ans ?N) (= ans ?\C-?))
- (setq edt-last-answer nil))
- ((= ans ?\r) (setq edt-last-answer (not not-yes)))
- (t
- (setq doit t) (beep)
- (message "Please answer y or n. %s[%s]"
- prompt (if not-yes "n" "y")))))))
- edt-last-answer)
-\f
-;;;
-;;; INITIALIZATION COMMANDS.
-;;;
-
-(declare-function edt-mapper "edt-mapper" ())
-
-;;;
-;;; Function used to load LK-201 key mapping file generated by edt-mapper.el.
-;;;
-(defun edt-load-keys (file)
- "Load the LK-201 key mapping FILE generated by edt-mapper.el.
-If FILE is nil, which is the normal case, try to load a default file.
-The default file names are based upon the window system and terminal
-type. If a default file does not exist, ask user if one should be
-created."
- (interactive "fKey definition file: ")
- (cond (file
- (setq file (expand-file-name file)))
- (edt-keys-file
- (setq file (expand-file-name edt-keys-file)))
- (t
- (setq file
- (expand-file-name
- (concat
- "~/.edt-gnu"
- (if edt-term (concat "-" edt-term))
- (if edt-xserver (concat "-" edt-xserver))
- (if window-system
- (concat "-" (upcase (symbol-name window-system))))
- "-keys")))))
- (cond ((file-readable-p file)
- (load-file file))
- (t
- (switch-to-buffer "*scratch*")
- (erase-buffer)
- (insert "
-
- Ack!! You're running the Enhanced EDT Emulation without loading an
- EDT key mapping file. To create an EDT key mapping file, run the
- edt-mapper program. It is safest to run it from an Emacs loaded
- without any of your own customizations found in your init file, etc.
- The reason for this is that some user customizations confuse edt-mapper.
- You can do this by quitting Emacs and then invoking Emacs again as
- follows:
-
- emacs -q -l edt-mapper -f edt-mapper
-
- [NOTE: If you do nothing out of the ordinary in your init file, and
- the search for edt-mapper is successful, you can try running it now.]
-
- The library edt-mapper includes these same directions on how to
- use it! Perhaps it's lying around here someplace. \n ")
- (let ((path (locate-library
- "edt-mapper"
- nil (append (list default-directory) load-path))))
- (if path
- (progn
- (insert (format
- "Ah yes, there it is, in \n\n %s \n\n" path))
- (if (edt-y-or-n-p "Do you want to run it now? ")
- (progn
- (load-file path)
- (edt-mapper))
- (error "EDT Emulation not configured")))
- (insert (substitute-command-keys
- "Nope, I can't seem to find it. :-(\n\n"))
- (sit-for 20)
- (error "EDT Emulation not configured"))))))
-
-;;;
-;;; Turning the EDT Emulation on and off.
-;;;
-
-;;;###autoload
-(defun edt-emulation-on ()
- "Turn on EDT Emulation."
- (interactive)
- ;; If using pc window system (MS-DOS), set terminal type to pc.
- ;; If not a window system, get terminal type.
- (if (eq window-system 'pc)
- (setq edt-term "pc")
- (if (not window-system)
- (setq edt-term (getenv "TERM"))))
- ;; Look for a terminal configuration file for this terminal type.
- ;; Otherwise, load the user's custom configuration file.
- (if (or (not window-system) (memq window-system '(pc tty)))
- (progn
- ;; Load terminal-specific configuration file, if it exists for this
- ;; terminal type. Note: All DEC VT series terminals are supported
- ;; by the same terminal configuration file: edt-vt100.el.
- (if (string-equal "vt" (substring edt-term 0 (min (length edt-term) 2)))
- (setq edt-term "vt100"))
- (let ((term edt-term)
- hyphend)
- (while (and term
- (not (load (concat "edt-" term) t t)))
- ;; Strip off last hyphen and what follows, then try again
- (if (setq hyphend (string-match "[-_][^-_]+$" term))
- (setq term (substring term 0 hyphend))
- (setq term nil)))
- ;; If no terminal-specific configuration file exists, load user's
- ;; custom EDT terminal configuration file.
- ;; If this is a pc running MS-DOS, then custom configuration files
- ;; are not supported. So, if the file is missing, issue an error
- ;; message.
- (if (null term)
- (if (equal edt-term "pc")
- (error "Unable to find EDT terminal specific file edt-pc.el")
- (edt-load-keys nil))
- (setq edt-term term))))
- (edt-load-keys nil))
- ;; Make highlighting of selected text work properly for EDT commands.
- (setq edt-orig-transient-mark-mode
- (default-value 'transient-mark-mode))
- (add-hook 'activate-mark-hook
- (lambda ()
- (edt-select-mode t)))
- (add-hook 'deactivate-mark-hook
- (lambda ()
- (edt-select-mode nil)))
- ;; Load user's EDT custom key bindings file, if it exists.
- ;; Otherwise, use the default bindings.
- (if (load "edt-user" t t)
- (edt-user-emulation-setup)
- (edt-default-emulation-setup)))
-
-(defun edt-emulation-off()
- "Select original global key bindings, disabling EDT Emulation."
- (interactive)
- (use-global-map global-map)
- (if (not edt-keep-current-page-delimiter)
- (setq page-delimiter edt-orig-page-delimiter))
- (setq edt-direction-string "")
- (setq edt-select-mode-current nil)
- (edt-reset)
- (force-mode-line-update t)
- (setq-default transient-mark-mode edt-orig-transient-mark-mode)
- (message "Original key bindings restored; EDT Emulation disabled"))
-
-(defun edt-default-menu-bar-update-buffers ()
- ;; Update edt-default-global-map with latest copy of
- ;; `global-buffers-menu-map' each time `menu-bar-update-buffers'
- ;; updates global-map.
- (define-key edt-default-global-map [menu-bar buffer]
- (cons "Buffers" global-buffers-menu-map)))
-
-(defun edt-user-menu-bar-update-buffers ()
- ;; We need to update edt-user-global-map with latest copy of
- ;; `global-buffers-menu-map' each time `menu-bar-update-buffers'
- ;; updates global-map.
- (define-key edt-user-global-map [menu-bar buffer]
- (cons "Buffers" global-buffers-menu-map)))
-
-(defun edt-default-emulation-setup (&optional user-setup)
- "Setup emulation of DEC's EDT editor.
-Optional argument USER-SETUP non-nil means called from function
-`edt-user-emulation-setup'."
- ;; Setup default EDT global map by copying global map bindings.
- ;; This preserves ESC and C-x prefix bindings and other bindings we
- ;; wish to retain in EDT emulation mode keymaps. It also permits
- ;; customization of these bindings in the EDT global maps without
- ;; disturbing the original bindings in global-map.
- (fset 'edt-default-ESC-prefix (copy-keymap 'ESC-prefix))
- (setq edt-default-global-map (copy-keymap (current-global-map)))
- (define-key edt-default-global-map "\e" 'edt-default-ESC-prefix)
- (define-prefix-command 'edt-default-gold-map)
- (edt-setup-default-bindings)
- ;; If terminal has additional function keys, the terminal-specific
- ;; initialization file can assign bindings to them via the optional
- ;; function edt-setup-extra-default-bindings.
- (if (fboundp 'edt-setup-extra-default-bindings)
- (edt-setup-extra-default-bindings))
- ;; Variable needed by edt-learn.
- (setq edt-learn-macro-count 0)
- ;; Display EDT text selection active within the mode line
- (or (assq 'edt-select-mode minor-mode-alist)
- (setq minor-mode-alist
- (cons '(edt-select-mode edt-select-mode) minor-mode-alist)))
- ;; Display EDT direction of motion within the mode line
- (or (assq 'edt-direction-string minor-mode-alist)
- (setq minor-mode-alist
- (cons
- '(edt-direction-string edt-direction-string) minor-mode-alist)))
- (if user-setup
- (progn
- (setq edt-user-map-configured t)
- (fset 'edt-emulation-on (symbol-function 'edt-select-user-global-map)))
- (progn
- (fset 'edt-emulation-on (symbol-function 'edt-select-default-global-map))
- (edt-select-default-global-map)))
- ;; Keep the menu bar Buffers menu up-to-date in edt-default-global-map.
- (add-hook 'menu-bar-update-hook #'edt-default-menu-bar-update-buffers))
-
-(defun edt-user-emulation-setup ()
- "Setup user custom emulation of DEC's EDT editor."
- ;; Initialize EDT default bindings.
- (edt-default-emulation-setup t)
- ;; Setup user EDT global map by copying default EDT global map bindings.
- (fset 'edt-user-ESC-prefix (copy-keymap 'edt-default-ESC-prefix))
- (setq edt-user-global-map (copy-keymap edt-default-global-map))
- (define-key edt-user-global-map "\e" 'edt-user-ESC-prefix)
- ;; If terminal has additional function keys, the user's initialization
- ;; file can assign bindings to them via the optional
- ;; function edt-setup-extra-default-bindings.
- (define-prefix-command 'edt-user-gold-map)
- (fset 'edt-user-gold-map (copy-keymap 'edt-default-gold-map))
- ;; This is a function that the user can define for custom bindings.
- ;; See Info node `edt' for more details, and sample edt-user.el file.
- (if (fboundp 'edt-setup-user-bindings)
- (edt-setup-user-bindings))
- (edt-select-user-global-map)
- ;; Keep the menu bar Buffers menu up-to-date in edt-user-global-map.
- (add-hook 'menu-bar-update-hook #'edt-user-menu-bar-update-buffers))
-
-(defun edt-select-default-global-map()
- "Select default EDT emulation key bindings."
- (interactive)
- (transient-mark-mode 1)
- (use-global-map edt-default-global-map)
- (if (not edt-keep-current-page-delimiter)
- (progn
- (setq edt-orig-page-delimiter page-delimiter)
- (setq page-delimiter "\f")))
- (setq edt-default-map-active t)
- (edt-advance)
- (setq edt-select-mode-current 'edt-select-mode-string)
- (edt-reset)
- (message "Default EDT keymap active"))
-
-(defun edt-select-user-global-map()
- "Select user EDT emulation custom key bindings."
- (interactive)
- (if edt-user-map-configured
- (progn
- (transient-mark-mode 1)
- (use-global-map edt-user-global-map)
- (if (not edt-keep-current-page-delimiter)
- (progn
- (setq edt-orig-page-delimiter page-delimiter)
- (setq page-delimiter "\f")))
- (setq edt-default-map-active nil)
- (edt-advance)
- (setq edt-select-mode-current 'edt-select-mode-string)
- (edt-reset)
- (message "User EDT custom keymap active"))
- (error "User EDT custom keymap NOT configured!")))
-
-(defun edt-switch-global-maps ()
- "Toggle between default EDT keymap and user EDT keymap."
- (interactive)
- (if edt-default-map-active
- (edt-select-user-global-map)
- (edt-select-default-global-map)))
-
-;;
-;; Functions used to set up DEFAULT bindings to EDT emulation functions.
-;;
-
-(defun edt-bind-function-key-default (function-key binding gold-binding)
- "Binds LK-201 function keys to default bindings in the EDT Emulator.
-Argument FUNCTION-KEY is the name of the function key or keypad function key.
-Argument BINDING is the Emacs function to be bound to <KEY>.
-Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
- (let ((key (cdr (assoc function-key *EDT-keys*))))
- (if (and key (not (equal key "")))
- (progn
- (define-key edt-default-global-map key binding)
- (define-key 'edt-default-gold-map key gold-binding)))))
-
-(defun edt-bind-key-default (key binding)
- "Bind key sequences to default bindings in the EDT Emulator.
-Argument KEY is the name of a standard key or a function key.
-Argument BINDING is the Emacs function to be bound to <KEY>."
- (define-key edt-default-global-map key binding))
-
-(defun edt-bind-gold-key-default (key gold-binding)
- "Binds <GOLD> key sequences to default bindings in the EDT Emulator.
-Argument KEY is the name of a standard key or a function key.
-Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
- (define-key 'edt-default-gold-map key gold-binding))
-
-;;
-;; Functions used to set up USER CUSTOM bindings to EDT emulation functions.
-;;
-(defun edt-bind-function-key (function-key binding gold-binding)
- "Binds LK-201 function keys to custom bindings in the EDT Emulator.
-Argument FUNCTION-KEY is the name of the function key or keypad function key.
-Argument BINDING is the Emacs function to be bound to <KEY>.
-Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
- (let ((key (cdr (assoc function-key *EDT-keys*))))
- (if (and key (not (equal key "")))
- (progn
- (define-key edt-user-global-map key binding)
- (define-key 'edt-user-gold-map key gold-binding)))))
-
-(defun edt-bind-key (key binding)
- "Bind standard key sequences to custom bindings in the EDT Emulator.
-Argument KEY is the name of a key. It can be a standard key or a function key.
-Argument BINDING is the Emacs function to be bound to <KEY>."
- (define-key edt-user-global-map key binding))
-
-(define-obsolete-function-alias 'edt-bind-standard-key #'edt-bind-key "28.1")
-
-(defun edt-bind-gold-key (key gold-binding)
- "Binds <GOLD> standard key sequences to custom bindings in the EDT Emulator.
-Argument KEY is the name of a standard key or a function key.
-Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
- (define-key 'edt-user-gold-map key gold-binding))
-
-(defun edt-setup-default-bindings ()
- "Assigns default EDT Emulation keyboard bindings."
-
- ;; Function Key Bindings: Regular and GOLD.
-
- ;; VT100/VT200/VT300 PF1 (GOLD), PF2, PF3, PF4 Keys
- (edt-bind-function-key-default "PF1"
- 'edt-default-gold-map 'edt-mark-section-wisely)
- (edt-bind-function-key-default "PF2"
- 'edt-electric-keypad-help 'describe-function)
- (edt-bind-function-key-default "PF3" 'edt-find-next 'edt-find)
- (edt-bind-function-key-default "PF4" 'edt-delete-line 'edt-undelete-line)
-
- ;; VT100/VT200/VT300 Arrow Keys
- (edt-bind-function-key-default "UP" 'edt-previous-line 'edt-window-top)
- (edt-bind-function-key-default "DOWN" 'edt-next-line 'edt-window-bottom)
- (edt-bind-function-key-default "LEFT" 'backward-char 'edt-sentence-backward)
- (edt-bind-function-key-default "RIGHT" 'forward-char 'edt-sentence-forward)
-
- ;; VT100/VT200/VT300 Keypad Keys
- (edt-bind-function-key-default "KP0" 'edt-line 'open-line)
- (edt-bind-function-key-default "KP1" 'edt-word 'edt-change-case)
- (edt-bind-function-key-default "KP2"
- 'edt-end-of-line 'edt-delete-to-end-of-line)
- (edt-bind-function-key-default "KP3" 'edt-character 'quoted-insert)
- (edt-bind-function-key-default "KP4" 'edt-advance 'edt-bottom)
- (edt-bind-function-key-default "KP5" 'edt-backup 'edt-top)
- (edt-bind-function-key-default "KP6" 'edt-cut 'yank)
- (edt-bind-function-key-default "KP7" 'edt-page 'execute-extended-command)
- (edt-bind-function-key-default "KP8" 'edt-sect 'edt-fill-region)
- (edt-bind-function-key-default "KP9" 'edt-append 'edt-replace)
- (edt-bind-function-key-default "KP-" 'edt-delete-word 'edt-undelete-word)
- (edt-bind-function-key-default "KP,"
- 'edt-delete-character 'edt-undelete-character)
- (edt-bind-function-key-default "KPP" 'edt-select 'edt-reset)
- (edt-bind-function-key-default "KPE" 'other-window 'edt-substitute)
-
- ;; VT200/VT300 Function Keys
- ;; (F1 through F5, on the VT220, are not programmable, so we skip
- ;; making default bindings to those keys.
- (edt-bind-function-key-default "FIND" 'edt-find-next 'edt-find)
- (edt-bind-function-key-default "INSERT" 'yank 'edt-key-not-assigned)
- (edt-bind-function-key-default "REMOVE" 'edt-cut 'edt-copy)
- (edt-bind-function-key-default "SELECT"
- 'edt-toggle-select 'edt-key-not-assigned)
- (edt-bind-function-key-default "NEXT"
- 'edt-sect-forward 'edt-key-not-assigned)
- (edt-bind-function-key-default "PREVIOUS"
- 'edt-sect-backward 'edt-key-not-assigned)
- (edt-bind-function-key-default "F6"
- 'edt-key-not-assigned 'edt-key-not-assigned)
- (edt-bind-function-key-default "F7"
- 'edt-copy-rectangle 'edt-key-not-assigned)
- (edt-bind-function-key-default "F8"
- 'edt-cut-rectangle-overstrike-mode 'edt-paste-rectangle-overstrike-mode)
- (edt-bind-function-key-default "F9"
- 'edt-cut-rectangle-insert-mode 'edt-paste-rectangle-insert-mode)
- (edt-bind-function-key-default "F10" 'edt-cut-rectangle 'edt-paste-rectangle)
- ;; Under X, the F11 key can be bound. If using a VT-200 or higher terminal,
- ;; the default emacs terminal support causes the VT F11 key to seem as if it
- ;; is an ESC key when in emacs.
- (edt-bind-function-key-default "F11"
- 'edt-key-not-assigned 'edt-key-not-assigned)
- (edt-bind-function-key-default "F12"
- 'edt-beginning-of-line 'delete-other-windows) ;BS
- (edt-bind-function-key-default "F13"
- 'edt-delete-to-beginning-of-word 'edt-key-not-assigned) ;LF
- (edt-bind-function-key-default "F14"
- 'edt-key-not-assigned 'edt-key-not-assigned)
- (edt-bind-function-key-default "HELP"
- 'edt-electric-keypad-help 'edt-key-not-assigned)
- (edt-bind-function-key-default "DO"
- 'execute-extended-command 'edt-key-not-assigned)
- (edt-bind-function-key-default "F17"
- 'edt-key-not-assigned 'edt-key-not-assigned)
- (edt-bind-function-key-default "F18"
- 'edt-key-not-assigned 'edt-key-not-assigned)
- (edt-bind-function-key-default "F19"
- 'edt-key-not-assigned 'edt-key-not-assigned)
- (edt-bind-function-key-default "F20"
- 'edt-key-not-assigned 'edt-key-not-assigned)
-
- ;; Control key bindings: Regular and GOLD
- ;;
- ;; Standard EDT control key bindings conflict with standard Emacs
- ;; control key bindings. Normally, the standard Emacs control key
- ;; bindings are left unchanged in the default EDT mode. However, if
- ;; the variable edt-use-EDT-control-key-bindings is set to true
- ;; before invoking edt-emulation-on for the first time, then the
- ;; standard EDT bindings (with some enhancements) as defined here are
- ;; used, instead.
- (if edt-use-EDT-control-key-bindings
- (progn
- (edt-bind-key-default "\C-a" 'edt-key-not-assigned)
- (edt-bind-key-default "\C-b" 'edt-key-not-assigned)
- ;; Leave binding of C-c to an Emacs prefix key.
- (edt-bind-key-default "\C-d" 'edt-key-not-assigned)
- (edt-bind-key-default "\C-e" 'edt-key-not-assigned)
- (edt-bind-key-default "\C-f" 'edt-key-not-assigned)
- ;; Leave binding of C-g to the Emacs keyboard-quit
- (edt-bind-key-default "\C-h" 'edt-beginning-of-line)
- (edt-bind-key-default "\C-i" 'edt-tab-insert)
- (edt-bind-key-default "\C-j" 'edt-delete-to-beginning-of-word)
- (edt-bind-key-default "\C-k" 'edt-define-key)
- (edt-bind-gold-key-default "\C-k" 'edt-restore-key)
- (edt-bind-key-default "\C-l" 'edt-form-feed-insert)
- ;; Leave binding of C-m to newline.
- (edt-bind-key-default "\C-n" 'edt-set-screen-width-80)
- (edt-bind-key-default "\C-o" 'edt-key-not-assigned)
- (edt-bind-key-default "\C-p" 'edt-key-not-assigned)
- (edt-bind-key-default "\C-q" 'edt-key-not-assigned)
- ;; Leave binding of C-r to isearch-backward.
- ;; Leave binding of C-s to isearch-forward.
- (edt-bind-key-default "\C-t" 'edt-display-the-time)
- (edt-bind-key-default "\C-u" 'edt-delete-to-beginning-of-line)
- (edt-bind-key-default "\C-v" 'redraw-display)
- (edt-bind-key-default "\C-w" 'edt-set-screen-width-132)
- ;; Leave binding of C-x as original prefix key.
- (edt-bind-key-default "\C-y" 'edt-key-not-assigned)
- ;; Leave binding of C-z to suspend-emacs.
- )
- )
-
- ;; GOLD bindings for a few keys.
- (edt-bind-gold-key-default "\C-g" 'keyboard-quit); Just in case.
- (edt-bind-gold-key-default "\C-\\" 'split-window-below)
-
- ;; GOLD bindings for regular keys.
- (edt-bind-gold-key-default "a" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "A" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "b" 'buffer-menu)
- (edt-bind-gold-key-default "B" 'buffer-menu)
- (edt-bind-gold-key-default "c" 'compile)
- (edt-bind-gold-key-default "C" 'compile)
- (edt-bind-gold-key-default "d" 'delete-window)
- (edt-bind-gold-key-default "D" 'delete-window)
- (edt-bind-gold-key-default "e" 'edt-exit)
- (edt-bind-gold-key-default "E" 'edt-exit)
- (edt-bind-gold-key-default "f" 'find-file)
- (edt-bind-gold-key-default "F" 'find-file)
- (edt-bind-gold-key-default "g" 'find-file-other-window)
- (edt-bind-gold-key-default "G" 'find-file-other-window)
- (edt-bind-gold-key-default "h" 'edt-electric-keypad-help)
- (edt-bind-gold-key-default "H" 'edt-electric-keypad-help)
- (edt-bind-gold-key-default "i" 'insert-file)
- (edt-bind-gold-key-default "I" 'insert-file)
- (edt-bind-gold-key-default "j" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "J" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "k" 'edt-toggle-capitalization-of-word)
- (edt-bind-gold-key-default "K" 'edt-toggle-capitalization-of-word)
- (edt-bind-gold-key-default "l" 'edt-lowercase)
- (edt-bind-gold-key-default "L" 'edt-lowercase)
- (edt-bind-gold-key-default "m" 'save-some-buffers)
- (edt-bind-gold-key-default "M" 'save-some-buffers)
- (edt-bind-gold-key-default "n" 'next-error)
- (edt-bind-gold-key-default "N" 'next-error)
- (edt-bind-gold-key-default "o" 'switch-to-buffer-other-window)
- (edt-bind-gold-key-default "O" 'switch-to-buffer-other-window)
- (edt-bind-gold-key-default "p" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "P" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "q" 'edt-quit)
- (edt-bind-gold-key-default "Q" 'edt-quit)
- (edt-bind-gold-key-default "r" 'revert-buffer)
- (edt-bind-gold-key-default "R" 'revert-buffer)
- (edt-bind-gold-key-default "s" 'save-buffer)
- (edt-bind-gold-key-default "S" 'save-buffer)
- (edt-bind-gold-key-default "t" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "T" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "u" 'edt-uppercase)
- (edt-bind-gold-key-default "U" 'edt-uppercase)
- (edt-bind-gold-key-default "v" 'find-file-other-window)
- (edt-bind-gold-key-default "V" 'find-file-other-window)
- (edt-bind-gold-key-default "w" 'write-file)
- (edt-bind-gold-key-default "W" 'write-file)
- (edt-bind-gold-key-default "x" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "X" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "y" 'edt-emulation-off)
- (edt-bind-gold-key-default "Y" 'edt-emulation-off)
- (edt-bind-gold-key-default "z" 'edt-switch-global-maps)
- (edt-bind-gold-key-default "Z" 'edt-switch-global-maps)
- (edt-bind-gold-key-default "1" 'delete-other-windows)
- (edt-bind-gold-key-default "!" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "2" 'edt-split-window)
- (edt-bind-gold-key-default "@" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "3" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "#" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "4" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "$" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "5" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "%" 'edt-goto-percentage)
- (edt-bind-gold-key-default "6" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "^" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "7" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "&" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "8" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "*" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "9" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "(" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "0" 'edt-key-not-assigned)
- (edt-bind-gold-key-default ")" 'edt-key-not-assigned)
- (edt-bind-gold-key-default " " 'undo)
- (edt-bind-gold-key-default "," 'edt-key-not-assigned)
- (edt-bind-gold-key-default "<" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "." 'edt-key-not-assigned)
- (edt-bind-gold-key-default ">" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "/" 'query-replace)
- (edt-bind-gold-key-default "?" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "\\" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "|" 'edt-key-not-assigned)
- (edt-bind-gold-key-default ";" 'edt-key-not-assigned)
- (edt-bind-gold-key-default ":" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "'" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "\"" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "-" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "_" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "=" 'goto-line)
- (edt-bind-gold-key-default "+" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "[" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "{" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "]" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "}" 'edt-key-not-assigned)
- (edt-bind-gold-key-default "`" 'what-line)
- (edt-bind-gold-key-default "~" 'edt-key-not-assigned)
-)
-\f
-;;;
-;;; DEFAULT EDT KEYPAD HELP
-;;;
-
-;;
-;; Upper case commands in the keypad diagram below indicate that the
-;; emulation should look and feel very much like EDT. Lower case
-;; commands are enhancements and/or additions to the EDT keypad
-;; commands or are native Emacs commands.
-;;
-
-(defun edt-keypad-help ()
- "DEFAULT EDT Keypad Active.
-
- F7: Copy Rectangle +----------+----------+----------+----------+
- F8: Cut Rect Overstrike |Prev Line |Next Line |Bkwd Char |Frwd Char |
- G-F8: Paste Rect Overstrike | (UP) | (DOWN) | (LEFT) | (RIGHT) |
- F9: Cut Rect Insert |Window Top|Window Bot|Bkwd Sent |Frwd Sent |
- G-F9: Paste Rect Insert +----------+----------+----------+----------+
- F10: Cut Rectangle
-G-F10: Paste Rectangle
- F11: ESC
- F12: Beginning of Line +----------+----------+----------+----------+
-G-F12: Delete Other Windows | GOLD | HELP | FNDNXT | DEL L |
- F13: Delete to Begin of Word | (PF1) | (PF2) | (PF3) | (PF4) |
- HELP: Keypad Help |Mark Wisel|Desc Funct| FIND | UND L |
-G-HELP: Emacs Help +----------+----------+----------+----------+
- DO: Execute extended command | PAGE | SECT | APPEND | DEL W |
- C-g: Keyboard Quit | (7) | (8) | (9) | (-) |
-G-C-g: Keyboard Quit |Ex Ext Cmd|Fill Regio| REPLACE | UND W |
- C-h: Beginning of Line +----------+----------+----------+----------+
-G-C-h: Emacs Help | ADVANCE | BACKUP | CUT | DEL C |
- C-i: Tab Insert | (4) | (5) | (6) | (,) |
- C-j: Delete to Begin of Word | BOTTOM | TOP | Yank | UND C |
- C-k: Define Key +----------+----------+----------+----------+
-G-C-k: Restore Key | WORD | EOL | CHAR | Next |
- C-l: Form Feed Insert | (1) | (2) | (3) | Window |
- C-n: Set Screen Width 80 | CHNGCASE | DEL EOL |Quoted Ins| !
- C-r: Isearch Backward +---------------------+----------+ (ENTER) |
- C-s: Isearch Forward | LINE | SELECT | !
- C-t: Display the Time | (0) | (.) | SUBS |
- C-u: Delete to Begin of Line | Open Line | RESET | |
- C-v: Redraw Display +---------------------+----------+----------+
- C-w: Set Screen Width 132
- C-z: Suspend Emacs +----------+----------+----------+
-G-C-\\: Split Window | FNDNXT | Yank | CUT |
- | (FIND) | (INSERT) | (REMOVE) |
- G-b: Buffer Menu | FIND | | COPY |
- G-c: Compile +----------+----------+----------+
- G-d: Delete Window |SELECT/RES|SECT BACKW|SECT FORWA|
- G-e: Exit | (SELECT) |(PREVIOUS)| (NEXT) |
- G-f: Find File | | | |
- G-g: Find File Other Window +----------+----------+----------+
- G-h: Keypad Help
- G-i: Insert File
- G-k: Toggle Capitalization Word
- G-l: Downcase Region
- G-m: Save Some Buffers
- G-n: Next Error
- G-o: Switch to Next Window
- G-q: Quit
- G-r: Revert File
- G-s: Save Buffer
- G-u: Upcase Region
- G-v: Find File Other Window
- G-w: Write file
- G-y: EDT Emulation OFF
- G-z: Switch to User EDT Key Bindings
- G-1: Delete Other Windows
- G-2: Split Window
- G-%: Go to Percentage
- G- : Undo (GOLD Spacebar)
- G-=: Go to Line
- G-`: What line
- G-/: Query-Replace"
-
- (interactive)
- (describe-function 'edt-keypad-help))
-
-(defun edt-electric-helpify (fun)
- (let ((name "*Help*"))
- (if (save-window-excursion
- (let* ((p (symbol-function 'help-print-return-message))
- (b (get-buffer name))
- (m (buffer-modified-p b)))
- (and b (not (get-buffer-window b))
- (setq b nil))
- (unwind-protect
- (progn
- (message "%s..." (capitalize (symbol-name fun)))
- (and b
- (with-current-buffer b
- (set-buffer-modified-p t)))
- (fset 'help-print-return-message #'ignore)
- (call-interactively fun)
- (and (get-buffer name)
- (get-buffer-window (get-buffer name))
- (or (not b)
- (not (eq b (get-buffer name)))
- (not (buffer-modified-p b)))))
- (fset 'help-print-return-message p)
- (and b (buffer-name b)
- (with-current-buffer b
- (set-buffer-modified-p m))))))
- (with-electric-help 'delete-other-windows name t))))
-
-(defun edt-electric-keypad-help ()
- "Display default EDT bindings."
- (interactive)
- (edt-electric-helpify 'edt-keypad-help))
-
-(defun edt-electric-user-keypad-help ()
- "Display user custom EDT bindings."
- (interactive)
- (edt-electric-helpify 'edt-user-keypad-help))
-
-;;;
-;;; EDT emulation screen width commands.
-;;
-;; Some terminals require modification of terminal attributes when
-;; changing the number of columns displayed, hence the fboundp tests
-;; below. These functions are defined in the corresponding terminal
-;; specific file, if needed.
-
-(defun edt-set-screen-width-80 ()
- "Set screen width to 80 columns."
- (interactive)
- (if (fboundp 'edt-set-term-width-80)
- (edt-set-term-width-80))
- (set-frame-width nil 80)
- (message "Terminal width 80"))
-
-(defun edt-set-screen-width-132 ()
- "Set screen width to 132 columns."
- (interactive)
- (if (fboundp 'edt-set-term-width-132)
- (edt-set-term-width-132))
- (set-frame-width nil 132)
- (message "Terminal width 132"))
-
-(defconst edt-version "4.0" "EDT Emulation version number.")
-(make-obsolete-variable 'edt-version 'emacs-version "28.1")
-
-(provide 'edt)
-
-;;; edt.el ends here
sh-mode ksh-mode csh-mode
gnus-article-mode
- mh-show-mode
)
"Major modes that require Vi command state."
:type '(repeat symbol))
recentf-dialog-mode
occur-mode
- mh-folder-mode
gnus-group-mode
gnus-summary-mode
(internal-ange-ftp-mode vi-state viper-comint-mode-modifier-map)
(dired-mode emacs-state viper-dired-modifier-map)
(tar-mode emacs-state viper-slash-and-colon-map)
- (mh-folder-mode emacs-state viper-slash-and-colon-map)
(gnus-group-mode emacs-state viper-gnus-modifier-map)
(gnus-summary-mode emacs-state viper-gnus-modifier-map)
(Info-mode emacs-state viper-slash-and-colon-map)
(viper-set-emacs-state-searchstyle-macros nil 'dired-mode) ; dired
(viper-set-emacs-state-searchstyle-macros nil 'tar-mode) ; tar
- (viper-set-emacs-state-searchstyle-macros nil 'mh-folder-mode) ; mhe
(viper-set-emacs-state-searchstyle-macros nil 'gnus-group-mode) ; gnus
(viper-set-emacs-state-searchstyle-macros nil 'gnus-summary-mode)
(viper-set-emacs-state-searchstyle-macros nil 'Info-mode) ; info
:type '(repeat (cons character sexp))
:risky t)
-(defvar eshell-predicate-help-string
- "Eshell predicate quick reference:
-
- - follow symbolic references for predicates after the `-'
- ^ invert sense of predicates after the `^'
-
-FILE TYPE:
- / directories s sockets
- . regular files p named pipes
- * executable (files only) @ symbolic links
-
- %x file type == `x' (as by ls -l; so `c' = char device, etc.)
-
-PERMISSION BITS (for owner/group/world):
- r/A/R readable s setuid
- w/I/W writable S setgid
- x/E/X executable t sticky bit
-
-OWNERSHIP:
- U owned by effective uid
- G owned by effective gid
- u(UID|\\='user\\=') owned by UID/user
- g(GID|\\='group\\=') owned by GID/group
-
-FILE ATTRIBUTES:
- l[+-]N +/-/= N links
- a[Mwhms][+-](N|\\='FILE\\=') access time +/-/= N months/weeks/hours/mins/secs
- (days if unspecified) if FILE specified,
- use as comparison basis; so a+\\='file.c\\='
- shows files accessed before file.c was
- last accessed
- m[Mwhms][+-](N|\\='FILE\\=') modification time...
- c[Mwhms][+-](N|\\='FILE\\=') change time...
- L[kmp][+-]N file size +/-/= N Kb/Mb/blocks
-
-EXAMPLES:
- *(^@) all non-dot files which are not symlinks
- .#*(^@) all files which are not symbolic links
- **/.#*(*) all executable files, searched recursively
- ***/*~f*(-/) recursively (though not traversing symlinks),
- find all directories (or symlinks referring to
- directories) whose names do not begin with f.
- e*(*Lk+50) executables 50k or larger beginning with `e'")
-
-(defvar eshell-modifier-help-string
- "Eshell modifier quick reference:
-
-FOR SINGLE ARGUMENTS, or each argument of a list of strings:
- E evaluate again
- L lowercase
- U uppercase
- C capitalize
- h dirname
- t basename
- e file extension
- r strip file extension
- q escape special characters
-
- S split string at any whitespace character
- S/PAT/ split string at each occurrence of PAT
-
-FOR LISTS OF ARGUMENTS:
- o sort alphabetically
- O reverse sort alphabetically
- u uniq list (typically used after :o or :O)
- R reverse list
-
- j join list members, separated by a space
- j/PAT/ join list members, separated by PAT
- i/PAT/ exclude all members not matching PAT
- x/PAT/ exclude all members matching PAT
-
- s/pat/match/ substitute PAT with MATCH
- gs/pat/match/ substitute PAT with MATCH for all occurrences
-
-EXAMPLES:
- *.c(:o) sorted list of .c files")
-
(defvar eshell-pred-delimiter-pairs
'((?\( . ?\))
(?\[ . ?\])
(defvar eshell-error-if-no-glob) ; Defined in em-glob.el.
-(defvar-keymap eshell-pred-mode-map
- "C-c M-q" #'eshell-display-predicate-help
- "C-c M-m" #'eshell-display-modifier-help)
-
;;; Functions:
-(defun eshell-display-predicate-help ()
- (interactive)
- (with-electric-help
- (lambda ()
- (insert eshell-predicate-help-string))))
-
-(defun eshell-display-modifier-help ()
- (interactive)
- (with-electric-help
- (lambda ()
- (insert eshell-modifier-help-string))))
-
(define-minor-mode eshell-pred-mode
"Minor mode for the eshell-pred module.
-\\{eshell-pred-mode-map}"
- :keymap eshell-pred-mode-map)
+\\{eshell-pred-mode-map}")
(defun eshell-pred-initialize () ;Called from `eshell-mode' via intern-soft!
"Initialize the predicate/modifier code."
("leim" . emacs)
("ja-dic" . emacs)
("quail" . emacs)
- ("mh-e" . mh-e)
("obsolete" . emacs)
;; This should really be ("nxml" . nxml-mode), because nxml-mode.el
;; is the main file for the package. Then we would not need an
:type '(radio (function-item :tag "Default Emacs mail"
:format "%t\n"
sendmail-user-agent)
- (function-item :tag "Emacs interface to MH"
- :format "%t\n"
- mh-e-user-agent)
(function-item :tag "Gnus Message package"
:format "%t\n"
message-user-agent)
+++ /dev/null
-;;; gnus-mh.el --- mh-e interface for Gnus -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1994-2024 Free Software Foundation, Inc.
-
-;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
-;; Lars Magne Ingebrigtsen <larsi@gnus.org>
-;; Keywords: news
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Send mail using mh-e.
-
-;; The following mh-e interface is all cooperative works of
-;; tanaka@flab.fujitsu.CO.JP (TANAKA Hiroshi), kawabe@sra.CO.JP
-;; (Yoshikatsu Kawabe), and shingu@casund.cpr.canon.co.jp (Toshiaki
-;; SHINGU).
-
-;;; Code:
-
-(require 'gnus)
-(require 'mh-e)
-(require 'mh-comp)
-(require 'gnus-msg)
-(require 'gnus-sum)
-
-(defvar mh-lib-progs)
-
-(defcustom gnus-rcvstore-options nil
- "Options that are passed to rcvstore, or nil.
-These are used when saving articles to an MH folder."
- :version "26.1"
- :group 'gnus-article
- :type '(repeat string))
-
-(defun gnus-summary-save-article-folder (&optional arg)
- "Append the current article to an mh folder.
-If N is a positive number, save the N next articles.
-If N is a negative number, save the N previous articles.
-If N is nil and any articles have been marked with the process mark,
-save those articles instead."
- (interactive "P" gnus-summary-mode)
- (require 'gnus-art)
- (let ((gnus-default-article-saver 'gnus-summary-save-in-folder))
- (gnus-summary-save-article arg)))
-
-(defun gnus-summary-save-in-folder (&optional folder)
- "Save this article to MH folder (using `rcvstore' in MH library).
-Optional argument FOLDER specifies folder name."
- ;; Thanks to yuki@flab.Fujitsu.JUNET and ohm@kaba.junet.
- (mh-find-path)
- (let ((folder
- (cond ((and (eq folder 'default)
- gnus-newsgroup-last-folder)
- gnus-newsgroup-last-folder)
- (folder folder)
- (t (mh-prompt-for-folder
- "Save article in"
- (funcall gnus-folder-save-name gnus-newsgroup-name
- gnus-current-headers gnus-newsgroup-last-folder)
- t))))
- (errbuf (gnus-get-buffer-create " *Gnus rcvstore*"))
- ;; Find the rcvstore program.
- (exec-path (cond
- ((and (boundp 'mh-lib-progs) mh-lib-progs)
- (cons mh-lib-progs exec-path))
- (mh-lib (cons mh-lib exec-path))
- (t exec-path))))
- (with-current-buffer gnus-original-article-buffer
- (save-restriction
- (widen)
- (unwind-protect
- (apply
- #'call-process-region
- (point-min) (point-max) "rcvstore" nil errbuf nil folder
- gnus-rcvstore-options)
- (set-buffer errbuf)
- (if (zerop (buffer-size))
- (message "Article saved in folder: %s" folder)
- (message "%s" (buffer-string)))
- (kill-buffer errbuf))))
- (setq gnus-newsgroup-last-folder folder)))
-
-(defun gnus-Folder-save-name (newsgroup _headers &optional last-folder)
- "Generate folder name from NEWSGROUP, HEADERS, and optional LAST-FOLDER.
-If variable `gnus-use-long-file-name' is nil, it is +News.group.
-Otherwise, it is like +news/group."
- (or last-folder
- (concat "+"
- (if gnus-use-long-file-name
- (gnus-capitalize-newsgroup newsgroup)
- (gnus-newsgroup-directory-form newsgroup)))))
-
-(defun gnus-folder-save-name (newsgroup _headers &optional last-folder)
- "Generate folder name from NEWSGROUP, HEADERS, and optional LAST-FOLDER.
-If variable `gnus-use-long-file-name' is nil, it is +news.group.
-Otherwise, it is like +news/group."
- (or last-folder
- (concat "+"
- (if gnus-use-long-file-name
- newsgroup
- (gnus-newsgroup-directory-form newsgroup)))))
-
-(provide 'gnus-mh)
-
-;;; gnus-mh.el ends here
variable `mail-header-separator'.
Valid values include `message-send-mail-with-sendmail'
-`message-send-mail-with-mh', `message-send-mail-with-qmail',
-`message-smtpmail-send-it', `smtpmail-send-it',
-`feedmail-send-it' and `message-send-mail-with-mailclient'. The
-default is system dependent and determined by the function
-`message-send-mail-function'.
+`message-send-mail-with-qmail', `message-smtpmail-send-it',
+`smtpmail-send-it', `feedmail-send-it' and
+`message-send-mail-with-mailclient'. The default is system dependent
+and determined by the function `message-send-mail-function'.
See also `send-mail-function'."
:type '(radio (function-item message--default-send-mail-function)
(function-item message-send-mail-with-sendmail)
- (function-item message-send-mail-with-mh)
(function-item message-send-mail-with-qmail)
(function-item message-smtpmail-send-it)
(function-item :doc "Use SMTPmail package." smtpmail-send-it)
'message-mail 'message-send-and-exit
'message-kill-buffer 'message-send-hook)
-(defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)
- "If non-nil, delete the deletable headers before feeding to mh.")
-
(defvar message-send-method-alist
'((news message-news-p message-send-via-news)
(mail message-mail-p message-send-via-mail))
(function-item :tag "Default Emacs mail"
:format "%t\n"
sendmail-user-agent)
- (function-item :tag "Emacs interface to MH"
- :format "%t\n"
- mh-e-user-agent)
(function :tag "Other"))
:version "21.1"
:group 'message)
(autoload 'gnus-request-post "gnus-int")
(autoload 'gnus-server-string "gnus")
(autoload 'message-setup-toolbar "messagexmas")
-(autoload 'mh-new-draft-name "mh-comp")
-(autoload 'mh-send-letter "mh-comp")
(autoload 'nndraft-request-associate-buffer "nndraft")
(autoload 'nndraft-request-expire-articles "nndraft")
(autoload 'nnvirtual-find-group-art "nnvirtual")
;; should never happen
(_ (error "qmail-inject reported unknown failure"))))
-(defvar mh-previous-window-config)
-
-(defun message-send-mail-with-mh ()
- "Send the prepared message buffer with mh."
- (let ((mh-previous-window-config nil)
- (name (mh-new-draft-name)))
- (setq buffer-file-name name)
- ;; MH wants to generate these headers itself.
- (when message-mh-deletable-headers
- (let ((headers message-mh-deletable-headers))
- (while headers
- (goto-char (point-min))
- (when (re-search-forward
- (concat "^" (symbol-name (car headers)) ": *") nil t)
- (delete-line))
- (pop headers))))
- (run-hooks 'message-send-mail-hook)
- ;; Pass it on to mh.
- (mh-send-letter)))
-
(defun message-use-send-mail-function ()
(run-hooks 'message-send-mail-hook)
(funcall send-mail-function))
(define-key map "\C-e" 'hexl-end-of-line)
(define-key map "\C-f" 'hexl-forward-char)
- (if (not (memq (key-binding (char-to-string help-char))
- '(help-command ehelp-command)))
+ (if (not (eq (key-binding (char-to-string help-char)) 'help-command))
(define-key map (char-to-string help-char) 'undefined))
(define-key map "\C-k" 'undefined)
("info" "Index")
("mairix" "(mairix-el)Variable Index" "(mairix-el)Function Index")
("message" "Index")
- ("mh" "(mh-e)Option Index" "(mh-e)Command Index")
("newsticker" "Index")
("octave" "(octave-mode)Variable Index" "(octave-mode)Lisp Function Index")
("org" "Variable Index" "Command and Function Index")
\f
(defvar Info-file-list-for-emacs
- '("ediff" "eudc" "forms" "gnus" "info" ("Info" . "info") ("mh" . "mh-e")
+ '("ediff" "eudc" "forms" "gnus" "info" ("Info" . "info")
"sc" "message" ("dired" . "dired-x") "viper" "vip" "idlwave"
("c" . "ccmode") ("c++" . "ccmode") ("objc" . "ccmode")
("java" . "ccmode") ("idl" . "ccmode") ("pike" . "ccmode")
"Does nothing. Use this instead of nil to get a blank header."
())
-(declare-function mh-in-header-p "mh-utils" ())
-
(defun sc-no-blank-line-or-header ()
"Similar to `sc-no-header' except it removes the preceding blank line."
(and (not (bobp))
(or (= (point)
(save-excursion
(rfc822-goto-eoh)
- (line-beginning-position 2)))
- (and (eq major-mode 'mh-letter-mode)
- (mh-in-header-p))))
+ (line-beginning-position 2)))))
(progn
(forward-line)
(kill-line))))
+++ /dev/null
-2005-09-30 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-refile-msg, mh-tool-bar-reply-from)
- (mh-tool-bar-reply-to, mh-tool-bar-reply-all)
- (mh-alias-grab-from-field, mh-pack-folder): Image files moved to
- etc/images/mail so added "mail/" prefix.
- (mh-reply): Ditto. Also renamed reply2.* to reply.*.
- (mh-rescan-folder): Ditto. Renamed image file to refresh.* since
- it can be used in the general sense. Does not have "mail/"
- prefix.
-
-2005-09-29 Bill Wohler <wohler@newt.com>
-
- Merged in changes from CVS Emacs including:
-
- * mh-mime.el (mh-compose-forward, mh-mhn-compose-forw):
- * mh-comp.el (mh-insert-letter):
- * mh-utils.el (mh-prompt-for-folder):
- Follow convention for reading with the minibuffer. Emilio C. Lopes
- <eclig@gmx.net> 2005-09-24.
-
-2005-09-26 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (desktop-buffer-mode-handlers): Only add to this list if
- the variable exists. Not present pre-version 22.
-
- Merged in changes from CVS Emacs including:
-
- * mh-print.el (mh-ps-print-msg-show): Fix misplaced parenthesis in
- previous change. Juanma Barranquero <lekktu@gmail.com> 2005-09-19
-
- * mh-alias.el (mh-alias-ali): Fix `message' call: first arg
- should be a format spec.
-
- * mh-print.el (mh-ps-spool-buffer, mh-ps-spool-a-msg)
- (mh-ps-print-msg, mh-ps-print-msg-show): Ditto.
-
- * mh-mime.el (mh-toggle-mh-decode-mime-flag): Ditto.
-
- * mh-index.el (mh-index-sequenced-messages): Ditto.
-
- * mh-e.el (mh-refile-or-write-again, mh-page-msg): Ditto.
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist)
- (mh-spamassassin-blacklist, mh-spamassassin-whitelist): Ditto. D
- Goel <deego@gnufans.org> 2005-09-18.
-
- * mh-customize.el: Do not use face-alias compatibility for
- faces that did not appear in the previous Emacs release. Dan
- Nicolaescu <dann@ics.uci.edu> 2005-08-15.
-
- * mh-e.el: Add handler to desktop-buffer-mode-handlers.
- (mh-restore-desktop-buffer): Remove autoload cookie.
- (mh-folder-mode): Add autoload cookie. Lars Hansen
- <larsh@soem.dk> 2005-08-10.
-
- Update FSF's address in GPL notices Lute Kamstra <lute@gnu.org>
- 2005-07-04 .
-
- * mh-customize.el (mh-folder-body-face, mh-folder-cur-msg-face)
- (mh-folder-cur-msg-number-face): New backward-compatibility
- aliases for renamed faces. Lute Kamstra <lute@gnu.org> 2005-06-17.
-
- * mh-customize.el (mh-folder-body, mh-folder-cur-msg)
- (mh-folder-cur-msg-number, mh-folder-date, mh-folder-followup)
- (mh-folder-msg-number, mh-folder-refiled, mh-folder-subject)
- (mh-folder-tick, mh-folder-to, mh-index-folder)
- (mh-letter-header-field, mh-show-cc, mh-show-date)
- (mh-show-header, mh-show-pgg-good, mh-show-pgg-unknown)
- (mh-show-pgg-bad, mh-show-signature, mh-show-to, mh-show-from)
- (mh-show-xface, mh-speedbar-folder, mh-speedbar-selected-folder)
- (mh-speedbar-folder-with-unseen-messages)
- (mh-speedbar-selected-folder-with-unseen-messages)
- (mh-folder-msg-number, mh-folder-subject, mh-folder-followup)
- (mh-folder-subject): Remove "-face" suffix from face names.
- (mh-folder-body, mh-folder-cur-msg, mh-folder-cur-msg-number)
- (mh-folder-date-face, mh-folder-followup-face)
- (mh-folder-msg-number-face, mh-folder-refiled-face)
- (mh-folder-subject-face, mh-folder-tick-face, mh-folder-to-face)
- (mh-index-folder-face, mh-letter-header-field-face)
- (mh-show-cc-face, mh-show-date-face, mh-show-header-face)
- (mh-show-pgg-good-face, mh-show-pgg-unknown-face)
- (mh-show-pgg-bad-face, mh-show-signature-face, mh-show-to-face)
- (mh-show-from-face, mh-show-xface-face, mh-speedbar-folder-face)
- (mh-speedbar-selected-folder-face)
- (mh-speedbar-folder-with-unseen-messages-face)
- (mh-speedbar-selected-folder-with-unseen-messages-face):
- New backward-compatibility aliases for renamed faces.
- (mh-folder-body-face, mh-folder-cur-msg-face)
- (mh-folder-cur-msg-number-face, mh-folder-date-face)
- (mh-folder-followup-face, mh-folder-msg-number-face)
- (mh-folder-deleted-face, mh-folder-refiled-face)
- (mh-folder-subject-face, mh-folder-address-face)
- (mh-folder-scan-format-face, mh-folder-to-face)
- (mh-index-folder-face, mh-show-cc-face, mh-show-date-face)
- (mh-show-header-face, mh-show-pgg-good-face)
- (mh-show-pgg-unknown-face, mh-show-pgg-bad-face)
- (mh-show-to-face, mh-show-from-face, mh-show-subject-face)
- (mh-speedbar-folder-with-unseen-messages)
- (mh-speedbar-selected-folder-with-unseen-messages):
- Use renamed MH-E faces.
-
- * mh-utils.el (mh-letter-font-lock-keywords)
- (mh-face-display-function): Use renamed MH-E faces.
- * mh-speed.el (mh-folder-speedbar-buttons)
- (mh-speed-update-current-folder, mh-speed-normal-face)
- (mh-speed-bold-face, mh-speed-add-buttons)
- (mh-speed-invalidate-map): Likewise.
- * mh-mime.el (mh-signature-highlight): Likewise. Miles Bader
- <miles@gnu.org> 2005-06-17.
-
- * mh-comp.el (mh-send-sub):
- * mh-identity.el (mh-identity-field-handler):
- * mh-mime.el (mh-secure-message):
- Don't use `format' on `error' arguments. Juanma
- Barranquero <lekktu@gmail.com> 2005-06-16.
-
- * mh-mime.el (mh-secure-message): Follow error conventions.
- Juanma Barranquero <lekktu@gmail.com> 2005-06-14.
-
-2005-09-24 Bill Wohler <wohler@newt.com>
-
- * mh-unit.el (mh-unit): Changed lm-verify test to Emacs 22.
-
-2005-09-22 Bill Wohler <wohler@newt.com>
-
- * Makefile: Incorporated ideas from Clemens Fruhwirth to
- generalize mh-loaddefs.el to make it work for both GNU Emacs and
- XEmacs.
- (EMACS_OPTIONS, XEMACS_OPTIONS): Use double-dash for all long
- options.
- (EMACS_LOADDEFS_COOKIE): New variable for generate-autoload-cookie
- setting. Obsoletes XEMACS_LOADDEFS_COOKIE.
- (EMACS_EXPORT_MH_LOADDEFS): New variable for GNU Emacs commands to
- rebuild mh-loaddefs.el.
- (XEMACS_EXPORT_MH_LOADDEFS): New variable for XEmacs commands to
- rebuild mh-loaddefs.el. Obsoletes XEMACS_LOADDEFS_FILE and
- XEMACS_LOADDEFS_PKG_NAME.
- (MH-E-LOADDEFS-SRC): New variable which is set to $(MH-E-SRC) on
- GNU Emacs, and adds $(MH-E-XEMACS-SRC) on XEmacs.
- (all): Modify EMACS_EXPORT_MH_LOADDEFS and MH-E-LOADDEFS-SRC on
- XEMacs.
- (mh-loaddefs.el): Now depends on $(MH-E-LOADDEFS-SRC) and has
- generic compile command that works on both GNU Emacs XEmacs.
- (xemacs): Depend on autoloads instead of deleted loaddefs-xemacs.
- (loaddefs-xemacs): Deleted.
-
-2005-08-10 Lars Hansen <larsh@soem.dk>
-
- * mh-e.el: Add handler to desktop-buffer-mode-handlers.
- (mh-restore-desktop-buffer): Remove autoload cookie.
- (mh-folder-mode): Add autoload cookie.
-
-2005-07-19 Bill Wohler <wohler@newt.com>
-
- * README (INSTALL): Added info for Mac users.
-
-2005-07-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-font-lock-field-data): Fix a bug where the
- function would return t but match-data was being set to nil
- (closes SF #1241017).
-
-2005-07-12 Jeffrey C Honig <jch@honig.net>
-
- * mh-customize.el (mh-invisible-header-fields-internal)
- (mh-invisible-header-fields-internal): Add Received-SPF header and
- X-Gmail- prefixes seen from Gmail.
-
-2005-06-08 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-auto-fields): Insert identity regardless of
- whether one was already set, since if one used a default identity
- it would never be overridden (closes SF #1204506).
-
-2005-06-02 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-customize): Use customization group mh-e.
-
- * mh-init.el (mh-path): Use customization group mh-e. Thanks to
- Peter Whaite for these patches (closes SF #1213716).
-
-2005-06-01 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-compose-forward): Only use mh-sent-from-msg as a
- default message if it's a number (as is done elsewhere).
- Otherwise, an error is thrown if this function is called from a
- draft created by mh-forward since this variable is a list. Also
- added a space after the "Messages [%s]:" prompt.
-
-2005-05-30 Jeffrey C Honig <jch@honig.net>
-
- * mh-mime.el (mh-compose-forward): Allow insertion of multiple
- forwarded messages by range (including sequences). For the sent
- folder the default message presented is the sent message. For
- other folders, the default message is "cur", if it exists.
-
-2005-05-28 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Added +cvs to version.
-
-2005-05-28 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.84.
-
- * MH-E-NEWS, README: Updated for release 7.84.
-
- * mh-e.el (Version, mh-version): Updated for release 7.84.
-
-2005-05-28 Bill Wohler <wohler@newt.com>
-
- * mh-e.el, mh-comp.el: Don't autoload Info-goto-node. It's not
- used, and if it were, the code should use the info function
- instead.
-
- Use full year in copyright notices (for example, 2005, not 05).
-
- * Makefile (mh-loaddefs.el, mh-e-autoloads.el): Added 2005 to
- copyright notice.
-
- * mh-inc.el: Use three ;;; to precede Local Variables to be
- consistent with other files. Will have to ask Stefan Monnier why
- he changed it.
-
- * README: This version of MH-E to appear in GNU Emacs 22.1, not
- 21.5.
-
- * ChangeLog: The * in a ChangeLog entry must only be used before a
- filename.
-
- Fixed compilation warnings in CVS Emacs. This included using
- "public" functions instead of "private" ones (info instead of
- Info-goto-node, view-mode-enter instead of view-mode), and
- removing a customization group that didn't have a parent group. In
- addition, string-to-int was recently deprecated; use
- string-to-number instead.
-
- * mh-customize.el (Info-goto-node): Deleted autoload.
- (mh-e): Deleted mh group. Use single mh-e group instead.
- (mh-tool-bar-folder-help, mh-tool-bar-letter-help): Use info
- instead of Info-goto-node.
-
- * mh-e.el (mh-read-msg-list): string-to-int deprecated; use
- string-to-number.
-
- * mh-funcs.el (mh-list-folders): Use view-mode-enter instead of
- view-mode.
-
- * mh-seq.el (mh-list-sequences): Use view-mode-enter instead of
- view-mode.
-
- * mh-utils.el (mh-get-msg-num): string-to-int deprecated; use
- string-to-number.
-
- Merged in changes from CVS Emacs including:
-
- * mh-utils.el (mh-show-mode):
- * mh-pick.el (mh-pick-mode): Remove spurious run-hooks. Lute
- Kamstra <lute@gnu.org> 2005-05-26.
-
-2005-05-25 Bill Wohler <wohler@newt.com>
-
- Merged in changes from CVS Emacs including:
-
- * mh-customize.el (mh-speedbar-selected-folder-face): Special case
- high number of colors displays. Dan Nicolaescu <dann@ics.uci.edu>
- 2005-04-08.
-
- * mh-e.el, mh-identity.el, mh-mime.el: Replace `legal' with
- `valid'. Replace `illegal' with `invalid'. Werner Lemberg
- <wl@gnu.org> 2005-03-25.
-
- * mh-inc.el (mh-inc-spool-list): Correctly declare the external
- var. Stefan <monnier@iro.umontreal.ca> 2004-09-07.
-
-2005-05-18 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-reply): Mention use of mh-repl-group-formfile in
- docstring.
-
-2005-05-05 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Added +cvs to release number.
-
-2005-05-05 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.83.
-
- * MH-E-NEWS, README: Updated for release 7.83.
-
- * mh-e.el (Version, mh-version): Updated for release 7.83.
-
-2005-05-05 Bill Wohler <wohler@newt.com>
-
- * README: To appear in Emacs 21.5, since 21.4 was released (but
- without the latest MH-E).
-
- * release-utils (usage): Added --variable-changes.
-
-2005-05-04 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (*-face): Made docstrings consistent.
-
- * mh-seq.el (mh-pick-args-list): Extracted function for turning
- string of pick arguments to list. Fixed list so that multi-word
- arguments were put in a single string (closes SF #1122655).
- (mh-edit-pick-expr): Use it.
-
- * mh-unit.el (mh-unit): Since 21.4 sneaked out but didn't contain
- updated lm-verify, don't run lm-verify on versions before 21.5.
- (mh-unit-test-pick-args-list): Added.
-
- * mh-customize.el (mh-yank-from-start-of-msg): Use headline
- capitalization. Changed wording of some choices to be more consistent.
- (mh-invisible-header-fields-internal): Added fields from usa.net.
-
-2005-04-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-mime-security-button-face): New function which
- determines the face to use to colorize encrypted or signed emails.
- (mh-insert-mime-security-button): Modified to colorize the button
- differently based on whether the signature was valid or not,
- whether the decryption was successful or not, etc.
-
- * mh-customize.el (mh-show-pgg-good-face)
- (mh-show-pgg-unknown-face, mh-show-pgg-bad-face): Faces added to
- highlight buttons introduced for encrypted or signed MIME parts.
-
-2005-03-19 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-mml-method-default): Sorted alphabetically.
- (mh-insert-x-mailer-flag, mh-reply-show-message-flag): Moved from
- mh-letter group to mh-sending-mail group. The writing of the
- documentation revealed that these options were misplaced.
-
-2005-03-17 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-junk-background): Put in alphabetical order.
- Synced with manual.
- (mh-junk-program): Use double-quotes on non-symbols.
-
- * mh-pick.el (mh-search-folder): Synced docstrings with manual.
-
- * mh-index.el (mh-index-search, mh-pick-execute-search)
- (mh-grep-execute-search, mh-mairix-execute-search)
- (mh-swish-execute-search, mh-swish++-execute-search)
- (mh-namazu-execute-search): Synced docstrings with manual. Note
- that I'm now grabbing the output of an Info buffer which is why
- the indents on the examples has changed a bit. If we all use that
- methodology in the future, we shouldn't produce as many gratuitous
- diffs. I also noticed that `grep' and `search' became links to
- unrelated things, so let's use double-quotes for quoting
- non-symbols in the docstrings.
-
- * mh-customize.el (mh-index-new-messages-folders)
- (mh-index-ticked-messages-folders): Synced docstrings with manual.
-
-2005-02-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-swish-execute-search): Simplify the indexing
- recipe for swish. Thanks to Eric Jensen for the suggestion.
-
-2005-02-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-swish-execute-search)
- (mh-swish++-execute-search): Make the indexing recipes better.
- (mh-swish-next-result): The indexer might find matches in files
- that aren't messages. Make the function handle that case
- gracefully.
-
-2005-02-07 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-inc-prog, mh-inc-spool-list): Synced
- docstrings with manual.
-
-2005-02-06 Bill Wohler <wohler@newt.com>
-
- * mh-junk.el (mh-spamassassin-blacklist): Removed trailing
- whitespace.
-
- * mh-e.el (mh-refile-or-write-again): Checkdoc fix.
-
- * mh-identity.el (mh-identity-list-set)
- (mh-identity-field-handler, mh-identity-handler-gpg-identity)
- (mh-identity-handler-signature)
- (mh-identity-handler-attribution-verb)
- (mh-identity-handler-default, mh-identity-handler-top): Docstring
- editing.
-
- * mh-customize.el (mh-identity-list, mh-auto-fields-list)
- (mh-identity-default, mh-identity-handlers): Synced docstrings
- with manual.
-
-2005-02-03 Bill Wohler <wohler@newt.com>
-
- * mh-xemacs.el (define-behavior 'mh): Moved Ben's code here from
- mh-e.el and added standard documentation.
-
- * mh-e.el: Received patch from Ben Wing <ben@666.com> to add
- define-behavior on XEmacs.
-
-2005-01-28 Jeffrey C Honig <jch@honig.net>
-
- * mh-customize.el (mh-invisible-header-fields-internal): Added
- X-Evolution header added by Evolution mai client.
-
-2005-01-18 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-invisible-header-fields-internal): Added
- DomainKey-Signature (http://antispam.yahoo.com/domainkeys/).
- There's a Comment field that goes with it, but I thought it was
- too general to add.
-
-2005-01-06 Bill Wohler <wohler@newt.com>
-
- * mh-junk.el (mh-spamassassin-blacklist): Fixed typo to fix an
- error when junking spamassassin mail when mh-junk-background is
- turned on.
-
-2004-12-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-unquote-From): Make the buffer writable
- before trying to change it (closes SF #1089870).
-
- * mh-comp.el (mh-complete-word): Fix a typo in a variable
- name (closes SF #1089870)
-
-2004-11-28 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-complete-word): Kill the *Completions* buffer in
- any cases where we believe we are done with it. Not perfect, but
- better than just leaving it around.
-
-2004-11-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-acros.el (mh-funcall-if-exists): In XEmacs, presence of a
- function at compile time doesn't guarantee its existence at run
- time. So make the macro handle that situation better.
-
-2004-11-05 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-acros.el (advice): Load advice, since it isn't loaded in
- XEmacs causing compilation problems.
-
-2004-10-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-mairix-execute-search)
- (mh-mairix-regexp-builder): Update the interface to mairix so that
- it will work with versions of mairix 0.12 and later.
-
- * mh-funcs.el (mh-rmf-daemon): Avoid using
- beginning-of-buffer since it clobbers the mark and it was pointed
- out on the Emacs developers list to be the wrong thing to do.
-
- * mh-e.el (mh-inc-folder): Only remove the window on the show
- buffer. This means if the user has BBDB enabled then the window
- displaying BBDB information isn't clobbered.
- (mh-refile-or-write-again): Don't use the function
- interactive-p. There was a long thread on the Emacs developers
- list where it was pointed out that it is incorrect to use this
- function most of the time.
-
- * mh-comp.el (autoload): Don't set auto-mode-alist. This could
- screw things up for users that don't use MH-E (closes SF #1032353).
-
-2004-10-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-refile-or-write-again): Generalize the function to
- work on a range of messages (closes SF #1046330).
-
-2004-09-02 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-process-commands): The concurrent execution of mark
- and refile can cause problems since both the commands change the
- current folder. This change avoids that by getting rid of the
- concurrency. Another change covers the corner case where we refile
- messages to a previously empty folder. Before the modification
- sequences weren't preserved even if the appropriate flag was
- set. That is no longer the case.
-
-2004-08-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-get-new-mail): Also, update the unseen sequence from
- disk. Otherwise, the new messages aren't highlighted.
-
- * mh-seq.el (mh-thread-inc): Fix a bug which appears when inc is
- run in a narrowed folder. The user sequence notation was getting
- lost. The change fixes that.
-
- * mh-e.el (mh-get-new-mail): Make inc more efficient by reusing
- the existing user sequence notation and deleted/refiled notation.
-
-2004-08-24 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Added +cvs to release number.
-
-2004-08-24 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.82.
-
- * MH-E-NEWS, README: Updated for release 7.82.
-
- * mh-e.el (Version, mh-version): Updated for release 7.82.
-
-2004-08-24 Bill Wohler <wohler@newt.com>
-
- * mh-init.el (mh-variant-set): Change MH to mh as that's what is
- emitted by `mh-variant-mh-info' (closes SF #1014781).
- (mh-variant-p): Add mu-mh to docstring.
-
-2004-08-23 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-acros.el (mh-require-cl): Remove unneeded autoloads.
- (require): Add an advice to the function so that at compile time
- the uncompiled file is loaded. This avoids compilation problems
- when built in the Emacs tree.
-
- * mh-mime.el (mh-identity-pgg-default-user-id): Defvar the
- variable, to avoid compiler warnings.
-
- * mh-e.el (mh-seq): Load mh-seq since functions defined there are
- used here. Without this, the state mh-seq.elc would be loaded.
-
- * mh-customize.el (mh-init, mh-identity): Load mh-init and
- mh-identity at compile time manually, before the corresponding
- stale elc files get autoloaded.
-
-2004-08-21 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to release number.
-
-2004-08-21 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.81.
-
- * MH-E-NEWS, README: Updated for release 7.81.
-
- * mh-e.el (Version, mh-version): Updated for release 7.81.
-
-2004-08-21 Bill Wohler <wohler@newt.com>
-
- * release-utils (variable_changes): Check for checked-out
- directory before proceeding. Remove temporary files.
- Rename --variable-update flag to --variable-changes.
-
-2004-08-16 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-toggle-mh-decode-mime-flag: New function.
- * mh-e.el (mh-help-messages): Add [;] help string for it.
- (mh-folder-mode-map): Add ";" key binding for it.
-
-2004-08-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-acros.el (mh-defstruct): Distinguishing structures created
- by mh-defstruct just based on the number of fields is not
- sufficient, since both the mh-thread-message and
- mh-thread-container structures have the same length.
-
-2004-08-15 Mark D. Baushke <mdb@gnu.org>
-
- * mh-customize.el (mh-identity-handlers): Use ":default" instead of
- "default" to avoid problems with "Default:" as a user defined field.
- * mh-identity.el (mh-identity-field-handler): Ditto.
-
-2004-08-15 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Added +cvs to release number.
-
-2004-08-15 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.4.80.
-
- * MH-E-NEWS, README: Updated for release 7.4.80.
-
- * mh-e.el (Version, mh-version): Updated for release 7.4.80.
-
-2004-08-15 Bill Wohler <wohler@newt.com>
-
- * mh-funcs.el, mh-gnus.el, mh-inc.el, mh-init.el, mh-junk.el,
- mh-pick.el, mh-print.el, mh-xemacs.el: Added 2004 to Copyright.
-
- * mh-acros.el, mh-alias.el: Checkdoc fixes.
-
-2004-08-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-acros.el (cl): Load cl in this file. That is all right, since
- this file is only used at compile time, and so cl doesn't get
- loaded at run time. This avoids problems with stale *.elc files
- present in the Emacs source tree during compilation.
- (mh-defstruct): Modify it to make it more CL like and in the
- process simplify it a bit. This makes the argument list of the
- constructor compatible with the previous version, thereby avoiding
- a compilation error when an old version of mh-seq.elc is present.
-
- * mh-seq.el (mh-thread-id-container, mh-thread-get-message)
- (mh-thread-get-message-container): Revert back to the CL style
- of using keyword arguments, since the mh-defstruct now produces
- code compatible to such usage.
-
-2004-08-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-acros.el (mh-defstruct, mh-require-cl): Checkdoc fixes.
-
- * mh-utils.el (message-tokenize-header, message-fetch-field): Add
- autoloads.
- (mh-folder-completing-read): Make the folder completion look
- better with CVS Emacs.
-
- * mh-init.el (mh-variant-set): Remove dead code.
-
-2004-08-11 Bill Wohler <wohler@newt.com>
-
- * *.el: Use the following at the top of each file which seems to
- do a good job of suppressing compilation warnings in 21.3 and CVS
- Emacs (21.4). This replaces (require 'cl) or (require
- 'utils) (mh-require-cl) calls:
-
- (eval-when-compile (require 'mh-acros))
- (mh-require-cl)
-
-2004-08-10 Bill Wohler <wohler@newt.com>
-
- * release-utils (DESCRIPTION): Added one.
- (FILES, SEE ALSO, VERSION): Deleted empty and incorrect sections.
-
- * mh-e.el (mh-colors-available-p): Call x-display-color-cells with
- mh-funcall-if-exists since it no longer seems to be defined in
- GNU Emacs 21.4.
-
-2004-08-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-process-kill-without-query, mh-speed-flists):
- Avoid a compiler warning in versions of Emacs where
- process-kill-without-query is a deprecated function.
-
- * mh-seq.el (mh-thread-message, mh-thread-container): Use
- mh-defstruct instead of defstruct.
- (mh-thread-id-container, mh-thread-get-message-container)
- (mh-thread-get-message): Use the slightly different structure
- constructor function.
-
- * mh-acros.el (mh-defstruct): New macro which is a partial
- replacement of the defstruct in CL.
- (no-byte-compile): Don't compile the file since it isn't loaded at
- run time, so efficiency isn't an issue.
-
- * mh-utils.el (mh-buffer-data): Use mh-defstruct instead of
- defstruct.
-
-2004-08-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-funcs.el, mh-junk.el, mh-print.el: Use mh-require-cl to avoid
- compilation warnings in Emacs-21.3.
-
- * mh-acros.el (mh-require-cl): Add autoloads of CL functions used.
-
-2004-08-09 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-show-use-xface-flag): Mention that `fetch' and
- `curl' are supported as well.
-
-2004-08-08 Bill Wohler <wohler@newt.com>
-
- * mh-xemacs.el (mh-xemacs-has-toolbar-flag): Checkdoc fixes.
-
- * mh-mime.el (mh-display-with-external-viewer): Checkdoc fixes.
-
- * mh-identity.el (mh-identity-attribution-verb-end): Stripped
- trailing space; checkdoc fixes.
-
- * mh-e.el (mh-restore-desktop-buffer): Checkdoc fixes.
-
- * mh-customize.el (mh-inc-spool-list)
- (mh-compose-forward-as-mime-flag, defcustom): Stripped trailing
- space; checkdoc fixes.
-
- * mh-comp.el (mh-reply): Stripped trailing space.
-
- * mh-unit.el (mh-unit-files): Added mh-acros.el and mh-gnus.el.
- (mh-unit): Don't lm-verify pre-21.4. Save buffers before killing
- since we might have done some editing.
-
- * import-emacs: Deleted. Functionality subsumed by release-utils.
-
- * release-utils: New script. Performs import-emacs functionality
- and displays new and deleted options.
-
- * Makefile (import-emacs): Call release-utils instead of
- import-emacs.
-
- * mh-funcs.el (mh-undo-folder): Removed deprecated `ignore'
- argument.
-
- * mh-e.el (mh-scan-date-regexp): Deleted as Peter claims it is
- obsolete.
- (mh-folder-font-lock-keywords): Removed reference to deleted
- variable `mh-scan-date-regexp'.
-
- * mh-customize.el (mh-auto-fields-prompt-flag): Made reference to
- `mh-auto-fields-lists'.
- (mh-forward-hook): Fixed docstring typo.
-
-2004-08-07 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el: New file. Currently holds macros needed by
- mh-customize.el but is planned to hold all macros to avoid
- dependency problems when compiling.
-
- * mh-utils.el (mh-xemacs-flag): Defined in mh-customize.el now.
- (mh-require-cl, mh-do-in-gnu-emacs, mh-do-in-xemacs)
- (mh-funcall-if-exists, mh-make-local-hook, mh-mark-active-p):
- Moved to new file mh-acros.el.
-
- * mh-customize.el: Require mh-acros and cl only when compiling and
- mh-loaddefs at runtime instead of mh-utils.
- (mh-xemacs-flag): Define it here instead of mh-utils.el.
-
- * Makefile (MH-E-SRC): Added mh-acros.el.
-
- * mh-gnus.el (default-enable-multibyte-characters): Don't define
- any more. It doesn't seem to be needed.
-
- * mh-customize.el (mh-junk-background): New variable. If on, spam
- programs are run in background. Running in foreground can be slow.
- Defaults to nil to spare machines with little memory.
-
- * mh-junk.el (mh-spamassassin-blacklist, mh-bogofilter-blacklist)
- (mh-bogofilter-whitelist, mh-spamprobe-blacklist)
- (mh-spamprobe-whitelist): Use new option mh-junk-background.
-
-2004-07-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-folder-completing-read): In recent CVS Emacs,
- the first letter of the possible choices in the completion buffer
- is highlighted. The change is needed for this feature to work
- during folder name completion. This is not entirely sufficient,
- since the leading "+" in folder names is still mishandled. A patch
- is required in Emacs itself to address that.
-
-2004-07-22 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (recursive-load-depth-limit): Move
- recursive-load-depth-limit code to ...
- * mh-utils.el (recursive-load-depth-limit): ... here to avoid
- problems compiling mh-utils.el and mh-alias.el with gnus-5.10.6
- under emacs-21.1. Use eval-and-compile instead of eval-when.
-
-2004-07-20 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-invisible-header-fields-internal): Added
- header fields emitted by T-Mobile picture phones (X-Mms-*, and
- commented out X-Operator field saying it's like X-Mailer).
-
-2004-07-12 Bill Wohler <wohler@newt.com>
-
- * mh-gnus.el: Set local variables indent-tabs-mode and
- sentence-end-double-space to nil.
-
- * mh-customize.el: Checkpoint from option docstring updates and
- manual synchronization from last summer. For the options listed
- below, docstring was usually completely rewritten. Use "on"
- instead of "t" in docstring to match what is seen in customization
- buffer. Use headline capitalization. Standardize on "Auto-detect"
- text when option has that capability.
- (mh): Since we work on more than one type of Emacs, use Emacs
- instead of GNU Emacs. Prefer GNU mailutils over GNU Mailutils.
- (mh-variant): s/Autodetect at startup/Auto-detect/.
- (mh-alias-insertion-location): s/Sorted
- alphabetically/Alphabetical/. s/At the top of file/Top/. s/At the
- bottom of file/Bottom/.
- (mh-alias-local-users-prefix): s/Use login instead of real
- name/Use Login/.
- (mh-identity-list): Sorted values by fields, attribution,
- signature, GPG key.
- (mh-auto-fields-list): Missing quote.
- (mh-compose-insertion): s/Use Gnus/Gnus/. s/Use mhn/mhn/.
- (mh-compose-space-does-completion-flag): s/SPACE/<SPC>/.
- (mh-extract-from-attribution-verb): Since we have French, added
- German too ;-).
- (mh-letter-complete-function): Mention default in docstring.
- (mh-invisible-header-fields-internal): Added X-ELNK-Trace from
- Earthlink.
- (mh-alias-flash-on-comma, mh-alias-insert-file)
- (mh-alias-passwd-gecos-comma-separator-flag)
- (mh-recenter-summary-flag, mh-default-folder-for-message-function)
- (mh-default-folder-must-exist-flag, mh-index-program)
- (mh-index-ticked-messages-folders, mh-ins-buf-prefix)
- (mh-delete-yanked-msg-window-flag, mh-identity-default): See
- summary above.
-
- * mh-init.el (mh-variant-set, mh-sys-path, mh-variant-mu-mh-info):
- Prefer GNU mailutils over GNU Mailutils MH.
-
- * mh-comp.el (sc-cite-original, mh-smail, mh-smail-batch)
- (mh-edit-again, mh-extract-rejected-mail, mh-forward)
- (mh-smail-other-window, mh-reply, mh-send, mh-send-other-window):
- Use `mh-send' instead of \\[mh-send]] since links in the docstring
- are more useful than a key sequence in these cases. Use "See also"
- instead of "See also documentation for".
-
- Merged in 7.4.4 changes, described below.
-
- * mh-e.el (Version, mh-version): Set to 7.4.4+cvs.
-
-2004-07-10 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.4.4.
-
- * MH-E-NEWS, README: Updated for release 7.4.4.
-
- * mh-e.el (Version, mh-version): Updated for release 7.4.4.
-
- This patch release contains the following patches:
-
- * mh-xemacs.el: New file from concatenation of mh-xemacs-compat.el
- and mh-xemacs-icons.el which were removed since their names
- exceeded DOS 8+3 limits.
-
- * Makefile:
- (mh-e-autoloads.el): Add target to make `mh-e-autoloads.el', a
- file containing usual entry commands into MH-E to be used for users
- installing MH-E separately from Emacs.
- (XEMACS_LOADDEFS_FILE): New. Used to generate mh-loaddefs.el
- in XEmacs.
- (XEMACS_LOADDEFS_COOKIE): Ditto.
- (XEMACS_LOADDEFS_PKG_NAME): Ditto.
- (XEMACS_OPTIONS): Add '-no-autoloads' to give a cleaner build
- environment.
- (MH-E-SRC): Moved mh-xemacs.el to new variable MH-E-XEMACS-SRC.
- (MH-E-XEMACS-SRC): New variable to hold XEmacs source files.
- (MH-E-XEMACS-OBJ): New variable to hold XEmacs object files.
- (clean): Moved XEmacs-specific code to clean-xemacs.
- (xemacs): Added clean-xemacs prerequisite. Moved down to XEmacs
- section of file. Add target to build mh-loaddefs.el in XEmacs.
- (loaddefs-xemacs): New rule to build mh-loaddefs.el in XEmacs.
- (clean-xemacs): New target to remove XEmacs-specific files.
- (compile-xemacs): New. It allows for the '-no-autoloads' option
- and byte-compiles all the source files with a single instance of
- XEmacs.
- (dist): Added $(MH-E-XEMACS-SRC) to tarball.
- (AUTO_PRELOADS): Removed, in favor of 'AUTOLOAD_PACKAGE_NAME' and
- 'AUTOLOAD_FILE'.
- (AUTOLOAD_PACKAGE_NAME): New.
- (AUTOLOAD_FILE): New.
- (all): Don't set $EMACS_HOME if building with XEmacs.
- (xemacs): Use 'compile-xemacs' instead of 'compile'.
- (auto-autoloads.elc): Use new $AUTOLOAD_* vars and allow for
- '-no-autoloads'.
- (custom-load.elc): Allow for '-no-autoloads'.
-
- * mh-e.el: Don't require mh-xemacs-compat which no longer exists.
- The XEmacs stuff gets required by mh-customize.el which is
- required by mh-utils.el which is required by mh-e.el. This all
- happens before mh-xemacs-compat was required, so all should be
- well.
- (mh-restore-desktop-buffer): Move from desktop.el. Add Parameters.
- (mh-restore-desktop-buffer): Delete with-no-warnings.
- (mh-folder-mode): Bind desktop-save-buffer to t.
- (Courtesy Lars Hansen).
-
- * mh-alias.el (mh-assoc-ignore-case): New macro to use
- assoc-string when available (Emacs 21.4+); assoc-ignore-case
- otherwise.
- (mh-alias-reload, mh-alias-expand,
- mh-alias-minibuffer-confirm-address): Use it.
-
- * mh-seq.el: Added mh-autoload to mh-read-seq-default.
-
- * mh-utils.el (mh-require-cl): The Emacs coding conventions
- require that the cl package not be required at runtime. However,
- the cl package in versions of Emacs prior to 21.4 left cl routines
- in their macro expansions. Use mh-require-cl to provide the cl
- routines in the best way possible (closes SF #930012).
- (require 'mouse): To shush compiler.
-
- Use new function mh-require-cl throughout.
-
- Add arch taglines (courtesy Miles Bader).
-
- * mh-unit.el (mh-unit-files): Replaced mh-xemacs-compat.el and
- mh-xemacs-icons.el with mh-xemacs.el.
-
- * import-emacs: Also grab the ChangeLog.
-
- * *.pbm: Regenerated using GIMP to be consistent with other Emacs
- icons.
- 1. Edit .xpm image in GIMP.
- 2. Image > Mode > Indexed. Check Use Black/White Palette and No
- Color Dithering.
- 3. File > Save As file.xbm.
- 4. Run xbmtopbm < file.xbm > file.pbm.
- Thanks to jan.h.d@swipnet.se for the help.
-
-2004-07-07 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-customize.el (mh-invisible-header-fields-internal):
- Add X-Greylist, X-Source*, and X-WebTV-Signature.
- Replace specific X-Spam-* headers with general pattern.
-
-2004-06-15 Bill Wohler <wohler@newt.com>
-
- * README: Vladimir Ivanovic reports that mh-rmail works with
- XEmacs 21.5.17, so updated requirements text accordingly (closes
- SF #644321).
-
-2004-05-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-mail-header-end): Replace call to
- rfc822-goto-eoh with something that allows From_ lines in the mail
- header.
-
-2004-04-26 Lars Hansen <larsh@math.ku.dk>
-
- * mh-e.el (mh-folder-mode): Bind desktop-save-buffer to t.
-
-2004-04-22 Lars Hansen <larsh@math.ku.dk>
-
- * mh-e.el (mh-restore-desktop-buffer): Delete with-no-warnings.
-
-2004-04-21 Lars Hansen <larsh@math.ku.dk>
-
- * mh-e.el (mh-restore-desktop-buffer): Move from desktop.el.
- Add Parameters.
-
-2004-04-14 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-show-mouse): s/EVENT/event/. Thanks to John Paul
- Wallington <jpw@gnu.org> for pointing this out.
-
-2004-04-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-folder-size-flist): Add -showzero option so that the
- parsing code doesn't get confused by the presence of -noshowzero
- in the user's .mh_profile (closes SF #933954).
-
-2004-04-07 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-insert-mime-button)
- (mh-insert-mime-security-button): Add evaporate property to
- overlays used in MIME part buttons. This avoids problems with
- CVS Emacs.
-
-2004-03-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-folder-from-address): Go to the end of buffer if the
- re-search-forward fails (closes SF #917096).
-
-2004-02-02 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-compose-forward-as-mime-flag): New user
- customizable variable that controls whether messages are forwarded
- as MIME attachments (closes SF #827203).
-
- * mh-comp.el (mh-forward): Call forw with -mime option only if
- mh-compose-forward-as-mime-flag is non-nil.
-
-2003-12-26 Jeffrey C Honig <jch@honig.net>
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist)
- (mh-spamassassin-blacklist, mh-spamassassin-blacklist)
- (mh-spamassassin-blacklist, mh-spamassassin-whitelist)
- (mh-spamassassin-whitelist, mh-bogofilter-blacklist)
- (mh-spamprobe-blacklist): Add progress messages. Change "Couldn't"
- to "Unable" in error messages. Run bogofilter and spamprobe in
- the foreground to prevent a large number of processes from
- swamping the system.
-
-2003-12-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-prompt-for-refile-folder): Marking the whole folder
- and then refiling all messages throws an error, since this
- function expects point to be on a valid scan line. The change
- relaxes this requirement, thereby avoiding the above problem.
-
-2003-12-14 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-ascii-buffer-p): New function that checks if a
- buffer is entirely composed of ASCII.
- (mh-send-letter): Encode the draft if it contains non-ASCII
- characters.
-
-2003-12-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-invisible-headers): Keep only unique fields
- in list of header fields to hide. This avoids problems in XEmacs.
-
-2003-12-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-print-scan-lines): The imenu index was not
- getting created for threaded index buffers. The change fixes this.
-
- * mh-index.el (mh-index-insert-folder-headers): Always create the
- imenu index.
- (mh-index-create-imenu-index): Set which-func-mode to t. If
- which-function-mode is turned on after the folder buffer has been
- prepared, display of the folder info was being inhibited. The
- change fixes that.
-
-2003-12-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-mode): Setup mh-mail-header-separator
- based on draft contents.
- (mh-letter-mode, mh-letter-mail-header-end-marker)
- (mh-letter-header-end): Remove use of the variable
- mh-letter-mail-header-end-marker. Instead use
- mh-mail-header-separator. This avoids problems in font locking
- draft buffers (closes SF #855479).
-
-2003-12-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-insert-folder-headers): Modified so that
- imenu--index-alist is updated.
- (mh-index-create-imenu-index): New function that generates an
- index usable by imenu. This adds which-func-mode support to index
- folders (closes SF #855520).
-
- * mh-e.el (which-func, which-func-modes): Tell which-func that
- mh-folder-mode supports it.
- (mh-folder-mode): Add support for imenu.
-
-2003-11-22 Peter S Galbraith <psg@debian.org>
-
- * Makefile: renamed mh-startup.el to mh-e-autoloads.el
-
- * README: renamed mh-startup.el to mh-e-autoloads.el
-
- * .cvsignore: Added mh-e-autoloads.el
-
-2003-11-18 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.4.3.
-
- * MH-E-NEWS, README: Updated for release 7.4.3.
-
- * mh-e.el (Version, mh-version): Updated for release 7.4.3.
-
- This patch release contains the following two patches:
-
- * mh-identity.el (mh-identity-make-menu): Removed condition on
- mh-auto-fields-list. Use it to enable or disable menu item
- instead.
-
- * mh-customize.el (mh-identity-list): Removed defvar and moved
- defcustom before mh-auto-fields-list so that defvar wouldn't
- clobber user's customization settings.
-
-2003-11-17 Jeffrey C Honig <jch@honig.net>
-
- * mh-print.el (mh-print-msg): Do not print a message on deprecated
- usage, the bindings have been removed.
-
- * mh-e.el (mh-folder-mode-map): Remove "l" binding for
- mh-print-msg.
-
- * mh-utils.el (mh-show-mode-map): Remove "l" binding for
- mh-print-msg.
-
-2003-11-16 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-beginning-of-word): Use the function
- mh-mail-abbrev-make-syntax-table instead of the function
- mail-abbrev-make-syntax-table.
-
- * mh-gnus.el (mh-mail-abbrev-make-syntax-table): Add a wrapper
- function that calls mail-abbrev-make-syntax-table if available.
- This is needed so that MH-E built with CVS Emacs will work with
- released versions of Emacs21 and vice versa.
-
-2003-11-14 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-invisible-header-fields-internal): Add
- "X-NAI-Spam-" and "X-Spam-Report:".
-
-2003-11-14 Mark D. Baushke <mdb@gnu.org>
-
- * mh-customize.el (mh-invisible-header-fields-internal):
- Add X-AntiAbuse and X-MailScanner.
- (Patch from Stephen Gildea.)
-
-2003-11-13 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-identity-handler-attribution-verb): New
- function. A new Identity handler for the attribution verb (e.g.
- "wrote:") to allow for different identities to use different
- languages.
- (mh-identity-insert-attribution-verb): New function. Insert the
- attribution verb, placing special markers so it can be deleted and
- replaced later.
- (mh-identity-attribution-verb-start): New variable. Holds the
- marker for the start of the attribution verb.
- (mh-identity-attribution-verb-end): New variable. Holds the
- marker for the end of the attribution verb.
-
- * mh-customize.el (mh-identity-handlers): Add new
- ":attribution-verb" tag for the attribution-verb handler.
- (mh-identity-list): Idem.
-
- * mh-comp.el (mh-yank-cur-msg): Insert attribution verb using
- mh-identity-insert-attribution-verb.
- (mh-extract-from-attribution): Extract only the name from the From
- line, without appending `mh-extract-from-attribution-verb' since
- markers need to be inserted around that now.
-
-2003-11-12 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-rmail, mh-nmail): Well, actually, we run in both GNU
- Emacs and XEmacs, so removed the "GNU" in the docstrings unless
- one is strictly talking about GNU Emacs.
-
- * mh-comp.el (mh-smail, mh-smail-batch, mh-smail-other-window):
- Ditto.
-
-2003-11-11 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-customize): Minor docstring change.
- (mh, mh-e): The short description for MH-E is: The GNU Emacs
- Interface to the MH Mail System. Therefore, updated docstrings
- accordingly.
-
- * mh-comp.el (mh-smail, mh-smail-batch, mh-smail-other-window):
- Ditto.
-
- * mh-e.el (mh-rmail, mh-nmail): Ditto.
-
-2003-11-10 Satyaki Das <satyakid@stanford.edu>
-
- * mh-mime.el (mh-mml-to-mime): In case errors happen in
- mml-to-mime, restore contents of the draft buffer (closes SF
- #839303).
-
-2003-11-07 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-letter-mode-hook): Moved to mh-sending-mail
- group (where it is now documented in the manual).
- (mh-pick-mode-hook): Moved to mh-index group (where it is now
- documented in the manual).
-
- * mh-loaddefs.el: Deleted per our discussion on mh-e-devel. No
- more conflicts! No more check-ins! Anyone pulling CVS MH-E is
- expected to compile. This file shall be added to the tarball so
- that users of the distribution are not.
-
-2003-11-07 Mark D. Baushke <mdb@gnu.org>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-customize.el (mh-forward-hook): Define new hook.
- * mh-comp.el (mh-forward): Use it.
-
-2003-11-07 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-show-toggle-mime-buttons)
- (mh-show-display-with-external-viewer): New interactive functions
- callable from the show buffer.
- (mh-show-mime-map): Add bindings for "K t" and "K e".
- (mh-show-msg): Propagate change to
- mh-display-buttons-for-inline-parts-flag to the show buffer.
-
- * mh-mime.el (mh-display-with-external-viewer): New interactive
- function to display MIME parts with external viewer (closes SF
- #839318).
-
- * mh-e.el (mh-folder-mode): Make the variable
- mh-display-buttons-for-inline-parts-flag buffer-local so that
- display of MIME buttons can be toggled.
- (mh-toggle-mime-buttons): New interactive function to toggle
- display of MIME buttons.
- (mh-mime-map): Modified to add bindings for "K t" and "K e".
-
-2003-11-04 Steve Youngs <sryoungs@bigpond.net.au>
-
- * Makefile (XEMACS_LOADDEFS_FILE): New. Used to generate
- mh-loaddefs.el in XEmacs.
- (XEMACS_LOADDEFS_COOKIE): Ditto.
- (XEMACS_LOADDEFS_PKG_NAME): Ditto.
- (xemacs): Add target to build mh-loaddefs.el in XEmacs.
- (clean-xemacs): Remove `mh-loaddefs.el*'.
- (loaddefs-xemacs): New rule to build mh-loaddefs.el in XEmacs.
-
-2003-11-02 Peter S Galbraith <psg@debian.org>
-
- * mh-init.el (mh-variant-set-variant): Reset `mh-x-mailer-string'
- when we select an MH variant.
-
-2003-11-02 Jeffrey C Honig <jch@honig.net>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-funcs.el (mh-print-msg): Move to mh-print.el.
-
- * mh-e.el (mh-folder-mode-map): Add mh-print-msg ("l") back, it
- will print a message that this usage is deprecated.
-
- * mh-print.el (require, mh-ps-print-msg, mh-ps-print-msg-file):
- Require mh-funcs for mh-note-printed. PS print functions were not
- setting the printed notation. Move mh-print-msg here for
- consistency. Print message if mh-print-msg invoked via deprecated
- key binding.
-
-2003-11-01 Peter S Galbraith <psg@debian.org>
-
- * Makefile: Add target to make `mh-startup.el', a file containing
- usual entry commands into MH-E to be used for users installing
- MH-E separately from Emacs.
-
- * README: Document the above for users.
-
-2003-10-29 Jeffrey C Honig <jch@honig.net>
-
- * mh-utils.el (mh-show-ps-print-map): Add "?" and "l" to
- mh-show-ps-print-map.
-
- * mh-e.el (mh-ps-print-map, mh-help-messages): Add "?" and "l" to
- mh-ps-print-map. Add "l" to help message.
-
-2003-10-27 Bill Wohler <wohler@newt.com>
-
- * Makefile (MH-E-SRC): Moved mh-xemacs.el to new variable
- MH-E-XEMACS-SRC.
- (MH-E-XEMACS-SRC): New variable to hold XEmacs source files.
- (MH-E-XEMACS-OBJ): New variable to hold XEmacs object files.
- (clean): Moved XEmacs-specific code to clean-xemacs.
- (xemacs): Added clean-xemacs prerequisite. Moved down to
- XEmacs section of file.
- (clean-xemacs): New target to remove XEmacs-specific files.
- (compile-xemacs): Added $(MH-E-XEMACS-SRC) prerequisite.
- (dist): Added $(MH-E-XEMACS-SRC) to tarball.
-
-2003-10-27 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-index.el (mh-indexer-choices): Remove option for the non-free
- glimpse indexer (closes SF #831276).
- (mh-glimpse-binary, mh-glimpse-directory)
- (mh-glimpse-execute-search, mh-glimpse-next-result): Functions
- and variables to implement glimpse support are removed.
-
- * mh-customize.el (mh-index-program): Remove option for glimpse.
-
-2003-10-24 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el: Remove top-level test for toolbar enabled
- XEmacs since it is not needed.
- (mh-tool-bar-define): Add test for XEmacs toolbar in the functions
- mh-toolbar-init, mh-tool-bar-letter-buttons-set and
- mh-tool-bar-folder-buttons-set. This enables proper compilation
- irrespective of whether the XEmacs was built with toolbar support
- or not.
-
- * mh-comp.el (mh-letter-mode): Remove conditional since it is not
- needed.
-
- * mh-e.el (mh-folder-mode): Same as above.
-
- * mh-utils.el (mh-show-mode): Same as above.
-
- * mh-xemacs.el (mh-xemacs-icon-map): Remove condition on toolbar
- presence since we want the build to work if XEmacs without
- toolbars is used during compilation.
-
-2003-10-23 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el: The Great Reorganization. Sorted groups
- alphabetically. Aligned variables in customization groups with
- manual sections. Group docstrings changed to match manual chapter
- titles.
-
-2003-10-22 Satyaki Das <satyakid@stanford.edu>
-
- * mh-speed.el (timer): Avoid compiler warning in XEmacs.
-
-2003-10-22 Steve Youngs <sryoungs@bigpond.net.au>
-
- * Makefile (XEMACS_OPTIONS): Add '-no-autoloads' to give a cleaner
- build environment.
- (AUTO_PRELOADS): Removed, in favor of 'AUTOLOAD_PACKAGE_NAME' and
- 'AUTOLOAD_FILE'.
- (AUTOLOAD_PACKAGE_NAME): New.
- (AUTOLOAD_FILE): New.
- (all): Don't set $EMACS_HOME if building with XEmacs.
- (xemacs): Use 'compile-xemacs' instead of 'compile'.
- (auto-autoloads.elc): Use new $AUTOLOAD_* vars and allow for
- '-no-autoloads'.
- (custom-load.elc): Allow for '-no-autoloads'.
- (compile-xemacs): New. It allows for the '-no-autoloads' option
- and byte-compiles all the source files with a single instance of
- XEmacs.
-
- * mh-e.el (mh-folder-mode): Only load the toolbar in XEmacs if
- toolbar support is available.
-
- * mh-comp.el (mh-letter-mode): Only load the toolbar in XEmacs if
- toolbar support is available.
-
- * mh-customize.el: Require 'mh-xemacs' at toplevel when
- 'mh-xemacs-flag' is non-nil.
- Wrap all the toolbar code in a test that is true if using
- GNU/Emacs or a toolbar-enabled XEmacs.
-
- * mh-print.el (mh-ps-spool-a-msg): Comment out
- `clean-message-header-flag' because it isn't used anywhere.
-
- * mh-utils.el (mh-show-mode): Only load the toolbar in XEmacs if
- toolbar support is available.
-
- * mh-xemacs.el: Autoload `regexp-opt', `customize-group',
- `view-mode', `with-electric-help', `pp', `sort-numeric-fields',
- `reverse-region', and `goto-address' at compile time.
- (mh-xemacs-has-toolbar-flag): New. This is non-nil when XEmacs
- has toolbar support.
- (mh-xemacs-toolbar-*-icon): Use it.
-
-2003-10-21 Mark D. Baushke <mdb@gnu.org>
-
- * mh-identity.el (mh-identity-field-handler): Fields that begin
- with ":" must have an mh-identity-handler defined or the user
- gets an error.
-
-2003-10-17 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-identity-list): This change affects users!
- The keyword "signature" becomes ":signature". The recently added
- keyword "pgg-default-user-id" becomes ":pgg-default-user-id".
- (mh-auto-fields-list): The keyword "Identity" becomes ":identity".
- (mh-identity-handlers): Idem for signature and pgg-default-user-id.
-
- * mh-comp.el (mh-insert-auto-fields): Idem for Identity.
-
-2003-10-17 Peter S Galbraith <psg@debian.org>
-
- * mh-xemacs.el: Add eval-and-compile call to (load "toolbar" t t) to
- make sure `toolbar-make-button-list' is defined. We can't use
- require because Emacs doesn't have this library.
-
-2003-10-16 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-signature-file-name)
- (mh-letter-insert-signature-hook): Merge docstring with manual.
-
- * mh-comp.el (mh-file-is-vcard-p): Checkdoc fix.
- (mh-insert-signature): Merge docstring with manual.
-
- * mh-customize.el (mh-junk): Changed manual link in defgroup from
- Customizing mh-e to Junk.
- (mh-junk-function-alist): Moved SpamAssassin to first in list on
- the hunch that it is the most popular and should be chosen if
- other anti-spam programs exist.
- (mh-junk-mail-folder): Since the variable can accept values other
- than folder names, renamed to mh-junk-disposition to more
- accurately reflect the content. Merge docstring with manual.
- (mh-junk-program): Moved SpamAssassin to the top of the menu for
- the same reason presented in mh-junk-function-alist. Also, fixed
- case of spam programs to match official usage. Merge docstring
- with manual.
-
- * mh-junk.el (mh-junk-blacklist):
- s/mh-junk-mail-folder/mh-junk-disposition/. Merge docstring with
- manual.
- (mh-junk-whitelist): Merge docstring with manual.
- (mh-bogofilter-blacklist): No longer suggest using automatic
- classification so use -s instead of -Ns.
- (mh-bogofilter-whitelist): No longer suggest using automatic
- classification so use -n instead of -Sn.
- (mh-spamassassin-blacklist, mh-spamassassin-whitelist): Merge
- docstring with manual. Moved spamassassin functions to top of file
- so functions appear in same order that they are presented in menu.
-
-2003-10-09 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mail-citation-hook): Moved from mh-comp.el and
- made into a defcustom.
-
-2003-10-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-comp.el (mh-get-header-field): Add autoload cookie.
-
- * mh-utils.el (mh-show-ps-print-toggle-mime)
- (mh-show-ps-print-toggle-color, mh-show-ps-print-toggle-faces)
- (mh-show-ps-print-msg-file, mh-show-ps-print-msg)
- (mh-show-ps-print-msg-show): New interactive functions callable
- from the show buffer.
- (mh-show-ps-print-map): New key map for printing.
-
- * mh-e.el (mh-folder-mode-map): Remove key binding for
- mh-print-msg.
- (mh-ps-print-map): Add new key map for printing.
-
- * Makefile (MH-E-SRC): Add mh-print.el.
-
-2003-10-07 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-x-image-url-fetch-image): In XEmacs,
- make-temp-file is not present. So to avoid security problems, use
- a temporary file in the user's home directory. This avoids issues
- in creating files in a world-writable directory.
-
- * mh-mime.el (mh-signature-highlight): In Emacs, arrange for the
- overlay to be freed when it is no longer needed. Also, implement
- signature highlighting in XEmacs.
-
-2003-10-05 Satyaki Das <satyakid@stanford.edu>
-
- * mh-mime.el (mh-mime-display, mh-mm-inline-message): Respect the
- value of `mm-verify-option' and `mm-decrypt-option'.
- (mh-mime-display-security): Rearrange code a bit to avoid too many
- new lines being inserted when message verification/decryption is
- carried out while the message is being read. Also use the
- point-m{in|ax}-marker functions to make the function easier to read.
- (mh-mime-security-press-button): Extend the function so that the
- user can verify/decrypt messages while reading them.
-
- * mh-gnus.el (mm-possibly-verify-or-decrypt): Added to avoid
- compiler warning with old Gnus.
-
- * mh-utils.el (mh-x-image-url-sane-p): New function which checks
- if the URL in X-Image-URL is something we can handle.
- (mh-x-image-url-display): Don't display image if the URL looks
- malformed.
-
-2003-10-04 Mark D. Baushke <mdb@gnu.org>
-
- * mh-comp.el (mh-letter-menu): Simplify menu heading.
-
-2003-10-03 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-mml-query-cryptographic-method): Avoid
- revisionist history and still provide a good default.
-
- * mh-comp.el (mh-letter-menu): Remove the Disable Security
- parenthetical comment.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-customize.el (mh-mml-method-default): What method should be
- used in secure directives.
-
- * mh-mime.el (mh-secure-message): New function used to generate
- the mml security tags.
- (mh-mml-unsecure-message): New wrapper function around
- mml-unsecure-messages.
- (mh-mml-secure-message-sign-pgpmime): Remove function.
- (mh-mml-secure-message-encrypt-pgpmime): Ditto.
- (mh-mml-cryptographic-method-history): New variable.
- (mh-mml-query-cryptographic-method): New function.
- (mh-mml-secure-message-encrypt): Ditto.
- (mh-mml-secure-message-signencrypt): Ditto.
- (mh-mml-secure-message-sign): Ditto.
-
- * mh-comp.el (mh-letter-menu, mh-letter-mode-help-messages)
- (mh-letter-mode-map): Update to use new functions.
-
-2003-09-26 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-interactive-range): The function has been
- extended so that it now takes a default result to return if no
- interactive prefix arg is given and no region is active.
-
- * mh-e.el (mh-add-sequence-notation): If transient-mark-mode is
- on, then the active region is deactivated based on whether a user
- sequence or a internal sequence is being notated. The change
- removes this inconsistency.
- (mh-catchup, mh-folder-map): A new interactive function to mark
- messages as read has been added and bound to "F c" in the folder
- mode.
-
- * mh-utils.el (mh-show-catchup, mh-show-folder-map): New
- interactive function callable from show mode buffers has been
- bound to "F c".
-
-2003-09-24 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-clean-message-header-flag)
- (mh-invisible-header-fields-default, mh-invisible-header-fields):
- Merge docstring with manual.
-
-2003-09-24 Mark D. Baushke <mdb@gnu.org>
-
- * mh-junk.el (mh-junk-blacklist): Junked messages should be put
- into the mh-seen-list to avoid propagating the unseen sequence
- into the spam folder.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-mime.el (mh-mml-secure-message-sign-pgpmime): Add an optional
- dontsign argument to remove an existing secure message directive.
- Update the docstring -- this function does not allow for
- encrypt/sign, just sign directives.
-
- * mh-mime.el (mh-mml-secure-message-sign-pgpmime): Use
- mml-insert-tag directly to provide a sender if
- mh-identity-pgg-default-user-id is set.
- (mh-mml-secure-message-encrypt-pgpmime): Use mml-insert-tag
- directly to provide a sender if this message is to be both signed
- and encrypted and mh-identity-pgg-default-user-id is set.
-
-2003-09-23 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (Commentary): Removed as it is now in the manual.
- (mh-alias-system-aliases): Moved here from mh-customize.el. By
- definition, "system" definitions are not user-visible, and user
- filenames are in the Aliasfile: profile component, so this
- variable really shouldn't be a defcustom.
- (mh-alias-tstamp, mh-alias-filenames, mh-alias-reload)
- (mh-alias-add-alias, mh-alias-grab-from-field)
- (mh-alias-add-address-under-point, mh-alias-apropos): Merge
- docstring with manual.
- (mh-alias-reload-maybe): Minor comment update.
- (mh-alias-insert-file): Merge docstring with manual. Removed
- "[press TAB]" from prompt since users should know about completion
- and space can be used as well.
- (mh-alias-for-from-p): No longer returns a surprising result (t if
- there was **not** an alias for the From field) if the From header
- field is missing. This function now returns what you would expect
- a function of this name to return. Renamed from
- mh-alias-from-has-no-alias-p since negatives in the function name
- make logic harder to follow.
- (mh-alias-add-alias-to-file): Merge docstring with manual.
- Improved verbiage of prompt. Aliases are now inserted "[b]efore"
- or "[a]fter" the existing alias instead of "[i]nsert" or
- "[a]ppend." Note how the new usage flows better.
-
- * mh-customize.el (mh-alias): Changed manual link in defgroup from
- Customizing mh-e to Aliases.
- (mh-alias-grab-from-field button): mh-alias-from-has-no-alias-p
- renamed to mh-alias-for-from-p and no longer returns surprising
- value if there isn't a From field. Therefore, enable button if
- there is a From header field and mh-alias-for-from-p returns nil.
- (mh-letter-complete-function)
- (mh-alias-completion-ignore-case-flag, mh-alias-flash-on-comma)
- (mh-alias-insert-file, mh-alias-insertion-location)
- (mh-alias-local-users, mh-alias-local-users-prefix)
- (mh-alias-passwd-gecos-comma-separator-flag): Merge docstring with
- manual.
- (mh-alias-system-aliases): Moved to mh-alias.el.
-
- * mh-comp.el (mh-letter-complete-function-alist): Removed comment
- about making this customizable since I didn't think it seemed
- appropriate in the manual.
- (mh-letter-complete): Merge docstring with manual.
-
-2003-09-23 Satyaki Das <satyakid@stanford.edu>
-
- * mh-speed.el (mh-speed-flists): When exiting emacs, don't ask if
- the flists process should be killed.
-
- * mh-e.el (mh-folder-message-menu): Enable undo menu entry only
- if something can be undone.
-
- * mh-customize.el (undo): Enable undo button only if something
- can be undone.
-
-2003-09-22 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-identity-handlers): New defcustom. Alist of
- Handler functions for mh-identity (downcased) fields.
- (mh-identity-list): Add support for pgg-default-user-id.
-
- * mh-identity.el (mh-insert-identity): Modified to use
- `mh-identity-handlers', adding hacking flexibility for those who
- might need it.
- (mh-identity-field-handler): New function. Return the handler for
- a FIELD or nil if none set. The field name is downcased.
- (mh-identity-handler-gpg-identity): New function; handler for pgg
- pgp identities. It sets a buffer-local value for
- `mh-pgg-default-user-id' which must be handled by mh-send-letter.
- (mh-identity-pgg-default-user-id): New buffer-local variable to
- hold the requested key ID.
- (mh-identity-handler-signature): New function; handler t insert
- and remove signature files.
- (mh-identity-handler-default): New function; the default handler
- to insert or remove generic field.
- (mh-identity-handler-top): Insert a field at the top of the
- header.
- (mh-identity-handler-bottom): Insert a field at the bottom of the
- header.
- (mh-header-field-delete): Make more robust wrt the field having a
- trailing colon or not.
- (mh-identity-make-menu): Add a "Customize Identities" menu entry.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-09-21 Peter S Galbraith <psg@debian.org>
-
- * mh-init.el (mh-variant-set): Bug fix for mh-variant long names
- with version numbers.
-
- * mh-e.el (mh-scan-format): patch from Sergey Poznyakoff.
- GNU mailutils now supports the %(decode) format
-
-2003-09-20 Satyaki Das <satyakid@stanford.edu>
-
- * mh-gnus.el (mh-mm-text-html-renderer): New function to query
- which HTML renderer is being used by Gnus.
-
- * mh-mime.el (mh-signature-highlight): Renderers used to display
- HTML parts garble the signature separator in various ways. The
- function has been modified to take that into account.
- (mh-mime-display-single, mh-mm-display-part): Pass the new
- optional argument to `mh-signature-highlight'.
-
-2003-09-19 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-have-file-command, mh-file-mime-type): Made an
- mh-autoload as they are used in mh-comp.el.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-09-18 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-fields): Make sure field has a colon.
-
-2003-09-18 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-toggle-tick): Don't hardcode the name of the tick
- sequencence in the function. This would have caused improper
- highlighting of the tick sequence if the user had changed its
- name.
-
-2003-09-15 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-folder-message-menu): Fix a little bug which shows
- up as a problem during compilation (closes SF #806577).
-
-2003-09-15 Mark D. Baushke <mdb@gnu.org>
-
- * mh-customize.el (mh-invisible-header-fields-internal): Added
- a new field for GNU mailutils per Sergey Poznyakoff.
-
-2003-09-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (vcard): Unconditionally load vcard.el, if
- available, so that vcards are always inlined.
-
-2003-09-09 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-file-mime-type-substitutions): Add entry to
- convert text/plain .vcf files to text/x-vcard.
- (mh-mime-content-types): Add text/x-vcard.
-
-2003-09-09 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-rejected-letter-start): Added strings for qmail
- and exim (addresses SF #404965).
-
-2003-09-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-gnus.el (mm-inline-text-vcard): Make vcard display work with
- Gnus-5.9. The extra file vcard.el is still needed.
-
- * mh-mime.el (mh-signature-highlight): New function that
- highlights message signatures.
- (mh-mm-display-part, mh-mime-display-single): Highlight signatures
- using `mh-signature-highlight' (closes SF #802722). More work is
- needed for XEmacs.
- (mh-mime-display): Highlight signature in non-MIME email too.
-
- * mh-customize.el (mh-show-signature-face): New face used to
- display message signature.
-
-2003-09-08 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-version): Do something sensible when
- mh-variant-in-use is undefined.
- * mh-junk.el (mh-spamassassin-blacklist)
- (mh-spamassassin-whitelist): Change options to be compatible with
- old version of spamassassin (V2.20).
-
-2003-09-07 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-access-types): Per RFC 2049, the "afs"
- access-type for message/external-body has been removed.
- Update the comments to reference the current MIME RFCs
- 2045, 2046 and 2049 rather than the obsolete RFC 1521.
-
-2003-09-05 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-version): Bumped version number to 7.4.2+cvs.
-
-2003-09-04 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-picon-directory-list, mh-picon-directory): The
- mh-picon-directory-list variable supersedes mh-picon-directory.
- (mh-picon-existing-directory-list): New variable that contains
- the list of picon directories that actually exist.
- (mh-picon-set-directory-list): New function to update
- mh-picon-existing-directory-list from mh-picon-directory-list.
- (mh-picon-get-image): The function has been modified to search a
- list of possible picon source directories. The regexp to extract
- the username from the email address has been made smarter so that
- it can recognize email addresses of the form user+random@foo.net
- and extract "user" from there.
- (mh-picon-file-contents): The file type recognition code has been
- moved from mh-picon-get-image into this function.
- (mh-picon-generate-path): The function has been generalized so
- that searching multiple paths is now feasible.
-
- * mh-pick.el, mh-e.el: Checkdoc fixes.
-
-2003-09-02 Satyaki Das <satyakid@stanford.edu>
-
- * mh-identity.el (eval-when): It seems that the mh-comp-loaded
- code isn't required any more.
-
-2003-08-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-init.el (mh-variant-set): Replace `error' with `message' so
- that Emacs CVS will compile without errors if no MH variant is
- present.
-
-2003-08-29 Satyaki Das <satyakid@stanford.edu>
-
- * mh-init.el (mh-variant-set): Add interactive spec to the
- function.
-
- * mh-mime.el (mh-mhn-compose-external-type): Optional arguments
- are prompted for only if prefix arg is given.
-
-2003-08-29 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-mhn-compose-external-type): Modified to be
- interactive and prompts for many of the fields. Made an
- mh-autoload.
- (mh-access-types): New table derived from RFC2017, RFC1521 and
- RFC1738, used in a completing-read in
- mh-mhn-compose-external-type.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-08-26 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-picon-image-types, mh-picon-get-image): Avoid
- compiler warnings.
- (mh-sub-folders-actual): Parsing of the output from folders has
- been modified, so that it also works for MH (closes SF #792300).
-
- * mh-junk.el (mh-spamassassin-whitelist): Avoid calling
- ietf-drums-parse-address if it isn't present.
- (mh-spamassassin-identify-spammers): Avoid use of puthash so that
- Emacs20 doesn't complain.
-
- * mh-e.el (mh-colors-available-p): Wrap call to
- display-color-cells in a mh-funcall-if-exists to avoid compiler
- warning in Emacs20.
-
-2003-08-25 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-colors-available-flag, mh-folder-mode): New
- variable to track if colors are available and it is set
- appropriately in mh-folder-mode.
- (mh-colors-available-p, mh-colors-in-use-p): Two functions to
- check whether colors are available and if they are actually being
- used.
- (mh-add-sequence-notation): Just changing a scan line doesn't
- make font-lock refontify the line in Emacs20. So explicitly
- refontify the scan line in such a situation.
- (mh-internal-seq): If colors aren't being used then treat the
- tick sequence like a normal user sequence.
-
- * mh-seq.el (mh-put-msg-in-seq): Do font-lock highlighting after
- the messages have been added to the sequence.
- (mh-toggle-tick): Modified so that highlighting of the ticked
- messages will be properly done. If font-lock isn't being used or
- if colors aren't supported by the Emacs where MH-E is running,
- then the `%' character is used to annotate ticked messages.
-
- * mh-utils.el (mh-picon-image-types): Since Emacs20 doesn't have
- image-type-available-p, wrap calls to that function in
- ignore-errors.
- (mh-add-msgs-to-seq): Do the font-lock highlighting after the
- messages have been added.
-
-2003-08-24 Bill Wohler <wohler@newt.com>
-
- * Makefile (MH-E-SRC): Replaced mh-xemacs-compat.el and
- mh-xemacs-icons.el with mh-xemacs.el.
-
- * mh-e.el: Don't require mh-xemacs-compat which no longer exists.
- The XEmacs stuff gets required by mh-customize.el which is
- required by mh-utils.el which is required by mh-e.el. This all
- happens before mh-xemacs-compat was required, so all should be
- well.
-
- * mh-unit.el (mh-unit-files): Replaced mh-xemacs-compat.el and
- mh-xemacs-icons.el with mh-xemacs.el.
-
- * mh-xemacs.el: New file from concatenation of mh-xemacs-compat.el
- and mh-xemacs-icons.el which were removed since their names
- exceeded DOS 8+3 limits.
-
- * mh-customize.el (mh-compose-skipped-header-fields): Use
- uppercase for field names.
-
-2003-08-21 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-sequences): Introduced new customization
- group for sequences.
- (mh-refile-preserves-sequences-flag, mh-tick-seq)
- (mh-update-sequences-after-mh-show-flag): Moved option from
- mh-folder to mh-sequences group. Synced docstring with manual.
- (mh-index-ticked-messages-folders): Since mh-tick-seq is
- customizable, use it instead of tick in the docstring.
-
- * mh-index.el (mh-index-ticked-messages): Since mh-tick-seq is
- customizable, use it instead of tick in the docstring.
-
- * mh-seq.el (mh-msg-is-in-seq): Can now specify an alternate
- message number with a prefix argument.
- (mh-narrow-to-tick): Since mh-tick-seq is customizable, use it
- instead of tick in the docstring. Also, use mh-tick-seq instead of
- tick in warning message.
-
-2003-08-20 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el: setq mh-variant to 'none when byte-compiling,
- since we don't care what MH variant (if any) is on the system at
- that point.
-
- * mh-init.el (mh-variant-set): Don't probe for MH variant when
- mh-variant is set to'none (during byte-compilation).
-
-2003-08-19 Peter S Galbraith <psg@debian.org>
-
- * mh-pick.el (mh-pick-single-dash): New defconst. Search
- components that are supported by single-dash option in
- pick.
- (mh-pick-regexp-builder): Use `mh-pick-single-dash' and adapt
- patch from Sergey Poznyakoff.
-
- * mh-comp.el (mh-reply): mu-mh supports `repl -group', thanks to
- Sergey Poznyakof.
-
- * mh-init.el: checkdoc fixes.
-
-2003-08-19 Bill Wohler <wohler@newt.com>
-
- * mh-seq.el (mh-edit-pick-expr): Renamed from mh-read-pick-regexp
- since the new name is more indicative of what the function does.
- Prompt now says "Pick expression" instead of "Pick regexp".
- (mh-narrow-to-subject): Rewrote function to behave like other
- similar functions.
- (mh-narrow-to-header-field, mh-narrow-to-range)
- (mh-narrow-to-tick): s/regexp/pick-expr/.
- (mh-widen, mh-narrow-to-from, mh-narrow-to-cc, mh-narrow-to-to):
- Synced docstrings with manual
-
-2003-08-19 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.4.2.
-
- * MH-E-NEWS, README: Updated for release 7.4.2.
-
- * mh-e.el (Version, mh-version): Updated for release 7.4.2.
-
- * mh-e.el (mh-folder-size, mh-folder-size-folder)
- (mh-folder-size-flist): If flist is not present use folder to find
- the number of messages in the folder. Also the .mh_sequences file
- is read to find the number of unseen messages (patch from 1.349
- and branched for 7.4.2, closes SF #791021).
-
- * mh-utils.el (mh-flists-present-flag, mh-find-progs): Introduce a
- new variable to test for the presence of the flists program and
- set it in mh-find-progs.
- (mh-collect-folder-names): Use folders instead of flists. One
- advantage is that folders is available on MH while flists is not.
- Another is that if an explicit -sequence argument isn't given and
- Unseen-Sequence profile is not present then flists croaks while
- folders doesn't.
- (mh-collect-folder-names-filter): Don't consider folder names that
- start with a `.' character. This is needed since the folders
- command doesn't filter them out like flists does.
- (patches from 1.307 and 1.309 and branched for 7.4.2, closes SF
- #791021).
-
-2003-08-18 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-index-sequenced-messages)
- (mh-index-new-messages, mh-index-ticked-messages): Updated
- docstrings from manual (closes SF #718833).
-
- * mh-customize.el (mh-variant): Checkdoc fix.
- (mh-index-new-messages-folders): Don't mention defvar in
- docstring, use `+inbox' instead.
- (mh-index-ticked-messages-folders): Don't mention defvar in
- docstring, use `tick' instead.
-
- * mh-comp.el (mh-repl-group-formfile): Checkdoc fix.
-
-2003-08-18 Peter S Galbraith <psg@debian.org>
-
- * mh-init.el (mh-variant-set, mh-sys-path, mh-variant-info): Add
- support for GNU mailutils.
- (mh-variant-mu-mh-info): New function to detect mu-mh and return
- info about it for `mh-variants'.
-
- * mh-e.el (mh-regenerate-headers): mu-mh has different error
- message for a invalid message list.
-
-2003-08-18 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-e): New defgroup. Sort of an alias for the
- 'mh group that a user might be more likely to find.
-
-2003-08-18 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-insert-auto-fields-done-local): Docstring tweak.
- (mh-compose-and-send-mail): Do not call mh-insert-auto-fields.
- This should be done only once in mh-send-letter.
-
-2003-08-18 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-mode): Call `mh-find-path unconditionally,
- like elsewhere in MH-E.
-
- * mh-utils.el (mh-find-path): Run setup code only if
- `mh-find-path-run' is nil such that this is only done once.
- Also remove the `setq' for `read-mail-command' and `mail-user-agent'.
-
-2003-08-18 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el: require 'mh-utils first
-
- * mh-customize.el (mh-variant): defcustom moved here.
-
- * mh-init.el (mh-variants): Made an mh-autoload.
-
-2003-08-18 Peter S Galbraith <psg@debian.org>
-
- * Makefile (MH-E-SRC): Added mh-init.el to MH-E-SRC.
-
- * mh-utils.el (mh-find-progs): Deleted. Make obsolete by mh-init.el.
- (mh-find-path): Call `mh-variants' instead of now obsolete
- `mh-find-progs'.
- (mh-path-search): Deleted. Was only used by `mh-find-progs'.
-
- * mh-e.el: require mh-init.el.
- (mh-version): Use simpler `mh-variant-in-use'.
- (mh-scan-format): Use (mh-variant-p 'nmh) instead of mh-nmh-flag.
-
- * mh-comp.el (mh-insert-x-mailer): Use simpler `mh-variant-in-use'.
-
- * mh-utils.el (mh-progs, mh-lib, mh-lib-progs)
- (mh-flists-present-flag): Moved to mh-init.el.
- (mh-nmh-flag): Deleted. Use (mh-variant-p 'nmh) instead.
-
- * mh-comp.el (mh-repl-group-formfile, mh-forward, mh-reply)
- (mh-send-letter): Use (mh-variant-p 'nmh) instead of mh-nmh-flag.
-
- * mh-mime.el (mh-edit-mhn, mh-mime-save-parts): Use (mh-variant-p
- 'nmh) instead of mh-nmh-flag.
-
-2003-08-16 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-folder-selection): New group to hold
- variables described in Folder Selection section in manual.
- (mh-default-folder-list, mh-default-folder-must-exist-flag,
- mh-default-folder-prefix): Moved to mh-folder-selection group.
- Updated docstrings per manual update.
- (mh-default-folder-for-message-function): New defcustom. Was a
- defvar in mh-utils.el. Updated docstring per manual update.
-
- * mh-utils.el (mh-default-folder-for-message-function): Moved to
- mh-customize.el.
-
- * mh-e.el (mh-folder-from-address, mh-prompt-for-refile-folder):
- Updated docstrings per manual update.
-
- * mh-unit.el (mh-unit-files): Added mh-init.el.
-
-2003-08-16 Peter S Galbraith <psg@debian.org>
-
- * mh-init.el: New file. Code to initialize the MH-E back-end.
- Highlights:
- (mh-variant): New defcustom. Users may customize `mh-variant' to
- switch between available variants.
- (mh-variants): Available MH variants are described in this variable.
- (mh-variant-in-use, mh-variant-p): Developers may check which
- variant is currently in use with the variable `mh-variant-in-use'
- or the function `mh-variant-p'.
-
-2003-08-15 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-auto-fields-list): The manual uses Fcc
- instead of fcc, so I've changed the user-visible text
- accordingly. I've left the const alone for backwards
- compatibility.
-
-2003-08-14 Bill Wohler <wohler@newt.com>
-
- * mh-identity.el (mh-insert-identity): Changed signature deletion
- test to test for both markers, rather than testing to see if the
- start marker is bound. Since the start marker is defined in this
- file, it should always be bound. Suggestion by Satyaki.
-
- * mh-comp.el (mh-send-letter): Go to the top of the draft so that
- the user can see which header fields have been inserted. I think
- this is more important than leaving point alone or going to the
- end to see the signature since Mail-Followup-To or Bcc or cc could
- have some deleterious effects.
-
- * mh-customize.el (mh-auto-fields-prompt-flag): New variable.
- Non-nil means to prompt before sending if fields inserted.
-
- * mh-comp.el (mh-insert-auto-fields): Now return t if fields
- inserted; otherwise nil.
- (mh-send-letter): Deleted obsolete documentation about adding
- X-Mailer and X-Face. Prompt before sending if auto fields added
- and mh-auto-fields-prompt-flag is t.
-
- * mh-customize.el (mh-identity-list): Allow signature to come from
- mh-signature-file-name. In this case, the "signature" value is set
- to nil. This might not be the best implementation. Suggestions
- welcome.
-
- * mh-identity.el (mh-insert-identity): Now that the signature can
- be a nil value, moved test higher up in cond so that the test for
- a nil value would not be executed first prevening signature
- handling. Handle nil signature value by calling
- mh-insert-signature with no arguments which means to use
- mh-signature-file-name.
-
- * mh-comp.el (mh-insert-signature): Changed text of message if no
- signature inserted.
-
- * mh-customize.el (mh-identity-list): Changed "Signature" constant
- back to "signature" so it *won't* be backwards-incompatible any
- more. I discovered one could use the :tag keyword to get headline
- captalization in the menu.
-
- * mh-identity.el (mh-insert-identity): Ditto.
-
- * mh-identity.el (mh-identity-make-menu): Always build menu.
- Always create Insert Auto Fields menu item. Just don't enable it
- if mh-auto-fields-list is nil. Enable radio buttons always. Make
- None a radio button choice with the other identities.
-
- * mh-comp.el (mh-letter-menu): Removed cond on fboundp
- 'easy-menu-define. We don't do this elsewhere.
-
-2003-08-13 Bill Wohler <wohler@newt.com>
-
- * mh-identity.el (mh-identity-make-menu, mh-insert-identity): Use
- headline capitalization in menu items. Even the internal names are
- exposed in the customize interface, so they need to be uppercase
- too.
- (mh-insert-identity): Rather than goto-char to
- mh-identity-signature-start before deleting, simply pass it to
- delete-region. When setting markers, use point-min-marker and
- point-max-marker instead of moving point. Set marker type of
- mh-identity-signature-start to t to fix a bug where changing
- identity deleted user's text.
-
- * mh-customize.el (mh-identity-list, mh-auto-fields-list):
- Reworked docstring. Use headline capitalization. Commented out
- implementation details for later deletion or resurrection upon
- popular demand. N.B. If your mh-identity-list contains "signature"
- then you will need to either edit your .emacs file manually, or
- delete your existing "signature" which will become a regular field
- with this change and create a new signature. I figured I could get
- away with this since 8.0 is a major release, and coinciding with
- the manual update will be a MAJOR release. I apologize profusely
- that I didn't catch this before it was released.
- (mh-identity-default): Use headline capitalization in example.
-
-2003-08-12 Jeffrey C Honig <jch@honig.net>
-
- * mh-customize.el (mh-alias-reloaded-hook): Define
- `mh-alias-reloaded-hook'.
-
- * mh-alias.el (mh-alias-reload): Run `mh-alias-reloaded-hook'
- after reloading the aliases.
-
-2003-08-12 Mark D. Baushke <mdb@gnu.org>
-
- * mh-comp.el (mh-insert-signature): Use functionp to avoid
- the possibility of doing a funcall on a void function.
-
-2003-08-12 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-identity): Point group manual link to new
- Identities section.
- (mh-signature-separator-flag): New variable which can be used to
- suppress the output of the signature separator.
-
- * mh-comp.el (mh-insert-signature): Use
- mh-signature-separator-flag.
-
- * mh-identity.el (mh-insert-identity): If the identity's signature
- file didn't exist, an fboundp error was thrown. This was fixed by
- removing signature tests that were redundant and out of date with
- the tests in mh-insert-signature. Removed second signature
- condition as it is now handled in the first signature condition.
-
-2003-08-12 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-insert-identity): Don't insert new lines on
- signatures anymore.
-
- * mh-comp.el (mh-insert-signature): Make sure signature file is
- readable before trying to insert it.
-
-2003-08-11 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-insert-signature): Unconditionally insert a
- newline so that signatures are inserted consistently, and so that
- there isn't any text after the cursor so that the user can start
- typing his message immediately. Use new variable and function
- mh-signature-separator and mh-signature-separator-p.
-
- * mh-customize.el (mh-delete-yanked-msg-window-flag): Checkdoc
- fix.
- (mh-signature-file-name): Updated docstring now that this variable
- can be a function. Added cross-references to
- mh-signature-separator, mh-signature-separator-regexp, and
- mh-signature-separator-p which might be used in such functions.
-
- * mh-identity.el (mh-insert-identity): Don't include signature if
- signature separator already present. Useful when running
- mh-edit-again.
-
- * mh-mime.el (mh-inline-vcard-p): Use mh-signature-separator-p.
-
- * mh-utils.el (mh-signature-separator-regexp): New variable
- containing "^-- $" which should be used when looking for the
- signature separator.
- (mh-signature-separator): New variable containing "-- \n" which
- should be used when inserting the signature separator.
- (mh-signature-separator-p): New function that returns non-nil if
- mh-signature-separator-regexp is found in the buffer.
-
-2003-08-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-x-image-scaling-function): Variable that
- contains function used to scale images. Possible choices are
- mh-x-image-scale-with-convert and mh-x-image-scale-with-pnm.
- (mh-convert-executable): Removed.
- (mh-x-image-scale-with-pnm, mh-x-image-scale-with-convert): New
- functions that scale images using pnm tools or ImageMagick.
- (mh-x-image-scale-and-display, mh-x-image-url-display): Use
- mh-x-image-scaling-function instead of mh-convert-executable.
-
-2003-08-08 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-signature): Bug fix. Handle case of nil
- `mh-signature-file-name' and hooks correctly.
-
- * mh-identity.el (mh-insert-identity): Refactor to use
- mh-insert-signature
-
- * mh-comp.el (mh-signature-separator-p): Removed.
-
- * mh-comp.el (mh-insert-signature): Merge MIME awareness from
- mh-insert-identity into this command. Allow
- `mh-signature-file-name' to be a function to call. See if "-- "
- needs to be inserted only after hooks have run.
-
-2003-08-07 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-compose-skipped-header-fields): Added
- X-Image-URL.
- (mh-autoload): Removed cookies. They aren't necessary in
- mh-e.el, mh-utils.el, or mh-customize.el.
-
- * mh-e.el (mh-autoload): Removed cookies. They aren't necessary in
- mh-e.el, mh-utils.el, or mh-customize.el.
-
- * mh-identity.el (mh-insert-identity): Made regexp for signature
- separator more explicit. Hmmm, maybe we should create
- mh-signature-separator-regexp...
-
- * mh-index.el (mh-replace-string): Moved to mh-utils.el.
-
- * mh-utils.el (mh-replace-string): Moved here from mh-index.el.
- (mh-autoload): Removed cookies. They aren't necessary in mh-e.el,
- mh-utils.el, or mh-customize.el.
-
- * mh-comp.el (mh-insert-signature): Added file argument to insert
- a file other than mh-signature-file-name. Insert signature
- separator, unless file already contains one.
-
-2003-08-06 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-folder-size, mh-folder-size-folder)
- (mh-folder-size-flist): If flist is not present use folder to
- find the number of messages in the folder. Also the .mh_sequences
- file is read to find the number of unseen messages.
-
- * mh-utils.el (mh-flists-present-flag, mh-find-progs): Introduce
- a new variable to test for the presence of the flists program and
- set it in mh-find-progs.
-
-2003-08-06 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el: Change the order of `mh-identity-list' and
- `mh-auto-fields-list' and remove byte-compilation defvar for
- `mh-identity-list'. This fixes a customization bug for
- `mh-identity-list', where it wasn't set correctly.
-
- * mh-identity.el (mh-identity-make-menu): mh-auto-fields-list may
- not be bound yet when initially loaded.
-
-2003-08-06 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (mh-alias-add-address-under-point): Removed trailing
- period from messages. The conventions say that errors should not
- end with a period and that "Foo...done" messages should not end in
- a period, but they aren't explicit about messages in general.
- Given what the conventions *do* say, and because most of our
- messages don't end with a period, let's just say that messages in
- general don't end in a period, just like error messages.
-
- * mh-comp.el (mh-extract-rejected-mail, mh-letter-mode-message):
- Ditto.
-
- * mh-e.el (mh-refile-a-msg): Ditto.
-
- * mh-funcs.el (mh-undo-folder): Ditto.
-
- * mh-mime.el (mh-mime-save-parts): Ditto.
-
- * mh-seq.el (mh-subject-to-sequence-unthreaded)
- (mh-narrow-to-subject, mh-delete-subject): Ditto.
-
- * mh-index.el (mh-index-sequenced-messages)
- (mh-index-new-messages, mh-index-ticked-messages): Discovered that
- in general we should only use question marks in yes-or-no-p or
- y-or-n-p prompts, but not in other prompts that use
- completing-read and offer defaults. In these cases, use colons
- instead (closes SF #730470).
-
- * mh-mime.el (mh-mime-save-parts): Ditto.
-
- * mh-utils.el (mh-prompt-for-folder): Ditto.
-
- * mh-alias.el (mh-alias-apropos): Multiple messages are usually
- shown one at a time rather than appended. Send output to
- mh-aliases-buffer instead of *Help*.
- (mh-alias-local-users): Checkdoc fix.
-
- * mh-funcs.el (mh-undo-folder): Removed commented-out code since
- its deadline had expired.
-
- * mh-utils.el (mh-aliases-buffer): New buffer name, used in
- mh-aliases.el.
-
-2003-08-06 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-x-image-url-cache-canonicalize): Make this
- function work for XEmacs too.
- (mh-collect-folder-names): Use folders instead of flists. One
- advantage is that folders is available on MH while flists is not.
- Another is that if an explicit -sequence argument isn't given and
- Unseen-Sequence profile is not present then flists croaks while
- folders doesn't.
- (mh-collect-folder-names-filter): Don't consider folder names that
- start with a `.' character. This is needed since the folders
- command doesn't filter them out like flists does.
-
- * mh-index.el (mh-replace-string): Add autoload for it.
-
-2003-08-05 Satyaki Das <satyakid@stanford.edu>
-
- * mh-mime.el (mh-compose-forward, mh-mhn-compose-forw)
- (mh-mml-forward-message): The variable mh-sent-from-msg can be a
- list. So check that the value is really a number before using it
- like one.
-
- * mh-comp.el (mh-insert-letter): Same as above.
-
- * mh-utils.el (mh-picon-get-image): Make the code that finds the
- address of the sender more robust.
- (mh-face-display-function): Make it work with XEmacs.
- (mh-picon-image-types): A new variable that stores what image
- types can be used.
-
-2003-08-05 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el (mh-tool-bar-define): Make the save button such
- that is activated only if the buffer needs to saved.
-
- * mh-utils.el (mh-face-display-function, mh-picon-get-image): Some
- domains, for instance cs.cmu.edu, don't have xpm files. So we need
- to search for all three files. The change does that.
- (mh-picon-file-contents): A utility function to return the
- contents of a file as a string.
- (mh-picon-get-image): Write it as a loop to make it simpler.
- (mh-x-image-set-download-state): Make the link simpler.
-
-2003-08-04 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-x-image-url-display): Don't bother to try to
- download image if we don't have the necessary tools to display
- it.
- (mh-face-display-function): Add preliminary support for "domain"
- picons.
- (mh-picon-get-image, mh-picon-generate-path): Functions to find
- best match for domain in the From header field.
-
- * mh-e.el (mh-previous-unread-msg): If some of the messages in the
- unseen sequence are not present in the folder buffer then calling
- this function gets stuck and can't skip over them. The change
- fixes this.
- (mh-next-unread-msg): Same as above.
-
-2003-08-04 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-show-mode): Added cross reference to
- mh-folder-mode in docstring (closes SF #728638). Added
- \\{mh-show-mode-map} to show keymap.
-
- * mh-e.el (mh-folder-mode): Added information about ranges to
- docstring (closes SF #728638).
-
- * mh-speed.el (mh-speed-refresh): New function that calls
- mh-speed-flists and mh-invalidate-map.
- (mh-folder-speedbar-key-map): Replaced keybindings for
- mh-speed-invalidate-map and mh-speed-flists with a single binding
- for mh-speed-refresh.
- (mh-folder-speedbar-menu-items): Replaced menu items for Run
- Flists and Invalidate Cached Folders with the single menu item
- Refresh Speedbar in order to simplify the UI.
-
- * mh-customize.el (mh-fetch-x-image-url): Added DOS as another
- reason not to set this to t.
-
-2003-08-04 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-scan-folder): Handle ranges from user input properly.
-
-2003-08-03 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-find-msg-get-num): Removed. If threading isn't
- present, the messages are sorted by index. So `mh-goto-msg' was
- implemented as a binary search and this function was used in that
- implementation. So this isn't needed any more.
- (mh-msg-search-pat): Removed. Before the advent of message
- threading, this function was used to generate a regexp used to
- search for a particular message. It isn't used anymore. The
- variable `mh-scan-msg-number-regexp' should be updated and used in
- `mh-goto-msg' instead of hardcoding the regexp in the code. Then
- we might be able to better support other scan line formats in the
- future.
-
- * mh-seq.el (mh-map-to-seq-msgs, mh-notate-seq): Removed. These
- functions were used to notate user sequences. But calling
- `mh-goto-msg' inside of a loop is inefficient. So the sequence
- notation code was rewritten thereby making these functions
- redundant.
- (mh-copy-line-to-point): Removed. This function was used in the
- implementation the now removed function `mh-copy-seq-to-point'.
- That function was problematic and was replaced by the less general
- `mh-copy-seq-to-eob'. This makes `mh-copy-line-to-point'
- redundant.
- (mh-region-to-msg-list): Removed since this is a special case of
- the more general `mh-range-to-msg-list'.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-08-03 Jeffrey C Honig <jch@honig.net>
-
- * mh-customize.el (mh-invisible-header-fields-default): Added
- several new fields to hide. Sorted the list with sort-lines.
-
-2003-08-03 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-invisible-headers): Variable renamed to
- `mh-invisible-header-fields-compiled'.
- (mh-invisible-headers): Implement above change.
-
- * mh-utils.el (mh-display-msg): Idem.
-
- * mh-mime.el (mh-mm-inline-message): Idem.
-
- * mh-comp.el (mh-insert-letter): Idem.
-
-2003-08-03 Bill Wohler <wohler@newt.com>
-
- * mh-speed.el (mh-folder-speedbar-menu-items): Added separator
- between standard and MH-E menu items. Use headline capitalization
- in menu items.
-
- * mh-utils.el (mh-temp-fetch-buffer): New constant to hold
- buffer name for wget output.
- (mh-x-image-url-fetch-image): Use mh-temp-fetch-buffer instead
- of hard-coded buffer name. Use make-temp-file to avoid race
- conditions and subsequent security issues raised in make-temp-name
- docstring.
-
-2003-08-03 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-wget-executable, mh-wget-choice, mh-wget-option)
- (mh-x-image-url-fetch-image): Support the use of `curl' and
- `fetch' as alternatives to `wget'.
- (mh-wget-choice): Change order of search.
- (mh-x-image-url-fetch-image): Rename buffer.
-
-2003-08-03 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-x-image-set-download-state)
- (mh-x-image-get-download-state): Specially named symbolic links
- are used to keep track of whether a X-Image-URL header field needs
- to downloaded the next time it is seen. These functions get and
- set the symlinks appropriately.
- (mh-x-image-url-fetch-image): Simplified since the query has been
- moved to `mh-x-image-url-display'. Also if wget isn't present then
- try again next time since the user might install wget before
- trying once more.
- (mh-x-image-scale-and-display): Handle absence of the `convert'
- program better. If it isn't present then we will try to display
- the image the next time it is encountered. Also use the -geometry
- option to convert since the -resize option isn't present in older
- versions.
- (mh-x-image-url-display): Move all the code that decides whether
- an X-Image-URL header field will be fetched in this function. Also
- remember the user's decision so that if the image couldn't be
- fetched the first time, we will try to fetch it later on without
- asking again.
-
-2003-08-02 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-local-users): Exclude all aliases already
- in mh-alias-alist from `ali' (closes SF #772595).
-
-2003-08-01 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-x-image-display, mh-x-image-url-display): Avoid
- a race. The X-Image-URL is displayed asynchronously. Suppose a
- message with a image is shown with `mh-show'. If a different
- message is displayed before the image can be fetched, then the new
- message will have the image displayed. With this change the race
- is less likely to happen.
-
-2003-08-01 Peter S Galbraith <psg@debian.org>
-
- * mh-inc.el (mh-inc-spool-map): Fix what `mh-inc-spool-map-help'
- must look like as a fake `mh-help-messages' in order to work
- correctly in mh-help.
-
-2003-07-31 Bill Wohler <wohler@newt.com>
-
- * mh-inc.el (mh-inc-spool-map): Use mh-help instead of
- mh-ephem-message in order to display help in its own buffer
- instead of minibuffer.
-
- * mh-utils.el (mh-help-buffer): New variable to hold the name of
- the MH-E help buffer name.
-
- * mh-funcs.el (mh-help, mh-prefix-help): Use with-electric-help to
- display help messages. I observed a friend with a vision
- disability and the 5 seconds the help appeared on the screen was
- not long enough for him to lock on it. I've therefore changed the
- help function to display the help in its own buffer called *MH-E
- Help* (closes SF #493740 and SF #656631).
-
- * mh-customize.el (mh-fetch-x-image-url): Changed default from nil
- to 'ask. Updated docstring from manual.
- (mh-invisible-header-fields-internal): Added X-Image-URL.
- (mh-show-use-xface-flag): Updated docstring from manual.
- (mh-x-face-file): Ditto.
-
- * mh-mime.el (mh-mhn-compose-external-type): Don't insert the
- directory parameter if it's nil. The mhbuild man page indicates
- that this parameter is optional, so this should be fine.
-
- * mh-comp.el (mh-letter-mode-map): Added keybindings for
- mh-mhn-compose-anon-ftp and
- mh-mhn-compose-external-compressed-tar.
- (mh-letter-menu): Uncommented menu items for same.
-
-2003-07-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-pick.el (mh-do-pick-search): Removed since the function
- `mh-pick-do-search' performs the same action as this function.
-
- * mh-index.el (mh-index-update-unseen): Removed since the
- generalized sequence synchronization code that keeps sequences in
- index folders in sync with the sequences in the source folders
- makes this function redundant.
-
- * mh-e.el (mh-folder-unseen-seq-name, mh-folder-unseen-seq-list):
- Removed. These two functions were used in the unseen sequence
- highlighting before the sequence highlighting code was
- generalized. In any event calls to the function
- `mh-folder-unseen-seq-name' can be replaced by the variable
- `mh-unseen-seq' and calls to `mh-folder-unseen-seq-list' can be
- replaced with (cdr (assoc mh-unseen-seq mh-seq-list)).
- (mh-unmark-all-headers): Removed since this function has been
- superseded by mh-remove-all-notation.
- (mh-map-over-seqs): Removed since we now have the generalized
- iteration over message ranges (the `mh-iterate-on-range' macro)
- that can be used instead.
- (mh-notate-if-in-one-seq): Removed. This function was used for
- changing the `%' notation for user sequences. It can't be used for
- that purpose any more, since we have a different scheme now.
-
- * mh-unit.el (mh-unit-tests): Removed since it isn't needed any
- more.
- (mh-unit): Run all function that start with the string
- "mh-unit-test-".
-
-2003-07-30 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-invisible-header-fields): Checkdoc fix.
-
- * mh-utils.el (mh-x-image-url-cache-canonicalize): Shortened using
- example in files.el:make-backup-file-name-1.
- (mh-face-display-function): Added X-Image-URL to docstring.
-
- * mh-unit.el (mh-unit-x-image-url-cache-canonicalize): New
- function to test mh-x-image-url-cache-canonicalize since it lent
- itself well to unit testing. Had to start somewhere!
- (mh-unit-equal): New function that throws an error if RESULT
- doesn't equal EXPECTED.
- (mh-unit): Call mh-unit-x-image-url-cache-canonicalize.
-
-2003-07-29 Satyaki Das <satyakid@stanford.edu>
-
- * mh-unit.el (mh-unit-update-call-graph): Make the function work
- better with dotted lists, that is lists of the form (a b c . d)
- where `d' isn't nil. With this we are able to avoid marking some
- functions as unused even though they are actually used in alists.
-
-2003-07-28 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-letter): Remove `mh-visible-headers'
- operation.
-
- * mh-mime.el (mh-mm-inline-message): Same.
-
- * mh-utils.el (mh-display-msg): Same.
- (mh-clean-msg-header): Make a note of above change.
-
- * mh-customize.el (mh-invisible-header-fields-internal): Renamed
- from prior `mh-invisible-header-fields-default'.
- (mh-invisible-header-fields-default): Renamed from prior
- `mh-invisible-header-fields-default-override'.
- (mh-invisible-header-fields): Renamed from prior
- `mh-invisible-header-fields-user'.
- (mh-visible-headers): Removed! We use invisible fields only now.
- (mh-visible-header-fields): Removed!
-
-2003-07-28 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-invisible-header-fields-default): Added 3
- new fields to hide.
-
-2003-07-28 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-show): Add an extra argument to the function so
- that interactive use will always force redisplay of the message.
-
- * mh-mime.el (mh-mime-display, mh-mm-inline-message): Bind the
- variables `mm-verify-option' and `mm-decrypt-option' so that
- verification and decryption of mail can happen without any
- additional tinkering.
-
-2003-07-25 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-invisible-header-fields-default): New defvar
- holding default fields to hide. This replaces the old
- `mh-invisible-header-fields' defcustom.
- (mh-invisible-header-fields-user): New defcustom. Users add
- fields to suppress that we didn't include in
- `mh-invisible-header-fields-default'. This could be named simply
- `mh-invisible-header-fields' and it wouldn't really break anything
- for users who have customized it to a long list now redundant with
- `mh-invisible-header-fields-default'.
- (mh-invisible-header-fields-default-override): New defcustom.
- Users check off the fields they want displayed from what we
- included in `mh-invisible-header-fields-default'.
- (mh-invisible-headers): Function adapted to new variables.
-
-2003-07-25 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-inc-folder): If the user is in a different folder
- displaying a message and runs mh-inc-folder, then the folder
- changes to +inbox but the show window continues to display the
- message in the old folder. The change fixes this.
- (mh-visit-folder): Make the handling of the show window similar to
- that of mh-inc-folder.
-
-2003-07-24 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-folder-message-menu, mh-folder-folder-menu): Use the
- predicate mh-outstanding-commands-p instead of its expansion.
- Also use the same label in both menus.
- (mh-outstanding-commands-p): Generalized so that it will work in
- mh-show-mode buffers as well.
-
- * mh-customize.el (mh-tool-bar-define): Enable tool-bar button for
- mh-execute-commands only if there are pending deletes or refiles.
-
-2003-07-19 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-show-msg): If a unseen message is first marked
- for deletion/refiling and then displayed, the bold highlighting
- does not go away. This change fixes that.
-
- * mh-seq.el (mh-msg-is-in-seq): Fix a bug in the function. If any
- message was marked for refiling, then the function would have you
- believe that every message in the folder is being refiled.
-
-2003-07-17 Bill Wohler <wohler@newt.com>
-
- * mh-e.el: Removed email address for Stephen Gildea's in Change
- Log at his request (damn spammers). Removed other email addresses
- while I was at it since the SourceForge URL should be sufficient
- contact information.
-
- (mh-scan-format-*mh): Fixed typo in comment above these variables.
- These variables are used if mh-scan-format-file is t, not nil.
- Also mh-scan-format-file is no longer "above" (courtesy Stephen
- Gildea).
-
-2003-07-17 Satyaki Das <satyakid@stanford.edu>
-
- * mh-mime.el (mh-mhn-quote-unescaped-sharp): New function that
- quotes `#' characters in the first column that aren't part of a
- MHN directive.
- (mh-mhn-directive-present-p): Generalized to allow the function
- to search for MHN directives in a part of the buffer.
- (mh-edit-mhn): Quote unescaped `#' characters in the draft (closes
- SF #762464).
-
-2003-07-16 Satyaki Das <satyakid@stanford.edu>
-
- * mh-alias.el (mh-alias-read-address-map): If
- mh-alias-flash-on-comma is nil when mh-alias is loaded, then
- setting mh-alias-flash-on-comma to t later on doesn't turn on
- address completion display till Emacs is restarted. The change
- fixes this.
-
-2003-07-15 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-cmd-note): Cleaned up docstring (changed phrase
- to sentences). Moved to Scan Line Formats section.
- (mh-scan-msg-number-regexp)
- (mh-scan-msg-overflow-regexp, mh-scan-msg-format-regexp)
- (mh-scan-msg-format-string, mh-scan-msg-search-regexp): Cleaned up
- docstrings (changed phrases to sentences).
- (mh-note-seq): Cleaned up docstring (changed phrase to sentences).
- Also, this variable is now a character and not a string. Moved to
- Scan Line Formats section.
-
- * mh-funcs.el (mh-note-copied, mh-note-printed): Cleaned up
- docstrings (changed phrases to sentences). Also, these variables
- are now characters and not strings.
-
- * mh-e.el (mh-scan-format-mh, mh-scan-format-nmh): Filled. I was
- hoping to quote the hint `t' but checkdoc wouldn't let me.
- (mh-note-deleted, mh-note-refiled, mh-note-cur): Moved to Scan
- Line Formats section.
- (mh-scan-good-msg-regexp, mh-scan-deleted-msg-regexp)
- (mh-scan-refiled-msg-regexp, mh-scan-valid-regexp)
- (mh-scan-cur-msg-number-regexp, mh-scan-date-regexp)
- (mh-scan-rcpt-regexp, mh-scan-body-regexp)
- (mh-scan-subject-regexp, mh-scan-format-regexp): Cleaned
- up docstrings (changed phrases to sentences).
- (mh-scan-cur-msg-regexp): Marked this variable as obsolete; it
- should be removed for 8.0.
-
- * mh-comp.el (mh-note-repl, mh-note-forw, mh-note-dist): Cleaned
- up docstrings (changed phrases to sentences). Also, these
- variables are now characters and not strings.
-
-2003-07-15 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-update-single-msg)
- (mh-index-create-sequences): Handle the situation where there are
- copies of the exact same message correctly.
-
-2003-07-15 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-thread-update-scan-line-map): Modified since
- notation is already a character.
-
- * mh-utils.el (mh-note-seq): Convert from string to character.
- (mh-notate): Modified since characters are used to notate instead
- of strings of length one.
-
- * mh-comp.el (mh-note-repl, mh-note-forw, mh-note-dist): Convert
- from string to characters.
-
- * mh-e.el (mh-note-deleted, mh-note-refiled, mh-note-cur): Same as
- above (closes SF #770772).
- (mh-unmark-all-headers): Modified since mh-note-* variables are
- now characters.
- (mh-remove-sequence-notation): The mh-notate function remembers
- the previous notation. Before the change to the mh-note-*
- variables, mh-notate would only remember the change if a string
- was used to notate the message. Now mh-notate is always called
- with a character notation. So the deletion has to take place
- explicitly.
-
-2003-06-28 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-mhn-directive-present-p): If shell comments are
- present that have a space after the # but no content, then this
- function would throw an error. This has been fixed (closes SF
- #762458).
-
-2003-06-27 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-search): Use the new and improved
- mh-index-new-folder.
- (mh-index-new-folder): Improved so that redoing the same search
- will reuse the old index folder.
- (mh-index-folder-search-regexp): New function which that extracts
- out the search expression that produced the index folder.
-
-2003-06-24 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Set to 7.4.1+cvs.
-
-2003-06-25 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.4.1.
-
- * MH-E-NEWS, README: Updated for release 7.4.1.
-
- * mh-e.el (Version, mh-version): Updated for release 7.4.1.
-
-2003-06-25 Bill Wohler <wohler@newt.com>
-
- * mh-unit.el (require 'cl): Added. Needed when compiling
- separately.
-
- * Makefile (clean): Now a double-colon rule. Added a second clean
- target to remove mh-unit.elc.
- (compile): Removed mh-unit.elc.
- (mh-unit.elc): New target used to compile mh-unit.
-
-2003-06-24 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Set to 7.4+cvs.
-
-2003-06-24 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.4.
-
- * MH-E-NEWS, README: Updated for release 7.4.
-
- * mh-e.el (Version, mh-version): Updated for release 7.4.
-
-2003-06-24 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (mh-alias-gecos-name, mh-alias-local-users)
- (mh-alias-suggest-alias): s/gcos/gecos. The original acronym was
- GECOS but was later renamed to GCOS (see
- http://info.astrian.net/jargon/terms/g/GCOS.html). But the term
- really needs to match the field named pw_gecos in struct passwd in
- /usr/include/pwd.h
-
- * mh-customize.el (mh-letter-faces): New group to house
- mh-letter-header-field-face.
- (mh-interpret-number-as-range-flag)
- (mh-kill-folder-suppress-prompt-hook): Use "you" instead of "the
- user" to make text more friendly.
- (mh-index-ticked-messages-folders, mh-visible-headers)
- (mh-visible-header-fields): Alphabetized.
- (mh-alias-passwd-gcos-comma-separator-flag): Alphabetized and
- s/gcos/gecos.
- (mh-alias-local-users-prefix): Fixed docstring. Prefixes are
- prepended, not appended. Additional checkdoc fix.
- (mh-letter-header-field-face): Set group to new group
- mh-letter-faces and moved option into this group.
-
- * mh-index.el (mh-index-sequenced-messages): Improved wording of
- docstring and mentioned use of prefix argument.
-
- * mh-seq.el (mh-widen): Made docstring more accurate (hopefully!).
-
-2003-06-18 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-replace-string): Modified to preserve case of
- replacement text.
- (mh-index-parse-search-regexp): Preserve case of search terms.
- This is needed to take advantage of the acronym indexing in
- swish++ (closes SF #755718).
-
-2003-06-13 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-show-index-sequenced-messages): Interactive
- function callable from the show buffer.
- (mh-show-folder-map): Add key binding for "F q".
-
- * mh-e.el (mh-folder-map): Same as above.
-
- * mh-index.el (mh-index-sequenced-messages): Add interactive spec
- to the function (closes SF #718833).
-
-2003-06-13 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-flists-execute): Needed to expand mhpath too.
-
-2003-06-12 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-flists-execute): Modified so that flists
- present in mh-progs is called.
-
-2003-06-07 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-forward, mh-forward): Use (mh-mail-header-end) to
- find the end of headers instead of doing an re-search-forward
- based on mh-mail-header-separator.
-
-2003-06-06 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-toggle-header-field-display): Make the
- function callable from the show buffer. This means that the
- buffer is temporarily made writable and the modification status
- of the buffer restored to the original value.
-
-2003-06-06 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-address-mail-regexp): Bug fix! It wasn't a true
- copy of the goto-addr variable. My modification only recognized
- addresses with one dot after the @. Sorry about that.
-
-2003-06-05 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-replace-in-string): Move comment into doc
- string to satisfy checkdoc.
-
- * mh-alias.el (mh-alias-apropos): Checkdoc fix.
-
-2003-06-05 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-identity-list): Fixed typo in docstring.
-
-2003-06-05 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-complete-function-alist): Add bcc an reply-to.
-
-2003-06-04 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-complete-function-alist): Add dcc.
-
-2003-06-03 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-replace-in-string): New function name instead of
- `dired-replace-in-string'.
- * mh-alias.el (mh-alias-gcos-name): Use it.
-
- * mh-alias.el (mh-alias-apropos): New command. Show all aliases
- that match REGEXP either in name or content.
-
- * mh-alias.el (mh-alias-suggest-alias): Add no-comma-swap optional
- arg.
- (mh-alias-canonicalize-suggestion): Change a comma to a period in
- created aliases.
- (mh-alias-local-users): Call `mh-alias-suggest-alias' with
- `no-comma-swap' arg set to t.
-
- * mh-alias.el (mh-alias-local-users): Fix case of nil
- `mh-alias-passwd-gcos-comma-separator-flag'.
-
- * mh-alias.el (mh-alias-gcos-name): Fix for case of empty gcos
- name field.
- (mh-alias-local-users): Fix same.
-
- * mh-alias.el (mh-alias-canonicalize-suggestion): Replace use by
- verbose `replace-regexp' by a looped `replace-match'
-
-2003-06-02 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (dired-replace-in-string): Bind if not already
- defined. Borrowed from dired.el
-
- * mh-alias.el (mh-alias-gcos-name): switch to using
- dired-replace-in-string.
-
-2003-06-02 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-letter-font-lock-keywords): Fontify header
- fields in the draft buffer that aren't skipped when navigating
- with TAB (or S-TAB).
-
- * mh-customize.el (mh-clean-message-header-flag)
- (mh-invisible-headers, mh-invisible-header-fields)
- (mh-alias-passwd-gcos-comma-separator-flag): Checkdoc fix.
- (mh-letter-header-field-face): New face to fontify the header
- fields.
-
- * mh-comp.el (mh-insert-auto-fields-done-local): Checkdoc fix.
- (mh-letter-mode, mh-letter-mail-header-end-marker): Remember the
- end of the message header in a marker. This is used to fontify the
- header fields.
- (mh-font-lock-field-data, mh-letter-header-end): Functions used
- to fontify message header fields.
-
- * mh-alias.el (mh-alias-gcos-name): Checkdoc fix.
-
-2003-06-02 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-gcos-name): New function. Return a usable
- address string from a GCOS-NAME and USERNAME.
- (mh-alias-local-users): Use it.
-
- * mh-customize.el (mh-alias-passwd-gcos-comma-separator-flag): New
- defcustom. Whether the gcos field in the passwd file uses comma as
- a separator.
-
- * mh-customize.el (mh-alias-local-users-prefix): New
- defcustom. String to append to the real names of users from the
- passwd file. If nil, use the username string unmodified instead of
- the real name from the gcos field of the passwd file.
-
- * mh-alias.el (mh-alias-local-users): Use it to generate aliases
- which by default are now the real name prefixed by "local."
-
-2003-06-01 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-modify-header-field): Bug fix. Calling with
- a value that was already inserted causes it to get inserted a
- second time. I have wrapped the value around \b word delimiters.
- Hope there are no side effects for other code.
-
- * mh-comp.el (mh-insert-auto-fields): Attempt regardless of
- `mh-insert-auto-fields-done-local' flag in interactive use.
-
- * mh-comp.el (mh-insert-auto-fields-done-local): Keep track of
- whether `mh-insert-auto-fields' was called in a buffer.
- (mh-insert-auto-fields): Set it and use it. Also, don't enter an
- identity if one was already entered manually.
- (mh-send-letter): Call `mh-insert-auto-fields' again when sending
- message.
- (mh-compose-and-send-mail): Call `mh-insert-auto-fields' _after_
- `mh-letter-mode' so `mh-identity-local' doesn't get cleared by the
- mode invocation.
-
-2003-06-01 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-thread-parse-scan-line): The value of
- mh-scan-field-from-start-offset was hardcoded in one place. The
- change fixes that.
-
- * mh-utils.el (mh-show-mode): Setup mh-show-mode to display
- ellipsis for truncated header fields and to skip over them quickly.
- (mh-clean-msg-header): Make another pass over the message header
- fields truncating long headers.
-
- * mh-comp.el (mh-letter-complete): Remove unnecessary autoload.
- (mh-letter-toggle-header-field-display): Take into account that
- an empty line can also end the message header. The function was
- originally written with the draft buffer in mind.
-
-2003-06-01 Mark D. Baushke <mdb@gnu.org>
-
- * mh-comp.el (mh-letter-mode-map): Do not steal C-t. Use C-c C-t
- for the mh-letter-toggle-header-field-display command.
-
-2003-05-31 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-visible-headers): Changed to a defvar that
- will be set using new `mh-visible-headers' function using
- `mh-visible-header-fields' as input.
- (mh-visible-headers): New function, described above.
- (mh-visible-header-fields): New defcustom. The UI to set
- `mh-visible-headers'.
- (mh-invisible-header-fields-set): Deleted. Code merged into
- defcustom since it's so short.
-
-2003-05-31 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-toggle-header-field-display): Extended to
- truncate headers if they are too long.
- (mh-letter-truncate-header-field): Make code that would be
- duplicated into a function.
- (mh-letter-hide-all-skipped-fields): Modified so that fields that
- are important are hidden if they are too long.
-
-2003-05-31 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el ("tool-bar"): Since tool-bar isn't available on
- XEmacs, requiring it causes problems. So load it instead.
- (mh-do-at-event-location): New macro to do stuff at location of
- events. This has been refactored out of mh-push-button.
-
- * mh-mime.el (mh-push-button): Simplified since it now uses the
- mh-do-at-event-location macro.
-
- * mh-comp.el (mh-hidden-header-keymap): Keymap to make mouse
- clicks on header toggle its display.
- (mh-letter-toggle-header-field-display-button): Interactive
- function to toggle header display when mouse button is clicked.
-
-2003-05-31 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-mode): Remove conditional on tool-bar-mode.
-
- * mh-comp.el (mh-letter-mode): Same.
-
- * mh-utils.el (mh-show-mode): Same.
-
-2003-05-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (tool-bar): Load tool-bar explicitly. This avoids
- problems with incorrect initialization of tool-bar-map otherwise.
-
-2003-05-30 Peter S Galbraith <psg@mixed.dyndns.org>
-
- * mh-comp.el (mh-modify-header-field): Minor fix of spaces for
- when an entry already existed.
- (mh-insert-auto-fields): Make interactive. Add optional `quiet'
- arg for use when called systematically on every buffer. Won't be
- used interactively for more verbose output.
- (mh-letter-mode-map): Add \C-c\M-d keybinding for
- mh-insert-auto-fields.
-
- * mh-identity.el (mh-identity-make-menu): Add a menu entry in
- Identity menu for mh-insert-auto-fields.
-
- * mh-customize.el (mh-invisible-header-fields): Add entries for
- `Envelope-to' and `X-Original-To'.
-
-2003-05-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-mode): Skip over invisible text quickly.
-
-2003-05-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-mode): Use text properties to achieve
- invisibility. This is more portable and the same code can be used
- for all Emacs versions.
- (mh-letter-toggle-header-field-display): Rewritten to use text
- properties.
- (mh-dead-overlay-p, mh-letter-hidden-header-fields)): Removed.
-
-2003-05-29 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-hidden-header-fields, mh-letter-mode): Add
- a hash table, initialized it in mh-letter-mode, to remember the
- overlays introduced to hide long headers fields.
- (mh-insert-x-mailer): checkdoc fix.
- (mh-compose-and-send-mail): Hide unimportant message header
- fields.
- (mh-letter-header-field-regexp, mh-letter-header-field-at-point)
- (mh-letter-next-header-field, mh-letter-previous-header-field):
- Add a variable that contains the header-field name regexp and use
- it instead of the regexp directly.
- (mh-letter-toggle-header-field-display, mh-letter-mode-map): Add
- new key binding in mh-letter-mode that toggles display of long
- header fields, in mh-letter-mode.
- (mh-dead-overlay-p): A predicate which checks if a given header
- field has an active overlay hiding it.
- (mh-letter-hide-all-skipped-fields): New function that shortens
- uninteresting headers.
-
-2003-05-29 Eric Ding <ericding@acorn.bethesda.net>
-
- * mh-comp.el (mh-letter-next-header-field-or-indent): Call
- indent-relative rather than indent-for-tab-command.
-
-2003-05-29 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-complete-or-space): The meaning of the
- customizable variable was reversed. Also make the doc string more
- accurate.
-
-2003-05-28 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el (mh-compose-skipped-header-fields): New
- customizable variable that lists headers that are skipped.
- (mh-compose-space-does-completion-flag): Option to do completion
- with space (closes SF #745634).
-
- * mh-comp.el (mh-insert-x-mailer): Check the value of
- mh-insert-x-mailer-flag in this function instead of in its caller.
- (mh-compose-and-send-mail, mh-send-letter): Insert X-Mailer and
- X-Face headers when the draft is first presented to the user
- instead of when the mail is sent (closes SF #745624).
- (mh-letter-complete-or-space): Allow for this key binding to be
- overridden.
- (mh-letter-next-header-field): Fix a problem with multiline header
- fields.
- (mh-letter-next-header-field, mh-letter-previous-header-field):
- Make these functions skip unwanted header fields.
- (mh-letter-skipped-header-field-p): New predicate that checks if a
- header field is to be skipped.
-
- * mh-seq.el (mh-thread-inc): Inc'ing email in threaded mode was
- causing duplication of the current notation. The change fixes that.
-
-2003-05-28 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-beginning-of-word): Generalize it to skip
- arbitrary number of words.
- (mh-letter-complete-or-space): New interactive function that
- allows space character to be used for completion.
- (mh-letter-mode-map): Add key binding to allow space to be used
- for completion.
-
-2003-05-27 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el (mh-compose-prompt-flag): Customizable variable
- that controls whether the user is prompted when composing a draft.
- It replaces mh-dont-prompt-for-address-flag (closes SF #745622).
-
- * mh-comp.el (mh-letter-next-header-field): If the point is in
- the header field name, then go the start of the header field
- instead of the next field.
- (mh-interactive-read-address, mh-interactive-read-string)
- (mh-letter-adjust-point): Use mh-compose-prompt-flag instead of
- mh-dont-prompt-for-address-flag.
-
-2003-05-27 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el (mh-tool-bar-define): Fix incorrect usage of
- set-specifier (closes SF #745655). Also the button enabling code
- interacts poorly with font-lock in XEmacs. So disable that.
-
-2003-05-26 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-folder-from-address): The function
- message-fetch-field expects that the buffer is narrowed to the
- mail header. The change makes sure that this is indeed the case.
-
- * mh-mime.el (mh-add-missing-mime-version-header)
- (mh-decode-message-body): Same as above.
-
-2003-05-25 Satyaki Das <satyakid@stanford.edu>
-
- * mh-alias.el (mh-alias-minibuffer-confirm-address): Modified to
- use mh-beginning-of-word.
-
- * mh-comp.el (mh-letter-confirm-address): Calling
- mh-alias-reload-maybe can be expensive. So do it only if we really
- need to.
-
-2003-05-25 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-comp.el (mh-letter-confirm-address): Load aliases if not yet
- loaded.
-
- * mh-alias.el (mh-alias-reload-maybe): Autoload it since it is
- used in mh-comp.el.
-
-2003-05-24 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-letter-skip-leading-whitespace-in-header-field):
- New function to skip leading space and tab characters when placing
- point in a header field.
- (mh-letter-next-header-field, mh-letter-previous-header-field):
- Skip leading whitespace when using TAB to navigate to header
- fields.
- (mh-letter-confirm-address): New interactive function that
- displays the last expansion of the last alias when "," is typed.
- (mh-letter-mode-map): Add key binding for "," (closes SF #745634).
-
-2003-05-23 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el (mh-edit-again, mh-forward, mh-send)
- (mh-send-other-window, mh-send-sub): Modified so that if
- mh-dont-prompt-for-address-flag is non-nil, then MH-E won't prompt
- for addresses to send mail to and instead directly jump to the
- draft (closes SF #745622).
- (mh-letter-complete-function-alist): An alist that is used to
- decide which completion function to use in which header. This
- variable should probably be customizable.
- (mh-letter-complete): Now uses mh-letter-complete-function-alist.
- (mh-letter-header-field-at-point, mh-letter-next-header-field)
- (mh-letter-next-header-field-or-indent)
- (mh-letter-previous-header-field): Commands for easier navigation
- to header fields.
- (mh-dont-prompt-for-address-flag): Variable which controls
- whether MH-E prompts for addresses.
- (mh-interactive-read-address, mh-interactive-read-string): Two
- functions to ask user for input depending on the value of the
- above flag.
- (mh-letter-adjust-point): New function that sets point to the
- first header field.
- (mh-letter-mode-map): Add key bindings for TAB and S-TAB (closes
- SF #745627).
-
-2003-05-23 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-comp.el (mh-complete-word): New function which is
- approximately equivalent to mail-abbrev-complete-alias.
- (mh-beginning-of-word): Refactor repeated code into its own
- function.
- (mh-folder-expand-at-point): Make Fcc completion work in XEmacs
- by not using mail-abbrev-complete-alias.
-
- * mh-alias.el (mh-alias-letter-expand-alias): Make alias
- expansion work in XEmacs. Replace the use of the function
- mail-abbrev-complete-alias, which isn't present in XEmacs.
-
- * mh-mime.el (mh-mml-to-mime): If a MIME message is created
- immediately after starting MH-E then invoking mh-mml-to-mime
- causes an error because "message" isn't being loaded. The change
- works around this problem.
- (mh-mime-maybe-display-alternatives): Give better indication of
- which MIME parts are alternatives.
-
-2003-05-22 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-add-sequence-notation, mh-remove-sequence-notation):
- Just delete and add the same character in the scan line to make
- font-lock refontify it. The previous trick of removing all text
- properties didn't work in XEmacs.
-
- * mh-seq.el (mh-put-msg-in-seq): Complain if the user tries to
- create an invalid MH sequence.
-
- * mh-mime.el (mh-mime-display-alternative): Modified to
- optionally display alternatives as buttons.
- (mh-mime-maybe-display-alternatives): New function which displays
- alternative MIME parts as buttons.
- (mh-mime-save-part): Initially mh-mime-save-parts-directory is
- nil and calling file-name-as-directory with nil arg leads to an
- error. So fall back on the default-directory in that case.
-
- * mh-customize.el (mh-display-buttons-for-alternatives-flag): New
- customizable variable that controls display of the alternative
- MIME parts (closes SF #741288).
-
-2003-05-22 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-invisible-header-fields): Commented out
- "User-Agent:". It's similar to X-Mailer, so display it.
-
-2003-05-21 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el (mh-tool-bar-define): Add an optional argument
- to the button description that can dynamically enable/disable
- buttons.
- (mh-tool-bar-define): The alias grabbing button is disabled if the
- current message doesn't have a From header or if the sender is
- already in the user's alias. This functionality was inadvertently
- lost when the Emacs/XEmacs toolbar unification took place.
-
-2003-05-20 Satyaki Das <satyakid@stanford.edu>
-
- * mh-unit.el (mh-unit-construct-call-graph): Be more aggressive
- and flag interactive functions that aren't autoloaded or have no
- key bindings.
- (mh-unit-interactive-function-p): Remove now unused function.
- (mh-unit, mh-unit-construct-call-graph): Replace mh-files with
- mh-unit-files.
-
-2003-05-20 Bill Wohler <wohler@newt.com>
-
- * mh-unit.el (mh-prune-trailing-spaces): Renamed to
- mh-unit-prune-trailing-spaces to clean up the namespace.
- (mh-files): Renamed to mh-unit-files. Ditto.
- (mh-unit): Checkdoc fix.
-
- * mh-index.el (mh-index-p): Added autoload cookie since mh-index-p
- is used by mh-customize.el. This calls for another mh-unit test
- that looks for mh-autoloads for functions that are no longer used
- in other files.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-05-20 Satyaki Das <satyakid@stanford.edu>
-
- * mh-unit.el (mh-unit-construct-call-graph): Factor out the code
- to read the lisp files to a separate function. Also change it to
- construct a function call-graph. Autoloaded functions are taken
- into account.
- (mh-unit-find-all-used-functions, mh-unit-called-functions)
- (mh-unit-find-all-unused-functions): Find all unused functions by
- computing a fixed point starting from the set of top level
- functions.
- (mh-unit-analyze-block): Removed.
- (mh-unit-update-call-graph): mh-unit-functions-called was renamed
- with modifications to update the function call graph.
-
-2003-05-19 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-notate): Modified to keep track of notation
- that was replaced when sequence notation is added. Thus when the
- sequence is deleted, the original notation is recovered.
- (mh-add-msgs-to-seq): Modified to work with the new sequence
- notation code.
-
- * mh-seq.el (mh-delete-seq, mh-put-msg-in-seq): Simplified since
- we don't need to handle tick and unseen sequences specially any
- more.
- (mh-narrow-to-seq): Don't need to call mh-notate-user-sequences
- since mh-copy-seq-to-eob already does that.
- (mh-widen): Remove sequence notation, so that notation when
- messages are replied to aren't lost.
- (mh-copy-seq-to-eob): Simplified with the use of
- mh-iterate-on-range.
- (mh-thread-inc): This function doesn't need to notate user
- sequences since its callers already do that.
- (mh-thread-parse-scan-line): Simplified since mh-note-seq doesn't
- appear in scan lines it is given as arguments.
- (mh-thread-update-scan-line-map): Remove the test, since its
- caller already does the required check.
- (mh-thread-folder): Simplified by the use of mh-iterate-on-range.
- (mh-tick-add-overlay, mh-tick-remove-overlay, mh-notate-tick):
- These functions aren't needed any more, since overlays aren't used
- any more. Also overlays aren't portable to XEmacs, so nasty
- conditional code that used overlays in Emacs and extents in XEmacs
- have been eliminated.
- (mh-toggle-tick): Generalize it to work on a range of messages
- like the other interactive messages.
-
- * mh-funcs.el (mh-undo-folder): Use mh-remove-all-notation
- instead of mh-unmark-all-headers.
-
- * mh-e.el (mh-folder-font-lock-keywords): The entry for unseen
- sequence highlighting is now done by the macro.
- (mh-generate-sequence-font-lock): New macro to highlight any
- arbitrary sequence. This macro is invoked twice to get the
- highlighting for unseen and tick sequences.
- (mh-sequence-notation-history, mh-folder-mode): New variable that
- keeps track of the old notation when a message is notated with
- mh-note-seq.
- (mh-regenerate-headers, mh-get-new-mail): Add appropriate calls to
- mh-notate-user-sequences and mh-remove-all-notation.
- (mh-unmark-all-headers): Add comment that this function shouldn't
- be used any more.
- (mh-add-sequence-notation, mh-remove-sequence-notation): New
- functions to notate message with mh-note-seq and to remove it.
- (mh-remove-all-notation): Simplified to use mh-iterate-on-range.
- (mh-process-commands): Use mh-remove-all-notation instead of
- mh-unmark-all-headers.
- (mh-notate-user-sequences, mh-delete-msg-from-seq): Simplified
- since the tick and unseen sequences don't need special handling
- any more.
- (mh-internal-seq): Make it possible to dynamically change what
- sequences are treated as internal (internal means font lock is
- used to highlight the sequence).
- (mh-clear-text-properties): Removed since it isn't needed
- anymore.
-
-2003-05-19 Satyaki Das <satyakid@stanford.edu>
-
- * mh-unit.el (mh-unit-analyze-block, mh-unit-interactive-function-p)
- (mh-unit-find-all-unused-functions): Change argument name bl to
- block.
-
-2003-05-19 Satyaki Das <satyakid@stanford.edu>
-
- * mh-unit.el (mh-unit-find-all-unused-functions): New interactive
- function to find all unused functions in MH-E.
- (mh-unit-analyze-block, mh-unit-interactive-function-p)
- (mh-unit-functions-called): Functions used by
- mh-unit-find-all-unused-functions do its job.
-
- * Makefile (compile): Byte-compile mh-unit.el, since the analysis
- to find unused code runs faster when compiled.
-
-2003-05-18 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-notate-deleted-and-refiled): Add autoload
- declaration since this function is used in mh-index.el.
-
- * mh-e.el, mh-customize.el, mh-utils.el: Adjust require/provide
- statements so that mh-e.el isn't loaded twice.
-
-2003-05-15 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-defun-show-buffer): Arrange for the current
- line in the folder buffer to be highlighted even when we are in
- the show buffer.
-
-2003-05-14 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-read-range): Allow this to work on invalid
- sequences that only MH-E knows about.
-
- * mh-index.el (mh-create-sequence-map, mh-index-add-to-sequence)
- (mh-index-delete-from-sequence): Don't consider sequences that
- aren't valid MH sequences.
-
- * mh-e.el (mh-valid-seq-p): New predicate to check if a symbol
- could be a MH sequence.
- (mh-undefine-sequence, mh-define-sequence): Don't execute "mark"
- unless the sequence name is a valid MH sequence.
-
- * mh-utils.el (mh-exec-cmd): In case an error happens in the
- call-process and non-strings are present in ARGS, then the error
- message isn't properly displayed. The change fixes this.
-
-2003-05-14 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-mime-save-part): Bug Fix: Make sure
- `mm-default-directory' gets a trailing "/" if
- `mh-mime-save-parts-directory' doesn't have one. Otherwise the
- default in the prompt of `mh-mm-save-part' will be wrong. Perhaps
- `mh-mm-save-part' needs to do this check itself.
-
-2003-05-14 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-unpropagated-sequences): New function and
- variable to keep track of sequences that shouldn't be propagated.
- (mh-create-sequence-map, mh-index-add-to-sequence)
- (mh-index-delete-from-sequence): Use mh-unpropagated-sequences to
- stop changes to some sequences being reflected back to the source
- folders.
-
-2003-05-13 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-e.el (mh-process-commands): Preserve sequences when messages
- are refiled (closes SF #737128).
-
- * mh-index.el (mh-create-sequence-map)
- (mh-index-create-sequences): Refactor code that is reused into a
- new function.
-
- * mh-customize.el (mh-refile-preserves-sequences-flag): New
- customizable flag that controls whether sequences are preserved
- when messages are refiled.
-
-2003-05-13 Eric Ding <ericding@alum.mit.edu>
-
- * mh-e.el (mh-scan-format): The argument for scan format files
- should be -form, not -format.
-
-2003-05-13 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-widen): The scan line map stack was not being
- properly updated when ALL-FLAG is non-nil. The change fixes that.
-
- * mh-e.el (mh-reset-threads-and-narrowing): The change resets the
- scan line map stack.
-
-2003-05-12 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-thread-scan-line-map-stack)
- (mh-thread-old-scan-line-map): Instead of the old scan line map,
- now we need to maintain a stack of scan line maps.
- (mh-narrow-to-seq): Modified so that multiple level of narrowings
- can be done. We now maintain a stack of old views instead of
- hiding the old scan lines. This makes it possible to have
- multiple levels of narrowings.
- (mh-widen): A optional prefix arg was added to allow undoing all
- narrowing.
- (mh-read-seq-default, mh-read-range): Don't use
- mh-narrowed-to-seq, since it doesn't exist any more.
- (mh-thread-initialize-hash, mh-thread-initialize): The
- mh-thread-initialize function has been refactored.
- (mh-thread-update-scan-line-map): Maintain notations in the stack
- of scan line maps.
- (mh-notate-tick, mh-toggle-tick): Simplified, since we don't have
- mh-narrowed-to-seq any more. This means there is a slight loss of
- functionality. Earlier if we narrowed to the tick sequence the
- ticked messages weren't highlighted. This feature isn't present
- any more.
-
- * mh-e.el (mh-execute-commands, mh-reset-threads-and-narrowing)
- (mh-folder-sequence-menu, mh-get-new-mail): Use
- mh-folder-view-stack instead of the now removed
- mh-narrowed-to-seq.
- (mh-narrowed-to-seq, mh-tick-seq-changed-when-narrowed-flag):
- These variables have been removed.
- (mh-folder-view-stack): New variable to keep track of a stack of
- narrowings.
- (mh-execute-commands, mh-get-new-mail): Add extra argument to
- mh-widen so that all narrowings are undone.
-
- * Makefile (MH-E-SRC, MH-E-OTHERS): Move mh-gnus.el from MH-E-SRC
- to MH-E-OTHERS so that it isn't byte compiled.
-
-2003-05-10 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-read-seq): Improve the function a bit by adding
- history to the sequence prompt.
-
-2003-05-09 Satyaki Das <satyakid@stanford.edu>
-
- * mh-gnus.el: New file that won't be byte-compiled. From now on
- having different Gnus versions at run-time and compile-time won't
- cause errors in MH-E.
-
- * mh-mime.el (mh-small-show-buffer-p, mh-display-smileys)
- (mh-display-emphasis): Handle all legal values of
- font-lock-maximum-size. The existing code assumed didn't consider
- the case where it could be an alist.
- (mh-small-image-p): Simplified, so that aliasing XEmacs functions
- in Emacs isn't necessary any more.
- (mh-mm-display-part): Remove unnecessary call to fboundp. The
- mh-funcall-if-exists does that for us any way.
- (mh-defun-compat, gnus-local-map-property, mm-merge-handles)
- (mm-set-handle-multipart-parameter, mm-readable-p)
- (mm-long-lines-p, mm-keep-viewer-alive-p, mm-destroy-parts)
- (mh-mm-save-part, mm-handle-multipart-ctl-parameter): These
- compatibility functions have been moved to mh-gnus.el.
-
- * Makefile (MH-E-SRC): Add mh-gnus.el.
-
- * mh-seq.el (mh-narrow-to-header-field)
- (mh-current-message-header-field): Checkdoc fixes.
-
- * mh-e.el (mh-undefine-sequence): Since mh-coalesce-msg-list
- returns a list, apply is needed.
-
-2003-05-09 Noel Cragg <noel@red-bean.com> (tiny change)
-
- * mh-junk.el (mh-spamassassin-blacklist): Separate "--local" and
- "--no-rebuild" arguments to call-process.
- [Patch committed by satyaki]
-
-2003-05-08 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-translate-range): Take into account different
- semantics of split-string in Emacs and XEmacs.
- (mh-read-pick-regexp, mh-narrow-to-from, mh-narrow-to-cc)
- (mh-narrow-to-to, mh-narrow-to-header-field)
- (mh-current-message-header-field, mh-narrow-to-range): New
- narrowing functions that can select messages based on different
- message headers.
-
- * mh-utils.el (mh-show-limit-map): Add new narrowing functions
- callable from the show buffer.
-
- * mh-e.el (mh-help-messages): Add help text for new functions.
- (mh-limit-map): Add new narrowing functions (closes SF #732823).
-
-2003-05-07 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-collect-folder-names): Use mh-exec-daemon to
- run flists. This means we don't have to remember to expand the MH
- executable in the mh-progs path.
- (mh-exec-cmd-daemon): Return the new process object produced.
-
-2003-05-06 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-folder-font-lock-unseen): Use mh-seq-list to do
- unseen sequence highlighting instead of reading the .mh_sequences
- file from disk every time.
-
-2003-05-05 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-show-sequence-map): Add key binding for S'
- (closes SF #732825).
-
- * mh-e.el (mh-sequence-map): Ditto.
- (mh-help-messages): Updated for S'.
-
-2003-05-04 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-write-data): The with-temp-buffer macro
- is a bit better than write-file, so use that instead.
-
-2003-05-03 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-update-maps, mh-index-search)
- (mh-index-sequenced-messages): Write index data to disk. This
- allows us to recover index folder information if Emacs is
- restarted, or the index folder is visited after the buffer has
- been killed (closes SF #701762).
- (mh-index-write-data, mh-index-read-data)
- (mh-index-write-hashtable, mh-index-read-hashtable): Functions to
- store and read index data information to disk.
- (mh-index-insert-folder-headers, mh-index-group-by-folder): We
- can no longer use object identity to compare strings, since they
- might have been read back from disk.
-
- * mh-e.el (mh-index-data-file): New variable that stores the name
- of the file that keeps track of index folder data.
- (mh-make-folder): Read index folder data if available.
-
- * mh-utils.el (mh-show, mh-summary-height, mh-modify): Make
- checkdoc happy.
-
- * mh-seq.el (mh-tick-add-overlay): Rearrange code to make code
- more uniform.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-05-02 Satyaki Das <satyakid@stanford.edu>
-
- * mh-seq.el (mh-tick-add-overlay): If a message with a short scan
- line is ticked, then the highlighting didn't extend to the right
- margin. This change fixes that.
-
-2003-05-01 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-help-messages): Added brackets around / and
- downcased limit to be consistent with other commands with
- punctuation keybindings. Don't document aliases.
-
-2003-05-01 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-read-range): Fix comment.
-
-2003-04-30 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-help-messages): Better documentation for the F map.
-
-2003-04-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-utils.el (mh-find-path): Cache folder names so that
- folder name completion is always fast.
- (mh-flists-partial-line, mh-flists-process): Variables used for
- pre-caching folder names.
- (mh-collect-folder-names, mh-collect-folder-names-filter)
- (mh-populate-sub-folders-cache): Functions to pre-cache folder
- names.
- (mh-exec-cmd): Produce more info in *MH-E Log*.
-
- * mh-index.el (mh-index-search): Call the correct function.
- (mh-index-sequenced-messages): If folders is nil, then all mail
- is searched. The change restores that.
-
-2003-04-30 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-summary-height): Move variable integer out
- of defcustom, and instead specify that `nil' means to calculate
- that size dynamically. Fixes SF #723267.
-
- * mh-utils.el (mh-summary-height): New function. Return ideal
- mh-summary-height value for current frame height.
- (mh-show-msg): Use it.
-
-2003-04-30 Mark D. Baushke <mdb@gnu.org>
-
- * mh-index.el (mh-index-ticked-messages): Fix prompt and
- description string.
- (mh-index-new-messages): Ditto.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-index.el (mh-index-sequenced-messages): Renamed from
- mh-index-new-messages with minor argument change.
- (mh-index-new-messages): Implement by calling
- mh-index-sequenced-messages with the appropriate arguments.
- (mh-index-ticked-messages): New function. Does the same thing as
- mh-index-new-messages, but on its own set of folders and using the
- mh-tick-seq instead of mh-unseen-seq.
-
- * mh-e.el (mh-folder-map): Add "F'" to the map for
- mh-index-ticked-messages.
- (mh-help-messages): Replace broken [t]hread with [n]ew messages.
-
- * mh-customize.el (mh-index-ticked-messages-folders): New user
- customizable flag that controls the folders to be searched by
- mh-index-ticked-messages.
-
- * mh-utils.el (mh-show-index-ticked-messages): Wrapper for
- mh-index-ticked-messages.
- (mh-show-folder-map): Add "F'" to the map for
- mh-index-ticked-messages.
-
-2003-04-30 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-search): The old cur in the source folder
- might not exist. This could cause mh-exec-cmd to fail. So don't
- add an error message in that case.
-
-2003-04-29 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-folder-from-address): Modified to allow multiple
- Cc: headers to work properly.
- (mh-inc-folder, mh-visit-folder): Fix an off by one error.
-
- * mh-utils.el (mh-notate): Update the scan line map. This fixes a
- tiny bug. In threaded view, if a message is replied to then the
- message is notated with a "-". Now if inc is done then the "-"
- added is lost. The change fixes this.
-
- * mh-seq.el (mh-translate-range): Use the correct function.
- (mh-thread-update-scan-line-map): New function that updates the
- scan line map when a message is notated.
-
-2003-04-28 Satyaki Das <satyakid@stanford.edu>
-
- * mh-index.el (mh-index-parse-search-regexp): Avoid compiler
- warning in GNU Emacs 21.3.
-
- * mh-seq.el (mh-widen): Ditto.
-
-2003-04-28 Satyaki Das <satyakid@stanford.edu>
-
- * mh-customize.el (mh-interpret-number-as-range-flag): New user
- customizable flag that controls whether a single number, N is
- interpreted as the range last:N.
-
- * mh-seq.el (mh-read-range): Generalize it for use when reading
- range to scan.
- (mh-interactive-range): Modified to use the new mh-read-range.
-
- * mh-speed.el (mh-speed-view): Use mh-read-range instead of the
- now removed mh-read-msg-range function.
-
- * mh-funcs.el (mh-pack-folder): Ditto.
-
- * mh-e.el (mh-rescan-folder, mh-visit-folder): Ditto.
- (mh-read-msg-range): Removed.
-
- * mh-loaddefs.el: Regenerated
-
-2003-04-27 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-range-completion-function): Fix checkdoc warning.
- (mh-iterate-on-range): Mention that the macro can iterate over a
- MH message range too.
-
-2003-04-27 Bill Wohler <wohler@newt.com>
-
- * mh-unit.el (mh-unit): As it turns out, lm-crack-copyright has
- been updated to handle multiple-line copyrights in 21.3, so
- updated code to run lm-verify only if user has 21.3 or greater.
- Delete buffers after use, unless user already had buffer open.
-
-2003-04-27 Satyaki Das <satyakid@stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-index.el (mh-index-search): The MH command "refile" changes
- cur. The change restores cur in source folders.
- (mh-index-new-messages): Use the appropriate arguments for
- mh-read-seq.
-
- * mh-seq.el (mh-read-seq-default, mh-read-seq): Restore these
- functions to just read sequence names.
- (mh-range-seq-names, mh-range-history, mh-range-completion-map)
- (mh-range-completion-function, mh-read-range): New function which
- reads MH range with completion and history.
- (mh-interactive-range): Use mh-read-range instead of
- mh-read-seq-default.
- (mh-put-msg-in-seq): Change documentation about MH message range.
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Change
- documentation about MH message range.
-
- * mh-funcs.el (mh-copy-msg, mh-print-msg): Ditto.
-
- * mh-e.el (mh-delete-msg, mh-delete-msg-no-motion)
- (mh-refile-msg, mh-undo, mh-delete-msg-from-seq): Ditto.
-
- * mh-comp.el (mh-forward): Ditto.
-
-2003-04-26 Satyaki Das <satyakid@stanford.edu>
-
- * mh-comp.el, mh-e.el, mh-funcs.el, mh-junk.el, mh-seq.el:
- Replace msg-or-seq with range everywhere.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-04-25 Satyaki Das <satyakid@stanford.edu>
-
- * mh-e.el (mh-index-sequence-search-flag, mh-folder-mode): New
- local variable to remember that a folder buffer contains results
- from a sequence search. This is needed so that "C-u F i" will work
- as expected.
- (mh-visit-folder): Create sequences in the index folder.
- (mh-process-commands, mh-delete-msg-from-seq): If speedbar is on
- then update the speedbar message counts immediately.
- (mh-delete-msg-from-seq): Make the code faster by calling "mark"
- just once. Also update source folder sequence if messages are
- being deleted from a sequence in an index folder.
- (mh-undefine-sequence): Simplified to remove the speedbar updating
- code. Also DTRT and don't change any sequence when called with an
- empty list of messages.
- (mh-refile-msg, mh-delete-msg): Move to next message only if the
- current message has been deleted or refiled, as the case may be.
-
- * mh-utils.el (mh-show-msg): Update the message counts in the
- speedbar, if it is on, immediately.
- (mh-speed-flists-active-p, mh-speed-flists-inhibit-flag): A new
- flag has been added which inhibits updating of the speedbar. This
- is used to avoid needless speedbar updates when
- mh-execute-commands is called in index folders.
-
- * mh-speed.el (mh-speed-flists): Extended so that multiple
- folders can be given as arguments. Also the code that kept track
- of the current folder, needed since flists adds an extra ?+ char
- at the end of the current folder name, wasn't entirely correct.
- That has also been fixed.
-
- * mh-seq.el (mh-delete-seq, mh-put-msg-in-seq): Modified so that
- sequence in source folder is updated if we delete a sequence in an
- index folder.
- (mh-read-seq, mh-read-seq-default, mh-translate-range)
- (mh-interactive-msg-or-seq): The mh-interactive-msg-or-seq
- function can read in an arbitrary MH message range.
- (mh-iterate-on-msg-or-seq): The macro has been extended to work on
- a MH range.
- (mh-subject-to-sequence, mh-subject-to-sequence-unthreaded)
- (mh-subject-to-sequence-threaded, mh-thread-find-msg-subject): Fix
- the mh-subject-to-sequence function so that it will work in
- threaded folders too.
- (mh-tick-add-overlay): Fix a leak of overlays.
- (mh-toggle-tick): Ticking, or unticking, messages in the index
- folder is propagated to the source folders (closes SF #709664).
-
- * mh-index.el (mh-flists-results-folder, mh-flists-sequence)
- (mh-flists-called-flag): New variables to implement searching for
- arbitrary sequences.
- (mh-index-generate-pretty-name): Updated so that folder names are
- generated for flists search that can take any sequence name.
- (mh-index-search): Since sequences are now properly maintained the
- unseen-flag argument isn't needed and hence removed. Also redoing
- a sequence search with "C-u F i" is handled correctly. Finally
- the speedbar is updated to reflect the new index folder created.
- (mh-index-create-sequences): New function that creates sequences
- in the index folder.
- (mh-index-matching-source-msgs, mh-index-execute-commands):
- Improved so that scan lines for refiled/deleted messages are
- removed from the source folders as well.
- (mh-index-add-to-sequence, mh-index-delete-from-sequence): New
- functions to update sequences in source folder to reflect changes
- in index folder.
- (mh-index-quote-for-shell): A utility function to that quotes
- characters with special meaning to /bin/sh.
- (mh-flists-execute, mh-index-new-messages): Updated to search for
- arbitrary sequences (closes SF #718833).
-
- * mh-loaddefs.el: Regenerated.
-
-2003-04-25 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-kill-folder-suppress-prompt-hook): New hook
- used by mh-kill-folder to suppress the prompt.
-
- * mh-funcs.el (mh-kill-folder): Suppress prompt not if
- mh-index-data is non-nil, but if any functions in
- mh-kill-folder-suppress-prompt-hook return non-nil.
-
- * mh-index.el (mh-index-p): New function with returns non-nil if
- the current folder was generated by an index search for use by
- mh-kill-folder-suppress-prompt-hook
-
- * mh-unit.el (mh-unit): Commented out lm-verify step until code
- updated to handle split Copyright lines.
-
- * mh-e.el (mh-version): Set to 7.3+cvs.
-
-2003-04-24 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.3.
-
- * MH-E-NEWS, README: Updated for release 7.3.
-
- * mh-e.el (Version, mh-version): Updated for release 7.3.
-
-2003-04-24 Satyaki Das <satyakid@stanford.edu>
-
- * mh-xemacs-compat.el (mh-utils): Require mh-utils at compile
- time, since the mh-do-in-xemacs macro is used.
-
- * mh-inc.el (cl): Require cl at compile time since we are using
- the loop and setf macros.
-
-2003-04-24 Satyaki Das <satyakid@stanford.edu>
-
- * mh-unit.el (mh-files): Fix the list of files to check.
-
-2003-04-24 Bill Wohler <wohler@newt.com>
-
- * ChangeLog: Appended copyright to end of file.
-
- * Makefile: Added copyright and license.
-
- * README: Added copyright.
-
- * import-emacs: Changed copyright from Newt Software to Bill
- Wohler and use license from mh-e.el, except that this file is
- a part of MH-E, not GNU Emacs.
-
- * mh-alias.el: Updated copyright so that it doesn't wrap upon
- advice from Richard Stallman who said to use two-digit years when
- they are surrounded by 4-digit years that are in the same century
- and to break up copyrights on multiple lines.
- * mh-comp.el: Ditto.
- * mh-e.el: Ditto.
- * mh-funcs.el: Ditto.
- * mh-identity.el: Ditto.
- * mh-mime.el: Ditto.
- * mh-seq.el: Ditto.
- * mh-utils.el: Ditto.
- * mh-xemacs-compat.el: Ditto.
-
- * mh-unit.el: New file. Unit tests for MH-E. This version merely
- runs checkdoc and lm-verify which is useful before releasing the
- software. It can and should be expanded to do real unit tests.
-
-2003-04-22 Mark D. Baushke <mdb@gnu.org>
-
- * mh-alias.el: Update Copyright.
- * mh-comp.el: Ditto.
- * mh-customize.el: Ditto.
- * mh-e.el: Ditto.
- * mh-funcs.el: Ditto.
- * mh-identity.el: Ditto.
- * mh-index.el: Ditto.
- * mh-mime.el: Ditto.
- * mh-pick.el: Ditto.
- * mh-seq.el: Ditto.
- * mh-speed.el: Ditto.
- * mh-utils.el: Ditto.
- * mh-xemacs-compat.el: Ditto.
-
-2003-04-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-normalize-folder-name): Make the completion
- code work properly with XEmacs. This change is needed since
- split-string behaves differently in XEmacs than it does in GNU
- Emacs.
- (mh-exec-cmd-error): Add a comment, so that we change it later on.
-
-2003-04-18 Steve Youngs <youngs@xemacs.org>
-
- * mh-xemacs-icons.el (mh-xemacs-icons): Provide 'mh-xemacs-icons'
- not 'mh-xemacs-toolbar'.
-
- * mh-xemacs-compat.el (mh-xemacs-toolbar): Remove require, it's
- now called 'mh-xemacs-icons' and it is required from
- 'mh-customize'.
-
- * mh-customize.el: Require 'mh-xemacs-icons' instead of
- 'mh-xemacs-toolbar'.
-
-2003-04-17 Peter S Galbraith <psg@debian.org>
-
- * mh-xemacs-icons.el: New file (renamed from mh-xemacs-toolbar.el).
- Holds XEmacs icons.
-
- * mh-xemacs-toolbar.el: Deleted.
-
- * Makefile: Incorporate the file renaming.
-
-2003-04-15 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-forward): Pass a list of messages into
- mh-compose-and-send-mail instead of msg-or-seq.
- (mh-annotate-msg): The previous version called
- mh-iterate-on-msg-or-seq in the letter buffer. The new version
- simply adds the ability to operate on message lists. Thanks to
- Satyaki for the fix and suggestion for passing a list from
- mh-forward.
-
-2003-04-14 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-annotate-msg): Updated to handle msg-or-seq for
- mh-forward was passing a msg-or-seq to mh-compose-and-send-mail
- which in turn passed the msg-or-seq to mh-annotate-msg. In
- particular, forwarding a region failed. Note that the msgs
- argument in much of mh-comp.el should really be converted to
- msg-or-seq accordingly. But not now, unless something is broken as
- was the case here. We can revamp after the release.
-
-2003-04-13 Bill Wohler <wohler@newt.com>
-
- * mh-funcs.el (mh-kill-folder): Added space after prompt to give
- the (yes or no) bit a little elbow room.
-
- * mh-xemacs-toolbar.el: Removing a copyright is a no-no.
- Reinstated Steve's copyright.
-
-2003-04-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-do-in-gnu-emacs, mh-do-in-xemacs): Add
- indentation hooks for the macros.
-
-2003-04-11 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el, mh-comp.el, mh-customize.el, mh-funcs.el,
- mh-identity.el, mh-inc.el, mh-index.el, mh-junk.el, mh-utils.el:
- Merged in changes from CVS GNU Emacs. These included the removal
- of trailing whitespace.
-
- * mh-customize.el: The "anti-entropy" check-in. Moved groups
- around slightly to reflect commentary. Moved defcustoms around
- to preserve alphabetization. Big diff, little content.
- (mh-xemacs-use-toolbar-flag): Doc fix.
- (mh-xemacs-toolbar-position): Fixed typo in docstring.
- (mh-default-folder-list): Updated docstring to reflect new Check
- Recipient tag. Also, set type of Address to regexp.
- (mh-x-mailer-string): Moved to mh-comp.el where it is used.
-
- * mh-comp.el (mh-x-mailer-string): Moved here from customize.el.
- Not quite sure how it got to mh-customize.el in the first place.
-
- * mh-e.el (mh-folder-folder-menu): Added Folder -> View New
- Messages menu item.
-
- * mh-utils.el (mh-show-folder-menu): Ditto.
-
- * mh-inc.el: Added Change Log comment (lm-verify fix).
-
- * mh-index.el (mh-index-search): Added documentation about prefix
- argument for users, in addition to documentation for programmers.
-
- * mh-mime.el (mh-edit-mhn, mh-edit-mhn, mh-mml-to-mime): Docstring
- fixes germaine to the change whereby we now check for MIME
- directives before sending.
-
- * mh-xemacs-toolbar.el: Fixed copyright. Added Change Log comment.
- (lm-verify fix). Added standard MH-E local variables. Removed
- time-stamp stuff.
-
-2003-04-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-iterate-on-msg-or-seq): Add a missed comma.
-
-2003-04-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-visit-folder): Prompt before reusing
- existing folder buffer.
-
- * mh-xemacs-toolbar.el (require): Require mh-utils at compile
- time to avoid compilation error when doing "make bootstrap" in
- CVS Emacs.
-
- * mh-inc.el (mh-inc-spool-list): Declare it so that a compile
- time warning is avoided when doing "make bootstrap" in CVS Emacs.
-
-2003-04-10 Peter S Galbraith <psg@debian.org>
-
- * mh-inc.el (mh-inc-spool-generator): Changed to a defun instead
- of a defmacro, applying Satyaki's patch.
- (mh-inc-spool-def-key): same.
- (mh-inc-spool-make): same.
-
- * mh-utils.el: define-key "I" in mh-show-mode-map for
- mh-inc-spool-map.
-
- * mh-comp.el (mh-modify-header-field): Remove debug message.
-
-2003-04-10 Peter S Galbraith <psg@debian.org>
-
- * mh-inc.el (mh-inc-spool-map-help): Default to nil.
- (mh-inc-spool-map): Make "?" key display message when
- `mh-inc-spool-map-help' is nil (instead of mh-inc-spool-map-help
- containing the message).
-
- * mh-e.el: require mh-inc.el
- * mh-e.el: define-key "I" in mh-folder-mode-map for mh-inc-spool-map.
- (mh-help-messages): Add help string for "I" key.
-
-2003-04-09 Peter S Galbraith <psg@debian.org>
-
- * mh-inc.el: New file. New feature to `inc' mail from various
- spool files into different folders.
-
- * mh-loaddefs.el: Regenerate for mh-inc's mh-inc-spool-list-set.
-
- * Makefile (MH-E-IMG): Add highlight icon.
- (MH-E-SRC): Add mh-inc.el file.
-
- * mh-customize.el (mh-inc-spool-list): New variable for new
- feature to `inc' mail from various spool files into different
- folders.
-
-2003-04-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-mail-delivery-buffer): Add a defconst for
- mh-mail-delivery-buffer.
-
- * mh-comp.el (mh-send-letter): Use mh-mail-delivery-buffer.
-
- * mh-mime.el (mh-small-image-p): Add mh-funcall-if-exists to
- avoid compiler warning in GNU Emacs.
-
-2003-04-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-small-image-p): Make the function slightly more
- error-resistant in XEmacs.
-
- * mh-seq.el (mh-narrow-to-seq, mh-widen): Update tool-bar-map in
- the show buffer if needed. This allows us to display the widen
- button in the show buffer only when the folder is narrowed.
-
- * mh-customize.el (mh-tool-bar-define): Changed so that a
- separate tool-bar-map is used in show-mode when folder is
- narrowed to a sequence.
-
-2003-04-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-iterate-on-msg-or-seq): Reinstate the use of
- make-symbol since using gensym causes compiler warnings in CVS
- Emacs.
-
-2003-04-08 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-forward): Function didn't handle a region of
- messages. Use new function mh-msg-or-seq-to-msg-list to get a list
- of messages in all circumstances. Also, use mh-coalesce-msg-list
- on message list before submitting to forw since this should always
- be done when calling a program to reduce the chance of exceeding
- command-line limits.
-
- * mh-seq.el (mh-iterate-on-msg-or-seq): Backed out previous
- change. A nil msg-or-seq should mean no messages, and Satyaki is
- going to use gensym instead of make-symbol.
- (mh-msg-or-seq-to-msg-list): New function to convert a msg-or-seq
- to a list of message numbers.
-
- * mh-e.el (mh-coalesce-msg-list): Touched up the docstring a
- little.
-
- * mh-funcs.el (mh-print-msg): Can now print regions, message
- lists, sequences and, of course, single messages. This version
- works a little differently from the old version. Instead of
- calling mhl | lpr once on all messages, mhl | lpr is called once
- per message in order to put each message's number in the header.
- Thanks to Satyaki for some code and ideas.
-
- * mh-seq.el (mh-iterate-on-msg-or-seq): The argument msg-or-seq
- can now be nil which means the current message. Make local symbols
- so that local variables don't step on user's symbols (the msgs
- symbol got me).
-
-2003-04-06 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-forward): Updated docstrings to indicate that a
- list of messages is acceptable as well.
-
- * mh-e.el (mh-delete-msg, mh-delete-msg-no-motion, mh-refile-msg)
- (mh-undo, mh-notate-user-sequences, mh-delete-msg-from-seq): Ditto.
-
- * mh-funcs.el (mh-copy-msg, mh-print-msg): Ditto.
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Ditto.
-
- * mh-seq.el (mh-put-msg-in-seq, mh-iterate-on-msg-or-seq)
- (mh-interactive-msg-or-seq): Ditto.
-
-2003-04-06 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Call
- mh-refile-a-msg and mh-delete-a-msg with nil as the message
- number since that is more efficient.
-
- * mh-seq.el (mh-iterate-on-msg-or-seq): Extended so that it will
- handle lists of messages numbers as well.
- (mh-put-msg-in-seq): Use mh-iterate-on-msg-or-seq to simplify the
- function.
-
- * mh-funcs.el (mh-copy-msg): Same as above.
-
- * mh-e.el (mh-refile-msg): Make it more efficient. Using nil in
- mh-refile-a-msg avoids needing to re-search-forward to that
- message.
- (mh-undo): Fix typo in interactive spec.
- (mh-notate-user-sequences): Generalize the function to take a
- msg-or-seq as argument.
- (mh-delete-msg-from-seq): Extend the function so that it is now
- able to subtract messages belonging in one sequence from another.
- (mh-undo): Unify the region and sequence handling. The message
- number branch of the function does extra stuff, so we can't merge
- that in.
-
-2003-04-06 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-forward): Use mh-interactive-msg-or-seq. Inserted
- consistent verbiage in docstring for msg-or-seq.
- (mh-reply): Don't mention default in opening line in all
- docstrings.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg)
- (mh-undo, mh-delete-msg-from-seq): Use mh-interactive-msg-or-seq.
- Inserted consistent verbiage in docstring for msg-or-seq. In
- mh-delete-msg-from-seq, renamed msg-or-region to msg-or-seq.
-
- * mh-funcs.el (mh-copy-msg, mh-print-msg): Use
- mh-interactive-msg-or-seq. Inserted consistent verbiage in
- docstring for msg-or-seq.
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Inserted
- consistent verbiage in docstring for msg-or-seq.
-
- * mh-seq.el (mh-msg-is-in-seq): Don't mention default in opening
- line in all docstrings.
- (mh-put-msg-in-seq): Use mh-interactive-msg-or-seq. Inserted
- consistent verbiage in docstring for msg-or-seq.
-
- * mh-e.el (mh-delete-msg, mh-delete-msg-no-motion, mh-refile-msg):
- Rewritten to use new mh-interactive-msg-or-seq function and
- mh-iterate-on-msg-or-seq macro. mh-delete-msg-no-motion gained the
- ability to operate on regions.
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Rewritten to
- use new mh-interactive-msg-or-seq function and
- mh-iterate-on-msg-or-seq macro thereby gaining the ability to
- operate on sequences or regions.
-
- * mh-seq.el (mh-iterate-on-msg-or-seq): New macro to execute code
- on a message, a region of messages, or a sequence. This macro
- should be in all functions that operate on messages to provide a
- uniform interface.
- (mh-interactive-msg-or-seq): New function used in interactive
- calls to obtain a message number, region, or sequence. This
- function should be in all functions that operate on messages to
- provide a uniform interface.
-
- * mh-utils.el (with-mh-folder-updating, mh-in-show-buffer): Use
- 'defun lisp-indent-hook property instead of 1 to fix indentation
- of these macros.
-
-2003-04-05 Peter S Galbraith <psg@debian.org>
-
- * mh-loaddefs.el: Regenerated.
- * mh-funcs.el (mh-ephem-message): autoload.
-
-2003-04-04 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-from-address): Minor Fix. Wrong ending of
- `when' block.
-
-2003-04-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-mml-directive-present-p): The regexp has been
- modified to recognize directives to encrypt/sign messages.
-
-2003-04-03 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-folder-from-address): E-mail messages missing the
- To: field, but which have a Cc: field should also be handled.
-
-2003-04-03 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-inc-folder): Modified the prompt text to read
- better.
-
- * mh-comp.el (mh-forward): Deleted local variable `compose'.
- Deleted obsolete setting of mh-{mmh|mml}-compose-insert-flag.
- (mh-letter-menu): Use mh-{mmh|mml}-directive-present-p instead of
- obsolete. mh-{mmh|mml}-compose-insert-flag.
- (mh-letter-mode): Deleted obsolete setting of
- mh-{mmh|mml}-compose-insert-flag.
- (mh-send-letter): This function now automatically runs the
- directive-to-MIME conversion if any directives are detected,
- rather than relying on the unreliable
- mh-{mmh|mml}-compose-insert-flag variables. Updated docstring
- accordingly.
-
- * mh-identity.el (mh-insert-identity): Use
- mh-{mmh|mml}-directive-present-p instead of obsolete.
- mh-{mmh|mml}-compose-insert-flag.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-mime.el (mh-mhn-compose-type, mh-mhn-compose-external-type)
- (mh-mhn-compose-forw, mh-edit-mhn, mh-mml-to-mime)
- (mh-mml-forward-message, mh-mml-attach-file)
- (mh-mml-secure-message-sign-pgpmime)
- (mh-mml-secure-message-encrypt-pgpmime): Deleted obsolete setting
- of mh-{mmh|mml}-compose-insert-flag.
- (mh-mml-directive-present-p): Checkdoc fix.
-
- * mh-utils.el (mh-mhn-compose-insert-flag,
- mh-mml-compose-insert-flag): Deleted. Replaced by
- mh-{mhn|mml}-directive-present-p.
-
-2003-04-03 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-folder-from-address): Fix minor problem with To:
- address processing.
-
- * mh-e.el (mh-folder-from-address): Bugfix match ?+ character not
- a "?+" string.
-
-2003-04-03 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-inc-folder): Add second optional argument for the
- folder to inc new mail into instead of mh-inbox.
-
-2003-04-03 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-from-address): The first match found in
- `mh-default-folder-list' is used.
-
- * mh-customize.el (mh-default-folder-list): Tweak docs
-
-2003-04-03 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-mime.el (mh-mhn-directive-present-p): New function to test if
- a MHN directive is present in the current buffer.
- (mh-mml-directive-present-p): New function to test if a MML
- directive is present in the current buffer.
-
- * mh-comp.el (mh-letter-mode): Originally this function checked if
- a #forw directive was present and set mh-mhn-compose-insert-flag
- to t. The modification generalizes this test so that one of the
- variables mh-{mml|mhn}-compose-insert-flag will get set if we have
- any sort of MHN or MML directive is already present.
-
- * mh-seq.el (tool-bar-map): Add a defvar to avoid compiler
- warnings in CVS version of GNU Emacs.
-
- * mh-utils.el (tool-bar-map): Same as above.
-
- * mh-e.el (tool-bar-map): same as above.
-
-2003-04-02 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-xemacs-toolbar.el (mh-xemacs-toolbar-toggle-tick-icon):
- Change color to match mh-folder-tick-face.
-
- * highlight.xpm: Same as above.
-
-2003-04-02 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-from-address): Check `mh-default-folder-list'
- for cases against the recipient instead of the originator.
-
- * mh-customize.el (mh-default-folder-list): Add extra boolean flag
- to conditionally check the recipient address instead of the
- originator.
-
-2003-04-02 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-folder-tick-face): Change tick highlight
- face to a background yellow-green, as suggested by Bill.
-
-2003-04-01 Peter S Galbraith <psg@debian.org>
-
- * highlight.xpm: New icon for mh-toggle-tick.
-
- * mh-xemacs-toolbar.el (mh-xemacs-icon-map): Add tool-bar entry
- for mh-toggle-tick.
- (mh-xemacs-toolbar-toggle-tick-icon): New constant.
-
- * mh-customize.el: Add tool-bar entry for mh-toggle-tick.
-
-2003-03-31 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-show-narrow-to-tick, mh-show-limit-map)
- (mh-show-sequence-menu): Add new interactive function
- mh-show-narrow-to-tick callable from the show buffer and arrange
- for a key binding and a menu entry.
-
- * mh-seq.el (mh-narrow-to-tick): New interactive function that
- narrows to the tick sequence.
-
- * mh-e.el (mh-folder-sequence-menu, mh-limit-map): Arrange for a
- key binding and a menu entry for mh-narrow-to-tick.
-
- * mh-comp.el (mh-letter-mode): Enable undo since we could be
- reusing a show buffer where undo is disabled (closes SF #712777).
-
-2003-03-31 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-sequence-menu): Add entry for mh-toggle-tick.
-
- * mh-utils.el (mh-show-sequence-menu): Add entry for
- mh-show-toggle-tick.
-
-2003-03-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-delete-seq): If the tick sequence is killed with
- "S k" then the highlighting wasn't getting removed. The change
- fixes this.
-
-2003-03-27 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-notate-user-sequences): Extend it so that only the
- messages in a part of the folder are notated.
- (mh-delete-msg-from-seq): Extend it so that it will delete all
- messages in the marked region.
- (mh-delete-a-msg-from-seq): New function that deletes a single
- message from a sequence.
- (mh-clear-text-properties): If there is a ticked unseen message
- and the message is removed from the unseen list with "S d" then
- unticking the message doesn't change the highlight. This change
- fixes this.
-
-2003-03-27 Peter S Galbraith <psg@debian.org>
-
- * mh-xemacs-toolbar.el (mh-xemacs-toolbar-*-icon): Use original
- 24x24 icons, changing background only.
-
-2003-03-27 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-junk.el (mh-spamassassin-identify-spammers): Remove unused
- variable buffer-exists.
- (mh-spamassassin-identify-spammers): Remove unused variable user.
-
- * mh-customize.el (mh-junk-choose): Tweak it to remove XEmacs
- compiler warning.
-
-2003-03-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-print-scan-lines): Handling of a boundary
- condition when messages from the last source folder had been
- removed was incorrect. This caused a folder header to appear
- without any messages listed under it. This change fixes this.
- (mh-thread-forget-message): Remove the entry from the scan line
- table as well. This is needed for proper display of threaded view
- of index folders.
-
-2003-03-26 Bill Wohler <wohler@newt.com>
-
- * Makefile, README, import-emacs, mh-alias.el, mh-comp.el,
- mh-customize.el, mh-e.el, mh-funcs.el, mh-identity.el,
- mh-index.el, mh-loaddefs.el, mh-mime.el, mh-pick.el, mh-seq.el,
- mh-speed.el, mh-utils.el, mh-xemacs-compat.el,
- mh-xemacs-toolbar.el: Removed RCS keywords per Emacs conventions
- (closes SF #680731).
-
-2003-03-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el: Fix commentary to mention that mairix is supported
- as well.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-show-junk-blacklist, mh-show-junk-whitelist):
- Interactive functions callable from the show buffer.
- (mh-show-junk-map): Key bindings in show mode.
-
- * mh-e.el (mh-junk-map): Key bindings to call spam program.
- (mh-help-messages): Update help text.
-
- * mh-customize.el (mh-junk): New customization group for spam
- program interface.
- (mh-junk-choice, mh-junk-function-alist, mh-junk-choose):
- Functions and variables that decide which junk program is used.
- (mh-junk-program, mh-junk-mail-folder): User customizable
- variables that control the choice of spam program and the action
- performed on received spam.
-
- * Makefile (MH-E-SRC): Add mh-junk.el.
-
-2003-03-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-show-toggle-tick, mh-show-mode-map): New
- interactive function callable from the show buffer and a key
- binding for it.
-
- * mh-seq.el (mh-delete-seq): Remove highlight from tick sequence.
- (mh-put-msg-in-seq): Disable adding messages to tick sequence.
- (mh-widen): Reset mh-tick-seq-changed-when-narrowed-flag.
- (mh-tick-add-overlay, mh-tick-remove-overlay, mh-notate-tick)
- (mh-toggle-tick): New functions to highlight/unhighlight tick
- sequence and the interactive function that is used to toggle
- tick.
-
- * mh-e.el (mh-tick-seq-changed-when-narrowed-flag): New variable
- that remembers if we are narrowed to the tick sequence. In that
- case the highlighting isn't shown, since it adds no extra info.
- (mh-folder-mode): Initialize mh-tick-seq-changed-when-narrowed-flag.
- (mh-notate-user-sequences): Notate the tick sequence.
- (mh-internal-seq): Treat mh-tick-seq like an internal sequence.
- (mh-delete-msg-from-seq): Don't allow deletion from tick sequence.
- (mh-folder-mode-map): Add key binding for "'"
-
- * mh-customize.el (mh-tick-seq, mh-folder-tick-face): New
- customizable variables that contain the name of the tick sequence
- and the face to use to highlight it.
-
-2003-03-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-thread-print-scan-lines): New function which
- prints out thread tree. It maintains the original folder info if
- the folder was created by index search (closes SF #709672).
- (mh-copy-seq-to-eob, mh-thread-inc, mh-thread-folder): Use
- factored out function mh-thread-print-scan-lines.
- (mh-toggle-threads): Since threading is allowed in index folders
- there can be lines in the folder which aren't valid message scan
- lines. So it is OK for mh-get-msg-num to fail once in a while.
-
- * mh-index.el (mh-index-update-maps): Make the parsing of messages
- that need to be annotated with the X-MHE-Checksum header more robust.
- If the search yielded no results then an error was being produced.
- (mh-index-search): Enable automatic threading of index folders if
- mh-show-threads-flag is non-nil (closes SF #709667).
- (mh-index-next-folder): Relax error checking since index folder
- can be threaded while the source folder info is visible.
- (mh-index-group-by-folder): New function that is used in
- mh-thread-folder to keep source folder info visible during
- threading.
-
-2003-03-25 Bill Wohler <wohler@newt.com>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-customize.el (mh-index-new-messages-folders): New variable
- that controls which folders "F n (mh-index-new-messages)"
- accesses. Was mh-flists-search-folders.
-
- * mh-index.el (mh-flists-search-folders): Still used internally,
- but users now use new option mh-index-new-messages-folders.
- Removed documentation since to avoid duplication with
- mh-index-new-messages-folders.
- (mh-flists-recursive-search-flag): Deleted. Use
- mh-recursive-folders-flag instead.
- (mh-flists-execute): Updated docs to specify which global
- variables are used. Use mh-recursive-folders-flag instead of
- mh-flists-recursive-search-flag.
- (mh-index-new-messages): Edited doc, and refer to new option
- mh-index-new-messages-folders. Ditto within code. Don't need to
- prepend + to folder name as flists does that for us. Use
-
-2003-03-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-refile-msg): Add optional argument that controls
- whether mh-last-destination-folder is updated or not.
-
-2003-03-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-tool-bar-define): Fix a problem in the
- XEmacs version which caused the show mode toolbar to have the
- buttons in the reverse order. Also the add-hooks are no longer
- needed since mh-toolbar-init is called in the appropriate modes.
-
- * mh-comp.el (mh-letter-mode): Call mh-toolbar-init in XEmacs to
- initialize toolbar.
-
- * mh-utils.el (mh-show-mode): Same as above.
-
- * mh-e.el (mh-folder-mode): Same as above.
-
-2003-03-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-exec-cmd-env-daemon): New function which
- executes a command asynchronously with its own environment.
-
- * mh-comp.el (mh-redistribute): The function has been modified so
- that /bin/sh isn't used to run send. It has also been refactored
- so that the same code isn't repeated.
-
-2003-03-21 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-invisible-header-fields): Added X-Bogosity
- for bogofilter.
-
-2003-03-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-xemacs-toolbar.el: Remove the code since that gets generated
- when mh-tool-bar-define is expanded.
- (mh-xemacs-icon-map): An alist to map GNU Emacs icon names to the
- actual icons to be used in XEmacs. This is used in
- mh-tool-bar-define.
-
- * mh-customize.el (mh-toolbar): Use this group in XEmacs as well.
- (mh-tool-bar-item-*): All these constants have been removed since
- they aren't needed in the new scheme.
- (mh-tool-bar-reply-3-buttons-flag): This variable has been
- removed.
- (mh-tool-bar-search-function): This is now used in XEmacs as well.
- (mh-tool-bar-folder-set, mh-tool-bar-folder-buttons-set)
- (mh-tool-bar-letter-buttons-set, mh-tool-bar-show-set)
- (mh-tool-bar-letter-set): These functions aren't defined at the
- top level any more.
- (mh-tool-bar-reply-generator): A macro to generate the required
- functions for the three reply buttons.
- (mh-tool-bar-search, mh-tool-bar-customize)
- (mh-tool-bar-folder-help, mh-tool-bar-letter-help)
- (mh-tool-bar-reply-from, mh-show-tool-bar-reply-from)
- (mh-tool-bar-reply-to, mh-show-tool-bar-reply-to)
- (mh-tool-bar-reply-all, mh-show-tool-bar-reply-all): New
- interactive functions that are called when tool bar buttons are
- clicked.
- (mh-xemacs-use-toolbar-flag, mh-xemacs-toolbar-position):
- Additional customizable variables that are present only for
- XEmacs.
- (mh-tool-bar-define): A macro that generates the required code
- for GNU Emacs and XEmacs tool bar.
- (mh-tool-bar-define): Define the MH-E tool bar.
-
-2003-03-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-notate-cur): Notate current message only if it
- hasn't been marked for deletion or refiling.
-
-2003-03-15 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-invisible-header-fields): Added
- X-Spam-Checker-Version.
- (mh-auto-fields-list): checkdoc fix.
-
-2003-03-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-new-messages): If the destination folder
- where the unseen messages are supposed to be copied to was
- already present, but MH-E doesn't have it open, then a new folder
- was being created. The change fixes this.
- (mh-index-update-unseen, mh-flists-recursive-search-flag): Fix
- checkdoc warnings.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-03-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-flists-results-folder): Subfolder under
- +mhe-index where the results of the flists call is put.
- (mh-index-generate-pretty-name): Make sure that normal index
- searching will never use the folder reserved for the flists
- results.
- (mh-index-search): Add an extra parameter that marks all the
- messages in the index folder to the unseen sequence.
- (mh-index-update-unseen): Function to keep unseen sequence of
- index folder synced with the actual folders from where the
- messages were copied. This works only if the unseen messages are
- displayed with mh-show. Killing the unseen sequence in the index
- folder or adding/removing messages to it doesn't change the
- unseen sequence in the source folders yet.
- (mh-flists-search-folders): Variable that decides the folders on
- which flists is run.
- (mh-flists-recursive-search-flag): If non-nil, flists is passed
- the -recurse option.
- (mh-flists-execute): Function which uses /bin/sh to execute
- flists and then print out the list of message files that match.
- (mh-index-new-messages): New interactive function which searches
- for messages in the unseen sequence (closes SF #701756).
-
- * mh-utils.el (mh-show-folder-map): Add binding for
- mh-index-new-messages.
- (mh-show-msg): Update the unseen sequence in the source folder.
-
- * mh-e.el (mh-folder-font-lock-unseen): The function assumes that
- the end of buffer is reached when there isn't a valid scan line
- on the current line. This doesn't work in the index folder since
- we have lines containing the folder name and empty lines in
- between the actual scan lines. The modification removes this
- assumption.
- (mh-folder-map): Add key binding for "Fn"
-
- * mh-seq.el (mh-iterate-on-messages-in-region): If the point is
- not at the beginning of the line, then the first message in the
- region would be missed. The fix avoids this.
-
- * mh-mime.el (mh-inline-vcard-p): Don't try to inline vcards if
- we don't have the right libraries.
-
-2003-03-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-next-undeleted-msg, mh-previous-undeleted-msg)
- (mh-next-msg): Add optional argument wait-after-complaining-flag.
- If non-nil and there are no undeleted messages after (or before)
- the current one, then pause for a second after printing out the
- message.
- (mh-refile-or-write-again): Modify call to mh-next-msg to use the
- wait-after-complaining-flag.
-
-2003-03-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-refile-or-write-again): If mh-next-msg fails to find
- a message to go to it prints out a diagnostic, which overwrites
- the diagnostic about the folder the message was refiled to. The
- change fixes this.
-
-2003-03-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-widen, mh-narrow-to-seq): Update
- mh-narrowed-to-seq before notating sequences. This is a bit
- helpful for mh-tick.el.
- (mh-put-msg-in-seq): Fix a minor bug. No internal sequence should
- be notated -- the original code was doing the right thing only for
- the "unseen" sequence.
-
- * mh-index.el (mh-index-choose): Add autoload cookie for
- mh-index-choose. This is needed for GNU Emacs 20.5.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-03-09 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-display-smileys): This function originally had a
- test to see if font-lock-maximum-size was bound, but this was
- recently removed. The test was put in for a reason; if
- font-lock-maximum-size isn't bound, void-variable errors would
- ensue. I put the bound test back in.
-
-2003-03-08 Steve Youngs <youngs@xemacs.org>
-
- * mh-mime.el (mh-mime-security-button-map): Use 'mh-push-button'
- in XEmacs as well.
-
-2003-03-07 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-xemacs-toolbar.el: Declare a whole bunch of stuff for GNU
- Emacs, so that we don't get so many compiler warnings. Also
- surround calls to set-specifier and toolbar-make-button-list with
- mh-funcall-if-exists. Maybe GNU Emacs shouldn't try to compile
- this file in the first place.
-
- * mh-xemacs-compat.el (mh-modeline-glyph): Declare it within
- mh-do-in-xemacs to avoid compiler warning in GNU Emacs.
- (mh-xemacs-push-button): Removed.
-
- * mh-mime.el (mh-mime-button-map): Use the generalized
- mh-push-button function.
- (mh-push-button): Enhance it so that it works on XEmacs too.
-
-2003-03-08 Steve Youngs <youngs@xemacs.org>
-
- * mh-xemacs-compat.el (mh-modeline-logo): New constant holding the
- modeline image.
- (mh-modeline-glyph): Use it.
-
-2003-03-08 Steve Youngs <youngs@xemacs.org>
-
- * mh-xemacs-toolbar.el: New file that defines and displays a
- toolbar in XEmacs.
-
- * mh-xemacs-compat.el (mh-xemacs-toolbar): Require it here.
-
- * Makefile (MH-E-SRC): Add mh-xemacs-toolbar.el.
-
- * mh-customize.el (mh-toolbar):
- (mh-tool-bar-letter-buttons):
- (mh-tool-bar-letter-buttons-set):
- (mh-tool-bar-folder-buttons):
- (mh-tool-bar-folder-buttons-set):
- (mh-tool-bar-search-function):
- (mh-tool-bar-reply-3-buttons-flag):
- (mh-tool-bar-item-inc):
- (mh-tool-bar-item-save-mime):
- (mh-tool-bar-item-prev-msg):
- (mh-tool-bar-item-page-msg):
- (mh-tool-bar-item-next-msg):
- (mh-tool-bar-item-delete):
- (mh-tool-bar-item-refile):
- (mh-tool-bar-item-undo):
- (mh-tool-bar-item-perform):
- (mh-tool-bar-item-toggle-show):
- (mh-tool-bar-item-reply-from):
- (mh-tool-bar-item-reply-to):
- (mh-tool-bar-item-reply-all):
- (mh-tool-bar-item-reply):
- (mh-tool-bar-item-alias):
- (mh-tool-bar-item-compose):
- (mh-tool-bar-item-rescan):
- (mh-tool-bar-item-repack):
- (mh-tool-bar-item-search):
- (mh-tool-bar-item-visit):
- (mh-tool-bar-item-prefs):
- (mh-tool-bar-item-help):
- (mh-tool-bar-item-widen):
- (mh-tool-bar-item-send):
- (mh-tool-bar-item-attach):
- (mh-tool-bar-item-spell):
- (mh-tool-bar-item-save):
- (mh-tool-bar-item-undo-op):
- (mh-tool-bar-item-kill):
- (mh-tool-bar-item-copy):
- (mh-tool-bar-item-paste):
- (mh-tool-bar-item-kill-draft):
- (mh-tool-bar-item-comp-prefs):
- The MH-E toolbar for XEmacs is defined differently from the
- GNU/Emacs version, so only define these if we're in GNU/Emacs.
- XEmacs doesn't need to see them and it's always good to cut down
- on pollution.
-
-2003-03-08 Steve Youngs <youngs@xemacs.org>
-
- * mh-mime.el (mh-mime-button-map): Bind the 2nd mouse button to
- `mh-xemacs-push-button' in XEmacs.
- (mh-mime-security-button-map): Ditto.
-
- * mh-xemacs-compat.el: Shush the byte-compiler.
- (mh-xemacs-push-button): New function to make MIME buttons work in
- XEmacs.
-
-2003-03-08 Steve Youngs <youngs@xemacs.org>
-
- * mh-mime.el (mh-display-emphasis): Don't test
- `font-lock-maximum-size' to see if it is bound, just test for a
- non-nil value. This variable can have a nil value which makes it
- bound and dividing nil by 8 throws an error.
- This fixes a bug in MH-E under XEmacs when
- `font-lock-maximum-size' is nil that prevented article emphasis
- and smiley display which in turn was causing the "Flush changes in
- article x y/n" errors.
- (mh-display-smileys): Ditto.
-
-2003-03-08 Steve Youngs <youngs@xemacs.org>
-
- * mh-utils.el (mh-logo-display): Display logo in XEmacs as well.
-
- * mh-xemacs-compat.el (mh-modeline-glyph): New. The MH-E modeline
- logo for XEmacs.
-
-2003-03-06 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-allow-root-folder-flag): New global variable
- that decides if "+" is an acceptable folder name.
- (mh-folder-completion-function): Refine the test for existing
- folders to take mh-allow-root-folder-flag into account.
- (mh-folder-completing-read, mh-prompt-for-folder): Use the
- allow-root-folder-flag argument of mh-prompt-for-folder and add a
- similar argument to mh-folder-completing-read.
- (mh-exec-cmd-error): Make the function nicer by using
- process-environment to pass the environment variable assignments.
-
-2003-03-05 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-push-button): Preserve point in the show buffer
- if the mouse is used to expand/contract a button.
-
- * mh-customize.el (mh-x-face-file): Mention X-Image-URL in
- documentation.
-
- * mh-comp.el (mh-insert-x-face): Modified to allow insertion of
- X-Image-URL header field.
-
-2003-03-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-face-display-function): Modified to facilitate
- display of X-Image-URL images.
- (mh-find-path): Initialize X-Image-URL cache directory.
- (mh-x-image-url-cache-canonicalize, mh-x-image-url-fetch-image)
- (mh-x-image-scale-and-display, mh-x-image-url-display)
- (mh-x-image-display): New functions for X-Image-URL image display
- and cache management.
-
- * mh-customize.el (mh-show-use-xface-flag): Add info about
- requirements for X-Image-URL display.
- (mh-fetch-x-image-url): New customizable variable that controls
- fetching of X-Image-URL.
-
-2003-03-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-make-local-hook): New macro which works around
- API changes in add-hook. Version of GNU Emacs before 21.1 and
- XEmacs require a call to make-local-hook and just the LOCAL
- argument of add-hook is not sufficient.
- (mh-show-mode): Make kill-buffer-hook buffer local.
-
- * mh-e.el (mh-folder-mode): Same as above.
-
- * mh-comp.el (mh-compose-and-send-mail): Same as above.
-
-2003-03-02 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-push-button): Clicking on a MIME button used to
- cause the window with the show buffer to be selected. With this
- change the selected window doesn't change.
-
-2003-03-01 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-flists): Avoid a potential race condition.
- When flists is called manually, or when an unseen message is read,
- mh-speed-partial-line was not reinitialized.
-
- * mh-e.el (mh-visit-folder): If mh-visit-folder is used to visit
- the folder currently being visited (effectively doing a rescan)
- then mh-previous-window-config is erroneously set. The change
- fixes this.
-
- * mh-customize.el (mh-index-show-hook): Remove unused variable.
-
-2003-02-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-scan-folder): Call mh-reset-threads-and-narrowing
- only after the user has replied to question. This avoids premature
- clearing of the folder.
- (mh-rescan-folder, mh-visit-folder): Remove calls to
- mh-reset-threads-and-narrowing since it is now called in
- mh-scan-folder anyway.
-
- * mh-funcs.el (mh-sort-folder): Same as above.
-
-2003-02-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-alias.el (mh-alias-alist): Change initial value to a symbol,
- so that it is different from the empty list, which could also
- mean that there are no aliases.
- (mh-alias-reload-maybe): Change test so that empty alist of
- aliases is properly handled (closes SF #693859).
-
-2003-02-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-decode-message-header): The message header could
- be encoded, for instance the author's name could contain
- characters not in ASCII. This function will decode such header
- fields.
- (mh-mm-inline-message): Use mh-decode-message-header.
-
- * mh-utils.el (mh-display-msg): Use mh-decode-message-header.
- (mh-message-number-width): Use mh-scan-prog instead of "scan".
-
- * mh-loaddefs.el: Regenerated.
-
-2003-02-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-truncate-log-buffer): Refine it so that the
- function will do the right thing even if called from a buffer
- other than mh-log-buffer.
-
-2003-02-22 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-add-alias): Really fix SF #690216.
- This functions needs to strip brackets on standalone addresses as
- well.
-
-2003-02-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-xemacs-compat.el (replace-regexp-in-string): Remove the
- definition since it isn't used any more.
-
-2003-02-20 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-which-file-has-alias): Bug fix. Needed to
- specify `noerror' on search.
-
- * mh-alias.el (mh-alias-suggest-alias): Add condition for input
- string being an email address in brackets. We need to strip out
- the brackets. (closes SF #690216)
-
-2003-02-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-pick.el (mh-search-folder): The function was setting the
- global value of the variables mh-current-folder and
- mh-previous-window-config. This can lead to problems in code which
- assumes that these variables are nil when we aren't in a folder
- buffer. So make the variables local before setting them.
-
-2003-02-19 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-mime-display): All the MIME display code has been
- wrapped in a condition-case so that if something goes wrong, the
- raw message will be displayed.
-
- * mh-funcs.el (mh-undo-folder): Comment out call to sit-for that
- seems unnecessary.
-
- * mh-e.el (mh-scan-folder): Messages marked for deletion or
- refiling weren't getting annotated properly. The change fixes
- this.
- (mh-process-or-undo-commands): Change prompt to reflect what
- really happens in the code.
-
-2003-02-18 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-folder-expand-at-point): The function
- mail-abbrev-complete-alias often returns nil. This had the
- unfortunate consequence of always causing an error. The change
- fixes this.
-
- * mh-alias.el (mh-alias-canonicalize-suggestion): New function
- which obviates the our need replace-regexp-in-string.
- (mh-alias-suggest-alias): Use mh-alias-canonicalize-suggestion to
- eliminate calls to replace-regexp-in-string. This avoids problems
- in Emacs20.
-
- * mh-utils.el (mh-notate): Handle the case when nil is passed as
- notation gracefully.
- (mh-speed-flists-active-p): New function that returns non-nil if
- flists is being used in the speedbar to update message counts.
-
- * mh-seq.el (mh-put-msg-in-seq): Fix a bug which made it
- impossible to add messages to the unseen sequence. Also adding
- messages to the unseen sequence will now update the speedbar
- message counts immediately.
-
- * mh-e.el (mh-get-new-mail, mh-process-commands)
- (mh-undefine-sequence): Update speedbar message counts, if the
- speedbar is active and is displaying message counts.
- (mh-delete-msg-from-seq): In addition to updating message counts,
- unhighlight the message so that interactively removing messages
- from the unseen sequence makes the bold highlight of unseen
- messages in the scan buffer go away.
- (mh-clear-text-properties): New function that removes all text
- properties from the current scan line.
-
-2003-02-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-face-display-function): Wrap call of
- insert-image in mh-funcall-if-exists. This avoids a compiler
- warning in Emacs20.
-
- * mh-speed.el (mh-speed-flists): Weaken test a bit to avoid
- compiler warning in Emacs20.
- (mh-speedbar-change-expand-button-char): Wrap call of
- speedbar-insert-image-button-maybe in mh-funcall-if-exists. This
- function isn't present in the speedbar that ships with Emacs20, so
- calling it there causes an error.
-
- * mh-seq.el (mh-msg-is-in-seq): Adjust loop call a bit to avoid
- compiler warning in XEmacs. The XEmacs compiler should be improved
- so that such spurious warnings from builtin macros are suppressed.
-
- * mh-index.el (mh-index-search): Same as above.
-
- * mh-e.el (tool-bar-mode): The declaration is needed for Emacs20
- too.
-
- * mh-comp.el (mailabbrev): Try loading it any way. Some day XEmacs
- will get it and then MH-E will just use it.
- (tool-bar-mode, tool-bar-map): These declarations are needed for
- Emacs20 too.
- (mh-mail-abbrev-make-syntax-table, mh-folder-expand-at-point):
- Remove mh-mail-abbrev-make-syntax-table since mh-funcall-if-exists
- can be used instead.
-
- * mh-alias.el (require): Avoid autoloading functions that may not
- be defined.
- (mh-read-address, mh-alias-letter-expand-alias): Rewrite using
- mh-funcall-if-exists.
-
-2003-02-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-speed.el (mh-folder-speedbar-buttons, mh-speed-add-buttons)
- (mh-speed-toggle): Reuse markers instead of creating more of them.
- (mh-speed-flists-folder, mh-speed-flists): Add optional folder
- argument to mh-speed-flists so that message counts are updated
- only for that one folder.
- (mh-speed-parse-flists-output): If no change in counts then avoid
- consing.
-
- * mh-index.el (mh-index-execute): Rewritten to use a temporary
- buffer that is not left behind.
-
- * mh-funcs.el (mh-store-buffer): Use mh-log-buffer instead of the
- special purpose *Store Output* buffer.
-
-2003-02-14 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-show-xface-face): Make it always be black
- foreground on a white background (the reverse of that can make
- some X-Face images look creepy).
-
- * mh-utils.el (mh-truncate-log-buffer): Modify the function to
- return the current size of mh-log-buffer. Also we are now a bit
- more careful in adding separators between consecutive messages.
- (mh-exec-cmd): Fix a bug where the log buffer would be
- displayed even if no error happened in the current command but
- the log buffer had messages from a previous error.
-
- * mh-mime.el (mh-mime-save-parts): Use mh-log-buffer to show
- error messages.
-
- * mh-alias.el (mh-alias-local-users): Add a space between parens.
-
-2003-02-14 Steve Youngs <youngs@xemacs.org>
-
- * mh-utils.el (mh-face-display-function): Call
- `x-face-xmas-wl-display-x-face' using `mh-funcall-if-exists'.
-
- * mh-xemacs-compat.el (replace-regexp-in-string): New.
-
-2003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-log-buffer-lines): New variable that keeps
- track of the number of lines to keep in mh-log-buffer.
- (mh-truncate-log-buffer): New function that is used to make sure
- that the log buffer doesn't grow to unbounded size.
- (mh-exec-cmd, mh-exec-cmd-daemon, mh-handle-process-error): Use
- mh-truncate-log-buffer instead of erase-buffer to keep some
- number of previous log messages around (closes SF #685476).
-
-2003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (tool-bar-mode): Declare it in XEmacs.
- (mh-folder-mode): Use mh-funcall-if-exists to call hl-line-mode.
-
- * mh-utils.el (mh-funcall-if-exists): New macro that calls a
- function only if it exists.
- (mh-logo-display, mh-defun-show-buffer): Use mh-funcall-if-exists
- to call the functions find-image and deactivate-mark.
-
- * mh-mime.el (mh-mime-cleanup, mh-small-image-p)
- (mh-mm-display-part): Use mh-funcall-if-exists to call the
- functions image-size and remove-images.
-
- * mh-comp.el (tool-bar-map, tool-bar-mode): Declare the variables
- in XEmacs.
- (mh-folder-expand-at-point): Use mh-funcall-if-exists to call
- mail-abbrev-complete-alias if it exists.
-
- * mh-alias.el (mh-read-address): Use mh-funcall-if-exists for
- future extensibility.
-
-2003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-logo-display): The function find-image is
- present only in GNU Emacs.
- (mh-defun-show-buffer): The function deactivate-mark is present
- only in GNU Emacs.
- (default-enable-multibyte-characters): Declare it in XEmacs to
- avoid compiler warning.
- (mh-face-display-function): Avoid inserting space if there isn't
- any Face or X-Face header field to display.
-
- * mh-seq.el (mh-thread-last-ancestor): Move declaration of
- variable before its first use to silence XEmacs warning.
-
- * mh-mime.el (default-enable-multibyte-characters, dots, type):
- Declare these in XEmacs to remove compiler warnings in XEmacs.
- (mh-mime-cleanup, mh-mm-display-part): Call remove-images only in
- GNU Emacs.
- (mh-small-image-p): Call image-size only in GNU Emacs.
-
- * mh-index.el (mh-mairix-next-result): Fix a bug where a quote
- was missing.
- (mh-swish++-regexp-builder): Remove the unused binding meta.
-
- * mh-e.el (mh-folder-size): Pass on an extra value to remove
- XEmacs warning.
- (mh-folder-mode): Surround calls to hl-line-mode and
- tool-bar-mode with mh-do-in-gnu-emacs since these functions
- aren't present in XEmacs.
-
- * mh-customize.el (mh-tool-bar-show-set, mh-tool-bar-letter-set)
- (mh-tool-bar-folder-set): These functions call tool-bar-*
- functions which are present only in GNU Emacs. So surround them
- with mh-do-in-gnu-emacs.
-
- * mh-comp.el (mh-letter-mode, mh-folder-expand-at-point): Only
- call these functions in GNU Emacs.
- (mail-abbrevs): Declare it in XEmacs.
-
- * mh-alias.el (mh-read-address): Call completing-read-multiple
- only in GNU Emacs.
- (mail-abbrevs): Declare it in XEmacs.
- (mh-alias-add-alias-to-file): Remove unused code.
-
-2003-02-14 Ville Skyttä <scop@xemacs.org>
-
- * mh-comp.el: Add autoloaded auto-mode-alist association.
-
-2003-02-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-face-display-function): Make the XEmacs part a
- little simpler.
-
-2003-02-14 Steve Youngs <youngs@xemacs.org>
-
- * mh-customize.el (mh-show-xface-face): XEmacs doesn't have the
- ':inherit' keyword for defface, rewrite with sane defaults.
-
- * mh-utils.el (mh-face-display-function): Fix bug that was
- corrupting xface images when displayed with XEmacs' internal
- xface image support. Also make XEmacs honor 'mh-show-xface-face'
- when using internal xface image support.
-
-2003-02-12 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-modify-header-field): New function. To header
- FIELD add VALUE. If OVERWRITE-FLAG is non-nil then the old value,
- if present, is discarded. This is more flexible than before.
- (mh-insert-auto-fields): Use it. This and the new function are a
- courtesy of Satyaki. Thanks!
-
- * mh-customize.el (mh-auto-fields-list): Doc tweaks suggested by
- Bill.
-
-2003-02-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-folder-expand-at-point): Tweak the error
- message. Completion in the Fcc header field is only supported in
- GNU Emacs 21.
-
-2003-02-12 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-auto-fields-list): Reorder after
- `mh-identity-list' since it needs it to be defined. Move to
- mh-identity customization group.
-
-2003-02-11 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-insert-mail-followup-to-flag): Removed.
- Obsolete.
- (mh-insert-mail-followup-to-list): Removed. Obsolete. Use
- `mh-auto-fields-list' instead, which is a more general solution.
- (mh-auto-fields-list): New defcustom. Alist of addresses for
- which header lines are automatically inserted. Replaces
- `mh-insert-mail-followup-to-list'.
-
- * mh-comp.el (mh-insert-mail-followup-to): Removed. Obsolete.
- (mh-insert-auto-fields): New function. Insert custom fields if To
- or Cc match `mh-auto-fields-list', replacing
- mh-insert-mail-followup-to with a more general solution.
- (mh-compose-and-send-mail): Call mh-insert-auto-fields instead of
- mh-insert-mail-followup-to. Also don't call mh-insert-identity to
- insert default setting if mh-insert-auto-fields inserted an
- identity.
-
-2003-02-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-xface-function): Try to load the external
- x-face library only if XEmacs doesn't have xface support.
- (mh-face-display-function): Renamed. Also handle various
- permutations of x-face and xface support in XEmacs better.
-
- * mh-customize.el (mh-show-use-xface-flag): Any emacs whose
- major version is greater than or equal to 21 supports display of
- X-Face and Face header fields.
-
-2003-02-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-do-in-gnu-emacs, mh-do-in-xemacs): Macros that
- execute code only in GNU Emacs and XEmacs respectively.
- (mh-emacs21-face-display-function): Refactor to make it slightly
- nicer. Get rid of compiler warnings in GNU Emacs by using the
- above macros. Also check for presence of xface feature (in XEmacs
- specific code) before trying to display X-Face header field image.
-
-2003-02-11 Steve Youngs <youngs@xemacs.org>
-
- * mh-customize.el (mh-show-use-xface-flag): If using XEmacs and
- can't find the external x-face pkg still enable X-Face images if
- feature 'xface is present.
- Update the doc string.
-
- * mh-utils.el (mh-emacs21-face-display-function): Make it work in
- XEmacs.
- (mh-show-xface-function): If using XEmacs without xface support,
- use x-face.el pkg. If using XEmacs with xface support, or Emacs
- 21, use mh-emacs21-face-display-function.
-
-2003-02-11 Mark D. Baushke <mdb@gnu.org>
-
- * mh-customize.el (mh-invisible-header-fields): Add
- "X-Notes-Item:" which is generated by Lotus Notes Domino. See
- URL<http://www-12.lotus.com/ldd/doc/domino_notes/Rnext/help6_admin.nsf
- /f4b82fbb75e942a6852566ac0037f284/5eda03c647f879c285256c1d00396051
- ?OpenDocument&Highlight=0,x-notes-item> for details on how Domino
- users may disable (restore the default) generation of these headers.
-
-2003-02-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-folder-expand-at-point): Add function doc string
- and produce a nicer error message for Emacs versions that lack
- mail-abbrev-complete-alias.
-
- * mh-utils.el (mh-handle-process-error): Check doc fix.
-
- * mh-e.el (mh-folder-from-address): Same as above.
-
-2003-02-10 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el: require mailabbrev, except in XEmacs.
- (mh-mail-abbrev-make-syntax-table): New defmacro to call
- mail-abbrev-make-syntax-table introduced in Emacs21.
- (mh-folder-expand-at-point): Handle nested folders.
- All of the above was written by Satyaki. I just applied the patch
- and tested.
-
-2003-02-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el: Fixes to keep the byte compiler happy.
-
- * mh-customize.el (mh-invisible-header-fields): Modified to
- remove space after ":" in header field names.
-
-2003-02-09 Peter S Galbraith <psg@mixed.dyndns.org>
-
- * mh-comp.el (mh-letter-complete): Add completion for fcc lines.
- (mh-folder-expand-at-point): Do completion at point for folder
- name. Like `mh-alias-letter-expand-alias' for aliases, it doesn't
- work on XEmacs because it relies on `mail-abbrev-complete-alias'
- to do completion. Maybe Steve could update XEmacs' mailabbrev.el?
-
-2003-02-09 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-invisible-header-fields): Remove trailing
- space in "X-Face: " and "Face: " entries since those line often
- break there.
-
-2003-02-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-emacs21-face-display-function): Use
- mh-show-xface-face to colorize X-Face image.
-
- * mh-customize.el (mh-invisible-header-fields): Add extra headers
- to ignore.
- (mh-show-xface-face): Allow customization of the X-Face colors.
-
-2003-02-07 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-uncompface-executable, mh-uncompface): Remember
- the path of the uncompface executable so that we don't need to
- search for it every time.
- (mh-emacs21-face-display-function): If more than one X-Face (or
- Face) header field was present then the fields would get
- concatenated, leading to garbled output. The change only displays
- the first image.
-
- * mh-customize.el (mh-x-face-file): Change documentation since it
- can now be used to insert a Face header field.
-
- * mh-comp.el (mh-insert-x-face): Generalized to allow insertion
- of Face header field.
-
-2003-02-06 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-emacs21-face-display-function): Updated
- docstring. It is a common mistake to refer to a header field as a
- header. The term header refers to the entire header while the term
- header field refers to a single field.
-
- * mh-customize.el (mh-show-use-xface-flag): Ditto.
-
-2003-02-06 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-xface-function): Modified to use
- mh-emacs21-face-display-function if we are running GNU Emacs 21.
- (mh-face-to-png): New function to convert a Face header to a png
- image.
- (mh-uncompface): New function which converts an X-Face header to
- a pbm image.
- (mh-icontopbm): New function that does the job of icontopbm.
- (mh-emacs21-face-display-function): New function that displays
- Face/X-Face image in GNU Emacs 21.
- (mh-show-xface): Modified to test if we are running in X.
- Otherwise face display is suppressed.
-
- * mh-customize.el (mh-show-use-xface-flag): Tweak it, now that
- MH-E supports face display natively on Emacs 21. Also remove the
- check for window-system since it doesn't belong in a customizable
- variable.
-
-2003-02-06 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (sendmail): Require it so that XEmacs can find
- rfc822-goto-eoh.
- (mh-mail-header-end): A substitute for mail-header-end that
- doesn't widen the buffer. This is essential to avoid problems when
- dealing with nested messages.
- (mh-in-header-p, mh-letter-header-font-lock)
- (mh-header-field-font-lock, mh-show-font-lock-fontify-region)
- (mh-show-unquote-From): Use mh-mail-header-end instead of
- mail-header-end.
-
- * mh-mime.el (mh-decode-message-body): same as above (closes SF
- #681518).
-
- * mh-comp.el (mh-yank-cur-msg): same as above.
-
-2003-02-05 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-display-msg): Call mh-show-mode before invisible
- headers are cleaned. This means that any surviving X-Face header
- can be removed unconditionally in mh-clean-msg-header.
- (mh-clean-msg-header): Since the function is now called with a
- read-only buffer, make the buffer temporarily writable.
-
- * mh-mime.el (mh-mm-inline-message): Do X-Face display before
- invisible headers are removed.
-
- * mh-customize.el (mh-invisible-headers): Simplified since the
- X-Face header isn't treated specially any more.
- (mh-invisible-header-fields): Add Face: and X-Face: to list of
- invisible headers.
-
- * mh-mime.el (mh-mime-display): If body is empty the headers would
- be treated like the body. The change fixes this (closes SF #681162).
- (mh-mime-display): This change really fixes the above problem.
-
-2003-02-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-current-folder-name): Global variable that
- keeps track of current folder.
- (mh-normalize-folder-name): Substitute @ with
- mh-current-folder-name (closes SF #666774).
- (mh-prompt-for-folder): Bind mh-current-folder-name. Also
- invalidate cache if we are visiting a folder that wasn't found in
- the sub-folder cache. This is an indication that folders may have
- been created outside of MH-E and so the cache may be stale.
-
-2003-02-03 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-decode-content-transfer-encoded-message): Removed.
- (mh-display-msg): Remove the use of the above function.
- (mh-normalize-folder-name): Leading "/" characters were being
- lost. The change fixes this (closes SF #676890).
-
- * mh-mime.el (mh-decode-message-body): New function, factored out
- from mh-mime-display and enhanced, to decode message based on
- charset and content-transfer-encoding. This eliminates the need
- for the external mimencode (closes SF #674857).
- (mh-mime-display): Use mh-decode-message-body.
-
- * mh-e.el (mh-header-display): Don't need the binding since the
- variable isn't present any more.
- (mh-inc-folder): Avoid calling mh-show if point is not on a valid
- scan line (closes SF #678115).
-
- * mh-customize.el
- (mh-decode-content-transfer-encoded-message-flag): Removed.
-
-2003-02-03 Bill Wohler <wohler@newt.com>
-
- * import-emacs: MH-E now has its own directory in Emacs.
-
- * mh-e.el (mh-version): Set to 7.2+cvs.
-
-2003-02-03 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.2.
-
- * MH-E-NEWS, README: Updated for release 7.2.
-
- * mh-e.el (Version, mh-version): Updated for release 7.2.
-
-2003-02-03 Bill Wohler <wohler@newt.com>
-
- * Makefile (dist): mkdir needs to happen *before* files are
- copied.
-
- * MH-E-NEWS: Fixed some awkward verbiage.
-
-2003-02-02 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-invisible-headers): Surround regexp-opt
- expression in parens to avoid problems viewing certain messages.
-
-2003-01-30 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-flists): Search for flists in mh-progs.
- The original was inadvertently searching for flists in the user's
- path.
-
-2003-01-27 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-default-folder-must-exist-flag): Changed
- default to t according to the principle of least surprise.
-
-2003-01-26 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el: Checkdoc fixes.
-
- * mh-pick.el (mh-do-search, mh-search-folder): Checkdoc fixes.
-
- * mh-loaddefs.el: Regenerated (lm-verify fixes).
-
- * mh-index.el (mh-mairix-next-result): Checkdoc fixes.
-
- * mh-alias.el: lm-verify fix.
-
- * Makefile (MH-E-SRC): Added ChangeLog, now that Emacs has a
- lisp/mh-e directory.
- (MH-E-ETC-ETC): Removed ChangeLog.
- (dist): Moved creation of mail directory next to copy of files
- into mail directory.
- (install-emacs): Copy $(MH-E-SRC) into new directory
- $(EMACS_HOME/lisp/mh-e.
- (MH-E-SRC): Moved ChangeLog into new variable MH-E-OTHERS and
- include MH-E-LOADDEFS there too.
- (mh-loaddefs.el): Added lines so that lm-verify passes.
- (dist, install-emacs): Use MH-E-OTHERS instead of MH-E-LOADDEFS.
-
-2003-01-26 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-tidy-draft-buffer, mh-compose-and-send-mail):
- Rename mh-kill-draft-hook to mh-tidy-draft-buffer.
-
-2003-01-25 Jeffrey C Honig <jch@honig.net>
-
- * mh-utils.el (mh-exec-cmd, mh-exec-cmd-daemon)
- (mh-process-daemon): Use mh-log-buffer for the output of commands
- from mh-exec-cmd.
-
- * mh-utils.el (mh-temp-folders-buffer): Sequences and folders
- lose the -temp from their buffer names as they are interesting to
- the user.
-
- * mh-seq.el (mh-list-sequences): New name, mh-sequences-buffer as
- it is intended to be interesting to the user.
-
- * mh-funcs.el (mh-list-folders): New name, mh-folders-buffer as it
- is intended to be interesting to the user.
-
- * mh-comp.el (mh-check-whom, mh-compose-and-send-mail): Use
- mh-recipients-buffer constant. Add a kill buffer hook to delete
- the recipients buffer when a draft buffer is killed.
-
-2003-01-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-customize): New interactive argument
- deletes other windows.
- (mh-tool-bar-show-set, mh-tool-bar-letter-set)
- (mh-tool-bar-folder-set): Modified so that clicking the customize
- and help buttons deletes the other windows in the frame.
-
- * mh-mime.el (mh-mm-inline-message): Remove unused code.
-
- * mh-seq.el (mh-notate-deleted-and-refiled): Fix a small bug where
- the wrong notation was being used.
- (mh-toggle-threads): The function had a bug if you did the
- following starting from an unthreaded wide folder:
- (1) Create a sequence with S p
- (2) Narrow to new sequence with S n
- (3) Thread narrowed folder with T t
- (4) Kill sequence with S k
- (5) Unthread narrowed folder with T t
- At this point we would have an empty folder. The change fixes
- this.
- (mh-toggle-threads): Fix documentation.
-
- * mh-customize.el (mh-invisible-header-fields): Add
- X-MHE-Checksum to invisible headers.
-
- * mh-comp.el (mh-insert-x-mailer): Slightly more informative
- X-Mailer header.
-
-2003-01-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-header-display): Modified so that quoted-printable
- or base64 encoded messages are left untouched.
-
- * mh-utils.el (mh-decode-content-transfer-encoded-message): Munge
- the Content-Transfer-Encoding header so that the MIME decoding
- routines of Gnus doesn't get confused.
- (mh-display-msg): Use insert-file-contents-literally so that
- display will work for non-ascii.
-
- * mh-mime.el (mh-mime-display): Use charset info to decode
- message file (closes SF #655123).
-
-2003-01-24 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (mh-alias-add-alias-to-file): Removed period from
- error message and added parens around error function.
-
-2003-01-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-decode-quoted-printable-flag): Removed.
- (mh-decode-content-transfer-encoded-message-flag): This replaces
- mh-decode-quoted-printable-flag.
-
- * mh-utils.el (mh-decode-content-transfer-encoded-message): New
- function which handles messages that are encoded as base64 or
- quoted-printable (closes SF #674190).
- (mh-decode-quoted-printable): Removed.
- (mh-display-msg): Use mh-decode-content-transfer-encoded-message
- instead of mh-decode-quoted-printable.
-
-2003-01-23 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate-scan-lines): Fix a little bug
- that would occasionally cause angles ('<' and '>') to appear at
- root level.
-
-2003-01-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-notate-cur): Enable overlay arrow display in text
- mode too.
-
- * mh-e.el (mh-folder-mode): Initialize overlay-arrow-string so
- that a '>' is displayed in text mode.
-
-2003-01-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-scan-msg-overflow-regexp): Change the variable
- so that a space is always maintained in the beginning of the scan
- line.
-
- * mh-seq.el (mh-notate-seq, mh-notate-cur): Make the functions
- faster by cutting down on the use of mh-goto-msg.
- (mh-toggle-threads): Add call to mh-notate-cur, since inserting
- the folder names in a search results folder screws up the
- location of the overlay arrow.
-
- * mh-index.el (mh-index-delete-folder-headers): Position the
- point on a message line if possible.
-
- * mh-funcs.el (mh-copy-msg): Use the mh-iterate macro to make the
- function faster.
-
- * mh-e.el (mh-scan-folder): Reuse mh-notate-deleted-and-refiled.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-add-msgs-to-seq): Add a new parameter that
- suppresses the annotation of the sequence since it is
- inefficient.
-
- * mh-seq.el (mh-delete-seq): Speed up the part of the function
- that removes the sequence notation.
- (mh-put-msg-in-seq, mh-notate-deleted-and-refiled): Use
- mh-iterate-on-messages-in-region to make the function fasters when
- operating on regions. The key idea is to loop over the folder
- buffer exactly once and do all annotations. The existing algo
- would walk over the buffer multiple times thereby slowing things
- down.
- (mh-iterate-on-messages-in-region): Added an extra parameter which
- is bound to the message index as the loop is executed.
- (mh-region-to-msg-list, mh-thread-delete, mh-thread-refile): Use
- the new mh-iterate-on-messages-in-region macro.
-
- * mh-e.el (mh-delete-msg-no-motion, mh-refile-msg, mh-undo): Same
- as above.
- (mh-notate-user-sequences): Change algorithm to make notating of
- user sequences fast.
-
-2003-01-19 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-logo.xpm: New image file that contains the MH-E logo.
- Change foreground color to the blue in the MH-E logo.
-
- * Makefile (MH-E-IMG): Add mh-logo.xpm to list of image files.
-
- * mh-utils.el (mh-show-buffer-mode-line-buffer-id): Adjust it to
- keep space in the beginning for the logo.
- (mh-logo-cache): New variable that caches the logo image file
- location.
- (mh-logo-display): Display the MH-E logo on the mode line.
- (mh-display-msg): Display logo in mh-show-mode.
-
- * mh-e.el (mh-make-folder-mode-line): Display logo in
- mh-folder-mode.
-
- * mh-comp.el (mh-compose-and-send-mail): Display logo in
- mh-letter-mode.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-seq.el (mh-iterate-on-messages-in-region): New macro to
- iterate on all messages in a region.
- (mh-region-to-msg-list): Simplified since it uses
- mh-iterate-on-messages-in-region now.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg): Change interactive spec
- to pass the region that is to be deleted when appropriate.
- (mh-delete-msg-no-motion, mh-refile-msg, mh-undo): Operate on
- regions directly without creating the list of messages to be
- deleted/refiled.
- (mh-delete-a-msg, mh-refile-a-msg, mh-undo-msg): The msg
- parameter in these functions can now be nil. If so, the current
- message is deleted, refiled or undone respectively. Avoids the
- use of mh-goto-msg in this case and speeds up operations on
- regions quite a bit.
-
-2003-01-19 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-read-address): Bug Fix. In XEmacs and Emacs20,
- it would always prompt using "To: " instead of using the command
- argument (closes SF #670913).
-
-2003-01-19 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-folder-completion-function): If there is a
- +foo/bar folder and the user types foo//bar then the completion
- function would say a match happened without showing the
- normalized folder name. This change fixes that.
-
-2003-01-18 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-rmail): Modified so that new and unseen messages
- are shown (closes SF #667542).
-
-2003-01-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-generate-pretty-name): Generate nicer
- names. In particular all '-' characters are removed.
-
-2003-01-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-index-program): Documentation fix.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-customize.el (mh-index-program): Add choices for mairix and
- pick.
-
- * mh-index.el (mh-indexer-choices): Add search interfaces for
- mairix and pick.
- (mh-index-search): Add links for mairix and pick.
- (mh-index-pick-folder, mh-pick-binary): Variables needed to
- implement pick support.
- (mh-pick-execute-search, mh-pick-next-result): New functions to
- implement pick support.
- (mh-mairix-binary, mh-mairix-directory, mh-mairix-folder): New
- variables for mairix support.
- (mh-mairix-execute-search, mh-mairix-next-result)
- (mh-mairix-regexp-builder, mh-mairix-convert-to-sop*): New
- functions for mairix.
-
- * mh-funcs.el (mh-kill-folder): Move message to the end.
-
- * mh-e.el (mh-folder-mode): Make overlay-arrow-position and
- overlay-arrow-string local variables so that the arrow will
- remain even if some other folder is visited.
- (mh-remove-cur-notation, mh-remove-all-notation): The test isn't
- required any more since overlay-arrow-position is local.
- (mh-goto-cur-msg): Remove overlay arrow if current message
- doesn't exist.
-
- * mh-seq.el (mh-notate-cur): Don't need to set
- overlay-arrow-string any more since it is local and has been set
- at initialization.
-
-2003-01-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-current-folder): Keep track of current
- folder when flists is called.
- (mh-speed-flists, mh-speed-parse-flists-output): Try to avoid
- ambiguity when folders are present with + at the end of the name.
- Unfortunately it can't always be avoided.
-
- * mh-e.el (mh-folder-size): Remove the unnecessary error check.
- (mh-parse-flist-output-line): Add extra argument which
- occasionally avoid problems with folder names that end with '+'.
-
- * mh-utils.el (mh-sub-folders-actual): Fix the folder name
- parsing so that it doesn't get confused by trailing '+' chars in
- the folder name.
-
-2003-01-14 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-normalize-folder-name): Enhanced so that it can
- now handle ".." and "." correctly during folder name completion.
- (mh-normalize-folder-name): Avoid error in boundary condition
- where the folder string is empty.
-
-2003-01-14 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-visit-folder): Pass `current-prefix-arg' to
- the `mh-read-msg-range' function as the optional
- always-prompt-flag.
-
-2003-01-14 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-normalize-folder-name): New function that
- normalizes folder names.
- (mh-sub-folders): Use mh-normalize-folder-name. Also the function
- has been modified so that a trailing slash is only added if the
- folder potentially has subfolders.
- (mh-sub-folders-actual): Simplified since the folder has already
- been normalized in mh-sub-folders.
- (mh-remove-from-sub-folders-cache): Modified so that the cached
- results of two of the folders ancestors are invalidated.
- (mh-folder-completion-map): Ugly hack to make the error go away
- when minibuffer-complete-word is called.
- (mh-folder-completion-function): The completion function will now
- be more selective in adding '/' at the end of completed folder
- names.
- (mh-folder-completing-read): The folder name is normalized before
- return. The minibuffer-local-completion-map is shadowed to avoid
- error with SPC (bound to minibuffer-complete-word). We really
- need a better solution.
-
-2003-01-13 Bill Wohler <wohler@newt.com>
-
- * mh-seq.el: Edited comment and docstring text to conform with RFC
- 2822 terminology. Message-ID is the header field. It contains a
- message identifier.
-
-2003-01-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-sub-folders): Add an argument that returns
- sub-folders with a / character appended at the end.
- (mh-folder-completion-function): Modify the function so that one
- tab is now sufficient to complete the folder name and add a
- trailing /.
- (mh-folder-completing-read): Remove the trailing / that the
- completion function now adds to the folder name. Also multiple /
- characters in the folder input are removed. So if the user inputs
- +foo///bar//baz///// then that will be converted to +foo/bar/baz.
- This will improve the performance of caching.
-
- * mh-seq.el (mh-notate-cur): Check that a valid current message
- exists before trying to notate (closes SF #667331).
- (mh-message-id-regexp): New variable to store regexp to recognize
- message-ids.
- (mh-thread-generate): Use mh-message-id-regexp to filter out non
- message-id's from the References: header.
-
-2003-01-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-notate-cur): Disable overlay-arrow display if we
- aren't on a graphic display.
-
-2003-01-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-notate-cur): New function to notate the current
- message. The marker in the fringe is updated too.
- (mh-narrow-to-seq, mh-widen, mh-thread-inc, mh-thread-folder): Use
- the specialized function mh-notate-cur instead of mh-notate-seq.
-
- * mh-e.el (mh-arrow-marker): New buffer local variable to store
- the position where the marker in the fringe is going to be
- displayed (closes SF #664824).
- (mh-folder-mode): Create a marker for the fringe.
- (mh-update-sequences, mh-get-new-mail, mh-goto-cur-msg): Call the
- specialized function mh-notate-cur instead of mh-notate-seq or
- mh-notate.
- (mh-remove-cur-notation, mh-remove-all-notation): Reset the
- overlay-arrow-position if needed.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-01-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-remove-from-sub-folders-cache): Modified so that
- creating nested folders doesn't produce inconsistent results.
- (mh-prompt-for-folder): Remove call of mh-folder-list-change-hook.
-
- * mh-funcs.el (mh-kill-folder): Don't ask for confirmation if
- called on a folder holding index search results. Also the now
- removed mh-folder-list-change-hook is called no more.
-
- * mh-customize.el (mh-auto-folder-collect-flag)
- (mh-folder-list-change-hook): Removed.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-01-10 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-default-folder-must-exist-flag): New
- variable to suppress suggested folder if the folder doesn't
- already exist (closes SF #657096).
- (mh-default-folder-list): New variable that
- holds mapping between an address and the desired folder for
- filing (closes SF #657096).
- (mh-default-folder-prefix, mh-default-folder-must-exist-flag): In
- docstring, refer to documentation for mh-prompt-for-refile-folder
- and mh-folder-from-address.
- (mh-highlight-citation-p, mh-compose-insertion)
- (mh-insert-mail-followup-to-list, mh-index-program)
- (mh-identity-default): Fixed case of tags.
-
- * mh-e.el (mh-folder-from-address): Use new variable
- mh-default-folder-must-exist-flag to return nil if this variable
- is t and the folder doesn't already exist. In addition, can now
- look up a default folder in the new variable
- mh-default-folder-list (closes SF #657096).
- (mh-prompt-for-refile-folder): In docstring, refer to
- documentation in mh-folder-from-address.
-
- * mh-index.el (mh-swish-execute-search): Changed \..* to \\..* in
- the FileRules filename in the sample config file. Otherwise, the
- users don't see the backslash at all, and no files are indexed!
- (closes SF #665888).
-
-2003-01-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-folder): Get headers for exactly the
- messages that are present. If only messages 1-10 and 3800-3900
- are being shown then we will now scan exactly those messages and
- not the full range from 1-3900 as was being done earlier.
- (mh-toggle-threads): When converting from threaded to normal view
- only the messages present in the buffer are scanned. Earlier all
- messages from the minimum to the maximum would be scanned (closes
- SF #626117).
-
- * mh-pick.el (mh-search-folder): Fix typo.
- (mh-pick-do-search): Fix bug from cut and paste. Also set window
- config properly.
-
- * mh-utils.el (mh-prompt-for-folder): Add new argument to allow
- it to accept + as a folder name. This allows the user to search
- all folders when "Fs" is used.
-
- * mh-pick.el (mh-search-folder): Fix interactive spec of function.
- (mh-pick-do-search): Rewritten to call pick in one go. This will
- make adding pick as a default index search program easier. Also
- pick now accepts the same query syntax as the index search
- programs (closes SF #664816).
- (mh-next-pick-field): Removed.
- (mh-pick-parse-search-buffer): New function to parse the search
- buffer.
- (mh-pick-construct-regexp, mh-pick-regexp-builder): New function
- to produce a pick query from the parsed representation.
-
- * mh-index.el (mh-index-do-search): Refactor the search pattern
- parser into a new function and use that instead.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-01-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-utils.el (mh-remove-from-sub-folders-cache)
- (mh-prompt-for-folder): Replace mh-update-sub-folders-cache with
- mh-remove-from-sub-folders-cache.
- (mh-exec-cmd-daemon): Mention set-process-filter in documentation.
-
- * mh-pick.el (mh-searching-function): New buffer local variable
- that keeps track of the default searching function to be used.
- (mh-pick-mode): Make mh-searching-function buffer local.
- (mh-search-folder): Set mh-searching-function to use pick.
- (mh-search-folder, mh-pick-menu, mh-pick-mode-help-messages)
- (mh-pick-mode, mh-do-pick-search, mh-pick-do-search): Rename
- mh-do-pick-search to mh-pick-do-search. But keep
- mh-do-pick-search as a deprecated function.
- (mh-do-search): New interactive function that performs the
- default search.
- (mh-pick-mode-map): Update keymap.
-
- * mh-index.el (mh-index-search): Set mh-searching-function to do
- index search.
- (mh-index-new-folder): Replace mh-update-sub-folders-cache with
- mh-remover-from-sub-folders-cache.
-
- * mh-funcs.el (mh-kill-folder): Same as above.
-
- * mh-index.el (mh-index-evaluate, mh-swish++-regexp-builder):
- Checkdoc fixes.
-
- * mh-customize.el: Fixes to make byte compiler in CVS Emacs
- perfectly happy.
-
-2003-01-09 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folder-from-address): New function that proposes the
- name of a folder with an alias for the address in the current message.
- (mh-prompt-for-refile-folder): Use it (closes SF #657096).
-
- * mh-customize.el (mh-default-folder-prefix): New variable used by
- mh-folder-from-address.
- (mh-invisible-header-fields): Edited docstring.
-
- * mh-alias.el (mh-alias-address-to-alias): Added ;;;###mh-autoload
- cookie (used by mh-folder-from-address in mh-e.el). Edited text in
- comment.
-
- * mh-utils.el: Provided naming conventions for buffer and buffer
- variable names.
- (mh-temp-folders-buffer): Renamed buffer to " *mh-folders*".
- (mh-temp-sequences-buffer): Renamed buffer to " *mh-sequences*".
- (mh-info-buffer): Renamed from mh-temp-info-buffer.
- (mh-log-buffer): New buffer variable to hold name of "*MH-E Log*"
- buffer which is expected to be used for the output of MH commands.
- Perhaps we always create this buffer at initialization and append
- to it rather than erase it each time?
-
- * mh-e.el (mh-quit): Loop over all buffers and delete MH-E
- temporary and working buffers. As long as the buffer naming
- conventions are followed, new buffers will be automatically
- killed.
- (mh-version): Renamed mh-temp-info-buffer to mh-info-buffer.
-
- * mh-comp.el (mh-insert-x-mailer): Renamed mh-temp-info-buffer to
- mh-info-buffer.
-
-2003-01-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-folder-size): If the user doesn't have a
- Unseen-Sequence definition in .mh_profile then an error was
- produced. This change fixes that.
-
- * mh-seq.el (mh-thread-generate): Replace the *mh-thread* buffer
- with a temporary buffer which is cleaned up when the function
- exits.
-
- * mh-e.el (mh-prompt-for-refile-folder): New function which
- refactors out the intelligent folder guessing code from
- mh-refile-msg.
- (mh-refile-msg): Use mh-prompt-for-refile-folder.
-
- * mh-seq.el (mh-thread-refile): Use mh-prompt-for-refile-folder to
- do the same intelligent destination folder guessing as
- mh-refile-msg (closes SF #664829).
-
- * mh-utils.el (mh-folder-list, mh-make-folder-list-process)
- (mh-folder-list-temp, mh-folder-list-partial-line)
- (mh-set-folder-list): Removed.
- (mh-sub-folders-cache, mh-sub-folders, mh-sub-folders-actual):
- Moved over from mh-speed.el to implement hierarchical completion.
- (mh-update-sub-folders-cache): Utility function called when
- new folders are created or folders are removed.
- (mh-folder-completion-function): New function is the folder name
- completion function used in completing-read.
- (mh-folder-completing-read): A thin wrapper function that is used
- instead of completing-read directly. In the future we might want
- to allow the user a customizable variable which will turn off
- folders based completion.
- (mh-prompt-for-folder): Use mh-folder-completing-read to read in
- the folder name with hierarchical completion (closes SF #664821).
-
- * mh-speed.el (mh-speed-folders, mh-speed-folders-cache)
- (mh-speed-folders-actual): Moved to mh-utils.el as mh-sub-folders,
- mh-sub-folders-cache and mh-sub-folders-actual respectively.
- (mh-speed-invalidate-map, mh-speed-invalidate-map)
- (mh-speed-add-folder): Use the new names.
-
- * mh-funcs.el (mh-kill-folder): Remove code that used to update
- mh-folder-list which is no longer present. Instead
- mh-update-sub-folders-cache is called.
-
- * mh-index.el (mh-index-new-folder): Same as above.
-
-2003-01-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-exec-cmd-daemon): An argument was added which
- controls what is done with the process output.
-
- * mh-funcs.el (mh-kill-folder): Use mh-previous-window-config to
- restore window configuration. Also the call to mh-exec-cmd-daemon
- only displays output if an error happened (closes SF #664828).
- (mh-rmf-daemon): Check rmf output and display it only if
- something went wrong.
- (mh-print-msg): Pass in nil argument to mh-exec-cmd-daemon.
-
- * mh-comp.el (mh-redistribute, mh-send-letter): Pass in nil
- argument to mh-exec-cmd-daemon so that the functions will behave
- as before.
-
- * mh-pick.el (mh-search-folder): The current window config is
- stored.
- (mh-make-pick-template): Make the message headers read-only.
- (mh-pick-mode-help-messages): Update help message.
- (mh-do-pick-search): Fix problem when buffer isn't showing any
- messages.
- (mh-next-pick-field): Use buffer-substring-no-properties is
- better.
- (mh-pick-mode-map): Add key bindings (partially addresses
- SF #664816)
-
- * mh-index.el (mh-indexer-choices): Add a new field for each
- index program choice. If it is non-nil then it is the name of a
- function that given a lisp expression to search for generates a
- pattern that is acceptable to the search program.
- (mh-index-regexp-builder): New variable that stores the function
- to be used to convert from the lisp expression syntax to
- something that the search program understands.
- (mh-index-generate-pretty-name): Generalized so that it can take
- a list of strings as input.
- (mh-index-search): Modified so that if the configured program has
- a corresponding regexp-builder then a search buffer like pick
- search is produced. Otherwise the previous behavior is maintained.
- (mh-index-do-search): New interactive function that takes the
- contents of the search buffer, generates an appropriate query and
- produces the search results buffer by calling mh-index-search.
- (mh-replace-string, mh-index-parse-search-regexp)
- (mh-index-add-implicit-ops, mh-index-evaluate): New functions
- which parses the infix search expression that the user enters. A
- parse tree from which queries for different search programs can
- be produced is produced.
- (mh-swish++-regexp-builder, mh-swish++-print-regexp): Takes the
- internal form of the query and produces input suitable for
- swish++.
-
- * mh-loaddefs.el: Regenerated.
-
-2003-01-08 Bill Wohler <wohler@newt.com>
-
- * Makefile (emacs-logs): New target for viewing CVS Emacs logs.
- Useful to see if an Emacs developer has changed MH-E.
-
- * MH-E-NEWS: Fixed case of MH-E in the "Changes" title.
-
- * mh-utils.el (mh-temp-info-buffer): New variable to hold name of
- buffer that contains version info.
-
- * mh-e.el (mh-version): Use mh-temp-info-buffer instead of
- mh-temp-buffer since version information was getting clobbered by
- the aliasing code before it could be seen (closes SF #664467).
- (mh-quit): Delete mh-temp-info-buffer.
-
- * mh-comp.el (mh-insert-x-mailer): Use mh-temp-info-buffer to find
- version info instead of mh-temp-buffer. You kind of need this
- patch to send mail.
-
-2003-01-07 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Set to 7.1+cvs.
-
-2003-01-07 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.1.
-
- * MH-E-NEWS, README: Updated for release 7.1.
-
- * mh-e.el (Version, mh-version): Updated for release 7.1.
-
-2003-01-07 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-auto-folder-collect-flag,
- mh-alias-system-aliases, mh-alias-insert-file): Edited docstrings.
-
- * Makefile (MH-E-IMG): Added alias.pbm and alias.xpm.
-
- * mh-alias.el (mh-alias-insert-file, mh-alias-add-alias): Fixed
- checkdoc warnings.
-
-2003-01-07 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-search-from-end): New function that is used to
- replace our usage of the CL function search.
- (font-lock): The library is loaded to avoid compilation warning
- in CVS Emacs.
-
- * mh-speed.el (mh-speed-goto-folder, mh-speed-add-folder)
- (mh-speed-extract-folder-name, mh-speed-invalidate-map): Use
- mh-search-from-end instead of search.
-
- * mh-seq.el (mh-thread-remove-parent-link): Use loop instead of
- remove*.
- (mh-thread-process-in-reply-to): Use mh-search-from-end instead
- of search.
-
- * mh-index.el (mh-md5-parser): Fix name of function.
- (mh-index-update-single-msg, mh-index-update-maps): Avoid using
- destructuring-bind since Emacs-20.7 can't handle this particular
- usage.
- (mh-namazu-next-result): Use mh-search-from-end instead of
- search.
-
- * mh-e.el (recursive-load-depth-limit): Add a defvar since CVS
- emacs which doesn't have the variable defined causes a compiler
- warning.
- (mh-refile-a-msg): Rewritten to avoid using pushnew.
- (mh-undo-msg): Use loop instead of remove-if.
-
- * mh-comp.el (mh-show-buffer-message-number): Use
- mh-search-from-end instead of search.
-
-2003-01-01 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-visit-folder): Modified so that if RANGE is nil then
- all messages are displayed. Documentation modified so that this is
- explicitly stated.
- (mh-visit-folder): Really fix it this time.
-
-2003-01-01 Mark D. Baushke <mdb@gnu.org>
-
- * mh-alias.el (mh-alias-from-has-no-alias-p): Needs the
- mh-autoload comment or mh-customize may have problems finding the
- function.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-namazu-execute-search): Fix bug in documentation.
-
-2002-12-28 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-letter-mode): Mention mh-compose-insertion
- variable in docstring, explain how to expand directives, and
- don't mention mh-mhn-compose-insertion which isn't used directly
- any more.
- (mh-send-letter): Mention that X-Mailer and X-Face are inserted
- automatically so that a user isn't tempted to do so himself in
- mh-before-send-letter-hook.
- (mh-insert-letter): Use "variable" prefix for mh-invisible-headers
- now that we have both a function and a variable. Clarified
- language a bit.
-
-2002-12-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-xface-function): Only load x-face-e21 if
- the emacs is not XEmacs.
-
- * mh-index.el (mh-index-new-folder): The folder created should
- always be added to mh-folder-list. Otherwise folder name
- completion doesn't find the new folder created.
-
-2002-12-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-clean-message-header-flag)
- (mh-visible-headers, mh-invisible-headers)
- (mh-invisible-header-fields-set): Reworded to satisfy checkdoc.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-e.el (mh-inc-folder, mh-visit-folder, mh-read-msg-range):
- Handle nil value of mh-large-folder properly.
-
- * mh-customize.el (mh-tool-bar-show-set, mh-tool-bar-letter-set)
- (mh-tool-bar-folder-set, mh-tool-bar-folder-buttons)
- (mh-invisible-headers, mh-invisible-header-fields-set): Checkdoc
- fixes.
- (mh-large-folder): Updated to allow for infinity. If
- mh-large-folder is nil then all folders are deemed small.
-
-2002-12-23 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-inc-folder, mh-visit-folder): Emit a message if
- threading was suppressed because the number of messages exceed
- mh-large-folder.
-
-2002-12-23 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-invisible-headers): Deleted. Moved to
- mh-customize.el
-
- * mh-customize.el (mh-invisible-header-fields): New
- defcustom. Simple user interface to change mh-invisible-headers.
- (mh-invisible-header-fields-set): New function called when
- mh-invisible-header-fields is set.
- (mh-invisible-headers): New function. Does the actual work of
- building the variable mh-invisible-headers from
- mh-invisible-header-fields.
- (mh-invisible-headers): defvar moved from mh-utils.el
-
-2002-12-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-folder-size): Removed. Something very
- similar appears as mh-folder-size.
- (mh-speed-view): Simplified since the range selection logic has
- been moved to mh-read-msg-range.
- (mh-speed-parse-flists-output-line): Moved to mh-e.el as
- mh-parse-flist-output-line.
-
- * mh-funcs.el (mh-pack-folder): Use the new mh-read-msg-range.
-
- * mh-e.el (mh-rescan-folder): Use the new mh-read-msg-range.
- (mh-parse-flist-output-line): Moved from mh-speed.el where this
- function was called mh-speed-parse-flists-output-line.
- (mh-folder-size): Renamed from mh-speed-folder-size. The function
- has been made more general and can be called from any buffer and
- not just the speedbar buffer.
- (mh-visit-folder): Use the new mh-read-msg-range (addresses SF
- #655891).
- (mh-read-msg-range): Rewritten.
-
-2002-12-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-delete-subject-or-thread): New interactive
- function that intelligently deletes messages based on threading,
- if the folder is threaded, or on subject if folder isn't threaded.
-
- * mh-utils.el (mh-show-delete-subject-or-thread): New interactive
- function, callable from the show buffer, to intelligently delete
- messages based on threading info or subject.
- (mh-show-mode-map): Change binding of "k" to call
- mh-show-delete-subject-or-thread.
-
- * mh-e.el (mh-folder-mode-map): Change binding of "k" to call
- mh-delete-subject-or-thread.
-
- * mh-comp.el (mh-letter-mode-map): Add key binding for
- mh-insert-identity.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-21 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-tool-bar-letter-set): Bug fix. The
- `tool-bar-add-item-from-menu' items were broken. I can't use my
- constants there.
-
-2002-12-21 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-insert-file): Bug fix. I never checked
- that an AliasFile entry existed in .mh_profile.
-
-2002-12-21 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-alias-insertion-location): New defustom.
- Specifies where new aliases are entered in alias files.
-
- * mh-alias.el (mh-alias-add-alias-to-file): Use it.
-
-2002-12-21 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-add-alias-to-file): If ALIAS matches
- exactly, prompt to [i]nsert before old value or [a]ppend after it.
- (mh-alias-insert-file): Make sure we don't edit the passwd file.
- Add optional argument for alias; If ALIAS is specified and it
- already exists, try to return the file that contains it.
- (mh-alias-which-file-has-alias): New function. Return the name of
- writable file which defines ALIAS from list FILE-LIST.
- (mh-alias-add-alias): Remove prompts for case of alias already
- defined; done in mh-alias-add-alias-to-file.
-
-2002-12-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-folders-actual): Fix bug in parsing of
- folder names that have spaces in them. The original function would
- truncate the folder name at the first space.
- (mh-speed-flists): Add -sequence option to flists. This guards
- against the user specifying something other than the unseen
- sequence in his .mh_profile.
- (mh-speed-parse-flists-output-line): New function that parses a
- single line in the output of flists to find the folder name and
- the counts of unseesn and total messages.
- (mh-speed-parse-flists-output): Fix parsing bug which truncates
- the folder names at the first space.
-
- * mh-index.el (mh-index-generate-pretty-name): New function which
- generates a nicer name for the search results. It trims white
- space at the beginning and end and replaces white space with
- underscores within the search regexp.
- (mh-index-search): Use mh-index-generate-pretty-name.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-new-folder): Add new folder to
- mh-folder-list to enable name completion.
- (mh-glimpse-execute-search, mh-swish-execute-search)
- (mh-swish++-execute-search): Fix documentation.
-
- * mh-seq.el (mh-thread-generate): Fixed a stupid bug where the wrong
- folder could get 'scan'ed when generating the threaded view.
-
- * mh-index.el (mh-index-search): If optional prefix arg is given
- then the search in the current index buffer is redone.
- (mh-glimpse-execute-search, mh-swish-execute-search)
- (mh-namazu-execute-search): Documentation fixes.
-
- * mh-e.el (mh-index-previous-search): New buffer local variable
- stores parameters of search that created the buffer.
- (mh-folder-mode): Make mh-index-previous-search buffer local.
- (mh-visit-folder): Tweak the function so that only a single window
- with the folder buffer is shown if mh-showing-mode is nil.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-19 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-add-alias): Bug fix.
-
-2002-12-19 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-add-alias): New interactive command. Add
- ALIAS for ADDRESS in personal alias file.
- (mh-alias-grab-from-field): New interactive command. Add ALIAS for
- ADDRESS in personal alias file.
- (mh-alias-add-address-under-point): New interactive
- command. Insert an alias for email address under point.
- (mh-alias-suggest-alias): New function. Suggest an alias for STRING.
- (mh-alias-insert-file): New function. Return the alias file to
- write a new entry in.
- (mh-alias-address-to-alias): New function. Return the ADDRESS
- alias if defined, or nil.
- (mh-alias-from-has-no-alias-p): New function. Return t is From has
- no current alias set. Used as tool-bar button enable function.
- (mh-alias-add-alias-to-file): New function. Add ALIAS for ADDRESS
- in alias FILE without alias check or prompts.
-
- * alias.xpm, alias.pbm: New tool-bar icon for
- mh-alias-grab-from-field.
-
- * mh-e.el (mh-folder-line-matches-show-buffer-p): New function.
- Return t if the message under point in folder-mode is in the show
- buffer.
-
- * mh-utils.el (mh-goto-address-find-address-at-point): New
- function copied from goto-addr.el, which we don't want to
- force-load on users. Find e-mail address around or before point.
- (mh-address-mail-regexp): New defvar. A regular expression
- probably matching an e-mail address.
-
- * mh-customize.el (mh-alias-insert-file): New defcustom.
- Filename to use to store new MH-E aliases.
- (mh-tool-bar-folder-buttons): Enable mh-tool-bar-item-alias icon.
-
- * mh-comp.el (mh-extract-from-header-value): New function.
- Extract From: string from header.
-
-2002-12-19 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-update-single-msg): New defvar controls
- max number of command line args.
- (mh-index-execute): New function which is to be used
- instead of xargs so that we don't give the shell too many command
- line args.
- (mh-index-update-maps): Use mh-index-execute instead of xargs.
- (mh-index-search): Remove unused code. Also the first message in
- folder buffer is made current.
-
-2002-12-18 Peter S Galbraith <psg@debian.org>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-comp.el (mh-letter-tool-bar-map): Moved to mh-customize.el
-
- * mh-e.el (mh-folder-tool-bar-map): Moved to mh-customize.el
-
- * mh-utils.el (mh-get-msg-num): autoloaded.
- (mh-show-tool-bar-map): Moved to mh-customize.el
-
- * mh-customize.el (mh-tool-bar-item-*): 33 new defconsts for
- tool-bar setup and customization.
- (mh-tool-bar-folder-buttons-set): New function to setup the
- tool-bar after customization.
- (mh-tool-bar-folder-buttons): New defcustom to specify which icons
- appears in the tool-bar.
- (mh-tool-bar-letter-buttons-set): New function to setup the
- tool-bar after customization.
- (mh-tool-bar-letter-buttons): New defcustom to specify which icons
- appears in the tool-bar.
- (mh-tool-bar-show-set): New function to setup mh-letter-tool-bar-map.
- (mh-tool-bar-letter-set): New function to setup
- mh-letter-tool-bar-map.
-
-2002-12-18 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-folder-mode-map): Change entries for "\t", "\M-\t"
- and backtab to call mh-index-next-folder and
- mh-index-previous-folder as appropriate.
-
- * mh-index.el (mh-index-next-folder, mh-index-previous-folder):
- New interactive functions which jumps to search results of next
- and previous folders respectively.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-index.el (mh-index-delete-folder-headers): Arrange for
- mh-goto-cur-msg to just go to the current message.
-
- * mh-e.el (mh-visit-folder): Since mh-scan-folder erases the whole
- buffer anyway, we don't need to delete the folder headers. Also
- index-data is non-nil only when the buffer folder doesn't exist.
- So we need to call mh-make-folder.
- (mh-folder-mode): Fix bug in that mh-index-checksum-origin-map was
- not being made buffer local!
-
-2002-12-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-visit-folder): Fix bug.
-
- * mh-index.el (mh-md5sum-buffer): Buffer from which md5sum is run.
- (mh-index-folder-first, mh-index-folder-last)
- (mh-index-original-msg-list): Convenience macros aren't needed
- anymore since the data structure has been changed.
- (mh-index-update-single-msg): New function to update maps that
- relate MD5 checksums to actual messages and vice-versa for a
- single message.
- (mh-index-update-maps): Do the above for all messages. If some
- messages don't have MD5 checksums, they are annotated with the
- result of md5sum.
- (mh-index-search): Updated for the new version of mh-index-data.
- (mh-msg-exists-p): New function to test a message exists.
- (mh-index-insert-folder-headers): Updated for new mh-index-data.
- (mh-index-delete-folder-headers): New function used to eliminate
- original folder names from the buffer and make it look like a
- plain folder buffer. This is used from mh-process-commands.
- (mh-index-visit-folder): Use new version of mh-index-data.
- (mh-index-match-checksum): New function which checks if the
- X-MHE-Checksum header of a message matches.
- (mh-index-execute-commands): New function that rmm's the original
- messages. Then after mh-execute-commands executes it will seem
- that the original messages were executed upon. This completes the
- fix of SF #623321.
- (mh-checksum-buffer): Renamed from mh-md5sum-buffer.
- (mh-checksum-cmd, mh-checksum-parser): New globals to allow
- different checksum programs to be used.
- (mh-checksum-choose): New functions to find a checksum program.
- (mh-openssl-parser, mh-md5sum-parser, mh-md5-parser): Functions to
- parse the output of md5, md5sum and openssl.
- (mh-index-update-maps): Use checksum parsing function.
- (mh-index-search): Set checksum choice. Add a call to recenter,
- otherwise the window point in the index buffer doesn't get set
- properly.
-
- * mh-funcs.el (mh-pack-folder, mh-sort-folder): Enable these
- functions in folders created by index search.
-
- * mh-e.el (mh-index-msg-checksum-map)
- (mh-index-checksum-origin-map): New buffer local variables that
- keep track of message checksums (used to implement
- refiling/deletion for folders created by index folders).
- (mh-last-msg): Make the function behave like mh-first-msg.
- (mh-visit-folder): Add new optional argument which initializes
- folders created by mh-index-search.
- (mh-folder-mode): Make the variables mh-index-msg-checksum-map and
- mh-index-checksum-origin-map buffer local.
- (mh-process-commands): Call mh-index-execute-commands when called
- from an index search buffer. This will reflect the changes being
- made in the search folder to the original folders.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-insert-folder-headers): Fix a bug which
- caused the folder buffer to be marked as modified after rescanning
- an index folder.
-
-2002-12-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-visit-folder): The function should insert folder
- names if it is visiting a folder created by index search.
-
- * mh-index.el (mh-index-insert-folder-headers): The function now
- maintains the old value of buffer-modified-p and temporarily makes
- the buffer writable.
-
- * mh-utils.el (mh-show-index-visit-folder): New interactive
- function callable from show buffer that displays search results
- from one folder.
- (mh-show-mode-map): Key binding for "v".
-
- * mh-speed.el: Fix credits.
- (mh-index-folder-speedbar-buttons)
- (mh-index-show-speedbar-buttons)
- (mh-index-folder-speedbar-key-map)
- (mh-index-show-speedbar-key-map)
- (mh-index-folder-speedbar-menu-items)
- (mh-index-show-speedbar-menu-items): Removed since the modes
- mh-index-folder-mode and mh-index-show-mode no longer exist.
- (mh-speed-extract-folder-name): Remove the bits about
- mh-index-folder-mode and mh-index-show-mode.
-
- * mh-seq.el (mh-copy-seq-to-eob): Updated to work properly with
- index search results.
- (mh-region-to-msg-list): Skip over non-scan lines.
- (mh-thread-inc, mh-thread-add-spaces, mh-thread-folder): Skip
- non-scan lines when populating mh-thread-scan-line-map.
- (mh-thread-folder, mh-toggle-threads): Move the check for buffer
- modification from mh-thread-folder to mh-toggle-threads.
- (mh-toggle-threads): When returning to unthreaded view insert the
- folder names if called from a index folder.
-
- * mh-index.el: Fix credits and update commentary.
- (font-lock-defaults, mh-index-buffer, mh-index-show-buffer)
- (mh-index-ma-x-msg-index, mh-index-other-buffer)
- (mh-index-matches, mh-index-previous-window-configuration)
- (mh-index-current-msg, mh-index-folder-mode-keymap)
- (mh-index-button-map, mh-index-folder-mode-help-messages): Remove
- eliminated variables.
- (mh-index-folder): New variable sets the MH folder under which the
- index searches are stored.
- (mh-index-folder-first, mh-index-folder-last)
- (mh-index-original-msg-list): Convenience macros used to pull data
- elements out of a list. If needed setf can be used to change them
- as well.
- (mh-index-search): Rewritten to create real folders where all the
- normal folder operation. This partially fixes SF #623321 (refiles
- and deletes doesn't work on original messages).
- (mh-index-find-max-width, mh-index-search-again)
- (mh-index-insert-scan, mh-index-callback, mh-index-search)
- (mh-index-notate, mh-index-show, mh-index-header-display)
- (mh-index-next, mh-index-folder-mode, mh-index-show-mode):
- Functions, macros and modes removed.
- (mh-folder-exists-p): New function to check if a folder exists.
- (mh-index-new-folder): Generate a new folder name from a given
- base string that mimics the way emacs generates buffer names.
- (mh-index-insert-folder-headers): Insert folder names among the
- search results.
- (mh-index-visit-folder): New interactive function to show the
- search results of one individual folder.
- (mh-swish++-execute-search): Update documentation.
-
- * mh-funcs.el (mh-pack-folder, mh-sort-folder): Disable these
- functions if index search results are being viewed.
-
- * mh-e.el (mh-folder-font-lock-keywords): Add highlight for
- folder.
- (mh-index-data): New buffer local variable that will be used to
- store info about index search results.
- (mh-rescan-folder): Implement rescanning for index search results.
- (mh-folder-mode): Make mh-index-data buffer local.
- (mh-remove-all-notation): Modified to take into account not all
- lines in the folder buffer are normal scan lines.
- (mh-folder-mode-map): Add key binding for "v" to jump to original
- folder narrowed to search results.
-
- * mh-customize.el (mh-index-folder-face): Make it bold so that it
- will look like before.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-map-to-seq-msgs): Modified so that it can be given
- a list of messages in addition to a sequence.
- (mh-region-to-sequence, mh-region-to-msg-list): The function
- mh-region-to-msg-list replaces mh-region-to-sequence. The new
- function avoids creating a dummy sequence in MH-E.
- (mh-thread-delete, mh-thread-refile, mh-put-msg-in-seq): Modified
- to use mh-region-to-msg-list.
-
- * mh-funcs.el (mh-copy-msg): Modified to use mh-region-to-msg-list.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo): Modified to use
- mh-region-to-msg-list.
-
- * mh-comp.el (mh-forward): Modified to use mh-region-to-msg-list.
- The buffer-local variable mail-header-separator is no longer
- bound. This fixes a bug where the default value of
- mail-header-separator gets used if mh-forward is called in a fresh
- emacs session.
- (mh-annotate-msg): Update this so that it will handle message
- lists too.
- (mh-insert-letter): Make the test stronger. Since %d is being used
- the argument better be an integer.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-funcs.el (mh-copy-msg): Add support for transient-mark-mode.
- If mark is active and transient-mark-mode is enabled then all the
- messages in the region are copied.
-
- * mh-seq.el (mh-list-sequences): Use mh-coalesce-msg-list to print
- messages in sequence nicely. The prompt for the folder is removed
- (the current folder is always used) and the output is made nicer
- by not overflowing the screen width.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-letter-complete): Checkdoc fix.
-
- * mh-seq.el (mh-thread-current-indentation-level): New function
- which returns the thread indentation level of current message.
- (mh-thread-next-sibling, mh-thread-previous-sibling): New
- interactive functions to jump to the next and previous siblings in
- thread tree respectively.
- (mh-thread-immediate-ancestor): New function to jump to ancestor
- of current message in thread tree.
- (mh-thread-ancestor): New interactive function to jump to
- immediate ancestor or to root message of current thread depending
- on optional argument.
-
- * mh-utils.el (mh-show-thread-ancestor)
- (mh-show-thread-next-sibling, mh-show-thread-previous-sibling):
- Interactive functions callable from the show buffer.
- (mh-show-thread-map): Bindings for Tu, Tp and Tn.
-
- * mh-e.el (mh-thread-map): Bindings for Tu, Tp and Tn.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-region-to-sequence): Change name of region
- sequence created to 'mhe-region. This avoids any chance of
- collision with actual MH sequences.
- (mh-put-msg-in-seq, mh-thread-delete, mh-thread-refile): Change
- name of region sequence used to 'mhe-region. Also delete the
- 'mhe-region sequence when done.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo): Same as above.
-
- * mh-comp.el (mh-forward): Same as above.
-
- * mh-loaddefs.el: Regenerated.
-
-2002-12-08 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el: Edited documentation. Broke up file into 2
- sections: Alias Loading and Alias Expansion. Made terminology
- consistent (replaced expand, substitute, and translate with
- expand).
- (mh-alias-reload): Brought message in line with coding conventions
- and made more concise too.
- (mh-alias-translate): Renamed to mh-alias-expand.
- (mh-alias-substitute-aliases-flag): Renamed to
- mh-alias-expand-aliases-flag.
- (mh-alias-reload-local-users): Renamed to mh-alias-local-users.
- Now just returns an alist of local users rather than have
- side-effects.
- (mh-alias-reload): Set timestamp at beginning of function to catch
- edge case when alias added just after ali runs. Changed logic to
- reflect return value of mh-alias-local-users.
-
- * mh-customize.el (mh-alias-substitute-aliases-flag): Renamed to
- mh-alias-expand-aliases-flag.
- (mh-alias-local-users): Fixed documentation.
-
- * mh-loaddefs.el: Regenerated
-
-2002-12-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (require): Load Gnus at compile time so that the
- constant gnus-version is defined when MH-E is being compiled.
- (mh-macro-expansion-time-gnus-version, mh-run-time-gnus-version):
- Use the constant gnus-version instead of the function gnus-version
- to find out about gnus version information.
- (gnus-version): Remove the autoload since it is not needed any
- more.
-
-2002-12-08 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-version): Moved compilation information in front of
- Emacs information. The idea is that you start at MH-E and move
- outwards. Show N/A if Gnus not compiled (be explicit). Matched
- coding style with other output statements. (Aside: not that
- efficiency matters here, but fewer calls to format have to be
- faster, right? ;-). Matched output style of old output to new
- statement--liked Satyaki's indentation better ;-).
-
-2002-12-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (gnus-version): Autoload the function for use in
- mh-version.
- (mh-macro-expansion-time-gnus-version): New macro that finds the
- Gnus version at macro expansion time.
- (mh-run-time-gnus-version): New function to find the Gnus version
- at run time.
- (mh-version): Add information about Gnus versions available at
- compile time and run time.
-
-2002-12-07 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-ali): Add optional argument. if USER is
- t, then assume ALIAS is an address and call ali with option -user.
-
- * mh-alias.el (mh-alias-filenames): if ARG is t, appends list of
- files from `mh-alias-system-aliases' to output list obtained from
- mhparam output user list only.
- (mh-alias-tstamp): Use it.
-
-2002-12-05 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-inline-vcard-p): A new function which decides if
- a vcard should be displayed inline.
- (mh-mime-display-single): Use mh-inline-vcard-p to display
- attached vcard as a signature if no other signature is present
- (this partially addresses SF #649216).
-
-2002-12-05 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-send-letter): Edits docs for mh-mml-to-mime
- getting run if variable `mh-mml-compose-insert-flag' is set.
- (mh-get-header-field): use buffer-substring-no-properties instead
- of buffer-substring.
-
-2002-12-04 Peter S Galbraith <psg@debian.org>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-customize.el (mh-customize): Add ;;;###mh-autoload tag.
-
-2002-12-04 Peter S Galbraith <psg@debian.org>
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-comp.el (mh-letter-complete): New command to do alias or word
- completion in letter-mode.
- (mh-letter-mode-map): Add \M-\t binding for mh-letter-complete.
-
- * mh-alias.el (mh-alias-letter-mode-expand-alias-hook): Obsolete.
- Replaced by mh-letter-complete command.
- (mh-alias-reload-maybe): New function to rebuild alias table if
- out of date.
- (mh-alias-letter-expand-alias): No longer interactive. Use
- mh-letter-complete instead.
-
-2002-12-04 Peter S Galbraith <psg@debian.org>
-
- * mh-customize.el (mh-letter-complete-function): New defcustom.
- Function to call when completing outside of fields specified to
- aliases.
-
- * mh-alias.el (mh-alias-filenames):
- s/mh-mhparam-component/mh-profile-component/
- (mh-profile-component): Move to mh-utils.el and make interactive.
- (mh-read-address): Make it autoloaded.
-
- * mh-loaddefs.el: Regenerated.
-
- * mh-comp.el (mh-read-address): Removed. Replaced by mh-alias
- version.
-
- * mh-utils.el (mh-profile-component): Moved from mh-alias.el.
-
-2002-12-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-msg-is-in-seq): Formatting change.
-
- * mh-index.el (mh-index-insert-scan): Remove unused variable.
-
-2002-12-04 Bill Wohler <wohler@newt.com>
-
- * mh-loaddefs.el: Regenerated.
-
- * Makefile (MH-E-SRC): Moved mh-loaddefs.el into MH-E-LOADDEFS as
- this was causing a cycle.
- (MH-E-LOADDEFS): New variable to house mh-loaddefs.el.
- (emacs): Reintroduced autoloads.
- (autoloads): We're baaa-aack!
- (dist, install-emacs): Use MH-E-LOADDEFS.
-
- * mh-comp.el (mh-customize): Moved to mh-customize.el.
-
- * mh-customize.el (mh-customize): Moved here from mh-comp. Makes
- more sense, doesn't it?
-
- * mh-alias.el, mh-comp.el, mh-e.el, mh-index.el, mh-mime.el,
- mh-pick.el, mh-speed.el: Added mh-autoload cookie to all
- interactive functions.
-
-2002-12-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * Makefile (world): Remove target.
- (mh-loaddefs.el): Add comment that only GNU Emacs can be used to
- regenerate mh-loaddefs.el.
-
- * mh-make.el: Removed.
-
-2002-12-04 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (recursive-load-depth-limit): Only modify the limit
- if it is an integer.
-
-2002-12-04 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-header-field-beginning): New function. Move to
- the beginning of the current header field.
-
-2002-12-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-make.el (mh-files): Read in the MH-E filenames from the
- environment variable where the Makefile puts it.
- (mh-generate-autoloads, step2): Simplified since we now have the
- complete file names.
-
- * Makefile (world): Pass the MH-E files into the script, so that
- the filenames don't need to be repeated in the script.
-
-2002-12-04 Bill Wohler <wohler@newt.com>
-
- * mh-loaddefs.el: New file. Check in automatically generated file
- and include in package for the benefit of those who don't want to
- or can't compile.
-
- * Makefile (MH-E-SRC): Added mh-loaddefs.el now that it is checked
- in and will be packaged.
- (emacs): Removed autoloads. Adding mh-loaddefs.el to MH-E-SRC is
- sufficient to build it.
- (compile): Depend on MH-E-SRC instead of MH-E-OBJ and pass $? into
- emacs so that Emacs is only invoked once to compile files. This
- speeds things up by a factor of 3. It would be nice to only pass
- those files that have been modified, but Emacs 21.4 will have
- batch-byte-compile-if-not-done which we might be able to copy into
- mh-make.el (or my proposed mh-e-dev.el which would be more
- general-purpose).
- (.SUFFIXES): Removed. Now that compile works directly on the
- sources, the implicit rule is obsolete.
- (autoloads): Deleted. See emacs change above.
-
-2002-12-03 Bill Wohler <wohler@newt.com>
-
- * Makefile (MH-E-SRC, emacs):
-
-2002-12-03 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-make.el (mh-emacs): Make failing condition more strict.
- (mh-loaddefs-end): Remove redundant statement.
-
- * Makefile (world): A little typo. The bug didn't seem to make any
- difference though.
-
- * mh-make.el: New script that compiles MH-E.
- (mh-loaddefs-beginning, mh-loaddefs-end): Don't save the autoloads
- file in between. Only save at the end.
- (mh-emacs-generate-autoloads, mh-xemacs-generate-autoloads)
- (mh-generate-autoloads): Replace the separate functions in Emacs
- and XEmacs with one that works in both variants. This simplifies
- the script a lot.
- (mh-generate-autoloads): doc fix.
-
- * Makefile (world): New target which works for both GNU Emacs and
- XEmacs.
-
-2002-12-03 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-mhparam-component): Don't raise error if call to
- mhparam fails.
-
- * mh-alias.el (mh-alias-letter-expand-alias): Build alias table if
- not already available.
-
-2002-12-03 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-show-threads-flag): Alphabetized.
-
-2002-12-03 Jeffrey C Honig <jch@honig.net>
-
- * Makefile: Moved .PHONY rule after all rule for compatibility
- with BSD/OS's old pmake.
-
-2002-12-03 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-get-new-mail): Simplify no-new-mail test.
- (mh-add-cur-notation): Remove unnecessary function.
-
-2002-12-03 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-identity-make-menu): Check if
- 'mh-letter-mode-map' is bound, since this code also gets run when
- mh-customize.el is loaded at startup.
-
-2002-12-03 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-customize.el (mh-show-threads-flag): New customizable
- variable which controls if new folders start of in threaded mode
- (closes SF #646794).
-
- * mh-e.el (mh-rescan-folder): Fix the function so that threading
- is preserved across rescans.
- (mh-visit-folder, mh-inc-folder): The folder is threaded if it was
- already threaded or if mh-show-threads-flag is non-nil and the
- number of scan lines is fewer than mh-large-folders (closes SF
- #646794).
-
-2002-12-02 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-add-cur-notation): New function to mark the
- current message with the mh-note-cur character.
- (mh-get-new-mail): Use mh-add-cur-notation to undo the work of
- mh-remove-cur-notation if there was no new mail (closes SF #647681).
-
- * mh-e.el (mh-set-cmd-note): Do not update the default mh-cmd-note
- value (closes SF #643701).
-
-2002-12-02 Peter S Galbraith <psg@debian.org>
-
- * mh-alias.el (mh-alias-reload): Renamed from mh-alias-learn-aliases.
- (mh-alias-load-local-users): Renamed from mh-alias-learn-local-users.
- (mh-alias-passwd-alist): New variable, holding aliases extracted
- from the passwd file.
- (mh-alias-tstamp): New variable storing the timestamp for alias
- list generation.
- (mh-read-address, mh-alias-reload, mh-alias-reload-local-users):
- Complete rewrite.
- (mh-alias-minibuffer-confirm-address): Use mh-alias-translate.
- (mh-alias-translate): New function. Return translation for alias,
- checking if in blind or passwd list.
- (mh-alias-letter-expand-alias): Rewrite using
- mail-abbrev-complete-alias from mailabbrev.el.
- (mh-alias-expand-alias-map): New variable.
- (mh-alias-ali): New function. Return formatted string of
- translated ALIAS from ali.
- (mh-mhparam-component): New function. Return COMPONENT value from
- mhparam, or nil if unset.
- (mh-alias-filenames): New function. Provide list of alias
- filenames from mhparam, or nil if none are set.
-
- * mh-customize.el (mh-alias-display-blind-name-on-completion-flag):
- Obsoleted.
- (mh-alias-timestamp): Renamed to mh-alias-system-aliases.
-
-2002-12-02 Bill Wohler <wohler@newt.com>
-
- * Makefile (mh-loaddefs.el): Suppress creation of backup file.
-
-2002-12-02 Mark D. Baushke <mdb@gnu.org>
-
- * Makefile (mh-loaddefs.el): Simplify rule.
-
- * Makefile (clean): Remove mh-loaddefs.el* for good measure.
- ($(MH-E-OBJ)): Depend on mh-loaddefs.el to compile these.
- (autoloads, mh-loaddefs.el): Revamp rules.
- (mh-loaddefs.el-tail, autoloads-gen): Remove rules.
-
- * mh-e.el (recursive-load-depth-limit): Do not try to
- bump the value unless the variable exists.
-
- * mh-e.el (recursive-load-depth-limit): Bump value of
- recursive-load-depth-limit to 50 to allow emacs 21.1 which
- normally has a default value of 10 to be able to compile MH-E.
-
-2002-12-02 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-funcs.el (mh-pack-folder, mh-sort-folder): Fix the functions
- so that threading is preserved (needed for SF #646794).
-
- * mh-identity.el (mh-identity-signature-start)
- (mh-identity-signature-end): Checkdoc fixes.
-
- * mh-e.el (mh-previous-unread-msg, mh-next-unread-msg): Checkdoc
- fixes.
-
-2002-12-01 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-identity.el (compile): Make mh-identity.el compile without
- warnings.
-
- * mh-e.el (mh-previous-unread-msg, mh-next-unread-msg): New
- interactive functions that go to next and previous unread
- messages (closes SF #630328).
- (mh-folder-mode-map): Add key bindings for M-n and M-p to
- mh-folder-mode-map.
-
- * mh-utils.el (mh-show-next-unread-msg)
- (mh-show-previous-unread-msg): New interactive functions that go
- to the next and previous unread messages respectively. These are
- callable from the show buffer.
- (mh-show-mode-map): Add key bindings for M-n and M-p to
- mh-show-mode-map.
-
-2002-12-01 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-defun-compat): Make it indent like a defun.
-
- * mh-index.el (mh-defun-index): Make it indent like a defun.
-
- * mh-customize.el: New file (closes SF #643722).
-
- * Makefile (MH-E-SRC): Added mh-customize.el (closes SF #643722).
-
- * mh-speed.el, mh-pick.el, mh-mime.el, mh-index.el, mh-e.el,
- mh-comp.el: Moved all defgroups, defcustoms, and deffaces to
- mh-customize.el (closes SF #643722).
-
- * mh-utils.el (mh-xemacs-flag): Moved here from below since
- needed by mh-customize.el.
- (mh-customize): Required. mh-invisible-headers)
- (mh-bury-show-buffer-flag, mhl-formfile):
- Moved all defgroups, defcustoms, and deffaces to mh-customize.el
- (closes SF #643722) .
-
- * mh-identity.el (mh-comp-loaded): New variable in a desperate
- attempt to prevent an infinite loop.
- (eval-when-compile): Was able to remove these defvars as they are
- now predefined in mh-loaddefs and mh-customize.
- (mh-identity-list-set): Added ;;;###mh-autoload cookie.
- Moved all defgroups, defcustoms, and deffaces to mh-customize.el
- (closes SF #643722).
-
- * mh-alias.el (mh-e): Require this, as it needs defcustoms, which
- is in mh-customize which is required by mh-utils which is required
- by mh-e.
- Moved all defgroups, defcustoms, and deffaces to mh-customize.el
- (closes SF #643722).
-
-2002-11-30 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-thread-map): Add key bindings "Td" and "To" (closes
- SF #630493).
- (mh-help-messages): Update help message for prefix map.
- (mh-help-messages): Doc fix.
- (mh-help-messages): Really fix it.
-
- * mh-utils.el (mh-show-thread-delete, mh-show-thread-refile): New
- interactive functions corresponding to mh-thread-delete and
- mh-thread-refile callable from the show buffer.
- (mh-show-thread-map): Add key bindings for "Td" "To".
-
- * mh-seq.el (mh-narrow-to-seq, mh-put-msg-in-seq, mh-rename-seq)
- (mh-narrow-to-subject, mh-delete-subject, mh-toggle-threads): Add
- mh-autoload cookies.
- (mh-thread-find-children): New function which finds the region
- containing all children of a message.
- (mh-thread-delete): New interactive function that marks for
- deletion the current message and its children.
- (mh-thread-refile): New interactive function that marks for
- refiling the current message and its children.
-
-2002-11-30 Bill Wohler <wohler@newt.com>
-
- * mh-funcs.el, mh-identity.el, mh-index.el, mh-pick.el, mh-seq.el:
- Removed MH-E autoloads. These are now provided by mh-loaddefs.el.
- Added ;;;###mh-autoload tag to selected functions so that
- autoloads for those functions can be automatically created in
- mh-loaddefs.el (closes half of SF #643722).
-
- * mh-mime.el (mh-buffer-data): Moved to mh-utils where it is used.
- Added ;;;###mh-autoload tag to selected functions so that
- autoloads for those functions can be automatically created in
- mh-loaddefs.el (closes half of SF #643722)..
-
- * mh-utils.el (mh-loaddefs): Added require.
- (mh-buffer-data): Moved here from mh-mime.el as it is used in
- mh-display-msg.
- (mh-set-cmd-note): Moved to mh-e.el.
- Removed MH-E autoloads. These are now provided by mh-loaddefs.el.
- Added ;;;###mh-autoload tag to selected functions so that
- autoloads for those functions can be automatically created in
- mh-loaddefs.el (closes half of SF #643722)..
-
- * mh-e.el (mh-set-cmd-note): Moved here from mh-utils.el since it
- uses mh-scan-format-file which is defined here.
- Removed MH-E autoloads. These are now provided by mh-loaddefs.el.
- Added ;;;###mh-autoload tag to selected functions so that
- autoloads for those functions can be automatically created in
- mh-loaddefs.el (closes half of SF #643722)..
-
- * mh-comp.el, mh-speed.el (mh-utils): Removed require. mh-utils is
- provided via mh-e.el.
- Removed MH-E autoloads. These are now provided by mh-loaddefs.el.
- Added ;;;###mh-autoload tag to selected functions so that
- autoloads for those functions can be automatically created in
- mh-loaddefs.el (closes half of SF #643722)..
-
- * Makefile (emacs): Add dependency on autoloads.
- (clean): Remove mh-loaddefs.el too.
- (autoloads): New target. Builds mh-loaddefs.el.
- (mh-loaddefs.el): New target. Initializes mh-loaddefs.el.
- (mh-loaddefs.el-tail): New target. Appends to mh-loaddefs.el.
- (autoloads-gen): Runs batch-update-autoloads to populate
- mh-loaddefs.el (closes half of SF #643722)..
- (auto-autoloads.elc): Renamed from autoloads to be explicit about
- file that's created.
- (custom-load.elc): Ditto.
-
-2002-11-30 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-last-ancestor): New variable which keeps
- track of oldest ancestor of last message. If due to narrowing the
- common ancestor of two messages is lost then one of them is
- promoted to be the parent of the other. This variable helps in
- this process.
- (mh-thread-generate-scan-lines): Group messages which belong to
- the same thread tree, even if a common ancestor is no longer
- present.
- (mh-thread-folder, mh-copy-seq-to-eob, mh-thread-inc): Bind
- mh-thread-last-ancestor to nil when calling
- mh-thread-generate-scan-lines.
-
- * mh-mime.el (font-lock): Font-lock required at compile time to
- avoid warning about font-lock-maximum-size.
- (mh-display-smileys, mh-display-emphasis): Show graphical smileys
- and emphasis only if message isn't too large.
-
- * mh-e.el (mh-visit-folder): Revisiting a buried folder which has
- been threaded or narrowed confuses MH-E. Even though the folder is
- displayed as not threaded and not narrowed, MH-E still believes
- the folder is in the previous state. This can cause problems when
- trying to narrow/thread the folder. The change fixes this.
-
- * mh-mime.el (mh-mime-display-alternative): The setting of
- mh-display-buttons-for-inline-parts-flag was not being used when
- displaying one of the alternatives. This change fixes that.
-
- * mh-comp.el (mh-show-buffer-message-number): Replace subseq with
- substring.
- (mh-filter-out-non-text): When filtering out MIME buttons from
- yanked text, the last line of the MIME part was getting lost. The
- fix avoids that and removes only the last new line instead.
-
-2002-11-29 Peter S Galbraith <psg@debian.org>
-
- * Makefile (MH-E-SRC): Add mh-alias.
-
- * mh-alias.el: Assign copyright to FSF instead of myself.
- (mh-read-address): Add support for emacs-21's
- completing-read-multiple to prompt for multiple entries.
- (mh-alias-PC-complete-address): Deleted.
- (mh-alias-learn-aliases): Use mh-exec-cmd-quiet instead of old kludge.
- (mh-alias-letter-mode-expand-alias-hook): Simplify.
- (mh-alias-hostname): Deleted.
- (mh-alias-substitute-aliases-flag): Change default to nil.
- (mh-alias-display-blind-name-on-completion-flag) Change default to
- nil.
- (mh-alias-alist): Now holds alias values.
- (mh-alias-lowercase-alist): Deleted.
- (mh-alias-minibuffer-confirm-address, mh-alias-learn-aliases)
- (mh-alias-learn-local-users, mh-alias-letter-expand-alias): Use
- new mh-alias-alist instead of old mh-alias-lowercase-alist.
-
- * mh-alias.el: Moved from contrib/ directory. Now part of MH-E!
-
- * Makefile (MH-E-SRC): Add mh-identity.
-
- * mh-identity.el (mh-compose-and-send-mail, mh-insert-identity)
- (mh-identity-make-menu, mh-identity-default, mh-identity-menu):
- Moved to mh-comp.el.
-
- * mh-comp.el (mh-compose-and-send-mail): Add mh-identity support.
- (mh-insert-identity, mh-identity-make-menu, mh-identity-default)
- (mh-identity-menu): Added from mh-identity.el
-
-2002-11-29 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el, mh-e.el, mh-funcs.el, mh-identity.el, mh-index.el,
- mh-mime.el, mh-pick.el, mh-seq.el, mh-speed.el, mh-utils.el:
- Ran indent-region, reformatted long lines, ran untabify.
- (indent-tabs-mode): Set file local variable to nil.
-
-2002-11-29 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.0.
-
- * mh-e.el (Version, mh-version): Updated for release 7.0.
-
- * mh-comp.el (subseq, search): Require cl instead of autoloading
- these due to compilation warnings in CVS Emacs.
-
-2002-11-23 Bill Wohler <wohler@newt.com>
-
- * MH-E-NEWS: Emphasize the renaming of the variables at the top of
- the notes.
-
-2002-11-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-mode-map): Remove binding for RET since it
- is not needed and the binding is more useful to toggle display of
- MIME parts.
-
- * mh-mime.el (mh-mime-button-commands): Remove bindings for "i"
- and "o" from MIME buttons.
- (mh-insert-mime-button): Change comment to reflect change in
- button key map.
-
-2002-11-21 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 6.1.91.
-
- * mh-e.el (Version, mh-version): Updated for release 6.1.91.
-
- * MH-E-NEWS: Inline HTML parts supported with Gnus 5.10, not 5.9.
-
-2002-11-21 Mark D. Baushke <mdb@gnu.org>
-
- * mh-comp.el (mh-letter-insert-signature-hook): This should be in
- customize-group mh-compose.
-
-2002-11-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (load): Load mm-view.el here so that
- mm-inline-text-html would be defined if available.
- (mh-mm-inline-media-tests): If mm-inline-text-html is available
- then use it, otherwise fall back on using mm-inline-text (closes
- SF #641482).
-
- * mh-mime.el (load): Remove the load of mm-view here since it
- happens in mh-utils.el now.
-
-2002-11-15 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 6.1.90.
-
- * README (Compile): New section. Users must now compile MH-E due
- to the vagaries of the various versions of gnus.
-
- * Makefile (MH-E-IMG): Added reply-all.pbm, reply-all.xpm,
- reply-from.pbm, reply-from.xpm, reply-to.pbm, reply-to.xpm.
- (MH-E-ETC-ETC): Added Makefile and README.
- (dist): Depend on all, so clean happens. Don't add .elc files to
- tarball as they are built upon installation now.
-
-2002-11-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-process-commands): Fix a bug in mh-execute-commands.
- If called in threaded mode, cur was always getting set to the last
- message in the folder.
-
-2002-11-14 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Updated for release 6.1.90.
-
- * MH-E-NEWS, README: Updated for release 7.0.
-
- * mh-utils.el (mh-index-search): Added full docstring which new
- users will need before they run a search!
- (mh-swish++-execute-search, mh-swish-execute-search,
- mh-namazu-execute-search mh-glimpse-execute-search): Added
- autoloads with full docstrings for the same reason!
-
- * mh-e.el (mh-limit-map): Removed / / alias for
- mh-narrow-to-subject.
-
- * mh-utils.el (mh-show-thread-map): Removed / / alias for
- mh-show-narrow-to-subject.
-
- * mh-seq.el (mh-delete-subject): Checkdoc fix.
-
- * mh-e.el (mh-help-messages): Added / prefix character to help
- string. Tweaked / helpstring a little.
-
-2002-11-14 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-set-cmd-note): Fix nitpick by adding one to the
- width for cosmetic reasons.
-
-2002-11-14 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-insert-identity): Fix a few things undone by
- Jeff's patch.
- (mml-insert-tag): Add autoload.
-
-2002-11-13 Mark D. Baushke <mdb@gnu.org>
-
- * mh-identity.el (mh-insert-identity): A value of either nil or
- "" should cause the field to be removed.
- (mh-identity-list): Update the docstring.
-
-2002-11-13 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-limit-map): New key map for limits (subject for now).
- * mh-utils.el (mh-show-limit-map): Same.
-
- * mh-seq.el (mh-delete-subject): Renamed from
- mh-delete-subject-sequence.
- (mh-narrow-to-subject): Renamed from mh-narrow-to-subject-sequence.
- (mh-next-unseen-subject-sequence): Removed. :-(
- * mh-e.el: Use 'em
- * mh-seq.el: Use 'em.
-
-2002-11-13 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-alt-show): New defalias for mh-show.
- (mh-alt-refile-msg): New defalias for mh-refile-msg.
- (mh-alt-send): New defalias for mh-send.
- (mh-folder-mode-map): Use mh-alt-show, mh-alt-refile-msg and
- mh-alt-send for the alias bindings.
- (mh-alt-visit-folder): New defalias for mh-visit-folder.
- (mh-folder-map): Use it.
- (mh-folder-message-menu): Revert previous change.
-
-2002-11-13 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-message-menu): Make key binding "o" appear in
- menu for mh-refile-msg.
-
-2002-11-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate-scan-lines): In threaded view,
- scan lines of duplicate messages were too long. The change fixes
- that.
-
-2002-11-13 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-adaptive-cmd-note-flag): Improved grammar in
- docstring.
-
- * mh-speed.el (mh-speed-run-flists-flag): While documenting this
- variable in the release notes, I was unsure what would happen if
- set to nil. So, I clarified the docstring and indicated
- implications of setting this variable to nil, and offered manual
- workaround.
-
-2002-11-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-quit): Fix documentation and run
- mh-before-quit-hook and mh-quit-hook.
-
-2002-11-13 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (with-mh-folder-updating): Renamed local variable
- mh-save-modification-flag to save-modification-flag.
-
-2002-11-12 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-index-keymap): Renamed to
- mh-index-folder-mode-keymap to be a closer to the usual keymap
- naming convention. Since we want our own keymap and not inherit
- the one in mh-folder-mode, we need to use a suffix other than
- -map.
-
- * mh-e.el (mh-folder-sequence-menu): s/Msg/Message.
- s/Seq/Sequence.
- (mh-folder-message-menu): s/Msg/Message. Removed redundant refile
- item.
- (mh-folder-folder-menu): Aligned symbols.
-
- * mh-index.el (mh-index-folder-message-menu): s/Msg/Message.
-
- * mh-utils.el (mh-show-sequence-menu): s/Msg/Message.
- s/Seq/Sequence.
- (mh-show-message-menu): s/Msg/Message. Removed redundant refile
- item.
- (mh-show-folder-menu): Aligned symbols.
-
-2002-11-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-matches, mh-index-current-match): Remove
- these variables since they were only used for glimpse and grep.
- Now the functionality of all the indexing programs will be
- uniform.
- (mh-index-search, mh-index-insert-scan, mh-defun-index)
- (mh-index-show): Simplify functions since matches are no longer
- shown.
- (mh-index-parse-match): Remove function.
-
- * mh-e.el (mh-scan-cmd-note-width, mh-scan-destination-width)
- (mh-scan-date-width, mh-scan-date-flag-width)
- (mh-scan-from-mbox-width, mh-scan-from-mbox-sep-width): New
- variables to keep track of the widths of the different fields in
- the scan lines.
- (mh-scan-field-from-start-offset, mh-scan-field-from-end-offset)
- (mh-scan-field-subject-start-offset): Offsets that are computed
- from the scan line widths.
-
- * mh-seq.el (mh-copy-seq-to-eob, mh-thread-inc)
- (mh-thread-parse-scan-line): Use new variables that remember the
- various offsets in place of integer constants.
- (mh-thread-generate-scan-lines): Space shouldn't be added here!
-
-2002-11-12 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-scan-format-mh, mh-scan-format-nmh): Noted that the
- first column is column number 0 and changed "sixth column" to
- "fifth column" accordingly.
-
- * mh-index.el (mh-index-folder-mode): Clarified method of replying
- in mode documentation.
- (mh-index-folder-tool-bar-map): s/mh-e/MH-E/.
-
- * mh-e.el (mh-generate-new-cmd-note): Try not to mention internal
- variable mh-cmd-note in docstrings.
-
- * mh-utils.el (mh-adaptive-cmd-note-flag): Set default value to t.
- Reworded docstring so it doesn't mention internal variable
- mh-cmd-note. Added information about using fixed-width message
- numbers.
- (mh-cmd-note): Mention mh-set-cmd-note in docstring. Also suggest
- that it is updated dynamically only if mh-scan-format-file is t.
- (mh-set-cmd-note): Grammar fix in docstring.
- (mh-cmd-note): Noted that the first column is column number 0.
-
- * mh-e.el (mh-scan-format-file): Added information about
- mh-set-cmd-note and mh-adaptive-cmd-note-flag to docstring.
-
- * mh-index.el (mh-index-keymap): Added bindings for i
- (mh-inc-folder), m (mh-send alias), and s (mh-send) since these
- appear to be supported and are found in the toolbar.
- (mh-index-folder-key-map): Ditto for f (mh-visit-folder alias), o
- (mh-visit-folder) alias, and v (mh-visit-folder).
- (mh-index-folder-mode-help-messages): Changes for above.
- (mh-index-folder-message-menu, mh-index-folder-folder-menu): New
- menus. I decided to delete the unavailable items since graying out
- implies that the user can do something to access them. In this
- case, that's not the case. Well, that's not entirely true--the
- user could write code for those functions ;-).
- (mh-index-folder-mode): Use new menus.
-
- * mh-utils.el (mh-prompt-for-folder): Added optional argument
- default-string which can be used in case the string for default
- isn't intuitive enough.
-
- * mh-index.el (mh-index-search): Made default prompt more
- intuitive (I hope!).
-
-2002-11-11 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-header-field-delete): Remove save-excursion.
- Strange that this worked for me before... Thanks to Jeff for the
- patch.
- (mh-insert-identity): Numerous tweaks and fixes from Jeff who also
- adds a nicer-looking MIME header for signatures inserted after
- MIME insertions.
-
-2002-11-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-parse-scan-line): Generalize this function
- so that it can take a string containing the scan-line as argument
- in addition to using the line at point.
- (mh-thread-add-spaces): New function to pad each scan line to the
- appropriate length. This is called when mh-cmd-note is increased.
-
- * mh-e.el (mh-generate-new-cmd-note): Make this work on a threaded
- folder by using mh-thread-add-spaces to pad the pre-existing lines
- in mh-thread-scan-line-map appropriately.
- (mh-thread-add-spaces): Autoload from mh-seq.
-
-2002-11-11 Mark D. Baushke <mdb@gnu.org>
-
- * mh-index.el: Fix checkdoc nit.
-
- * mh-mime.el (mh-display-buttons-for-inline-parts-flag): Renamed
- from mh-display-buttons-for-inline-parts.
- (mh-mime-display-single): Use it.
- This addresses part of SF #627015.
-
- * mh-e.el (mh-print-background-flag): Renamed from
- mh-print-background.
- * mh-funcs.el (mh-print-msg): Use it.
- This addresses part of SF #627015.
-
- * mh-comp.el (mh-delete-yanked-msg-window-flag): Renamed from
- mh-delete-yanked-msg-window.
- (mh-yank-from-start-of-msg, mh-yank-cur-msg): Use it.
- This addresses part of SF #627015.
-
- * mh-utils.el (mh-update-sequences-after-mh-show-flag): Renamed
- from mh-update-sequences-after-mh-show.
- (mh-show-msg): Use it.
- This addresses part of SF #627015.
-
- * mh-utils.el (mh-decode-quoted-printable-flag): Renamed from
- mh-decode-quoted-printable.
- (mh-display-msg, mh-decode-quoted-printable-have-mimedecode):
- Use it.
- This addresses part of SF #627015.
-
- * mh-utils.el (mh-recursive-folders-flag): Renamed from
- mh-recursive-folders.
- (mh-make-folder-list-background): Use it.
- * mh-funcs.el (mh-list-folders): Ditto.
- This addresses part of SF #627015.
-
- * mh-utils.el (mh-auto-folder-collect-flag): Renamed from
- mh-auto-folder-collect.
- (mh-find-path): Use it.
- This addresses part of SF #627015.
-
- * mh-utils.el (mh-decode-mime-flag): Renamed from
- mh-decode-mime.
- * mh-utils.el (mh-show-mode, mh-show-xface)
- (mh-decode-quoted-printable, mh-display-msg, mh-display-msg): Use it.
- * mh-mime.el (mh-graphical-smileys-flag)
- (mh-graphical-emphasis-flag): Ditto.
- * mh-index.el (mh-index-search, mh-index-show): Ditto.
- * mh-e.el (mh-header-display): Ditto.
- This addresses part of SF #627015.
-
- * mh-e.el (mh-make-folder-mode-line): Use save-window-excursion
- to get back to the current message.
-
-2002-11-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-keymap, mh-index-page-msg)
- (mh-index-folder-tool-bar-map): Replace mh-index-scroll-up with
- mh-index-page-msg.
- (mh-index-keymap, mh-index-previous-page): Replace
- mh-index-scroll-down with mh-index-previous-page.
-
-2002-11-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (autoload/require): Load mh-mime when mh-index.el is
- loaded. This fixes the infinite load loop. I am not sure what the
- actual problem is. Also removed the nop requires/autoloads.
- (mh-defun-index): Use the right argument for mh-recenter.
- Otherwise it misbehaves for the default value of
- mh-summary-height.
-
- * mh-e.el (mh-goto-next-button): Fix infinite loop when S-Tab was
- used on first line of index folder buffer.
-
-2002-11-09 Peter S Galbraith <psg@debian.org>
-
- * mh-index.el (mh-index-folder-tool-bar-map): Tool-bar for
- mh-index-mode.
- (mh-index-folder-mode): Use it.
- (mh-index-keymap): Added mouse-2 binding, like in regular
- folder-mode.
-
-2002-11-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-folder-mode): Fix doc string for major
- mode. It was pointing to the wrong keymap.
- (mh-index-show-mode): Fix doc string for mode. Also add mh-help
- support.
-
- * mh-comp.el (mh-forward, mh-yank-cur-msg): Use new macro
- mh-mark-active-p instead. This does the right thing for different
- variants of Emacs.
- (mh-yank-cur-msg): Add a space between sexprs.
-
- * mh-utils.el (mh-mark-active-p): New macro which papers over
- differences between GNU Emacs and XEmacs. The variables mark-active
- and transient-mark-mode are used in GNU Emacs while zmacs-regions
- and region-active-p are used in XEmacs.
-
- * mh-seq.el (mh-put-msg-in-seq, mh-thread-ancestor-p): Use
- mh-mark-active-p as above.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo): Use
- mh-mark-active-p as above.
-
-2002-11-06 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-yank-cur-msg): Fix for XEmacs. It didn't work
- with a selected region, and left the inserted text selected (in
- reverse video). I didn't use SF patch #402315 to implement this.
-
-2002-11-05 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-show-tool-bar-map): Change call to
- mh-tool-bar-search-command such that user can customize it for the
- current session.
-
- * mh-e.el (mh-folder-tool-bar-map): Same.
-
-2002-11-05 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el, mh-e.el (mh-tool-bar-search-function): Renamed from
- mh-tool-bar-search-command.
-
- * mh-index.el (mh-index-search): Backed out previous change to
- prompt. There ain't no folder named "all."
-
- * mh-utils.el (mh-tool-bar-search-command): Added mh-search-folder
- and mh-index-search to the docstring so that user can easily click
- on them for more information.
-
- * mh-pick.el (mh-search-folder): Mention that this function uses
- the MH pick command to give the user more information when
- choosing between mh-search-folder and mh-index-folder.
-
- * mh-index.el (mh-index-search): Edited the docstring. Direct the
- user to mh-index-program if necessary.
- (mh-index-program): Edited this docstring too. Viewing the help
- in a *Help* buffer really exposes grammatical flaws.
-
-2002-11-05 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-tool-bar-search-command): New defcustom to set
- what search function to use in tool-bar.
- (mh-show-tool-bar-map): Use it.
-
- * mh-e.el (mh-folder-tool-bar-map): Use it.
-
-2002-11-05 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-index-search): Changed default prompt from "+"
- to "all". mh-prompt-for-folder doesn't seem to mind.
-
- * mh-e.el (mh-folder-folder-menu): Added menu entry for
- mh-index-search.
-
- * mh-utils.el (mh-show-folder-menu): Added menu entry for
- mh-index-search.
-
- * mh-index.el: Added commentary on supported search engines and
- for getting started (initializing database).
-
-2002-11-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-keymap, mh-index-folder-key-map): Move key
- binding of "i" to "Fi".
- (mh-index-folder-mode-help-messages): Change help message to
- reflect above change.
-
-2002-11-04 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-index-program, mh-indexer): Swapped names since
- the former seems like a better user variable name. If you've
- customized mh-indexer, be sure to toss it out and customize
- mh-index-program.
-
-2002-11-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-indexer-choices): Not having the quotes in the
- binary names is a bit nicer since that maintains uniformity with
- the other names.
- (mh-index-choose): Use symbol-value instead of eval. Eval should
- be avoided except when it can't be :-).
-
-2002-11-04 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-index-program): New variable to hold the name of
- the indexer that was found; use this instead of clobbering
- user-customizable variable mh-indexer.
- (mh-index-search): Use it. Added comments to keep others from
- doing what I had done (fortunately, I caught myself before
- checking it in ;-).
- (mh-index-choose): Set mh-index-program instead of mh-indexer.
- Update docstring to describe side-effects.
-
- * mh-index.el (mh-indexer): Added swish++ to docstring. Chances
- are good that if someone has both swish++ and swish, they want to
- use the much faster, much smaller swish, so move it up in the
- list.
- (mh-indexer-choices): Ditto for rationale for moving swish++ up in
- priority over swish. Also, use -binary symbols instead of
- hard-coding binary names. This allows package installers to
- customize the location of the binaries in site-lisp and still have
- the auto-detection code work. It also allows one to have alternate
- binary names (see mh-swish++-binary).
- (mh-index-search): Ditto (moving swish++ up).
- (mh-swish++-binary): Look for search++, then search. The rationale
- is that a package maintainer may rename search to search++ if
- search is already in use (e.g., Debian) so try it first.
- (mh-swish++-execute-search): Replaced Satyaki's path with dummy
- path in docstring. Also removed RecurseSubdirs since this is the
- default. Added comment that index might be named index++ on some
- systems (e.g., Debian).
- (mh-index-choose): Updated to work with new mh-indexer-choices.
-
-2002-11-04 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-identity-list-set): Don't call easy-menu-add
- here, since that adds the menu to the Customize buffer in XEmacs.
-
-2002-11-04 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-mhn-compose-insert-flag)
- (mh-mml-compose-insert-flag): Removed eval-when-compile defvar.
-
- * mh-mime.el (mh-mhn-compose-insert-flag)
- (mh-mml-compose-insert-flag): Move variables to mh-utils.el.
- Fixes mh-letter-menu for XEmacs.
-
-2002-11-04 Eric Ding <eding@rational.com>
-
- * mh-comp.el (mh-rejected-letter-start): add another string
-
-2002-11-04 Eric Ding <ericding@alum.mit.edu>
-
- * mh-comp.el (mh-rejected-letter-start): regexp-opt doesn't take
- regexps as args, only regular strings
-
-2002-11-04 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-mail-followup-to): Don't modify a
- pre-existing M-F-T field. If a nmh replgroupcomps propagates a
- M-F-T field in a message reply, then we have to have it alone.
-
-2002-11-02 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el, mh-e.el, mh-funcs.el, mh-identity.el, mh-index.el,
- mh-mime.el, mh-pick.el, mh-seq.el, mh-speed.el, mh-utils.el,
- mh-xemacs-compat.el: Added Local Variables section. Defined
- sentence-end-double-space to be nil so that those who might not
- buy my setting of this variable can at least run checkdoc without
- a whole lot of noise.
-
-2002-11-02 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el: New file. Multiple Identify support for MH-E.
- Used to easily set different fields such as From and Organization,
- as well as different signature files. This file won't be included
- with V7.0.
-
-2002-11-02 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-mm-save-part): New function to wrap mm-save-part
- from Gnus 5.10 to make it explicit which code has been
- commandeered.
- (mh-mime-save-part): Call mh-mm-save-part instead of cut-n-pasted
- code from Gnus 5.10.
-
-2002-11-02 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-yank-from-start-of-msg): Edit docstring to
- mention related variables mh-reply-show-message-flag and
- mh-delete-yanked-msg-window.
- (mh-reply): Change the "Reply to whom" prompt.
-
-2002-11-01 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-show-hook): Moved to mh-utils.el where it is used.
- (mh-folder-list-change-hook): Converted this from defvar in other
- files to defcustom here. It is called, not documented as
- obsolete, and might as well be documented.
- (mh-inc-folder, mh-quit, mh-delete-a-msg, mh-refile-a-msg,
- mh-process-commands, mh-update-unseen): Added missing
- documentation about hook, or made verbiage about hook consistent
- throughout, even if the function isn't interactive.
-
- * mh-utils.el (mh-folder-list-change-hook): Moved defvar to mh-e
- and made it a defcustom.
- (mh-show-mode-hook): Put it back in (actually, it was in mh-e.el,
- but this is the place where it is called).
- (mh-show-hook): Moved here from mh-e.el since it's called here.
- (mh-show-mode): Call mh-show-mode-hook.
- (mh-show-mode, mh-show-msg, mh-find-path, mh-prompt-for-folder,
- mh-prompt-for-folder, mh-set-folder-list): Added missing
- documentation about hook, or made verbiage about hook consistent
- throughout, even if the function isn't interactive.
-
- * mh-comp.el (mh-send-letter): Made verbiage about hook consistent
- throughout.
- (mh-insert-prefix-string): Made docstring more descriptive of what
- is going on.
-
- * mh-funcs.el (mh-kill-folder): Added missing documentation about
- hook.
-
- * mh-index.el (mh-index-show-hook): Moved defvar to defcustom.
- (mh-index-show): Made verbiage about hook consistent throughout.
-
- * mh-mime.el (mh-edit-mhn-hook): Moved defvar to defcustom.
- (mh-edit-mhn): Added missing documentation about hook.
-
- * mh-pick.el (mh-pick-mode): Made verbiage about hook consistent
- throughout. Call the damn hook.
-
-2002-11-01 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-insert-mail-followup-to-list): Fix typo so that
- it will look right in info.
-
- * mh-index.el (mh-index-search): Change argument name from
- new-buffer-p to new-buffer-flag.
- (mh-index-search-again, mh-index-search): New index-buffers were
- being named *mh-index*<2>, *m-index*<2><2> and so on. This problem
- is fixed.
- (mh-index-scroll-up, mh-index-scroll-down): Scrolling in index
- show buffers (after the first one) was broken.
- (mh-index-quit): Bury show buffer instead of killing it. Killing
- it, without killing the corresponding folder buffer, can cause
- confusion with two folder buffers trying to display in the same
- show buffer.
-
- * mh-seq.el (mh-thread-prune-containers): Rewritten without
- recursion. Also removed the top-level-p argument since it isn't
- required anymore.
- (mh-thread-sort-containers): New function factored out from
- previous definition of mh-thread-prune-containers. It sorts
- message containers in ascending order wrt their message indices.
- (mh-thread-generate): Use new mh-thread-prune-containers.
-
- * mh-e.el (mh-remove-all-notation): Fix the test. It was testing
- at the wrong place!
-
-2002-10-31 Bill Wohler <wohler@newt.com>
-
- * Makefile, README, import-emacs, mh-comp.el, mh-e.el,
- mh-funcs.el, mh-index.el, mh-mime.el, mh-pick.el, mh-seq.el,
- mh-speed.el, mh-utils.el: Replaced mh-e with MH-E.
-
-2002-10-31 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-parse-scan-line): Modified to remove user
- sequence notation and leave notation for other things alone. This
- ensures that threading doesn't lose notations for replied-to
- messages.
-
- * mh-e.el (mh-inc-folder): Remove call to mh-widen here and
- instead do it in mh-get-new-mail. This way the widening happens
- only if new mail is incorporated.
- (mh-generate-new-cmd-note): The function now returns the point
- from which the new messages start. This will allow threading to do
- the right thing.
- (mh-get-new-mail): Always call mh-remove-cur-notation. Otherwise
- adaptive scan mode leaves two messages marked as current in
- certain cases. Fix indentation of if statement. If there are
- messages to be incorporated, the folder is widened. If mh-cmd-note
- changes set start-of-inc correctly.
- (mh-remove-all-notation): Change this function to only remove user
- sequence notation and leave notation for replied-to messages and
- similar notation alone. This means operations like narrowing to
- subject sequence and widening don't lose notations.
-
-2002-10-31 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-insert-mail-followup-to-list): Fixed typo in
- docstring and other minor edits. Checkdoc removed trailing spaces.
- (mh-insert-signature): Checkdoc flagged docstring. Reverted to
- previous value. Added specific name of hook that is run.
- (mh-regexp-in-field-p, mh-insert-letter): Checkdoc removed
- trailing spaces.
-
-2002-10-31 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-show-mode-hook): Remove the unused
- mh-show-mode-hook, mh-show-hook is the one that is used.
-
- * mh-utils.el (mh-show-mode): Change the documentation to refer to
- mh-show-hook instead of the unused mh-show-mode-hook.
-
-2002-10-31 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-mail-followup-to-list): Set default to nil
- and include example in doc string.
-
-2002-10-31 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-indexer): Add customization choice for swish++.
- (mh-indexer-choices): Add swish++ choice.
- (mh-index-search): Change doc to reflect addition of swish++ option.
- (mh-swish++-binary, mh-swish++-directory): New variables for
- swish++ interface.
- (mh-swish++-execute-search): New function to execute swish++
- search.
- (mh-swish++-next-result): Function aliased to mh-swish-next-result
- since the result format of swish++ is the same as that of swish-e.
- (mh-index-search): Always overwrite window-configuration with new
- value. This is needed since we don't kill the index-buffer when
- quitting which means the window configuration wasn't getting set
- properly.
- (mh-index-search-again): If index buffer is reused, reset the old
- window config to its original value.
-
-2002-10-30 Bill Wohler <wohler@newt.com>
-
- * Makefile (emacs, xemacs): New targets.
- (all): Use these targets instead of calling specific targets.
- (.PHONY): Added emacs, xemacs, autoloads, custom-loads. Broke up
- target and moved pieces into their own sections.
-
-2002-10-30 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-show-font-lock-keywords): Wrap an
- 'eval-and-compile around its defvar, otherwise byte-compilation
- fails on `mh-show-font-lock-keywords-with-cite'.
-
-2002-10-29 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-letter-insert-signature-hook)
- (mh-insert-signature): Add a hook to be called before inserting
- the signature. Do not attempt to insert the signature if
- mh-insert-signature-file-name is nil.
-
-2002-10-29 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-inc-folder): Call mh-widen when mh-narrowed-to-seq
- (Closes SF #629233: inc in narrowed folder suboptimal)
-
- * mh-comp.el (mh-insert-letter): Stop using mhl to include a
- message before it mangles the header, and supercite fails
- (Closes SF #629153: mh-insert-letter uses mhl?).
- (mh-insert-prefix-string): Leave point at beginning instead of
- end, since that's what sc-cite-original does.
- (mh-yank-cur-msg): Adjust for mh-insert-prefix-string change.
-
-2002-10-30 Steve Youngs <youngs@xemacs.org>
-
- * mh-e.el (mh-folder-mode): Check for 'font-lock-auto-fontify'
- when in XEmacs so we don't do font-locking unconditionally.
-
- * mh-utils.el (mh-show-mode): Ditto.
-
-2002-10-29 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-refiled-face, mh-folder-cur-msg-number-face)
- (mh-folder-to-face, mh-folder-body-face): Define faces instead of
- copying them from font-lock faces. This mh-e will look the same
- in XEmacs as it does in Emacs.
- * mh-utils.el (mh-show-cc-face, mh-show-date-face)
- (mh-show-header-face): Ditto.
-
-2002-10-29 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-send-letter): I meant to use
- mh-goto-header-field, not mh-get-header-field. The former returns
- nil if the header is not found and doesn't need a conditional.
-
-2002-10-29 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-forward): Bug fix. Change 'kill-line for a
- 'delete-region, because I don't want that text yanked with C-y.
-
- * mh-seq.el (mh-put-msg-in-seq): Add support for selected
- region (Closes SF feature request #630324).
-
-2002-10-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-prune-subject): Make the regexp a little
- general so that a subject of the form "Re[218]: howdy" would be
- properly pruned.
-
- * mh-mime.el (mh-mime-save-part): Copy function definition of
- mm-save-part from cvs gnus since that function is buggy in gnus
- that comes with emacs21.2.
-
-2002-10-28 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-scan-subject-regexp): Add an expression to match an
- optional bracketed number after "Re", such as in "Re[2]:".
- (Patch by Satyaki; I checked it and applied).
- (mh-folder-font-lock-subject): Adapt to new mh-scan-subject-regexp.
- * mh-seq.el (mh-subject-to-sequence): Ditto.
-
- * mh-e.el (mh-folder-sequence-menu): Remove "Toggle Subject
- Thread" from menu. mh-toggle-threads is in the Folder menu.
-
- * mh-e.el (mh-folder-sequence-menu): Minor menu text edits.
-
- * mh-utils.el (mh-show-update-sequences): Added to
- mh-defun-show-buffer builds; needed for menu.
- (mh-show-sequence-menu, mh-show-message-menu)
- (mh-show-folder-menu): 3 new menus in mh-show-mode-map that mirror
- the menus used in mh-folder-mode.
- (mh-show-mode): easy-menu-add the 3 menus.
-
-2002-10-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-goto-msg): Fix the regexp to search so that we
- go to the right message. In a threaded folder message 2 may be
- present after 26 and the previous regexp would go to 26 when we
- really wanted to go to 2!
-
- * mh-seq.el (mh-widen): Add call to mh-recenter to make it like
- mh-narrow-to-seq.
-
-2002-10-28 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-show-mime-save-parts): Deleted definition.
- (mh-show-mime-map, tool-bar-map): Use mh-mime-save-parts instead
- of mh-show-mime-save-parts.
-
-2002-10-28 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-tool-bar-map): tool-bar-add-item key name
- bug fix.
- * mh-utils.el (mh-show-tool-bar-map): Same.
- * mh-e.el (mh-folder-tool-bar-map, mh-folder-seq-tool-bar-map): Same
-
-2002-10-27 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-toggle-threads): Add call to mh-recenter to make
- its behavior like that of mh-narrow-to-seq.
-
-2002-10-27 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-mime-save-parts): Renamed from
- mh-store-mime-parts for consistency with mh-mime-save-part. Fixed
- bug whereby mh-mime-save-parts-directory was not getting
- initialized properly from a string-valued
- mh-mime-save-parts-default-directory.
- (mh-mime-save-parts-default-directory): Ditto. Check your
- customizations!
- (mh-mime-save-parts-directory): Ditto.
-
- * mh-utils.el (mh-show-mime-save-parts): Renamed from
- mh-store-mime-parts.
- (mh-show-mime-map): Added keybinding "K a" for
- mh-show-mime-save-parts.
-
- * mh-e.el (mh-mime-save-parts) Renamed from mh-store-mime-parts.
- (mh-mime-map): Added keybinding "K a" for mh-mime-save-parts.
- (mh-help-messages): Added help for "K a".
-
-2002-10-27 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-search-addr-regexp, mh-regexp-in-field-p): Rename
- the first to the second (and recode a bit).
- (mh-insert-mail-followup-to): Use it.
-
-2002-10-27 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-invisible-headers): Backed out change. Removed
- Mail-Followup-To due to objections from Peter and Mark.
-
-2002-10-27 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-msg-is-in-seq): Modified to show info about
- whether the message being queried about has been marked to be
- deleted or refiled.
-
- * mh-mime.el (mh-insert-mime-security-button): Make
- pressed-details a local.
-
-2002-10-27 Steve Youngs <youngs@xemacs.org>
-
- * .cvsignore: New file.
-
-2002-10-26 Steve Youngs <youngs@xemacs.org>
-
- * mh-seq.el (mh-notate-deleted-and-refiled): Don't bind local
- variable 'dest', it isn't used anywhere.
-
- * mh-pick.el (mh-do-pick-search): Don't bind local variable
- 'finding-messages', it isn't used anywhere.
-
- * mh-utils.el: Byte-compiler warning suppression.
- (mh-gnus-article-highlight-citation): Rather than redefining
- 'gnus-cite-face-list', just re-order it.
- (mh-show-mode): Force turning on font-lock in XEmacs.
-
- * mh-seq.el: Byte-compiler warning suppression.
-
- * mh-index.el: Byte-compiler warning suppression.
-
- * mh-comp.el: Byte-compiler warning suppression.
-
- * mh-xemacs-compat.el: Add defaliases for 'timerp' &
- 'cancel-timer' to the equivalent 'itimer' functions.
- (rfc822): Require it for 'rfc822-goto-eoh'.
- Byte-compiler warning suppression.
-
- * mh-e.el (mh-folder-mode): Force turning on font-lock in XEmacs.
- (mh-toggle-threads): Remove duplicate autoload.
- Byte-compiler warning suppression.
- (mh-folder-unseen-seq-list): Use 'with-temp-buffer' to fix a bug
- in XEmacs when font-lock is on.
- (mh-folder-unseen-seq-name): Ditto.
-
-2002-10-27 Mark D. Baushke <mdb@gnu.org>
-
- * Makefile: Reorganize to allow for building also compiling for
- XEmacs too. Sanitize so that it will work using least-common
- denominator versions of 'make'. Tested using GNU make, Solaris make,
- and Berkely make.
- (all): Use recursive invocation based on the emacs or xemacs
- executable passed on the 'make EMACS=xemacs' command line.
- (XEMACS_OPTIONS): The incantation to be passed to an xemacs editor
- to compile things properly.
- (AUTO_PRELOADS): Magic XEmacs glue.
- (clean): Ditto.
- (autoloads): Ditto.
- (custom-loads): Ditto.
-
-2002-10-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-last-msg): Add call to mh-recenter.
-
-2002-10-26 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-search-addr-regexp, mh-re-search-to-cc): Remove
- `mh-re-search-to-cc' in favor of more generalized new function
- `mh-search-addr-regexp'.
- (mh-insert-mail-followup-to): Use it.
-
-2002-10-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-copy-seq-to-eob): Avoid rethreading when the
- folder is already threaded. This is more efficient and also avoids
- problems when the folder is widened.
- (mh-thread-inc): Don't try to restore the point to original
- location since mh-inc-folder from where this is called changes
- point location after calling this function.
-
- * mh-e.el (mh-make-folder-mode-line): Fix a small bug where the
- test was wrong.
-
-2002-10-26 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-mail-followup-to): Fix for new defcustom.
-
-2002-10-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-notate-deleted-and-refiled): Remove unused binding
- of dest. The problem was pointed out by Steve as well.
-
- * mh-e.el (mh-toggle-threads): Remove duplicate autoload as
- pointed out by Steve.
-
-2002-10-26 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-invisible-headers): Added Mail-Followup-To.
-
-2002-10-26 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-mail-followup-to-list): Change defvar to
- defcustom.
-
-2002-10-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-remove-all-notation): New function that removes all
- notation.
-
- * mh-seq.el (mh-narrow-to-seq): When hiding the original folder
- remove all notation. This avoids stale notation hanging around.
- Also changes in show buffer and position in folder buffer are
- avoided if possible.
- (mh-widen): When widening the scan-lines are notated based on the
- current state of the folder. This means any changes made when the
- folder was narrowed are shown consistently.
- (mh-notate-deleted-and-refiled): Update the documentation.
- (mh-thread-parse-scan-line): For some reason the ASCII value of
- the space character was being used here. This is fixed.
- (mh-thread-inc, mh-toggle-threads): Avoid change of point in
- folder and message being displayed in shown buffer.
-
- * mh-utils.el (mh-recenter): Rewrite mh-recenter to show fewer
- blank lines when point is towards the end of the folder buffer.
-
-2002-10-25 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-mail-followup-to-flag): New boolean
- defcustom to append a Mail-Followup-To field to the header. The
- insertion is done if the To: or Cc: fields matches an entry in
- `mh-insert-mail-followup-to-list'."
- (mh-insert-mail-followup-to-list): New defvar. List of addresses
- for which a Mail-Followup-To field is inserted.
- (mh-re-search-to-cc): New function. Search for REGEXP in To: and
- Cc: fields.
- (mh-insert-mail-followup-to): New function. Insert
- Mail-Followup-To: if To or Cc match `mh-insert-mail-followup-to-list'.
- (mh-compose-and-send-mail): Call mh-insert-mail-followup-to if
- mh-insert-mail-followup-to-flag is true.
-
-2002-10-25 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-show-maximum-size): New variable to control
- the display of large messages.
- (mh-display-msg): Use it (Closes SF #488696).
-
- * mh-seq.el (mh-toggle-threads): Checkdoc fix.
-
- * mh-e.el (mh-reset-threads-and-narrowing): Checkdoc fix.
-
- * mh-comp.el (mh-insert-x-mailer-flag): Renamed from
- mh-insert-x-mailer-p. Update docstring.
- (mh-send-letter): Use it.
- (mh-reply-show-message-flag): Renamed from
- mh-reply-show-message-p. Update docstring.
- (mh-reply): Use it.
- This addresses part of SF #627015.
-
- * mh-e.el (mh-recenter-summary-flag): Renamed from
- mh-recenter-summary-p. Update docstring.
- (mh-set-scan-mode): Use it.
- This addresses part of SF #627015.
-
-2002-10-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-reset-threads-and-narrowing): New function which
- resets all thread and narrowing state to completely unthreaded and
- widened state. As a side effect, the folder buffer is erased.
- (mh-rescan-folder): Reset threads and narrowing state.
-
- * mh-funcs.el (mh-pack-folder-1): Reset threads and narrowing state.
-
- * mh-seq.el (mh-copy-seq-to-eob): Change mh-view-ops after
- threading is over so that if user aborts threading, it doesn't
- leave mh-e in an inconsistent state.
- (mh-toggle-threads): Use mh-scan-folder to populate the folder
- buffer instead of mh-rescan-folder which resets threading and
- narrowing state.
-
-2002-10-24 Bill Wohler <wohler@newt.com>
-
- * mh-e is completely checkdoc clean now.
-
- * mh-utils.el (mh-clean-message-header-flag): Renamed from
- mh-clean-message-header.
- (mh-bury-show-buffer-flag): Renamed from mh-bury-show-buffer.
- (mh-show-use-goto-addr-flag): Renamed from mh-show-use-goto-addr.
- This addresses part of SF #627015.
-
- * mh-mime.el (mh-clean-message-header-flag): Renamed from
- mh-clean-message-header.
- Checkdoc fixes. This addresses part of SF #627015.
-
- * mh-index.el (mh-clean-message-header-flag): Renamed from
- mh-clean-message-header. This addresses part of SF #627015.
-
- * mh-funcs.el (mh-do-not-confirm-flag): Renamed from
- mh-do-not-confirm. This addresses part of SF #627015.
-
- * mh-e.el (mh-do-not-confirm-flag): Renamed from
- mh-do-not-confirm.
- (mh-clean-message-header-flag): Renamed from
- mh-clean-message-header.
- This addresses part of SF #627015.
-
- * mh-comp.el: checkdoc fixes.
-
-2002-10-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-copy-seq-to-eob): Rewritten to scan the headers
- fresh instead of yanking from buffer. This is needed to get
- correct threading in copied sequence.
- (mh-thread-inc, mh-thread-update-scan-line-map)
- (mh-thread-parse-scan-line): Eliminate the use, and hence the
- definition of, the kludgy mh-thread-update-scan-line-map. Instead
- the functions mh-notate-deleted-and-refiled and
- mh-notate-user-sequences are used to get the message marks right.
- (mh-thread-generate-scan-lines): Updated to allow the thread tree
- to be used in a narrowed folder buffer.
- (mh-thread-folder, mh-toggle-threads): Remove
- mh-folder-threaded-view-flag.
- (mh-thread-old-scan-line-map): New buffer-local variable that
- remembers the original scan-line map so that the sequence thread,
- narrow, widen will work.
- (mh-narrow-to-seq, mh-widen): Remember the scan-line map when
- narrowing and restore it when widening.
-
- * mh-e.el (mh-folder-threaded-view-flag, mh-folder-folder-menu)
- (mh-regenerate-headers, mh-get-new-mail)
- (mh-make-folder-mode-line, mh-process-commands)
- (mh-delete-scan-msgs): Remove mh-folder-threaded-view-flag.
- Instead (memq 'unthread mh-view-ops) is used to test if the folder
- is threaded.
-
- * mh-mime.el (mh-display-emphasis): Shadow article-goto-body here
- since we want to do emphasis on the whole of the region and not
- just after the first blank line.
- (mh-mm-display-part): When displaying a text part show smilies and
- emphasis.
-
- * mh-index.el (mh-index-insert-scan): Attempt to keep number of
- args to scan small if there are lots of adjacent matches.
- (mh-index-quit): Bury index-buffer on quit instead of killing it.
- This behavior is more like that of mh-quit.
-
- * mh-seq.el (mh-widen): If folder was threaded after narrowing
- then make mh-widen undo the threading instead of erroring out.
-
-2002-10-24 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-toggle-threads): Add a cond (as suggested by
- Satyaki) to properly unthread a narrowed-to-sequence.
-
- * mh-seq.el (mh-thread-generate-scan-lines): Fix threading
- breakage from partial switch to mh-container-real-child-flag and
- to dupl-flag.
-
- * mh-comp.el (mh-yank-cur-msg): Bug fix: specify
- (eq t mh-yank-from-start-of-msg) when that's what we want.
-
-2002-10-24 Mark D. Baushke <mdb@gnu.org>
-
- * mh-seq.el (mh-thread-prune-subject): Renamed subject-pruned-p as
- subject-pruned-flag.
- (mh-thread-inc): Renamed old-buffer-modified-p as
- old-buffer-modified-flag.
- (mh-thread-generate-scan-lines): Renamed dupl-p as dupl-flag.
- This addresses part of SF #627015.
-
- * mh-index.el (mh-index-advance): Renamed backward-p
- local variable as backward-flag.
- (mh-index-next-button): Renamed backward-p
- argument as backward-flag.
- (mh-index-show): Renamed display-headers-p argument as
- display-headers-flag.
- This addresses part of SF #627015.
-
- * mh-e.el (mh-scan-format, mh-version): Use mh-nmh-flag.
- (mh-folder-mime-action): Renamed include-security-p
- argument as include-security-flag.
- (mh-goto-next-button, mh-next-button): Renamed backward-p
- argument as backward-flag.
- (mh-get-new-mail): Renamed new-mail-p local variable as
- new-mail-flag.
- (mh-goto-cur-msg): Renamed minimal-changes-p argument as
- minimal-changes-flag.
- (redraw-needed-flag): Renamed redraw-needed-p local variable as
- redraw-needed-flag.
- (mh-seq-containing-msg): Renamed include-internal-p argument as
- include-internal-flag.
- (mh-page-msg): Use mh-page-to-next-msg-flag.
- This addresses part of SF #627015.
-
- * mh-mime.el (mh-mhn-compose-insert-flag): Renamed from
- mh-mhn-compose-insert-p. Make it buffer-local.
- (mh-mhn-compose-type, mh-mhn-compose-external-type,
- mh-mhn-compose-forw, mh-edit-mhn): Use mh-mhn-compose-insert-flag.
- (mh-mml-to-mime, mh-mml-secure-message-encrypt-pgpmime,
- mh-mime-display-part, mh-mime-display-single): Use
- mh-gnus-pgp-support-flag renamed from mh-gnus-pgp-support-p.
- (mh-mime-display-single): Renamed small-image-p local
- variable as small-image-flag.
- (mh-mime-inline-part): Renamed local variable inserted-p as
- inserted-flag.
- (mh-mime-inline-part): Renamed local variable displayed-p as
- displayed-flag.
- This addresses part of SF #627015.
-
- * mh-comp.el (mh-letter-menu, mh-letter-mode, mh-send-letter):
- mh-mhn-compose-insert-flag.
- (mh-repl-group-formfile, mh-forward): Use mh-nmh-flag
- renamed from mh-nmh-p.
- (mh-reply, mh-insert-x-mailer, mh-send-letter): Use mh-nmh-flag.
- (mh-letter-mode-map): Use mh-gnus-pgp-support-flag renamed from
- mh-gnus-pgp-support-p.
- (mh-mml-secure-message-sign-pgpmime): Use
- mh-gnus-pgp-support-flag.
- This addresses part of SF #627015.
-
- * mh-utils.el (mh-page-to-next-msg-flag): Renamed from
- mh-page-to-next-msg-p.
- (mh-show-msg): Use mh-page-to-next-msg-flag.
- (mh-gnus-pgp-support-flag): Renamed from
- mh-gnus-pgp-support-p.
- (mh-show-font-lock-fontify-region): Fix docstring per checkdoc.
- (with-mh-folder-updating): Renamed argument
- save-modification-flag-p as mh-save-modification-flag.
- (mh-prompt-for-folder): Renamed new-file-p local
- variable as new-file-flag.
- This addresses part of SF #627015.
-
-2002-10-24 Mark D. Baushke <mdb@gnu.org>
-
- * mh-comp.el (mh-forward): Fix mh-mml-compose-insert-p reference
- in last commit to be mh-mml-compose-insert-flag.
- (mh-mml-compose-insert-flag): Move defvar to fix compiler warning.
-
-2002-10-24 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-forward): Add support for transient-mark mode.
- When using nmh, always specify -mime so as to preserve the
- original message(s). If mh-compose-insertion is 'gnus, convert
- the mhbuild format forwarding directives into MML.
-
-2002-10-24 Eric Ding <ericding@alum.mit.edu>
-
- * mh-comp.el (mh-send-letter): Fix for earlier change that added
- "-mime" for bcc'ed MIME mail; still doesn't work with nmh 1.0, but
- at least no longer triggered for every outgoing message!
-
-2002-10-24 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-yank-cur-msg): Fix selected regions for supercite
- (see text below).
-
- * mh-comp.el (mh-yank-cur-msg): Fix for supercite. Someone played
- with the point and mark setting prior to the call to
- 'mh-insert-prefix-string and that broke supercite. I put comments
- to make it obvious to future coders why those settings exists.
- Note that supercite is still broken when a region is selected in
- the show buffer. Presumably it's been like that for a long time.
- We need to insert the header as well as the selected region oin
- that case. I'll submit an SF bug.
-
-2002-10-24 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-yank-from-start-of-msg, mh-reply): Use -noformat
- flag to reply when 'autosupercite or 'autoattrib are specified to
- prevent duplicate cites of the body of a message.
-
-2002-10-23 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (font-lock-default-fontify-region): Add autoload to
- avoid compiler warning.
-
-2002-10-23 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-mode): set fill-paragraph-function to our
- own 'mh-fill-paragraph-function instead of simply
- 'mail-mode-fill-paragraph (because it doesn't handle a non-nil
- fill-prefix correctly).
- (mh-fill-paragraph-function): New function for mh-letter-mode
- fill-paragraph-function in order to handle non-nil fill-prefix.
- Call sendmail's mail-mode-fill-paragraph if in the mail header,
- else call default fill-paragraph with fill-prefix set to nil.
- (Closes SF #489927)
-
- * mh-comp.el (mh-letter-mode): Let's use font-lock even if gnus is
- used in show-mode. The reason is that gnus uses static text
- properties which are not appropriate for a buffer that will be
- edited. So the choice here is either fontify the citations and
- header or the header only.
-
- * mh-utils.el (mh-show-font-lock-fontify-region): Limit font-lock
- in mh-show-mode to the header. Used when mh-highlight-citation-p
- is set to gnus, leaving the body to be dealt with by gnus
- highlighting. This fixes gnus text emphasis in mh-show-mode.
- (mh-show-mode): In font-lock-defaults, set
- font-lock-fontify-region-function to mh-show-font-lock-fontify-region.
-
-2002-10-23 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-mml-attach-file): Prompt for disposition should
- be Disposition, not Content-Type. The Content-Type has been
- determined automatically.
-
-2002-10-23 Mark D. Baushke <mdb@gnu.org>
-
- * MH-E-NEWS:
- s/mh-adaptive-cmd-note/mh-adaptive-cmd-note-flag/
- s/mh-show-use-xface/mh-show-use-xface-flag/
- s/mh-tool-bar-reply-3-buttons/mh-tool-bar-reply-3-buttons-flag/
- This addresses part of SF #627015.
-
- * mh-comp.el:
- s/mh-mml-compose-insert-p/mh-mml-compose-insert-flag/
- s/mh-xemacs-p/mh-xemacs-flag/
- (mh-letter-menu): Use mh-mml-compose-insert-flag.
- (mh-insert-x-mailer): Use mh-xemacs-flag.
- (mh-mml-compose-insert-flag): Renamed from
- mh-mml-compose-insert-p.
- (mh-send-letter): Use mh-mml-compose-insert-flag.
- This addresses part of SF #627015.
-
- * mh-e.el:
- s/mh-folder-threaded-view-p/mh-folder-threaded-view-flag/
- s/mh-adaptive-cmd-note/mh-adaptive-cmd-note-flag/
- s/mh-xemacs-p/mh-xemacs-flag/
- (mh-folder-threaded-view-flag): Renamed from
- mh-folder-threaded-view-p. Make it buffer local.
- (mh-folder-tool-bar-map): Use mh-tool-bar-reply-3-buttons-flag.
- (mh-remove-xemacs-horizontal-scrollbar): Use mh-xemacs-flag.
- (mh-make-folder, mh-regenerate-headers, mh-get-new-mail): Use
- mh-adaptive-cmd-note-flag.
- (mh-folder-folder-menu, mh-regenerate-headers, mh-get-new-mail,
- mh-make-folder-mode-line, mh-process-commands,
- mh-delete-scan-msgs): Use mh-folder-threaded-view-flag.
- This addresses part of SF #627015.
-
- * mh-index.el:
- s/mh-adaptive-cmd-note/mh-adaptive-cmd-note-flag/
- (mh-index-search): Use mh-adaptive-cmd-note-flag.
- This addresses part of SF #627015.
-
- * mh-mime.el:
- s/mh-mml-compose-insert-p/mh-mml-compose-insert-flag/
- s/mh-xemacs-p/mh-xemacs-flag/
- (mh-mml-compose-insert-flag): Renamed from
- mh-mml-compose-insert-p. Make it buffer local.
- (mh-mml-attach-file, mh-mml-secure-message-sign-pgpmime,
- mh-mml-secure-message-encrypt-pgpmime): Use it.
- (gnus-local-map-property): Use mh-xemacs-flag.
- This addresses part of SF #627015.
-
- * mh-seq.el:
- s/mh-folder-threaded-view-p/mh-folder-threaded-view-flag/
- (mh-thread-generate, mh-thread-folder, mh-toggle-threads): Use
- mh-folder-threaded-view-flag.
- This addresses part of SF #627015.
-
- * mh-speed.el:
- s/mh-speed-run-flists-p/mh-speed-run-flists-flag/
- s/mh-speed-refresh-p/mh-speed-refresh-flag/
- (mh-speed-run-flists-flag): Renamed from mh-speed-run-flists-p.
- (mh-folder-speedbar-buttons): Use it.
- (mh-speed-refresh-flag): Renamed from mh-speed-refresh-p.
- (mh-speed-update-current-folder, mh-speed-invalidate-map,
- mh-speed-add-folder): Use it.
- This addresses part of SF #627015.
-
- * mh-utils.el:
- s/mh-xemacs-p/mh-xemacs-flag/
- s/mh-tool-bar-reply-3-buttons/mh-tool-bar-reply-3-buttons-flag/
- s/mh-show-use-xface/mh-show-use-xface-flag/
- (mh-xemacs-flag): Renamed from mh-xemacs-p.
- (mh-show-xface-function): Use it.
- (mh-tool-bar-reply-3-buttons-flag): Renamed from
- mh-tool-bar-reply-3-buttons.
- (mh-show-tool-bar-map): Use it.
- (mh-adaptive-cmd-note-flag): Renamed from mh-adaptive-cmd-note.
- (mh-cmd-note): Use it in description.
- (mh-show-use-xface-flag): Renamed from mh-show-use-xface. Use
- mh-xemacs-flag.
- (mh-show-xface): Use mh-show-use-xface-flag.
- This addresses part of SF #627015.
-
-2002-10-23 Bill Wohler <wohler@newt.com>
-
- * Makefile (all): Rather than have to run "make clean all" all the
- time, make the default target do a clean so all you have to say is
- "make".
-
- * mh-e.el (mh-folder-map): Moved "t (mh-toggle-threads)" to T
- prefix.
-
-2002-10-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-indexer-choices, mh-swish-binary): The
- executable swish-e can be used to search (just like swish-search).
- However the Makefile in swish-e-2.2.2 doesn't install
- swish-search. So it is preferable to use swish-e.
-
-2002-10-22 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-letter-mode-map): Added aliases for keybindings.
- For example, you now have "C-c C-m C-i" in addition to "C-c C-m
- i".
-
-2002-10-22 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-graphical-smileys-flag): Renamed from
- mh-graphical-smileys-p.
- (mh-display-smileys): Use it.
- (mh-graphical-emphasis-flag): Renamed from mh-graphical-emphasis-p.
- (mh-display-emphasis): Use it. This addresses part of SF #627015.
-
-2002-10-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-insert-mime-security-button): A message is
- produced if PGP decryption/verification fails. This addresses
- SF# 627025.
-
-2002-10-21 Bill Wohler <wohler@newt.com>
-
- * mh-seq.el (mh-widen): Checkdoc removed the period in the error.
- The info node (elisp) Coding Conventions says: "An error message
- should start with a capital letter but should not end with a
- period."
-
- * mh-e.el, mh-utils.el (mh-tool-bar-reply-3-buttons): Moved
- defcustom to mh-utils because I got an error about a nil value for
- mh-tool-bar-reply-3-buttons when I fired up mh-rmail.
-
- * mh-comp.el, mh-funcs.el, mh-mime.el, mh-pick.el: Moved (provide)
- to the end of the file to be consistent with most other files (see
- additional rationale in mh-e.el description below).
-
- * mh-e.el: Had to remove eval-when-compile from the (require 'cl)
- here too (because the remove-if generated a warning in CVS Emacs).
- Moved (provide) to the end of the file to be consistent with most
- other files. My guess is that this is good to keep a feature from
- being "provided" if the file craps out while being loaded.
-
-2002-10-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-reply, Info-goto-node): Add autoloads to avoid
- compiler warnings.
- (mh-tool-bar-reply-3-buttons): Add defvar to avoid compiler
- warning.
-
- * mh-seq.el (mh-narrow-to-seq): Remember that a narrowing has
- occurred.
- (mh-valid-view-change-operation-p): New function that checks if
- the widening or unthreading that we are about to perform is
- allowed.
- (mh-widen): Check if widening is applicable.
- (mh-thread-inc, mh-thread-folder): Use delete-region instead of
- erase-buffer. This means if the buffer is narrowed then the hidden
- parts aren't removed. This allows widening of the folder later on.
- (mh-toggle-threads): Maintain mh-view-ops.
-
- * mh-e.el (mh-view-ops, mh-folder-mode): New buffer-local variable
- that keeps track of the sequence in which threading and narrowing
- of the folder buffer has been carried out. This is needed so that
- narrowing followed by threading (or vice versa) behaves in a
- reasonable manner.
- (mh-regenerate-headers): Use delete-region instead of
- erase-buffer.
- (mh-make-folder-mode-line): Change mh-first-msg-num and
- mh-last-msg-num conservatively. This might show a larger range in
- the mode-line but allows the unthreading to not miss messages
- present initially.
-
-2002-10-21 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-graphical-emphasis-p): Added _underline_ to the
- docstring, as well as the source of the strings,
- gnus-emphasis-alist.
- (mh-graphical-emphasis-p, mh-graphical-smileys-p): Set the default
- to t.
-
-2002-10-21 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-show-mode): Invoke new toolbar.
- (mh-show-tool-bar-map): New tool-bar for mh-show-mode, similar to
- mh-letter-mode.
-
-2002-10-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-display-msg): Call the smiley display function
- after the call to mh-show-mode. This is needed since mh-show-mode
- kills all buffer-local variables and resets the variable that
- controls display of graphical smileys.
-
-2002-10-21 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folder-mime-action): Change mime to MIME in message.
-
- * mh-comp.el (mh-mml-to-mime autoload): Ditto.
-
-2002-10-21 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (smiley-region): Use load for a non-fatal dependency
- on the smiley library.
-
-2002-10-21 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-forward): Search for a blank line as well as
- mail-header-separator.
- (mh-letter-mode): Search for a blank line as well as
- mail-header-separator.
- (mh-send-letter): The default BCC encapsulation will make a MIME
- message unreadable. If we are running nmh and the letter contains
- a Bcc: and a Content-Type: field, add the -mime switch to the
- arguments to send.
-
-2002-10-21 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el: Add a mh-defun-show-buffer call to define
- mh-show-pack-folder.
-
-2002-10-21 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-store-mime-parts): Simplify code a bit.
-
- * mh-e.el (mh-help-messages): Update help message for changed
- keybindings.
-
-2002-10-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-invalidate-map): Invalidate
- mh-speed-folders-cache before it is used by mh-speed-folders. Also
- fix indentation of if statement.
- (mh-speed-folder-size): The folder name should be extracted from
- the speedbar buffer and not from the temp buffer has was happening
- before.
- (mh-speed-folder-size): Harden the function some more. It
- shouldn't produce errors any more unless flist really didn't work.
-
-2002-10-21 Bill Wohler <wohler@newt.com>
-
- * mh-seq.el (mh-put-msg-in-seq): Formatting only. The reason I was
- in there is because I was trying to use mh-put-msg-in-seq and
- mh-msg-is-in-seq non-interactively and found that although the
- docstring says it uses the current message by default, I got
- errors if I passed in nil for the message. Is this expected, or is
- this a bug? I suppose the fix would be to make the arguments
- optional, right? This would cause the arguments in
- mh-put-msg-in-seq to be reversed, however. Might be a backwards
- compatibility problem.
-
- * mh-speed.el (mh-speed-view): Convert default size to string
- before passing it to read-string. This was done because XEmacs
- can't handle a numeric value for the default.
-
-2002-10-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-mode-map, mh-show-folder-map)
- (mh-show-sequence-map, mh-show-thread-map, mh-show-extract-map)
- (mh-show-digest-map, mh-show-mime-map): Interactive functions
- callable in show buffer are now prefixed with mh-show.
-
- * mh-seq.el (mh-notate-deleted-and-refiled): Take into account the
- changes to mh-refile-list and the removal of the 'deleted
- sequence.
- (mh-toggle-threads): Changing from threaded to normal view doesn't
- try to push out message refiles and deletions to MH.
-
- * mh-e.el (mh-rescan-folder, mh-scan-folder): Add a new optional
- argument to both functions that prevents them from carrying out
- pending refiles and deletes.
- (mh-undo): Remove dead code.
- (mh-delete-a-msg, mh-undo-msg): Get rid of the 'deleted sequence.
- The same information is present in mh-delete-list any way.
- (mh-refile-a-msg, mh-undo-msg, mh-process-commands): Change the
- semantics of mh-refile-list to make it self-contained. This
- variable now contains a list of lists. The first element of each
- sublist is the destination folder name. The remaining elements are
- the messages that are to be refiled to the destination folder.
- (mh-toggle-threads, mh-folder-folder-menu): Use mh-toggle-threads
- instead of mh-thread-folder.
-
-2002-10-20 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-store-mime-parts): Bug fix? Make this command
- work when in the show buffer, and not just in the folder buffer
- pointing to a message.
-
-2002-10-20 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-narrow-to-subject-sequence): Renamed from
- mh-narrow-to-subject-thread.
- (mh-subject-to-sequence): Renamed from mh-subject-thread-to-sequence.
- (mh-delete-subject-sequence): Renamed from mh-delete-subject-thread.
- (mh-next-unseen-subject-sequence): Renamed from
- mh-next-unseen-subject-thread.
- (mh-toggle-subject-thread): Removed. :-(
-
- * mh-e.el: s/subject-thread/subject-sequence/
- (mh-thread-map): Bind mh-widen to "w".
-
- * mh-utils.el: s/subject-thread/subject-sequence/
- (mh-show-thread-map): Bind mh-widen to "w".
-
-2002-10-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-folder): This function is no longer
- interactive. The mh-toggle-threads is the interactive function
- that gets called by the user. Also the already computed values in
- mh-first-msg-num and mh-last-msg-num are used instead of
- recomputing the first and last message indices in the current
- folder.
- (mh-toggle-threads): New interactive function that toggles
- threaded view of the folder.
-
- * mh-utils.el (mh-letter-toggle-threads): New interactive function
- which toggles thread view from show buffer. This function replaces
- mh-letter-thread-folder.
- (mh-show-folder-map): Use mh-letter-toggle-threads instead of
- mh-letter-thread-folder.
-
- * mh-e.el (mh-folder-map): Use mh-toggle-threads instead of
- mh-thread-folder.
-
-2002-10-20 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-scan-folder): Formatting only.
- (mh-goto-cur-msg): Removed call to mh-last-msg in those cases
- where there isn't a current message. Since I've started using the
- speedbar to read my mh-e mail, I've had to use M-< every time to
- go to the beginning of the new messages. Very annoying! Thus, if
- there isn't a current message, the cursor is left alone, which
- sounds like the right thing to do anyway.
-
-2002-10-19 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-subject-thread-to-sequence): Bug fix. After
- making the 'subject sequence real, I now have to delete it globally.
-
- * mh-seq.el (mh-toggle-subject-thread): Make toggle back to full
- scan exactly mh-widen (removed moving to current message).
-
- * mh-seq.el (mh-subject-thread-to-sequence): Make 'subject
- sequence a real one, exported to MH. This means you can, for
- example, mh-forward it. But it also shows up with a mark in the
- scan output. (Closes SF #489445).
-
-2002-10-19 Bill Wohler <wohler@newt.com>
-
- * mh-speed.el (mh-speed-view): If there weren't any unseen
- messages, and you specified a string (a sequence like "last") when
- prompted for the number of messages to display, you got an error.
- This has been fixed.
-
-2002-10-19 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-last-destination-folder): Destination of last refile
- command.
- (mh-last-destination-write): Destination of last write command.
- (mh-refile-msg): Use 'mh-last-destination-folder and update both it
- and 'mh-last-destination.
- (mh-write-msg-to-file): Use 'mh-last-destination-write and update
- both it and 'mh-last-destination (Closes SF #580772).
-
-2002-10-19 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-yank-from-start-of-msg): Changed default to
- 'attribution.
- (mh-letter-mode-map): Removed commented-out keybindings as well as
- alias "C-c C-m a (mh-compose-insertion)." Prefer "C-c C-m i."
-
- * mh-utils.el: Removed autoload of help. It no longer appears to
- be necessary in cvs Emacs (21.4).
-
-2002-10-18 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-execute-commands): Doc fix.
- (mh-compat-write-file-hook): Renamed to
- mh-write-file-functions-compat.
- (mh-folder-mode): Add mh-write-file-functions-compat instead of
- mh-compat-write-file-hook
-
-2002-10-18 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-invisible-headers-show-xface): Killed this
- variable.
- (mh-invisible-headers): Use 'mh-show-use-xface instead of
- 'mh-invisible-headers-show-xface to determine whether to render
- the X-Face header line visible or not.
-
-2002-10-18 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-compat-write-file-hook, mh-folder-mode): Use the new
- macro mh-compat-write-file-hook to use write-file-functions for
- Emacs 21.4 and local-write-file-hooks for older versions.
-
-2002-10-18 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-invisible-headers): Add more anti-spam headers.
-
-2002-10-18 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-mml-forward-message): mml-attach-file constructs
- a malformed composition if the description string is empty, so
- test for that and call mml-attach-file without that argument if
- it's an empty string (closes SF #625168).
-
-2002-10-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-keymap): Removed extra binding of " ".
- (mh-index-folder-mode-help-messages): Made the cheat sheet entry
- of quit like the others.
- (mh-index-search): If space was pressed in the index buffer before
- a search result has been shown with ".", the old show buffer would
- be scrolled. This is confusing since the index and show buffer
- contents are contradictory. Killing the show buffer here avoids
- this problem.
- (mh-index-configure-windows): Refine the window configuration
- logic. Avoid the two window view unless there is a message being
- displayed in the show buffer.
- (mh-index-scroll-up): Rewrite this function. The old version had a
- bizarre problem where the show buffer wouldn't be scrolled if the
- speedbar was present.
- (mh-index-scroll-down): Rewritten because of similar reason as
- above.
-
-2002-10-17 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-reply): Add an undo boundary in the undo list
- before calling 'mh-yank-cur-msg (closes SF #623693).
-
-2002-10-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-folder-mode): Use local-write-file-hooks instead of
- write-file-hooks. This is required for XEmacs and also the right
- thing according to GNU Emacs21 documentation.
-
-2002-10-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate): Get threading to work correctly
- on partial folders. The fix here disregards messages that aren't
- already present in the buffer.
- (mh-thread-folder): When querying scan about thread info try to
- avoid asking about messages that aren't present in the folder
- buffer. A more efficient fix would be to ask scan about just the
- messages that are present instead of a range of messages. However
- that runs the risk of sending long command lines to scan. Another
- change was to populate the mh-scan-line-map early so that the
- change in mh-thread-generate would work.
- (mh-thread-generate-scan-lines): In case duplicates are present
- make one of them the pseudo parent of the rest. This makes it look
- prettier if there are multiple duplicates at top level.
-
- * mh-comp.el (mh-edit-again): If a buffer in show-mode is being
- reused then reinsert message file. This should fix SF #624283.
-
- * mh-mime.el (mh-mm-display-part): Make sure mh-display-part is
- always called when we want to remove the displayed MIME part.
-
-2002-10-16 Bill Wohler <wohler@newt.com>
-
- * mh-speed.el (mh-speed-folder-size): checkdoc fix.
- (mh-speed-view): Tweaked output to mirror gnus verbiage. Offer
- to view number of messages in folder rather than mh-large-folder.
- Replaced (intern mh-unseen-seq) with mh-unseen-seq since the
- former was generating errors.
-
-2002-10-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-large-folder): New customizable variable to
- control mh-e's perception of large folders.
- (mh-speed-folder-size): New function which computes the size of
- folder on current line.
- (mh-speed-view): Modified to handle large folders. If the folder
- being clicked has unseen messages then only those messages are
- shown. Otherwise if number of messages in folder is larger than
- mh-large-folders then the user is asked for the number of messages
- to be shown. If the folder satisfies neither of the above cases
- then it is displayed in its entirety
-
-2002-10-15 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-index-keymap): Use gnus-define-keys. Sorted.
- Noticed that there were two key bindings for SPACE...
-
- * mh-speed.el (mh-folder-speedbar-key-map): Ditto (except for the
- dup SPACE binding).
-
- Completed help in other modes:
-
- * mh-utils.el (mh-xemacs-p): Fixed doc.
- (mh-show-mode-map, mh-show-folder-map, mh-show-sequence-map)
- (mh-show-thread-map, mh-show-extract-map): Added binding for
- mh-help.
-
- * mh-pick.el (mh-search-folder): Added startup help message.
- (mh-pick-mode-help-messages): New variable that contains help
- messages for pick buffer.
- (mh-pick-mode): Set local buffer variable mh-help-messages to
- mh-pick-mode-help-messages.
-
- * mh-index.el (mh-index-keymap): Added binding for mh-help.
- (mh-index-folder-mode-help-messages): New variable that contains
- help messages for MH Index buffer.
- (mh-index-folder-mode): Set local buffer variable mh-help-messages
- to mh-index-mode-help-messages.
-
- * mh-funcs.el (mh-help, mh-prefix-help): Call
- substitute-command-keys on the help messages.
-
- * mh-e.el (mh-help-messages): Added ,. Ran C-M-q.
- (mh-help): This autoload doc is now used for more than just the
- MH-Folder, so drop that specific text.
-
- * mh-comp.el (mh-edit-again, mh-extract-rejected-mail)
- (mh-forward, mh-reply, mh-send-sub): Call mh-letter-mode-message
- to display a help message at startup.
- (mh-letter-mode): Set local buffer variable mh-help-messages to
- mh-letter-mode-help-messages.
- (mh-letter-mode-help-messages): New variable with help messages
- for the MH-Letter buffer.
- (mh-letter-mode-message): New function that displays a startup
- help message.
- (mh-letter-mode-map): Added binding for mh-help. Sorted.
-
-2002-10-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speedbar-selected-folder-with-unseen-messages-face)
- (mh-speedbar-folder-face, mh-speedbar-selected-folder-face)
- (mh-speedbar-folder-with-unseen-messages-face): New faces for mh-e
- speedbar.
- (mh-folder-speedbar-buttons, mh-speed-update-current-folder)
- (mh-speed-add-buttons): Use the new faces.
- (mh-speed-normal-face, mh-speed-bold-face): Functions to convert
- to bold face and back to normal face.
- (mh-speed-set-face): Removed.
- (mh-speed-highlight): Modified to allow it to be used instead of
- mh-speed-set-face. Also changes were made to fontify folders with
- unread messages.
- (mh-speed-parse-flists-output, mh-speed-parse-flists-output)
- (mh-speed-invalidate-map): Use mh-speed-highlight instead of
- mh-speed-set-face.
-
-2002-10-15 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el, mh-seq.el, mh-speed.el, mh-utils.el: It appears that
- the cl package has been restructured in 21.4 in such a way that
- the use of eval-when-compile no longer suppresses warnings when
- compiling so that (require 'cl) must be called directly (maybe
- this is a bug in 21.4 ;-). Thus the autoloads of cl are no longer
- needed. Now compiles clean under 21.4.
-
- * mh-e.el (mh-folder-mode): The use of local-write-file-hooks is
- deprecated in Emacs 21.4, so use add-hook write-file-functions (or
- write-file-hook for older versions) with the LOCAL argument
- instead. Now compiles clean under 21.4.
-
- * mh-comp.el (mh-yank-cur-msg): Push a mark at the opposite end of
- the included text to make it easy to jump or delete to the other
- end of the included text.
-
-2002-10-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-insert-prefix-string): Remove the erroneous use
- of set-mark and other related functions.
-
-2002-10-14 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-yank-from-start-of-msg): Fixed documentation. It
- isn't ignored if there is a region. It is still used for the
- attribution.
- (mh-yank-cur-msg): Removed unnecessary push-mark when snarfing the
- entire message. Move the cursor to the end of the snarfed message
- if there is a region. In this case, push a mark so user can pop to
- the beginning of the snarfed fragment.
- (mh-insert-prefix-string): This calls set-mark which I find
- suspect since I found that my last user mark was deleted after
- yanking a message. Added a comment to this effect. Will probably
- add a bug report...
-
- * README (Installed, Supported versions): To appear in GNU Emacs
- 21.3; supported on Emacs 21, 20.7 and XEmacs 21.
-
- * mh-funcs.el (mh-concat-list): Deleted. Use mapconcat instead.
- (mh-help, mh-prefix-help): Use mapconcat instead of mh-concat-list.
- (mh-ephem-message): Use "%s" in message.
-
- * mh-funcs.el (mh-concat-list): New function to concatenate a list
- of strings into a single string. I would have thought elisp
- already contained a function like this, but I couldn't find it.
- (mh-ephem-message): New function to display a message in the
- minibuffer ephemerally. minibuffer-message seemed like the right
- function, but it writes to the current buffer oddly enough.
- (mh-help, mh-prefix-help): New functions to display command
- cheat sheets in the minibuffer (closes SF #493740). It would be
- nice to refactor these two into a single function if possible.
-
- * mh-e.el (mh-folder-mode-map, mh-folder-map, mh-sequence-map)
- (mh-thread-map, mh-extract-map): Added ? keybinding for `mh-help'
- and `mh-prefix-help' (closes SF #493740).
- (mh-help-messages): New variable to hold various help messages.
- (mh-help, mh-prefix-help): Autoload from mh-funcs.el.
-
-2002-10-13 Bill Wohler <wohler@newt.com>
-
- * mh-index.el (mh-glimpse-directory, mh-swish-directory,
- mh-namazu-directory): New variables that hold the name of the
- configuration and indexing directory. All are now hidden `.'
- directories.
-
- * mh-e.el, mh-funcs.el, mh-index.el, mh-mime.el, mh-pick.el,
- mh-seq.el, mh-xemacs-compat.el (Docstrings): Converted comments to
- docstrings, reworded some docstrings to conform to Emacs
- documentation conventions, and eliminated all checkdoc warnings
- (except for -flag, which we'll fix after 6.2 is released).
-
-2002-10-13 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-swish-next-result): Fix a bug in a corner case
- where the lack of a trailing "/" caused the function to wrongly
- filter out correct hits. This should fix SF #622679.
-
-2002-10-12 Steve Youngs <youngs@xemacs.org>
-
- * mh-utils.el (mh-xemacs-p): Simplify it, don't test for
- 'defvaralias' and don't use 'running-xemacs'.
-
-2002-10-11 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el: (Docstrings): Eliminated all checkdoc warnings by
- converting comments to docstrings and rewording some docstrings to
- conform to Emacs documentation conventions.
-
-2002-10-11 Steve Youngs <youngs@xemacs.org>
-
- * mh-utils.el (mh-xemacs-p): New.
- (mh-show-use-xface): Use it.
- (mh-show-xface-function): Ditto.
-
- * mh-e.el (toplevel): Ditto.
- (mh-remove-xemacs-horizontal-scrollbar): Ditto.
- (mh-folder-mode-map): Ditto.
-
- * mh-comp.el (mh-insert-x-mailer): Ditto.
-
- * mh-mime.el (gnus-local-map-property): Ditto.
- (mh-mml-to-mime): Move (require 'mh-utils) to toplevel.
- (mh-prompt-for-folder): Autoloading this not needed because
- mh-utils is now required at toplevel.
- (mh-show-xface): Ditto.
- (mh-show-addr): Ditto.
-
-2002-10-11 Bill Wohler <wohler@newt.com>
-
- * Makefile (EMACS_HOME): Set default to $(TOP)/../emacs so it
- would be useful.
-
- * mh-utils.el (mh-invisible-headers): Added various spam header
- fields.
- (mh-path-search): Removed argument `func-p' and related code. It
- was not documented and no one used it.
- (Docstrings): Converted comments to docstrings, reworded some
- docstrings to conform to Emacs documentation conventions, and
- basically eliminated all checkdoc warnings (except for -flag
- warnings).
-
-2002-10-11 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate): Kill dead code.
-
-2002-10-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-region-to-sequence): Don't include point-max in
- region (closes SF #621632).
-
- * mh-utils.el (mh-defun-show-buffer): Fix call of
- frame-first-window to work with XEmacs. Also avoid warning about
- cur-buffe-name in XEmacs.
- (mh-modify, mh-goto-msg): Remove dead code.
-
- * mh-speed.el (mh-speed-toggle, mh-speed-add-buttons): Remove dead
- code.
-
- * mh-seq.el (mh-subject-thread-to-sequence, mh-thread-get-message,
- mh-thread-generate, mh-thread-folder): Remove dead code.
-
- * mh-mime.el (mh-mm-inline-message): Remove dead code.
-
- * mh-index.el (mh-index-search): Remove dead code.
-
- * mh-comp.el (mh-open-line): Remove dead code.
-
- * mh-e.el (mh-folder-mode): Use the macro
- mh-remove-xemacs-horizontal-scrollbar to avoid compiler-warning in
- Emacs.
- (mh-remove-xemacs-horizontal-scrollbar): New macro to avoid
- compiler-warnings.
-
-2002-10-10 Mark D. Baushke <mdb@gnu.org>
-
- * Makefile (EMACS_OPTIONS): New macro for command-line compile
- options.
- (EMACS): Allow the user to specify which emacs command to use for
- the compile.
- (COMPILE_COMMAND): Combine the compile command with its options.
- (.el.elc): Use the new $(COMPILE_COMMAND).
-
-2002-10-10 Mark D. Baushke <mdb@gnu.org>
-
- * mh-speed.el (mh-speed-select-attached-frame): Define a new
- compatibility macro for getting to the attached-frame.
- (mh-speed-update-current-folder): Use it.
-
-2002-10-10 Mark D. Baushke <mdb@gnu.org>
-
- * mh-speed.el (mh-speed-update-current-folder): Use
- 'dframe-select-attached-frame if we are in a newer speedbar
- version that no longer supports the 'speedbar-attached-frame
- variable.
-
-2002-10-10 Steve Youngs <youngs@xemacs.org>
-
- * mh-speed.el (mh-speed-update-current-folder): Use
- 'dframe-select-attached-frame' if we're in XEmacs.
-
- * mh-e.el (mh-folder-mode): Remove the horizontal scrollbar from
- the MH-Folder buffer if we're in XEmacs.
-
-2002-10-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-show-xface-function): New global that stores
- what function needs to be called to display X-Face.
- (mh-show-xface): Rewritten to avoid compiler warning.
-
-2002-10-09 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-exchange-point-and-mark-preserving-active-mark):
- Simplify code for all emacsen to avoid byte-compilation warnings.
-
-2002-10-09 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-mm-display-part): If a sub-part of the current
- part is an inline image then clicking the button keeps the image
- around. The change fixes this bug.
-
-2002-10-09 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-exec-cmd-output): Use new function
- 'mh-exchange-point-and-mark-preserving-active-mark instead of
- 'exchange-point-and-mark. Fixes a bug in emacs20 and XEmacs21.
- (mh-exchange-point-and-mark-preserving-active-mark): New function.
- Does like 'exchange-point-and-mark but doesn't activate the mark.
-
- * mh-comp.el (mh-letter-menu): Allow access to "Pull in All
- Compositions" menu entries when edits have really occurred.
- Works with "forw: -mime" mh_profile entry, so this fixes a bug.
-
- * mh-mime.el (mh-mime-inline-part, mh-mm-display-part): Use
- line-beginning-position and line-end-position instead of
- point-at-bol and point-at-eol XEmacs functions.
- * mh-xemacs-compat.el: Added line-end-position and
- line-beginning-position compatibility aliases.
-
-2002-10-08 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-scan-msg-format-regexp): The regexp to find
- %number(msg).
- (mh-scan-msg-format-string): Format to be used with the current
- maximum width of message number for the folder in the
- `mh-update-scan-format' function.
- (mh-update-scan-format): Use `mh-scan-msg-format-regexp' for greater
- flexibility. The message number is no longer anchored to the
- beginning of the `mh-scan-format-nmh' or `mh-scan-format-mh' format
- strings. The `mh-update-scan-format' allows for using zero-filled
- message numbers.
-
-2002-10-08 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-folder-menu): Add entry for "Thread Folder".
-
-2002-10-07 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate): Use mh-progs to get path to mh
- executables.
-
- * mh-speed.el (mh-speed-flists): Use mh-progs to get path to mh
- executables right.
- (mh-speed-folders-actual): Same as above.
-
-2002-10-05 Steve Youngs <youngs@xemacs.org>
-
- * mh-comp.el (mh-yank-from-start-of-msg): Make default setting 't'
- a const.
-
- * mh-xemacs-compat.el (match-string-no-properties): Rewrite as a
- defsubst using 'buffer-substring-no-properties' so we don't grab
- any extents.
- (rfc822-goto-eoh): Removed. This exists in the XEmacs mail-lib
- package.
- (mail-header-end): Ditto.
- (mail-mode-fill-paragraph): Ditto.
-
-2002-10-05 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-invalidate-map): When called interactively
- the function will clear mh-speed-folders-cache.
-
-2002-10-02 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-insert-mime-button): Rewrite without using
- replace-match.
-
-2002-10-01 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-file-mime-type-substitutions): Reorder code to
- avoid compiler warning.
-
-2002-10-01 Bill Wohler <wohler@newt.com>
-
- * Makefile (MH-E-ETC): Moved ChangeLog into MH-E-ETC-ETC since it
- shouldn't get installed in Emacs.
- (install-emacs): Install MH-E-IMG into Emacs' lisp/toolbar and
- MH-E-IMG2 into Emacs' lisp/mail.
-
-2002-10-01 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-tool-bar-reply-3-buttons): New customization.
- Non-nil means use three buttons for reply commands in tool-bar.
- If you have room on your tool-bar because you are using a large
- font, you may set this variable to expand the single reply
- button into three buttons that won't lead to minibuffer prompt
- about who to reply to.
- (mh-folder-tool-bar-map): Use mh-tool-bar-reply-3-buttons to
- decide how many buttons to use for replying.
-
- * mh-mime.el (mh-file-mime-type-substitutions)
- (mh-file-mime-type-substitute): Fix typos and doc strings.
-
-2002-09-30 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-file-mime-type): Run Content-Type string returned
- by file command through mh-file-mime-type-substitute (see below).
- (mh-file-mime-type-substitute): Possibly change Content-Type
- string using mh-file-mime-type-substitutions variable. This is
- mostly because all MS-Office file are seen as application/msword
- by the file command.
- (mh-file-mime-type-substitutions): New variable. Defines
- substitutions to make for Content-Type returned from file command.
-
-2002-09-27 Bill Wohler <wohler@newt.com>
-
- * README: Moved Id to end of file since it broke outline mode at
- the beginning.
-
- * import-emacs (release): Renamed "mainline" tag to
- "emacs-mainline" to correspond with existing CVS tag.
- (EMACS_HOME): Fixed typo in docstring.
-
- * mh-utils.el (mh-folder-name-p, mh-defun-show-buffer): Lowercase
- NIL and T in docstring.
- (mh-update-scan-format): Fixed typo.
-
- * mh-comp.el, mh-e.el, mh-pick.el, mh-utils.el: Updated from CVS
- Emacs. The only new thing appears to be to downcase NIL and T in
- the documentation.
-
-2002-09-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate): The threading code will now be
- more resistant to corruption of messages. Before the change any
- corruption of message x would cause all messages with indices
- higher than x to be neglected when threading!
-
-2002-09-23 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-store-mime-parts): Don't store value into
- user-customizable variable mh-store-mime-parts-default-directory
- and use mh-store-mime-parts-directory instead.
-
-2002-09-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-prune-subject): Use regular expressions to
- make the subject pruning behave the way it is specified in the
- imap-thread RFC.
-
- * mh-speed.el (mh-speed-folders-actual): Don't use pop when we
- are not going to use the first element. This avoids a compilation
- warning with cvs emacs.
-
-2002-09-19 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-display-msg): Put the call to
- set-buffer-modified after mh-show-mode. This is needed for CVS
- emacs since calling mh-show-mode marks the buffer as modified if
- font-lock is on.
-
-2002-09-17 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-store-mime-parts-default-directory): Renamed from
- mh-store-mime-parts-directory.
- (mh-store-mime-parts-directory): Renamed from
- mh-store-mime-parts-directory-default.
-
-2002-09-16 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mail-citation-hook): Doc tweaks suggested by Bill.
-
-2002-09-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (autoloads): Reorder autoload of mh-reply to avoid
- compiler warning.
-
-2002-09-03 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-store-mime-parts-directory): New defcustom.
- Default directory to use for mh-store-mime-parts.
- (mh-store-mime-parts): New Command. Store the MIME parts of the
- current message.
- (mh-store-mime-parts-directory-default): New internal working
- variable. Default to use for mh-store-mime-parts-directory, set
- from last use.
-
- * mh-e.el (mh-folder-seq-tool-bar-map): Add mh-store-mime-parts to
- toolbar.
-
-2002-08-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-generate-scan-lines): In threaded view,
- complete scan lines are printed for all messages (not just the
- ones at the top of a thread).
-
- * mh-index.el (mh-index-insert-scan): Replace use of kill-line
- since that pollutes the kill-ring.
-
- * mh-comp.el (autoloads): Add autoloads for search and subseq to
- get rid of compiler warnings.
-
-2002-08-19 Peter S Galbraith <psg@debian.org>
-
- * reply-to.xpm, reply-to.pbm, reply-from.xpm, reply-from.pbm,
- * reply-all.xpm, reply-all.pbm: New icons for various reply methods.
- * mh-e.el (mh-folder-tool-bar-map): Split reply button into three
- that won't prompt for "from", "to" and "all".
- * mh-comp.el (mh-reply): Put variable reply-to in the interactive
- list since it's specified on the command line for the new toolbar.
-
- * mh-comp.el (mail-citation-hook): Tweak docs concerning
- historical usage for supercite.
- (mh-yank-from-start-of-msg): Add settings 'supercite and
- 'autosupercite. Rename 'automatic to 'autoattrib.
- (mh-insert-prefix-string): Invoke sc-cite-original if
- mh-yank-from-start-of-msg is et to 'supercite or 'autosupercite.
-
-2002-08-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (compilation-fix): Reorder defvars to avoid warnings
- during compilation.
-
-2002-08-17 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-yank-from-start-of-msg): Add 'automatic choice.
- Do as for `attribution' automatically when show buffer matches the
- message being replied-to.
- (mh-reply): Call 'mh-yank-cur-msg when mh-yank-from-start-of-msg
- is set to 'automatic and show buffer matches message number being
- replied-to.
- (mh-show-buffer-message-number): New helper function to get the
- message number of the current show-buffer.
- (mh-yank-cur-msg): Handle 'automatic choice the same as 'attribution.
- (mh-yank-cur-msg): Bug fix. It would bail on error if
- mh-show-buffer didn't exists.
-
-2002-08-16 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-x-mailer): It wrongly assumed that Emacs
- was used even when XEmacs was used. Fixed so X-Mailer header is
- more exact about what we are using.
-
-2002-08-15 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-version): Change CVS version number to 6.1+cvs just
- so X-Mailer header is more exact about what we are using.
-
- * mh-mime.el (mh-mhn-compose-insertion, mh-mhn-compose-anon-ftp,
- mh-mml-attach-file):
- "Jeffrey P. Morgenthaler" <jpmorgen@congee.gsfc.nasa.go> reported
- that "require" in emacs 20.3 doesn't handle 3 arguments. We
- use "load" at the top of file elsewhere anyway to handle such a
- case of non-essential loading, so switch to that here.
-
-2002-08-06 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-funcs.el (autoload): Add autoload for mh-speed-invalidate-map.
-
- * mh-speed.el (mh-speed-add-folder): New function to make the
- speedbar aware of new folders when they are created by mh-e.
-
- * mh-utils.el (mh-prompt-for-folder): Use mh-speed-add-folder to
- tell speedbar that new folder is being created. Also use folder
- instead of mkdir to create new folders.
-
-2002-08-01 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-decode-quoted-printable): Conditionalize the
- limit of search for quoted-printable. If we're using mm-decode
- for MIME decoding, it's possible that `mimedecode' could mess our
- message, so we only run a full search for quoted-printable parts
- when not using gnus' mm-decode. When using mm-decode, mimedecode
- can still help by handling the case of the whole message being
- quoted-printable as opposed to only a part.
-
-2002-07-31 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-compose-insertion): Moved from mh-mime.el because
- the pulldown menu were broken in XEmacs21 from this variable being
- undefined.
-
-2002-07-28 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-show-mode): Use the default paragraph-start
- rather than the inherited text-mode value.
-
-2002-07-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-duplicates): New hash table to track
- duplicate messages.
- (mh-thread-get-message): Remove debug code.
- (mh-thread-canonicalize-id): Modified to handle messages without
- message-id header. Such messages are given distinct copies of the
- empty string as message-id.
- (mh-thread-generate): The function was inadvertently rebuilding
- the thread tree when message refiles and message deletes are
- processed. The change here fixes that. Also code has been added to
- keep track of duplicate message-id's.
- (mh-thread-generate-scan-lines): Modified to print scan lines for
- duplicate messages (that is messages with the same message-id).
- (mh-thread-forget-message): Modified to maintain
- mh-thread-duplicates.
-
-2002-07-22 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-parse-flists-output): Use delete-region
- instead of kill-region. Otherwise the kill ring gets polluted.
-
-2002-07-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-thread-update-scan-line-map): New function to
- refresh the stale scan lines.
- (mh-thread-inc): Update old scan lines when mh-thread-inc is
- called. Otherwise notations for deleted and refiled messages get
- lost and the folder display gets out of sync with real mh-e state.
-
- * mh-mime.el (mh-mm-display-part): Call Gnus citation highlight
- code when text part is displayed. Otherwise buttonized text parts
- aren't correctly fontified when they are displayed.
-
-2002-07-15 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mm-decode): Use load for the Non-fatal dependency
- on the mm-decode library.
- * mh-mime.el (mm-decode, mm-uu, mm-view): Use load for the
- Non-fatal dependencies on the mm-decode, mm-uu and mm-view
- libraries.
-
-2002-07-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-require, mh-autoload): Remove these macros.
- (mh-decode-mime): Initialized to t iff the mm-decode library is
- present in the load-path.
- * mh-mime.el (mh-require): Don't use it anymore.
-
-2002-07-15 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-update-scan-format): Rewrite for compatibility
- with XEmacs as replace-match appears not to have identical
- functionality with GNU Emacs.
- (mh-scan-msg-format-regexp): Deleted. This regexp is now hardcoded
- into the mh-update-scan-format function.
-
-2002-07-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el: Add message threading code.
-
- * mh-utils.el (mh-letter-thread-folder): New interactive function
- that allows switching to threaded view from show buffer.
- (mh-show-folder-map): Bound "F t" to call mh-letter-thread-folder.
- (mh-goto-msg): Replace the function to not assume that messages
- are sorted in the folder buffer.
-
- * mh-e.el (mh-folder-threaded-view-p): New buffer local variable
- in the folder buffer that records whether threaded view is being
- used currently.
- (mh-scan-subject-regexp, mh-scan-format-regexp): Get font lock
- working for threaded view as well.
- (mh-regenerate-headers): Reset mh-folder-threaded-view-p to nil.
- (mh-get-new-mail, mh-process-commands): Do incremental threading
- if folder is in threaded view.
- (mh-delete-scan-msgs): Update thread tables if folder is in
- threaded view.
- (mh-folder-map): Add "F t" as key binding for mh-thread-folder
-
- * mh-comp.el (mh-yank-cur-msg): Bug fix. mh-show-buffer is only
- has a meaningful value in the folder buffer.
-
-2002-07-11 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-yank-cur-msg): Run only if mh-show-buffer
- actually exists (otherwise a back-traceable error occurred).
-
- * mh-utils.el (mh-find-progs): Run PATH search only when mh-progs,
- mh-lib and mh-lib-progs are not all already set. This allows the
- user to set them using a simple setq prior to loading mh-e. This
- is useful for implementation of mh-e on w32. Note that many
- commands still call mh-find-path which also parses the mh_profile
- file (that may still fail on w32), so this is still done often.
- But it lets us change the mh_profile file and have mh-e see the
- changed file without exiting emacs and starting over so I left
- that in.
-
-2002-07-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-show): Fixed a bug in mh-index-show which
- caused it to lose track of point when called from show buffer.
-
-2002-07-04 Mark D. Baushke <mdb@gnu.org>
-
- * Makefile: Add more information and common methods to allow both
- GNU make and Berkeley make to properly build everything.
-
-2002-07-04 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-push-button): Bug fix for mime display with
- mouse. Select show window before executing the mime display
- functions.
-
-2002-07-01 Mark D. Baushke <mdb@gnu.org>
-
- * Makefile: Use a conditional variable assignment operator rather
- than ifndef to let Makefile be used by both GNU make and Berkeley
- make (or similar versions of make). This does not help Solaris
- /usr/ccs/bin/make, but Solaris make has problems with the ifndef
- syntax too.
-
-2002-07-01 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-search): Check for mh-decode-mime before
- adding mh-mime-cleanup to kill-buffer-hook.
-
- * mh-mime.el (mm-destroy-parts): Add definition for old emacs.
-
-2002-06-30 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-update-scan-format): Add documentation string.
- (mh-scan-msg-format-regexp): Update the regexp to find %(msg).
- (mh-set-cmd-note): When mh-scan-format-file is not t, dynamic
- update of mh-cmd-note is wrong. Do not assume that
- mh-scan-format-nmh and mh-scan-format-mh can be kept in lock-step
- with mh-cmd-note via mh-set-cmd-note. The mh-scan-format function
- is now where the updated mh-cmd-note value is put into the scan
- format.
-
- * mh-e.el (mh-generate-new-cmd-note): Add documentation string.
- (mh-scan-format): Use mh-update-scan-format to get updated copies
- of mh-scan-format-nmh and mh-scan-format-mh to avoid format skew.
- (mh-get-new-mail): Do not try to adapt mh-cmd-note unless
- mh-scan-format-file is equal to t.
- (mh-scan-format-nmh): No longer buffer local.
- (mh-scan-format-mh): No longer buffer local.
-
-2002-06-30 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-max-msg-index): New variable to keep track
- of max message index among search results. If mh-adaptive-cmd-note
- is non-nil this is used to compute the width of the index field.
- (mh-index-search): Keep track of max index seen while parsing the
- search results and set it if mh-adaptive-cmd-note is non-nil.
- (mh-index-find-max-width): New function to find the required width
- of the message index field.
- (mh-defun-index): Binding buffer local variables is bad, so don't
- do that.
- (mh-index-show): New argument display-headers-p decides whether
- the message is displayed in raw form or not.
- (mh-index-header-display): New interactive function bound to ","
- which shows the message in raw form.
- (mh-index-keymap): Add appropriate bindings for backtab and ",".
- (read-from-string): Add ignore-errors around it so that the code
- doesn't die when it gets unexpected input.
-
-2002-06-29 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-count-windows): This function works around the
- lack of the window-list builtin function in emacs20.
-
-2002-06-29 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-message-number-width): New function to scan
- the last message of a folder and return its width.
- (mh-adaptive-cmd-note): New variable, if Non-nil indicates that
- mh-set-cmd-note should be called with the message width for the
- folder.
- (mh-cmd-note): Update documentation.
- (mh-update-scan-format): Helper function for updating the
- mh-scan-format-nmh and mh-scan-format-mh variables.
- (mh-scan-msg-overflow-regexp): New variable to help find problem
- messages after an inc.
- (mh-scan-msg-format-regexp): New variable to find the old message
- width in one of the mh-scan-format-nmh or mh-scan-format-mh
- variables.
- (mh-set-default-cmd-note): Replaced by mh-set-cmd-note.
- (mh-set-cmd-note): New function to replace update mh-cmd-note
- value.
-
- * mh-e.el (mh-regenerate-headers): If mh-adaptive-cmd-note is
- non-nil, use mh-set-cmd-note on empty folder buffers.
- (mh-make-folder): Ditto.
- (mh-generate-new-cmd-note): New function to adapt the mh-cmd-note
- to fit when mh-get-new-mail gets message number truncation.
- (mh-get-new-mail): Maybe use mh-generate-new-cmd-note if
- mh-adaptive-cmd-note is Non-nil.
-
-2002-06-29 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el (mh-speed-view): The display gets confused if the
- cursor is in the show buffer when mh-speed-view is called. This is
- a fix for that.
-
-2002-06-27 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-next-undeleted-msg): Get rid of optional arg
- reverse-p. If there are no more undeleted messages the point
- remains at its original position and a message is produced (closes
- SF #494304).
- (mh-previous-undeleted-msg): Change similar to
- mh-next-undeleted-msg.
- (mh-next-msg, mh-refile-msg, mh-delete-msg): Backout previous
- change.
- (mh-folder-map): Bind "S-tab" and "K S-tab" to mh-prev-button.
-
- * mh-utils.el (mh-show-mode-map): Bind "S-tab" and "K S-tab" to
- mh-letter-prev-button.
-
- * mh-mime.el (gnus-newsgroup-name): Initialize it to nil, so that
- mm-uu-dissect doesn't cause error.
-
-2002-06-27 Mark D. Baushke <mdb@gnu.org>
-
- * mh-utils.el (mh-cmd-note): Make buffer-local. Changes to this
- variable should be made via the new mh-set-default-cmd-note
- function.
- (mh-set-default-cmd-note): New function to setq-default the
- mh-cmd-note, mh-scan-format-mh and mh-scan-format-nmh values to
- related values.
-
- * mh-e.el (mh-scan-format-mh): Make buffer-local.
- (mh-scan-format-nmh): Ditto.
- (mh-scan-good-msg-regexp): Use a more general regular expression
- so that the width of message numbers, mh-cmd-note, may vary.
- (mh-scan-deleted-msg-regexp): Ditto.
- (mh-scan-refiled-msg-regexp): Ditto.
- (mh-scan-cur-msg-number-regexp): Ditto.
- (mh-scan-cur-msg-regexp): Ditto.
- (mh-scan-subject-regexp): Ditto.
-
-2002-06-26 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-speed.el: Speedbar support code.
-
- * Makefile: Add mh-speed.el to MH-E-SRC.
-
- * mh-utils.el (mh-prompt-for-folder): Add speedbar hook if
- speedbar is being used.
-
- * mh-funcs.el (mh-kill-folder): Add speedbar hook if speedbar is
- being used.
-
- * mh-e.el (speedbar-autoloads): Autoload speedbar initialization
- functions so that speedbar can find them.
-
-2002-06-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-grep-execute-search, mh-grep-next-result): Allow
- grep to be used to search mail.
- (mh-index-font-lock-keywords): Modified to avoid bug when using
- lazy font-lock.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg): Modify so that if no
- undeleted (or unrefiled) message exists in the current movement
- direction then try to find an undeleted (or unrefiled) message in
- the opposite direction instead.
- (mh-next-undeleted-msg): Added a new optional argument. If non-nil
- search for undeleted message backwards if none exists in the
- forward direction.
- (mh-previous-undeleted-msg): Added an optional argument. If
- non-nil search for undeleted message in the forward direction if
- none exists in the backward direction.
- (mh-next-msg): Optional argument to change direction if undeleted
- messages are not found in the current direction.
-
- * mh-index.el (mh-cmd-note): Use mh-cmd-note instead of hardcoding
- the index field size to 4.
-
- * mh-utils.el (mh-show-addr, mh-show-xface): New functions added
- to do xface display and goto-addr interface to allow reuse by the
- mime display code.
- (mh-show-mode): Use mh-show-addr and mh-show-xface. Only add
- mh-mime-cleanup to kill-buffer-hook if mime decoding is enabled.
- (mh-modify): Use mh-letter-mode instead of mh-show-mode when
- editing messages.
-
- * mh-mime.el (mh-mm-inline-message): Arrange for xface and
- highlighting to work in forwarded messages.
-
-2002-06-23 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-yank-from-start-of-msg): Add 'attribution' option
- to add an attribution line in mh-yank-cur-msg.
- (mh-extract-from-attribution-verb): Verb to use for attribution
- when a message is yanked by mh-yank-cur-msg. Provides a method
- for setting a different language.
- (mh-yank-cur-msg): Add support for 'attribution' option.
- (mh-extract-from-attribution): Function to get the attribution
- line, or the sender from the From: line in the current show buffer.
-
-2002-06-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-show): mh-display-msg was not being called
- in the show buffer. This causes weird results on some mime messages.
-
- * mh-mime.el (gnus-newsgroup-charset): Defvar to avoid error in
- pgp messages if gnus hasn't been used yet.
-
- * mh-comp.el (mh-letter-mode-map): Typo fix.
-
-2002-06-19 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-mml-secure-message-encrypt-pgpmime): Typo fix.
- (compiler-warnings): Add autoloads to remove compiler warnings.
-
- * mh-index.el (autoload-fixes): Fix autoload forms.
-
-2002-06-18 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-letter-mode-map): Change binding of "\C-c\C-ma"
- to mh-compose-insertion. Remove duplicate binding for "C-c\C-mf".
- (compiler-warnings): Add defvar to remove compiler-warning.
-
-2002-06-18 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-menu): Conditionalize GPG function on
- mh-gnus-pgp-support-p.
-
- * mh-mime.el (mh-mml-forward-message): s/subseq/substring/.
- (mh-compose-forward): cut&paste typo: s/messages/message/.
- (mml-minibuffer-read-file): autoload added.
- (mml-minibuffer-read-description): autoload added.
- (mml-insert-empty-tag): autoload added.
- (mh-mml-secure-message-sign-pgpmime): Check mh-gnus-pgp-support-p.
- (mh-mml-secure-message-encrypt-pgpmime): Check mh-gnus-pgp-support-p.
-
-2002-06-17 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-show-use-xface): Check for availability of
- `uncompface' executable on system.
-
- * mh-mime.el (mh-compose-forward): New front end for both
- mh-mml-forward-message and mh-mhn-compose-forw.
- (mh-compose-insertion): New front end for both mh-mml-attach-file
- and mh-mhn-compose-insertion.
- (mh-mml-to-mime): New function. Compose mime message from mml
- directives.
- (mh-mml-forward-message): New function. Forward a message as
- attachment.
- (mh-mml-attach-file): New function. Attach a file to the outgoing
- MIME message.
- (mh-mml-compose-insert-p): New variable. Buffer-local variable to
- know whether MIME insertion was done. Triggers an automatic call
- to `mh-mml-to-mime' in `mh-send-letter'.
- (mh-mml-secure-message-sign-pgpmime): New function.
- Front end to mml-secure-message-sign-pgpmime.
- (mh-mml-secure-message-encrypt-pgpmime): New function.
- Front end to mml-secure-message-encrypt-pgpmime.
-
- * mh-comp.el (mh-send-letter): automatic call to `mh-mml-to-mime'
- if mh-mml-compose-insert-p is set.
- (mh-letter-mode-map): Add keys for new mh-mime functions above.
- * mh-comp.el: Added autoloads for new mh-mime functions above.
-
-2002-06-17 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-show-use-xface): new defcustom to determine
- whether to call external package x-face to display the x-face.
- (mh-invisible-headers-show-xface): variable now defaults to value
- of mh-show-use-xface.
- (mh-show-mode): When mh-show-use-xface is t, invoke
- external package x-face to display the x-face.
-
-2002-06-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-prev-button): New interactive function which moves
- point to the previous mime button in the show buffer.
- (mh-folder-mode-map): Bind M-TAB and K M-TAB to mh-prev-button.
-
- * mh-utils.el (mh-show-mode-map): Bind M-TAB and K M-TAB to call
- mh-letter-prev-button (which is analogous to mh-prev-button).
- (mh-gnus-pgp-support-p): New global variable to replace the
- variable mh-recent-gnus-p. The name better describes what it is
- used for.
-
- * mh-mime.el (mh-mime-display-part, mh-mime-display-single): Use
- mh-gnus-pgp-support-p instead of mh-recent-gnus-p.
-
-2002-06-12 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-display-buttons-for-inline-parts): New
- customizable variable. When non-nil inline parts have are
- displayed with a button (that is initially expanded).
- (mh-maybe-insert-newline): The function has been removed.
- (mh-mime-display-single): Add code to display buttons for inline
- parts. Reduce the insertion of extra newlines between inline parts
- and also for pgp signature parts.
- (mh-mm-display-part): The function has been rewritten and cleaned
- up. There was a bug which could change the show buffer if the user
- pressed C-g while a mime part was being displayed has been fixed.
- (mh-press-button, mh-push-button): Use unwind-protect to make sure
- that set-buffer-modified-p is always called after mime display.
- (mh-mime-inline-part): The behavior of the function has been
- changed so that it toggles the display of the raw bytes.
- (mh-mime-display-security): Remove the display of too many
- newlines.
- (documentation): Remove most check-doc warnings.
-
- * mh-comp.el (mh-filter-out-non-text): Updated since whitespace
- added around mime buttons have changed.
-
-2002-06-10 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-index.el (mh-index-last-search, mh-index-search): The default
- prompt in mh-index-search has been removed since currently there
- is no good way of reading "+" with mh-prompt-for-folder.
- (mh-index-folder-mode, mh-index-show-mode): New major modes
- derived from mh-folder-mode and mh-show-mode respectively. They
- use a restricted keymap compared to the parent modes.
- (mh-index-folder-face): New customizable face to display folder
- names in the index buffer.
- (documentation): Change two spaces after period back to one.
-
-2002-06-08 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-folder-toggle-mime-part): New interactive function
- to control mime display from folder buffer.
- (mh-folder-inline-mime-part): New interactive function to inline
- raw mime part from folder buffer.
- (mh-folder-save-mime-part): New interactive function to save mime
- part from folder buffer.
- (mh-folder-mode-map): Add keybindings for "K v", "K o", "K i" and
- "K \t" to mh-folder-mode-map.
- (mh-goto-next-button): Modified to allow searching for next button
- that satisfies some condition.
- (mh-folder-mime-action): Support function for
- mh-folder-save-mime-part, mh-folder-inline-mime-part and
- mh-folder-toggle-mime-part.
-
- * mh-utils.el (mh-show-mode-map): Modify keymap to add appropriate
- bindings for "K v", "K o", "K i" and "K \t".
-
- * mh-index.el (documentation): Fix docs according to checkdoc
- format.
-
-2002-06-07 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el, mh-funcs.el (Compiler): Remove (require 'view) and
- instead add defvar for view-exit-action.
-
-2002-06-06 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (mh-insert-x-face): If transient-mark-mode is enabled
- the call to mark returns error. So avoid using mark.
-
- * mh-index.el: Support for new interactive function
- mh-index-search.
-
- * mh-e.el (mh-next-button, mh-goto-next-button): Refactor
- mh-next-button so that the code may be reused by mh-index.el.
- (mh-folder-map): Add key "F i" to call mh-index-search.
-
- * mh-utils.el (mh-recent-gnus-p): Fix documentation.
- (mh-msg-folder, mh-display-msg): The new function mh-msg-folder
- maps a MH folder name to the buffer displaying it. In normal
- operation the two names are identical but they are different in a
- folder buffer generated by index search. Minor modification to
- mh-display-msg to use mh-msg-folder to enable mh-index-search to
- reuse code.
- (mh-show-mode-map): Add key "F i" to call mh-index-search.
-
- * Makefile: Add mh-index.el
-
-2002-06-05 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-message-menu): Add an entry for mh-modify.
-
-2002-05-31 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-decode-quoted-printable): Only decode if the
- whole message is encoded. So restrict the search for the
- content-transfer-encoding header to the headers of the message
- itself.
-
- * mh-mime.el (mh-mime-display-alternative): Make sure that point
- is moved after mm-display-part is called.
-
-2002-05-29 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (mh-mime-display-single): Fix the logic that
- determines when an attachment is buttonized. For inline parts that
- can't be displayed a button is now created.
-
-2002-05-29 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-regenerate-headers): Fix an error in which the
- mh-mode-line-annotation was not being set properly.
-
- * mh-mime.el, mh-utils.el (compilation): Macros mh-require and
- mh-autoload are used to make sure that emacs20 doesn't croak when
- it tries to load non-existent mm-* files.
- (mh-decode-mime): Make it default to nil for Emacs major version
- below 21.
-
-2002-05-28 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-e.el (mh-regenerate-headers): Generalize the function to
- handle multiple ranges.
-
-2002-05-25 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * Makefile, mh-comp.el, mh-e.el, mh-funcs.el, mh-seq.el, mh-utils.el:
- Reduce use of eval-when-compile so that load-path is
- not changed if lisp files are loaded without compilation.
-
- * mh-e.el (mh-next-button, mh-folder-mode-map): New interactive
- function to advance point to next MIME button. It is bound to TAB.
-
- * mh-utils.el (mh-letter-next-button, mh-show-mode-map): New
- interactive function mh-letter-next-button has been added to
- advance point to the next MIME button. It is bound to TAB.
-
- * mh-mime.el (comments): Added some comments.
-
-2002-05-24 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-mime.el (compilation): Replace (eval-when-compile ...) by
- (eval-when (compile) ...) to remove a bug when mh-e is loaded
- without compilation.
-
-2002-05-23 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-comp.el (compilation): Some code was rearranged to avoid
- compiler warnings.
-
- * mh-e.el (compilation): Code rearrangement and extra autoloads to
- remove compiler warnings.
- (mh-quit): Add call to mh-destroy-postponed-handles to remove
- handles that are associated with external viewers. Also fixed a
- bug that I accidentally introduced by adding an extra line when
- cut and pasting my changes.
-
- * mh-funcs.el (compilation): Code rearrangement to remove compiler
- warnings.
-
- * mh-mime.el (compilation): Code rearrangement to remove compiler
- warnings.
- (mh-defun-compat): New macro to define to useful functions that
- aren't present in old Gnus.
- (mh-destroy-postponed-handles): New function to cleanup handles
- that are associated with external viewers.
- (mh-handle-set-external-undisplayer): New function to replace
- mm-handle-set-external-undisplayer. It associates handles for
- external viewers with the folder buffer. These are released when
- the user quits the folder.
- (mh-mime-display, mh-press-button, mh-push-button): Hook in
- mh-handle-set-external-undisplayer.
- (mh-maybe-insert-newline): New function to avoid inserting too
- many newlines between mime parts.
- (mh-mm-display-part): Workaround for Gnus bug which causes new
- lines to be inserted when images are shown inline.
- (mh-mime-display-security): Cut down on newlines inserted.
-
- * mh-pick.el (compilation): Code rearrangement to remove compiler
- warnings.
-
- * mh-seq.el (compilation): Code rearrangement to remove compiler
- warnings.
- (comments): Remove @SD from comments.
-
- * mh-utils.el (compilation): Slight code rearrangement.
- (mh-defun-show-buffer): Fix documentation so that the first line
- is not too long as was the case earlier. Use
- mh-previous-window-config to remember where the cursor should
- return functions like mh-reply.
- (mh-display-msg): Initialize handles data-structure for the folder
- buffer so that postponed handles can be added to it.
- (mh-add-msgs-to-seq): Always keep messages in the sequences
- sorted. This removes some unexpected behavior when working with
- sequences that go out of sync with the corresponding MH sequences.
- (mh-canonicalize-sequence): New function to sort and remove
- duplicates from mh-e sequence.
-
-2002-05-21 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (require): Load mm-decode.el here so that
- mm-inline-media-tests is properly initialized.
-
- * mh-comp.el (mh-yank-cur-msg): Don't try to remove the displayed
- mime parts when yanking the message. This also fixes the problem
- of regions not being respected during the yank.
-
-2002-05-20 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (compiler-warnings): Some code was rearranged to
- remove all compiler warnings.
- (mh-decode-mime): New defcustom to control whether
- mime attachments are shown using Gnus.
- (mh-globals-hash): New global variable which maps a given buffer
- to the corresponding mime data structures.
- (mh-recent-gnus-p): New global variable which checks if Gnus is
- recent enough so that PGP/GPG encrypted messages can be handled.
- (mh-mm-inline-media-tests): Tests to determine whether a mime part
- can be shown inline.
- (mh-gnus-article-highlight-citation): Shadow the Gnus function,
- gnus-article-add-button before gnus-article-highlight-citation is
- called. This prevents the insertion of useless buttons in the
- message.
- (mh-show-mode): Don't set font-lock-support-mode to nil. Modify
- kill-buffer-hook to call mh-mime-cleanup.
- (mh-modify): Only the edit buffer is shown.
- (mh-display-msg): Add call to mh-mime-display, mh-display-smileys,
- mh-display-emphasis when mh-decode-mime is non-nil.
-
- * mh-mime.el (mh-buffer-data): New structure to keep track of
- per-buffer mime information.
- (compiler-warnings): Some code was rearranged to get rid of all
- compiler warnings.
- (mh-graphical-smileys-p): New defcustom which controls whether
- graphical smileys are shown.
- (mh-graphical-emphasis-p): New defcustom for graphical emphasis.
- (mh-max-inline-image-width, mh-max-inline-image-height): New
- defcustoms for inlining image.
- (gnus-local-map-property, mm-merge-handles): Copy utility
- functions for use with version of Gnus that ships with Emacs21.1.
- (mh-mime-cleanup): New function to free mime data-structures.
- (mh-add-missing-mime-version-header): New function to add missing
- Mime-Version header if a Content-Type header exists.
- (mh-display-smileys): New function to show graphical smileys.
- (mh-display-emphasis): New function to show graphical emphasis.
- (new-globals): New variables mh-mime-button-* and
- mh-mime-security-* were added to control mime buttons.
- (mh-mime-display): New function to display mime messages. The
- functions mh-mime-display-part, mh-mime-display-alternative,
- mh-mime-display-mixed, mh-mime-part-index, mh-small-image-p,
- mh-mime-display-single, mh-insert-mime-button, mh-mm-display-part,
- mh-press-button, mh-push-button, mh-mime-save-part,
- mh-mime-inline-part, mh-widget-press-button, mh-mm-inline-message,
- mh-mime-display-security, mh-mime-security-show-details,
- mh-mime-security-press-button and mh-insert-mime-security-button
- were added to support mh-mime-display.
-
- * mh-e.el (mh-header-display): Bind mh-decode-mime to nil when
- mh-show-msg is called, so that mime isn't decoded when headers are
- displayed.
- (mh-quit): The show buffer is killed instead of invalidating and
- burying it.
-
- * mh-comp.el (mh-yank-cur-msg): Filter out the mime buttons from
- the yanked message.
- (mh-filter-out-non-text): New function to filter out attachments
- from message being yanked.
-
-2002-05-20 Bill Wohler <Bill.Wohler@openwave.com>
-
- * mh-utils.el (mh-invisible-headers-show-xface): First sentence of
- docstring was not entirely on first line so was truncated in
- customize and help buffers. Reworded so first sentence could fit
- within 80 columns per checkdoc recommendation.
- (mh-defun-show-buffer): Reworded per checkdoc recommendations.
- Removed @SD while I was in there.
-
-2002-05-18 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-seq.el (mh-narrow-to-seq): This function now removes the
- current message notation in the folder. Otherwise, two current
- message notations may be present after mh-widen is called. Also
- mh-copy-seq-to-eob is called instead of mh-copy-seq-to-point since
- the latter has a bug.
- (mh-copy-seq-to-point): This function has a tricky problem. It
- calls mh-map-to-seq-msgs which uses mh-goto-msg. mh-goto-msg
- assumes that the folder is sorted (since it uses binary
- search). The assumption isn't true, so it may not copy all the
- messages. Since this function is not used any more it has been
- removed.
- (mh-copy-seq-to-eob): This function is a specialized (and
- hopefully correct) replacement for mh-copy-seq-to-point.
-
-2002-05-17 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-utils.el (mh-gnus-article-highlight-citation): Workaround for
- problem caused by low value of recursive-load-depth-limit in
- Emacs21.1 and CVS version of Gnus.
- (mh-show-mode-map): New keymap variable to facilitate use of
- summary commands from the show buffer.
- (mh-show-folder-buffer): New local variable which keeps track of
- the folder-buffer corresponding to the message being shown.
- (mh-defun-show-buffer): New macro to convert interactive functions
- callable in the summary buffer to interactive functions callable
- in the show buffer.
- (mh-show-mode): Make buffer read-only and use mh-show-mode-map as
- keymap (closes SF #527946).
- (mh-modify): New interactive function to edit a message in-place.
-
- * mh-e.el (mh-goto-cur-msg): Add an optional argument,
- minimal-changes-p. If non-nil, the function will just change
- the point to current message and do not change folder display.
- (mh-folder-mode-map): Make "M" call mh-modify.
-
-2002-05-07 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-invisible-headers-show-xface): New defcustom
- variable. If non-nil, the X-Face header line will be excluded from
- the variable `mh-invisible-headers'. Set this when using a
- package such as x-face-el to display X-Face icons in mh-show-mode.
- This variable's setting will eventually be set automatically when
- mh-e does its own X-Face decoding (or this variable will be replaced
- by one telling mh-e to decode the X-Face). We may not ship the
- next release with this variable.
-
-2002-05-07 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-x-face-file): New defcustom variable. File name
- containing the encoded X-Face string to insert in outgoing mail.
- (mh-insert-x-face): New function. Appends an X-Face field to the
- header, but only if it doesn't already exist and if 'mh-x-face-file'
- is non-nil and points to an existing file.
- (mh-send-letter): Invoke mh-insert-x-face.
-
-2002-04-29 Mike Kupfer <m.kupfer@acm.org>
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo): Check
- whether XEmacs region is actually active (needed at least for 21.1).
- [Patch committed by psg]
-
-2002-04-29 Mike Kupfer <m.kupfer@acm.org>
-
- * mh-utils.el (mh-prompt-for-folder): Remove "default" argument
- from completing-read as XEmacs-21.1 doesn't have it (21.4 does
- however) and using the argument adds no functionality.
- [Patch committed by psg]
-
-2002-04-11 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo): Add support for
- XEmacs to act on selected region when active.
-
-2002-04-10 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo): XEmacs fix; Add
- check to see if mark-active is bound, because Mandrake Linux include
- XEmacs initialization code that binds transient-mark-mode. This
- fix gets around a problem in Mandrake only. It wasn't a problem
- on XEmacs generally. Fixes SF #541915.
-
-2002-04-08 Bill Wohler <wohler@newt.com>
-
- Released mh-e version 6.1.
-
- * mh-e.el (mh-folder-unseen-seq-name): Use "mhparam -component
- Unseen-Sequence" command and "Unseen-Sequence: \\(.*\\)$" regexp
- to increase robustness.
- (mh-folder-unseen-seq-list): Use `expand-file-name' as
- `mh-expand-file-name' isn't needed and the former saves function
- call.
- (Version, mh-version): Updated for release 6.1.
-
-2002-04-08 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-unseen-seq-list): Specify mh-progs path in
- call to mark command. Fixes a bug in which unseen messages
- weren't highlighted if "mark" wasn't in the path.
-
-2002-04-07 Bill Wohler <wohler@newt.com>
-
- * MH-E-NEWS: Updated for release 6.1.
-
- * README: Updated for release 6.1. Updated verbiage about reading
- MH-E-NEWS.
-
- * mh-comp.el, mh-e.el, mh-funcs.el, mh-mime.el, mh-seq.el,
- mh-utils.el, mh-xemacs-compat.el: Updated copyright in files
- modified this year.
-
- * mh-xemacs-compat.el: Put Author field back in, but set to FSF.
-
- * mh-comp.el, mh-funcs.el, mh-mime.el, mh-seq.el,
- mh-utils.el: Fixed all checkdoc errors, except for no
- documentation, and documentation in comments. Also removed the-
- prefix from certain local variables.
-
- * mh-e.el: Fixed all checkdoc errors, except for no documentation,
- and documentation in comments. Also removed the- prefix from
- certain local variables.
- (mh-folder-unseen-seq-name): Refactored to make default sequence
- name more explicit and to handle undefined Unseen-Sequence MH
- profile entry better.
-
-2002-04-02 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el: 'defvar mh-folder-unseen-seq-name' called a function to
- set its value, and this happens also on byte-compilation (where
- it can fail if the user's MH environment is not setup correctly).
- I now set the value of mh-folder-unseen-seq-name at runtime when I
- first need it. This should fix Debian bugs
- https://bugs.debian.org/140232 and https://bugs.debian.org/140817
-
-2002-03-25 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el: remove "(require 'mh-e)" since mh-utils.el should
- be at the bottom of the dependency tree.
- * mh-e.el (mh-folder-unseen-seq-name): Make sure mh-progs is set
- and use it as path to mhparam command in call-process.
-
-2002-01-23 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-font-lock-keywords): Add call to
- mh-folder-font-lock-unseen to fontify unseen messages in bold.
- (mh-folder-unseen-seq-name): Provide name of unseen sequence from
- mhparam. Used as default for variable of same name.
- (mh-folder-unseen-seq-list): Returns a list of unseen messages
- numbers for current folder.
- (mh-folder-unseen-seq-cache): Cache variable to hold list of
- unseen message numbers while font-lock iterates. This variable is
- buffer-local.
- (mh-folder-font-lock-unseen): Returns unseen message lines to
- font-lock one by one.
-
-2002-01-15 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-prefix-string): Wrap a
- "(let ((zmacs-regions nil))" around (mark) so it works in XEmacs.
- Bug reported and fix suggested by Will Partain <partain@dcs.gla.ac.uk>
- Indeed, this is how it appears in XEmacs-21's mh-comp.el.
-
-2001-12-16 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-forward): Move the assignment to `fwd-msg-file'
- to before the assignment to `draft' as the later changes buffers
- and invalidates `mh-seq-list' (which is used in a function called
- by (mh-seq-to-msgs)). Resolves SF #489448.
-
- * mh-utils.el: Add defcustoms for `mh-temp-folders-buffer' and
- `mh-temp-sequences-buffer'.
-
- * mh-e.el (mh-quit): If they exist, kill 'mh-temp-buffer,
- 'mh-temp-folders-buffer and 'mh-temp-sequences-buffer when
- quitting.
-
- * mh-funcs.el (mh-list-folders): Use `mh-temp-folders-buffer'
- (a defcustom initialized to "*Folders*") for folder listing. Put
- into view mode and set it up to kill the buffer when exiting view
- mode.
-
- * mh-seq.el (mh-list-sequences): Use `mh-temp-sequences-buffer'
- (a defcustom initialized to "*Sequences") for sequences listing.
- Put into view mode and set it up to kill the buffer when exiting
- view mode.
-
-2001-12-16 Bill Wohler <wohler@newt.com>
-
- Released mh-e version 6.0.
-
- * MH-E-NEWS: Be a little more specific about incompatible changes.
- Added info about outdated manual.
- Removed variables in mh-scan regexp table that did not exist in
- 5.0.2.
- Added helpful documentation about finding relevant variables
- containing regexps to mh-scan-format-file's description.
-
- * mh-e.el (mh-scan-format-file): Added information about getting a
- list of regexp variables that you'll need to change if you
- customize your scan's output.
- (mh-folder-mode): Added documentation about `mh-scan-format-file'
- for those users who modify their scan formats.
-
- * README: New file. Describes packages and provides simple
- installation instructions.
-
- * Makefile (clean, dist, install-emacs): Replaced $(RM) with rm
- -rf (closes SF #488661).
-
-2001-12-14 Bill Wohler <wohler@newt.com>
-
- Released mh-e version 5.0.93.
-
- * Makefile (MH-E-SRC): Added mh-xemacs-compat.el.
- (MH-E-IMG): Added .pbm images for all. Removed mail_ prefix from
- all.
- (MH-E-IMG2): New variable to hold images in mail sub-directory.
- (dist): Updated target to make mail sub-directory and copy
- MH-E-IMG2 images there.
-
- * mh-xemacs-compat.el: Modified docs per GNU coding conventions.
-
- * mh-e.el: Reorganized variables having to do with the scan line.
- Moved some random variables that were interspersed out of the
- middle. Moved `mh-scan-format-file' first and let the variables
- flow from there.
-
- As the number of variables increases, it is becoming important to
- organize the mh-e namespace. Several variables having to do with
- the format of scan lines were renamed, as follows:
- (mh-good-msg-regexp): Renamed to mh-scan-good-msg-regexp.
- (mh-deleted-msg-regexp): Renamed to mh-scan-deleted-msg-regexp.
- (mh-refiled-msg-regexp): Renamed to mh-scan-refiled-msg-regexp.
- (mh-valid-scan-line): Renamed to mh-scan-valid-regexp.
- (mh-cur-msg-number-regexp): Renamed to mh-scan-cur-msg-number-regexp.
- (mh-cur-msg-line-regexp): Renamed to mh-scan-cur-msg-regexp.
- (mh-scan-rcpt-addr-regexp): Renamed to mh-scan-rcpt-regexp.
- (mh-scan.font-lock-regexp): Renamed to mh-scan-format-regexp.
- (mh-folder-scan-font-lock-face): Renamed to
- mh-folder-scan-format-face.
- (mh-folder-cur-msg-line-face): Renamed to mh-folder-cur-msg-face).
-
-2001-12-13 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-msg-number-regexp): Renamed to
- mh-scan-msg-number-regexp.
- (mh-msg-search-regexp): Renamed to mh-scan-msg-search-regexp.
-
- * Corrected typos, quoted variables in doc strings, and made minor
- wording changes in docs.
-
-2001-12-13 Peter S Galbraith <psg@debian.org>
-
- * mh-xemacs-compat.el: defalias 'match-string-no-properties to
- 'match-string for XEmacs. I've seen a better function for this
- that actually removes text properties, but this will do for now.
-
- * mh-utils.el (mh-decode-quoted-printable): deactivate-mark not
- bound in XEmacs.
-
- * mh-xemacs-compat.el: GNU Emacs Functions needed by XEmacs.
- New file.
- * mh-e.el: (require 'mh-xemacs-compat) when running XEmacs.
-
-2001-12-12 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-send-letter): function local-variable-p needs two
- arguments in XEmacs.
- (mh-send-letter): sendmail-coding-system not bound in XEmacs.
- (mh-send-letter): default-buffer-file-coding-system not bound in
- XEmacs.
-
- * mh-e.el (mh-delete-msg, mh-refile-msg, mh-undo):
- transient-mark-mode not bound in XEmacs. The feature of
- operations made on all messages in the selected range when
- transient-mark-mode is on doesn't work in XEmacs.
-
- * mh-e.el, mh-utils.el: Conditionalize calls to
- 'add-to-list 'facemenu-unlisted-faces for XEmacs.
-
-2001-12-11 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-scan-format): Add `mh-scan-format-file' variable to
- specify the scan format string or file to use. Define formats for
- MH and nmh that are compatible with the standard format, but
- provide hints for font-lock. Define (mh-scan-format) for use by
- (mh-regenerate-headers) and (mh-get-new-mail) to specify the args
- necessary to inform the scan program which scan format string or
- file to use.
-
-2001-12-07 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (scan.font-lock): New format file documented in comments.
- (mh-scan.font-lock-regexp): Adapted to new format.
- (mh-folder-font-lock-keywords): Use new format.
-
- * mh-e.el (page-down.xpm): Icon renamed from nextpage.
-
- * mh-utils.el (mh-decode-quoted-printable): Bug fix. Better check
- on what actually is a quoted-printable attachment.
-
-2001-12-06 Eric Ding <ericding@alum.mit.edu>
-
- * mh-mime.el (mh-mhn-compose-insertion, mh-mhn-compose-anon-ftp):
- require mailcap.el here rather than using autoload at top of
- mh-mime.
- (mh-file-mime-type): get rid of unused variables (why were they
- there to begin with?)
-
-2001-12-06 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-cur-msg-number-regexp, mh-cur-msg-line-regexp):
- mh-cur-scan-msg-regexp splits into these two variables.
- The whole-line fontification is disabled, but easily restored by a
- user (although it could be a defcustom with choices DISABLED or
- the correct regexp?)
- (mh-folder-cur-msg-line-face): mh-folder-current-msg-face renamed
- to this.
- (mh-folder-cur-msg-number-face): mh-folder-current-face renamed to
- this.
-
- * cabinet.xpm: Revert to rescan icon name.
- * mh-e.el (mh-folder-tool-bar-map): s/cabinet/rescan/
-
- * mh-e.el (mh-folder-font-lock-keywords): Reorder and tweak such
- that current message line highlight doesn't mess up other highlights.
-
-2001-12-05 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el (mh-show-from-face): Change mh-show-from-face to
- cyan on dark backgrounds; through a series of changes, it had
- become the same color as mh-show-subject-face!
-
-2001-12-05 Bill Wohler <Bill.Wohler@openwave.com>
-
- * mh-e.el, mh-utils.el: Fixed typos in face definitions, and made
- a couple of small doc string tweaks while I was in there. Peter,
- if you don't agree, let me know and I'll back them out. I thought
- the "mh-e" in the text was redundant since the variables start
- with "mh"; I was also thinking ahead to how the documentation may
- read.
-
-2001-12-05 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-cur-scan-msg-regexp): Match 0 is the whole line.
- (mh-folder-current-msg-face): New face with only a background
- settings, used in font-lock for the current message.
- (mh-folder-font-lock-keywords): Use mh-folder-current-msg-face for
- mh-cur-scan-msg-regexp.
-
- * mh-utils.el (mh-show-from-face): Use red3 instead of red for
- light backgrounds. It's not as bright on the eyes.
- (mh-show-subject-face): copy from mh-folder-subject-face instead.
- Makes the look consistent with folder-mode.
-
- * mh-e.el (mh-folder-subject-face): Moved to mh-utils since we
- need it to copy to mh-show-subject-face.
-
-2001-12-05 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folder-mode-map): Moved `mh-extract-rejected-mail'
- from "a" to "E". Better mnemonic, nicer to folks used to using a
- for `mh-reply'.
-
-2001-12-04 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folder-map): Added "S" for `mh-sort-folder'.
-
-2001-12-04 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-subject-face et al.): Yet another attempt at
- colors for folder-mode. Still themed, but fewer and darker
- colors (Blame Eric this time!). I'll get to underlining tomorrow
- night.
-
- * mh-e.el (mh-folder-tool-bar-map): Renamed all icons so they
- don't have the word mail in them. Also generated a pbm format of
- each icon for users without XPM support conpiled into Emacs.
-
-2001-12-04 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el (mh-show-font-lock-keywords): Use
- mh-header-subject-font-lock instead of regexp for subject headers,
- which may go multiple lines.
- (mh-header-subject-font-lock): New function.
- Fix typos ("highlight").
-
-2001-12-04 Eric Ding <ericding@alum.mit.edu>
-
- * mh-e.el: changes to face colors on dark backgrounds.
- (mh-folder-followup-face): change to LightGoldenRod.
- (mh-folder-date-face): change to snow3.
- (mh-folder-msg-number-face): change to snow4.
-
-2001-12-04 Bill Wohler <wohler@newt.com>
-
- Released mh-e version 5.0.92.
-
- * mh-utils.el (gnus-cite-face-list)
- (mh-gnus-article-highlight-citation): Don't autoload. Revert to
- requiring in `mh-gnus-article-highlight-citation' as before. With
- the autoloads, if you ran mh-e before gnus, you'd get an undefined
- gnus variable when viewing an article in gnus. Go figure.
-
-2001-12-03 Bill Wohler <wohler@newt.com>
-
- Released mh-e version 5.0.91.
-
- * MH-E-NEWS: Removed info about bumping up `max-specpdl-size' now
- that workaround has been implemented.
-
- * Makefile (MH-E-OBJ): New variable to hold .elc files.
- (all): Just compile.
- (clean): New target that blows away MH-E-OBJ.
- (dist): Added $(MH-E-OBJ) to tarball.
-
- Attempt to quiet compilation errors to a dull roar.
-
- * mh-e.el: Require easymenu, added autoload of info.
- (mh-smail, mh-smail-other-window): Comment says these were needed
- by Emacs 18. Out!
-
- * mh-utils.el: Don't require sendmail, but require mh-e.
- Moved autoloads to top of file, and autoload gnus-cite and
- sendmail too.
-
- * mh-pick.el: Require easymenu. Remove cond on
- `easy-menu-define'--it exists.
-
- * mh-mime.el: Autoload mailcap.
-
- * mh-comp.el: Require mh-e and easymenu, moved autoloads to top of
- file.
-
- * Makefile (EMACS): New constant to hold emacs calling sequence.
- (install): Renamed to install-emacs.
- (compile): New target to compile all files.
- (dist): Make dependent on compile.
- (import): Renamed to import-emacs.
- (%.elc): New implicit rule to compile elisp files.
-
- * mh-e.el (mh-thread-map): Added "Td" for
- mh-delete-subject-thread.
-
-2001-12-03 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-tool-bar-map): Change tooltip for exec icon.
-
- * mh-e.el (mh-folder-subject-face): Change to IndianRed1.
- (mh-folder-followup-face): Change to IndianRed.
- (mh-folder-deleted-face): Use sedate face instead of bright one.
-
-2001-12-03 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-invisible-headers): Increase size of
- `max-specpdl-size' locally to work around insufficient default.
- (mh-invisible-headers): Added X-Info and X-VSMLoop (NTMail).
-
-2001-12-03 Jeffrey C Honig <jch@honig.net>
-
- * mh-utils.el (mh-find-progs): Searches should not stop if the
- strings are not found, there is error detection at the end of the
- routine (closes SF #488231).
-
-2001-12-02 Bill Wohler <wohler@newt.com>
-
- * MH-E-NEWS: Added info about bumping up `max-specpdl-size'.
-
- * Makefile (MH-E-IMG): New variable that contains images used by
- mh-e. Add these files to release.
-
- * MH-E-NEWS: Second draft of mh-e 6.0 (was 5.1) release notes.
-
- * mh-e.el (mh-folder-updated-hook): Reworded to avoid ambiguity.
- Is the hook called when you type `d' or when you type `x'?
- (mh-unseen-updated-hook): Reworded to be consistent with
- `mh-folder-updated-hook.'
-
- * mh-utils.el (mh-recenter): Accepted Gerd's change which is
- evaluated at compile time.
-
-2001-12-02 Bill Wohler <wohler@newt.com>
-
- * mh-e.el Major, major keymap changes. The specific changes are
- listed below, but view the sources, or use "C-h m" in MH Folder
- mode for the complete list.
-
- Use of sub-keymaps inspired by gnus. The changes tripped me up at
- first too, but after about 5 minutes of shock (which is to be
- expected, I've been using the old keybindings for 16 years), I
- honestly found the new bindings to be nice indeed. It will also
- provide flexibility to allow for future functionality. I hate to
- do this on the eve of the beta release, but you asked for it! It's
- likely I'll have to pull an Eric and back this change out, but if
- we can live with pink subjects, this can't be so bad ;-).
- Question: will the users revolt? If they do, I suppose we can
- release 6.0.1 the next day ;-).
- (mh-folder-map, mh-sequence-map, mh-extract-map, mh-digest-map):
- New keymaps which start with F, S, X, and D, respectively. The
- mhstore commands can go in the mh-extract-map eventually.
- (mh-thread-map): Renamed from mh-folder-thread-map.
-
- Keymap changes and rationale. The sub-keymaps allowed some
- consistency (e.g., esp. with l(ist) and k(ill).
-
- e Deleted. Already have x. Now used by mh-edit-again.
- a Deleted. Already have r. Now used by mh-extract-rej..
- j Deleted. Already have g.
-
- M-a -> e Better mnemonic. Matches rmail. Frees movement cmd.
- M-e -> a Try `a'gain!
-
- M-f -> Fv Frees movement command
- M-f -> Ff Alias (keep?)
- M-f -> Fo Alias (keep?)
- M-k -> Fk No reason but to keep with folder commands
- M-l -> Fl No reason but to keep with folder commands
- M-p -> Fp No reason but to keep with folder commands
- M-r -> Fr Frees movement command
- M-s -> Fs No reason but to keep with folder commands
- M-u -> Fu No reason but to keep with folder commands
-
- M-% -> Sd Better mnemonic
- M-# -> Sk Better mnemonic
- M-q -> Sl Better mnemonic
- C-xn -> Sn Frees up standard key binding
- % -> Sp Better mnemonic for putting a message in a sequence
- ? -> Ss Shows sequences that message is in
- C-xw -> Sw Frees up standard key binding
-
- M-n -> Xs Better mnemonic (shar)
- M-n -> Xu Better mnemonic (uuencode)
-
- M-SPC -> DSPC Frees mark command
- M-\177 -> D\177 No reason but to keep with digest commands
- M-b -> Db Frees movement command
-
-2001-12-01 Bill Wohler <wohler@newt.com>
-
- * mh-e.el: Use gnus style of keymaps. Now requires gnus-util.
- (mh-folder-thread-map): New map, created by gnus-define-keys.
- Reached when typing T in mh-folder-mode-map. Moved threading
- functions to this new keymap so we can use dired again.
- (mh-folder-mode-map): Defined by gnus-define-keys. Otherwise than
- the new threading functions, no changes to the UI were made at
- this point--saving that for the next check-in.
-
- * mh-pick.el (mh-pick-mode-map): Use gnus-define-keys. Now
- requires gnus-util.
-
- * mh-comp.el (mh-letter-mode-map): Use gnus-define-keys. Now
- requires gnus-util.
-
-2001-12-01 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el: Update the documentation for the regexps used by
- `mh-folder-font-lock-keywords' to specify how many parenthesized
- expressions they are expected to have and what those expressions
- are expected to match.
-
-2001-12-01 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folder-mode): Removed iteration of key bindings,
- \\{mh-folder-mode-map} suffices. Removed variable documentation
- also as this is already out of date and a maintenance hassle.
- Reference new mh customization group instead.
-
- * mh-comp.el (mh-letter-mode): Ditto. Also added new information
- about MIME directives getting processed automatically if inserted
- via mh-e commands.
-
- * mh-pick.el (mh-pick-mode): Edited documentation so it reads like
- the other modes.
-
- * mh-e.el (mh-compat-quit): Deleted obsolete and unused function.
- Comment in this function said that `b' shouldn't be used for
- burst-digest, as it is used for `back' in info, less, and rn. But
- what does `back' mean in MH Folder? I suppose if you visit a
- folder, you would go `back' to the original folder. Hmmm, I guess
- we'll leave the `b' binding alone for now.
-
- * mh-utils.el: Moved some of the variable comments to the first
- column so they wouldn't wrap in such an ugly fashion.
- (mh-showing-mode): Renamed variable and function from mh-showing
- to conform with minor mode conventions. Added optional arg to
- function so it would behave like a normal minor mode: no or nil
- arg toggles mode, 0 arg turns off, non-nil turns on. It also turns
- out that desktop-create-buffer would barf when recreating mh-e
- buffers because it was calling mh-show with an arg.
- (mh-show-mode): Use define-derived-mode to simplify definition a
- *lot*.
- (mh-set-mode-name): Deprecated by use of define-derived-mode.
- Removed.
-
- * mh-pick.el (mh-pick-mode): Use define-derived-mode to simplify
- definition a *lot*.
-
- * mh-e.el (mh-scan-prog): Removed message about "Buffer local" as
- this message will appear in a future version of Emacs.
- (mh-inc-folder): mh-showing renamed to mh-show-mode and made a
- real minor mode.
- (mh-folder-mode): Use define-derived-mode to simplify definition a
- *lot*.
-
- * import-emacs (release): Change `(none)' to `mainline' so import
- doesn't choke after running `cvs up -A' on Emacs.
- (COPYING): Moved from $EMACS_HOME/etc to $EMACS_HOME.
- (cvs update): Whoops! Forgot the second join (-jemacs).
- make import works fine again.
-
-2001-11-30 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-font-lock-keywords): Change order of
- font-lock patterns such that subject body text doesn't get date
- fontification.
-
- * mh-e.el (mh-scan-subject-regexp): Bug fix. Remove a dot.
- scan.font-lock users have to setq it separately.
-
-2001-11-30 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el (mh-clean-msg-header): Go back to using
- mh-delete-line. Using invisible text property is nicer in some
- ways, but winds up with somewhat mysterious behavior should user
- kill/yank stuff from the header (i.e., text gets yanked invisibly
- and won't be seen by user until file is reloaded).
-
-2001-11-29 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-page-msg): Use mh-next-direction to page in the
- right direction.
-
-2001-11-29 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-scan-folder): Fix logic to not attempt to go to
- the current message if there are no messages in the folder.
-
-2001-11-29 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-font-lock-subject): New fontifier function
- for subject lines in folder-mode.
- (mh-scan-followup-regexp): Deleted obsolete regexp. Use
- mh-scan-subject-regexp instead.
- (mh-folder-font-lock-keywords): Use mh-folder-font-lock-subject
- instead of obsolete mh-scan-followup-regexp variable.
- (mh-folder-date-face, mh-folder-msg-number-face):
- (mh-folder-subject-face, mh-folder-followup-face):
- Now defined as proper faces instead of copied from font-lock
- faces.
-
- * mh-mime.el (mh-media-type-regexp): New variable. Regexp matching
- valid media types used in MIME attachment compositions.
- (mh-file-mime-type): Use mh-media-type-regexp instead of
- hard-wiring its value.
-
- * mh-utils.el (mh-show-unquote-From): New function to unquote
- "^>From" in mh-show-mode (not saved to disk).
- (mh-show-mode): Call mh-show-unquote-From.
-
-2001-11-29 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el (mh-clean-msg-header): Use mh-make-line-invisible
- rather than mh-delete-line.
- (mh-make-line-invisible): New function to make line(s) invisible
- rather than deleting line(s). Optional argument specifies number
- of lines to delete.
- (mh-show-msg): screen-height has been deprecated; use no more.
- (mh-notate): screen-width has been deprecated; use no more.
-
-2001-11-29 Jeffrey C Honig <jch@honig.net>
-
- * mh-utils.el (mh-find-progs): Change mh-find-progs to rely on
- the existence of mhparam. The location of mhparam is used to find
- `mh-progs'. It uses the libdir and etcdir to find the
- `mh-lib-progs' and `mh-lib' directories. If etcdir doesn't return
- anything we assume `mh-lib-progs' is the same as `mh-lib' and that
- we are using MH instead of nmh.
-
-2001-11-29 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-scan.font-lock-regexp): Change docs to reflect that
- second paren expression is the user match.
- (mh-folder-font-lock-keywords): Change from 1st to 2nd parenthesized
- expression to match user name, after Jeffrey's change to the regexps.
-
-2001-11-29 Bill Wohler <Bill.Wohler@openwave.com>
-
- * mh-utils.el (mh-clean-message-header): Default is now t.
- (mh-invisible-headers): Padded out to contain all the headers that
- the mh-e developers don't like to see (closes SF #415759).
-
-2001-11-28 Bill Wohler <Bill.Wohler@openwave.com>
-
- * mh-comp.el (mh-rejected-letter-start): Added MIME MDN. While
- this allows mh-extract-rejected-mail to strip the start of the
- MDN, there is still a closing MIME marker at the end. This should
- be cleaned up eventually.
-
-2001-11-28 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-seq-tool-bar-map): New tool-bar used for
- folder-mode when narrowed to sequence.
- * mh-seq.el (mh-narrow-to-seq): Set tool-bar to
- mh-folder-seq-tool-bar-map.
- (mh-widen): Set tool-bar to mh-folder-tool-bar-map.
- * widen.xpm: New icon used in mh-folder-seq-tool-bar-map.
-
- * mh-mime.el (mh-file-mime-type): Much better check on validity of
- 'file' output.
-
- * mh-e.el (mh-scan-subject-regexp): New regexp variable for
- subject string in folder mode. Used to extract subject sequence,
- and will be used for font-lock soon.
- * mh-seq.el (mh-subject-thread-to-sequence): More robust code by
- using mh-scan-subject-regexp, allows users with non-standard
- scan format to use subject sequences.
-
- * mh-comp.el (mh-letter-fill-column): Fill column to use in
- mh-letter-mode. (Yes, I'm doing this in spite of what Bill said;
- Someone can always undo it later)
- (mh-letter-mode): setq fill-column to mh-letter-fill-column.
-
-2001-11-28 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-page-msg): The first time the end of page is hit,
- set mh-page-to-next-msg-p to t. The second time the end of page is
- hit, go to the next message.
-
- * mh-utils.el (mh-show-msg): Initialize mh-page-to-next-msg-p to
- nil.
-
-2001-11-27 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-mime-content-types): Updated list of types to
- contain types used by mh-e developers, but not including types not
- listed in
- http://www.isi.edu/in-notes/iana/assignments/media-types/media-types.
-
-2001-11-27 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-subject-thread-to-sequence) New function placing
- all messages with similar subject line into a sequence named
- 'subject.
- (mh-narrow-to-subject-thread): New command to narrow to all
- messages with similar subject line into a sequence named 'subject.
- (mh-toggle-subject-thread): New command to toggle between a new
- 'subject sequence or the wide view of a folder.
- (mh-delete-subject-thread): New command to delete all following
- messages with similar subject lines (leaving preceding ones
- untouched).
- (mh-next-unseen-subject-thread): New command to create and move to
- a new subject thread created from the next unseen message as a
- starting point.
- * mh-e.el (mh-folder-message-menu): New menu entries for subject
- threads.
- (mh-folder-mode-map): New keybindings for subject threads.
- (mh-lessp): New function to sort messages.
-
- * mh-utils.el (mh-show-font-lock-keywords): and various
- faces... scoped within eval-after-load "font-lock" to avoid
- requiring font-lock to use its faces.
- * mh-e.el (mh-folder-font-lock-keywords): Same.
-
-2001-11-27 Jeffrey C Honig <jch@honig.net>
-
- * mh-mime.el (mh-file-mime-type): Use mh-temp-buffer instead of
- " *mh-temp".
-
- * mh-comp.el (mh-insert-x-mailer): Kill mh-temp-buffer after use.
-
-2001-11-26 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el: revert to using external mimedecode to decode
- MIME quoted-printable parts
-
-2001-11-26 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-process-commands): Added mh-folder-updated-hook.
- * mh-e.el (mh-update-unseen): Added mh-unseen-updated-hook.
-
-2001-11-26 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-file-mime-type): Make sure output from file
- command is known to mailcap file, otherwise prompt the user.
- (mh-mime-content-types): Add "image/png" type.
-
- * mh-e.el (mh-folder-font-lock-keywords): Use a bunch of new
- mh-folder-*-face faces.
- * mh-utils.el (mh-show-font-lock-keywords): Use a bunch of new
- mh-show-*-face faces.
-
- * mh-utils.el (mh-letter-header-font-lock): Bug fix. Fix infinite
- loop in emacs20 font-locking.
- (mh-header-field-font-lock): Preventive fix with similar change.
-
- * mh-comp.el (mh-reply-show-message-p): Fix typo for "displayed".
- * MH-E-NEWS: Same.
-
- * mh-e.el (mh-folder-tool-bar-map): Bug fix. I had
- mh-repack-folder instead of mh-pack-folder.
-
-2001-11-26 Bill Wohler <wohler@phone.com>
-
- * mh-e.el:
- Updated header for consistency and to conform with (elisp)Library
- Headers.
- (mh-do-not-confirm): Updated documentation string to reflect
- reality (e.g., is no longer used by mh-kill-folder and is used by
- more functions than just mh-undo-folder).
- (mh-page-msg): Now shows the next undeleted message if looking at the
- bottom of the current message.
- (mh-process-or-undo-commands): Fixed indentation.
-
- * mh-mime.el:
- (mh-mhn-compose-insertion, mh-mhn-compose-anon-ftp): If MIME type
- cannot be determined with file command, use mailcap-mime-types (if
- available) to provide list for completing read.
-
- * MH-E-NEWS: First draft of mh-e 5.1 release notes.
-
-2001-11-26 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el (mh-decode-quoted-printable): Implement
- quoted-printable decoding in elisp (starting with code copied
- from FLIM).
- (mh-decode-quoted-printable-region): Move (require 'hexl) outside
- while loop.
- (mh-decode-quoted-printable): give user a choice between using
- internal code or external program to decode quoted-printable
- content. Resurrect code that calls external mimedecode program.
-
-2001-11-25 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-highlight-citation-p): New variable to determine
- whether to highlight citations in message body with gnus,
- font-lock or not at all.
- (mh-show-font-lock-keywords): removed citations from keywords.
- (mh-show-font-lock-keywords-with-cite): New variable, equivalent
- to prior mh-show-font-lock-keywords.
- (mh-gnus-article-highlight-citation): hook into gnus for
- multi-level citation highlighting.
- (mh-show-mode): Use either mh-show-font-lock-keywords or
- mh-show-font-lock-keywords-with-cite, depending on value of
- mh-highlight-citation-p, and possibly call
- mh-gnus-article-highlight-citation.
- * mh-comp.el (mh-letter-mode): Same as for mh-show-mode above.
-
-2001-11-25 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el (mh-redistribute): Added mh-redist-background
- variable to cause mh-redistribute to run the redist command in the
- background. This causes the transaction log to be visible, like
- with send.
-
-2001-11-25 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-inc-folder): 'inc' finishes by displaying the first
- new message if already showing messages.
-
-2001-11-22 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-prompt-for-folder): Exit with error if no folder
- specified, otherwise mh-refile-msg may try to create a folder with
- empty name, and this creates problems; even mh-undo can't handle
- it (Closes SF #476824).
-
- * mh-comp.el (mh-letter-tool-bar-map): Info button needed to
- require 'info. Also tweaked help texts.
- (mh-letter-menu): Use headline capitalization (Closes SF #483203).
- * mh-e.el (mh-folder-tool-bar-map): Same as above.
- (mh-folder-folder-menu, mh-folder-message-menu):
- (mh-folder-sequence-menu): Same as above.
- * mh-pick.el (mh-pick-menu): Same as above.
-
-2001-11-21 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-reply-show-message-p): The setting of this
- variable determines whether the MH show-buffer is displayed with
- the current message when using mh-reply without a prefix argument.
- Set it to nil if you already include the message automatically in
- your draft using "repl: -filter repl.filter" in your ~/.mh_profile
- file.
- (mh-reply): Don't show message in other window if
- mh-reply-show-message-p is nil.
-
- * mh-e.el (mh-folder-tool-bar-map): Add mail_exec.xpm icon for
- mh-execute-commands.
-
- * mh-utils.el (mh-show-mouse): New function to click on a message
- in folder-mode and show that message.
- * mh-e.el (mh-folder-mode-map): Bind mh-show-mouse to mouse-2.
-
- * mh-e.el (mh-page-msg): Show buffer first if not displayed,
- instead of simply complaining there's no other window.
-
- * mh-e.el (mh-folder-tool-bar-map): New tool-bar for folder mode!
- (mh-folder-mode): Setup tool-bar.
-
- * mh-mime.el (mh-have-file-command): try to non-fatally load
- executable.el because emacs20 doesn't autoload it.
- * mh-utils.el (load "executable" t t): Idem.
-
- * mh-utils.el (mh-clean-msg-header): Bug fix. locally bind
- after-change-functions to nil, working around a strange font-lock
- bug in emacs20 when (add-hook 'mh-show-mode-hook 'turn-on-font-lock)
- was used.
-
- * mh-comp.el (require 'sendmail): Moved from mh-comp.el to
- mh-utils.el because it is needed in reading mail too.
- (mh-header-field-end, mh-in-header-p): Moved to mh-utils.el
- because they are needed by mh-show-mode's font-lock code.
- Unfortunately, this splits the field related code into two files.
- Perhaps it should all go into mh-utils?
-
-2001-11-20 Eric Ding <ericding@alum.mit.edu>
-
- * mh-utils.el (mh-show-from-face): Fix typo in defface
-
-2001-11-20 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-mail-header-separator): Set to -------- as
- defined by MH (components, and replcomps files). This variable
- cannot be a regexp since it is used as an argument to insert and
- is passed through regexp-quote before being used. The previous
- value broke a lot of code, including mailcrypt.
-
- * mh-comp.el (mh-letter-mode, mh-send-letter): Insert X-Mailer
- header field from mh-send-letter.
- (mh-edit-again, mh-extract-rejected-mail): Call
- mh-insert-header-separator to ensure that there is a separator.
- Packages such as mailcrypt depend on it.
- (mh-insert-header-separator): New function to insert
- mh-mail-header-separator if it doesn't exist.
-
-2001-11-20 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-mode): Make font-lock-defaults a local variable
- * mh-e.el (mh-folder-mode): Same.
- * mh-utils.el (mh-show-mode): Same.
-
- * mh-e.el (mh-scan-msg-num-regexp): Delete variable and replace
- with mh-good-msg-regexp.
-
- * mh-utils.el (mh-mail-header-separator): Bug fix. Moved from
- mh-comp.el to mh-utils.el (which mh-comp.el loads).
-
- * mh-comp.el (mh-in-header-p): Recycle sendmail.el code (as
- suggested by Bill).
- * mh-utils.el (mh-letter-header-font-lock): Use mh-in-header-p.
-
- * mh-comp.el (mh-letter-tool-bar-map): tool-bar customize button goes
- to customizing mh-compose group.
-
- * mh-utils.el (mh-show-mode): font-lock bug fix. Locally set
- font-lock-support-mode to nil.
- (mh-letter-header-font-lock, mh-header-field-font-lock): font-lock
- bug fix. Don't return match beyond font-lock search limit.
-
- * mh-comp.el (mh-letter-mode): Emacs20 bug fix. tool-bar-mode is
- not a bound variable.
-
-2001-11-19 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-tool-bar-map): tool-bar help button goes
- to 'Draft Editing' info node.
-
- * mh-utils.el (mh-show-from-face, mh-show-to-face): New faces used
- for font-lock.
- (mh-header-to-font-lock, mh-header-cc-font-lock)
- (mh-header-field-font-lock): New helper function returning whole
- header field arguments to font-lock.
- (mh-show-font-lock-keywords): Heavily modified using the above.
-
- * mh-e.el (mh-scan-msg-num-regexp): Regexp matching the message
- number in scan lines.
- (mh-scan-date-regexp): Regexp matching a valid date in scan lines.
- (mh-scan-rcpt-addr-regexp): Regexp specifying the recipient in
- scan lines for messages we sent.
- (mh-scan-followup-regexp): Regexp matching a followup subject
- line, starting with Re:
- (mh-scan-body-regexp):
- Regexp matching the message body beginning displayed in scan lines.
- (mh-scan.font-lock-regexp): Regexp matching output of the
- optional scan.font-lock format file.
- (mh-folder-font-lock-keywords): New font-lock for folder-mode that
- uses the above regexps.
-
-2001-11-19 chad brown <y@mit.edu>
-
- * mh-comp.el (mh-letter-tool-bar-map): made both references to
- mh-letter-tool-bar-map conditional on tool-bar-mode, instead of
- just one.
-
-2001-11-19 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-position-on-field): Move to the end of the header
- if the field is not present. This function was documented to do
- this, but wasn't doing so.
- (mh-insert-x-mailer): Simplified by using existing
- mh-goto-header-field and mh-insert-fields functions. Now that
- mh-insert-fields is used to insert X-Mailer header field, no
- longer need to include X-Mailer in mh-x-mailer-string.
-
-2001-11-18 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-tool-bar-map): New version of
- mh-letter-mode tool-bar. Changed order of buttons; made customize
- and info buttons specific to mh-e.
-
- * mh-e.el (mh-folder-font-lock-keywords): New font-lock regexp
- uses variables mh-deleted-msg-regexp, mh-refiled-msg-regexp and
- mh-cur-scan-msg-regexp, so will better adapt to non-default scan
- formats. Also, lines marked for refiling are now fontified.
-
-2001-11-18 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-show-mode): Added local variable
- mail-header-separator which is initialized to
- mh-mail-header-separator.
-
- * mh-comp.el (mh-mail-header-separator): Updated to include ^$.
- Needed when running mh-edit-again, since by then the separator is
- gone. Added documentation saying one should use
- mail-header-separator and initialize it from
- mh-mail-header-separator.
- (mh-forward): Initialize mail-header-separator since
- mh-letter-mode hasn't kicked in yet (which does initialize
- mail-header-separator).
- (mh-letter-mode): Initialize mail-header-separator from
- mh-mail-header-separator, not hard-coded string.
-
- * mh-comp.el (mh-insert-x-mailer-p): New variable to control
- whether X-Mailer string is inserted. Default: t.
- (mh-x-mailer-string): New variable that caches actual X-Mailer
- string.
- (mh-letter-mode): Call mh-insert-x-mailer if mh-insert-x-mailer-p
- is t.
- (mh-insert-x-mailer): New function that inserts X-Mailer header
- field.
-
-2001-11-17 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-letter-header-font-lock): New function to return
- the entire mail header to font-lock for sedate font-locking.
- (mh-show-font-lock-keywords): Modified to fontify whole lines and use
- mh-letter-header-font-lock above to fontify whole header.
-
-2001-11-17 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mail-header-separator): Added ^ and $ to make more
- specific.
- (mh-forward, mh-letter-mode): Replaced hard-coded string with
- mail-header-separator.
-
-2001-11-16 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-e-RCS-id): Renamed to mh-version.
- (mh-version): The variable: Set to a number instead of Id since
- the Id didn't have the mh-e version number, and both Emacs and
- gnus do it this way too.
- (mh-version): The function: Fixed for nmh. Now displays mh-e
- version correctly. Cleaned up output and display mh-progs, etc.
- (Closes SF #405620.)
-
-2001-11-15 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-tool-bar-map): New tool-bar support for
- mh-letter-mode in emacs21. Uses icons from gnus/message.el.
- * mh-comp.el (mh-letter-mode): Add buffer-local binding of
- tool-bar-map to mh-letter-tool-bar-map.
-
-2001-11-15 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-have-file-command): Add check for existence of
- executable-find command, which Jeffrey didn't exist in emacs-20.4.
- * mh-utils.el (mh-decode-quoted-printable-have-mimedecode): same
- as above.
- * mh-mime.el (mh-file-mime-type): Bug Fix. Some versions of
- 'file' output a string like "file: Using regular magic file..."
- to stderr, so discard stderr when using call-process with 'file'.
-
-2001-11-14 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-have-file-command): Check if 'file' command on
- system accepts arguments -i -b before accepting it for our use.
-
-2001-11-14 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-find-progs): Use expand-file-name instead of
- concatenating together strings into a path.
-
-2001-11-14 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-folder-sequence-menu): Enable mh-widen in sequence
- menu only when mh-narrowed-to-seq is t.
-
-2001-11-14 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-have-file-command): Use 'executable-find' instead
- of more complicated and error-prone call-process to which command.
- * mh-utils.el (mh-decode-quoted-printable-have-mimedecode): Same
- change as above.
-
-2001-11-14 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-make-folder-mode-line): Bug fix. Properly deal with
- folders that do not have any lines in them. Print "no msgs"
- instead of "0 msgs". Do not try to print a range when there are
- no messages.
- * mh-e.el (mh-regenerate-headers): Bug fix. Catch and remove the
- "scan: bad message list" message.
-
-2001-11-13 Jeffrey C Honig <jch@honig.net>
-
- * mh-utils.el (mh-find-progs): Bug fix. Add "mh/etc" to the
- subdirectories to search for "components". On BSD/OS, nmh is in
- "/usr/contrib/mh/*".
-
-2001-11-13 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-mode): Bug fix. Load mh-mime before
- setting mh-mhn-compose-insert-p (when looking at a "forw: -mime"
- message containing a MIME composition) such that the variable is
- properly declared as buffer-local.
-
-2001-11-12 Bill Wohler <wohler@newt.com>
-
- * mh-funcs.el (mh-print-msg): mhl is in the mh-lib-progs
- directory, not mh-lib (closes SF #481128).
-
-2001-11-12 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-widen): Bug fix (closes SF #481036).
- In a sequence with pending deletes and refiles, running mh-widen
- would wipe out their notations, even though the sequences are still
- defined. Fixed by calling a new function,
- mh-notate-deleted-and-refiled. Also changed the coping of
- mh-goto-msg-num since it didn't work consistently.
- * mh-seq.el (mh-notate-deleted-and-refiled): New functions written
- to fix above mh-widen bug. It's a first cut, we may want to clear
- all notations first, and notate the current-message sequence and
- user sequences. Time will tell.
-
-2001-11-12 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-widen): Make it attempt to stay on the same
- message number (closes SF bug #480922).
-
-2001-11-11 Bill Wohler <wohler@newt.com>
-
- * import-emacs: New shell script to import Emacs changes to mh-e.
-
- * Makefile (import): New target to import Emacs changes.
-
-2001-11-09 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-file-mime-type): Bug fix. Change regexp to
- extract mime type from 'file -i' command output.
-
-2001-11-08 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-update-sequences-after-mh-show):
- New customizable variable telling whether to run
- mh-update-sequences in mh-show-mode. Default is t.
- * mh-utils.el (mh-show-msg): Run mh-update-sequences when
- mh-update-sequences-after-mh-show is set.
-
-2001-11-08 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-decode-quoted-printable-have-mimedecode):
- New variable telling whether command 'mimedecode' is on system.
- (http://www.freesoft.org/CIE/FAQ/mimedeco.c)
- * mh-utils.el (mh-decode-quoted-printable):
- New customizable variable telling whether to run mimedecode on
- MIME message containing quoted-printable parts. mimedecode will
- only alter quoted-printable parts, leaving others intact, and the
- resulting message is still fully MIME.
- * mh-utils.el (mh-decode-quoted-printable): New function to run
- mimedecode on the current buffer.
- * mh-utils.el (mh-display-msg): Conditionally call
- mh-decode-quoted-printable function if mh-decode-quoted-printable
- variable is set, to view messages containing quoted-printable
- characters into 8-bit.
-
-2001-11-08 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-mode): Set mh-mhn-compose-insert-p if
- looking at a "forw: -mime" message containing a MIME composition.
- * mh-mime.el (mh-file-mime-type): Bug fix. Failed on files like
- "~/.mh_profile" because of shell construct. Wrapped filename with
- expand-file-name.
- * mh-comp.el (mh-letter-mode-map): C-cC-o keybinding in
- mh-letter-mode-map for mh-open-line.
-
-2001-11-07 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-open-line): New user function to split open a line
- when editing a reply with included text.
- * mh-comp.el (mh-current-fill-prefix): New function used by
- mh-open-line to get the fill-prefix on the current line.
- * mh-comp.el: Add mh-open-line to mh-letter-mode menubar.
-
-2001-11-06 Peter S Galbraith <psg@debian.org>
-
- * mh-seq.el (mh-region-to-sequence): New function, creating a
- sequence named 'region containing the message list in the selected
- region.
- * mh-e.el (mh-delete-msg): Mark messages in region for deletion if
- mark is active and in transient-mark-mode.
- * mh-e.el (mh-refile-msg): Mark messages in region for refiling if
- mark is active and in transient-mark-mode.
- * mh-e.el (mh-undo): Undo message marks for refile or deletion if
- region if mark is active and in transient-mark-mode.
-
-2001-11-06 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-letter-mode): Use sendmail.el's fill-paragraph.
- Copy its settings for paragraph-start, paragraph-separate,
- fill-paragraph-function, adaptive-fill-regexp and
- adaptive-fill-first-line-regexp. This make M-q (fill-paragraph)
- work correctly!
-
-2001-11-05 Peter S Galbraith <psg@debian.org>
-
- * mh-funcs.el (mh-kill-folder): Remove mh-do-not-confirm condition
- and always prompt the user for such a drastic step. Also change
- the prompt a bit to clarify it.
-
-2001-11-04 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-mhn-compose-insert-p): New buffer-local variable
- to tell when a MIME insertion was done in a letter.
- * mh-mime.el (mh-mhn-compose-type): Set mh-mhn-compose-insert-p.
- * mh-mime.el (mh-mhn-compose-external-type):
- Set mh-mhn-compose-insert-p.
- * mh-mime.el (mh-mhn-compose-forw): Set mh-mhn-compose-insert-p.
- * mh-mime.el (mh-edit-mhn): Clear mh-mhn-compose-insert-p.
- * mh-comp.el (mh-send-letter): Run mh-edit-mhn when
- mh-mhn-compose-insert-p is set.
-
-2001-11-03 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-have-file-command): new function testing whether
- file command is on the system.
- * mh-mime.el (mh-file-mime-type): new function returning MIME type
- from file command.
- * mh-mime.el (mh-mhn-compose-insertion): Make use of
- mh-file-mime-type function instead of prompting.
-
-2001-10-30 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-show-use-goto-addr): defcustom this new
- variable, determining whether to call goto-addr in mh-show-mode.
- * mh-utils.el (mh-show-mode): Call goto-address when
- mh-show-use-goto-addr is t.
-
-2001-10-25 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-recenter): Clarify docs and change '(t) to
- (list 4) to match elisp doc on what C-u prefix argument actually is.
-
-2001-10-23 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-summary-height): In my quest to make mh-e more
- useful out-of-the-box for new users, set mh-summary-height to a
- minimum of 4 and a maximum of 10 depending on frame height. I
- typically have 70 lines in my Emacs frame, so having a default of
- 4 was silly for my case.
- * mh-e.el (mh-update-sequences): Check for nil value of
- mh-current-folder, which happens if mh-summary-height < 4
- although I haven't tracked down why that happens.
-
-2001-10-22 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-insert-fields): Test for nil value when inserting
- field.
-
-2001-10-20 Peter S Galbraith <psg@debian.org>
-
- * mh-comp.el (mh-user-agent-compose): Merged-in from XEmacs-21.4 source
- * mh-comp.el (mh-letter-mode): Add easy-menu-add statement for XEmacs21
- * mh-pick.el (mh-pick-mode): Add easy-menu-add statement for XEmacs21.
- * mh-e.el (mh-folder-mode): Add easy-menu-add statements for XEmacs21.
- * mh-utils.el: defalias 'screen-height to 'frame-height for XEmacs21.
-
-2001-10-19 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-edit-mhn): Use mhbuild in nmh context.
- * mh-utils.el (mh-find-progs): The variable mh-nmh-p (t when nmh
- is in use rather than MH) was set assuming that the string "nmh"
- will be in mh-lib-progs or mh-lib. This failed on Debian systems.
- Better to check for the existence of mhbuild in directory mh-progs.
- (closes SF bug #441776)
-
-2001-10-18 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el: Add menubar entry from contrib/mh-menubar.el
- * mh-comp.el: Add menubar entry from contrib/mh-menubar.el
- * mh-pick.el: Add menubar entry from contrib/mh-menubar.el
-
-2001-07-30 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el: Change font-lock patterns for folders.
- Fontify scan.font-lock patterns (which will be documented)
- and fontify subject lines prefixed with "Re:" differently.
- * mh-comp.el (mh-letter-mode): Add font-lock support as in
- mh-show-mode.
-
-2001-04-14 chad brown <y@mit.edu>
-
- Rearrange the font-lock keywords a bit.
-
-2001-04-12 chad brown <y@mit.edu>
-
- Preliminary (somewhat boring) font-lock support for mh-e. More
- interesting font-lock support probably wants to have better
- support for multiple format files
-
-2001-02-24 chad brown <y@mit.edu>
-
- Add default nmh paths to mh-find-prog in mh-utils.el.
- change to mh-kill-folder in mh-funcs.el to make it more general.
-
-2001-02-19 Bill Wohler <wohler@newt.com>
-
- * Makefile (EMACS): Renamed to EMACS_HOME. Also, don't define if
- EMACS_HOME already exists to give developer a chance to set
- environment variable.
- (install): $MH-E-SRC is copied to $(EMACS_HOME)/lisp/mail, not
- $(EMACS_HOME)/src.
- (dist): Leave release in current directory.
-
-
- Copyright (C) 2003-2024 Free Software Foundation, Inc.
-
- This file is part of GNU Emacs.
-
- GNU Emacs is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU Emacs is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;; Local Variables:
-;; coding: utf-8
-;; End:
+++ /dev/null
-2014-10-20 Glenn Morris <rgm@gnu.org>
-
- * Merge in all changes up to 24.4 release.
-
-2014-09-30 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.6.
-
- * mh-e.el (Version, mh-version): Update for release 8.6.
-
-2014-09-30 Mike Kupfer <m.kupfer@acm.org>
-
- * mh-comp.el (mh-insert-x-face): Ensure that mh-x-face-file is a
- string before trying to use it (closes SF #474).
- (mh-bare-components): New function to create a temporary initial
- components file; replaces mh-find-components. Improve the temp
- folder and file names as per a suggestion from Bill Wohler.
- Also address XEmacs compatibility issues: use mm-make-temp-file instead
- of make-temp-file, and only pass one argument to delete-directory.
- (mh-edit-again, mh-send-sub): Use mh-bare-components instead of
- mh-find-components (partially closes SF #468).
-
-2014-05-09 Glenn Morris <rgm@gnu.org>
-
- * mh-e.el (mh-variants): Use file-accessible-directory-p.
-
-2014-03-16 Bill Wohler <wohler@newt.com>
-
- * mh-folder.el (mh-regenerate-headers): Fix scan: bad message list
- `unseen' error (closes SF #471).
- * mh-e.el (mh-version): Add +bzr to version.
-
-2014-03-06 Glenn Morris <rgm@gnu.org>
-
- * mh-compat.el (mh-display-completion-list):
- Replace use of obsolete argument of display-completion-list.
-
-2013-11-05 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-print.el (mh-ps-print-preprint): Don't use dynamic-var
- `prefix-arg' as function argument.
-
-2013-06-18 Juri Linkov <juri@jurta.org>
-
- * mh-alias.el (mh-alias-local-users): Add non-nil arg REPLACE to
- the call of `shell-command-on-region'. (Bug#14637)
-
-2013-05-22 Glenn Morris <rgm@gnu.org>
-
- * mh-speed.el (mh-speed-view):
- Use dframe-with-attached-buffer rather than speedbar- alias.
-
-2013-05-21 Glenn Morris <rgm@gnu.org>
-
- * mh-comp.el (mh-regexp-in-field-p): Fix previous change.
-
-2013-05-09 Glenn Morris <rgm@gnu.org>
-
- * mh-e.el (mh-sortm-args, mh-default-folder-for-message-function):
- Fix custom types.
-
-2013-05-08 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-comp.el (mh-regexp-in-field-p): Minor simplification.
-
-2013-03-02 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.5.
-
- * mh-e.el (Version, mh-version): Update for release 8.5.
-
-2013-03-02 Jeffrey C Honig <jch@honig.net>
-
- * mh-folder.el (mh-inc-folder): Revert SF #2321115, SF #250
- which processed pending deletes and refiles. Call to
- mh-process-or-undo-commands to ensure that pending changes are
- properly tagged after including new mail (closes SF #271).
-
- * mh-comp.el: Ensure that mail-header-separator is set before
- invoking any mml functions (closes SF #270).
-
-2013-01-23 Dmitry Antipov <dmantipov@yandex.ru>
-
- * mh-acros.el (mh-do-at-event-location): Use point-marker.
- * mh-search.el (mh-index-create-imenu-index): Likewise.
- * mh-xface.el (mh-x-image-url-display): Likewise.
-
-2012-11-25 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.4.
-
- * mh-e.el (Version, mh-version): Update for release 8.4.
-
- * mh-comp.el (mh-regexp-in-field-syntax-table): Fix docstring.
- (mh-edit-again): Format.
- (mh-components-to-list): Fix docstring.
- (mh-regexp-in-field-p): Remove unused variable `field'.
-
- * mh-compat.el (mh-define-obsolete-variable-alias)
- (mh-make-obsolete-variable): New macros to fix XEmacs compiler
- warnings.
-
- * mh-letter.el (mh-yank-hooks): Use new mh-make-obsolete-variable
- macro.
-
- * mh-e.el (mh-kill-folder-suppress-prompt-hooks):
- Use new mh-define-obsolete-variable-alias macro.
-
- * mh-compat.el (mh-cl-flet): New alias for cl-flet on Emacs 24 and
- flet elsewhere.
-
- * mh-thread.el (mh-thread-set-tables): Replace flet with new alias
- mh-cl-flet.
-
- * mh-show.el (mh-gnus-article-highlight-citation):
- Replace flet with new alias mh-cl-flet.
-
- * mh-mime.el (mh-display-with-external-viewer, mh-mime-display)
- (mh-press-button, mh-push-button, mh-display-emphasis):
- Replace flet with new alias mh-cl-flet.
-
- * mh-e.el (mh-invisible-header-fields-internal):
- Remove trailing whitespace.
-
-2012-11-25 Jeffrey C Honig <jch@honig.net>
-
- * mh-comp.el: (mh-edit-again): Use the components file to specify
- default values for missing headers in the draft.
- (mh-regexp-in-field-syntax-table, mh-fcc-syntax-table)
- (mh-addr-syntax-table, mh-regexp-in-field-p): Use a syntax table
- so we'll properly parse non-address fields.
- (mh-components-to-list, mh-extract-header-field): New functions to
- read components file.
- (mh-find-components, mh-send-sub): Move code to locate components
- file into a new function.
- (mh-insert-auto-fields, mh-modify-header-field): New syntax for
- calling mh-regexp-in-field-p (closes SF #1708292).
-
- * mh-e.el (mh-invisible-header-fields-internal): Added: X-xsi.
- (addresses SF #1916032).
-
- * mh-folder.el (mh-inc-folder): Call mh-process-or-undo-commands
- before running to ensure we do not lose any pending changes.
- (closes SF #2321115).
-
-2012-11-25 Ted Phelps <phelps@gnusto.com>
-
- Postpone junk processing (closes SF #2945712). Patch submitted by
- Ted Phelps and refined by Bill Wohler.
-
- * mh-e.el (mh-blacklist, mh-whitelist): New variables.
- (mh-whitelist-preserves-sequences-flag): New option.
- (mh-before-commands-processed-hook): Update documentation.
- (mh-blacklist-msg-hook, mh-whitelist-msg-hook): New hooks.
- (mh-folder-blacklisted, mh-folder-whitelisted): New faces.
- * mh-folder.el (mh-folder-message-menu): Add "Junk" to "Undo."
- (mh-folder-font-lock-keywords): Add regexps for blacklisted and
- whitelisted messages.
- (mh-folder-mode): Add mh-blacklist and mh-whitelist variables.
- (mh-execute-commands): Update documentation.
- (mh-undo, mh-outstanding-commands-p, mh-process-commands)
- (mh-delete-a-msg, mh-refile-a-msg, mh-undo-msg):
- Handle blacklisted and whitelisted messages.
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Update to put
- messages in blacklist and whitelist respectively for latter
- processing.
- (mh-blacklist-a-msg, mh-junk-whitelist-a-msg): New function to
- support previous functions.
- (mh-junk-blacklist-disposition): New function.
- (mh-junk-process-blacklist, mh-junk-process-whitelist):
- New functions that perform the blacklisting and whitelisting
- respectively that used to be performed by mh-junk-blacklist and
- mh-junk-whitelist.
- * mh-scan.el (mh-scan-blacklisted-msg-regexp)
- (mh-scan-whitelisted-msg-regexp): New scan line regexps.
- (mh-scan-good-msg-regexp): Add B and W characters to regexp.
- (mh-scan-cmd-note-width): Update documentation.
- (mh-note-blacklisted, mh-note-whitelisted): New scan line
- characters.
- * mh-search.el (mh-index-execute-commands): Handle blacklisted and
- whitelisted messages.
-
-2012-11-25 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-invisible-header-fields-internal): Added:
- Bounces-To:, Bounces_to:, X-ACL-Warn:, X-BFI:, X-BPS1:, X-BPS2:,
- X-Campaign-Id:, X-Campaign:, X-Cloudmark-SP-, X-Destination-ID:,
- X-detected-operating-system:, X-DocGen-Version:, X-EM-,
- X-Email-Type-Id:, X-FB-SS:, X-FuHaFi:, X-MailFlowPolicy:,
- X-mail_abuse-inquires, X-MailingID:, X-Match:,
- X-MaxCode-Template:, X-ME-Bayesian:, X-Sendergroup:, X-SFDC-,
- X-SMFBL:, X-SMHeaderMap:, X-VGI-OESCD:, X-VirtualServer:,
- X-VirtualServerGroup:, X-XPT-XSL-Name:, X-Y-GMX-Trusted:,
- X-XWALL-, X-ZixNet:. Changed X-Habeas-SWE- to X-Habeas-.
- Updated the comment. (addresses SF #1916032).
-
-2012-11-25 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-invisible-header-fields-internal):
- Add X-AnalysisOut, X-Authentication-Info, X-Auto-Response-Suppress,
- X-Bayes-Prob, X-Cam-, X-CanIt-Geo, X-Completed, X-Facebook,
- X-Forwarded-, X-Generated-By, X-Headers-End, X-IEEE-UCE,
- X-Jira-Fingerprint, X-Junkmail-, X-Launchpad-, X-MXL-Hash,
- X-Notification-, X-Notifications, X-Oracle-Calendar.
- Replace X-DCC-Usenix-Metrics with X-DCC- (addresses SF #1916032).
-
-2012-11-25 Jeffrey C Honig <jch@honig.net>
-
- * mh-letter.el (mh-yank-cur-msg): Replace usage of set-buffer with
- with-current-buffer in mh-yang-cur-msg, semantics changed in emacs
- 23 and we do not want to use set-buffer unless we actually want to
- change the buffer the user is looking at (closes SF #2830504).
-
- * mh-show.el (mh-show-folder-map): Add missing key binding for
- mh-show-pack-folder (closes SF #3466086).
-
-2012-11-25 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +bzr to version.
-
-2012-10-23 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-letter.el (mh-yank-hooks): Use make-obsolete-variable.
-
-2012-04-25 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-utils.el (minibuffer-completing-file-name): Don't declare, unused.
-
-2012-04-21 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-folder.el (top): Check whether which-func-modes is t before
- adding mh-folder-mode.
-
-2011-11-20 Bill Wohler <wohler@newt.com>
-
- * Release MH-E version 8.3.1.
-
- * mh-e.el (Version, mh-version): Update for release 8.3.1.
-
-2011-11-20 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-utils.el (mh-folder-list): Fix typo.
- (mh-children-p): Move part of the docstring to a comment.
-
-2011-11-16 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-search.el (mh-pick-parse-search-buffer): Fix typo.
-
-2011-09-20 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.3.
-
- * mh-e.el (Version, mh-version): Update for release 8.3.
-
-2011-07-30 Bill Wohler <wohler@newt.com>
-
- * mh-show.el (mh-unvisit-file): Clarify language in yes-or-no-p
- and error messages.
-
-2011-07-17 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.2.93.
-
- * mh-e.el (Version, mh-version): Update for release 8.2.93.
-
- * mh-compat.el (mh-pop-to-buffer-same-window): Delete.
- * mh-folder.el (mh-inc-folder, mh-modify, mh-scan-folder)
- (mh-make-folder): Revert to switch-to-buffer, as the Emacs folks
- decided that it was fine to use it in programs.
-
-2011-07-16 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.2.92.
-
- * mh-e.el (Version, mh-version): Update for release 8.2.92.
-
-2011-07-12 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.2.91.
-
- * mh-e.el (Version, mh-version): Update for release 8.2.91.
-
- * mh-compat.el (mh-pop-to-buffer-same-window): Add compatibility
- function to call switch-to-buffer on systems that lack
- pop-to-buffer-same-window.
- * mh-folder.el (mh-inc-folder, mh-modify, mh-scan-folder)
- (mh-make-folder): Call mh-pop-to-buffer-same-window instead of
- switch-to-buffer. The previous change which used pop-to-buffer
- produced the wrong behavior.
-
-2011-07-12 Henrique Martins <henrique@martins.cc> (tiny change)
-
- * mh-xface.el (mh-picon-get-image): Remove quote from block
- argument.
- * mh-mime.el (mh-mh-directive-present-p): Ditto.
-
-2011-07-10 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.2.90.
-
- * mh-e.el (Version, mh-version): Update for release 8.2.90.
-
- * mh-utils.el (mh-sub-folders-actual): Remove FIXME question.
-
- * mh-mime.el (mh-decode-message-subject): Fix case of Subject.
-
- * mh-folder.el (mh-inc-folder, mh-modify, mh-scan-folder)
- (mh-make-folder): Replace calls to switch-to-buffer with of
- pop-to-buffer. The former is intended for interactive use only
- and generates warnings in Emacs 24.
-
-2011-07-09 Bill Wohler <wohler@newt.com>
-
- * mh-speed.el (mh-speed-toggle, mh-speed-view): Document "ignored"
- arguments to keep checkdoc happy.
-
- * mh-search.el (mh-flists-execute): Ditto.
-
- * mh-funcs.el (mh-undo-folder): Ditto.
-
- * mh-comp.el (mh-user-agent-compose): Ditto.
-
- * mh-xface.el (mh-face-to-png, mh-uncompface)
- (mh-picon-file-contents): Only call set-buffer-multibyte if it
- exists, which it doesn't in XEmacs.
-
-2011-07-04 Bill Wohler <wohler@newt.com>
-
- * mh-e.el: Just require mh-loaddefs since loading it in an
- eval-and-compile block causes compilation errors in XEmacs.
-
- * mh-acros.el, mh-comp.el, mh-e.el, mh-folder.el, mh-letter.el:
- * mh-mime.el, mh-search.el, mh-seq.el: Shush XEmacs compiler in
- mh-do-in-xemacs block.
-
- * mh-compat.el (mh-window-full-height-p): Add compatibility
- function for XEmacs.
- * mh-show.el (mh-show-msg): Use it, and avoid compiler warning on
- XEmacs.
-
- * mh-letter.el (mh-letter-mode-map, mh-letter-complete)
- (mh-complete-word): Remove FIXME comments since these functions
- are still needed in other Emacsen. However, they can probably
- stand to be generalized like completion-at-point.
- (mh-letter-complete-or-space): Remove unused variable.
-
-2011-07-03 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-test-completion): Add compatibility function
- for XEmacs.
- * mh-alias.el (mh-alias-letter-expand-alias): Use it, and avoid
- compiler warning on XEmacs.
-
- * mh-utils.el:
- * mh-mime.el: Shush XEmacs compiler in mh-do-in-xemacs block.
-
- * mh-folder.el: Use boundp instead of fboundp when testing
- existence of desktop-buffer-mode-handlers (closes SF #1510145).
-
-2011-05-10 Jim Meyering <meyering@redhat.com>
-
- Fix doubled-word typos.
- * mh-alias.el (mh-alias-minibuffer-confirm-address):
- * mh-scan.el (mh-scan-destination-width): Fix typos.
-
-2011-04-28 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-utils.el (mh-folder-completion-function): Make it work like
- file-name completion, so partial-completion can do its job.
-
- * mh-letter.el (mh-letter-completion-at-point): New function, extracted
- from mh-letter-complete
- (mh-letter-mode, mh-letter-complete, mh-letter-complete-or-space):
- Use it.
- (mh-complete-word): Only use the common-substring arg when it works.
- (mh-folder-expand-at-point):
- * mh-alias.el (mh-alias-letter-expand-alias): Return data suitable for
- completion-at-point-functions.
-
-2011-04-06 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-funcs.el (mh-undo-folder): Accept and ignore arguments,
- for compatibility with `revert-buffer'. Doc fix. (Bug#8431)
-
-2011-03-07 Chong Yidong <cyd@stupidchicken.com>
-
- * Version 23.3 released.
-
-2011-03-05 Antoine Levitt <antoine.levitt@gmail.com>
-
- * mh-funcs.el (mh-store-msg, mh-store-buffer):
- * mh-mime.el (mh-mime-save-parts): Use read-directory-name.
-
-2011-01-13 Chong Yidong <cyd@stupidchicken.com>
-
- * mh-comp.el (mh-user-agent-compose): New arg RETURN-ACTION.
-
-2010-11-07 Glenn Morris <rgm@gnu.org>
-
- * mh-seq.el (mh-read-msg-list): Use point-at-eol.
-
-2010-11-03 Glenn Morris <rgm@gnu.org>
-
- * mh-mime.el (dots, type, ov): Avoid unnecessary declaration.
-
-2010-05-14 Peter S Galbraith <psg@debian.org>
-
- * mh-mime.el (mh-decode-message-subject): New function to decode
- RFC2047 encoded Subject lines. Used for reply drafts.
- * mh-comp.el (mh-compose-and-send-mail):
- Call `mh-decode-message-subject' on (reply or forward) message drafts.
-
-2010-05-07 Chong Yidong <cyd@stupidchicken.com>
-
- * Version 23.2 released.
-
-2010-05-03 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-show.el (mh-showing-mode): Move function to mh-e.el.
- * mh-e.el (mh-showing-mode): Use define-minor-mode.
-
-2010-03-24 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-scan.el (mh-scan-cmd-note-width): Doc fix.
- (mh-scan-format-mh, mh-scan-body-regexp, mh-scan-cur-msg-number-regexp)
- (mh-scan-cur-msg-number-regexp, mh-scan-date-regexp)
- (mh-scan-deleted-msg-regexp, mh-scan-good-msg-regexp)
- (mh-scan-msg-format-regexp, mh-scan-msg-format-string)
- (mh-scan-msg-number-regexp, mh-scan-rcpt-regexp)
- (mh-scan-refiled-msg-regexp, mh-scan-sent-to-me-sender-regexp)
- (mh-scan-subject-regexp, mh-update-scan-format)
- (mh-msg-num-width-to-column): Fix typos in docstrings.
-
-2010-03-10 Chong Yidong <cyd@stupidchicken.com>
-
- * Branch for 23.2.
-
-2009-12-01 Bill Wohler <wohler@newt.com>
-
- * mh-search.el (mh-mairix-execute-search): Use mh vfolder_format.
- Fix typo in database path.
- (mh-namazu-execute-search): Specify -q in example since namazu is
- excessively garrulous.
-
-2009-11-05 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-thread.el (mh-thread-set-tables):
- * mh-speed.el (mh-folder-speedbar-menu-items, mh-speed-stealth-update)
- (mh-speed-extract-folder-name, mh-speed-parse-flists-output)
- (mh-speed-invalidate-map, mh-speed-add-folder):
- * mh-show.el (mh-invalidate-show-buffer, mh-show-sequence-menu):
- * mh-seq.el (mh-list-sequences):
- * mh-search.el (mh-index-execute-commands, mh-index-add-to-sequence)
- (mh-index-delete-from-sequence, mh-index-update-maps):
- * mh-scan.el (mh-msg-num-width):
- * mh-print.el (mh-ps-spool-buffer):
- * mh-mime.el (mh-mime-save-parts, mh-handle-set-external-undisplayer)
- (mh-file-mime-type):
- * mh-letter.el (mh-yank-cur-msg):
- * mh-funcs.el (mh-list-folders, mh-pipe-msg, mh-store-msg)
- (mh-store-buffer):
- * mh-folder.el (mh-modify, mh-visit-folder, mh-write-msg-to-file)
- (mh-prompt-for-refile-folder):
- * mh-e.el (mh-exec-cmd, mh-exec-cmd-error, mh-exec-cmd-daemon)
- (mh-handle-process-error, mh-variant-info):
- * mh-comp.el (mh-forward):
- * mh-alias.el (mh-alias-local-users, mh-alias-which-file-has-alias)
- (mh-alias-add-alias-to-file): Use with-current-buffer (closes SF
- #1903293).
-
-2009-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-e.el: Load mh-loaddefs during compilation as well.
-
-2009-11-04 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-e.el (mh-loaddefs): Load rather than require.
-
-2009-10-06 Glenn Morris <rgm@gnu.org>
-
- * mh-show.el (mh-show-msg): Use window-full-height-p.
-
-2009-08-28 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-comp.el (mh-send-letter): default-buffer-file-coding-system
- => (default-value 'buffer-file-coding-system).
-
-2009-08-10 Bill Wohler <wohler@newt.com>
-
- * mh-junk.el (mh-spamassassin-blacklist, mh-bogofilter-blacklist)
- (mh-spamprobe-blacklist): Sync docstring with manual.
-
-2009-07-22 Kevin Ryde <user42@zip.com.au>
-
- * mh-junk.el (mh-spamassassin-blacklist, mh-bogofilter-blacklist)
- (mh-spamprobe-blacklist): Hyperlink URLs in docstrings with URL `...'.
-
-2009-06-13 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.2.
-
- * mh-e.el (Version, mh-version): Update for release 8.2.
-
- * mh-seq.el (mh-folder-size-flist)
- * mh-speed.el (mh-speed-parse-flists-output)
- * mh-xface.el (mh-face-display-function): Remove trailing space.
-
-2009-03-13 D. Goel <deego3@gmail.com>
-
- * mh-seq.el (mh-folder-size-flist): Use (values-list) in m-v call
- to list.
-
- * mh-speed.el (mh-speed-parse-flists-output): Ditto.
- * mh-xface.el (mh-face-display-function): Ditto.
- * mh-search.el (mh-index-parse-search-regexp): Ditto.
-
- * mh-thread.el (mh-thread-generate): Ditto.
-
- * mh-seq.el (mh-parse-flist-output-line): Return list rather than values.
- We want to avoid emacs using m-v facilities.
- (mh-folder-size-folder): Ditto.
- (mh-parse-flist-output-line): Ditto.
- * mh-thread.el (mh-thread-prune-subject): Ditto.
- * mh-xface.el (mh-picon-get-image): Ditto.
- (mh-picon-file-contents): Ditto.
- * mh-search.el (mh-index-evaluate): Ditto.
-
-2009-01-27 Bill Wohler <wohler@newt.com>
-
- * mh-funcs.el (mh-pack-folder): Fix docstring.
-
- * mh-e.el (mh-pack-folder-hook): Bump package-version to 8.2.
-
- * mh-gnus.el (mh-mm-merge-handles)
- (mh-mm-set-handle-multipart-parameter, mh-mm-inline-text-vcard)
- (mh-mml-minibuffer-read-disposition, mh-mm-save-part): Update with
- code from Gnus 5.11 (closes SF #2235022).
-
-2009-01-26 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-e.el (mh-pack-folder-hook): New variable.
- * mh-funcs.el (mh-pack-folder): Call new mh-pack-folder-hook.
-
-2009-01-26 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-goto-header-end): Use mh-mail-header-separator
- instead of -* in regexp.
-
- * mh-folder.el (mh-folder-mode-help-messages): Add e and t to K's
- help.
-
-2009-01-09 Glenn Morris <rgm@gnu.org>
-
- * mh-letter.el: Replace last-input-char with last-input-event.
-
-2008-08-18 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.1.
-
- * mh-e.el (Version, mh-version): Update for release 8.1.
-
-2008-08-11 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-variant-mh-info, mh-variant-nmh-info)
- (mh-variant-set-variant, mh-variant-p, mh-profile-component)
- (mh-variant-set, mh-variant, mh-scan-format-file): Fix typo in
- docstring.
-
- * mh-comp.el (mh-reply)
- * mh-e.el (mh-sys-path, mh-variant-info, mh-variant-mu-mh-info)
- (mh-variant-p, mh-profile-component, mh-variant-set, mh-variant)
- (mh-scan-format-file)
- * mh-folder.el (mh-regenerate-headers)
- * mh-scan.el (mh-scan-format)
- * mh-search.el (mh-pick-regexp-builder): Rename variant mu-mh to
- gnu-mh and be explicit about GNU mailutils MH in docstrings (with
- thanks to Darel Henman) (closes SF #1768928).
-
-2008-08-01 Bill Wohler <wohler@newt.com>
-
- * mh-show.el (mh-show-preferred-alternative)
- * mh-e.el (mh-annotate-msg-hook): Sync docstring with manual.
-
- * mh-comp.el (mh-send-letter, mh-redistribute):
- Mention mh-annotate-msg-hook in docstring.
-
-2008-06-29 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add invisible
- header fields for X-Hz (mail from Hertz), X-Proofpoint (Proofpoint
- antivirus/anti-spam) and X-RIM (Research In Motion).
-
-2008-06-20 Stephen Eglen <stephen@gnu.org>
-
- * mh-show.el (mh-defun-show-buffer): Use `...' rather than
- "..." in generated docstrings.
-
-2008-06-12 Glenn Morris <rgm@gnu.org>
-
- * mh-seq.el (tool-bar-map): Define for compiler.
-
- * mh-folder.el (mh-folder-mode):
- * mh-letter.el (mh-letter-mode):
- * mh-show.el (mh-show-mode): Check tool-bar-map is bound.
-
-2008-06-08 John Paul Wallington <jpw@pobox.com>
-
- * mh-acros.el (toplevel): Put `doc-string-elt' properties on
- `defun-mh' and `defmacro-mh'.
-
- * mh-alias.el (mh-alias-read-address-map): Define within defvar.
-
- * mh-comp.el (mh-letter-mode-syntax-table): Define within defvar.
-
- * mh-letter.el (mh-complete-word): Doc fix.
-
-2008-06-02 John Paul Wallington <jpw@pobox.com>
-
- * mh-e.el (mh-exec-cmd-env-daemon): Doc fix.
-
-2008-06-01 John Paul Wallington <jpw@pobox.com>
-
- * mh-e.el (mh-path, mh-variant): Use dotted syntax for
- `package-version' info.
-
-2008-05-26 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-invisible-header-fields-internal): Remove Newsgroups
- from the list. Add Bytes, X-Campaignid, X-Country-Chain,
- X-Declude-, X-fmx-, X-Identity, X-Mailer_, X-pair-, X-SPF-,
- X-Usenet-Provider.
-
-2008-05-23 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-invisible-header-fields-internal):
- Remove DKIM-Signature as it is covered by DKIM-. Fully qualify X-EID.
-
-2008-05-19 Sergey Poznyakoff <gray@gnu.org.ua>
-
- * mh-mime.el (mh-mh-to-mime, mh-mh-to-mime-undo): Preserve modes
- when converting to or from MIME (closes SF #1966722).
-
-2008-05-19 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-invisible-header-fields-internal): Sort list in a
- case-insensitive way and add comment about it. Add many header
- fields (closes SF #1916032).
-
-2008-05-19 Xavier Maillard <xma@gnu.org> (tiny change)
-
- * mh-utils.el (mh-find-path): Don't throw error if MH environment
- variable is being used (closes SF #1946861).
-
-2008-05-19 Nick Dokos <nicholas.dokos@hp.com> (tiny change)
-
- * mh-search.el (mh-mairix-regexp-builder): Add additional items to
- search string to support org-mode (closes SF #1965704).
-
-2008-03-18 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add Accreditor,
- Seal-Send-Time.
- (mh-invisible-header-fields, mh-invisible-header-fields-default):
- Update URL to bug report for users to report ignored fields.
-
-2008-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-xface.el (mh-uncompface, mh-picon-file-contents):
- Use set-buffer-multibyte...
- (mh-face-display-function, mh-x-image-display): ...rather than bind
- default-enable-multibyte-characters.
-
-2008-02-24 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-send-letter): Call split-string on mh-send-args
- when sending synchronously too.
-
-2008-02-19 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-annotate-msg):
- * mh-e.el (mh-invisible-header-fields-internal): Remove trailing
- whitespace.
-
-2008-01-30 Bill Wohler <wohler@newt.com>
-
- * mh-mime.el (mh-mml-to-mime): Don't look up sender if From
- absent. Fixes "Wrong type argument: stringp, nil" error.
-
-2007-12-02 Glenn Morris <rgm@gnu.org>
-
- * mh-mime.el (mail-strip-quoted-names): Autoload it.
-
-2007-11-17 Dan Nicolaescu <dann@ics.uci.edu>
-
- * mh-e.el (mh-xemacs-flag): Remove.
- (mh-min-colors-defined-flag):
- * mh-xface.el (mh-show-xface-function):
- * mh-utils.el (mh-colors-available-p):
- * mh-show.el (mh-show-mode):
- * mh-gnus.el (mh-gnus-local-map-property):
- * mh-folder.el (mh-folder-mode-map)
- (mh-remove-xemacs-horizontal-scrollbar, mh-folder-mode):
- * mh-comp.el (mh-insert-x-mailer): Replace uses of mh-xemacs-flag
- with (featurep 'xemacs).
-
-2007-09-11 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2007-08-25 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-e.el (mh-annotate-msg-hook): New variable.
-
- * mh-comp.el (mh-annotate-msg): Call new mh-annotate-msg-hook.
- (mh-annotate-list): New variable, for mh-annotate-msg-hook.
-
-2007-08-21 Jeffrey C Honig <jch@honig.net>
-
- * mh-folder.el (mh-folder-message-menu, mh-folder-mode-map):
- Add folder mode support for mh-show-preferred-alternative (closes SF
- #1777321).
-
- * mh-show.el (mh-show-preferred-alternative)
- (mh-show-write-message-to-file, mh-show-message-menu)
- (mh-show-mode-map): Add mh-show-preferred-alternative (bound to
- ":") which will show the message's preferred alternative
- overriding the users configured preference. Useful for showing
- HTML when text content is lacking (closes SF #1777321).
-
- * mh-e.el:
- (mh-invisible-header-fields-internal): Exclude Fax and Phone.
- Put known exclusions as comments before the list and move parens to
- separate lines to aid in sorting (closes SF #1701231).
-
- * mh-mime.el (mm-decode-body): Remove explicit autoload of
- mh-alias-expand.
-
- * mh-alias.el (mh-alias-expand): Set up automatic autoload of
- mh-alias-expand.
-
-2007-08-20 Jeffrey C Honig <jch@honig.net>
-
- * mh-mime.el (message-options-set): Add missing autoloads from my
- last change.
-
- * mh-comp.el (mh-forward): When forwarding with mml, messages are
- no longer included in reverse order (closes SF #1730393).
-
- * mh-mime.el (mh-mml-forward-message): Forward messages as inline
- attachments (closes SF #1378993).
-
-2008-02-06 Richard Stallman <rms@gnu.org>
-
- * mh-seq.el (mh-make-seq, mh-seq-name): Use defsubst.
-
- * mh-acros.el (mh-do-in-gnu-emacs, mh-do-in-xemacs)
- (with-mh-folder-updating, mh-in-show-buffer)
- (mh-iterate-on-messages-in-region, mh-iterate-on-range)
- (mh-do-at-event-location): Add debug decls.
- (mh-seq-msgs): Use defsubst.
-
-2008-02-05 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-e.el (mh-scan-format-file-check, mh-adaptive-cmd-note-flag-check):
- * mh-xface.el (mh-x-image-url-cache-canonicalize):
- Replace `legal' with `valid'.
-
-2007-08-19 Jeffrey C Honig <jch@honig.net>
-
- * mh-e.el (mh-invisible-header-fields-internal): We want to show
- Comments: and hide Comment:, not the other way around.
-
- * mh-mime.el (mh-mml-to-mime): GPG requires e-mail addresses, not
- aliases. So resolve aliases before passing addresses to GPG/PGP
- (closes SF #649226).
-
- * mh-e.el (mh-invisible-header-fields-internal): Update with all
- the entries from
- http://people.dsv.su.se/~jpalme/ietf/mail-headers, plus some of my
- own. I added attributions to entries we already had that did not
- list an RFC.
-
-2007-08-08 Glenn Morris <rgm@gnu.org>
-
- * mh-folder.el, mh-letter.el, mh-show.el: Replace `iff' in
- doc-strings and comments.
-
-2007-07-25 Glenn Morris <rgm@gnu.org>
-
- * Relicense all FSF files to GPLv3 or later.
-
-2007-07-11 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-display-color-cells): Fix on XEmacs 21.5b28.
- Thanks to Henrique Martins for the help (closes SF #1749774).
-
-2007-06-06 Juanma Barranquero <lekktu@gmail.com>
-
- * mh-mime.el (mh-mh-directive-present-p):
- * mh-search.el (mh-index-group-by-folder): Fix typos in docstrings.
-
-2006-11-14 Bill Wohler <wohler@newt.com>
-
- * mh-xface.el (mh-x-image-url-cache-canonicalize): Add `*' to
- reserved Windows filename characters (closes SF #1396499).
-
-2006-11-13 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.0.3.
-
- * mh-e.el (Version, mh-version): Update for release 8.0.3.
-
- * mh-e.el (mh-alias-local-users): Boolean docstrings should start
- with "Non-nil means". Perhaps this option should have a -flag
- appended.
- (mh-junk-background): Sync docstring with manual.
-
- * mh-junk.el (mh-spamassassin-blacklist, mh-bogofilter-blacklist)
- (mh-spamprobe-blacklist): Sync docstring with manual.
-
-2006-11-11 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-junk.el (mh-spamassassin-blacklist, mh-spamassassin-whitelist):
- Use mh-junk-background consistently in call-process calls.
- (mh-bogofilter-blacklist, mh-bogofilter-whitelist)
- (mh-spamprobe-blacklist, mh-spamprobe-whitelist):
- Use with-current-buffer so the right thing happens if
- mh-junk-background is t (closes SF #1594802).
-
- * mh-e.el (mh-junk-background): Document that On value is 0;
- t may be used for debugging.
-
-2006-11-10 Andreas Schwab <schwab@suse.de>
-
- * mh-e.el (mh-draft-folder): Avoid starting sentence with "nil".
-
-2006-11-10 Glenn Morris <rgm@gnu.org>
-
- * mh-e.el (mh-draft-folder): Doc fix (Nil -> nil).
-
-2006-09-25 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-junk.el (mh-spamassassin-whitelist): Add two missing
- quotation marks, so that the last two arguments of sa-learn
- are separated properly (closes SF #1565460).
- (mh-spamassassin-blacklist): In example .procmailrc, add
- PATH element to find mhparam on Debian.
-
-2006-09-24 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-comp.el (mh-send-args): Initialize to "" instead of nil
- so that we always have a valid string for split-string even if
- nothing is added in mh-send-letter (closes SF #1564742).
-
-2006-07-03 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.0.2.
-
- * mh-e.el (Version, mh-version): Update for release 8.0.2.
-
-2006-07-03 Ted Phelps <phelps@gnusto.com> (tiny change)
-
- * mh-tool-bar.el (mh-tool-bar-define): Fix XEmacs' vector-list so
- it refers to the icons in mh-xemacs-icon-map instead of trying to
- declare the icons in situ. This allows mh-tool-bar.el to be
- compiled under XEmacs. Remove initial value for
- mh-tool-bar-folder-buttons, mh-tool-bar-show-buttons,
- mh-tool-bar-letter-buttons. The MH-E icons now appear in XEmacs.
- In mh-tool-bar-init, check for mh-xemacs-use-tool-bar-flag sooner.
- This allows MH-E to be used in XEmacs in a tty (closes SF #1506846).
-
-2006-07-03 Bill Wohler <wohler@newt.com>
-
- * mh-e.el: Require mh-buffers and mh-compat before mh-xemacs now
- that mh-xemacs needs functions in mh-compat.
-
-2006-06-29 Bill Wohler <wohler@newt.com>
-
- * mh-search.el (mh-search, mh-index-group-by-folder): Add "the" in
- loop construct to be consistent with other loops, and because
- edebug doesn't work without it.
-
-2006-06-29 Ted Phelps <phelps@gnusto.com> (tiny change)
-
- * mh-search.el (mh-folder-exists-p): Strip + from folder to avoid
- redundant +s in regexp (closes SF #1514424).
-
-2006-06-29 Sergey Poznyakoff <gray@Mirddin.farlep.net> (tiny change)
-
- * mh-mime.el (mh-mime-save-parts): Add -store option to
- mhn (closes SF #1513140).
-
-2006-06-20 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.0.1.
-
- * mh-e.el (Version, mh-version): Update for release 8.0.1.
-
-2006-06-15 Bill Wohler <wohler@newt.com>
-
- * mh-search.el (mh-index-new-folder): Use -2 suffix instead of <2>
- suffix for folder names, as <> are illegal filename characters on
- Windows (closes SF #1507002).
-
-2006-06-05 Jacob Morzinski <morzinski@MIT.EDU> (tiny change)
-
- * mh-comp.el (mh-send-uses-spost): New variable.
- (mh-send-letter): Do not use -msgid and -mime if
- mh-send-uses-spost is t (closes SF #1486726).
-
-2006-06-02 Bill Wohler <wohler@newt.com>
-
- * mh-search.el (mh-folder-exists-p): Change test from an empty buffer,
- to one that contains the actual folder, since GNU mailutils' folder
- command displays output if the folder doesn't exist (closes SF
- #1499712).
-
-2006-05-06 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 8.0.
-
- * mh-e.el (Version, mh-version): Update for release 8.0.
-
-2006-05-05 Bill Wohler <wohler@newt.com>
-
- * mh-e.el: Update commentary.
-
-2006-04-28 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 7.95.
-
- * mh-e.el (Version, mh-version): Update for release 7.95.
-
-2006-04-26 Eric Ding <ericding@alum.mit.edu>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add entry
- "X-Provags-ID:".
-
-2006-04-25 Bill Wohler <wohler@newt.com>
-
- * mh-letter.el (mh-folder-expand-at-point): Fix folder completion.
- Folders returned by mh-folder-completion-function no longer need
- adornment (closes SF #1476270).
-
-2006-04-21 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2006-04-21 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 7.94.
-
- * mh-e.el (Version, mh-version): Update for release 7.94.
-
-2006-04-21 Bill Wohler <wohler@newt.com>
-
- * mh-letter.el (mh-insert-letter): If a message number isn't
- given, throw an error rather than using a potentially incorrect
- message number (closes SF #1473729). In addition, use the cur
- message if mh-sent-from-msg is nil (when sending a message, in
- contrast to replying). Move conversion of int to string into
- interactive stanza so body can assume variables are of proper
- type.
-
-2006-04-20 Bill Wohler <wohler@newt.com>
-
- * mh-tool-bar.el (image-load-path): Define to shush compiler.
- (mh-buffer-exists-p): Move inside mh-do-in-gnu-emacs since it
- isn't used outside of it.
- (mh-tool-bar-folder-buttons-init, mh-tool-bar-letter-buttons-init):
- Update load-path/image-load-path before setting buttons.
- This code used to be in mh-folder-mode/mh-letter-mode but this was
- the wrong place since mh-tool-bar-*-buttons-init can also be called
- when customizing the buttons.
- (mh-tool-bar-update): New function which updates tool-bar-map in
- all of the MH-E buffers after customizing the buttons (closes SF
- #1452718).
- (mh-tool-bar-folder-buttons-set, mh-tool-bar-letter-buttons-set):
- Call it (closes SF #1452718).
-
- * mh-folder.el (mh-folder-buttons-init-flag): Delete.
- Use mh-folder-tool-bar-map instead.
- (image-load-path): Delete. No longer used.
- (mh-folder-mode): Move setting of image-load-path into
- mh-tool-bar-folder-buttons-init.
-
- * mh-letter.el (mh-letter-buttons-init-flag): Delete.
- Use mh-letter-tool-bar-map instead.
- (image-load-path): Delete. No longer used.
- (mh-letter-mode): Move setting of image-load-path into
- mh-tool-bar-letter-buttons-init.
-
- * mh-seq.el (mh-narrow-to-seq, mh-widen): Use with-current-buffer
- instead of set-buffer.
-
-2006-04-19 Bill Wohler <wohler@newt.com>
-
- * mh-tool-bar.el (mh-tool-bar-define): Fix enable-expr so that one
- can permanently disable a button (such as a separator) with nil.
-
-2006-04-18 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (defcustom-mh, defface-mh, defgroup-mh, mh-face-data)
- (mh-strip-package-version, mh-face-data, mh-inherit-face-flag)
- (mh-min-colors-defined-flag): Do not unbind these macros and
- variables. Nice idea, but too many nasty side-effects. These
- macros are needed by [Cc]ustom-make-dependencies when creating the
- MH-E customization groups in mh-cus-load.el. These disappeared
- when the macros above were introduced. Besides, if a developer
- were to try to show the help for a macro or variable they were
- looking at and got [No match] when they did so, that would be bad.
-
-2006-04-17 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-insert-x-mailer): Strip build number from
- version in X-Mailer field (closes SF #1466481).
-
- * mh-acros.el (mh-defun-compat): Rename to defun-mh in order that
- variables and functions with the same name are found correctly by
- find-func (invoked by clicking on the filename link in the *Help*
- buffer).
- (mh-defmacro-compat): Rename to defmacro-mh. Ditto.
-
- * mh-e.el (mh-defgroup): Rename to defgroup-mh. Ditto.
- (mh-defcustom): Rename to defcustom-mh. Ditto.
- (mh-defface): Rename to defface-mh. Ditto.
- (mh-font-lock-add-keywords): Make changes according to these
- renamings.
-
- * mh-e.el, mh-compat.el, mh-gnus.el: Use the new names (closes SF
- #1472029).
-
- * mh-utils.el (mh-sub-folders-actual): Mention that folder must
- have been processed by mh-normalize-folder-name.
- (mh-folder-completion-function): Handle completion of folders with
- absolute names. Also, when flag is t, display complete folder name
- to provide proper highlighting in Emacs 22 now that
- minibuffer-completing-file-name is nil (closes SF #1470518).
- (mh-folder-completing-read): No longer set
- minibuffer-completing-file-name to t. This was causing "Can't set
- current directory errors" when browsing absolute file names.
- Another benefit of this change is that SPC can be used for
- completion again (closes SF #1470518).
-
-2006-04-15 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-font-lock-add-keywords): Fix typo in docstring.
-
-2006-04-14 Bill Wohler <wohler@newt.com>
-
- * mh-funcs.el (view-exit-action): No need to wrap defvar with
- eval-when-compile when shushing compiler.
-
- * mh-mime.el (mh-identity-pgg-default-user-id): Ditto.
-
- * mh-seq.el (view-exit-action): Ditto.
-
- * mh-show.el (font-lock-auto-fontify): Ditto.
-
- * mh-utils.el (mh-speed-flists-cache): Ditto.
-
- * mh-acros.el (struct, x, y): No need to wrap defvar with
- eval-when-compile when shushing compiler, even when
- mh-do-in-xemacs or another construct is used.
-
- * mh-comp.el (sendmail-coding-system): Ditto.
-
- * mh-e.el (mark-active): Ditto.
-
- * mh-folder.el (desktop-save-buffer, font-lock-auto-fontify)
- (image-load-path, font-lock-defaults): Ditto.
-
- * mh-letter.el (image-load-path, font-lock-defaults): Ditto.
-
- * mh-mime.el (dots, type, ov)
- (mm-verify-function-alist, mm-decrypt-function-alist)
- (pressed-details): Ditto.
-
- * mh-search.el (pick-folder, mh-do-in-xemacs)
- (mh-mairix-folder, mh-flists-search-folders)
- (which-func-mode, mh-speed-flists-inhibit-flag): Ditto.
-
- * mh-seq.el (tool-bar-mode): Ditto.
-
- * mh-utils.el (completion-root-regexp)
- (minibuffer-completing-file-name): Ditto.
-
- * mh-xface.el (default-enable-multibyte-characters): Ditto.
-
- * mh-compat.el (mh-font-lock-add-keywords): New alias for
- font-lock-add-keywords. Returns nil on XEmacs.
-
- * mh-e.el: Add MH-E function and variable keywords such as
- mh-defun-compat and mh-defcustom to font-lock-keywords.
-
-2006-04-13 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (customize-package-emacs-version-alist)
- (mh-e, mh-alias, mh-folder, mh-folder-selection)
- (mh-identity, mh-inc, mh-junk, mh-letter, mh-ranges)
- (mh-scan-line-formats, mh-search, mh-sending-mail)
- (mh-sequences, mh-show, mh-speedbar, mh-thread, mh-tool-bar)
- (mh-hooks, mh-faces, mh-alias-completion-ignore-case-flag)
- (mh-alias-expand-aliases-flag, mh-alias-flash-on-comma)
- (mh-alias-insert-file, mh-alias-insertion-location)
- (mh-alias-local-users, mh-alias-local-users-prefix)
- (mh-alias-passwd-gecos-comma-separator-flag)
- (mh-new-messages-folders, mh-ticked-messages-folders)
- (mh-large-folder, mh-recenter-summary-flag)
- (mh-recursive-folders-flag, mh-sortm-args)
- (mh-default-folder-for-message-function)
- (mh-default-folder-list, mh-default-folder-must-exist-flag)
- (mh-default-folder-prefix, mh-identity-list)
- (mh-auto-fields-list, mh-auto-fields-prompt-flag)
- (mh-identity-default, mh-identity-handlers, mh-inc-prog)
- (mh-inc-spool-list, mh-junk-background, mh-junk-disposition)
- (mh-junk-program, mh-compose-insertion)
- (mh-compose-skipped-header-fields)
- (mh-compose-space-does-completion-flag)
- (mh-delete-yanked-msg-window-flag)
- (mh-extract-from-attribution-verb, mh-ins-buf-prefix)
- (mh-letter-complete-function, mh-letter-fill-column)
- (mh-mml-method-default, mh-signature-file-name)
- (mh-signature-separator-flag, mh-x-face-file)
- (mh-yank-behavior, mh-interpret-number-as-range-flag)
- (mh-adaptive-cmd-note-flag, mh-scan-format-file, mh-scan-prog)
- (mh-search-program, mh-compose-forward-as-mime-flag)
- (mh-compose-letter-function, mh-compose-prompt-flag)
- (mh-forward-subject-format, mh-insert-x-mailer-flag)
- (mh-redist-full-contents-flag, mh-reply-default-reply-to)
- (mh-reply-show-message-flag)
- (mh-refile-preserves-sequences-flag, mh-tick-seq)
- (mh-update-sequences-after-mh-show-flag)
- (mh-bury-show-buffer-flag, mh-clean-message-header-flag)
- (mh-decode-mime-flag)
- (mh-display-buttons-for-alternatives-flag)
- (mh-display-buttons-for-inline-parts-flag)
- (mh-do-not-confirm-flag, mh-fetch-x-image-url)
- (mh-graphical-smileys-flag, mh-graphical-emphasis-flag)
- (mh-highlight-citation-style, mh-invisible-header-fields)
- (mh-invisible-header-fields-default, mh-lpr-command-format)
- (mh-max-inline-image-height, mh-max-inline-image-width)
- (mh-mhl-format-file, mh-mime-save-parts-default-directory)
- (mh-print-background-flag, mh-show-maximum-size)
- (mh-show-use-xface-flag, mh-store-default-directory)
- (mh-summary-height, mh-speed-update-interval)
- (mh-show-threads-flag, mh-tool-bar-search-function)
- (mh-defcustom, mh-after-commands-processed-hook)
- (mh-alias-reloaded-hook, mh-before-commands-processed-hook)
- (mh-before-quit-hook, mh-before-send-letter-hook)
- (mh-delete-msg-hook, mh-find-path-hook, mh-folder-mode-hook)
- (mh-forward-hook, mh-inc-folder-hook, mh-insert-signature-hook)
- (mh-kill-folder-suppress-prompt-hooks, mh-letter-mode-hook)
- (mh-mh-to-mime-hook, mh-search-mode-hook, mh-quit-hook)
- (mh-refile-msg-hook, mh-show-hook, mh-show-mode-hook)
- (mh-unseen-updated-hook, mh-folder-address, mh-folder-body)
- (mh-folder-cur-msg-number, mh-folder-date, mh-folder-deleted)
- (mh-folder-followup, mh-folder-msg-number, mh-folder-refiled)
- (mh-folder-sent-to-me-hint, mh-folder-sent-to-me-sender)
- (mh-folder-subject, mh-folder-tick, mh-folder-to)
- (mh-letter-header-field, mh-search-folder, mh-show-cc)
- (mh-show-date, mh-show-from, mh-show-header, mh-show-pgg-bad)
- (mh-show-pgg-good, mh-show-pgg-unknown, mh-show-signature)
- (mh-show-subject, mh-show-to, mh-show-xface)
- (mh-speedbar-folder, mh-speedbar-folder-with-unseen-messages)
- (mh-speedbar-selected-folder)
- (mh-speedbar-selected-folder-with-unseen-messages): Use dotted
- notation in :package-version keyword.
-
-2006-04-07 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-path, mh-variant): Define with mh-defcustom and add
- :package-version keyword.
-
-2006-03-31 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-strip-package-version): Move before use to avoid
- compiler error. Make macro, also to avoid compiler error.
- (mh-defface-compat): Incorporate body into mh-face-data and
- delete.
-
-2006-03-30 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-defcustom, mh-defface, mh-defgroup): Macros to
- remove new :package-version keyword in older settings.
- (customize-package-emacs-version-alist): Add MH-E version to Emacs
- version mappings.
- (mh-e, mh-alias, mh-folder, mh-folder-selection)
- (mh-identity, mh-inc, mh-junk, mh-letter, mh-ranges)
- (mh-scan-line-formats, mh-search, mh-sending-mail)
- (mh-sequences, mh-show, mh-speedbar, mh-thread, mh-tool-bar)
- (mh-hooks, mh-faces): Add :package-version keyword to these
- groups (closes SF #1452724).
- (mh-alias-completion-ignore-case-flag)
- (mh-alias-expand-aliases-flag, mh-alias-flash-on-comma)
- (mh-alias-insert-file, mh-alias-insertion-location)
- (mh-alias-local-users, mh-alias-local-users-prefix)
- (mh-alias-passwd-gecos-comma-separator-flag)
- (mh-new-messages-folders, mh-ticked-messages-folders)
- (mh-large-folder, mh-recenter-summary-flag)
- (mh-recursive-folders-flag, mh-sortm-args)
- (mh-default-folder-for-message-function)
- (mh-default-folder-list, mh-default-folder-must-exist-flag)
- (mh-default-folder-prefix, mh-identity-list)
- (mh-auto-fields-list, mh-auto-fields-prompt-flag)
- (mh-identity-default, mh-identity-handlers, mh-inc-prog)
- (mh-inc-spool-list, mh-junk-background, mh-junk-disposition)
- (mh-junk-program, mh-compose-insertion)
- (mh-compose-skipped-header-fields)
- (mh-compose-space-does-completion-flag)
- (mh-delete-yanked-msg-window-flag)
- (mh-extract-from-attribution-verb, mh-ins-buf-prefix)
- (mh-letter-complete-function, mh-letter-fill-column)
- (mh-mml-method-default, mh-signature-file-name)
- (mh-signature-separator-flag, mh-x-face-file)
- (mh-yank-behavior, mh-interpret-number-as-range-flag)
- (mh-adaptive-cmd-note-flag, mh-scan-format-file, mh-scan-prog)
- (mh-search-program, mh-compose-forward-as-mime-flag)
- (mh-compose-letter-function, mh-compose-prompt-flag)
- (mh-forward-subject-format, mh-insert-x-mailer-flag)
- (mh-redist-full-contents-flag, mh-reply-default-reply-to)
- (mh-reply-show-message-flag)
- (mh-refile-preserves-sequences-flag, mh-tick-seq)
- (mh-update-sequences-after-mh-show-flag)
- (mh-bury-show-buffer-flag, mh-clean-message-header-flag)
- (mh-decode-mime-flag)
- (mh-display-buttons-for-alternatives-flag)
- (mh-display-buttons-for-inline-parts-flag)
- (mh-do-not-confirm-flag, mh-fetch-x-image-url)
- (mh-graphical-smileys-flag, mh-graphical-emphasis-flag)
- (mh-highlight-citation-style, mh-invisible-header-fields)
- (mh-invisible-header-fields-default, mh-lpr-command-format)
- (mh-max-inline-image-height, mh-max-inline-image-width)
- (mh-mhl-format-file, mh-mime-save-parts-default-directory)
- (mh-print-background-flag, mh-show-maximum-size)
- (mh-show-use-xface-flag, mh-store-default-directory)
- (mh-summary-height, mh-speed-update-interval)
- (mh-show-threads-flag, mh-tool-bar-search-function):
- Add :package-version keyword to these options (closes SF #1452724).
- (mh-after-commands-processed-hook)
- (mh-alias-reloaded-hook, mh-before-commands-processed-hook)
- (mh-before-quit-hook, mh-before-send-letter-hook)
- (mh-delete-msg-hook, mh-find-path-hook, mh-folder-mode-hook)
- (mh-forward-hook, mh-inc-folder-hook)
- (mh-insert-signature-hook)
- (mh-kill-folder-suppress-prompt-hooks, mh-letter-mode-hook)
- (mh-mh-to-mime-hook, mh-search-mode-hook, mh-quit-hook)
- (mh-refile-msg-hook, mh-show-hook, mh-show-mode-hook)
- (mh-unseen-updated-hook): Add :package-version keyword to these
- hooks (closes SF #1452724).
- (mh-min-colors-defined-flag)
- (mh-folder-address, mh-folder-body, mh-folder-cur-msg-number)
- (mh-folder-date, mh-folder-deleted, mh-folder-followup)
- (mh-folder-msg-number, mh-folder-refiled)
- (mh-folder-sent-to-me-hint, mh-folder-sent-to-me-sender)
- (mh-folder-subject, mh-folder-tick, mh-folder-to)
- (mh-letter-header-field, mh-search-folder, mh-show-cc)
- (mh-show-date, mh-show-from, mh-show-header, mh-show-pgg-bad)
- (mh-show-pgg-good, mh-show-pgg-unknown, mh-show-signature)
- (mh-show-subject, mh-show-to, mh-show-xface)
- (mh-speedbar-folder, mh-speedbar-folder-with-unseen-messages)
- (mh-speedbar-selected-folder)
- (mh-speedbar-selected-folder-with-unseen-messages):
- Add :package-version keyword to these faces (closes SF #1452724).
-
- * mh-tool-bar.el (mh-tool-bar-define): Add commented-out
- :package-version keywords (closes SF #1452724).
-
-2006-03-28 Bill Wohler <wohler@newt.com>
-
- * mh-tool-bar.el: Use clipboard-kill-region,
- clipboard-kill-ring-save, and clipboard-yank instead of undo,
- kill-region, and menu-bar-kill-ring-save respectively.
- In MH-Letter mode, move save-buffer and mh-fully-kill-draft icons in
- front of mh-compose-insertion to be consistent with other mailers,
- such as Evolution. In MH-Folder mode, move vanilla reply icon to
- the left of the other reply icons. Use mail/inbox icon instead of
- mail, next-page instead of page-down, delete instead of close,
- mail/move instead of mail/refile, data-save instead of execute,
- mail/flag-for-followup instead of highlight, contact instead of
- mail/alias, open instead of fld-open, zoom-out instead of widen.
-
- * mh-folder.el (mh-execute-commands, mh-rescan-folder):
- * mh-funcs.el (mh-pack-folder): Sync docstrings with manual.
-
-2006-03-27 Eric Ding <ericding@alum.mit.edu>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add entries
- "X-AOL-IP:" and "X-MB-Message-" (AOL WebMail).
-
-2006-03-19 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-reply): Sync docstring with manual.
-
- * mh-compat.el (mh-image-load-path-for-library): Shorten first line in
- docstring.
-
-2006-03-17 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-image-load-path-for-library): Minor docstring fix.
-
-2006-03-16 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-send-letter): Use split-string to break up
- mh-send-args (closes SF #1448604).
- (mh-compose-and-send-mail): Use run-hook-with-args for
- mh-compose-letter-function.
-
- * mh-e.el (mh-list-to-string-1): Use dolist.
-
- * mh-compat.el (mh-image-load-path-for-library): Prefer user's images.
-
-2006-03-15 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-image-load-path-for-library): Fix example by
- not recommending that one binds image-load-path. Just defvar it to
- placate compiler and only use it if previously defined.
-
- * mh-e.el (image-load-path): Don't bind!
-
- * mh-folder.el (mh-folder-mode): Only use image-load-path if
- previously defined.
-
- * mh-letter.el (mh-letter-mode): Ditto.
-
- * mh-utils.el (mh-logo-display): Ditto.
-
-2006-03-14 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-image-load-path-for-library):
- Incorporate changes from image-load-path-for-library, which are:
- (image-load-path-for-library): Pass value of path rather than
- symbol. Always return list of directories. Guarantee that image
- directory comes first.
-
- * mh-e.el (image-load-path): Define on those Emacsen that lack it
- to avoid compile and run-time errors.
-
- * mh-folder.el (mh-folder-mode): Use new idiom for setting
- image-load-path.
-
- * mh-letter.el (mh-letter-mode): Ditto.
-
- * mh-utils.el (mh-logo-display): Ditto.
-
-2006-03-12 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-folder-list): Fix docstring (closes SF
- #1448498).
-
-2006-03-10 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-replace-regexp-in-string): Pass the literal
- flag to replace-in-string. This was badly needed by
- mh-quote-pick-expr in order to properly quote subjects when using
- / s on XEmacs (closes SF #1447598).
- (mh-image-load-path-for-library): Merged changes from Reiner.
- Add no-error argument. If path t, just return directory.
-
- * mh-e.el (mh-profile-component): Drop `s' from mhparam
- -components for Mailutils compatibility (closes SF #1446985).
-
-2006-03-06 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2006-03-05 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-search.el (mh-index-update-single-msg): Fix a bug in the
- handling of duplicate messages. The test in cond was too strong
- and wasn't catching the case where origin-map was nil.
-
-2006-03-05 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 7.93.
-
- * mh-e.el (Version, mh-version): Update for release 7.93.
-
-2006-03-05 Bill Wohler <wohler@newt.com>
-
- * mh-folder.el (mh-folder-mode): Drop 'load-path argument when
- calling mh-image-load-path-for-library since this is the default.
-
- * mh-letter.el (mh-letter-mode): Ditto.
-
- * mh-utils.el (mh-logo-display): Ditto.
-
-2006-03-04 Bill Wohler <wohler@newt.com>
-
- * mh-compat.el (mh-image-load-path-for-library): Move here from
- mh-utils.el and wrap with mh-defun-compat since this function will
- be soon added to image.el.
-
- * mh-utils.el (mh-image-load-path-for-library): Move to mh-compat.el.
- (mh-normalize-folder-name): Add return-nil-if-folder-empty
- argument which is useful when calling mh-normalize-folder-name to
- process the folder argument for the folders command.
- (mh-sub-folders): Use new flag to mh-normalize-folder-name to make
- this function more robust. It could too easily list the folders in /.
- (mh-folder-list): Fix a couple of problems pointed out by Thomas
- Baumann. Set folder to nil if empty. Don't append "/" if folder nil.
-
-2006-03-03 Bill Wohler <wohler@newt.com>
-
- * mh-folder.el (mh-folder-mode): Rename mh-image-load-path to
- mh-image-load-path-for-library.
-
- * mh-letter.el (mh-letter-mode): Rename mh-image-load-path to
- mh-image-load-path-for-library.
-
- * mh-utils.el (mh-image-load-path): Rename to
- mh-image-load-path-for-library. Add example to docstring. Rename
- local variable mh-image-directory to image-directory. Move error
- checks to default case in cond and simplify.
-
- * mh-comp.el (mh-send-letter, mh-insert-auto-fields):
- Sync docstrings with manual.
-
-2006-03-02 Bill Wohler <wohler@newt.com>
-
- * mh-folder.el (mh-tool-bar-init): Autoload.
- (mh-folder-mode): Call mh-tool-bar-init conditionally in XEmacs.
- Set scoped variables image-load-path and load-path with updated
- mh-image-load-path before calling mh-tool-bar-folder-buttons-init.
-
- * mh-letter.el (mh-tool-bar-init): Autoload.
- (mh-letter-mode): Call mh-tool-bar-init conditionally in XEmacs.
- Set scoped variables image-load-path and load-path with updated
- mh-image-load-path before calling mh-tool-bar-letter-buttons-init.
-
- * mh-show.el (mh-tool-bar-init): Autoload.
- (mh-show-mode): Perform tool bar stuff conditionally in XEmacs and
- GNU Emacs.
-
- * mh-tool-bar.el (mh-tool-bar-define): Don't quote stuff in error
- messages per conventions.
- (mh-tool-bar-folder-buttons-init)
- (mh-tool-bar-letter-buttons-init): Don't call mh-image-load-path.
- (mh-tool-bar-define call): Format.
-
- * mh-utils.el (mh-image-directory)
- (mh-image-load-path-called-flag): Delete.
- (mh-image-load-path): Incorporate changes from Gnus team.
- Biggest changes are that it no longer uses/sets mh-image-directory or
- mh-image-load-path-called-flag, and returns the updated path
- rather than change it.
- (mh-logo-display): Change usage of mh-image-load-path.
-
-2006-02-28 Bill Wohler <wohler@newt.com>
-
- * mh-limit.el (mh-narrow-to-cc, mh-narrow-to-from)
- (mh-narrow-to-subject, mh-narrow-to-to): Fix inability to narrow
- to subjects with special characters by quoting regular expression
- characters in pick expression derived from existing subjects and
- other fields (closes SF #1432548).
- (mh-narrow-to-subject): Remove Re: string from subject so that
- pick can find originating message (closes SF #1438369).
-
- * mh-utils.el (mh-image-load-path): Rename variable to
- mh-image-directory.
- (mh-image-load-path): Access mh-image-directory instead of
- mh-image-load-path.
- (mh-folder-list): Fix problem with passing in a folder and getting
- nothing back. Fix problem with passing in empty string and getting
- the entire filesystem (or infinite loop). Don't append slash to
- folder. These fixes fix problems observed with the pick search.
- Thanks to Thomas Baumann for the help (closes SF #1435381).
- (mh-pick-regexp-chars, mh-quote-pick-expr): New variable and
- function for quoting pick regular expression characters (closes SF
- #1432548).
-
-2006-02-27 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-default-folder-for-message-function): Sync docstring
- with manual.
-
- * mh-mime.el (mh-minibuffer-read-type): Delete comment in
- docstring about obsolete variable mh-mime-content-types.
-
- * mh-e.el (mh-variant): Sync docstring with manual.
- (cus-face): Require as it is needed by mh-inherit-face-flag.
-
- * mh-compat.el (mh-display-color-cells): Return 2 if
- device-color-cells returns nil (closes SF #1436924).
-
- * mh-e.el (mh-compiling-flag): Delete. No longer needed by
- mh-display-color-cells.
-
-2006-02-21 Eric Ding <ericding@alum.mit.edu>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add entry
- "X-Sasl-enc:".
-
-2006-02-20 Eric Ding <ericding@alum.mit.edu>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add entries
- "X-Authenticated-Sender:", "X-Barracuda-", "X-EFL-Spamscore",
- "X-IronPort-AV:", "X-Mail-from:", "X-Mailman-Approved-At:",
- "X-Resolved-to:", and "X-SA-Exim". Fixed "X-Bugzilla-" and
- "X-Roving-" by removing unnecessary "*" at end.
-
-2006-02-19 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (mh-address-mail-regexp)
- (mh-goto-address-find-address-at-point): Delete copies from
- goto-addr.el.
- (mh-alias-suggest-alias): Use goto-address-mail-regexp instead of
- mh-address-mail-regexp.
- (mh-alias-add-address-under-point):
- Use goto-address-find-address-at-point instead of
- mh-goto-address-find-address-at-point.
-
- * mh-e.el (mh-show-use-goto-addr-flag): Delete.
-
- * mh-show.el (mh-show-mode): Mention goto-address-highlight-p in
- docstring.
- (mh-show-addr): Call goto-address unconditionally. User should use
- goto-address-highlight-p instead of mh-show-use-goto-addr-flag.
-
-2006-02-18 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2006-02-18 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 7.92.
-
- * mh-e.el (Version, mh-version): Update for release 7.92.
-
-2006-02-17 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folder-msg-number): Use purple on low-color, light
- backgrounds per Mark's suggestion.
-
- * mh-utils.el (mh-image-load-path): Fix problem that images on
- load-path or image-load-path would win over relative paths (newer
- MH-E or Emacs distribution).
-
-2006-02-16 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-inherit-face-flag): New variable. Non-nil means that
- the defface :inherit keyword is available.
- (mh-face-data): New variable (contains all face specs) and
- function (accessor).
- (mh-folder-address, mh-folder-body, mh-folder-cur-msg-number)
- (mh-folder-date, mh-folder-deleted, mh-folder-followup)
- (mh-folder-msg-number, mh-folder-refiled)
- (mh-folder-sent-to-me-hint, mh-folder-sent-to-me-sender)
- (mh-folder-subject, mh-folder-tick, mh-folder-to)
- (mh-search-folder, mh-letter-header-field, mh-show-cc)
- (mh-show-date, mh-show-from)
- (mh-show-header, mh-show-pgg-bad, mh-show-pgg-good)
- (mh-show-pgg-unknown, mh-show-signature, mh-show-subject)
- (mh-show-to, mh-show-xface, mh-speedbar-folder)
- (mh-speedbar-folder-with-unseen-messages)
- (mh-speedbar-selected-folder)
- (mh-speedbar-selected-folder-with-unseen-messages):
- Use mh-face-data.
-
- * mh-utils.el (mh-image-load-path): The variables image-load-path
- or load-path would not get updated if user set mh-image-load-path.
- Moved tests and add-to-list calls outside of cond so they are
- applied consistently, even if they are redundant in some
- circumstances. Efficiency isn't a concern here. Made error
- messages more user-friendly.
-
-2006-02-15 Peter S Galbraith <psg@debian.org>
-
- * mh-compat.el (mh-image-search-load-path): Compatibility code.
- Emacs 21 and XEmacs don't have `image-search-load-path'.
-
- * mh-utils.el (mh-image-load-path): Don't bail out on error if the
- images are already found.
-
-2006-02-10 Bill Wohler <wohler@newt.com>
-
- * mh-search.el (mh-search): Wrap code in (block mh-search ...)
- rather than use defun*. XEmacs cannot create a proper autoload for
- a defun*.
-
-2006-02-09 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-folder-list): Don't replace "/*$" with "/" since
- that causes an infinite loop on XEmacs.
-
- * mh-compat.el(mh-replace-regexp-in-string): Add missing regexp
- argument.
-
-2006-02-08 Peter S Galbraith <psg@debian.org>
-
- * mh-e.el (mh-invisible-header-fields-internal): Add entries
- "X-BrightmailFiltered:", "X-Brightmail-Tracker:" and "X-Hashcash".
-
-2006-02-04 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-inc-spool-list): Update example for Emacs 22 which
- has an emacsclient command that supports --eval. I had read that
- gnudoit was deprecated in favor of gnuclient anyway.
-
-2006-02-04 Eric Ding <ericding@alum.mit.edu>
-
- * mh-mime.el (mh-file-mime-type-substitutions): Add entries to
- handle OpenOffice documents.
-
-2006-02-03 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2006-02-03 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 7.91.
-
- * mh-e.el (Version, mh-version): Update for release 7.91.
-
-2006-02-03 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-image-load-path, mh-image-load-path-called-flag)
- (mh-image-load-path): Checkdoc fix. Docstring edits. Reduce scope
- of local variable mh-library-name.
-
- * mh-e.el (mh-folder-msg-number, mh-folder-refiled, mh-folder-to)
- (mh-show-cc, mh-show-date, mh-show-header): Replace (min-colors
- 88) with (min-colors 64) in face specifications so that MH-E still
- looks good on systems with fewer colors (such as Eric Ding's).
-
-2006-02-03 Peter S Galbraith <psg@debian.org>
-
- * mh-utils.el (mh-image-load-path): New variable to optionally
- hold the directory where MH-E images are stored. If nil, then
- the function `mh-image-load-path' will find it. This variable
- will be used for Debian packaging.
- (mh-image-load-path function): Use variable `mh-image-load-path'
- if non-nil and exists.
-
-2006-02-03 Mark D. Baushke <mdb@gnu.org>
-
- * mh-tool-bar.el: Add conditional require of 'tool-bar or 'toolbar
- for GNU Emacs or XEmacs to avoid void-variable tool-bar-map lisp
- errors if describe-bindings is called before tool-bar-mode is used.
-
-2006-02-03 Peter S Galbraith <psg@debian.org>
-
- * mh-compat.el (mh-url-unreserved-chars): Fix typo from
- `mh-url-unresrved-chars'.
-
-2006-02-02 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2006-02-02 Bill Wohler <wohler@newt.com>
-
- Release MH-E version 7.90.
-
- * mh-e.el (Version, mh-version): Update for release 7.90.
-
-2006-02-01 Bill Wohler <wohler@newt.com>
-
- * mh-search.el (which-func-mode): Shush compiler on Emacs 21 too.
-
- * mh-alias.el (mh-alias-gecos-name):
- Use mh-replace-regexp-in-string instead of replace-regexp-in-string.
- (crm, multi-prompt): Use mh-require instead of require.
- (mh-goto-address-find-address-at-point):
- Use mh-line-beginning-position and mh-line-end-position instead of
- line-beginning-position and line-end-position.
- Use mh-match-string-no-properties instead of
- match-string-no-properties.
-
- * mh-comp.el (mh-modify-header-field):
- Use mh-line-beginning-position and mh-line-end-position instead of
- line-beginning-position and line-end-position.
-
- * mh-compat.el (mailabbrev): Use mh-require instead of require.
- (mh-assoc-string, mh-display-completion-list, mh-face-foreground)
- (mh-face-background): Make docstring consistent.
- (mh-require, mh-cancel-timer, mh-display-color-cells)
- (mh-line-beginning-position, mh-line-end-position)
- (mh-match-string-no-properties, mh-replace-regexp-in-string)
- (mh-view-mode-enter): Move definition here from mh-xemacs.el and
- add mh- prefix since compatibility functions should have our
- package prefix (mh-) by Emacs convention and to avoid messing up
- checks for the same functions in other packages.
-
- * mh-e.el (mh-compiling-flag): Move mh-xemacs-compiling-flag here
- from mh-xemacs.el and rename.
- (mh-xargs): Use mh-line-beginning-position and
- mh-line-end-position instead of line-beginning-position and
- line-end-position.
- (mh-defface-compat): Use mh-display-color-cells instead of
- display-color-cells.
-
- * mh-folder.el (which-func): Use mh-require instead of require.
-
- * mh-funcs.el (mh-list-folders): Use mh-view-mode-enter instead of
- view-mode-enter.
-
- * mh-gnus.el (gnus-util, mm-bodies, mm-decode, mm-view, mml):
- Use mh-require instead of require.
-
- * mh-letter.el (mh-letter-header-end, mh-letter-mode)
- (mh-letter-next-header-field): Use mh-line-beginning-position and
- mh-line-end-position instead of line-beginning-position and
- line-end-position.
-
- * mh-limit.el (mh-subject-to-sequence-unthreaded):
- Use mh-match-string-no-properties instead of
- match-string-no-properties.
- (mh-narrow-to-header-field): Use mh-line-beginning-position and
- mh-line-end-position instead of line-beginning-position and
- line-end-position.
-
- * mh-mime.el (mh-mime-inline-part, mh-mm-display-part)
- (mh-mh-quote-unescaped-sharp, mh-mh-directive-present-p):
- Use mh-line-beginning-position and mh-line-end-position instead of
- line-beginning-position and line-end-position.
-
- * mh-search.el (which-func): Use mh-require instead of require.
- (mh-make-pick-template, mh-index-visit-folder)
- (mh-pick-parse-search-buffer, mh-swish-next-result)
- (mh-mairix-next-result, mh-namazu-next-result)
- (mh-pick-next-result, mh-grep-next-result)
- (mh-index-create-imenu-index, mh-index-match-checksum)
- (mh-md5sum-parser, mh-openssl-parser, mh-index-update-maps):
- Use mh-line-beginning-position and mh-line-end-position instead of
- line-beginning-position and line-end-position.
-
- * mh-seq.el (mh-list-sequences): Use mh-view-mode-enter instead of
- view-mode-enter.
- (mh-folder-size-flist, mh-parse-flist-output-line)
- (mh-add-sequence-notation): Use mh-line-beginning-position and
- mh-line-end-position instead of line-beginning-position and
- line-end-position.
-
- * mh-show.el (mh-show-addr): Use mh-require instead of require.
-
- * mh-speed.el (mh-folder-speedbar-menu-items, mh-speed-toggle)
- (mh-speed-view, mh-folder-speedbar-buttons)
- (mh-speed-highlight, mh-speed-goto-folder)
- (mh-speed-add-buttons, mh-speed-parse-flists-output)
- (mh-speed-invalidate-map, mh-speedbar-change-expand-button-char)
- (mh-speed-add-folder): Use mh-line-beginning-position and
- mh-line-end-position instead of line-beginning-position and
- line-end-position.
- (mh-speed-flists): Use mh-cancel-timer instead of cancel-timer.
-
- * mh-thread.el (mh-thread-find-children)
- (mh-thread-parse-scan-line, mh-thread-generate):
- Use mh-line-beginning-position and mh-line-end-position instead of
- line-beginning-position and line-end-position.
-
- * mh-utils.el (mh-colors-available-p): Use mh-display-color-cells
- instead of display-color-cells.
- (mh-folder-list): Use mh-replace-regexp-in-string instead of
- replace-regexp-in-string.
- (mh-sub-folders-actual, mh-letter-toggle-header-field-display):
- Use mh-line-beginning-position and mh-line-end-position instead of
- line-beginning-position and line-end-position.
-
- * mh-comp.el (mh-send-sub): Don't find components file in current
- directory--this seems to have been a side-effect of commenting out
- the use of an old mh-etc variable. Improve error message.
-
-2006-01-31 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el (mh-defun-compat, mh-defmacro-compat): Add name
- argument since compatibility functions should have our package
- prefix (mh-) by Emacs convention and to avoid messing up checks
- for the same functions in other packages. Use explicit argument
- instead of forming name by adding mh- prefix so that one can grep
- and find the definition.
-
- * mh-alias.el (mh-alias-local-users, mh-alias-reload)
- (mh-alias-expand, mh-alias-minibuffer-confirm-address):
- Use mh-assoc-string instead of assoc-string.
-
- * mh-compat.el (assoc-string): Rename to mh-assoc-string.
- (mh-mail-abbrev-make-syntax-table, mh-url-hexify-string):
- Move here from mh-utils.el.
- (mh-display-completion-list): Move here from mh-comp.el.
- (mh-face-foreground, mh-face-background): Move here from
- mh-xface.el.
- (mh-write-file-functions): Move here from mh-folder.el.
-
- * mh-folder.el (mh-write-file-functions-compat): Move to
- mh-compat.el and rename to mh-write-file-functions.
- (mh-folder-mode): Use the new name.
-
- * mh-gnus.el (gnus-local-map-property): Rename to
- mh-gnus-local-map-property.
- (mm-merge-handles): Rename to mh-mm-merge-handles.
- (mm-set-handle-multipart-parameter): Rename to
- mh-mm-set-handle-multipart-parameter.
- (mm-inline-text-vcard): Rename to mh-mm-inline-text-vcard.
- (mm-possibly-verify-or-decrypt): Rename to
- mh-mm-possibly-verify-or-decrypt.
- (mm-handle-multipart-ctl-parameter): Rename to
- mh-mm-handle-multipart-ctl-parameter.
- (mm-readable-p): Rename to mh-mm-readable-p.
- (mm-long-lines-p): Rename to mh-mm-long-lines-p.
- (mm-keep-viewer-alive-p): Rename to mh-mm-keep-viewer-alive-p.
- (mm-destroy-parts): Rename to mh-mm-destroy-parts.
- (mm-uu-dissect-text-parts): Rename to mh-mm-uu-dissect-text-parts.
- (mml-minibuffer-read-disposition): Rename to
- mh-mml-minibuffer-read-disposition.
-
- * mh-identity.el (mh-identity-field-handler): Use mh-assoc-string
- instead of assoc-string.
-
- * mh-mime.el (mh-mm-inline-media-tests, mh-mm-inline-message)
- (mh-mime-display, mh-mime-display-security)
- (mh-insert-mime-button, mh-insert-mime-security-button)
- (mh-handle-set-external-undisplayer)
- (mh-mime-security-press-button, mh-mime-security-show-details)
- (mh-mml-attach-file, mh-mime-cleanup)
- (mh-destroy-postponed-handles): Use new mh-* names for
- compatibility functions.
-
- * mh-utils.el (mail-abbrev-make-syntax-table): Move to
- mh-compat.el and rename to mh-mail-abbrev-make-syntax-table.
- (mh-beginning-of-word): Use the new name.
- (mh-get-field): Delete ancient alias.
-
- * mh-xface.el (mh-face-foreground-compat): Move to mh-compat.el
- and rename to mh-face-foreground.
- (mh-face-background-compat): Move to mh-compat.el
- and rename to mh-face-background.
- (mh-face-display-function): Use the new names.
- (mh-x-image-url-cache-canonicalize): Use mh-url-hexify-string
- instead of url-hexify-string.
- (url-unreserved-chars): Move to mh-compat.el and rename to
- mh-url-unreserved-chars.
- (url-hexify-string): Move to mh-compat.el and rename to
- mh-url-hexify-string.
-
- * mh-letter.el (mh-complete-word): Fix bug in call to
- mh-display-completion-list. Wrong argument was passed, so
- completions wouldn't show highlighted prefix.
-
-2006-01-29 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-scan-format-file-check): Allow any non-nil for
- mh-adaptive-cmd-note-flag.
-
- * mh-comp.el (sc-cite-original): Remove autoload of "sc" with old
- docstring. sc-cite-original is autoloaded via loaddefs.el for all
- supported versions. In addition, the package name "sc" has been
- made obsolete by "supercite since at least Emacs 21.
-
- * mh-scan.el (mh-note-copied, mh-note-printed): Reorganization
- revealed character constants that were still strings (closes SF
- #770772).
-
- * mh-comp.el (mh-letter-hide-all-skipped-fields)
- (mh-get-header-field): Move to mh-utils.el so that you can read
- messages without having to load mh-comp.el and mh-letter.el.
-
- * mh-letter.el (mh-hidden-header-keymap)
- (mh-letter-toggle-header-field-display)
- (mh-letter-skipped-header-field-p)
- (mh-letter-skip-leading-whitespace-in-header-field)
- (mh-letter-truncate-header-field): Move to mh-utils.el so that you
- can read messages without having to load mh-comp.el and
- mh-letter.el.
-
- * mh-utils.el (mh-get-header-field)
- (mh-letter-hide-all-skipped-fields)
- (mh-letter-skipped-header-field-p, mh-hidden-header-keymap)
- (mh-letter-toggle-header-field-display)
- (mh-letter-skip-leading-whitespace-in-header-field)
- (mh-letter-truncate-header-field): Move here from mh-comp.el and
- mh-letter.el so that you can read messages without having to load
- mh-comp.el and mh-letter.el.
-
- * mh-comp.el (mh-insert-fields): Handle nil values. Rmail, at
- least, will deliver them to us.
-
- * mh-e.el (mh-after-commands-processed-hook)
- (mh-before-commands-processed-hook): Specify what sort of requests
- in docstring.
-
- * mh-folder.el (mh-folder-mode): Use add-to-list to modify
- minor-mode-alias.
-
- * mh-letter.el (mh-letter-menu): Remove. Defvar no longer needed
- to shush compiler.
- (mh-letter-mode): Remove Mail menu.
-
-2006-01-29 Bill Wohler <wohler@newt.com>
-
- The Great Cleanup
- Remove circular dependencies. mh-e.el now includes few require
- statements and stands alone. Other files should need to require
- mh-e.el, which requires mh-loaddefs.el, plus variable-only files
- such as mh-scan.el.
- Remove unneeded require statements.
- Remove unneeded load statements, or replace them with non-fatal
- require statements.
- Break out components into their own files that were often spread
- between many files.
- As a result, many functions that are now only used within a single
- file no longer need to be autoloaded.
- Rearrange and provide consistent headings.
- Untabify.
-
- * mh-acros.el: Update commentary to reflect current usage.
- Add autoload cookies to all macros.
- (mh-require-cl): Merge docstring and comment.
- (mh-do-in-xemacs): Fix typo in docstring.
- (assoc-string): Move to new file mh-compat.el.
- (with-mh-folder-updating, mh-in-show-buffer)
- (mh-do-at-event-location, mh-seq-msgs): Move here from mh-utils.el.
- (mh-iterate-on-messages-in-region, mh-iterate-on-range): Move here
- from mh-seq.el.
-
- * mh-alias.el (mh-address-mail-regexp)
- (mh-goto-address-find-address-at-point): Move here from mh-utils.el.
- (mh-folder-line-matches-show-buffer-p): Move here from mh-e.el.
-
- * mh-buffers.el: Update descriptive text.
-
- * mh-comp.el (mh-note-repl, mh-note-forw, mh-note-dist): Move to
- new file mh-scan.el.
- (mh-yank-hooks, mh-to-field-choices, mh-position-on-field)
- (mh-letter-menu, mh-letter-mode-help-messages)
- (mh-letter-buttons-init-flag, mh-letter-mode)
- (mh-font-lock-field-data, mh-letter-header-end)
- (mh-auto-fill-for-letter, mh-to-field, mh-to-fcc)
- (mh-file-is-vcard-p, mh-insert-signature, mh-check-whom)
- (mh-insert-letter, mh-extract-from-attribution, mh-yank-cur-msg)
- (mh-filter-out-non-text, mh-insert-prefix-string)
- (mh-current-fill-prefix, mh-open-line, mh-complete-word)
- (mh-folder-expand-at-point, mh-letter-complete-function-alist)
- (mh-letter-complete, mh-letter-complete-or-space)
- (mh-letter-confirm-address, mh-letter-header-field-at-point)
- (mh-letter-next-header-field-or-indent)
- (mh-letter-next-header-field, mh-letter-previous-header-field)
- (mh-letter-skipped-header-field-p)
- (mh-letter-skip-leading-whitespace-in-header-field)
- (mh-hidden-header-keymap)
- (mh-letter-toggle-header-field-display-button)
- (mh-letter-toggle-header-field-display)
- (mh-letter-truncate-header-field, mh-letter-mode-map): Move to new
- file mh-letter.el.
- (mh-letter-mode-map, mh-sent-from-folder, mh-send-args)
- (mh-pgp-support-flag, mh-x-mailer-string)
- (mh-letter-header-field-regexp): Move to mh-e.el.
- (mh-goto-header-field, mh-goto-header-end)
- (mh-extract-from-header-value, mh-beginning-of-word): Move to
- mh-utils.el.
- (mh-insert-header-separator): Move to mh-comp.el.
- (mh-display-completion-list-compat): Move to new file
- mh-compat.el.
-
- * mh-compat.el: New file.
- (assoc-string): Move here from mh-acros.el.
- (mh-display-completion-list): Move here from mh-comp.el.
-
- * mh-customize.el: Move content into mh-e.el and remove.
-
- * mh-e.el (mh-folder-mode-map, mh-folder-seq-tool-bar-map)
- (mh-folder-tool-bar-map, mh-inc-spool-map, mh-letter-mode-map)
- (mh-letter-tool-bar-map, mh-search-mode-map, mh-show-mode-map)
- (mh-show-seq-tool-bar-map, mh-show-tool-bar-map): All maps now
- declared here so that they can be used in docstrings.
- (mh-sent-from-folder, mh-sent-from-msg)
- (mh-letter-header-field-regexp, mh-pgp-support-flag)
- (mh-x-mailer-string): Move here from mh-comp.el.
- (mh-folder-line-matches-show-buffer-p): Move to mh-alias.el.
- (mh-thread-scan-line-map, mh-thread-scan-line-map-stack):
- Move here from mh-seq.el.
- (mh-draft-folder, mh-inbox, mh-user-path, mh-current-folder)
- (mh-previous-window-config, mh-seen-list, mh-seq-list)
- (mh-show-buffer, mh-showing-mode, mh-globals-hash)
- (mh-show-folder-buffer, mh-mail-header-separator)
- (mh-unseen-seq, mh-previous-seq, mh-page-to-next-msg-flag)
- (mh-signature-separator, mh-signature-separator-regexp)
- (mh-list-to-string, mh-list-to-string-1): Move here from
- mh-utils.el.
- (mh-index-max-cmdline-args, mh-xargs, mh-quote-for-shell)
- (mh-exec-cmd, mh-exec-cmd-error, mh-exec-cmd-daemon)
- (mh-exec-cmd-env-daemon, mh-process-daemon, mh-exec-cmd-quiet)
- (mh-exec-cmd-output)
- (mh-exchange-point-and-mark-preserving-active-mark)
- (mh-exec-lib-cmd-output, mh-handle-process-error): Move here from
- deprecated file mh-exec.el.
- (mh-path): Move here from deprecated file mh-customize.el.
- (mh-sys-path, mh-variants, mh-variant-in-use, mh-progs, mh-lib)
- (mh-flists-present-flag, mh-variants, mh-variant-mh-info)
- (mh-variant-mu-mh-info, mh-variant-nmh-info, mh-file-command-p)
- (mh-variant-set-variant, mh-variant-p, mh-profile-component)
- (mh-profile-component-value, mh-defface-compat): Move here from
- deprecated file mh-init.el.
- (mh-goto-next-button, mh-folder-mime-action)
- (mh-folder-toggle-mime-part, mh-folder-inline-mime-part)
- (mh-folder-save-mime-part, mh-toggle-mime-buttons): Move to to
- mh-mime.el.
- (mh-scan-format-mh, mh-scan-format-nmh, mh-note-deleted)
- (mh-note-refiled, mh-note-cur, mh-scan-good-msg-regexp)
- (mh-scan-deleted-msg-regexp, mh-scan-refiled-msg-regexp)
- (mh-scan-valid-regexp, mh-scan-cur-msg-number-regexp)
- (mh-scan-date-regexp, mh-scan-rcpt-regexp, mh-scan-body-regexp)
- (mh-scan-subject-regexp, mh-scan-sent-to-me-sender-regexp)
- (mh-scan-cmd-note-width, mh-scan-destination-width)
- (mh-scan-date-width, mh-scan-date-flag-width)
- (mh-scan-from-mbox-width, mh-scan-from-mbox-sep-width)
- (mh-scan-field-destination-offset)
- (mh-scan-field-from-start-offset, mh-scan-field-from-end-offset)
- (mh-scan-field-subject-start-offset, mh-scan-format)
- (mh-msg-num-width-to-column, mh-set-cmd-note): Move to new file
- mh-scan.el.
- (mh-partial-folder-mode-line-annotation)
- (mh-folder-font-lock-keywords, mh-folder-font-lock-subject)
- (mh-generate-sequence-font-lock, mh-last-destination)
- (mh-last-destination-write, mh-first-msg-num, mh-last-msg-num)
- (mh-rmail, mh-nmail, mh-delete-msg, mh-delete-msg-no-motion)
- (mh-execute-commands, mh-first-msg, mh-header-display)
- (mh-inc-folder, mh-last-msg, mh-next-undeleted-msg)
- (mh-folder-from-address, mh-prompt-for-refile-folder)
- (mh-refile-msg, mh-refile-or-write-again, mh-quit, mh-page-msg)
- (mh-previous-page, mh-previous-undeleted-msg)
- (mh-previous-unread-msg, mh-next-button, mh-prev-button)
- (mh-reset-threads-and-narrowing, mh-rescan-folder)
- (mh-write-msg-to-file, mh-toggle-showing, mh-undo)
- (mh-visit-folder, mh-update-sequences, mh-delete-a-msg)
- (mh-refile-a-msg, mh-next-msg, mh-next-unread-msg)
- (mh-set-scan-mode, mh-undo-msg, mh-make-folder)
- (mh-folder-sequence-menu, mh-folder-message-menu)
- (mh-folder-folder-menu, mh-remove-xemacs-horizontal-scrollbar)
- (mh-write-file-functions-compat, mh-folder-mode)
- (mh-restore-desktop-buffer, mh-scan-folder)
- (mh-regenerate-headers, mh-generate-new-cmd-note)
- (mh-get-new-mail, mh-make-folder-mode-line, mh-goto-cur-msg)
- (mh-process-or-undo-commands, mh-process-commands)
- (mh-update-unseen, mh-delete-scan-msgs)
- (mh-outstanding-commands-p): Move to new file mh-folder.el.
- (mh-mapc, mh-colors-available-p, mh-colors-in-use-p)
- (mh-make-local-vars, mh-coalesce-msg-list, mh-greaterp)
- (mh-lessp): Move to mh-utils.el.
- (mh-parse-flist-output-line, mh-folder-size-folder)
- (mh-folder-size-flist, mh-folder-size, mh-add-sequence-notation)
- (mh-remove-sequence-notation, mh-remove-cur-notation)
- (mh-remove-all-notation, mh-delete-seq-locally)
- (mh-read-folder-sequences, mh-read-msg-list)
- (mh-notate-user-sequences, mh-internal-seqs, mh-internal-seq)
- (mh-valid-seq-p, mh-delete-msg-from-seq, mh-catchup)
- (mh-delete-a-msg-from-seq, mh-undefine-sequence)
- (mh-define-sequence, mh-seq-containing-msg): Move to mh-seq.el.
- (mh-xemacs-flag)
- (mh-customize, mh-e, mh-alias, mh-folder, mh-folder-selection)
- (mh-identity, mh-inc, mh-junk, mh-letter, mh-ranges)
- (mh-scan-line-formats, mh-search, mh-sending-mail, mh-sequences)
- (mh-show, mh-speedbar, mh-thread, mh-tool-bar, mh-hooks)
- (mh-faces, mh-alias-completion-ignore-case-flag)
- (mh-alias-expand-aliases-flag, mh-alias-flash-on-comma)
- (mh-alias-insert-file, mh-alias-insertion-location)
- (mh-alias-local-users, mh-alias-local-users-prefix)
- (mh-alias-passwd-gecos-comma-separator-flag)
- (mh-new-messages-folders, mh-ticked-messages-folders)
- (mh-large-folder, mh-recenter-summary-flag)
- (mh-recursive-folders-flag, mh-sortm-args)
- (mh-default-folder-for-message-function, mh-default-folder-list)
- (mh-default-folder-must-exist-flag, mh-default-folder-prefix)
- (mh-identity-list, mh-auto-fields-list)
- (mh-auto-fields-prompt-flag, mh-identity-default)
- (mh-identity-handlers, mh-inc-prog, mh-inc-spool-list)
- (mh-junk-choice, mh-junk-function-alist, mh-junk-choose)
- (mh-junk-background, mh-junk-disposition, mh-junk-program)
- (mh-compose-insertion, mh-compose-skipped-header-fields)
- (mh-compose-space-does-completion-flag)
- (mh-delete-yanked-msg-window-flag)
- (mh-extract-from-attribution-verb, mh-ins-buf-prefix)
- (mh-letter-complete-function, mh-letter-fill-column)
- (mh-mml-method-default, mh-signature-file-name)
- (mh-signature-separator-flag, mh-x-face-file, mh-yank-behavior)
- (mh-interpret-number-as-range-flag, mh-adaptive-cmd-note-flag)
- (mh-scan-format-file-check, mh-scan-format-file)
- (mh-adaptive-cmd-note-flag-check, mh-scan-prog)
- (mh-search-program, mh-compose-forward-as-mime-flag)
- (mh-compose-letter-function, mh-compose-prompt-flag)
- (mh-forward-subject-format, mh-insert-x-mailer-flag)
- (mh-redist-full-contents-flag, mh-reply-default-reply-to)
- (mh-reply-show-message-flag, mh-refile-preserves-sequences-flag)
- (mh-tick-seq, mh-update-sequences-after-mh-show-flag)
- (mh-bury-show-buffer-flag, mh-clean-message-header-flag)
- (mh-decode-mime-flag, mh-display-buttons-for-alternatives-flag)
- (mh-display-buttons-for-inline-parts-flag)
- (mh-do-not-confirm-flag, mh-fetch-x-image-url)
- (mh-graphical-smileys-flag, mh-graphical-emphasis-flag)
- (mh-highlight-citation-style)
- (mh-invisible-header-fields-internal)
- (mh-delay-invisible-header-generation-flag)
- (mh-invisible-header-fields, mh-invisible-header-fields-default)
- (mh-invisible-header-fields-compiled, mh-invisible-headers)
- (mh-lpr-command-format, mh-max-inline-image-height)
- (mh-max-inline-image-width, mh-mhl-format-file)
- (mh-mime-save-parts-default-directory, mh-print-background-flag)
- (mh-show-maximum-size, mh-show-use-goto-addr-flag)
- (mh-show-use-xface-flag, mh-store-default-directory)
- (mh-summary-height, mh-speed-update-interval)
- (mh-show-threads-flag, mh-tool-bar-search-function)
- (mh-after-commands-processed-hook, mh-alias-reloaded-hook)
- (mh-before-commands-processed-hook, mh-before-quit-hook)
- (mh-before-send-letter-hook, mh-delete-msg-hook)
- (mh-find-path-hook, mh-folder-mode-hook, mh-forward-hook)
- (mh-inc-folder-hook, mh-insert-signature-hook)
- (mh-kill-folder-suppress-prompt-hooks, mh-letter-mode-hook)
- (mh-mh-to-mime-hook, mh-search-mode-hook, mh-quit-hook)
- (mh-refile-msg-hook, mh-show-hook, mh-show-mode-hook)
- (mh-unseen-updated-hook, mh-min-colors-defined-flag)
- (mh-folder-address, mh-folder-body)
- (mh-folder-cur-msg-number, mh-folder-date, mh-folder-deleted)
- (mh-folder-followup, mh-folder-msg-number, mh-folder-refiled)
- (mh-folder-sent-to-me-hint, mh-folder-sent-to-me-sender)
- (mh-folder-subject, mh-folder-tick, mh-folder-to)
- (mh-search-folder, mh-letter-header-field, mh-show-cc)
- (mh-show-date, mh-show-from, mh-show-header, mh-show-pgg-bad)
- (mh-show-pgg-good, mh-show-pgg-unknown, mh-show-signature)
- (mh-show-subject, mh-show-to, mh-show-xface, mh-speedbar-folder)
- (mh-speedbar-folder-with-unseen-messages)
- (mh-speedbar-selected-folder)
- (mh-speedbar-selected-folder-with-unseen-messages): Move here from
- deprecated file mh-customize.el.
-
- * mh-exec.el: Move content into mh-e.el and remove.
-
- * mh-folder.el: New file. Contains mh-folder-mode from mh-e.el.
-
- * mh-funcs.el (mh-note-copied, mh-note-printed): Move to new file
- mh-scan.el.
- (mh-ephem-message, mh-help, mh-prefix-help): Move to mh-utils.el.
-
- * mh-gnus.el (mm-uu-dissect-text-parts): Add.
- (mh-mail-abbrev-make-syntax-table): Move to mh-utils.el and rename
- to mail-abbrev-make-syntax-table.
-
- * mh-identity.el (mh-identity-menu): New variable for existing
- menu.
- (mh-identity-make-menu-no-autoload): New alias for
- mh-identity-make-menu which can be called from mh-e.el.
- (mh-identity-list-set): Move to mh-e.el.
- (mh-identity-add-menu): New function.
- (mh-insert-identity): Add optional argument maybe-insert so that
- local variable mh-identity-local does not have to be visible.
-
- * mh-inc.el (mh-inc-spool-map): Move declaration to mh-e.el (with
- rest of keymaps). Update key binding for ? to call mh-help with
- help messages in new argument.
- (mh-inc-spool-make-no-autoload): New alias for mh-inc-spool-make
- which can be called from mh-e.el.
- (mh-inc-spool-list-set): Simplify update of mh-inc-spool-map-help.
-
- * mh-init.el: Move content into mh-e.el and remove.
-
- * mh-junk.el: Update requires, untabify, and add mh-autoload
- cookies.
-
- * mh-letter.el: New file. Contains mh-letter-mode from mh-comp.el.
-
- * mh-limit.el: New file. Contains display limit commands from
- mh-mime.el.
-
- * mh-mime.el: Rearrange for consistency with other files.
- (mh-buffer-data, mh-mm-inline-media-tests): Move here from
- mh-utils.el.
- (mh-folder-inline-mime-part, mh-folder-save-mime-part)
- (mh-folder-toggle-mime-part, mh-toggle-mime-buttons)
- (mh-goto-next-button): Move here from mh-e.el.
-
- * mh-print.el: Rearrange for consistency with other files.
-
- * mh-scan.el: New file. Contains scan line constants and utilities
- from XXX, mh-funcs, mh-utils.el.
-
- * mh-search.el: Rearrange for consistency with other files.
- (mh-search-mode-map): Drop C-c C-f {dr} bindings since these
- fields which don't exist in the saved header. Replace C-c C-f f
- with C-c C-f m per mail-mode consistency.
- (mh-search-mode): Use mh-set-help instead of setting
- mh-help-messages.
-
- * mh-seq.el (mh-thread-message, mh-thread-container)
- (mh-thread-id-hash, mh-thread-subject-hash, mh-thread-id-table)
- (mh-thread-id-index-map, mh-thread-index-id-map)
- (mh-thread-scan-line-map, mh-thread-scan-line-map-stack)
- (mh-thread-subject-container-hash, mh-thread-duplicates)
- (mh-thread-history, mh-thread-body-width)
- (mh-thread-find-msg-subject mh-thread-initialize-hash)
- (mh-thread-initialize, mh-thread-id-container)
- (mh-thread-remove-parent-link, mh-thread-add-link)
- (mh-thread-ancestor-p, mh-thread-get-message-container)
- (mh-thread-get-message, mh-thread-canonicalize-id)
- (mh-thread-prune-subject, mh-thread-container-subject)
- (mh-thread-rewind-pruning, mh-thread-prune-containers)
- (mh-thread-sort-containers, mh-thread-group-by-subject)
- (mh-thread-process-in-reply-to, mh-thread-set-tables)
- (mh-thread-update-id-index-maps, mh-thread-generate)
- (mh-thread-inc, mh-thread-generate-scan-lines)
- (mh-thread-parse-scan-line, mh-thread-update-scan-line-map)
- (mh-thread-add-spaces, mh-thread-print-scan-lines)
- (mh-thread-folder, mh-toggle-threads, mh-thread-forget-message)
- (mh-thread-current-indentation-level, mh-thread-next-sibling)
- (mh-thread-previous-sibling, mh-thread-immediate-ancestor)
- (mh-thread-ancestor, mh-thread-find-children)
- (mh-message-id-regexp, mh-thread-delete, mh-thread-refile):
- Move to new file mh-thread.el.
- (mh-subject-to-sequence, mh-subject-to-sequence-unthreaded)
- (mh-subject-to-sequence-threaded, mh-edit-pick-expr)
- (mh-pick-args-list, mh-narrow-to-subject, mh-narrow-to-from)
- (mh-narrow-to-cc, mh-narrow-to-to, mh-narrow-to-header-field)
- (mh-current-message-header-field, mh-narrow-to-range)
- (mh-delete-subject, mh-delete-subject-or-thread): Move to new file
- mh-limit.el.
- (mh-iterate-on-messages-in-region, mh-iterate-on-range): Move to
- mh-acros.el.
- (mh-internal-seqs, mh-catchup, mh-delete-msg-from-seq)
- (mh-internal-seq, mh-valid-seq-p, mh-seq-containing-msg)
- (mh-define-sequence, mh-undefine-sequence)
- (mh-delete-a-msg-from-seq, mh-delete-seq-locally)
- (mh-folder-size, mh-folder-size-flist, mh-folder-size-folder)
- (mh-parse-flist-output-line, mh-read-folder-sequences)
- (mh-read-msg-list, mh-notate-user-sequences)
- (mh-remove-cur-notation, mh-add-sequence-notation)
- (mh-remove-sequence-notation, mh-remove-all-notation): Move here
- from mh-e.el.
- (mh-make-seq, mh-seq-name, mh-find-seq, mh-seq-to-msgs)
- (mh-add-msgs-to-seq, mh-notate): Move here from mh-utils.el.
-
- * mh-show.el: New file. Contains mh-show-mode from mh-utils.el.
-
- * mh-speed.el: Rearrange for consistency with other files.
-
- * mh-thread.el: New file. Contains threading code from mh-seq.el.
-
- * mh-tool-bar.el: New file. Contains tool bar creation code from
- deprecated file mh-customize.el.
-
- * mh-utils.el (recursive-load-depth-limit): Remove setting.
- No longer needed.
- (mh-scan-msg-number-regexp, mh-scan-msg-overflow-regexp)
- (mh-scan-msg-format-regexp, mh-scan-msg-format-string)
- (mh-scan-msg-search-regexp, mh-cmd-note, mh-note-seq)
- (mh-update-scan-format, mh-msg-num-width): Move to new file
- mh-scan.el.
- (mh-show-buffer-mode-line-buffer-id, mh-letter-header-font-lock)
- (mh-header-field-font-lock, mh-header-to-font-lock)
- (mh-header-cc-font-lock, mh-header-subject-font-lock)
- (mh-show-font-lock-keywords)
- (mh-show-font-lock-keywords-with-cite)
- (mh-show-font-lock-fontify-region)
- (mh-gnus-article-highlight-citation, mh-showing-with-headers)
- (mh-start-of-uncleaned-message, mh-invalidate-show-buffer)
- (mh-unvisit-file, mh-defun-show-buffer, mh-show-mode-map)
- (mh-show-sequence-menu, mh-show-message-menu)
- (mh-show-folder-menu, mh-show-mode, mh-show-addr)
- (mh-maybe-show, mh-show, mh-show-msg, mh-show-unquote-From)
- (mh-msg-folder, mh-display-msg, mh-clean-msg-header): Move to new
- file mh-show.el.
- (mh-mail-header-separator, mh-signature-separator-regexp)
- (mh-signature-separator, mh-globals-hash, mh-user-path)
- (mh-draft-folder, mh-unseen-seq, mh-previous-seq, mh-inbox)
- (mh-previous-window-config, mh-current-folder mh-show-buffer)
- (mh-showing-mode, mh-show-mode-map, mh-show-folder-buffer)
- (mh-showing-mode, mh-seq-list, mh-seen-list, mh-summary-height)
- (mh-list-to-string, mh-list-to-string-1): Move to mh-e.el.
- (mh-buffer-data, mh-mm-inline-media-tests): Move to mh-mime.el.
- (mh-address-mail-regexp, mh-goto-address-find-address-at-point):
- Move to mh-alias.el.
- (mh-letter-font-lock-keywords): Move to new file mh-letter.el.
- (mh-folder-filename, mh-msg-count, mh-recenter, mh-msg-filename)
- (mh-show-mouse, mh-modify, mh-goto-msg, mh-set-folder-modified-p):
- Move to new file mh-folder.el.
- (with-mh-folder-updating, mh-in-show-buffer)
- (mh-do-at-event-location, mh-seq-msgs): Move to mh-acros.el.
- (mh-make-seq, mh-seq-name, mh-notate, mh-find-seq)
- (mh-seq-to-msgs, mh-add-msgs-to-seq, mh-canonicalize-sequence):
- Move to mh-seq.el.
- (mh-show-xface-function, mh-uncompface-executable, mh-face-to-png)
- (mh-uncompface, mh-icontopbm, mh-face-foreground-compat)
- (mh-face-background-compat, mh-face-display-function)
- (mh-show-xface, mh-picon-directory-list)
- (mh-picon-existing-directory-list)
- (mh-picon-cache, mh-picon-image-types)
- (mh-picon-set-directory-list, mh-picon-get-image)
- (mh-picon-file-contents, mh-picon-generate-path)
- (mh-x-image-cache-directory, mh-x-image-scaling-function)
- (mh-wget-executable, mh-wget-choice, mh-wget-option)
- (mh-x-image-temp-file, mh-x-image-url, mh-x-image-marker)
- (mh-x-image-url-cache-file, mh-x-image-scale-with-pnm)
- (mh-x-image-scale-with-convert)
- (url-unreserved-chars, url-hexify-string)
- (mh-x-image-url-cache-canonicalize)
- (mh-x-image-set-download-state, mh-x-image-get-download-state)
- (mh-x-image-url-fetch-image, mh-x-image-display)
- (mh-x-image-scale-and-display, mh-x-image-url-sane-p)
- (mh-x-image-url-display): Move to new file mh-xface.el.
- (mh-logo-display): Call mh-image-load-path.
- (mh-find-path-run, mh-find-path): Move here from deprecated file
- mh-init.el.
- (mh-help-messages): Now an alist of modes to an alist of messages.
- (mh-set-help): New function used to set mh-help-messages.
- (mh-help): Adjust for new format of mh-help-messages.
- Add help-messages argument.
- (mh-prefix-help): Refactor to use mh-help.
- (mh-coalesce-msg-list, mh-greaterp, mh-lessp): Move here from
- mh-e.el.
- (mh-clear-sub-folders-cache): New function added to avoid exposing
- mh-sub-folders-cache variable.
-
- * mh-xface.el: New file. Contains X-Face and Face header field
- display routines from mh-utils.el.
-
-2006-01-17 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el (assoc-string): Fix typo in argument.
-
-2006-01-16 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el (require): Remove defadvice of require as defadvice
- is verboten within Emacs and our implementation was returning the
- wrong value from require. Upcoming restructuring should make this
- unnecessary.
- (mh-assoc-ignore-case): Replace with defsubst assoc-string.
-
- * mh-alias.el (mh-alias-local-users, mh-alias-reload)
- (mh-alias-expand, mh-alias-minibuffer-confirm-address): Use it.
-
- * mh-identity.el (mh-identity-field-handler): Use it.
-
- * mh-comp.el (mh-show-buffer-message-number): Replace (car
- (read-from-string string) with (string-to-number string).
-
- * mh-e.el (mh-parse-flist-output-line, mh-folder-size-folder):
- Ditto.
-
- * mh-mime.el (mh-mml-forward-message): Ditto.
-
- * mh-search.el (mh-swish-next-result, mh-mairix-next-result)
- (mh-namazu-next-result, mh-grep-next-result, mh-md5sum-parser)
- (mh-openssl-parser, mh-index-update-maps): Ditto.
-
- * mh-seq.el (mh-translate-range, mh-narrow-to-header-field)
- (mh-thread-generate): Ditto.
-
-2006-01-16 Katsumi Yamaoka <yamaoka@jpl.org>
-
- * mh-mime.el (mh-mime-display, mh-mm-inline-message): Fix use of
- mm- functions for proper text=flowed handling (addresses SF
- #1273521).
-
-2006-01-15 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-limit-map, mh-help-messages): Change keybinding of
- mh-narrow-to-from from / f to / m; mh-narrow-to-range from / r to
- / g.
-
- * mh-utils.el (mh-show-limit-map): Ditto.
-
- * mh-exec.el: Require mh-acros, mh-buffers, and mh-utils for
- standalone compile.
- (mh-progs, mh-lib, mh-lib-progs): Move here from mh-init.el.
-
- * mh-init.el (mh-progs, mh-lib, mh-lib-progs): Move to mh-exec.el,
- where they are used.
-
- * mh-comp.el (mh-pgp-support-flag): Move here from mh-utils.el;
- needed to help remove dependency on mh-utils.
-
- * mh-exec.el: New file. Move process support routines here from
- mh-utils.el.
-
- * mh-init.el (mh-utils): Remove require.
- (mh-exec): Add require.
- (mh-profile-component, mh-profile-component-value): Move here from
- mh-utils.el.
-
- * mh-utils.el (mh-pgp-support-flag): Move to mh-comp.el to reduce
- dependencies on mh-utils.el.
- (mh-profile-component, mh-profile-component-value): Move to
- mh-init.el since that's the only place that uses them. (Other than
- mh-alias.el; I'm thinking that mh-find-path can set variable from
- the Aliasfile component like it does the other components).
- (mh-index-max-cmdline-args, mh-xargs, mh-quote-for-shell)
- (mh-exec-cmd, mh-exec-cmd-error, mh-exec-cmd-daemon)
- (mh-exec-cmd-env-daemon, mh-process-daemon, mh-exec-cmd-quiet)
- (defvar, mh-exec-cmd-output)
- (mh-exchange-point-and-mark-preserving-active-mark)
- (mh-exec-lib-cmd-output, mh-handle-process-error): Move to new
- file mh-exec.el so that mh-init.el doesn't have to depend on
- mh-utils.el, breaking circular dependency.
-
- * mh-alias.el:
- * mh-customize.el:
- * mh-e.el:
- * mh-funcs.el:
- * mh-gnus.el:
- * mh-identity.el:
- * mh-inc.el:
- * mh-junk.el:
- * mh-mime.el:
- * mh-print.el:
- * mh-search.el:
- * mh-seq.el:
- * mh-speed.el: Added debugging statements (commented out) around
- requires to help find dependency loops. Will remove them when
- issues are resolved.
-
-2006-01-14 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-index): Rename group to mh-search and sort
- group definition and options accordingly.
- (mh-index-program): Rename to mh-search-program.
- (mh-kill-folder-suppress-prompt-hooks): Rename mh-index-p to
- mh-search-p.
- (mh-search-mode-hook): Change group from mh-index to mh-search.
- (mh-index-folder): Rename to mh-search-folder. Change group from
- mh-index to mh-search.
-
- * mh-e.el (mh-folder-font-lock-keywords): Rename mh-index-folder
- to mh-search-folder.
-
- * mh-search.el (mh-indexer) Rename to mh-searcher. The commands
- pick and grep are searchers too but aren't indexed.
- (mh-index-execute-search-function): Rename to mh-search-function.
- (mh-index-next-result-function): Rename to
- mh-search-next-result-function.
- (mh-index-regexp-builder): Rename to mh-search-regexp-builder.
- (mh-search): Since redo-search-flag defaults to nil and is of
- lesser importance, make it an optional argument and place it after
- the folder and search-regexp arguments. Sync docstring with manual.
- (mh-search-mode-map): Autoload so that keys are shown in help even
- before mh-search is loaded.
- (mh-search-mode): Sync docstring with manual.
- (mh-index-do-search): Rename argument indexer to searcher.
- Sync docstring with manual.
- (mh-pick-do-search): Sync docstring with manual.
- (mh-index-p): Rename to mh-search-p.
- (mh-indexer-choices): Rename to mh-search-choices.
- (mh-index-choose): Rename to mh-search-choose. Rename argument
- indexer to searcher.
- (mh-swish++-execute-search, mh-swish-execute-search)
- (mh-mairix-execute-search, mh-namazu-execute-search): Drop "and
- read the results" from docstring since these functions don't.
- (mh-pick-execute-search, mh-grep-execute-search): Sync docstring
- with manual.
- (mh-index-generate-pretty-name): Prune -search from string so that
- folder names for pick searches are the same as those of other
- searches.
-
-2006-01-13 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el (require): Add Satyaki's comment regarding what
- needs to happen to remove this defadvice which caused a little
- discussion on emacs-devel today (see Subject: mh-e/mh-acros.el
- advices `require' incorrectly).
-
- * mh-search.el (mh-index-next-result-function): Add format to
- docstring.
- (mh-mairix-next-result): Use nil instead of () which doesn't stand
- out as well.
- (mh-pick-execute-search): Operate across all folders if no folder
- given and recurse folder(s).
- (mh-pick-next-result): Handle new output.
-
- * mh-utils.el (mh-collect-folder-names): Fix docstring.
- (mh-children-p, mh-folder-list): New functions.
-
-2006-01-12 Bill Wohler <wohler@newt.com>
-
- * mh-search.el: New file containing contents of mh-index.el and
- mh-pick.el. C-c C-c launches your mh-index-program; C-c C-p runs
- pick. Pick no longer sets the "search" sequence. Instead, it
- brings up a folder view that we're accustomed to. (Closes SF
- #829207.)
- (mh-index-search): Rename to mh-search.
- (mh-pick-menu): Rename menu from Pick to Search. Rename Execute
- the Search to Perform Search and call mh-do-search. Add Search
- with Pick menu item.
- (mh-do-search): Delete.
- (mh-search-mode): Rename from mh-pick-mode.
- (MH-Search): Rename mode from MH-Pick.
- (mh-search-mode-map): Rename from mh-pick-mode-map.
- (mh-search-mode-help-messages): Rename from
- mh-pick-mode-help-messages.
- (mh-index-choose): Don't reuse the last value of mh-indexer; when
- mh-pick-do-search sets it to 'pick, we don't necessarily want to
- stay with that choice!
-
- * mh-index.el:
- * mh-pick.el: Merge into mh-search.el and delete.
-
- * mh-customize.el (mh-index-program): Change mh-index-search to
- mh-search in docstring.
- (mh-tool-bar-search-function): Change default from
- mh-search-folder to mh-search. Remove mh-search-folder as choice
- and rename mh-index-search choice to mh-search. Fix docstring.
- (mh-pick-mode-hook): Rename to mh-search-mode-hook and change
- mh-search-folder to mh-search in docstring.
-
- * mh-e.el (mh-folder-folder-menu): Delete Search a Folder. Change
- Indexed Search to Search. Use mh-search instead of mh-index-search.
- (mh-folder-map): Delete i (mh-index-search) keybinding. Change s
- from mh-show-search-folder to mh-search.
-
- * mh-seq.el (mh-put-msg-in-seq): Fix docstring now that
- mh-search-folder no longer creates the search sequence.
-
- * mh-utils.el (mh-show-search-folder): Delete.
- (mh-show-folder-map): Delete i (mh-index-search) keybinding.
- Change s from mh-show-search-folder to mh-search.
- (mh-show-folder-menu): Delete Search a Folder. Change Indexed
- Search to Search. Use mh-search instead of mh-index-search.
- (mh-index-max-cmdline-args, mh-xargs, mh-quote-for-shell):
- Move here from deleted mh-index.el.
-
-2006-01-11 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el (mh-defun-compat, mh-defmacro-compat): Move here
- from mh-gnus.el.
-
- * mh-gnus.el: Require mh-acros.
- (mh-defmacro-compat, mh-defun-compat): Move to mh-acros.el.
-
- * mh-utils.el (mh-x-image-url-cache-canonicalize):
- Use url-hexify-string to remove special characters from filenames
- (closes SF #1396499). Note that this invalidates the existing
- names in your cache so you might as well remove
- ~/Mail/.mhe-x-image-cache/* now.
- (url-unreserved-chars, url-hexify-string): Define if not defined.
- Copied from url-util.el in Emacs22 for Emacs 21.
-
- * mh-buffers.el: New file. Contains constants and code from
- mh-index.el and mh-utils.el.
-
- * mh-alias.el:
- * mh-comp.el:
- * mh-e.el:
- * mh-funcs.el:
- * mh-init.el:
- * mh-junk.el:
- * mh-mime.el:
- * mh-print.el:
- * mh-seq.el: Require new file mh-buffers.el.
-
- * mh-index.el: Require new file mh-buffers.el.
- (mh-index-temp-buffer, mh-checksum-buffer): Move to new file
- mh-buffers.el.
-
- * mh-utils.el: Require new file mh-buffers.el.
- (mh-temp-buffer, mh-temp-fetch-buffer)
- (mh-aliases-buffer, mh-folders-buffer, mh-help-buffer)
- (mh-info-buffer, mh-log-buffer, mh-mail-delivery-buffer)
- (mh-recipients-buffer, mh-sequences-buffer, mh-log-buffer-lines)
- (mh-truncate-log-buffer): Move to new file mh-buffers.el.
-
- * mh-comp.el (mh-forward): Cosmetics on prompt when draft exists.
- (mh-send-letter): Add -msgid to mh-send-args (closes SF #725425).
-
-2006-01-10 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-insert-letter): If you choose a different folder,
- the cur message is used. Sync docstring with manual (closes SF
- #1205890).
-
- * mh-mime.el (mh-compose-forward): Use standard range argument
- instead of messages. Use more powerful mh-read-range instead of
- read-string. Sync docstring with manual (close SF #1205890).
-
- * mh-index.el (mh-index-search): Checking mh-find-path-run is
- unnecessary.
- (mh-index-next-folder): Don't back up a line when going backwards
- since this skips the current folder heading if point is on the
- first message after the folder heading (closes SF #1126188).
-
- * mh-init.el (mh-sys-path): Co-locate with mh-variants, which uses it.
- (mh-variants): Note variable isn't meant to be accessed directly;
- use function mh-variants instead.
- (mh-variant-info, mh-variant-mh-info, mh-variant-mu-mh-info)
- (mh-variant-nmh-info): Co-locate next to mh-variants, which uses
- them. Updated to use mh-file-command-p which is more accurate
- than file-executable-p which returns t for directories.
- (mh-file-command-p): Move here from mh-utils, since
- mh-variant-*-info are the only functions to use it.
- (mh-variant-set, mh-variant-set-variant, mh-variant-p):
- Use function mh-variants instead of variable. More robust.
- (mh-find-path-run): Move here from mh-utils.el. Mention that
- checking this variable is unnecessary.
- (mh-find-path): Move here from mh-utils.el. With the advent of MH
- variants and an mhparam command that doesn't work if there isn't
- an MH profile, we can't get libdir for running install-mh.
- So don't bother. If there's an issue with the environment, direct the
- user to install MH and run install-mh (closes SF #835192).
- Don't read ~/.mh_profile directly. Use mh-profile-component which uses
- mhparam (closes SF #1016027).
-
- * mh-utils.el (mh-get-profile-field): Rename to
- mh-profile-component-value. Add colon to search removing
- unnecessary addition of colon to field in mh-profile-component.
- (mh-profile-component): Modify call to mh-profile-component-value
- accordingly. Move next to mh-profile-component-value.
- (mh-find-path-run, mh-find-path, mh-file-command-p): Move to
- mh-init.el. It makes sense that code that is only run once per
- session (more or less) is in mh-init.el rather than cluttering
- mh-utils.el.
- (mh-no-install, mh-install): Delete.
-
- * mh-customize.el (mh-folder-msg-number):
- * mh-mime.el (mh-file-mime-type): Remove trailing whitespace.
-
-2006-01-09 Bill Wohler <wohler@newt.com>
-
- * mh-init.el (mh-variant-mu-mh-info, mh-variant-nmh-info):
- Applied patch from Satyaki from SF #1016027.
-
- * mh-e.el (mh-rescan-folder): Try to keep cursor at current
- message, even if cur sequence is no longer present (closes SF
- #1207247).
-
- * mh-comp.el: Use ";; Shush compiler." comment consistently per
- Mark's suggestion.
- (mh-letter-mode): Derive from mail-mode and delete code copied
- from mail-mode (closes SF #1385571). Mention mail-mode-hook in
- docstring.
- (mh-fill-paragraph-function): Delete. Handled by mail-mode.
- (mh-to-field-choices): For consistency with mail-mode, add "a" for
- "Mail-Reply-To:", "l" for "Mail-Followup-To:", and "r" for
- "Reply-To:". Change "r" to "m" for "From:" (closes SF #1400139).
- (mh-to-fcc): Move setting of folder argument to interactive
- argument as is the norm.
- (mh-letter-complete-function-alist): Add mail-reply-to.
- (mh-letter-mode-map): Add keys for mh-to-field (Mail-Reply-To,
- Mail-Followup-To, Reply-To, From).
-
- * mh-customize.el: Use ";; Forward definition." consistently.
- Comment declaration to remind programmer to update forward
- definition if default changes.
-
- * mh-funcs.el:
- * mh-inc.el:
- * mh-init.el:
- * mh-mime.el:
- * mh-seq.el:
- * mh-utils.el: Use ";; Shush compiler." comment consistently per
- Mark's suggestion.
-
-2006-01-08 Bill Wohler <wohler@newt.com>
-
- Removed code that was marked as Emacs 20 compatible that was
- easily found showing how important it is to document such
- things (closes SF #1359240). Feel free to nuke any other Emacs 20
- peculiarities that you find. Wrapped code for shushing compiler
- with (eval-when-compile), sometimes moving the defvars closer to
- where they were used.
-
- * mh-alias.el (mh-alias-gecos-name): Use replace-regexp-in-string
- instead of mh-replace-in-string as mh-replace-in-string was
- replaced by a more appropriate defsubst in mh-xemacs.el.
-
- * mh-comp.el: Require cleanup, wrap compiler-shushing defvars with
- eval-when-compile.
- (mh-file-is-vcard-p): Remove redundant test.
-
- * mh-customize.el: Require cleanup, wrap compiler-shushing defvars
- with eval-when-compile.
- (mh-adaptive-cmd-note-flag, mh-invisible-header-fields)
- (mh-invisible-header-fields-default): Add forward definitions.
- (mh-invisible-header-fields-default): Alphabetize.
-
- * mh-e.el: Require cleanup, wrap compiler-shushing defvars with
- eval-when-compile.
- (mh-thread-scan-line-map-stack, tool-bar-mode): Delete unused
- variables.
- (mh-colors-available-p): Just call display-color-cells. It's on
- all supported Emacsen (and defaliased on XEmacs).
-
- * mh-funcs.el:
- * mh-inc.el:
- * mh-init.el: Wrap compiler-shushing defvars with
- eval-when-compile.
-
- * mh-identity.el: Don't need (mh-require-cl).
-
- * mh-index.el: Don't need to load executable any more.
-
- * mh-mime.el: Wrap compiler-shushing defvars with
- eval-when-compile.
- (mh-have-file-command): Initialize variable to 'undefined.
- Add docstring. Update function of same name accordingly. Also don't
- need to load executable any more.
- (mh-mime-content-types): Delete.
- (mh-minibuffer-read-type): Prompt user for type if
- mh-file-mime-type returns application/octet-stream. Assume we have
- mailcap-mime-types.
- (mh-mime-display): Update error message.
-
- * mh-seq.el: Require cleanup, and wrap compiler-shushing defvars
- with eval-when-compile.
-
- * mh-utils.el: Require cleanup, and wrap compiler-shushing defvars
- with eval-when-compile.
- (mh-clean-msg-header): Don't set after-change-functions to nil.
- (mh-replace-in-string): Remove. Create defsubst in mh-xemacs.el
- instead.
-
-2006-01-07 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el: Updated Faces documentation in header.
- (mh-invisible-header-fields-internal): Add X-Lumos-SenderID,
- X-Return-Path-Hint, and X-Roving-* from Roving ConstantContact.
-
- * mh-mime.el (mh-mml-tag-present-p): Update regexp to handle <mml>
- tags inserted by Gnus gnus-summary-mail-forward (closes SF
- #1399307).
-
-2006-01-03 Mark D. Baushke <mdb@gnu.org>
-
- * mh-e.el (mh-delete-a-msg): Fix whitespace nit.
- * mh-index.el (mh-mairix-execute-search): Fix symbol quote.
-
-2006-01-03 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (mh-alias-add-alias): Grand message and error string
- unification. Use single sentence if possible by using semicolon.
- Don't end message with punctuation. Don't need format with
- message. Quote messages as in docstrings: use `' around symbols,
- \" for option choices. Don't use quotes around %s.
-
- * mh-comp.el (mh-complete-word): Ditto.
-
- * mh-customize.el (mh-adaptive-cmd-note-flag-check)
- (mh-scan-format-file-check): Ditto.
-
- * mh-e.el (mh-refile-or-write-again, mh-previous-unread-msg)
- (mh-delete-a-msg, mh-refile-a-msg, mh-next-unread-msg)
- (mh-msg-num-width-to-column): Ditto.
-
- * mh-identity.el (mh-identity-field-handler): Ditto.
-
- * mh-index.el (mh-mairix-execute-search)
- (mh-swish-execute-search, mh-swish++-execute-search)
- (mh-namazu-execute-search): Ditto.
-
- * mh-init.el (mh-variant-set): Ditto.
-
- * mh-mime.el (mh-mh-to-mime-undo, mh-mml-forward-message)
- (mh-secure-message, mh-mime-display): Ditto.
-
- * mh-pick.el (mh-search-folder, mh-pick-construct-regexp): Ditto.
-
- * mh-seq.el (mh-narrow-to-seq, mh-put-msg-in-seq, mh-read-seq)
- (mh-read-range, mh-thread-container-subject): Ditto.
-
- * mh-utils.el (mh-x-image-scale-and-display)
- (mh-prompt-for-folder, mh-handle-process-error)
- (mh-list-to-string-1): Ditto.
-
- * mh-comp.el (mh-reply): Use standard default notation in
- prompts (closes SF #1275933).
-
- * mh-mime.el (mh-mime-save-parts): Ditto.
-
- * mh-seq.el (mh-read-seq, mh-read-range): Ditto.
-
- * mh-customize.el (mh-folder-msg-number): Snow is actually
- off-white on low color displays which turns to white when bold.
- This is unreadable on white backgrounds. Use snow with min-colors
- requirement. Use cyan on low-color displays.
-
- * mh-init.el (mh-defface-compat): On low-color displays, delete
- the high-color display rather than simply strip the min-colors
- requirement since the existing algorithm shadowed the desired
- display on low-color displays.
-
- * mh-alias.el (mh-alias-add-alias): Remove leading * from
- docstring.
-
-2006-01-02 Bill Wohler <wohler@newt.com>
-
- * mh-alias.el (mh-alias-grab-from-field): Remove leading * from
- docstring. Does this mean something in a defun?
-
- * mh-customize.el (bw-new-face-to-old, bw-old-face-to-new):
- Checkdoc fix.
-
- * mh-e.el (mh-inc-folder): Rename maildrop-name argument to file
- so it reads better in docstring and manual. Sync docstring with
- manual.
-
- * mh-init.el (mh-defface-compat): Remove trailing space (checkdoc).
-
- * mh-alias.el (mh-alias-apropos): Sync docstring with manual.
-
- * mh-comp.el (mh-redistribute, mh-to-field, mh-to-fcc)
- (mh-insert-auto-fields, mh-send-letter, mh-yank-cur-msg)
- (mh-fully-kill-draft, mh-open-line, mh-letter-complete)
- (mh-letter-complete-or-space, mh-letter-confirm-address)
- (mh-letter-next-header-field-or-indent)
- (mh-letter-previous-header-field): Ditto.
-
- * mh-customize.el (mh-alias-completion-ignore-case-flag)
- (mh-default-folder-for-message-function, mh-mml-method-default)
- (mh-signature-file-name, mh-yank-behavior, mh-show-hook)
- (mh-show-mode-hook) Ditto.
-
- * mh-e.el (mh-refile-or-write-again, mh-toggle-showing): Ditto.
-
- * mh-funcs.el (mh-pipe-msg, mh-sort-folder, mh-undo-folder)
- (mh-store-msg, mh-store-buffer): Ditto.
-
- * mh-index.el (mh-index-search, mh-index-do-search)
- (mh-index-next-folder, mh-index-sequenced-messages): Ditto.
-
- * mh-junk.el (mh-spamassassin-blacklist): Ditto.
-
- * mh-mime.el (mh-mh-compose-external-compressed-tar)
- (mh-mh-compose-external-type, mh-mh-to-mime, mh-mh-to-mime-undo)
- (mh-mml-secure-message-sign, mh-mml-secure-message-encrypt)
- (mh-mml-secure-message-signencrypt): Ditto.
-
- * mh-pick.el (mh-search-folder): Ditto.
-
- * mh-seq.el (mh-widen): Ditto.
-
- * mh-utils.el (mh-show, mh-modify): Ditto.
-
-2006-01-02 Mark D. Baushke <mdb@gnu.org>
-
- * mh-mime.el (mh-mml-unsecure-message): Remove unused argument.
-
-2006-01-01 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el: Sync docstrings with manual for faces and sort
- them alphabetically.
- (mh-faces): Move below mh-hooks.
- (mh-folder-faces, mh-index-faces, mh-letter-faces)
- (mh-show-faces, mh-speed-faces): Delete. Organize faces like hooks.
- (mh-speed-update-interval): Fix group (mh-speedbar, not mh-speed).
- (facemenu-unlisted-faces): Might as well ignore all MH-E faces.
- (mh-folder-body-face, mh-folder-cur-msg-face)
- (mh-folder-cur-msg-number-face, mh-folder-date-face)
- (mh-folder-followup-face, mh-folder-msg-number-face)
- (mh-folder-deleted-face, mh-folder-refiled-face)
- (mh-folder-subject-face, mh-folder-address-face)
- (mh-folder-scan-format-face, mh-folder-to-face)
- (mh-index-folder-face, mh-show-cc-face, mh-show-date-face)
- (mh-show-header-face, mh-show-pgg-good-face)
- (mh-show-pgg-unknown-face, mh-show-pgg-bad-face)
- (mh-show-to-face, mh-show-from-face, mh-show-subject-face):
- Delete.
- (mh-folder-cur-msg): Unused. Delete.
- (mh-folder-address): Use defface; inherit from mh-folder-subject.
- (mh-folder-body, mh-folder-cur-msg-number, mh-folder-date):
- Inherit from mh-folder-msg-number.
- (mh-folder-deleted): Use defface. Inherit from
- mh-folder-msg-number.
- (mh-folder-sent-to-me-hint): New face. Inherit from
- mh-folder-date.
- (mh-folder-sent-to-me-sender): Rename from mh-folder-scan-format.
- Use defface. Inherit from mh-folder-followup.
- (mh-show-xface): Inherit from mh-show-from and highlight.
- (bw-face-generation, bw-toggle-faces)
- (bw-new-face-to-old, bw-old-face-to-new): New (tempoarary)
- variables, functions for toggling between old and new faces.
-
- * mh-e.el (font-lock-auto-fontify, font-lock-defaults): Hide in
- eval-when-compile. We should probably do this throughout.
- (mh-scan-good-msg-regexp, mh-scan-deleted-msg-regexp)
- (mh-scan-refiled-msg-regexp, mh-scan-cur-msg-number-regexp)
- (mh-scan-date-regexp, mh-scan-rcpt-regexp, mh-scan-body-regexp)
- (mh-scan-subject-regexp): Sync docstrings with manual.
- (mh-scan-format-regexp): Rename to
- mh-scan-sent-to-me-sender-regexp. Drop date parenthesized
- expression. Make expression more like the others (anchored at the
- beginning of line). Sync docstrings with manual.
- (mh-folder-font-lock-keywords): Use faces directly rather than
- -face variables. Use mh-scan-sent-to-me-sender-regexp instead of
- mh-scan-format-regexp, and within that expression, use faces
- mh-folder-sent-to-me-hint and mh-folder-sent-to-me-sender instead
- of mh-folder-date-face and mh-folder-scan-format-face which were
- misleading.
-
- * mh-mime.el (mh-mime-security-button-face): Use faces directly
- rather than -face variables.
-
- * mh-utils.el (mh-show-font-lock-keywords): Use faces directly
- rather than -face variables.
- (mh-face-foreground-compat, mh-face-background-compat): New macros.
- (mh-face-display-function): Use mh-face-foreground-compat and
- mh-face-background-compat to use inherited attributes of
- mh-show-xface on Emacs 22 while still working on Emacs 21.
-
-2005-12-28 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-e-user-agent): Move here from simple.el.
- Use mh-user-agent-compose instead of mh-smail-batch.
-
-2005-12-27 Bill Wohler <wohler@newt.com>
-
- * mh-utils.el (mh-prompt-for-folder): Use can-create argument to
- suppress creation of folder if it doesn't exist.
-
-2005-12-27 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * mh-utils.el (mh-process-daemon): Don't change buffer in proc-filter.
-
-2005-12-23 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-folders-changed): Fix typo in docstring.
-
- Follow MH-E Developers Guide conventions. Use `' quotes for Help
- hyperlinks such as symbols, Info nodes, or URLs. Use \" quotes for
- everything else. Otherwise, you can accidentally get links to
- nonsense symbols.
-
-2005-12-22 Bill Wohler <wohler@newt.com>
-
- Follow Emacs coding conventions. Use default setting of
- emacs-lisp-docstring-fill-column which is 65.
-
- * mh-alias.el (mh-alias-reload): Sync docstrings with manual.
-
- * mh-comp.el (mh-letter-mode): Use 60 column width.
- (mh-forward, mh-insert-signature, mh-send-letter): Sync docstrings
- with manual.
- (mh-yank-cur-msg): Mention that mh-ins-buf-prefix isn't used if
- you have added a mail-citation-hook and neither are used if you
- use one of the supercite flavors of mh-yank-behavior.
- Sync docstrings with manual.
-
- * mh-customize.el (mh-kill-folder-suppress-prompt-hooks):
- Rename from mh-kill-folder-suppress-prompt-hook since it is an abnormal
- hook. Use "Hook run by `function'..." instead of "Invoked...".
- Sync docstrings with manual.
- (mh-ins-buf-prefix, mh-yank-behavior): Mention that
- mh-ins-buf-prefix isn't used if you have added a
- mail-citation-hook and neither are used if you use one of the
- supercite flavors of mh-yank-behavior. Sync docstrings with manual.
- (mail-citation-hook): Delete. Use one in sendmail.el.
- (mh-signature-file-name, mh-after-commands-processed-hook)
- (mh-alias-reloaded-hook, mh-before-commands-processed-hook)
- (mh-before-quit-hook, mh-before-send-letter-hook)
- (mh-delete-msg-hook, mh-find-path-hook, mh-folder-mode-hook)
- (mh-forward-hook, mh-inc-folder-hook, mh-insert-signature-hook)
- (mh-letter-mode-hook)
- (mh-mh-to-mime-hook, mh-pick-mode-hook, mh-quit-hook)
- (mh-refile-msg-hook, mh-show-hook, mh-show-mode-hook)
- (mh-unseen-updated-hook): Use "Hook run by `function'..." instead
- of "Invoked...". Sync docstrings with manual.
-
- * mh-e.el (mh-last-destination, mh-last-destination-folder)
- (mh-last-destination-write, mh-folder-mode-map, mh-arrow-marker)
- (mh-delete-list, mh-refile-list, mh-folders-changed)
- (mh-next-direction, mh-view-ops, mh-folder-view-stack)
- (mh-index-data, mh-first-msg-num, mh-last-msg-num)
- (mh-mode-line-annotation, mh-sequence-notation-history)
- (mh-colors-available-flag): Move comment into docstring.
- (mh-delete-msg, mh-execute-commands, mh-inc-folder, mh-quit)
- (mh-process-commands): Sync docstrings with manual.
- (mh-refile-msg): Small doc edit.
- (mh-delete-a-msg, mh-refile-a-msg): Sync docstrings with manual.
- Rename msg argument to message.
-
- * mh-funcs.el (mh-kill-folder): Sync docstrings with manual.
-
- * mh-e.el (mh-update-unseen): No longer say "The value of
- `foo-hook' is a list of functions to be called, with no arguments,
- ...," but rather just "The hook foo-hook is called...".
-
- * mh-mime.el (mh-mh-to-mime): Ditto.
-
- * mh-pick.el (mh-pick-mode): Ditto.
-
- * mh-utils.el (mh-showing-mode): Use uppercase for argument in
- docstring.
- (mh-seq-list, mh-seen-list, mh-showing-with-headers): Move comment
- into docstring.
- (mh-show-mode, mh-show-msg, mh-find-path): Sync docstrings with
- manual.
-
-2005-12-19 Stephen Gildea <gildea@stop.mail-abuse.org>
-
- * mh-customize.el (mh-after-commands-processed-hook): New variable.
- (mh-before-commands-processed-hook): Rename mh-folder-updated-hook.
-
- * mh-e.el (mh-process-commands): Rename mh-folder-updated-hook to
- mh-before-commands-processed-hook, call new
- mh-after-commands-processed-hook.
- (mh-folders-changed): New variable (for use in
- mh-after-commands-processed-hook).
-
-2005-12-19 Bill Wohler <wohler@newt.com>
-
- * mh-acros.el:
- * mh-alias.el:
- * mh-comp.el:
- * mh-customize.el:
- * mh-e.el:
- * mh-funcs.el:
- * mh-gnus.el:
- * mh-identity.el:
- * mh-inc.el:
- * mh-index.el:
- * mh-init.el:
- * mh-junk.el:
- * mh-mime.el:
- * mh-pick.el:
- * mh-print.el:
- * mh-seq.el:
- * mh-speed.el:
- * mh-utils.el:
- Follow commenting conventions. Don't use ;;; form so much, except
- for headings. Precede headings with page feed. This was mostly
- already done, so I made it a convention. Did not update copyright
- on a couple of files since this was an insignificant change.
-
-2005-12-18 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-toolbar): Rename to mh-tool-bar.
- (mh-tool-bar-search-function): Sync docstrings with manual.
- (mh-tool-bar-customize): Replace toolbar with tool bar in docstring.
- (mh-tool-bar-letter-help): Fix manual reference.
- (mh-xemacs-use-toolbar-flag): Rename to
- mh-xemacs-use-tool-bar-flag. Initialize to
- mh-xemacs-has-tool-bar-flag. Sync docstrings with manual.
- (mh-xemacs-toolbar-position): Rename to
- mh-xemacs-tool-bar-position. Initialize to nil. Drop "no tool bar"
- option (redundant) and change "Same As Default Tool Bar" setting
- to nil. Sync docstrings with manual.
- (mh-tool-bar-define): Replace toolbar with tool-bar or tool bar
- depending on context.
- (mh-toolbar-init): Rename to mh-tool-bar-init. Simplify condition
- for calling set-specifier. Only look at the value of
- mh-xemacs-use-tool-bar-flag.
- (mh-tool-bar-folder-buttons, mh-tool-bar-letter-buttons):
- Sync docstrings with manual.
-
- * mh-comp.el (mh-letter-mode): Use mh-tool-bar-init instead of
- mh-toolbar-init.
-
- * mh-e.el (mh-folder-mode): Ditto.
-
- * mh-utils.el (mh-show-mode): Ditto.
-
-2005-12-15 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-delete-msg): Sync docstrings with manual.
-
- * mh-seq.el (mh-delete-subject, mh-thread-next-sibling)
- (mh-thread-previous-sibling, mh-thread-ancestor)
- (mh-thread-delete, mh-thread-refile): Ditto.
-
-2005-12-14 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-speed-flists-interval): Rename to
- mh-speed-update-interval.
- (mh-speed-run-flists-flag): Delete.
- Setting mh-speed-flists-interval to 0 accomplishes the same thing.
-
- * mh-speed.el (mh-folder-speedbar-buttons, mh-speed-flists):
- Use mh-speed-update-interval instead of mh-speed-run-flists-flag.
- (mh-speed-toggle, mh-speed-view, mh-speed-refresh):
- Sync docstrings with manual.
-
-2005-12-09 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-path): Move here from mh-init.el.
- (mh-variant): Mention that mh-path can be customized.
- (mh-invisible-header-fields-internal): Add X-ContentStamp,
- X-MAIL-INFO, and X-UNTD- from NetZero.
-
- * mh-init.el (mh-path): Move defcustom to mh-customize.el.
-
-2005-12-04 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-sortm-args): Sync docstrings with manual.
- (mh-invisible-header-fields-internal): Add X-Bugzilla-* and
- X-Virus-Scanned.
-
- * mh-customize.el (mh-insert-signature-hook):
- Rename mh-letter-insert-signature-hook to mh-insert-signature-hook.
-
- * mh-comp.el (mh-insert-signature): Ditto.
-
- * mh-customize.el (mh-fetch-x-image-url): Change default from 'ask
- to nil. Remove t option. Sync docstring with manual (closes SF
- #831278).
- (mh-invisible-header-fields-internal): Remove X-Image-URL so that
- users can see it, look it up in the manual's index, and discover
- mh-fetch-x-image-url (closes SF #831278).
-
- * mh-customize.el (mh-new-messages-folders): Rename from
- mh-index-new-messages-folders.
- (mh-ticked-messages-folders): Rename from
- mh-index-ticked-messages-folders.
-
- * mh-index.el (mh-index-sequenced-messages)
- (mh-index-new-messages): Ditto.
-
- * mh-comp.el (mh-forward): Went over all uses of the word "RANGE"
- in the docstrings and made usage consistent. Generally speaking,
- "messages in range" and "range of messages" is redundant and just
- "range" can be used in most circumstances. Also ensured that
- mh-interactive-range was mentioned in all interactive functions
- that use a range which describes the range argument for both users
- and programmers.
-
- * mh-e.el (mh-delete-msg-no-motion, mh-refile-msg)
- (mh-refile-or-write-again, mh-rescan-folder, mh-undo)
- (mh-visit-folder, mh-scan-folder, mh-regenerate-headers)
- (mh-notate-user-sequences, mh-delete-msg-from-seq, mh-catchup):
- Ditto.
-
- * mh-funcs.el (mh-copy-msg, mh-pack-folder, mh-pack-folder-1):
- Ditto.
-
- * mh-junk.el (mh-junk-blacklist, mh-junk-whitelist): Ditto.
-
- * mh-print.el (mh-ps-print-range, mh-ps-print-msg)
- (mh-ps-print-msg-file, mh-print-msg): Ditto.
-
- * mh-seq.el (mh-put-msg-in-seq, mh-range-to-msg-list)
- (mh-narrow-to-range, mh-toggle-tick): Ditto.
-
-2005-12-01 Bill Wohler <wohler@newt.com>
-
- Rewrote Reading Mail chapter in manual which affected mh-show
- customization group and related functions.
-
- * mh-comp.el (mh-letter-mode): Use mh-highlight-citation-style
- instead of mh-highlight-citation-p.
- (mh-letter-toggle-header-field-display): "Ellipsed" isn't a word,
- I think, so use "truncated".
-
- * mh-customize.el (mh-folder, mh-folder-faces): Group's manual
- section is Folders, not Organizing. Parent of mh-folder-faces is
- mh-folder, not mh-show.
- (mh-speed): Rename to mh-speedbar for consistency with mh-toolbar.
- (mh-thread): New group that corresponds with manual's Threading chapter.
- (mh-letter-faces): Group's manual section is Editing Drafts, not
- Sending Mail.
- (mh-sortm-args): New customization variable that used to be a defvar.
- (mh-index-new-messages-folders, mh-index-ticked-messages-folders):
- Move from mh-index group to mh-folders group.
- (mh-alias-local-users-prefix, mh-large-folder)
- (mh-recursive-folders-flag, mh-before-quit-hook)
- (mh-folder-mode-hook, mh-kill-folder-suppress-prompt-hook)
- (mh-quit-hook, mh-refile-msg-hook): Move from mh-show group to
- mh-folder group.
- (mh-highlight-citation-style): Rename from
- mh-highlight-citation-p. Sync docstrings with manual.
- (mh-mhl-format-file): Rename from mhl-formfile. Sync docstrings
- with manual.
- (mh-show-threads-flag): Move from mh-show group to mh-thread
- group.
- (mh-find-path-hook): Move from mh-show group to mh-e group.
- (mh-folder-updated-hook): Add to mh-folder group.
- (mh-forward-hook): Move from mh-folder to mh-sending-mail group.
- (mh-unseen-updated-hook): Move from mh-show to mh-sequences group.
- (mh-bury-show-buffer-flag, mh-clean-message-header-flag)
- (mh-decode-mime-flag, mh-display-buttons-for-alternatives-flag)
- (mh-display-buttons-for-inline-parts-flag)
- (mh-do-not-confirm-flag, mh-fetch-x-image-url)
- (mh-graphical-smileys-flag, mh-graphical-emphasis-flag)
- (mh-invisible-header-fields-default, mh-invisible-header-fields)
- (mh-lpr-command-format, mh-max-inline-image-height)
- (mh-max-inline-image-width)
- (mh-mime-save-parts-default-directory, mh-print-background-flag)
- (mh-show-maximum-size, mh-show-use-goto-addr-flag)
- (mh-show-use-xface-flag, mh-store-default-directory)
- (mh-summary-height, mh-delete-msg-hook)
- (mh-show-hook, mh-show-mode-hook): Sync docstrings with manual.
-
- * mh-e.el (mh-scan-format-mh, mh-scan-good-msg-regexp)
- (mh-scan-deleted-msg-regexp, mh-scan-refiled-msg-regexp)
- (mh-scan-cur-msg-number-regexp, mh-scan-subject-regexp):
- Use non-fontification instead of non-fontifying.
- (mh-header-display): Use mh-mhl-format-file instead of
- mhl-formfile. Sync docstrings with manual.
- (mh-next-undeleted-msg, mh-previous-undeleted-msg): Rename arg to
- count. Sync docstrings with manual.
- (mh-refile-or-write-again): Use output from mh-write-msg-to-file
- so that message doesn't change when using this command.
- Sync docstrings with manual.
- (mh-page-msg, mh-previous-page): Rename arg to lines.
- Sync docstrings with manual.
- (mh-write-msg-to-file): Rename msg to message. Rename no-headers
- to no-header. Sync docstrings with manual.
- (mh-ps-print-map): Delete keybindings for deleted commands
- mh-ps-print-toggle-mime and mh-ps-print-msg-show.
- (mh-help-messages): Update printing help.
- (mh-delete-msg, mh-delete-msg-no-motion, mh-first-msg)
- (mh-last-msg, mh-previous-unread-msg, mh-next-button)
- (mh-prev-button, mh-folder-toggle-mime-part)
- (mh-folder-inline-mime-part, mh-folder-save-mime-part)
- (mh-next-unread-msg, mh-toggle-mime-buttons): Sync docstrings with
- manual.
-
- * mh-funcs.el (mh-sortm-args): Now a customization option and in
- mh-customize.el.
- (mh-pipe-msg): Rename include-headers to include-header.
- Sync docstrings with manual.
- (mh-burst-digest, mh-page-digest, mh-page-digest-backwards)
- (mh-store-msg): Sync docstrings with manual.
-
- * mh-mime.el (mh-mime-save-parts): Rename arg to prompt.
- Sync docstrings with manual.
- (mh-toggle-mh-decode-mime-flag): Use English in message, not Lisp.
- Sync docstrings with manual.
- (mh-mm-display-part, mh-mm-inline-message):
- Use mh-highlight-citation-style instead of mh-highlight-citation-p.
- (mh-press-button): Sync docstrings with manual.
- (mh-display-with-external-viewer): Fix default output in
- minibuffer. Sync docstrings with manual.
-
- * mh-print.el (mh-ps-print-mime, mh-ps-print-toggle-mime):
- Delete.
- (mh-ps-print-color-option): Incorporate docstring from
- ps-print-color-p.
- (mh-ps-spool-buffer): Remove unused code. Fix indent.
- Slimline docstring.
- (mh-ps-spool-msg): Slimline docstring. Rename from
- mh-ps-spool-a-msg. Rewrite to use existing show buffer when
- available.
- (mh-ps-print-range): Extract method from common code in
- mh-ps-print-msg and mh-ps-print-msg-file.
- (mh-ps-print-preprint): Clean docstring. Use filename "mh-%s".
- (mh-ps-print-msg-show): Delete. Can use either
- mh-ps-print-msg-show or mh-ps-print-msg-show to same effect with
- new code in mh-ps-spool-msg.
- (mh-print-msg): Use mh-mhl-format-file instead of mhl-formfile.
- Sync docstrings with manual.
- (mh-ps-print-msg, mh-ps-print-msg-file)
- (mh-ps-print-toggle-faces, mh-ps-print-toggle-color):
- Sync docstrings with manual.
-
- * mh-utils.el (mh-show-ps-print-msg-show)
- (mh-show-ps-print-toggle-mime): Delete.
- (mh-show-ps-print-map): Update accordingly.
- (mh-show-mode): Use mh-highlight-citation-style instead of
- mh-highlight-citation-p.
- (mh-show-xface, mh-display-msg): Use mh-mhl-format-file instead of
- mhl-formfile.
- (mh-show): Use mh-mhl-format-file instead of mhl-formfile.
- Sync docstrings with manual.
- (mh-show-font-lock-fontify-region, mh-modify, mh-goto-msg):
- Sync docstrings with manual.
-
-2005-12-01 Bill Wohler <wohler@newt.com>
-
- * mh-init.el (mh-defface-compat): Checkdoc fix.
-
- * mh-junk.el (mh-bogofilter-blacklist, mh-bogofilter-whitelist):
- Bogofilter is lowercase except at beginning of sentence and in
- titles.
-
-2005-11-04 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-min-colors-defined-flag, mh-defface-compat):
- Move to mh-init.el to minimize bulk of mh-customize.el.
-
- * mh-init.el: Modify commentary since file is used for load and
- initialization as well as setting and getting the variant.
- (mh-min-colors-defined-flag, mh-defface-compat): Move here from
- mh-customize.el.
-
- * mh-customize.el: Refactor faces. Move grayscale requirements
- last before t. Use uniform line breaks.
- (mh-min-colors-defined-flag): New variable.
- (mh-defface-compat): New function. Provides backward compatibility
- for face specs.
- (mh-show-header, mh-show-date, mh-show-cc, mh-folder-to)
- (mh-folder-refiled, mh-folder-cur-msg-number, mh-folder-cur-msg)
- (mh-folder-body): Use mh-defface-compat.
-
-2005-11-03 Dan Nicolaescu <dann@ics.uci.edu>
-
- * mh-customize.el (mh-folder-body-face, mh-folder-cur-msg-face)
- (mh-folder-cur-msg-number-face, mh-folder-refiled-face)
- (mh-folder-to-face): Use the min-colors attribute instead of the
- type attribute.
-
-2005-11-03 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-refile-preserves-sequences-flag)
- (mh-tick-seq, mh-update-sequences-after-mh-show-flag):
- Sync docstrings with manual.
-
- * mh-e.el (mh-update-sequences): Sync docstrings with manual.
-
- * mh-seq.el (mh-delete-seq, mh-list-sequences, mh-narrow-to-seq)
- (mh-widen, mh-toggle-tick, mh-narrow-to-tick): Sync docstrings
- with manual.
-
-2005-11-01 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-redist-full-contents) Convert defvar to
- defcustom.
- (mh-smail, mh-extract-rejected-mail, mh-forward, mh-redistribute)
- (mh-reply, mh-send, mh-send-other-window)
- (mh-fill-paragraph-function): Sync docstrings with manual.
- (mh-edit-again, mh-extract-rejected-mail, mh-redistribute):
- Rename msg argument to message (to make for a better docstring).
-
- * mh-customize.el (mh-redist-full-contents-flag): Convert defvar
- to defcustom. Rename by adding -flag.
- (mh-compose-forward-as-mime-flag)
- (mh-compose-letter-function, mh-forward-subject-format)
- (mh-insert-x-mailer-flag, mh-reply-default-reply-to)
- (mh-reply-show-message-flag, mh-letter-mode-hook): Sync docstrings
- with manual.
-
- * mh-print.el (mh-ps-spool-buffer, mh-ps-spool-a-msg)
- (mh-ps-print-msg): Remove debugging messages.
- (mh-ps-print-msg-show, mh-ps-print-msg-show)
- (mh-ps-print-toggle-color, mh-ps-print-toggle-mime): Remove period
- after message per conventions.
-
-2005-10-30 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (mh-scan-good-msg-regexp, mh-scan-deleted-msg-regexp)
- (mh-scan-refiled-msg-regexp, mh-scan-cur-msg-number-regexp):
- Sync docstrings with manual.
-
- * mh-customize.el (mh-compose-space-does-completion-flag)
- (mh-signature-separator-flag, mh-interpret-number-as-range-flag)
- (mh-adaptive-cmd-note-flag): Use "Non-nil means" instead of "On
- means" to remain checkdoc clean and consistent with Emacs.
- I raised this issue with the Emacs developers and Stallman agrees
- that "On means" should be allowed in custom docstrings but that
- this change requires thought and should wait until after the Emacs
- 22 release.
-
-2005-10-28 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-annotate-msg): Use new variable
- mh-scan-field-destination-offset rather than hard-coding 1.
-
- * mh-customize.el (mh-interpret-number-as-range-flag): Add * to
- docstring.
- (mh-adaptive-cmd-note-flag-check, mh-scan-format-file-check):
- New functions to check input for mh-adaptive-cmd-note-flag and
- mh-scan-format-file respectively.
- (mh-adaptive-cmd-note-flag, mh-scan-format-file): Docstring fixes,
- add :set.
-
- * mh-e.el (mh-scan-field-destination-offset): New variable.
- The destination is the -, t, b, c, or n character for Replied, To, cc,
- Bcc, or Newsgroups respectively.
- (mh-make-folder, mh-regenerate-headers, mh-generate-new-cmd-note):
- Call new function mh-msg-num-width-to-column to make leap between
- width and column more explicit.
- (mh-msg-num-width-to-column): New function that steals logic from
- old mh-set-cmd-note. Also, throw error if mh-scan-format-file
- isn't t since we can't adapt the scan lines in this case.
- (mh-set-cmd-note): Now just simply sets mh-cmd-note which will
- make the documentation more clear.
- (mh-generate-new-cmd-note): Docstring fix--mh-cmd-note is a
- column, not a width.
- (mh-add-sequence-notation, mh-remove-sequence-notation): Use new
- variable mh-scan-field-destination-offset rather than hard-coding 1.
-
- * mh-utils.el (mh-cmd-note) Synced docstring with manual.
- (mh-notate): Use new variable mh-scan-field-destination-offset
- rather than hard-coding 1.
- (mh-message-number-width): Rename to mh-msg-num-width to be
- consistent with mh-get-msg-num and mh-msg-num-width-to-column.
-
- * mh-customize.el (mh-x-face-file, mh-show-use-xface-flag)
- (mail-citation-hook): Quote URLs in docstrings and precede with
- `URL'. The former will suppress checkdoc warnings, the latter will
- turn them into hyperlinks in Emacs 22 (I just added the code to do
- that today).
- (mh-scan-format-file): Checkdoc fix.
-
-2005-10-27 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-adaptive-cmd-note-flag)
- (mh-scan-format-file, mh-scan-prog): Sync docstrings with manual.
-
- * mh-e.el (mh-scan-format-mh, mh-note-deleted, mh-note-refiled)
- (mh-note-cur, mh-scan-good-msg-regexp)
- (mh-scan-deleted-msg-regexp, mh-scan-refiled-msg-regexp)
- (mh-scan-valid-regexp, mh-scan-cur-msg-number-regexp)
- (mh-scan-date-regexp, mh-scan-rcpt-regexp, mh-scan-body-regexp)
- (mh-scan-subject-regexp, mh-scan-format-regexp)
- (mh-folder-font-lock-keywords, mh-set-cmd-note): Sync docstrings
- with manual.
-
- * mh-funcs.el (mh-note-copied): Sync docstrings with manual.
-
- * mh-utils.el (mh-goto-msg): Use mh-scan-msg-search-regexp instead
- of hard-coded string.
- (mh-mail-header-separator, mh-signature-separator-regexp):
- Use "regular expression" in docstring instead of regexp.
- (mh-scan-msg-number-regexp)
- (mh-scan-msg-overflow-regexp, mh-scan-msg-format-regexp)
- (mh-scan-msg-format-string, mh-scan-msg-search-regexp)
- (mh-cmd-note): Sync docstrings with manual.
-
- * mh-comp.el (mh-insert-signature, mh-insert-auto-fields):
- Checkdoc fixes.
-
- * mh-customize.el (mh-compose-insertion, mh-x-face-file): Ditto.
-
- * mh-mime.el (mh-mh-to-mime, mh-mml-attach-file)
- (mh-mml-secure-message-sign, mh-mml-secure-message-encrypt)
- (mh-mml-secure-message-signencrypt): Ditto.
-
-2005-10-24 Bill Wohler <wohler@newt.com>
-
- * mh-gnus.el: Load mml.el in order to see if
- mml-minibuffer-read-disposition is defined or not.
-
- * mh-mime.el: Now that mh-gnus.el loads mml, we shouldn't need the
- mml autoloads.
-
-2005-10-23 Miles Bader <miles@gnu.org>
-
- * .arch-inventory: New file.
-
-2005-10-23 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-interpret-number-as-range-flag):
- Sync docstring with manual.
-
- * mh-identity.el (mh-assoc-ignore-case): Merge with version in
- mh-alias.el and move to mh-acros.el.
-
- * mh-alias.el (mh-assoc-ignore-case): Merge with version in
- mh-identity.el and move to mh-acros.el.
-
- * mh-acros.el (mh-assoc-ignore-case): Merge of function from
- mh-identity.el and mh-alias.el.
-
- * mh-mime.el: Autoload mm-uu for mm-uu-dissect to avoid compiler
- warning in Emacs 22.
-
-2005-10-23 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-identity.el (mh-assoc-ignore-case): New macro that uses
- assoc-string (if the function is available) and falls back on
- assoc-ignore-case if assoc-string is not found.
- (mh-identity-field-handler): Use mh-assoc-ignore-case since
- assoc-ignore-case is a obsolete function in Emacs 22.
-
- * mh-e.el (mh-folder-buttons-init-flag): New variable that keeps
- track of whether the tool-bar in mh-folder-mode has been
- initialized yet.
- (mh-folder-mode): Initialize the tool-bar for folders the first
- time we get into mh-letter-mode.
-
- * mh-customize.el (mh-buffer-exists-p): New function which tests
- presence of buffers of a given mode.
- (mh-tool-bar-define): New functions mh-tool-bar-folder-buttons-init and
- mh-tool-bar-letter-buttons-init are defined. These functions are
- used to create the tool-bar from the corresponding customizable
- variables.
-
- * mh-comp.el (mh-letter-buttons-init-flag): New variable that
- keeps track of whether the tool-bar in mh-letter-mode has been
- initialized yet.
- (mh-letter-mode): Initialize the tool-bar for drafts the first
- time we get into mh-letter-mode.
-
-2005-10-23 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-letter-menu):
- Rename mh-mhn-compose-external-compressed-tar to
- mh-mh-compose-external-compressed-tar.
- Rename mh-mhn-compose-anon-ftp to mh-mh-compose-anon-ftp. Rename
- mh-edit-mhn to mh-mh-to-mime. Rename mh-mhn-directive-present-p to
- mh-mh-directive-present-p. Rename mh-revert-mhn-edit to
- mh-mh-to-mime-undo. Rename mh-gnus-pgp-support-flag to
- mh-pgp-support-flag. Rename mh-compose-insertion value from 'mhn
- to 'mh.
- (mh-insert-signature): Rename mh-mhn-directive-present-p to
- mh-mh-directive-present-p.
- (mh-send-letter): Rename mh-mhn-directive-present-p to
- mh-mh-directive-present-p. Rename mh-edit-mhn to mh-mh-to-mime.
- (mh-letter-mode-map): Rename mh-edit-mhn to mh-mh-to-mime.
- Rename mh-mhn-compose-anon-ftp to mh-mh-compose-anon-ftp.
- Rename mh-mhn-compose-external-compressed-tar to
- mh-mh-compose-external-compressed-tar. Rename mh-revert-mhn-edit
- to mh-mh-to-mime-undo. Rename mh-mhn-compose-external-type to
- mh-mh-compose-external-type. Rename mh-mhn-compose-anon-ftp to
- mh-mh-compose-anon-ftp.
- Rename mh-mhn-compose-external-compressed-tar to
- mh-mh-compose-external-compressed-tar. Rename mh-revert-mhn-edit
- to mh-mh-to-mime-undo. Rename mh-mhn-compose-external-type to
- mh-mh-compose-external-type.
- (mh-send-letter, mh-letter-mode-map): Rename mh-edit-mhn to
- mh-mh-to-mime, mh-revert-mhn-edit to mh-mh-to-mime-undo.
- (mh-reply, mh-yank-cur-msg, mh-insert-prefix-string):
- Rename mh-yank-from-start-of-msg to mh-yank-behavior.
- (mh-letter-mode, mh-to-field, mh-to-fcc, mh-insert-signature)
- (mh-check-whom, mh-insert-auto-fields, mh-send-letter)
- (mh-insert-letter, mh-yank-cur-msg, mh-insert-prefix-string)
- (mh-fully-kill-draft, mh-open-line, mh-letter-complete)
- (mh-letter-complete-or-space, mh-letter-confirm-address)
- (mh-letter-next-header-field-or-indent)
- (mh-letter-previous-header-field)
- (mh-letter-toggle-header-field-display): Sync docstrings with
- manual.
-
- * mh-customize.el (mh-edit-mhn-hook): Rename to
- mh-mh-to-mime-hook.
- (mh-yank-from-start-of-msg): Rename to mh-yank-behavior.
- (mh-compose-insertion): Rename values from 'gnus and 'mhn to 'mh
- and user-visible values from mhn and Gnus to MH and MML.
- (mh-before-send-letter-hook): Add 'ispell-message option.
- (mh-mml-method-default): Rename mh-gnus-pgp-support-flag to
- mh-pgp-support-flag.
- (mh-compose-insertion, mh-compose-space-does-completion-flag)
- (mh-delete-yanked-msg-window-flag)
- (mh-extract-from-attribution-verb, mh-ins-buf-prefix)
- (mh-letter-complete-function, mh-letter-fill-column)
- (mh-mml-method-default, mh-signature-file-name)
- (mh-signature-separator-flag, mh-x-face-file)
- (mh-yank-behavior, mail-citation-hook)
- (mh-before-send-letter-hook, mh-mh-to-mime-hook): Sync docstrings
- with manual.
-
- * mh-gnus.el (mml-minibuffer-read-disposition): New function
- provided for Emacs 21 environments that lack it.
-
- * mh-mime.el (mh-mml-query-cryptographic-method): Use default
- prompt convention.
- (mh-compose-forward): mh-mh-forward-message requires string arg.
- (mh-minibuffer-read-type): New function.
- (mh-mhn-args): Rename to mh-mh-to-mime-args.
- (mh-mhn-compose-insertion): Rename to mh-mh-attach-file.
- (mh-mhn-compose-forw): Rename to mh-mh-forward-message.
- (mh-mhn-compose-type): Rename to mh-mh-compose-type.
- (mh-mhn-compose-anon-ftp): Rename to mh-mh-compose-anon-ftp.
- Rename mh-mhn-compose-external-type to mh-mh-compose-external-type.
- (mh-mhn-compose-external-compressed-tar): Rename to
- mh-mh-compose-external-compressed-tar.
- Rename mh-mhn-compose-external-type to mh-mh-compose-external-type.
- (mh-mhn-compose-external-type): Rename to mh-mh-compose-external-type.
- (mh-edit-mhn): Rename to mh-mh-to-mime. Rename mh-mhn-args to
- mh-mh-to-mime-args. Rename mh-edit-mhn-hook to mh-mh-to-mime-hook.
- Use correct program in message.
- (mh-mhn-directive-present-p): Rename to mh-mh-directive-present-p.
- (mh-mml-directive-present-p): Rename to mh-mml-tag-present-p.
- (mh-compose-forward, mh-mh-attach-file)
- (mh-mh-compose-anon-ftp, mh-mh-compose-external-compressed-tar)
- (mh-mh-compose-external-type, mh-mh-forward-message)
- (mh-mml-attach-file): Use mml-minibuffer-read-description,
- mh-minibuffer-read-type.
- (mh-mime-content-types): Move comment about only being used in
- Emacs 20 to docstring.
- (mh-mh-compose-external-type): Rename extra-param argument to
- parameters.
- (mh-mml-to-mime, mh-secure-message, mh-mml-unsecure-message)
- (mh-mime-display-part, mh-mime-display-single):
- Rename mh-gnus-pgp-support-flag to mh-pgp-support-flag.
- (mh-compose-insertion): Rename mh-mhn-compose-insertion to
- mh-mh-attach-file.
- (mh-compose-forward): Rename mh-mhn-compose-forw to
- mh-mh-forward-message.
- (mh-mhn-compose-insertion): Rename mh-mhn-compose-type to
- mh-mh-compose-type.
- (mh-compose-insertion, mh-compose-forward, mh-mh-to-mime-args)
- (mh-mh-attach-file, mh-mh-compose-type)
- (mh-mh-compose-anon-ftp, mh-mh-compose-external-compressed-tar)
- (mh-mh-compose-external-compressed-tar)
- (mh-mh-compose-external-type, mh-mh-forward-message)
- (mh-mh-to-mime, mh-mh-quote-unescaped-sharp)
- (mh-mh-to-mime-undo, mh-mh-directive-present-p, mh-mml-to-mime)
- (mh-mml-attach-file, mh-secure-message, mh-mml-unsecure-message)
- (mh-mml-secure-message-sign, mh-mml-secure-message-encrypt)
- (mh-mml-directive-present-p, mh-destroy-postponed-handles)
- (mh-display-smileys, mh-display-emphasis, mh-mime-save-parts):
- Sync docstrings with manual.
-
- * mh-utils.el (mh-gnus-pgp-support-flag): Rename to
- mh-pgp-support-flag.
-
-2005-10-17 Peter S Galbraith <psg@debian.org>
-
- * mh-identity.el (mh-identity-field-handler): Use `assoc-ignore-case'
- to compare against header field for mixed-case "From:".
-
-2005-10-17 Bill Wohler <wohler@newt.com>
-
- * mh-customize.el (mh-folder-tool-bar-map): Rename image file
- left_arrow to left-arrow, right_arrow to right-arrow, mail_compose
- to mail/compose, fld_open to fld-open.
- (mh-letter-tool-bar-map): Rename image file mail_send to
- mail/send.
-
-2005-10-16 Bill Wohler <wohler@newt.com>
-
- * mh-comp.el (mh-display-completion-list-compat): New macro which
- calls `display-completion-list' correctly in older environments.
- Versions of Emacs prior to version 22 lacked a COMMON-SUBSTRING
- argument.
- (mh-complete-word): Use it.
-
- * mh-init.el (mh-image-load-path): Use locate-library to find
- MH-E. This simplified the code a lot. Flattened out nested
- statements even more.
-
-2005-10-16 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-init.el (mh-image-load-path): Remove use of pushnew since it
- causes a compiler warning.
-
- * mh-utils.el (mh-display-msg): Do MIME cleanup before inserting
- the message to be viewed (closes SF #1306141).
-
-2005-10-16 Masatake YAMATO <jet@gyve.org>
-
- * mh-comp.el (mh-complete-word): Pass the common prefix substring
- of completion to `display-completion-list'.
-
-2005-10-15 Satyaki Das <satyaki@theforce.stanford.edu>
-
- * mh-init.el (mh-image-load-path-called-flag): New variable which
- is used by mh-image-load-path so that it runs only once.
- (mh-image-load-path): Modify so that it gets run only once.
- Also flatten out heavily nested if statements to make it clearer.
-
- * mh-e.el (mh-folder-mode): Call mh-image-load-path to allow Emacs
- to find images used in the toolbar.
-
- * mh-customize.el (:folder): Remove call to mh-image-load-path.
-
-2005-10-14 Bill Wohler <wohler@newt.com>
-
- * mh-e.el (Version, mh-version): Add +cvs to version.
-
-2005-10-14 Bill Wohler <wohler@newt.com>
-
- Released MH-E version 7.85.
-
- * mh-e.el (Version, mh-version): Update for release 7.85.
-
-2005-10-14 Bill Wohler <wohler@newt.com>
-
- * mh-e.el, mh-funcs.el, mh-init.el, mh-mime.el, mh-pick.el:
- * mh-seq.el, mh-utils.el: Ran mh-unit. Continued copyright lines
- need to be indented.
-
- * mh-e.el: mh-folder-tick-face had been renamed to mh-folder-tick
- but the code that invoked the face had not been updated.
- Tick highlighting working again.
-
- * mh-seq.el (mh-non-seq-mode-line-annotation):
- Move make-variable-buffer-local call to top level to avoid warnings in
- CVS Emacs.
-
- * mh-comp.el (mh-insert-letter): Replace deprecated read-input
- with read-string.
-
-2005-10-09 Bill Wohler <wohler@newt.com>
-
- * mh-init.el (mh-image-load-path): New function that adds the path
- to the MH-E images to the image-load-path or load-path depending
- on the version of Emacs.
-
- * mh-customize.el: Call mh-image-load-path just before
- mh-tool-bar-define so that the toolbar images can be found.
-
-2005-10-06 Bill Wohler <wohler@newt.com>
-
- * mh-loaddefs.el: Remove. Now generated automatically.
-
-2005-10-04 Bill Wohler <wohler@newt.com>
-
- * ChangeLog: Move contents into ChangeLog.1 and trim.
-
- * ChangeLog.1: New file. Contains old ChangeLog.
-
-See ChangeLog.1 for earlier changes.
-
- Copyright (C) 2005-2024 Free Software Foundation, Inc.
-
- This file is part of GNU Emacs.
-
- GNU Emacs is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU Emacs is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;; Local Variables:
-;; coding: utf-8
-;; sentence-end-double-space: nil
-;; add-log-time-zone-rule: t
-;; End:
+++ /dev/null
-;;; mh-acros.el --- macros used in MH-E -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc.
-
-;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file contains all macros that are used in more than one file.
-;; If you run "make recompile" in Bazaar Emacs and see the message
-;; "Source is newer than compiled," it is a sign that macro probably
-;; needs to be moved here.
-
-;; Historically, it was so named with a silent "m" so that it would be
-;; compiled first. Otherwise, "make recompile" in Bazaar Emacs would use
-;; compiled files with stale macro definitions. Later, no-byte-compile
-;; was added to the Local Variables section to avoid this problem and
-;; because it's pointless to compile a file full of macros. But we
-;; kept the name.
-
-;;; Code:
-
-(require 'cl-lib)
-
-\f
-
-;;; Miscellaneous
-
-;;;###mh-autoload
-(defmacro with-mh-folder-updating (save-modification-flag &rest body)
- "Format is (with-mh-folder-updating (SAVE-MODIFICATION-FLAG) &body BODY).
-Execute BODY, which can modify the folder buffer without having to
-worry about file locking or the read-only flag, and return its result.
-If SAVE-MODIFICATION-FLAG is non-nil, the buffer's modification flag
-is unchanged, otherwise it is cleared."
- (declare (debug t) (indent defun))
- (setq save-modification-flag (car save-modification-flag)) ; CL style
- `(prog1
- (let ((mh-folder-updating-mod-flag (buffer-modified-p))
- (buffer-read-only nil)
- (buffer-file-name nil)) ;don't let the buffer get locked
- (prog1
- (progn
- ,@body)
- (mh-set-folder-modified-p mh-folder-updating-mod-flag)))
- ,@(if (not save-modification-flag)
- '((mh-set-folder-modified-p nil)))))
-
-;;;###mh-autoload
-(defmacro mh-in-show-buffer (show-buffer &rest body)
- "Format is (mh-in-show-buffer (SHOW-BUFFER) &body BODY).
-Display buffer SHOW-BUFFER in other window and execute BODY in it.
-Stronger than `save-excursion', weaker than `save-window-excursion'."
- (declare (debug t) (indent defun))
- (setq show-buffer (car show-buffer)) ; CL style
- `(let ((mh-in-show-buffer-saved-window (selected-window)))
- (switch-to-buffer-other-window ,show-buffer)
- (if mh-bury-show-buffer-flag (bury-buffer (current-buffer)))
- (unwind-protect
- (progn
- ,@body)
- (select-window mh-in-show-buffer-saved-window))))
-
-;;;###mh-autoload
-(defmacro mh-do-at-event-location (event &rest body)
- "Switch to the location of EVENT and execute BODY.
-After BODY has been executed return to original window.
-The modification flag of the buffer in the event window is
-preserved."
- (declare (debug t) (indent defun))
- (let ((event-window (make-symbol "event-window"))
- (event-position (make-symbol "event-position"))
- (original-window (make-symbol "original-window"))
- (original-position (make-symbol "original-position"))
- (modified-flag (make-symbol "modified-flag")))
- `(save-excursion
- (let* ((,event-window (posn-window (event-start ,event)))
- (,event-position (posn-point (event-start ,event)))
- (,original-window (selected-window))
- (,original-position (progn
- (set-buffer (window-buffer ,event-window))
- (point-marker)))
- (,modified-flag (buffer-modified-p))
- (buffer-read-only nil))
- (unwind-protect (progn
- (select-window ,event-window)
- (goto-char ,event-position)
- ,@body)
- (set-buffer-modified-p ,modified-flag)
- (goto-char ,original-position)
- (set-marker ,original-position nil)
- (select-window ,original-window))))))
-
-\f
-
-;;; Sequences and Ranges
-
-;;;###mh-autoload
-(defsubst mh-seq-msgs (sequence)
- "Extract messages from the given SEQUENCE."
- (cdr sequence))
-
-;;;###mh-autoload
-(defmacro mh-iterate-on-messages-in-region (var begin end &rest body)
- "Iterate over region.
-
-VAR is bound to the message on the current line as we loop
-starting from BEGIN till END. In each step BODY is executed.
-
-If VAR is nil then the loop is executed without any binding."
- (declare (debug (symbolp body)) (indent defun))
- (unless (symbolp var)
- (error "Can not bind the non-symbol %s" var))
- (let ((binding-needed-flag var))
- `(save-excursion
- (goto-char ,begin)
- (beginning-of-line)
- (while (and (<= (point) ,end) (not (eobp)))
- (when (looking-at mh-scan-valid-regexp)
- (let ,(if binding-needed-flag `((,var (mh-get-msg-num t))) ())
- ,@body))
- (forward-line 1)))))
-
-;;;###mh-autoload
-(defmacro mh-iterate-on-range (var range &rest body)
- "Iterate an operation over a region or sequence.
-
-VAR is bound to each message in turn in a loop over RANGE, which
-can be a message number, a list of message numbers, a sequence, a
-region in a cons cell, or a MH range (something like last:20) in
-a string. In each iteration, BODY is executed.
-
-The parameter RANGE is usually created with
-`mh-interactive-range' in order to provide a uniform interface to
-MH-E functions."
- (declare (debug (symbolp body)) (indent defun))
- (unless (symbolp var)
- (error "Can not bind the non-symbol %s" var))
- (let ((binding-needed-flag var)
- (msgs (make-symbol "msgs"))
- (seq-hash-table (make-symbol "seq-hash-table")))
- `(cond ((numberp ,range)
- (when (mh-goto-msg ,range t t)
- (let ,(if binding-needed-flag `((,var ,range)) ())
- ,@body)))
- ((and (consp ,range)
- (numberp (car ,range)) (numberp (cdr ,range)))
- (mh-iterate-on-messages-in-region ,var
- (car ,range) (cdr ,range)
- ,@body))
- (t (let ((,msgs (cond ((and ,range (symbolp ,range))
- (mh-seq-to-msgs ,range))
- ((stringp ,range)
- (mh-translate-range mh-current-folder
- ,range))
- (t ,range)))
- (,seq-hash-table (make-hash-table)))
- (dolist (msg ,msgs)
- (setf (gethash msg ,seq-hash-table) t))
- (mh-iterate-on-messages-in-region v (point-min) (point-max)
- (when (gethash v ,seq-hash-table)
- (let ,(if binding-needed-flag `((,var v)) ())
- ,@body))))))))
-
-(defmacro mh-dlet* (binders &rest body)
- "Like `let*' but always dynamically scoped."
- (declare (debug let) (indent 1))
- ;; Works in both lexical and non-lexical mode.
- `(progn
- (with-suppressed-warnings ((lexical
- ,@(mapcar (lambda (binder)
- (if (consp binder)
- (car binder)
- binder))
- binders)))
- ,@(mapcar (lambda (binder)
- `(defvar ,(if (consp binder) (car binder) binder)))
- binders)
- (let* ,binders ,@body))))
-
-;; Emacs 24 made flet obsolete and suggested either cl-flet or
-;; cl-letf. This macro is based upon gmm-flet from Gnus.
-(defmacro mh-flet (bindings &rest body)
- "Make temporary overriding function definitions.
-That is, temporarily rebind the functions listed in BINDINGS and then
-execute BODY. BINDINGS is a list containing one or more lists of the
-form (FUNCNAME ARGLIST BODY...), similar to defun."
- (declare (indent 1) (debug ((&rest (sexp sexp &rest form)) &rest form)))
- (if (fboundp 'cl-letf)
- `(cl-letf ,(mapcar (lambda (binding)
- `((symbol-function ',(car binding))
- (lambda ,@(cdr binding))))
- bindings)
- ,@body)
- `(flet ,bindings ,@body)))
-
-(provide 'mh-acros)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-acros.el ends here
+++ /dev/null
-;;; mh-alias.el --- MH-E mail alias completion and expansion -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1994-1997, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Peter S. Galbraith <psg@debian.org>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'mh-e)
-
-(require 'goto-addr)
-
-(defvar mh-alias-alist 'not-read
- "Alist of MH aliases.")
-(defvar mh-alias-blind-alist nil
- "Alist of MH aliases that are blind lists.")
-(defvar mh-alias-passwd-alist nil
- "Alist of aliases extracted from passwd file and their expansions.")
-(defvar mh-alias-tstamp nil
- "Time aliases were last loaded.")
-(defvar mh-alias-read-address-map
- (let ((map (copy-keymap minibuffer-local-completion-map)))
- (define-key map "," #'mh-alias-minibuffer-confirm-address)
- (define-key map " " #'self-insert-command)
- map))
-
-(defcustom mh-alias-system-aliases
- '("/etc/nmh/MailAliases" "/etc/mh/MailAliases"
- "/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]."
- :type '(repeat file)
- :group 'mh-alias)
-
-\f
-
-;;; 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.
-If ARG is non-nil, set timestamp with the current time."
- (if arg
- (setq mh-alias-tstamp (current-time))
- (let ((stamp))
- (car (memq t (mapcar
- (lambda (file)
- (when (and file (file-exists-p file))
- (setq stamp (file-attribute-modification-time
- (file-attributes file)))
- (time-less-p mh-alias-tstamp stamp)))
- (mh-alias-filenames t)))))))
-
-(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."
- (or mh-progs (mh-find-path))
- (save-excursion
- (let* ((filename (mh-profile-component "Aliasfile"))
- (filelist (and filename (split-string filename "[ \t]+")))
- (userlist
- (mapcar
- (lambda (file)
- (if (and mh-user-path file
- (file-exists-p (expand-file-name file mh-user-path)))
- (expand-file-name file mh-user-path)))
- filelist)))
- (if arg
- (if (stringp mh-alias-system-aliases)
- (append userlist (list mh-alias-system-aliases))
- (append userlist mh-alias-system-aliases))
- userlist))))
-
-(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."
- (let ((res gecos-name))
- ;; Keep only string until first comma if COMMA-SEPARATOR is t.
- (if (and comma-separator
- (string-match "^\\([^,]+\\)," res))
- (setq res (match-string 1 res)))
- ;; Replace "&" with capitalized username
- (if (string-search "&" res)
- (setq res (replace-regexp-in-string "&" (capitalize username) res)))
- ;; Remove " character
- (if (string-search "\"" res)
- (setq res (replace-regexp-in-string "\"" "" res)))
- ;; If empty string, use username instead
- (if (string-equal "" res)
- (setq res username))
- ;; Surround by quotes if doesn't consist of simple characters
- (if (not (string-match "^[ a-zA-Z0-9-]+$" res))
- (setq res (concat "\"" res "\"")))
- res))
-
-(defun mh-alias-local-users ()
- "Return an alist of local users from /etc/passwd.
-Exclude all aliases already in `mh-alias-alist' from \"ali\""
- (let (passwd-alist)
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (cond
- ((eq mh-alias-local-users t)
- (if (file-readable-p "/etc/passwd")
- (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 t)
- (goto-char (point-min))))
- (while (< (point) (point-max))
- (cond
- ((looking-at "\\([^:]*\\):[^:]*:\\([^:]*\\):[^:]*:\\([^:]*\\):")
- (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))
- (alias-translation
- (if (string-equal username realname)
- (concat "<" username ">")
- (concat realname " <" username ">"))))
- (when (not (assoc-string alias-name mh-alias-alist t))
- (setq passwd-alist (cons (list alias-name alias-translation)
- passwd-alist)))))))
- (forward-line 1)))
- passwd-alist))
-
-(defun mh-alias-reload ()
- "Reload MH aliases.
-
-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.
-
-This function runs `mh-alias-reloaded-hook' after the aliases have
-been loaded."
- (interactive)
- (save-excursion
- (message "Loading MH aliases...")
- (mh-alias-tstamp t)
- (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser")
- (setq mh-alias-alist nil)
- (setq mh-alias-blind-alist nil)
- (while (< (point) (point-max))
- (cond
- ((looking-at "^[ \t]")) ;Continuation line
- ((looking-at "\\(.+\\): .+: .*$") ; A new -blind- MH alias
- (when (not (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 (assoc-string (match-string 1) mh-alias-alist t))
- (setq mh-alias-alist
- (cons (list (match-string 1)) mh-alias-alist)))))
- (forward-line 1)))
- (when mh-alias-local-users
- (setq mh-alias-passwd-alist (mh-alias-local-users))
- ;; Update aliases with local users, but leave existing aliases alone.
- (let ((local-users mh-alias-passwd-alist)
- user)
- (while local-users
- (setq user (car local-users))
- (if (not (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)
- (message "Loading MH aliases...done"))
-
-;;;###mh-autoload
-(defun mh-alias-reload-maybe ()
- "Load new MH aliases."
- (if (or (eq mh-alias-alist 'not-read) ; Doesn't exist?
- (mh-alias-tstamp nil)) ; Out of date?
- (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."
- (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-char -1))
- (buffer-substring (point-min)(point-max)))
- (error (progn
- (message "%s" (error-message-string err))
- alias))))
-
-;;;###mh-autoload
-(defun mh-alias-expand (alias)
- "Return expansion for ALIAS.
-Blind aliases or users from /etc/passwd are not expanded."
- (cond
- ((assoc-string alias mh-alias-blind-alist t)
- alias) ; Don't expand a blind alias
- ((assoc-string alias mh-alias-passwd-alist t)
- (cadr (assoc-string alias mh-alias-passwd-alist t)))
- (t
- (mh-alias-ali alias))))
-
-;;;###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
- (read-string prompt)
- (let* ((minibuffer-local-completion-map mh-alias-read-address-map)
- (completion-ignore-case mh-alias-completion-ignore-case-flag)
- (the-answer (completing-read-multiple 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 alias or blind first
- (mapconcat #'mh-alias-expand the-answer ",\n ")))))
-
-;;;###mh-autoload
-(defun mh-alias-minibuffer-confirm-address ()
- "Display the alias expansion if `mh-alias-flash-on-comma' is non-nil."
- (interactive)
- (when mh-alias-flash-on-comma
- (save-excursion
- (let* ((case-fold-search t)
- (beg (mh-beginning-of-word))
- (the-name (buffer-substring-no-properties beg (point))))
- (if (assoc-string the-name mh-alias-alist t)
- (message "%s -> %s" the-name (mh-alias-expand the-name))
- ;; Check if it was a single word likely to be an alias
- (if (and (equal mh-alias-flash-on-comma 1)
- (not (string-search " " the-name)))
- (message "No alias for %s" the-name))))))
- (self-insert-command 1))
-
-;;;###mh-autoload
-(defun mh-alias-letter-expand-alias ()
- "Expand mail alias before point."
- (mh-alias-reload-maybe)
- (let* ((begin (mh-beginning-of-word))
- (end (save-excursion
- (goto-char begin)
- (mh-beginning-of-word -1))))
- (when (>= end (point))
- (list
- begin (if (fboundp 'completion-at-point) end (point))
- (if (not mh-alias-expand-aliases-flag)
- mh-alias-alist
- (lambda (string pred action)
- (cl-case action
- ((nil)
- (let ((res (try-completion string mh-alias-alist pred)))
- (if (or (eq res t)
- (and (stringp res)
- (eq t (try-completion res mh-alias-alist pred))))
- (or (mh-alias-expand (if (stringp res) res string))
- res)
- res)))
- ((t) (all-completions string mh-alias-alist pred))
- ((lambda) (test-completion string mh-alias-alist pred)))))))))
-\f
-
-;;; 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."
- (cond
- ((string-match "^<\\(.*\\)>$" string)
- ;; <somename@foo.bar> -> recurse, stripping brackets.
- (mh-alias-suggest-alias (match-string 1 string) no-comma-swap))
- ((string-match "^\\sw+$" string)
- ;; One word -> downcase it.
- (downcase string))
- ((string-match "^\\(\\sw+\\)\\s-+\\(\\sw+\\)$" string)
- ;; Two words -> first.last
- (downcase
- (format "%s.%s" (match-string 1 string) (match-string 2 string))))
- ((string-match "^\\([-a-zA-Z0-9._]+\\)@[-a-zA-Z0-9_]+\\.+[a-zA-Z0-9]+$"
- string)
- ;; email only -> downcase username
- (downcase (match-string 1 string)))
- ((string-match "^\"\\(.*\\)\".*" string)
- ;; "Some name" <somename@foo.bar> -> recurse -> "Some name"
- (mh-alias-suggest-alias (match-string 1 string) no-comma-swap))
- ((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 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)
- ;; Strip out title
- (mh-alias-suggest-alias (match-string 2 string) no-comma-swap))
- ((string-match "^\\(.*\\), +\\(Jr\\.?\\|II+\\)$" string)
- ;; Strip out tails with comma
- (mh-alias-suggest-alias (match-string 1 string) no-comma-swap))
- ((string-match "^\\(.*\\) +\\(Jr\\.?\\|II+\\)$" string)
- ;; Strip out tails
- (mh-alias-suggest-alias (match-string 1 string) no-comma-swap))
- ((string-match "^\\(\\sw+\\) +[A-Z]\\.? +\\(.*\\)$" string)
- ;; Strip out initials
- (mh-alias-suggest-alias
- (format "%s %s" (match-string 1 string) (match-string 2 string))
- no-comma-swap))
- ((and (not no-comma-swap)
- (string-match "^\\([^,]+\\), +\\(.*\\)$" string))
- ;; Reverse order of comma-separated fields to handle:
- ;; From: "Galbraith, Peter" <psg@debian.org>
- ;; but don't this for a name string extracted from the passwd file
- ;; with mh-alias-passwd-gecos-comma-separator-flag set to nil.
- (mh-alias-suggest-alias
- (format "%s %s" (match-string 2 string) (match-string 1 string))
- no-comma-swap))
- (t
- ;; Output string, with spaces replaced by dots.
- (mh-alias-canonicalize-suggestion string))))
-
-(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."
- (with-temp-buffer
- (insert string)
- ;; Replace spaces with periods
- (goto-char (point-min))
- (while (re-search-forward " +" nil t)
- (replace-match "." nil nil))
- ;; Replace commas with periods
- (goto-char (point-min))
- (while (re-search-forward ",+" nil t)
- (replace-match "." nil nil))
- ;; Replace consecutive periods with a single period
- (goto-char (point-min))
- (while (re-search-forward "\\.\\.+" nil t)
- (replace-match "." nil nil))
- ;; 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."
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (let ((the-list file-list)
- (found))
- (while the-list
- (erase-buffer)
- (when (file-writable-p (car file-list))
- (insert-file-contents (car file-list))
- (if (re-search-forward (concat "^" (regexp-quote alias) ":") nil t)
- (setq found (car file-list)
- the-list nil)
- (setq the-list (cdr the-list)))))
- found)))
-
-(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."
- (cond
- ((and mh-alias-insert-file (listp mh-alias-insert-file))
- (if (not (elt mh-alias-insert-file 1)) ; Only one entry, use it
- (car mh-alias-insert-file)
- (if (or (not alias)
- (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist
- (completing-read "Alias file: "
- (mapcar #'list mh-alias-insert-file) nil t)
- (or (mh-alias-which-file-has-alias alias mh-alias-insert-file)
- (completing-read "Alias file: "
- (mapcar #'list mh-alias-insert-file) nil t)))))
- ((and mh-alias-insert-file (stringp mh-alias-insert-file))
- mh-alias-insert-file)
- (t
- ;; writable ones returned from (mh-alias-filenames):
- (let ((autolist (delq nil (mapcar (lambda (file)
- (if (and (file-writable-p file)
- (not (string-equal
- file "/etc/passwd")))
- file))
- (mh-alias-filenames t)))))
- (cond
- ((not autolist)
- (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)
- (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist
- (completing-read "Alias file: " autolist nil t))
- (t
- (or (mh-alias-which-file-has-alias alias autolist)
- (completing-read "Alias file: " autolist nil t))))))))
-
-;;;###mh-autoload
-(defun mh-alias-address-to-alias (address)
- "Return the ADDRESS alias if defined, or nil."
- (let* ((aliases (mh-alias-ali address t)))
- (if (string-equal aliases address)
- nil ; ali returned same string -> no.
- ;; Double-check that we have an individual alias. This means that the
- ;; alias doesn't expand into a list (of which this address is part).
- (car (delq nil (mapcar
- (lambda (alias)
- (let ((recurse (mh-alias-ali alias nil)))
- (if (string-match ".*,.*" recurse)
- nil
- alias)))
- (split-string aliases ", +")))))))
-
-;;;###mh-autoload
-(defun mh-alias-for-from-p ()
- "Return t if sender's address has a corresponding alias."
- (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))
- (let ((from-header (mh-extract-from-header-value)))
- (and from-header
- (mh-alias-address-to-alias from-header)
- t)))))
-
-(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."
- (if (not file)
- (setq file (mh-alias-insert-file alias)))
- (with-current-buffer (find-file-noselect file)
- (goto-char (point-min))
- (let ((alias-search (concat alias ":"))
- (letter)
- (case-fold-search t))
- (cond
- ;; Search for exact match (if we had the same alias before)
- ((re-search-forward
- (concat "^" (regexp-quote alias-search) " *\\(.*\\)") nil t)
- (let ((answer (read-string
- (format (concat "Alias %s exists; insert new address "
- "[b]efore or [a]fter: ")
- (match-string 1))))
- (case-fold-search t))
- (cond ((string-match "^b" answer))
- ((string-match "^a" answer)
- (forward-line 1))
- (t
- (error "Unrecognized response")))))
- ;; No, so sort-in at the right place
- ;; search for "^alias", then "^alia", etc.
- ((eq mh-alias-insertion-location 'sorted)
- (setq letter (substring alias-search -1)
- alias-search (substring alias-search 0 -1))
- (while (and (not (equal alias-search ""))
- (not (re-search-forward
- (concat "^" (regexp-quote alias-search)) nil t)))
- (setq letter (substring alias-search -1)
- alias-search (substring alias-search 0 -1)))
- ;; Next, move forward to sort alphabetically for following letters
- (beginning-of-line)
- (while (re-search-forward
- (concat "^" (regexp-quote alias-search) "[a-" letter "]")
- nil t)
- (forward-line 1)))
- ((eq mh-alias-insertion-location 'bottom)
- (goto-char (point-max)))
- ((eq mh-alias-insertion-location 'top)
- (goto-char (point-min)))))
- (beginning-of-line)
- (insert (format "%s: %s\n" alias address))
- (save-buffer)))
-
-(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."
- (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)
- (setq alias-address nil))
- (cond
- ((and (equal alias address-alias)
- (equal address 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))
- (mh-alias-add-alias-to-file alias address)))
- (t
- (mh-alias-add-alias-to-file alias address)))))
-
-;;;###mh-autoload
-(defun mh-alias-grab-from-field ()
- "Add alias for the sender of the current message."
- (interactive)
- (mh-alias-reload-maybe)
- (save-excursion
- (cond
- ((mh-folder-line-matches-show-buffer-p)
- (set-buffer mh-show-buffer))
- ((and (eq major-mode 'mh-folder-mode)
- (mh-get-msg-num nil))
- (set-buffer (get-buffer-create mh-temp-buffer))
- (insert-file-contents (mh-msg-filename (mh-get-msg-num t))))
- ((eq major-mode 'mh-folder-mode)
- (user-error "Cursor not pointing to a message")))
- (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))))
-
-(defun mh-alias-add-address-under-point ()
- "Insert an alias for address under point."
- (interactive)
- (let ((address (goto-address-find-address-at-point)))
- (if address
- (mh-alias-add-alias nil address)
- (message "No email address found under point"))))
-
-(defun mh-alias-apropos (regexp)
- "Show all aliases or addresses that match a regular expression REGEXP."
- (interactive "sAlias regexp: ")
- (if mh-alias-local-users
- (mh-alias-reload-maybe))
- (let ((matches "")
- (group-matches "")
- (passwd-matches))
- (save-excursion
- (message "Reading MH aliases...")
- (mh-exec-cmd-quiet t "ali" "-nolist" "-nouser")
- (message "Parsing MH aliases...")
- (while (re-search-forward regexp nil t)
- (beginning-of-line)
- (cond
- ((looking-at "^[ \t]") ;Continuation line
- (setq group-matches
- (concat group-matches
- (buffer-substring
- (save-excursion
- (or (re-search-backward "^[^ \t]" nil t)
- (point)))
- (progn
- (if (re-search-forward "^[^ \t]" nil t)
- (forward-char -1))
- (point))))))
- (t
- (setq matches
- (concat matches
- (buffer-substring (point)(progn (end-of-line)(point)))
- "\n")))))
- (message "Parsing MH aliases...done")
- (when mh-alias-local-users
- (message "Making passwd aliases...")
- (setq passwd-matches
- (mapconcat
- (lambda (elem)
- (if (or (string-match regexp (car elem))
- (string-match regexp (cadr elem)))
- (format "%s: %s\n" (car elem) (cadr elem))))
- mh-alias-passwd-alist ""))
- (message "Making passwd aliases...done")))
- (if (and (string-equal "" matches)
- (string-equal "" group-matches)
- (string-equal "" passwd-matches))
- (message "No matches")
- (with-output-to-temp-buffer mh-aliases-buffer
- (if (not (string-equal "" matches))
- (princ matches))
- (when (not (string-equal group-matches ""))
- (princ "\nGroup Aliases:\n\n")
- (princ group-matches))
- (when (not (string-equal passwd-matches ""))
- (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:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-alias.el ends here
+++ /dev/null
-;;; mh-buffers.el --- MH-E buffer constants and utilities -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 1997, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-;; The names of ephemeral buffers have a " *mh-" prefix (so that they
-;; are hidden and can be programmatically removed in mh-quit), and the
-;; variable names have the form mh-temp-.*-buffer.
-(defconst mh-temp-buffer " *mh-temp*") ;scratch
-(defconst mh-temp-checksum-buffer " *mh-checksum*")
-(defconst mh-temp-fetch-buffer " *mh-fetch*") ;wget/curl/fetch output
-(defconst mh-temp-index-buffer " *mh-index*")
-
-;; The names of MH-E buffers that are not ephemeral and can be used by
-;; the user (and deleted by the user when no longer needed) have a
-;; "*MH-E " prefix (so they can be programmatically removed in
-;; mh-quit), and the variable names have the form mh-.*-buffer.
-;; Temporary buffers for search results
-(defconst mh-aliases-buffer "*MH-E Aliases*") ;alias lookups
-(defconst mh-folders-buffer "*MH-E Folders*") ;folder list
-(defconst mh-help-buffer "*MH-E Help*") ;quick help
-(defconst mh-info-buffer "*MH-E Info*") ;version information buffer
-(defconst mh-log-buffer "*MH-E Log*") ;output of MH commands and so on
-(defconst mh-mail-delivery-buffer "*MH-E Mail Delivery*") ;mail delivery log
-(defconst mh-recipients-buffer "*MH-E Recipients*") ;killed when draft sent
-(defconst mh-sequences-buffer "*MH-E Sequences*") ;sequences list
-
-(defvar mh-log-buffer-lines 100
- "Number of lines to keep in `mh-log-buffer'.")
-
-\f
-
-(defun mh-truncate-log-buffer ()
- "If `mh-log-buffer' is too big then truncate it.
-If the number of lines in `mh-log-buffer' exceeds
-`mh-log-buffer-lines' then keep only the last
-`mh-log-buffer-lines'. As a side effect the point is set to the
-end of the log buffer.
-
-The function returns the size of the final size of the log buffer."
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (goto-char (point-max))
- (save-excursion
- (when (equal (forward-line (- mh-log-buffer-lines)) 0)
- (delete-region (point-min) (point))))
- (unless (or (bobp)
- (save-excursion
- (and (equal (forward-line -1) 0) (equal (char-after) ?\f))))
- (insert "\n\f\n"))
- (buffer-size)))
-
-(provide 'mh-buffers)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-buffers.el ends here
+++ /dev/null
-;;; mh-comp.el --- MH-E functions for composing and sending messages -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 1997, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file includes the functions in the MH-Folder maps that get us
-;; into MH-Letter mode, as well the functions in the MH-Letter mode
-;; that are used to send the mail. Other that those, functions that
-;; are needed in mh-letter.el should be found there.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-gnus) ;needed because mh-gnus.el not compiled
-(require 'mh-scan)
-
-(require 'sendmail)
-
-(autoload 'easy-menu-add "easymenu")
-(autoload 'mail-header-parse-address "mail-parse")
-(autoload 'mml-insert-tag "mml")
-
-\f
-
-;;; Site Customization
-
-(defvar mh-send-prog "send"
- "Name of the MH send program.
-Some sites need to change this because of a name conflict.")
-
-(defvar mh-send-uses-spost-flag nil
- "Non-nil means \"send\" uses \"spost\" to submit messages.
-
-If the value of \"postproc:\" is \"spost\", you may need to set
-this variable to t to tell MH-E to avoid using features of
-\"post\" that are not supported by \"spost\". You'll know that
-you'll need to do this if sending mail fails with an error of
-\"spost: -msgid unknown\".")
-
-(defvar mh-redist-background nil
- "If non-nil redist will be done in background like send.
-This allows transaction log to be visible if -watch, -verbose or
--snoop are used.")
-
-\f
-
-;;; Variables
-
-(defvar mh-comp-formfile "components"
- "Name of file to be used as a skeleton for composing messages.
-
-Default is \"components\".
-
-If not an absolute file name, the file is searched for first in the
-user's MH directory, then in the system MH lib directory.")
-
-(defvar mh-dist-formfile "distcomps"
- "Name of file to be used as a skeleton for redistributing messages.
-
-Default is \"distcomps\".
-
-If not an absolute file name, the file is searched for first in the
-user's MH directory, then in the system MH lib directory.")
-
-(defvar mh-repl-formfile "replcomps"
- "Name of file to be used as a skeleton for replying to messages.
-
-Default is \"replcomps\".
-
-If not an absolute file name, the file is searched for first in the
-user's MH directory, then in the system MH lib directory.")
-
-(defvar mh-repl-group-formfile "replgroupcomps"
- "Name of file to be used as a skeleton for replying to messages.
-
-Default is \"replgroupcomps\".
-
-This file is used to form replies to the sender and all recipients of
-a message. Only used if (mh-variant-p \\='nmh) is non-nil.
-If not an absolute file name, the file is searched for first in the
-user's MH directory, then in the system MH lib directory.")
-
-(defvar mh-rejected-letter-start
- (format "^%s$"
- (regexp-opt
- '("Content-Type: message/rfc822" ;MIME MDN
- "------ This is a copy of the message, including all the headers. ------";from exim
- "--- Below this line is a copy of the message."; from qmail
- " ----- Unsent message follows -----" ;from sendmail V5
- " --------Unsent Message below:" ; from sendmail at BU
- " ----- Original message follows -----" ;from sendmail V8
- "------- Unsent Draft" ;from MH itself
- "---------- Original Message ----------" ;from zmailer
- " --- The unsent message follows ---" ;from AIX mail system
- " Your message follows:" ;from MMDF-II
- "Content-Description: Returned Content" ;1993 KJ sendmail
- ))))
-
-(defvar mh-new-draft-cleaned-headers
- "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Sender:\\|^Errors-To:\\|^Delivery-Date:\\|^Return-Path:"
- "Regexp of header lines to remove before offering a message as a new draft\\<mh-folder-mode-map>.
-Used by the \\[mh-edit-again] and \\[mh-extract-rejected-mail] commands.")
-
-(defvar mh-letter-mode-syntax-table
- (let ((syntax-table (make-syntax-table text-mode-syntax-table)))
- (modify-syntax-entry ?% "." syntax-table)
- syntax-table)
- "Syntax table used by MH-E while in MH-Letter mode.")
-
-(defvar mh-regexp-in-field-syntax-table nil
- "Specify a syntax table for `mh-regexp-in-field-p' to use.")
-
-(defvar mh-fcc-syntax-table
- (let ((syntax-table (make-syntax-table text-mode-syntax-table)))
- (modify-syntax-entry ?+ "w" syntax-table)
- (modify-syntax-entry ?/ "w" syntax-table)
- syntax-table)
- "Syntax table used by MH-E while searching an Fcc field.")
-
-(defvar mh-addr-syntax-table
- (let ((syntax-table (make-syntax-table text-mode-syntax-table)))
- (modify-syntax-entry ?! "w" syntax-table)
- (modify-syntax-entry ?# "w" syntax-table)
- (modify-syntax-entry ?$ "w" syntax-table)
- (modify-syntax-entry ?% "w" syntax-table)
- (modify-syntax-entry ?& "w" syntax-table)
- (modify-syntax-entry ?' "w" syntax-table)
- (modify-syntax-entry ?* "w" syntax-table)
- (modify-syntax-entry ?+ "w" syntax-table)
- (modify-syntax-entry ?- "w" syntax-table)
- (modify-syntax-entry ?/ "w" syntax-table)
- (modify-syntax-entry ?= "w" syntax-table)
- (modify-syntax-entry ?? "w" syntax-table)
- (modify-syntax-entry ?^ "w" syntax-table)
- (modify-syntax-entry ?_ "w" syntax-table)
- (modify-syntax-entry ?` "w" syntax-table)
- (modify-syntax-entry ?{ "w" syntax-table)
- (modify-syntax-entry ?| "w" syntax-table)
- (modify-syntax-entry ?} "w" syntax-table)
- (modify-syntax-entry ?~ "w" syntax-table)
- (modify-syntax-entry ?. "w" syntax-table)
- (modify-syntax-entry ?@ "w" syntax-table)
- syntax-table)
- "Syntax table used by MH-E while searching an address field.")
-
-(defvar mh-send-args ""
- "Extra args to pass to \"send\" command.")
-
-(defvar mh-annotate-char nil
- "Character to use to annotate `mh-sent-from-msg'.")
-
-(defvar mh-annotate-field nil
- "Field name for message annotation.")
-
-(defvar mh-annotate-list nil
- "Messages annotated, either a sequence name or a list of message numbers.
-This variable can be used by `mh-annotate-msg-hook'.")
-
-(defvar-local mh-insert-auto-fields-done-local nil
- "Buffer-local variable set when `mh-insert-auto-fields' called successfully.")
-
-\f
-
-;;; MH-E Entry Points
-
-;;;###autoload
-(defun mh-smail ()
- "Compose a message with the MH mail system.
-See `mh-send' for more details on composing mail."
- (interactive)
- (mh-find-path)
- (call-interactively 'mh-send))
-
-;;;###autoload
-(defun mh-smail-other-window ()
- "Compose a message with the MH mail system in other window.
-See `mh-send' for more details on composing mail."
- (interactive)
- (mh-find-path)
- (call-interactively 'mh-send-other-window))
-
-(defun mh-send-other-window (to cc subject)
- "Compose a message in another window.
-
-See `mh-send' for more information and a description of how the
-TO, CC, and SUBJECT arguments are used."
- (interactive (list
- (mh-interactive-read-address "To: ")
- (mh-interactive-read-address "Cc: ")
- (mh-interactive-read-string "Subject: ")))
- (let ((pop-up-windows t))
- (mh-send-sub to cc subject (current-window-configuration))))
-
-(defvar mh-error-if-no-draft nil) ;raise error over using old draft
-
-;;;###autoload
-(defun mh-smail-batch (&optional to subject _other-headers &rest _ignored)
- "Compose a message with the MH mail system.
-
-This function does not prompt the user for any header fields, and
-thus is suitable for use by programs that want to create a mail
-buffer. Users should use \\[mh-smail] to compose mail.
-
-Optional arguments for setting certain fields include TO,
-SUBJECT, and OTHER-HEADERS. Additional arguments are IGNORED.
-
-This function remains for Emacs 21 compatibility. New
-applications should use `mh-user-agent-compose'."
- (mh-find-path)
- (let ((mh-error-if-no-draft t))
- (mh-send (or to "") "" (or subject ""))))
-
-;;;###autoload
-(define-mail-user-agent 'mh-e-user-agent
- 'mh-user-agent-compose 'mh-send-letter 'mh-fully-kill-draft
- 'mh-before-send-letter-hook)
-
-;;;###autoload
-(defun mh-user-agent-compose (&optional to subject other-headers &rest _ignored)
- "Set up mail composition draft with the MH mail system.
-This is the `mail-user-agent' entry point to MH-E. This function
-conforms to the contract specified by `define-mail-user-agent'
-which means that this function should accept the same arguments
-as `compose-mail'.
-
-The optional arguments TO and SUBJECT specify recipients and the
-initial Subject field, respectively.
-
-OTHER-HEADERS is an alist specifying additional header fields.
-Elements look like (HEADER . VALUE) where both HEADER and VALUE
-are strings.
-
-Any additional arguments are IGNORED."
- (mh-find-path)
- (let ((mh-error-if-no-draft t))
- (mh-send to "" subject)
- (while other-headers
- (mh-insert-fields (concat (car (car other-headers)) ":")
- (cdr (car other-headers)))
- (setq other-headers (cdr other-headers)))))
-
-(defvar sendmail-coding-system)
-
-;;;###autoload
-(defun mh-send-letter (&optional arg)
- "Save draft and send message.
-
-When you are all through editing a message, you send it with this
-command. You can give a prefix argument ARG to monitor the first stage
-of the delivery; this output can be found in a buffer called \"*MH-E
-Mail Delivery*\".
-
-The hook `mh-before-send-letter-hook' is run at the beginning of
-this command. For example, if you want to check your spelling in
-your message before sending, add the function `ispell-message'.
-
-Unless `mh-insert-auto-fields' had previously been called
-manually, the function `mh-insert-auto-fields' is called to
-insert fields based upon the recipients. If fields are added, you
-are given a chance to see and to confirm these fields before the
-message is actually sent. You can do away with this confirmation
-by turning off the option `mh-auto-fields-prompt-flag'.
-
-In case the MH \"send\" program is installed under a different name,
-use `mh-send-prog' to tell MH-E the name.
-
-The hook `mh-annotate-msg-hook' is run after annotating the
-message and scan line."
- (interactive "P")
- (run-hooks 'mh-before-send-letter-hook)
- (if (and (mh-insert-auto-fields t)
- mh-auto-fields-prompt-flag
- (goto-char (point-min)))
- (if (not (y-or-n-p "Auto fields inserted, send? "))
- (error "Send aborted")))
- (cond ((mh-mh-directive-present-p)
- (mh-mh-to-mime))
- ((or (mh-mml-tag-present-p) (not (mh-ascii-buffer-p)))
- (mh-mml-to-mime)))
- (save-buffer)
- (message "Sending...")
- (let ((draft-buffer (current-buffer))
- (file-name buffer-file-name)
- (config mh-previous-window-config)
- (coding-system-for-write (select-message-coding-system)))
- ;; Older versions of spost do not support -msgid and -mime.
- (unless mh-send-uses-spost-flag
- ;; Adding a Message-ID field looks good, makes it easier to search for
- ;; message in your +outbox, and best of all doesn't break threading for
- ;; the recipient if you reply to a message in your +outbox.
- (setq mh-send-args (concat "-msgid " mh-send-args))
- ;; The default Bcc encapsulation will make a MIME message unreadable.
- ;; With nmh use the -mime arg to prevent this.
- (if (and (mh-variant-p 'nmh)
- (mh-goto-header-field "Bcc:")
- (mh-goto-header-field "Content-Type:"))
- (setq mh-send-args (concat "-mime " mh-send-args))))
- (cond (arg
- (pop-to-buffer mh-mail-delivery-buffer)
- (erase-buffer)
- (mh-exec-cmd-output mh-send-prog t
- "-nodraftfolder" "-watch" "-nopush"
- (split-string mh-send-args) file-name)
- (goto-char (point-max)) ; show the interesting part
- (recenter -1)
- (set-buffer draft-buffer)) ; for annotation below
- (t
- (mh-exec-cmd-daemon mh-send-prog nil
- "-nodraftfolder" "-noverbose"
- (split-string mh-send-args) file-name)))
- (if mh-annotate-char
- (mh-annotate-msg mh-sent-from-msg
- mh-sent-from-folder
- mh-annotate-char
- "-component" mh-annotate-field
- "-text" (format "\"%s %s\""
- (mh-get-header-field "To:")
- (mh-get-header-field "Cc:"))))
-
- (cond ((or (not arg)
- (y-or-n-p "Kill draft buffer? "))
- (kill-buffer draft-buffer)
- (if config
- (set-window-configuration config))))
- (if arg
- (message "Sending...done")
- (message "Sending...backgrounded"))))
-
-;;;###autoload
-(defun mh-fully-kill-draft ()
- "Quit editing and delete draft message.
-
-If for some reason you are not happy with the draft, you can use
-this command to kill the draft buffer and delete the draft
-message. Use the command \\[kill-buffer] if you don't want to
-delete the draft message."
- (interactive)
- (if (y-or-n-p "Kill draft message? ")
- (let ((config mh-previous-window-config))
- (if (file-exists-p buffer-file-name)
- (delete-file buffer-file-name))
- (set-buffer-modified-p nil)
- (kill-buffer (buffer-name))
- (message "")
- (if config
- (set-window-configuration config)))
- (error "Message not killed")))
-
-\f
-
-;;; MH-Folder Commands
-
-;; Alphabetical.
-
-;;;###mh-autoload
-(defun mh-edit-again (message)
- "Edit a MESSAGE to send it again.
-
-If you don't complete a draft for one reason or another, and if
-the draft buffer is no longer available, you can pick your draft
-up again with this command. If you don't use a draft folder, your
-last \"draft\" file will be used. If you use draft folders,
-you'll need to visit the draft folder with \"\\[mh-visit-folder]
-drafts <RET>\", use \\[mh-next-undeleted-msg] to move to the
-appropriate message, and then use \\[mh-edit-again] to prepare
-the message for editing.
-
-This command can also be used to take messages that were sent to
-you and to send them to more people.
-
-Don't use this command to re-edit a message from a Mailer-Daemon
-who complained that your mail wasn't posted for some reason or
-another (see `mh-extract-rejected-mail').
-
-The default message is the current message.
-
-See also `mh-send'."
- (interactive (list (mh-get-msg-num t)))
- (let* ((from-folder mh-current-folder)
- (config (current-window-configuration))
- (components-file (mh-bare-components mh-comp-formfile))
- (draft
- (cond ((and mh-draft-folder (equal from-folder mh-draft-folder))
- (pop-to-buffer (find-file-noselect (mh-msg-filename message))
- t)
- (rename-buffer (format "draft-%d" message))
- ;; Make buffer writable...
- (setq buffer-read-only nil)
- ;; If buffer was being used to display the message reinsert
- ;; from file...
- (when (eq major-mode 'mh-show-mode)
- (erase-buffer)
- (insert-file-contents buffer-file-name))
- (buffer-name))
- (t
- (mh-read-draft "clean-up" (mh-msg-filename message) nil)))))
- (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil)
- (mh-insert-header-separator)
- ;; Merge in components
- (mapc
- (lambda (header-field)
- (let ((field (car header-field))
- (value (cdr header-field))
- (case-fold-search t))
- (cond
- ;; Address field
- ((string-match field "^To$\\|^Cc$\\|^From$")
- (cond
- ((not (mh-goto-header-field (concat field ":")))
- ;; Header field does not exist, add it
- (mh-goto-header-end 0)
- (insert field ": " value "\n"))
- ((string-equal value "")
- ;; Header field already exists and no value
- )
- (t
- ;; Header field exists and we have a value
- (let (address mailbox (alias (mh-alias-expand value)))
- (and alias
- (setq address (mail-header-parse-address alias))
- (setq mailbox (car address)))
- ;; XXX - Need to parse all addresses out of field
- (if (and
- (not (mh-regexp-in-field-p
- (concat "\\b" (regexp-quote value) "\\b") field))
- mailbox
- (not (mh-regexp-in-field-p
- (concat "\\b" (regexp-quote mailbox) "\\b") field)))
- (insert " " value ","))
- ))))
- ((string-match field "^Fcc$")
- ;; Folder reference
- (mh-modify-header-field field value))
- ;; Text field, that's an easy case
- (t
- (mh-modify-header-field field value)))))
- (mh-components-to-list components-file))
- (delete-file components-file)
- (goto-char (point-min))
- (save-buffer)
- (mh-compose-and-send-mail
- draft "" from-folder nil nil nil nil nil nil config)
- (mh-letter-mode-message)
- (mh-letter-adjust-point)))
-
-(defun mh-extract-header-field ()
- "Extract field name and field value from the field at point.
-Returns a list of field name and value (which may be null)."
- (let ((end (save-excursion (mh-header-field-end)
- (point))))
- (if (looking-at mh-letter-header-field-regexp)
- (save-excursion
- (goto-char (match-end 1))
- (forward-char 1)
- (skip-chars-forward " \t")
- (cons (match-string-no-properties 1) (buffer-substring-no-properties (point) end))))))
-
-
-(defun mh-components-to-list (components)
- "Convert the COMPONENTS file to a list of field names and values."
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (insert-file-contents components)
- (goto-char (point-min))
- (let
- ((header-fields nil))
- (while (mh-in-header-p)
- (setq header-fields (append header-fields (list (mh-extract-header-field))))
- (mh-header-field-end)
- (forward-char 1)
- )
- header-fields)))
-
-;;;###mh-autoload
-(defun mh-extract-rejected-mail (message)
- "Edit a MESSAGE that was returned by the mail system.
-
-This command prepares the message for editing by removing the
-Mailer-Daemon envelope and unneeded header fields. Fix whatever
-addressing problem you had, and send the message again with
-\\[mh-send-letter].
-
-The default message is the current message.
-
-See also `mh-send'."
- (interactive (list (mh-get-msg-num t)))
- (let ((from-folder mh-current-folder)
- (config (current-window-configuration))
- (draft (mh-read-draft "extraction" (mh-msg-filename message) nil)))
- (goto-char (point-min))
- (cond ((re-search-forward mh-rejected-letter-start nil t)
- (skip-chars-forward " \t\n")
- (delete-region (point-min) (point))
- (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil))
- (t
- (message "Does not appear to be a rejected letter")))
- (mh-insert-header-separator)
- (goto-char (point-min))
- (save-buffer)
- (mh-compose-and-send-mail draft "" from-folder message
- (mh-get-header-field "To:")
- (mh-get-header-field "From:")
- (mh-get-header-field "Cc:")
- nil nil config)
- (mh-letter-mode-message)))
-
-;;;###mh-autoload
-(defun mh-forward (to cc &optional range)
- "Forward message.
-
-You are prompted for the TO and CC recipients. You are given a
-draft to edit that looks like it would if you had run the MH
-command \"forw\". You can then add some text.
-
-You can forward several messages by using a RANGE. All of the
-messages in the range are inserted into your draft. Check the
-documentation of `mh-interactive-range' to see how RANGE is read
-in interactive use.
-
-The hook `mh-forward-hook' is called on the draft.
-
-See also `mh-compose-forward-as-mime-flag',
-`mh-forward-subject-format', and `mh-send'."
- (interactive (list (mh-interactive-read-address "To: ")
- (mh-interactive-read-address "Cc: ")
- (mh-interactive-range "Forward")))
- (let* ((folder mh-current-folder)
- (msgs (mh-range-to-msg-list range))
- (config (current-window-configuration))
- (fwd-msg-file (mh-msg-filename (car msgs) folder))
- ;; forw always leaves file in "draft" since it doesn't have -draft
- (draft-name (expand-file-name "draft" mh-user-path))
- (draft (cond ((or (not (file-exists-p draft-name))
- (y-or-n-p "The file draft exists; discard it? "))
- (mh-exec-cmd "forw" "-build"
- (if (and (mh-variant-p 'nmh)
- mh-compose-forward-as-mime-flag)
- "-mime")
- mh-current-folder
- (mh-coalesce-msg-list msgs))
- (prog1
- (mh-read-draft "" draft-name t)
- (mh-insert-fields "To:" to "Cc:" cc)
- (save-buffer)))
- (t
- (mh-read-draft "" draft-name nil)))))
- (let (orig-from
- orig-subject)
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (insert-file-contents fwd-msg-file)
- (setq orig-from (mh-get-header-field "From:"))
- (setq orig-subject (mh-get-header-field "Subject:")))
- (let ((forw-subject
- (mh-forwarded-letter-subject orig-from orig-subject)))
- (mh-modify-header-field "Subject" forw-subject t)
- (goto-char (point-min))
- ;; Set the local value of mh-mail-header-separator according to what is
- ;; present in the buffer...
- (setq-local mh-mail-header-separator
- (save-excursion
- (goto-char (mh-mail-header-end))
- (buffer-substring-no-properties (point)
- (line-end-position))))
- (setq-local mail-header-separator mh-mail-header-separator) ;override sendmail.el
- ;; If using MML, translate MH-style directive
- (if (equal mh-compose-insertion 'mml)
- (save-excursion
- (goto-char (mh-mail-header-end))
- (while
- (re-search-forward
- "^#forw \\[\\([^]]+\\)\\] \\(\\+\\S-+\\) \\(.*\\)$"
- (point-max) t)
- (let ((description (if (equal (match-string 1)
- "forwarded messages")
- "forwarded message %d"
- (match-string 1)))
- (msgs (split-string (match-string 3)))
- (i 0))
- (beginning-of-line)
- (delete-region (point) (progn (forward-line 1) (point)))
- (dolist (msg msgs)
- (setq i (1+ i))
- (mh-mml-forward-message (format description i)
- folder msg)
- ;; Was inserted before us, move to end of file to preserve order
- (goto-char (point-max)))))))
- ;; Position just before forwarded message.
- (if (re-search-forward "^------- Forwarded Message" nil t)
- (forward-line -1)
- (goto-char (mh-mail-header-end))
- (forward-line 1))
- (delete-other-windows)
- (mh-add-msgs-to-seq msgs 'forwarded t)
- (mh-compose-and-send-mail draft "" folder msgs
- to forw-subject cc
- mh-note-forw "Forwarded:"
- config)
- (mh-letter-mode-message)
- (mh-letter-adjust-point)
- (run-hooks 'mh-forward-hook)))))
-
-(defun mh-forwarded-letter-subject (from subject)
- "Return a Subject suitable for a forwarded message.
-Original message has headers FROM and SUBJECT."
- ;; Join continued lines.
- (setq from (replace-regexp-in-string "\\s *\n\\s +" " " from))
- (let ((addr-start (string-search "<" from))
- (comment (string-search "(" from)))
- (cond ((and addr-start (> addr-start 0))
- ;; Full Name <luser@host>
- (setq from (substring from 0 (1- addr-start))))
- (comment
- ;; luser@host (Full Name)
- (setq from (substring from (1+ comment) (1- (length from)))))))
- (format mh-forward-subject-format from subject))
-
-;;;###mh-autoload
-(defun mh-redistribute (to cc identity &optional message)
- "Redistribute a message.
-
-This command is similar in function to forwarding mail, but it
-does not allow you to edit the message, nor does it add your name
-to the \"From\" header field. It appears to the recipient as if
-the message had come from the original sender. When you run this
-command, you are prompted for the TO and CC recipients. You are
-also prompted for the sending IDENTITY to use. The default
-MESSAGE is the current message.
-
-Also investigate the command \\[mh-edit-again] for another way to
-redistribute messages.
-
-See also `mh-redist-full-contents-flag'.
-
-The hook `mh-annotate-msg-hook' is run after annotating the
-message and scan line."
- (interactive (list (mh-read-address "Redist-To: ")
- (mh-read-address "Redist-Cc: ")
- (if mh-identity-list
- (mh-select-identity mh-identity-default)
- nil)
- (mh-get-msg-num t)))
- (or message
- (setq message (mh-get-msg-num t)))
- (save-window-excursion
- (let ((folder mh-current-folder)
- (draft (mh-read-draft "redistribution"
- (if mh-redist-full-contents-flag
- (mh-msg-filename message)
- nil)
- nil))
- (from (mh-identity-field identity "From"))
- (fcc (mh-identity-field identity "Fcc"))
- (bcc (mh-identity-field identity "Bcc"))
- comp-fcc comp-to comp-cc comp-bcc)
- (if mh-redist-full-contents-flag
- (mh-clean-msg-header
- (point-min)
- "^Message-Id:\\|^Received:\\|^Return-Path:\\|^Date:\\|^Resent-.*:"
- nil))
- ;; Read fields from the distcomps file and put them in our
- ;; draft. For "To", "Cc", "Bcc", and "Fcc", multiple headers are
- ;; combined into a single header with comma-separated entries.
- ;; For "From", the first value wins, with the identity's "From"
- ;; trumping anything in the distcomps file.
- (let ((components-file (mh-bare-components mh-dist-formfile)))
- (mapc
- (lambda (header-field)
- (let ((field (car header-field))
- (value (cdr header-field))
- (case-fold-search t))
- (cond
- ((string-match field "^Resent-Fcc$")
- (setq comp-fcc value))
- ((string-match field "^Resent-From$")
- (or from
- (setq from value)))
- ((string-match field "^Resent-To$")
- (setq comp-to value))
- ((string-match field "^Resent-Cc$")
- (setq comp-cc value))
- ((string-match field "^Resent-Bcc$")
- (setq comp-bcc value))
- ((string-match field "^Resent-.*$")
- (mh-insert-fields field value)))))
- (mh-components-to-list components-file))
- (delete-file components-file))
- (mh-insert-fields "Resent-To:" (mapconcat #'identity (list to comp-to)
- ", ")
- "Resent-Cc:" (mapconcat #'identity (list cc comp-cc)
- ", ")
- "Resent-Fcc:" (mapconcat #'identity (list fcc comp-fcc)
- ", ")
- "Resent-Bcc:" (mapconcat #'identity (list bcc comp-bcc)
- ", ")
- "Resent-From:" from)
- (save-buffer)
- (message "Redistributing...")
- (let ((env "mhdist=1"))
- ;; Setup environment...
- (setq env (concat env " mhaltmsg="
- (if mh-redist-full-contents-flag
- buffer-file-name
- (mh-msg-filename message folder))))
- (unless mh-redist-full-contents-flag
- (setq env (concat env " mhannotate=1")))
- ;; Redistribute...
- (if mh-redist-background
- (mh-exec-cmd-env-daemon env mh-send-prog nil buffer-file-name)
- (mh-exec-cmd-error env mh-send-prog "-push" buffer-file-name))
- ;; Annotate...
- (mh-annotate-msg message folder mh-note-dist
- "-component" "Resent:"
- "-text" (format "\"To: %s Cc: %s From: %s\""
- to cc from)))
- (kill-buffer draft)
- (message "Redistributing...done"))))
-
-;;;###mh-autoload
-(defun mh-reply (message &optional reply-to includep)
- "Reply to a MESSAGE.
-
-When you reply to a message, you are first prompted with \"Reply
-to whom?\" (unless the optional argument REPLY-TO is provided).
-You have several choices here.
-
- Response Reply Goes To
-
- from The person who sent the message. This is the
- default, so <RET> is sufficient.
-
- to Replies to the sender, plus all recipients in the
- \"To:\" header field.
-
- all cc Forms a reply to the addresses in the
- \"Mail-Followup-To:\" header field if one
- exists; otherwise forms a reply to the sender,
- plus all recipients.
-
-Depending on your answer, \"repl\" is given a different argument
-to form your reply. Specifically, a choice of \"from\" or none at
-all runs \"repl -nocc all\", and a choice of \"to\" runs \"repl
--cc to\". Finally, either \"cc\" or \"all\" runs \"repl -cc all
--nocc me\".
-
-Two windows are then created. One window contains the message to
-which you are replying in an MH-Show buffer. Your draft, in
-MH-Letter mode (*note `mh-letter-mode'), is in the other window.
-If the reply draft was not one that you expected, check the
-things that affect the behavior of \"repl\" which include the
-\"repl:\" profile component and the \"replcomps\" and
-\"replgroupcomps\" files.
-
-If you supply a prefix argument INCLUDEP, the message you are
-replying to is inserted in your reply after having first been run
-through \"mhl\" with the format file \"mhl.reply\".
-
-Alternatively, you can customize the option `mh-yank-behavior'
-and choose one of its \"Automatically\" variants to do the same
-thing. If you do so, the prefix argument has no effect.
-
-Another way to include the message automatically in your draft is
-to use \"repl: -filter repl.filter\" in your MH profile.
-
-If you wish to customize the header or other parts of the reply
-draft, please see \"repl\" and \"mh-format\".
-
-See also `mh-reply-show-message-flag',
-`mh-reply-default-reply-to', and `mh-send'."
- (interactive (list
- (mh-get-msg-num t)
- (or mh-reply-default-reply-to
- (completing-read "Reply to whom (default from): "
- '(("from") ("to") ("cc") ("all"))
- nil
- t))
- current-prefix-arg))
- (let* ((folder mh-current-folder)
- (show-buffer mh-show-buffer)
- (config (current-window-configuration))
- (group-reply (or (equal reply-to "cc") (equal reply-to "all")))
- (form-file (cond ((and (mh-variant-p 'nmh 'gnu-mh) group-reply
- (stringp mh-repl-group-formfile))
- mh-repl-group-formfile)
- ((stringp mh-repl-formfile) mh-repl-formfile)
- (t nil))))
- (message "Composing a reply...")
- (mh-exec-cmd "repl" "-build" "-noquery" "-nodraftfolder"
- (if form-file
- (list "-form" form-file))
- mh-current-folder message
- (cond ((or (equal reply-to "from") (equal reply-to ""))
- '("-nocc" "all"))
- ((equal reply-to "to")
- '("-cc" "to"))
- (group-reply (if (mh-variant-p 'nmh 'gnu-mh)
- '("-group" "-nocc" "me")
- '("-cc" "all" "-nocc" "me"))))
- (cond ((or (eq mh-yank-behavior 'autosupercite)
- (eq mh-yank-behavior 'autoattrib))
- '("-noformat"))
- (includep '("-filter" "mhl.reply"))
- (t '())))
- (let ((draft (mh-read-draft "reply"
- (expand-file-name "reply" mh-user-path)
- t)))
- (delete-other-windows)
- (save-buffer)
-
- (let ((to (mh-get-header-field "To:"))
- (subject (mh-get-header-field "Subject:"))
- (cc (mh-get-header-field "Cc:")))
- (goto-char (point-min))
- (mh-goto-header-end 1)
- (or includep
- (not mh-reply-show-message-flag)
- (mh-in-show-buffer (show-buffer)
- (mh-display-msg message folder)))
- (mh-add-msgs-to-seq message 'answered t)
- (message "Composing a reply...done")
- (mh-compose-and-send-mail draft "" folder message to subject cc
- mh-note-repl "Replied:" config))
- (when (and (or (eq 'autosupercite mh-yank-behavior)
- (eq 'autoattrib mh-yank-behavior))
- (eq (mh-show-buffer-message-number) mh-sent-from-msg))
- (undo-boundary)
- (mh-yank-cur-msg))
- (mh-letter-mode-message))))
-
-;;;###mh-autoload
-(defun mh-send (to cc subject)
- "Compose a message.
-
-Your letter appears in an Emacs buffer whose mode is
-MH-Letter (see `mh-letter-mode').
-
-The arguments TO, CC, and SUBJECT can be used to prefill the
-draft fields or suppress the prompts if `mh-compose-prompt-flag'
-is on. They are also passed to the function set in the option
-`mh-compose-letter-function'.
-
-See also `mh-insert-x-mailer-flag' and `mh-letter-mode-hook'.
-
-Outside of an MH-Folder buffer (`mh-folder-mode'), you must call
-either \\[mh-smail] or \\[mh-smail-other-window] to compose a new
-message."
- (interactive (list
- (mh-interactive-read-address "To: ")
- (mh-interactive-read-address "Cc: ")
- (mh-interactive-read-string "Subject: ")))
- (let ((config (current-window-configuration)))
- (delete-other-windows)
- (mh-send-sub to cc subject config)))
-
-\f
-
-;;; Support Routines
-
-(defun mh-interactive-read-address (prompt)
- "Read an address.
-If `mh-compose-prompt-flag' is non-nil, then read an address with
-PROMPT.
-Otherwise return the empty string."
- (if mh-compose-prompt-flag (mh-read-address prompt) ""))
-
-(defun mh-interactive-read-string (prompt)
- "Read a string.
-If `mh-compose-prompt-flag' is non-nil, then read a string with
-PROMPT.
-Otherwise return the empty string."
- (if mh-compose-prompt-flag (read-string prompt) ""))
-
-;;;###mh-autoload
-(defun mh-show-buffer-message-number (&optional buffer)
- "Message number of displayed message in corresponding show buffer.
-
-Return nil if show buffer not displayed.
-If in `mh-letter-mode', don't display the message number being replied
-to, but rather the message number of the show buffer associated with
-our originating folder buffer.
-Optional argument BUFFER can be used to specify the buffer."
- (save-excursion
- (if buffer
- (set-buffer buffer))
- (cond ((eq major-mode 'mh-show-mode)
- (let ((number-start (mh-search-from-end ?/ buffer-file-name)))
- (string-to-number (substring buffer-file-name
- (1+ number-start)))))
- ((and (eq major-mode 'mh-folder-mode)
- mh-show-buffer
- (get-buffer mh-show-buffer))
- (mh-show-buffer-message-number mh-show-buffer))
- ((and (eq major-mode 'mh-letter-mode)
- mh-sent-from-folder
- (get-buffer mh-sent-from-folder))
- (mh-show-buffer-message-number mh-sent-from-folder))
- (t
- nil))))
-
-(defun mh-send-sub (to cc subject config)
- "Do the real work of composing and sending a letter.
-Expects the TO, CC, and SUBJECT fields as arguments.
-CONFIG is the window configuration before sending mail."
- (let ((folder mh-current-folder)
- (msg-num (mh-get-msg-num nil)))
- (message "Composing a message...")
- (let ((draft (mh-read-draft
- "message"
- (mh-bare-components mh-comp-formfile)
- t)))
- (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc)
- (goto-char (point-max))
- (mh-compose-and-send-mail draft "" folder msg-num
- to subject cc
- nil nil config)
- (mh-letter-mode-message)
- (mh-letter-adjust-point))))
-
-(defun mh-bare-components (formfile)
- "Generate a temporary, clean components file from FORMFILE.
-Return the path to the temporary file."
- ;; Let comp(1) create the skeleton for us. This is particularly
- ;; important with nmh-1.5, because its default "components" needs
- ;; some processing before it can be used. Unfortunately, comp(1)
- ;; didn't have a -build option until later versions of nmh. So, to
- ;; avoid the possibility of clobbering an existing draft, create
- ;; a temporary directory and use it as the drafts folder. Then
- ;; copy the skeleton to a regular temp file, and return the
- ;; regular temp file.
- (let (new
- (temp-folder (make-temp-file
- (concat mh-user-path "draftfolder.") t)))
- (mh-exec-cmd "comp" "-nowhatnowproc"
- "-draftfolder" (format "+%s"
- (file-name-nondirectory temp-folder))
- (if (stringp formfile)
- (list "-form" formfile)))
- (setq new (make-temp-file "comp."))
- (rename-file (concat temp-folder "/" "1") new t)
- ;; The temp folder could contain various metadata files. Rather
- ;; than trying to enumerate all the known files, just do a
- ;; recursive delete on the directory.
- (delete-directory temp-folder t)
- new))
-
-(defun mh-read-draft (use initial-contents delete-contents-file)
- "Read draft file into a draft buffer and make that buffer the current one.
-
-USE is a message used for prompting about the intended use of the
-message.
-INITIAL-CONTENTS is filename that is read into an empty buffer, or nil
-if buffer should not be modified. Delete the initial-contents file if
-DELETE-CONTENTS-FILE flag is set.
-Returns the draft folder's name.
-If the draft folder facility is enabled in ~/.mh_profile, a new buffer
-is used each time and saved in the draft folder. The draft file can
-then be reused."
- (cond (mh-draft-folder
- (let ((orig-default-dir default-directory)
- (draft-file-name (mh-new-draft-name)))
- (pop-to-buffer (generate-new-buffer
- (format "draft-%s"
- (file-name-nondirectory draft-file-name))))
- (condition-case ()
- (insert-file-contents draft-file-name t)
- (file-error))
- (setq default-directory orig-default-dir)))
- (t
- (let ((draft-name (expand-file-name "draft" mh-user-path)))
- (pop-to-buffer "draft") ; Create if necessary
- (if (buffer-modified-p)
- (if (y-or-n-p "Draft has been modified; kill anyway? ")
- (set-buffer-modified-p nil)
- (error "Draft preserved")))
- (setq buffer-file-name draft-name)
- (clear-visited-file-modtime)
- (unlock-buffer)
- (cond ((and (file-exists-p draft-name)
- (not (equal draft-name initial-contents)))
- (insert-file-contents draft-name)
- (delete-file draft-name))))))
- (cond ((and initial-contents
- (or (zerop (buffer-size))
- (if (y-or-n-p
- (format "A draft exists. Use for %s? " use))
- (if mh-error-if-no-draft
- (error "A prior draft exists"))
- t)))
- (erase-buffer)
- (insert-file-contents initial-contents)
- (if delete-contents-file (delete-file initial-contents))))
- (auto-save-mode 1)
- (if mh-draft-folder
- (save-buffer)) ; Do not reuse draft name
- (buffer-name))
-
-(defun mh-new-draft-name ()
- "Return the pathname of folder for draft messages."
- (save-excursion
- (mh-exec-cmd-quiet t "mhpath" mh-draft-folder "new")
- (buffer-substring (point-min) (1- (point-max)))))
-
-(defun mh-insert-fields (&rest name-values)
- "Insert the NAME-VALUES pairs in the current buffer.
-If the field exists, append the value to it.
-Do not insert any pairs whose value is the empty string."
- (let ((case-fold-search t))
- (while name-values
- (let ((field-name (car name-values))
- (value (car (cdr name-values))))
- (if (not (string-match "^.*:$" field-name))
- (setq field-name (concat field-name ":")))
- (cond ((or (null value)
- (equal value ""))
- nil)
- ((mh-position-on-field field-name)
- (insert " " (or value "")))
- (t
- (insert field-name " " value "\n")))
- (setq name-values (cdr (cdr name-values)))))))
-
-(defun mh-compose-and-send-mail (draft send-args
- sent-from-folder sent-from-msg
- to subject cc
- annotate-char annotate-field
- config)
- "Edit and compose a draft message in buffer DRAFT and send or save it.
-SEND-ARGS is the argument passed to the send command.
-SENT-FROM-FOLDER is buffer containing scan listing of current folder,
-or nil if none exists.
-SENT-FROM-MSG is the message number or sequence name or nil.
-The TO, SUBJECT, and CC fields are passed to the
-`mh-compose-letter-function'.
-If ANNOTATE-CHAR is non-null, it is used to notate the scan listing of
-the message. In that case, the ANNOTATE-FIELD is used to build a
-string for `mh-annotate-msg'.
-CONFIG is the window configuration to restore after sending the
-letter."
- (pop-to-buffer draft)
- (mh-letter-mode)
-
- ;; Insert identity.
- (mh-insert-identity mh-identity-default t)
- (mh-identity-make-menu)
-
- ;; Cleanup possibly RFC2047 encoded subject header
- (mh-decode-message-subject)
-
- ;; Insert extra fields.
- (mh-insert-x-mailer)
- (mh-insert-x-face)
-
- (mh-letter-hide-all-skipped-fields)
-
- (setq mh-sent-from-folder sent-from-folder)
- (setq mh-sent-from-msg sent-from-msg)
- (setq mh-send-args send-args)
- (setq mh-annotate-char annotate-char)
- (setq mh-annotate-field annotate-field)
- (setq mh-previous-window-config config)
- (setq mode-line-buffer-identification (list " {%b}"))
- (mh-logo-display)
- (add-hook 'kill-buffer-hook #'mh-tidy-draft-buffer nil t)
- (run-hook-with-args 'mh-compose-letter-function to subject cc))
-
-(defun mh-insert-x-mailer ()
- "Append an X-Mailer field to the header.
-The versions of MH-E, Emacs, and MH are shown."
- (or mh-variant-in-use (mh-variant-set mh-variant))
- ;; Lazily initialize mh-x-mailer-string.
- (when (and mh-insert-x-mailer-flag (null mh-x-mailer-string))
- (setq mh-x-mailer-string
- (format "MH-E %s; %s; Emacs %s"
- mh-version mh-variant-in-use emacs-version)))
- ;; Insert X-Mailer, but only if it doesn't already exist.
- (save-excursion
- (when (and mh-insert-x-mailer-flag
- (null (mh-goto-header-field "X-Mailer")))
- (mh-insert-fields "X-Mailer:" mh-x-mailer-string))))
-
-(defun mh-insert-x-face ()
- "Append X-Face, Face or X-Image-URL field to header.
-If the field already exists, this function does nothing."
- (when (and (stringp mh-x-face-file)
- (file-exists-p mh-x-face-file)
- (file-readable-p mh-x-face-file))
- (save-excursion
- (unless (or (mh-position-on-field "X-Face")
- (mh-position-on-field "Face")
- (mh-position-on-field "X-Image-URL"))
- (save-excursion
- (goto-char (+ (point) (cadr (insert-file-contents mh-x-face-file))))
- (if (not (looking-at "^"))
- (insert "\n")))
- (unless (looking-at "\\(X-Face\\|Face\\|X-Image-URL\\): ")
- (insert "X-Face: "))))))
-
-(defun mh-tidy-draft-buffer ()
- "Run when a draft buffer is destroyed."
- (let ((buffer (get-buffer mh-recipients-buffer)))
- (if buffer
- (kill-buffer buffer))))
-
-(defun mh-letter-mode-message ()
- "Display a help message for users of `mh-letter-mode'.
-This should be the last function called when composing the draft."
- (message "%s" (substitute-command-keys
- (concat "Type \\[mh-send-letter] to send message, "
- "\\[mh-help] for help"))))
-
-(defun mh-letter-adjust-point ()
- "Move cursor to first header field if are using the no prompt mode."
- (unless mh-compose-prompt-flag
- (goto-char (point-max))
- (mh-letter-next-header-field)))
-
-(defun mh-annotate-msg (msg folder note &rest args)
- "Mark MSG in FOLDER with character NOTE and annotate message with ARGS.
-MSG can be a message number, a list of message numbers, or a sequence.
-The hook `mh-annotate-msg-hook' is run after annotating; see its
-documentation for variables it can use."
- (apply #'mh-exec-cmd "anno" folder
- (if (listp msg) (append msg args) (cons msg args)))
- (save-excursion
- (cond ((get-buffer folder) ; Buffer may be deleted
- (set-buffer folder)
- (mh-iterate-on-range nil msg
- (mh-notate nil note
- (+ mh-cmd-note mh-scan-field-destination-offset))))))
- (let ((mh-current-folder folder)
- ;; mh-annotate-list is a sequence name or a list of message numbers
- (mh-annotate-list (if (numberp msg) (list msg) msg)))
- (run-hooks 'mh-annotate-msg-hook)))
-
-(defun mh-insert-header-separator ()
- "Insert `mh-mail-header-separator', if absent."
- (save-excursion
- (goto-char (point-min))
- (rfc822-goto-eoh)
- (if (looking-at "$")
- (insert mh-mail-header-separator))))
-
-;;;###mh-autoload
-(defun mh-insert-auto-fields (&optional non-interactive)
- "Insert custom fields if recipient is found in `mh-auto-fields-list'.
-
-Once the header contains one or more recipients, you may run this
-command to insert these fields manually. However, if you use this
-command, the automatic insertion when the message is sent is
-disabled.
-
-In a program, set buffer-local `mh-insert-auto-fields-done-local'
-if header fields were added. If NON-INTERACTIVE is non-nil,
-perform actions quietly and only if
-`mh-insert-auto-fields-done-local' is nil. Return t if fields
-added; otherwise return nil."
- (interactive)
- (when (or (not non-interactive)
- (not mh-insert-auto-fields-done-local))
- (save-excursion
- (when (and (or (mh-goto-header-field "To:")
- (mh-goto-header-field "cc:")))
- (let ((list mh-auto-fields-list)
- (fields-inserted nil))
- (while list
- (let ((regexp (nth 0 (car list)))
- (entries (nth 1 (car list))))
- (when (mh-regexp-in-field-p regexp "To:" "cc:")
- (setq mh-insert-auto-fields-done-local t)
- (setq fields-inserted t)
- (if (not non-interactive)
- (message "Fields for %s added" regexp))
- (let ((entry-list entries))
- (while entry-list
- (let ((field (caar entry-list))
- (value (cdar entry-list)))
- (cond
- ((equal ":identity" field)
- (when
- ;;(and (not mh-identity-local)
- ;; Bug 1204506. But do we need to be able
- ;; to set an identity manually that won't be
- ;; overridden by mh-insert-auto-fields?
- (assoc value mh-identity-list)
- ;;)
- (mh-insert-identity value)))
- (t
- (mh-modify-header-field field value
- (equal field "From")))))
- (setq entry-list (cdr entry-list))))))
- (setq list (cdr list)))
- fields-inserted)))))
-
-(defun mh-modify-header-field (field value &optional overwrite-flag)
- "To header FIELD add VALUE.
-If OVERWRITE-FLAG is non-nil then the old value, if present, is
-discarded."
- (cond ((and overwrite-flag
- (mh-goto-header-field (concat field ":")))
- (insert " " value)
- (delete-region (point) (line-end-position)))
- ((and (not overwrite-flag)
- (mh-regexp-in-field-p (concat "\\b" (regexp-quote value) "\\b") field))
- ;; Already there, do nothing.
- )
- ((and (not overwrite-flag)
- (mh-goto-header-field (concat field ":")))
- (insert " " value ","))
- (t
- (mh-goto-header-end 0)
- (insert field ": " value "\n"))))
-
-(defun mh-regexp-in-field-p (regexp &rest fields)
- "Non-nil means REGEXP was found in FIELDS."
- (let ((old-syntax-table (syntax-table)))
- (unwind-protect
- (save-excursion
- (let ((search-result nil))
- (while fields
- (let* ((field (car fields))
- (syntax-table
- (or mh-regexp-in-field-syntax-table
- (let ((case-fold-search t))
- (cond
- ((string-match field "^To$\\|^[BD]?cc$\\|^From$")
- mh-addr-syntax-table)
- ((string-match field "^Fcc$")
- mh-fcc-syntax-table)
- (t
- (syntax-table)))
- ))))
- (if (and (mh-goto-header-field field)
- (set-syntax-table syntax-table)
- (re-search-forward
- regexp (save-excursion (mh-header-field-end)(point)) t))
- (setq fields nil
- search-result t)
- (setq fields (cdr fields)))
- (set-syntax-table old-syntax-table)))
- search-result))
- (set-syntax-table old-syntax-table))))
-
-(defun mh-ascii-buffer-p ()
- "Check if current buffer is entirely composed of ASCII."
- (cl-loop for charset in (find-charset-region (point-min) (point-max))
- unless (eq charset 'ascii) return nil
- finally return t))
-
-(provide 'mh-comp)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-comp.el ends here
+++ /dev/null
-;;; mh-e.el --- GNU Emacs interface to the MH mail system -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1985-1988, 1990, 1992-1995, 1997, 1999-2024 Free
-;; Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Version: 8.6+git
-;; Keywords: mail
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; MH-E is an Emacs interface to the MH mail system.
-
-;; MH-E is compatible with MH versions 6.8.4 and higher, all versions
-;; of nmh, and GNU mailutils 1.0 and higher.
-
-;; MH (Message Handler) is a powerful mail reader. See
-;; https://rand-mh.sourceforge.io/.
-
-;; N.B. MH must have been compiled with the MHE compiler flag or several
-;; features necessary for MH-E will be missing from MH commands, specifically
-;; the -build switch to repl and forw.
-
-;; How to use:
-;; M-x mh-rmail to read mail. Type C-h m there for a list of commands.
-;; C-u M-x mh-rmail to visit any folder.
-;; M-x mh-smail to send mail. From within the mail reader, "s" works, too.
-
-;; Your .emacs might benefit from these bindings:
-;; (global-set-key "\C-cr" 'mh-rmail)
-;; (global-set-key "\C-xm" 'mh-smail)
-;; (global-set-key "\C-x4m" 'mh-smail-other-window)
-
-;; Mailing Lists:
-;; mh-e-users@lists.sourceforge.net
-;; mh-e-announce@lists.sourceforge.net
-;; mh-e-devel@lists.sourceforge.net
-
-;; Subscribe by sending a "subscribe" message to
-;; <list>-request@lists.sourceforge.net, or by using the web interface at
-;; https://sourceforge.net/mail/?group_id=13357
-
-;; Bug Reports:
-;; https://sourceforge.net/tracker/?group_id=13357&atid=113357
-;; Include the output of M-x mh-version in the bug report unless
-;; you're 110% sure we won't ask for it.
-
-;; Feature Requests:
-;; https://sourceforge.net/tracker/?group_id=13357&atid=363357
-
-;; Support:
-;; https://sourceforge.net/tracker/?group_id=13357&atid=213357
-
-;;; Change Log:
-
-;; Original version for Gosling emacs by Brian Reid, Stanford, 1982.
-;; Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985.
-;; Rewritten for GNU Emacs, James Larus, 1985.
-;; Modified by Stephen Gildea, 1988.
-;; Maintenance picked up by Bill Wohler and the
-;; SourceForge Crew <https://mh-e.sourceforge.io/>, 2001.
-;; Since 2016, MH-E development occurs within the Emacs repository.
-
-;;; Code:
-
-;; Provide functions to the rest of MH-E. However, mh-e.el must not
-;; use any definitions in files that require mh-e from mh-loaddefs,
-;; for if it does it will introduce a require loop.
-(require 'mh-loaddefs)
-
-(require 'cl-lib)
-
-(require 'mh-buffers)
-
-\f
-
-;;; Global Variables
-
-;; Try to keep variables local to a single file. Provide accessors if
-;; variables are shared. Use this section as a last resort.
-
-(defconst mh-version "8.6+git" "Version number of MH-E.")
-
-;; Variants
-
-(defvar mh-sys-path
- '("/usr/local/nmh/bin" ; nmh default
- "/usr/local/bin/mh/"
- "/usr/local/mh/"
- "/usr/bin/mh/" ; Ultrix 4.2, Linux
- "/usr/new/mh/" ; Ultrix < 4.2
- "/usr/contrib/mh/bin/" ; BSDI
- "/usr/pkg/bin/" ; NetBSD
- "/usr/local/bin/"
- "/usr/local/bin/mu-mh/" ; GNU mailutils MH - default
- "/usr/bin/mu-mh/") ; GNU mailutils MH - packaged
- "List of directories to search for variants of the MH variant.
-The list `exec-path' is searched in addition to this list.
-There's no need for users to modify this list. Instead add extra
-directories to the customizable variable `mh-path'.")
-
-(defvar mh-variants nil
- "List describing known MH variants.
-Do not access this variable directly as it may not have yet been initialized.
-Use the function `mh-variants' instead.")
-
-(defvar mh-variant-in-use nil
- "The MH variant currently in use; a string with variant and version number.
-This differs from `mh-variant' when the latter is set to
-\"autodetect\".")
-
-(defvar mh-progs nil
- "Directory containing MH commands, such as inc, repl, and rmm.")
-
-;;;###autoload
-(put 'mh-progs 'risky-local-variable t)
-
-(defvar mh-lib nil
- "Directory containing the MH library.
-This directory contains, among other things, the components file.")
-
-;;;###autoload
-(put 'mh-lib 'risky-local-variable t)
-
-(defvar mh-lib-progs nil
- "Directory containing MH helper programs.
-This directory contains, among other things, the mhl program.")
-
-;;;###autoload
-(put 'mh-lib-progs 'risky-local-variable t)
-
-;; Profile Components
-
-(defvar mh-draft-folder nil
- "Cached value of the \"Draft-Folder:\" MH profile component.
-Name of folder containing draft messages.
-Do not use a draft folder if nil.")
-
-(defvar mh-inbox nil
- "Cached value of the \"Inbox:\" MH profile component.
-Set to \"+inbox\" if no such component.
-Name of the Inbox folder.")
-
-(defvar mh-user-path nil
- "Cached value of the \"Path:\" MH profile component.
-User's mail folder directory.")
-
-;; Maps declared here so that they can be used in docstrings.
-
-(defvar-keymap mh-folder-mode-map
- :doc "Keymap for MH-Folder mode."
- :full t)
-
-(defvar mh-folder-seq-tool-bar-map nil
- "Keymap for MH-Folder tool bar.")
-
-(defvar mh-folder-tool-bar-map nil
- "Keymap for MH-Folder tool bar.")
-
-(defvar-keymap mh-inc-spool-map
- :doc "Keymap for MH-E's mh-inc-spool commands.")
-
-(defvar mh-letter-mode-map (copy-keymap text-mode-map)
- "Keymap for MH-Letter mode.")
-
-(defvar mh-letter-tool-bar-map nil
- "Keymap for MH-Letter tool bar.")
-
-(defvar-keymap mh-search-mode-map
- :doc "Keymap for MH-Search mode.")
-
-(defvar-keymap mh-show-mode-map
- :doc "Keymap for MH-Show mode.")
-
-(defvar mh-show-seq-tool-bar-map nil
- "Keymap for MH-Show tool bar.")
-
-(defvar mh-show-tool-bar-map nil
- "Keymap for MH-Show tool bar.")
-
-;; MH-Folder Locals (alphabetical)
-
-(defvar mh-arrow-marker nil
- "Marker for arrow display in fringe.")
-
-(defvar mh-blocklist nil
- "List of messages to use to train the junk filter.
-This variable can be used by
-`mh-before-commands-processed-hook'.")
-
-(defvar mh-colors-available-flag nil
- "Non-nil means colors are available.")
-
-(defvar mh-current-folder nil
- "Name of current folder, a string.")
-
-(defvar mh-delete-list nil
- "List of message numbers to delete.
-This variable can be used by
-`mh-before-commands-processed-hook'.")
-
-(defvar mh-folder-view-stack nil
- "Stack of previous folder views.")
-
-(defvar mh-index-data nil
- "Info about index search results.")
-
-(defvar mh-index-previous-search nil)
-
-(defvar mh-index-msg-checksum-map nil)
-
-(defvar mh-index-checksum-origin-map nil)
-
-(defvar mh-index-sequence-search-flag nil)
-
-(defvar mh-mode-line-annotation nil
- "Message range displayed in buffer.")
-
-(defvar mh-next-direction 'forward
- "Direction to move to next message.")
-
-(defvar mh-previous-window-config nil
- "Window configuration before MH-E command.")
-
-(defvar mh-refile-list nil
- "List of folder names in `mh-seq-list'.
-This variable can be used by
-`mh-before-commands-processed-hook'.")
-
-(defvar mh-seen-list nil
- "List of displayed messages to be removed from the \"Unseen\" sequence.")
-
-(defvar mh-seq-list nil
- "Alist of this folder's sequences.
-Elements have the form (SEQUENCE . MESSAGES).")
-
-(defvar mh-sequence-notation-history nil
- "Remember original notation that is overwritten by `mh-note-seq'.")
-
-(defvar mh-show-buffer nil
- "Buffer that displays message for this folder.")
-
-(define-minor-mode mh-showing-mode
- "Minor mode to show the message in a separate window."
- ;; FIXME: maybe this should be moved to mh-show.el.
- :lighter " Show")
-
-(defvar mh-view-ops nil
- "Stack of operations that change the folder view.
-These operations include narrowing or threading.")
-
-(defvar mh-allowlist nil
- "List of messages to use to train the junk filter.
-This variable can be used by
-`mh-before-commands-processed-hook'.")
-
-;; MH-Show Locals (alphabetical)
-
-(defvar mh-globals-hash (make-hash-table)
- "Keeps track of MIME data on a per buffer basis.")
-
-(defvar mh-show-folder-buffer nil
- "Keeps track of folder whose message is being displayed.")
-
-;; MH-Letter Locals
-
-(defvar mh-folders-changed nil
- "Lists which folders were affected by deletes and refiles.
-This list will always include the current folder
-`mh-current-folder'. This variable can be used by
-`mh-after-commands-processed-hook'.")
-
-(defcustom mh-mail-header-separator "--------"
- "Line used by MH to separate headers from text in messages being composed.
-
-This variable should not be used directly in programs. Programs
-should use `mail-header-separator' instead.
-`mail-header-separator' is initialized to
-`mh-mail-header-separator' in `mh-letter-mode'; in other
-contexts, you may have to perform this initialization yourself.
-
-Do not make this a regular expression as it may be the argument
-to `insert' and it is passed through `regexp-quote' before being
-used by functions like `re-search-forward'."
- :group 'mh-e ; FIXME?
- :type 'string)
-
-(defvar mh-sent-from-folder nil
- "Folder of msg assoc with this letter.")
-
-(defvar mh-sent-from-msg nil
- "Number of msg assoc with this letter.")
-
-;; Sequences
-
-(defvar mh-unseen-seq nil
- "Cached value of the \"Unseen-Sequence:\" MH profile component.
-Name of the Unseen sequence.")
-
-(defvar mh-previous-seq nil
- "Cached value of the \"Previous-Sequence:\" MH profile component.
-Name of the Previous sequence.")
-
-;; Etc. (alphabetical)
-
-(defvar mh-flists-present-flag nil
- "Non-nil means that we have \"flists\".")
-
-(defvar mh-index-data-file ".mhe_index"
- "MH-E specific file where index search info is stored.")
-
-(defvar mh-letter-header-field-regexp "^\\([A-Za-z][A-Za-z0-9-]*\\):")
-
-(defvar mh-page-to-next-msg-flag nil
- "Non-nil means next SPC or whatever goes to next undeleted message.")
-
-(defvar mh-pgp-support-flag (not (not (locate-library "mml2015")))
- "Non-nil means PGP support is available.")
-
-(defvar mh-signature-separator "-- \n"
- "Text of a signature separator.
-
-A signature separator is used to separate the body of a message
-from the signature. This can be used by user agents such as MH-E
-to render the signature differently or to suppress the inclusion
-of the signature in a reply. Use `mh-signature-separator-regexp'
-when searching for a separator.")
-
-(defvar mh-signature-separator-regexp "^-- $"
- "This regular expression matches the signature separator.
-See `mh-signature-separator'.")
-
-(defvar-local mh-thread-scan-line-map nil
- "Map of message index to various parts of the scan line.")
-
-(defvar-local mh-thread-scan-line-map-stack nil
- "Old map of message index to various parts of the scan line.
-This is the original map that is stored when the folder is
-narrowed.")
-
-(defcustom mh-x-mailer-string nil
- "String containing the contents of the X-Mailer header field.
-If nil, this variable is initialized to show the version of MH-E,
-Emacs, and MH the first time a message is composed."
- :group 'mh-e ; FIXME?
- :type '(choice (const :tag "Default" nil) string))
-\f
-
-;;; MH-E Entry Points
-
-(eval-when-compile (require 'gnus))
-
-(defmacro mh-macro-expansion-time-gnus-version ()
- "Return Gnus version available at macro expansion time.
-The macro evaluates the Gnus version at macro expansion time. If
-MH-E was compiled then macro expansion happens at compile time."
-gnus-version)
-
-(defun mh-run-time-gnus-version ()
- "Return Gnus version available at run time."
- (require 'gnus)
- gnus-version)
-
-(defvar mh-variant)
-
-;;;###autoload
-(defun mh-version ()
- "Display version information about MH-E and the MH mail handling system."
- (interactive)
- (set-buffer (get-buffer-create mh-info-buffer))
- (erase-buffer)
- ;; MH-E version.
- (insert "MH-E " mh-version "\n\n")
- ;; MH-E compilation details.
- (insert "MH-E compilation details:\n")
- (let* ((compiled-mhe (compiled-function-p (symbol-function 'mh-version)))
- (gnus-compiled-version (if compiled-mhe
- (mh-macro-expansion-time-gnus-version)
- "N/A")))
- (insert " Compiled:\t\t" (if compiled-mhe "yes" "no") "\n"
- " Gnus (compile-time):\t" gnus-compiled-version "\n"
- " Gnus (run-time):\t" (mh-run-time-gnus-version) "\n\n"))
- ;; Emacs version.
- (insert (emacs-version) "\n\n")
- ;; MH version.
- (or mh-variant-in-use (mh-variant-set mh-variant))
- (if mh-variant-in-use
- (insert mh-variant-in-use "\n"
- " mh-progs:\t" mh-progs "\n"
- " mh-lib:\t" mh-lib "\n"
- " mh-lib-progs:\t" mh-lib-progs "\n\n")
- (insert "No MH variant detected\n"))
- ;; Linux version.
- (condition-case ()
- (call-process "uname" nil t nil "-a")
- (file-error))
- (goto-char (point-min))
- (display-buffer mh-info-buffer))
-
-\f
-
-;;; Support Routines
-
-(defun mh-list-to-string (l)
- "Flatten the list L and make every element of the new list into a string."
- (nreverse (mh-list-to-string-1 l)))
-
-(defun mh-list-to-string-1 (l)
- "Flatten the list L and make every element of the new list into a string."
- (let (new-list)
- (dolist (element l)
- (cond ((null element))
- ((symbolp element)
- (push (symbol-name element) new-list))
- ((numberp element)
- (push (int-to-string element) new-list))
- ((equal element ""))
- ((stringp element)
- (push element new-list))
- ((listp element)
- (setq new-list (nconc (mh-list-to-string-1 element) new-list)))
- (t
- (error "Bad element: %s" element))))
- new-list))
-
-\f
-
-;;; MH-E Process Support
-
-(defvar mh-index-max-cmdline-args 500
- "Maximum number of command line args.")
-
-(defun mh-xargs (cmd &rest args)
- "Partial imitation of xargs.
-The current buffer contains a list of strings, one on each line.
-The function will execute CMD with ARGS and pass the first
-`mh-index-max-cmdline-args' strings to it. This is repeated till
-all the strings have been used."
- (goto-char (point-min))
- (let ((current-buffer (current-buffer)))
- (with-temp-buffer
- (let ((out (current-buffer)))
- (set-buffer current-buffer)
- (while (not (eobp))
- (let ((arg-list (reverse args))
- (count 0))
- (while (and (not (eobp)) (< count mh-index-max-cmdline-args))
- (push (buffer-substring-no-properties (point)
- (line-end-position))
- arg-list)
- (cl-incf count)
- (forward-line))
- (apply #'call-process cmd nil (list out nil) nil
- (nreverse arg-list))))
- (erase-buffer)
- (insert-buffer-substring out)))))
-
-;; XXX This should be applied anywhere MH-E calls out to /bin/sh.
-(defun mh-quote-for-shell (string)
- "Quote STRING for /bin/sh.
-Adds double-quotes around entire string and quotes the characters
-\\, `, and $ with a backslash."
- (concat "\""
- (cl-loop for x across string
- concat (format (if (memq x '(?\\ ?` ?$)) "\\%c" "%c") x))
- "\""))
-
-(defun mh-exec-cmd (command &rest args)
- "Execute mh-command COMMAND with ARGS.
-The side effects are what is desired. Any output is assumed to be
-an error and is shown to the user. The output is not read or
-parsed by MH-E."
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (let* ((initial-size (mh-truncate-log-buffer))
- (start (point))
- (args (mh-list-to-string args)))
- (apply #'call-process (expand-file-name command mh-progs) nil t nil args)
- (when (> (buffer-size) initial-size)
- (save-excursion
- (goto-char start)
- (insert "Errors when executing: " command)
- (cl-loop for arg in args do (insert " " arg))
- (insert "\n"))
- (save-window-excursion
- (switch-to-buffer-other-window mh-log-buffer)
- (sit-for 5))))))
-
-(defun mh-exec-cmd-error (env command &rest args)
- "In environment ENV, execute mh-command COMMAND with ARGS.
-ENV is nil or a string of space-separated \"var=value\" elements.
-Signals an error if process does not complete successfully."
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (let ((process-environment process-environment))
- ;; XXX: We should purge the list that split-string returns of empty
- ;; strings. This can happen in XEmacs if leading or trailing spaces
- ;; are present.
- (dolist (elem (if (stringp env) (split-string env " ") ()))
- (push elem process-environment))
- (mh-handle-process-error
- command (apply #'call-process (expand-file-name command mh-progs)
- nil t nil (mh-list-to-string args))))))
-
-(defun mh-exec-cmd-daemon (command filter &rest args)
- "Execute MH command COMMAND in the background.
-
-If FILTER is non-nil then it is used to process the output
-otherwise the default filter `mh-process-daemon' is used. See
-`set-process-filter' for more details of FILTER.
-
-ARGS are passed to COMMAND as command line arguments."
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (mh-truncate-log-buffer))
- (let* ((process-connection-type nil)
- (process (apply #'start-process
- command nil
- (expand-file-name command mh-progs)
- (mh-list-to-string args))))
- (set-process-filter process (or filter 'mh-process-daemon))
- process))
-
-(defun mh-exec-cmd-env-daemon (env command filter &rest args)
- "In environment ENV, execute mh-command COMMAND in the background.
-
-ENV is nil or a string of space-separated \"var=value\" elements.
-Signals an error if process does not complete successfully.
-
-If FILTER is non-nil then it is used to process the output
-otherwise the default filter `mh-process-daemon' is used. See
-`set-process-filter' for more details of FILTER.
-
-ARGS are passed to COMMAND as command line arguments."
- (let ((process-environment process-environment))
- (dolist (elem (if (stringp env) (split-string env " ") ()))
- (push elem process-environment))
- (apply #'mh-exec-cmd-daemon command filter args)))
-
-(defun mh-process-daemon (_process output)
- "PROCESS daemon that puts OUTPUT into a temporary buffer.
-Any output from the process is displayed in an asynchronous
-pop-up window."
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (insert-before-markers output)
- (display-buffer mh-log-buffer)))
-
-(defun mh-exec-cmd-quiet (raise-error command &rest args)
- "Signal RAISE-ERROR if COMMAND with ARGS fails.
-Execute MH command COMMAND with ARGS. ARGS is a list of strings.
-Return at start of mh-temp buffer, where output can be parsed and
-used.
-Returns value of `call-process', which is 0 for success, unless
-RAISE-ERROR is non-nil, in which case an error is signaled if
-`call-process' returns non-0."
- (set-buffer (get-buffer-create mh-temp-buffer))
- (erase-buffer)
- (let ((value
- (apply #'call-process
- (expand-file-name command mh-progs) nil t nil
- args)))
- (goto-char (point-min))
- (if raise-error
- (mh-handle-process-error command value)
- value)))
-
-(defun mh-exec-cmd-output (command display &rest args)
- "Execute MH command COMMAND with DISPLAY flag and ARGS.
-Put the output into buffer after point.
-Set mark after inserted text.
-Output is expected to be shown to user, not parsed by MH-E."
- (push-mark (point) t)
- (apply #'call-process
- (expand-file-name command mh-progs) nil t display
- (mh-list-to-string args))
-
- ;; The following is used instead of 'exchange-point-and-mark because the
- ;; latter activates the current region (between point and mark), which
- ;; turns on highlighting. So prior to this bug fix, doing "inc" would
- ;; highlight a region containing the new messages, which is undesirable.
- ;; The bug wasn't seen in emacs21 but still occurred in XEmacs21.4.
- (mh-exchange-point-and-mark-preserving-active-mark))
-
-(defun mh-exchange-point-and-mark-preserving-active-mark ()
- "Put the mark where point is now, and point where the mark is now.
-This command works even when the mark is not active, and
-preserves whether the mark is active or not."
- (interactive nil)
- (let ((is-active mark-active))
- (let ((omark (mark t)))
- (if (null omark)
- (error "No mark set in this buffer"))
- (set-mark (point))
- (goto-char omark)
- (setq mark-active is-active)
- nil)))
-
-(defun mh-exec-lib-cmd-output (command &rest args)
- "Execute MH library command COMMAND with ARGS.
-Put the output into buffer after point.
-Set mark after inserted text."
- (apply #'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args))
-
-(defun mh-handle-process-error (command status)
- "Raise error if COMMAND returned non-zero STATUS, otherwise return STATUS."
- (if (equal status 0)
- status
- (goto-char (point-min))
- (insert (if (integerp status)
- (format "%s: exit code %d\n" command status)
- (format "%s: %s\n" command status)))
- (let ((error-message (buffer-substring (point-min) (point-max))))
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (mh-truncate-log-buffer)
- (insert error-message)))
- (error "%s failed, check buffer %s for error message"
- command mh-log-buffer)))
-
-\f
-
-;;; MH-E Customization Support Routines
-
-;; Temporary function and data structure used customization.
-;; These will be unbound after the options are defined.
-(defmacro mh-strip-package-version (args)
- "ARGS is returned unchanged."
- (declare (obsolete identity "29.1"))
- args)
-
-(defmacro defgroup-mh (symbol members doc &rest args)
- "Declare SYMBOL as a customization group containing MEMBERS.
-See documentation for `defgroup' for a description of the arguments
-SYMBOL, MEMBERS, DOC and ARGS."
- (declare (obsolete defgroup "29.1") (doc-string 3) (indent defun))
- `(defgroup ,symbol ,members ,doc ,args))
-
-(defmacro defcustom-mh (symbol value doc &rest args)
- "Declare SYMBOL as a customizable variable that defaults to VALUE.
-See documentation for `defcustom' for a description of the arguments
-SYMBOL, VALUE, DOC and ARGS."
- (declare (obsolete defcustom "29.1") (doc-string 3) (indent defun))
- `(defcustom ,symbol ,value ,doc ,args))
-
-(defmacro defface-mh (face spec doc &rest args)
- "Declare FACE as a customizable face that defaults to SPEC.
-See documentation for `defface' for a description of the arguments
-FACE, SPEC, DOC and ARGS."
- (declare (obsolete defface "29.1") (doc-string 3) (indent defun))
- `(defface ,face ,spec ,doc ,args))
-
-\f
-
-;;; Variant Support
-
-(defcustom mh-path nil
- "Additional list of directories to search for MH.
-See `mh-variant'."
- :group 'mh-e
- :type '(repeat (directory))
- :package-version '(MH-E . "8.0"))
-
-(defun mh-variants ()
- "Return a list of installed variants of MH on the system.
-This function looks for MH in `mh-sys-path', `mh-path' and
-`exec-path'. The format of the list of variants that is returned
-is described by the variable `mh-variants'."
- (if mh-variants
- mh-variants
- (let ((list-unique))
- ;; Make a unique list of directories, keeping the given order.
- ;; We don't want the same MH variant to be listed multiple times.
- (cl-loop for dir in (append mh-path mh-sys-path exec-path) do
- ;; skip relative dirs, typically "."
- (if (file-name-absolute-p dir)
- (progn
- (setq dir (file-chase-links (directory-file-name dir)))
- (cl-pushnew dir list-unique :test #'equal))))
- (cl-loop for dir in (nreverse list-unique) do
- (when (and dir (file-accessible-directory-p dir))
- (let ((variant (mh-variant-info dir)))
- (if variant
- (add-to-list 'mh-variants variant)))))
- mh-variants)))
-
-(defun mh-variant-info (dir)
- "Return MH variant found in DIR, or nil if none present."
- (let ((tmp-buffer (get-buffer-create mh-temp-buffer)))
- (with-current-buffer tmp-buffer
- (cond
- ((mh-variant-mh-info dir))
- ((mh-variant-nmh-info dir))
- ((mh-variant-gnu-mh-info dir))))))
-
-(defun mh-variant-mh-info (dir)
- "Return info for MH variant in DIR assuming a temporary buffer is set up."
- ;; MH does not have the -version option.
- ;; Its version number is included in the output of "-help" as:
- ;;
- ;; version: MH 6.8.4 #2[UCI] (burrito) of Fri Jan 15 20:01:39 EST 1999
- ;; options: [ATHENA] [BIND] [DUMB] [LIBLOCKFILE] [LOCALE] [MAILGROUP] [MHE]
- ;; [MHRC] [MIME] [MORE='"/usr/bin/sensible-pager"'] [NLINK_HACK]
- ;; [NORUSERPASS] [OVERHEAD] [POP] [POPSERVICE='"pop-3"'] [RENAME]
- ;; [RFC1342] [RPATHS] [RPOP] [SENDMTS] [SMTP] [SOCKETS]
- ;; [SPRINTFTYPE=int] [SVR4] [SYS5] [SYS5DIR] [TERMINFO]
- ;; [TYPESIG=void] [UNISTD] [UTK] [VSPRINTF]
- (let ((mhparam (expand-file-name "mhparam" dir)))
- (when (mh-file-command-p mhparam)
- (erase-buffer)
- (call-process mhparam nil '(t nil) nil "-help")
- (goto-char (point-min))
- (when (search-forward-regexp "version: MH \\(\\S +\\)" nil t)
- (let ((version (format "MH %s" (match-string 1))))
- (erase-buffer)
- (call-process mhparam nil '(t nil) nil "libdir")
- (goto-char (point-min))
- (when (search-forward-regexp "^.*$" nil t)
- (let ((libdir (match-string 0)))
- `(,version
- (variant mh)
- (mh-lib-progs ,libdir)
- (mh-lib ,libdir)
- (mh-progs ,dir)
- (flists nil)))))))))
-
-(defun mh-variant-gnu-mh-info (dir)
- "Return info for GNU mailutils MH variant in DIR.
-This assumes that a temporary buffer is set up."
- ;; Sample '-version' outputs:
- ;; mhparam (GNU mailutils 0.3.2)
- ;; install-mh (GNU Mailutils 2.2)
- ;; install-mh (GNU Mailutils 3.7)
- (let ((install-mh (expand-file-name "install-mh" dir)))
- (when (mh-file-command-p install-mh)
- (erase-buffer)
- (call-process install-mh nil '(t nil) nil "-version")
- (goto-char (point-min))
- (when (search-forward-regexp "install-mh (\\(GNU [Mm]ailutils \\S +\\))"
- nil t)
- (let ((version (match-string 1))
- (mh-progs dir))
- `(,version
- (variant gnu-mh)
- (mh-lib-progs ,(mh-profile-component "libdir"))
- (mh-lib ,(mh-profile-component "etcdir"))
- (mh-progs ,dir)
- (flists ,(file-exists-p
- (expand-file-name "flists" dir)))))))))
-
-(defun mh-variant-nmh-info (dir)
- "Return info for nmh variant in DIR assuming a temporary buffer is set up."
- ;; Sample '-version' outputs:
- ;; mhparam -- nmh-1.1-RC1 [compiled on chaak at Fri Jun 20 11:03:28 PDT 2003]
- ;; install-mh -- nmh-1.7.1 built October 26, 2019 on build-server-000
- ;; "libdir" was deprecated in nmh-1.7 in favor of "libexecdir", and
- ;; removed completely in nmh-1.8.
- (let ((install-mh (expand-file-name "install-mh" dir)))
- (when (mh-file-command-p install-mh)
- (erase-buffer)
- (call-process install-mh nil '(t nil) nil "-version")
- (goto-char (point-min))
- (when (search-forward-regexp "install-mh -- nmh-\\(\\S +\\)" nil t)
- (let ((version (format "nmh %s" (match-string 1)))
- (mh-progs dir))
- `(,version
- (variant nmh)
- (mh-lib-progs ,(or (mh-profile-component "libdir")
- (mh-profile-component "libexecdir")))
- (mh-lib ,(mh-profile-component "etcdir"))
- (mh-progs ,dir)
- (flists ,(file-exists-p
- (expand-file-name "flists" dir)))))))))
-
-(defun mh-file-command-p (file)
- "Return t if file FILE is the name of an executable regular file."
- (and (file-regular-p file) (file-executable-p file)))
-
-(defun mh-variant-set-variant (variant)
- "Set up the system variables for the MH variant named VARIANT.
-If VARIANT is a string, use that key in the alist returned by the
-function `mh-variants'.
-If VARIANT is a symbol, select the first entry that matches that
-variant."
- (cond
- ((stringp variant) ;e.g. "nmh 1.1-RC1"
- (when (assoc variant (mh-variants))
- (let* ((alist (cdr (assoc variant (mh-variants))))
- (lib-progs (cadr (assoc 'mh-lib-progs alist)))
- (lib (cadr (assoc 'mh-lib alist)))
- (progs (cadr (assoc 'mh-progs alist)))
- (flists (cadr (assoc 'flists alist))))
- ;;(set-default mh-variant variant)
- (setq mh-x-mailer-string nil
- mh-flists-present-flag flists
- mh-lib-progs lib-progs
- mh-lib lib
- mh-progs progs
- mh-variant-in-use variant))))
- ((symbolp variant) ;e.g. 'nmh (pick the first match)
- (cl-loop for variant-list in (mh-variants)
- when (eq variant (cadr (assoc 'variant (cdr variant-list))))
- return (let* ((version (car variant-list))
- (alist (cdr variant-list))
- (lib-progs (cadr (assoc 'mh-lib-progs alist)))
- (lib (cadr (assoc 'mh-lib alist)))
- (progs (cadr (assoc 'mh-progs alist)))
- (flists (cadr (assoc 'flists alist))))
- ;;(set-default mh-variant flavor)
- (setq mh-x-mailer-string nil
- mh-flists-present-flag flists
- mh-lib-progs lib-progs
- mh-lib lib
- mh-progs progs
- mh-variant-in-use version)
- t)))))
-
-(defun mh-variant-p (&rest variants)
- "Return t if variant is any of VARIANTS.
-Currently known variants are `MH', `nmh', and `gnu-mh'."
- (or mh-variant-in-use (mh-variant-set mh-variant))
- (let ((variant-in-use
- (cadr (assoc 'variant (assoc mh-variant-in-use (mh-variants))))))
- (not (null (member variant-in-use variants)))))
-
-(defun mh-profile-component (component)
- "Return COMPONENT value from mhparam, or nil if unset."
- (save-excursion
- ;; MH and nmh use -components, GNU mailutils MH uses -component.
- ;; Since MH and nmh work with an unambiguous prefix, the `s' is
- ;; dropped here.
- (mh-exec-cmd-quiet nil "mhparam" "-component" component)
- (mh-profile-component-value component)))
-
-(defun mh-profile-component-value (component)
- "Find and return the value of COMPONENT in the current buffer.
-Returns nil if the component is not in the buffer."
- (let ((case-fold-search t))
- (goto-char (point-min))
- (cond ((not (re-search-forward (format "^%s:" component) nil t)) nil)
- ((looking-at "[\t ]*$") nil)
- (t
- (re-search-forward "[\t ]*\\([^\t \n].*\\)$" nil t)
- (let ((start (match-beginning 1)))
- (end-of-line)
- (buffer-substring start (point)))))))
-
-(defun mh-variant-set (variant)
- "Set the MH variant to VARIANT.
-Sets `mh-progs', `mh-lib', `mh-lib-progs' and
-`mh-flists-present-flag'.
-If the VARIANT is \"autodetect\", then first try nmh, then MH and
-finally GNU mailutils MH."
- (interactive
- (list (completing-read
- "MH variant: "
- (mapcar (lambda (x) (list (car x))) (mh-variants))
- nil t)))
-
- ;; TODO Remove mu-mh backwards compatibility in 9.0.
- (when (and (stringp variant)
- (string-match "^mu-mh" variant))
- (message
- (format "%s\n%s; %s" "The variant name mu-mh has been renamed to gnu-mh"
- "and will be removed in MH-E 9.0"
- "try M-x customize-option mh-variant"))
- (sit-for 5)
- (setq variant (concat "gnu-mh" (substring variant (match-end 0)))))
-
- (let ((valid-list (mapcar (lambda (x) (car x)) (mh-variants))))
- (cond
- ((eq variant 'none))
- ((eq variant 'autodetect)
- (cond
- ((mh-variant-set-variant 'nmh)
- (message "%s installed as MH variant" mh-variant-in-use))
- ((mh-variant-set-variant 'mh)
- (message "%s installed as MH variant" mh-variant-in-use))
- ((mh-variant-set-variant 'gnu-mh)
- (message "%s installed as MH variant" mh-variant-in-use))
- (t
- (message "No MH variant found on the system"))))
- ((member variant valid-list)
- (when (not (mh-variant-set-variant variant))
- (message "Warning: %s variant not found. Autodetecting..." variant)
- (mh-variant-set 'autodetect)))
- ((null valid-list)
- (message "Unknown variant %s; can't find MH anywhere" variant))
- (t
- (message "Unknown variant %s; use %s"
- variant
- (mapconcat (lambda (x) (format "%s" (car x)))
- (mh-variants) " or "))))))
-
-(defcustom mh-variant 'autodetect
- "Specifies the variant used by MH-E.
-
-The default setting of this option is \"Auto-detect\" which means
-that MH-E will automatically choose the first of nmh, MH, or GNU
-mailutils MH that it finds in the directories listed in
-`mh-path' (which you can customize), `mh-sys-path', and
-`exec-path'. If MH-E can't find MH at all, you may have to
-customize `mh-path' and add the directory in which the command
-\"mhparam\" is located. If, on the other hand, you have both nmh
-and GNU mailutils MH installed (for example) and
-`mh-variant-in-use' was initialized to nmh but you want to use
-GNU mailutils MH, then you can set this option to \"gnu-mh\".
-
-When this variable is changed, MH-E resets `mh-progs', `mh-lib',
-`mh-lib-progs', `mh-flists-present-flag', and `mh-variant-in-use'
-accordingly. Prior to version 8, it was often necessary to set
-some of these variables in \"~/.emacs\"; now it is no longer
-necessary and can actually cause problems."
- :type `(radio
- (const :tag "Auto-detect" autodetect)
- ,@(mapcar (lambda (x) `(const ,(car x))) (mh-variants)))
- :set (lambda (symbol value)
- (set-default symbol value) ;Done in mh-variant-set-variant!
- (mh-variant-set value))
- :initialize #'custom-initialize-default
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-\f
-
-;;; MH-E Customization
-
-;; All of the defgroups, defcustoms, and deffaces in MH-E are found
-;; here. This makes it possible to customize modules that aren't
-;; loaded yet. It also makes it easier to organize the customization
-;; groups.
-
-;; This section contains the following sub-sections:
-
-;; 1. MH-E Customization Groups
-
-;; These are the customization group definitions. Every group has a
-;; associated manual node. The ordering is alphabetical, except for
-;; the groups mh-faces and mh-hooks which are last .
-
-;; 2. MH-E Customization
-
-;; These are the actual customization variables. There is a
-;; sub-section for each group in the MH-E Customization Groups
-;; section, in the same order, separated by page breaks. Within
-;; each section, variables are sorted alphabetically.
-
-;; 3. Hooks
-
-;; All hooks must be placed in the mh-hook group; in addition, add
-;; the group associated with the manual node in which the hook is
-;; described. Since the mh-hook group appears near the end of this
-;; section, the hooks will appear at the end of these other groups.
-
-;; 4. Faces
-
-;; All faces must be placed in the mh-faces group; in addition, add
-;; the group associated with the manual node in which the face is
-;; described. Since the mh-faces group appears near the end of this
-;; section, the faces will appear at the end of these other groups.
-
-(defun mh-customize (&optional delete-other-windows-flag)
- "Customize MH-E variables.
-If optional argument DELETE-OTHER-WINDOWS-FLAG is non-nil, other
-windows in the frame are removed."
- (interactive "P")
- (customize-group 'mh-e)
- (when delete-other-windows-flag
- (delete-other-windows)))
-
-(add-to-list 'customize-package-emacs-version-alist
- '(MH-E ("6.0" . "22.1") ("6.1" . "22.1") ("7.0" . "22.1")
- ("7.1" . "22.1") ("7.2" . "22.1") ("7.3" . "22.1")
- ("7.4" . "22.1") ("8.0" . "22.1") ("8.1" . "23.1")
- ("8.2" . "23.1") ("8.3" . "24.1") ("8.4" . "24.4")
- ("8.5" . "24.4") ("8.6" . "24.4")))
-
-\f
-
-;;; MH-E Customization Groups
-
-(defgroup mh-e nil
- "Emacs interface to the MH mail system.
-MH is the Rand Mail Handler. Other implementations include nmh
-and GNU mailutils."
- :link '(custom-manual "(mh-e)Top")
- :group 'mail
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-alias nil
- "Aliases."
- :link '(custom-manual "(mh-e)Aliases")
- :prefix "mh-alias-"
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-(defgroup mh-folder nil
- "Organizing your mail with folders."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Folders")
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-(defgroup mh-folder-selection nil
- "Folder selection."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Folder Selection")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-identity nil
- "Identities."
- :link '(custom-manual "(mh-e)Identities")
- :prefix "mh-identity-"
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-(defgroup mh-inc nil
- "Incorporating your mail."
- :prefix "mh-inc-"
- :link '(custom-manual "(mh-e)Incorporating Mail")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-junk nil
- "Dealing with junk mail."
- :link '(custom-manual "(mh-e)Junk")
- :prefix "mh-junk-"
- :group 'mh-e
- :package-version '(MH-E . "7.3"))
-
-(defgroup mh-letter nil
- "Editing a draft."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Editing Drafts")
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-(defgroup mh-ranges nil
- "Ranges."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Ranges")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-scan-line-formats nil
- "Scan line formats."
- :link '(custom-manual "(mh-e)Scan Line Formats")
- :prefix "mh-"
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-search nil
- "Searching."
- :link '(custom-manual "(mh-e)Searching")
- :prefix "mh-search-"
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-sending-mail nil
- "Sending mail."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Sending Mail")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-sequences nil
- "Sequences."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Sequences")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-show nil
- "Reading your mail."
- :prefix "mh-"
- :link '(custom-manual "(mh-e)Reading Mail")
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-(defgroup mh-speedbar nil
- "The speedbar."
- :prefix "mh-speed-"
- :link '(custom-manual "(mh-e)Speedbar")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-thread nil
- "Threading."
- :prefix "mh-thread-"
- :link '(custom-manual "(mh-e)Threading")
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-tool-bar nil
- "The tool bar."
- :link '(custom-manual "(mh-e)Tool Bar")
- :prefix "mh-"
- :group 'mh-e
- :package-version '(MH-E . "8.0"))
-
-(defgroup mh-hooks nil
- "MH-E hooks."
- :link '(custom-manual "(mh-e)Top")
- :prefix "mh-"
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-(defgroup mh-faces nil
- "Faces used in MH-E."
- :link '(custom-manual "(mh-e)Top")
- :prefix "mh-"
- :group 'faces
- :group 'mh-e
- :package-version '(MH-E . "7.1"))
-
-\f
-
-;;; MH-E Customization
-
-;; See Variant Support, above, for mh-e group.
-
-;;; Aliases (:group 'mh-alias)
-
-(defcustom mh-alias-completion-ignore-case-flag t
- "Non-nil means don't consider case significant in MH alias completion.
-
-As MH ignores case in the aliases, so too does MH-E. However, you
-may turn off this option to make case significant which can be
-used to segregate completion of your aliases. You might use
-lowercase for mailing lists and uppercase for people."
- :type 'boolean
- :group 'mh-alias
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-alias-expand-aliases-flag nil
- "Non-nil means to expand aliases entered in the minibuffer.
-
-In other words, aliases entered in the minibuffer will be
-expanded to the full address in the message draft. By default,
-this expansion is not performed."
- :type 'boolean
- :group 'mh-alias
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-alias-flash-on-comma t
- "Specify whether to flash address or warn on translation.
-
-This option controls the behavior when a [comma] is pressed while
-entering aliases or addresses. The default setting flashes the
-address associated with an address in the minibuffer briefly, but
-does not display a warning if the alias is not found."
- :type '(choice (const :tag "Flash but Don't Warn If No Alias" t)
- (const :tag "Flash and Warn If No Alias" 1)
- (const :tag "Don't Flash Nor Warn If No Alias" nil))
- :group 'mh-alias
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-alias-insert-file nil
- "Filename used to store a new MH-E alias.
-
-The default setting of this option is \"Use Aliasfile Profile
-Component\". This option can also hold the name of a file or a
-list a file names. If this option is set to a list of file names,
-or the \"Aliasfile:\" profile component contains more than one file
-name, MH-E will prompt for one of them when MH-E adds an alias."
- :type '(choice (const :tag "Use Aliasfile Profile Component" nil)
- (file :tag "Alias File")
- (repeat :tag "List of Alias Files" file))
- :group 'mh-alias
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-alias-insertion-location 'sorted
- "Specifies where new aliases are entered in alias files.
-
-This option is set to \"Alphabetical\" by default. If you organize
-your alias file in other ways, then adding aliases to the \"Top\"
-or \"Bottom\" of your alias file might be more appropriate."
- :type '(choice (const :tag "Alphabetical" sorted)
- (const :tag "Top" top)
- (const :tag "Bottom" bottom))
- :group 'mh-alias
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-alias-local-users t
- "Non-nil means local users are added to alias completion.
-
-Aliases are created from \"/etc/passwd\" entries with a user ID
-larger than a magical number, typically 200. This can be a handy
-tool on a machine where you and co-workers exchange messages.
-These aliases have the form \"local.first.last\" if a real name is
-present in the password file. Otherwise, the alias will have the
-form \"local.login\".
-
-If you're on a system with thousands of users you don't know, and
-the loading of local aliases slows MH-E down noticeably, then
-turn this option off.
-
-This option also takes a string which is executed to generate the
-password file. For example, use \"ypcat passwd\" to obtain the
-NIS password file."
- :type '(choice (boolean) (string))
- :group 'mh-alias
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-alias-local-users-prefix "local."
- "String prefixed to the real names of users from the password file.
-This option can also be set to \"Use Login\".
-
-For example, consider the following password file entry:
-
- psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh
-
-The following settings of this option will produce the associated
-aliases:
-
- \"local.\" local.peter.galbraith
- \"\" peter.galbraith
- Use Login psg
-
-This option has no effect if variable `mh-alias-local-users' is
-turned off."
- :type '(choice (const :tag "Use Login" nil)
- (string))
- :group 'mh-alias
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-alias-passwd-gecos-comma-separator-flag t
- "Non-nil means the gecos field in the password file uses a comma separator.
-
-In the example in `mh-alias-local-users-prefix', commas are used
-to separate different values within the so-called gecos field.
-This is a fairly common usage. However, in the rare case that the
-gecos field in your password file is not separated by commas and
-whose contents may contain commas, you can turn this option off."
- :type 'boolean
- :group 'mh-alias
- :package-version '(MH-E . "7.4"))
-
-;;; Organizing Your Mail with Folders (:group 'mh-folder)
-
-(defcustom mh-new-messages-folders t
- "Folders searched for the \"unseen\" sequence.
-
-Set this option to \"Inbox\" to search the \"+inbox\" folder or
-\"All\" to search all of the top level folders. Otherwise, list
-the folders that should be searched with the \"Choose Folders\"
-menu item.
-
-See also `mh-recursive-folders-flag'."
- :type '(choice (const :tag "Inbox" t)
- (const :tag "All" nil)
- (repeat :tag "Choose Folders" (string :tag "Folder")))
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-ticked-messages-folders t
- "Folders searched for `mh-tick-seq'.
-
-Set this option to \"Inbox\" to search the \"+inbox\" folder or
-\"All\" to search all of the top level folders. Otherwise, list
-the folders that should be searched with the \"Choose Folders\"
-menu item.
-
-See also `mh-recursive-folders-flag'."
- :type '(choice (const :tag "Inbox" t)
- (const :tag "All" nil)
- (repeat :tag "Choose Folders" (string :tag "Folder")))
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-large-folder 200
- "The number of messages that indicates a large folder.
-
-If a folder is deemed to be large, that is the number of messages
-in it exceed this value, then confirmation is needed when it is
-visited. Even when `mh-show-threads-flag' is non-nil, the folder
-is not automatically threaded, if it is large. If set to nil all
-folders are treated as if they are small."
- :type '(choice (const :tag "No Limit") integer)
- :group 'mh-folder
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-recenter-summary-flag nil
- "Non-nil means to recenter the summary window.
-
-If this option is turned on, recenter the summary window when the
-show window is toggled off."
- :type 'boolean
- :group 'mh-folder
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-recursive-folders-flag nil
- "Non-nil means that commands which operate on folders do so recursively."
- :type 'boolean
- :group 'mh-folder
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-sortm-args nil
- "Additional arguments for \"sortm\"\\<mh-folder-mode-map>.
-
-This option is consulted when a prefix argument is used with
-\\[mh-sort-folder]. Normally default arguments to \"sortm\" are
-specified in the MH profile. This option may be used to provide
-an alternate view. For example, (\"-nolimit\" \"-textfield\"
-\"subject\") is a useful setting."
- :type '(repeat string)
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-;;; Folder Selection (:group 'mh-folder-selection)
-
-(defcustom mh-default-folder-for-message-function nil
- "Function to select a default folder for refiling or \"Fcc:\".
-
-When this function is called, the current buffer contains the message
-being refiled and point is at the start of the message. This function
-should return the default folder as a string with a leading \"+\"
-sign. It can also return nil so that the last folder name is used as
-the default, or an empty string to suppress the default entirely."
- :type '(choice (const nil) function)
- :group 'mh-folder-selection
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-default-folder-list nil
- "List of addresses and folders.
-
-The folder name associated with the first address found in this
-list is used as the default for `mh-refile-msg' and similar
-functions. Each element in this list contains a \"Check Recipient\"
-item. If this item is turned on, then the address is checked
-against the recipient instead of the sender. This is useful for
-mailing lists.
-
-See `mh-prompt-for-refile-folder' and `mh-folder-from-address'
-for more information."
- :type '(repeat (list (regexp :tag "Address")
- (string :tag "Folder")
- (boolean :tag "Check Recipient")))
- :group 'mh-folder-selection
- :package-version '(MH-E . "7.2"))
-
-(defcustom mh-default-folder-must-exist-flag t
- "Non-nil means guessed folder name must exist to be used.
-
-If the derived folder does not exist, and this option is on, then
-the last folder name used is suggested. This is useful if you get
-mail from various people for whom you have an alias, but file
-them all in the same project folder.
-
-See `mh-prompt-for-refile-folder' and `mh-folder-from-address'
-for more information."
- :type 'boolean
- :group 'mh-folder-selection
- :package-version '(MH-E . "7.2"))
-
-(defcustom mh-default-folder-prefix ""
- "Prefix used for folder names generated from aliases.
-The prefix is used to prevent clutter in your mail directory.
-
-See `mh-prompt-for-refile-folder' and `mh-folder-from-address'
-for more information."
- :type 'string
- :group 'mh-folder-selection
- :package-version '(MH-E . "7.2"))
-
-;;; Identities (:group 'mh-identity)
-
-(eval-and-compile
- (unless (fboundp 'mh-identity-make-menu-no-autoload)
- (defun mh-identity-make-menu-no-autoload ()
- "Temporary definition.
-Real definition will take effect when mh-identity is loaded."
- nil)))
-
-(defcustom mh-identity-list nil
- "List of identities.
-
-To customize this option, click on the \"INS\" button and enter a label
-such as \"Home\" or \"Work\". Then click on the \"INS\" button with the
-label \"Add at least one item below\". Then choose one of the items in
-the \"Value Menu\".
-
-You can specify an alternate \"From:\" header field using the \"From
-Field\" menu item. You must include a valid email address. A standard
-format is \"First Last <login@@host.domain>\". If you use an initial
-with a period, then you must quote your name as in `\"First I. Last\"
-<login@@host.domain>'. People usually list the name of the company
-where they work using the \"Organization Field\" menu item. Set any
-arbitrary header field and value in the \"Other Field\" menu item.
-Unless the header field is a standard one, precede the name of your
-field's label with \"X-\", as in \"X-Fruit-of-the-Day:\". The value of
-\"Attribution Verb\" overrides the setting of
-`mh-extract-from-attribution-verb'. Set your signature with the
-\"Signature\" menu item. You can specify the contents of
-`mh-signature-file-name', a file, or a function. Specify a different
-key to sign or encrypt messages with the \"GPG Key ID\" menu item.
-
-You can select the identities you have added via the menu called
-\"Identity\" in the MH-Letter buffer. You can also use
-\\[mh-insert-identity]. To clear the fields and signature added by the
-identity, select the \"None\" identity.
-
-The \"Identity\" menu contains two other items to save you from having
-to set the identity on every message. The menu item \"Set Default for
-Session\" can be used to set the default identity to the current
-identity until you exit Emacs. The menu item \"Save as Default\" sets
-the option `mh-identity-default' to the current identity setting. You
-can also customize the `mh-identity-default' option in the usual
-fashion."
- :type '(repeat (list :tag ""
- (string :tag "Label")
- (repeat :tag "Add at least one item below"
- (choice
- (cons :tag "From Field"
- (const "From")
- (string :tag "Value"))
- (cons :tag "Organization Field"
- (const "Organization")
- (string :tag "Value"))
- (cons :tag "Other Field"
- (string :tag "Field")
- (string :tag "Value"))
- (cons :tag "Attribution Verb"
- (const ":attribution-verb")
- (string :tag "Value"))
- (cons :tag "Signature"
- (const :tag "Signature"
- ":signature")
- (choice
- (const :tag "mh-signature-file-name"
- nil)
- (file)
- (function)))
- (cons :tag "GPG Key ID"
- (const :tag "GPG Key ID"
- ":pgg-default-user-id")
- (string :tag "Value"))))))
- :set (lambda (symbol value)
- (set-default symbol value)
- (mh-identity-make-menu-no-autoload))
- :group 'mh-identity
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-auto-fields-list nil
- "List of recipients for which header lines are automatically inserted.
-
-This option can be used to set the identity depending on the
-recipient. To customize this option, click on the \"INS\" button and
-enter a regular expression for the recipient's address. Click on the
-\"INS\" button with the \"Add at least one item below\" label. Then choose
-one of the items in the \"Value Menu\".
-
-The \"Identity\" menu item is used to select an identity from those
-configured in `mh-identity-list'. All of the information for that
-identity will be added if the recipient matches. The \"Fcc Field\" menu
-item is used to select a folder that is used in the \"Fcc:\" header.
-When you send the message, MH will put a copy of your message in this
-folder. The \"Mail-Followup-To Field\" menu item is used to insert an
-\"Mail-Followup-To:\" header field with the recipients you provide. If
-the recipient's mail user agent supports this header field (as nmh
-does), then their replies will go to the addresses listed. This is
-useful if their replies go both to the list and to you and you don't
-have a mechanism to suppress duplicates. If you reply to someone not
-on the list, you must either remove the \"Mail-Followup-To:\" field, or
-ensure the recipient is also listed there so that he receives replies
-to your reply. Other header fields may be added using the \"Other
-Field\" menu item.
-
-These fields can only be added after the recipient is known. Once the
-header contains one or more recipients, run the
-\\[mh-insert-auto-fields] command or choose the \"Identity -> Insert
-Auto Fields\" menu item to insert these fields manually. However, you
-can just send the message and the fields will be added automatically.
-You are given a chance to see these fields and to confirm them before
-the message is actually sent. You can do away with this confirmation
-by turning off the option `mh-auto-fields-prompt-flag'.
-
-You should avoid using the same header field in `mh-auto-fields-list'
-and `mh-identity-list' definitions that may apply to the same message
-as the result is undefined."
- :type `(repeat
- (list :tag ""
- (string :tag "Recipient")
- (repeat :tag "Add at least one item below"
- (choice
- (cons :tag "Identity"
- (const ":identity")
- ,(append
- '(radio)
- (mapcar
- (lambda (arg) `(const ,arg))
- (mapcar #'car mh-identity-list))))
- (cons :tag "Fcc Field"
- (const "fcc")
- (string :tag "Value"))
- (cons :tag "Mail-Followup-To Field"
- (const "Mail-Followup-To")
- (string :tag "Value"))
- (cons :tag "Other Field"
- (string :tag "Field")
- (string :tag "Value"))))))
- :group 'mh-identity
- :package-version '(MH-E . "7.3"))
-
-(defcustom mh-auto-fields-prompt-flag t
- "Non-nil means to prompt before sending if fields inserted.
-See `mh-auto-fields-list'."
- :type 'boolean
- :group 'mh-identity
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-identity-default nil
- "Default identity to use when `mh-letter-mode' is called.
-See `mh-identity-list'."
- :type (append
- '(radio)
- (cons '(const :tag "None" nil)
- (mapcar (lambda (arg) `(const ,arg))
- (mapcar #'car mh-identity-list))))
- :group 'mh-identity
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-identity-handlers
- '(("From" . mh-identity-handler-top)
- (":default" . mh-identity-handler-bottom)
- (":attribution-verb" . mh-identity-handler-attribution-verb)
- (":signature" . mh-identity-handler-signature)
- (":pgg-default-user-id" . mh-identity-handler-gpg-identity))
- "Handler functions for fields in `mh-identity-list'.
-
-This option is used to change the way that fields, signatures,
-and attributions in `mh-identity-list' are added. To customize
-`mh-identity-handlers', replace the name of an existing handler
-function associated with the field you want to change with the
-name of a function you have written. You can also click on an
-\"INS\" button and insert a field of your choice and the name of
-the function you have written to handle it.
-
-The \"Field\" field can be any field that you've used in your
-`mh-identity-list'. The special fields \":attribution-verb\",
-\":signature\", or \":pgg-default-user-id\" are used for the
-`mh-identity-list' choices \"Attribution Verb\", \"Signature\", and
-\"GPG Key ID\" respectively.
-
-The handler associated with the \":default\" field is used when no
-other field matches.
-
-The handler functions are passed two or three arguments: the
-FIELD itself (for example, \"From\"), or one of the special
-fields (for example, \":signature\"), and the ACTION `remove' or
-`add'. If the action is `add', an additional argument
-containing the VALUE for the field is given."
- :type '(repeat (cons (string :tag "Field") function))
- :group 'mh-identity
- :package-version '(MH-E . "8.0"))
-
-;;; Incorporating Your Mail (:group 'mh-inc)
-
-(defcustom mh-inc-prog "inc"
- "Program to incorporate new mail into a folder.
-
-This program generates a one-line summary for each of the new
-messages. Unless it is an absolute pathname, the file is assumed
-to be in the `mh-progs' directory. You may also link a file to
-\"inc\" that uses a different format. You'll then need to modify
-several scan line format variables appropriately."
- :type 'string
- :group 'mh-inc
- :package-version '(MH-E . "6.0"))
-
-(eval-and-compile
- (unless (fboundp 'mh-inc-spool-make-no-autoload)
- (defun mh-inc-spool-make-no-autoload ()
- "Temporary definition.
-Real definition will take effect when mh-inc is loaded."
- nil)))
-
-(defcustom mh-inc-spool-list nil
- "Alternate spool files.
-
-You can use the `mh-inc-spool-list' variable to direct MH-E to
-retrieve mail from arbitrary spool files other than your system
-mailbox, file it in folders other than your \"+inbox\", and assign
-key bindings to incorporate this mail.
-
-Suppose you are subscribed to the \"mh-e-devel\" mailing list and
-you use \"procmail\" to filter this mail into \"~/mail/mh-e\" with
-the following recipe in \".procmailrc\":
-
- MAILDIR=$HOME/mail
- :0:
- * ^From mh-e-devel-admin@stop.mail-abuse.org
- mh-e
-
-In order to incorporate \"~/mail/mh-e\" into \"+mh-e\" with an
-\"I m\" (mh-inc-spool-mh-e) command, customize this option, and click
-on the \"INS\" button. Enter a \"Spool File\" of \"~/mail/mh-e\", a
-\"Folder\" of \"mh-e\", and a \"Key Binding\" of \"m\".
-
-You can use \"xbuffy\" to automate the incorporation of this mail
-using \"emacsclient\" as follows:
-
- box ~/mail/mh-e
- title mh-e
- origMode
- polltime 10
- headertime 0
- command emacsclient --eval \\='(mh-inc-spool-mh-e)\\='"
- :type '(repeat (list (file :tag "Spool File")
- (string :tag "Folder")
- (character :tag "Key Binding")))
- :set (lambda (symbol value)
- (set-default symbol value)
- (mh-inc-spool-make-no-autoload))
- :group 'mh-inc
- :package-version '(MH-E . "7.3"))
-
-;;; Dealing with Junk Mail (:group 'mh-junk)
-
-(defvar mh-junk-choice nil
- "Chosen spam fighting program.")
-
-;; Available spam filter interfaces
-(defvar mh-junk-function-alist
- '((spamassassin mh-spamassassin-blocklist mh-spamassassin-allowlist)
- (bogofilter mh-bogofilter-blocklist mh-bogofilter-allowlist)
- (spamprobe mh-spamprobe-blocklist mh-spamprobe-allowlist))
- "Available choices of spam programs to use.
-
-This is an alist. For each element there are functions that
-blocklist a message as spam and allowlist a message incorrectly
-classified as spam.")
-
-(defun mh-junk-choose (symbol value)
- "Choose spam program to use.
-
-The function is always called with SYMBOL bound to
-`mh-junk-program' and VALUE bound to the new value of
-`mh-junk-program'. The function sets the variable
-`mh-junk-choice' in addition to `mh-junk-program'."
- (set symbol value) ;XXX shouldn't this be set-default?
- (setq mh-junk-choice
- (or value
- (cl-loop for element in mh-junk-function-alist
- until (executable-find (symbol-name (car element)))
- finally return (car element)))))
-
-(defcustom mh-junk-background nil
- "If on, spam programs are run in background.
-
-By default, the programs are run in the foreground, but this can
-be slow when junking large numbers of messages. If you have
-enough memory or don't junk that many messages at the same time,
-you might try turning on this option.
-
-Note that this option is used as the \"destination\" argument in
-the call to `call-process'. Therefore, turning on this option means
-setting its value to \"0\". You can also set its value to t to
-direct the programs' output to the \"*MH-E Log*\" buffer; this
-may be useful for debugging."
- :type '(choice (const :tag "Off" nil)
- (const :tag "On" 0))
- :group 'mh-junk
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-junk-disposition nil
- "Disposition of junk mail."
- :type '(choice (const :tag "Delete Spam" nil)
- (string :tag "Spam Folder"))
- :group 'mh-junk
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-junk-program nil
- "Spam program that MH-E should use.
-
-The default setting of this option is \"Auto-detect\" which means
-that MH-E will automatically choose one of SpamAssassin,
-bogofilter, or SpamProbe in that order. If, for example, you have
-both SpamAssassin and bogofilter installed and you want to use
-bogofilter, then you can set this option to \"Bogofilter\"."
- :type '(choice (const :tag "Auto-detect" nil)
- (const :tag "SpamAssassin" spamassassin)
- (const :tag "Bogofilter" bogofilter)
- (const :tag "SpamProbe" spamprobe))
- :set #'mh-junk-choose
- :group 'mh-junk
- :package-version '(MH-E . "7.3"))
-
-;;; Editing a Draft (:group 'mh-letter)
-
-(defcustom mh-compose-insertion (if (locate-library "mml") 'mml 'mh)
- "Type of tags used when composing MIME messages.
-
-In addition to MH-style directives, MH-E also supports MML (MIME
-Meta Language) tags. (see Info node `(emacs-mime)Composing').
-This option can be used to choose between them. By default, this
-option is set to \"MML\" if it is supported since it provides a
-lot more functionality. This option can also be set to \"MH\" if
-MH-style directives are preferred."
- :type '(choice (const :tag "MML" mml)
- (const :tag "MH" mh))
- :group 'mh-letter
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-compose-skipped-header-fields
- '("From" "Organization" "References" "In-Reply-To"
- "X-Face" "Face" "X-Image-URL" "X-Mailer")
- "List of header fields to skip over when navigating in draft."
- :type '(repeat (string :tag "Field"))
- :group 'mh-letter
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-compose-space-does-completion-flag nil
- "Non-nil means \\<mh-letter-mode-map>\\[mh-letter-complete-or-space] does completion in message header."
- :type 'boolean
- :group 'mh-letter
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-delete-yanked-msg-window-flag nil
- "Non-nil means delete any window displaying the message.
-
-This deletes the window containing the original message after
-yanking it with \\<mh-letter-mode-map>\\[mh-yank-cur-msg] to make
-more room on your screen for your reply."
- :type 'boolean
- :group 'mh-letter
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-extract-from-attribution-verb "wrote:"
- "Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
-
-The attribution consists of the sender's name and email address
-followed by the content of this option. This option can be set to
-\"wrote:\", \"a écrit:\", and \"schrieb:\". You can also use the
-\"Custom String\" menu item to enter your own verb."
- :type '(choice (const "wrote:")
- (const "a écrit:")
- (const "schrieb:")
- (string :tag "Custom String"))
- :group 'mh-letter
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-ins-buf-prefix "> "
- "String to put before each line of a yanked or inserted message.
-
-The prefix \"> \" is the default setting of this option. I
-suggest that you not modify this option since it is used by many
-mailers and news readers: messages are far easier to read if
-several included messages have all been indented by the same
-string.
-
-This prefix is not inserted if you use one of the supercite
-flavors of `mh-yank-behavior' or you have added a
-`mail-citation-hook'."
- :type 'string
- :group 'mh-letter
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-letter-complete-function 'ispell-complete-word
- "Function to call when completing outside of address or folder fields.
-
-In the body of the message,
-\\<mh-letter-mode-map>\\[completion-at-point] runs this function,
-which is set to \"ispell-complete-word\" by default."
- :type '(choice function (const nil))
- :group 'mh-letter
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-letter-fill-column 72
- "Fill column to use in MH Letter mode.
-
-By default, this option is 72 to allow others to quote your
-message without line wrapping."
- :type 'integer
- :group 'mh-letter
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-mml-method-default (if mh-pgp-support-flag "pgpmime" "none")
- "Default method to use in security tags.
-
-This option is used to select between a variety of mail security
-mechanisms. The default is \"PGP (MIME)\" if it is supported;
-otherwise, the default is \"None\". Other mechanisms include
-vanilla \"PGP\" and \"S/MIME\"."
- :type '(choice (const :tag "PGP (MIME)" "pgpmime")
- (const :tag "PGP" "pgp")
- (const :tag "S/MIME" "smime")
- (const :tag "None" "none"))
- :group 'mh-letter
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-signature-file-name "~/.signature"
- "Source of user's signature.
-
-By default, the text of your signature is taken from the file
-\"~/.signature\". You can read from other sources by changing this
-option. This file may contain a vCard in which case an attachment is
-added with the vCard.
-
-This option may also be a symbol, in which case that function is
-called. You may not want a signature separator to be added for you;
-instead you may want to insert one yourself. Options that you may find
-useful to do this include `mh-signature-separator' (when inserting a
-signature separator) and `mh-signature-separator-regexp' (for finding
-said separator). The function `mh-signature-separator-p', which
-reports t if the buffer contains a separator, may be useful as well.
-
-The signature is inserted into your message with the command
-\\<mh-letter-mode-map>\\[mh-insert-signature] or with the option
-`mh-identity-list'."
- :type 'file
- :group 'mh-letter
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-signature-separator-flag t
- "Non-nil means a signature separator should be inserted.
-
-It is not recommended that you change this option since various
-mail user agents, including MH-E, use the separator to present
-the signature differently, and to suppress the signature when
-replying or yanking a letter into a draft."
- :type 'boolean
- :group 'mh-letter
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-x-face-file "~/.face"
- "File containing face header field to insert in outgoing mail.
-
-If the file starts with either of the strings \"X-Face:\", \"Face:\"
-or \"X-Image-URL:\" then the contents are added to the message header
-verbatim. Otherwise it is assumed that the file contains the value of
-the \"X-Face:\" header field.
-
-The \"X-Face:\" header field, which is a low-resolution, black and
-white image, can be generated using the \"compface\" command (see URL
-`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z'). The
-\"Online X-Face Converter\" is a useful resource for quick conversion
-of images into \"X-Face:\" header fields (see URL
-`https://www.dairiki.org/xface/').
-
-Use the \"make-face\" script to convert a JPEG image to the higher
-resolution, color, \"Face:\" header field (see URL
-`https://quimby.gnus.org/circus/face/make-face').
-
-The URL of any image can be used for the \"X-Image-URL:\" field and no
-processing of the image is required.
-
-To prevent the setting of any of these header fields, either set
-`mh-x-face-file' to nil, or simply ensure that the file defined by
-this option doesn't exist."
- :type 'file
- :group 'mh-letter
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-yank-behavior 'attribution
- "Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
-
-To include the entire message, including the entire header, use
-\"Body and Header\". Use \"Body\" to yank just the body without
-the header. To yank only the portion of the message following the
-point, set this option to \"Below Point\".
-
-Choose \"Invoke supercite\" to pass the entire message and header
-through supercite.
-
-If the \"Body With Attribution\" setting is used, then the
-message minus the header is yanked and a simple attribution line
-is added at the top using the value of the option
-`mh-extract-from-attribution-verb'. This is the default.
-
-If the \"Invoke supercite\" or \"Body With Attribution\" settings
-are used, the \"-noformat\" argument is passed to the \"repl\"
-program to override a \"-filter\" or \"-format\" argument. These
-settings also have \"Automatically\" variants that perform the
-action automatically when you reply so that you don't need to use
-\\[mh-yank-cur-msg] at all. Note that this automatic action is
-only performed if the show buffer matches the message being
-replied to. People who use the automatic variants tend to turn on
-the option `mh-delete-yanked-msg-window-flag' as well so that the
-show window is never displayed.
-
-If the show buffer has a region, the option `mh-yank-behavior' is
-ignored unless its value is one of Attribution variants in which
-case the attribution is added to the yanked region.
-
-If this option is set to one of the supercite flavors, the hook
-`mail-citation-hook' is ignored and `mh-ins-buf-prefix' is not
-inserted."
- :type '(choice (const :tag "Body and Header" t)
- (const :tag "Body" body)
- (const :tag "Below Point" nil)
- (const :tag "Invoke supercite" supercite)
- (const :tag "Invoke supercite, Automatically" autosupercite)
- (const :tag "Body With Attribution" attribution)
- (const :tag "Body With Attribution, Automatically"
- autoattrib))
- :group 'mh-letter
- :package-version '(MH-E . "8.0"))
-
-;;; Ranges (:group 'mh-ranges)
-
-(defcustom mh-interpret-number-as-range-flag t
- "Non-nil means interpret a number as a range.
-
-Since one of the most frequent ranges used is \"last:N\", MH-E
-will interpret input such as \"200\" as \"last:200\" if this
-option is on (which is the default). If you need to scan just the
-message 200, then use the range \"200:200\"."
- :type 'boolean
- :group 'mh-ranges
- :package-version '(MH-E . "7.4"))
-
-;;; Scan Line Formats (:group 'mh-scan-line-formats)
-
-(eval-and-compile
- (unless (fboundp 'mh-adaptive-cmd-note-flag-check)
- (defun mh-adaptive-cmd-note-flag-check (symbol value)
- "Temporary definition.
-Real definition, below, uses variables that aren't defined yet."
- (set-default symbol value))))
-
-(defcustom mh-adaptive-cmd-note-flag t
- "Non-nil means that the message number width is determined dynamically.
-
-If you've created your own format to handle long message numbers,
-you'll be pleased to know you no longer need it since MH-E adapts its
-internal format based upon the largest message number if this option
-is on (the default). This option may only be turned on when
-`mh-scan-format-file' is set to \"Use MH-E scan Format\".
-
-If you prefer fixed-width message numbers, turn off this option and
-call `mh-set-cmd-note' with the width specified by your format file
-\(see `mh-scan-format-file'). For example, the default width is 4, so
-you would use \"(mh-set-cmd-note 4)\"."
- :type 'boolean
- :group 'mh-scan-line-formats
- :set #'mh-adaptive-cmd-note-flag-check
- :package-version '(MH-E . "7.0"))
-
-(defun mh-scan-format-file-check (symbol value)
- "Check if desired setting is valid.
-Throw an error if user tries to set `mh-scan-format-file' to
-anything but t when `mh-adaptive-cmd-note-flag' is on. Otherwise,
-set SYMBOL to VALUE."
- (if (and (not (eq value t))
- mh-adaptive-cmd-note-flag)
- (error "%s %s" "You must turn off `mh-adaptive-cmd-note-flag'"
- "unless you use \"Use MH-E scan Format\"")
- (set-default symbol value)))
-
-(defcustom mh-scan-format-file t
- "Specifies the format file to pass to the scan program.
-
-The default setting for this option is \"Use MH-E scan Format\". This
-means that the format string will be taken from the either
-`mh-scan-format-mh' or `mh-scan-format-nmh' depending on whether MH or
-nmh (or GNU mailutils MH) is in use. This setting also enables you to
-turn on the `mh-adaptive-cmd-note-flag' option.
-
-You can also set this option to \"Use Default scan Format\" to get the
-same output as you would get if you ran \"scan\" from the shell. If
-you have a format file that you want MH-E to use but not MH, you can
-set this option to \"Specify a scan Format File\" and enter the name
-of your format file.
-
-If you change the format of the scan lines you'll need to tell MH-E
-how to parse the new format. As you will see, quite a lot of variables
-are involved to do that. Use \"\\[apropos] RET mh-scan.*regexp\" to
-obtain a list of these variables. You will also have to call
-`mh-set-cmd-note' if your notations are not in column 4 (columns in
-Emacs start with 0)."
- :type '(choice (const :tag "Use MH-E scan Format" t)
- (const :tag "Use Default scan Format" nil)
- (file :tag "Specify a scan Format File"))
- :group 'mh-scan-line-formats
- :set #'mh-scan-format-file-check
- :package-version '(MH-E . "6.0"))
-
-(defun mh-adaptive-cmd-note-flag-check (symbol value)
- "Check if desired setting is valid.
-Throw an error if user tries to turn on
-`mh-adaptive-cmd-note-flag' when `mh-scan-format-file' isn't t.
-Otherwise, set SYMBOL to VALUE."
- (if (and value
- (not (eq mh-scan-format-file t)))
- (error "%s %s" "Can't turn on unless `mh-scan-format-file'"
- "is set to \"Use MH-E scan Format\"")
- (set-default symbol value)))
-
-(defcustom mh-scan-prog "scan"
- "Program used to scan messages.
-
-The name of the program that generates a listing of one line per
-message is held in this option. Unless this variable contains an
-absolute pathname, it is assumed to be in the `mh-progs'
-directory. You may link another program to `scan' (see
-\"mh-profile(5)\") to produce a different type of listing."
- :type 'string
- :group 'mh-scan-line-formats
- :package-version '(MH-E . "6.0"))
-(make-variable-buffer-local 'mh-scan-prog)
-
-;;; Searching (:group 'mh-search)
-
-(defcustom mh-search-program nil
- "Search program that MH-E shall use.
-
-The default setting of this option is \"Auto-detect\" which means
-that MH-E will automatically choose one of swish++, swish-e,
-mairix, namazu, pick and grep in that order. If, for example, you
-have both swish++ and mairix installed and you want to use
-mairix, then you can set this option to \"mairix\".
-
-More information about setting up an indexing program to use with
-MH-E can be found in the documentation of `mh-search'."
- :type '(choice (const :tag "Auto-detect" nil)
- (const :tag "swish++" swish++)
- (const :tag "swish-e" swish)
- (const :tag "mairix" mairix)
- (const :tag "namazu" namazu)
- (const :tag "pick" pick)
- (const :tag "grep" grep))
- :group 'mh-search
- :package-version '(MH-E . "8.0"))
-
-;;; Sending Mail (:group 'mh-sending-mail)
-
-(defcustom mh-compose-forward-as-mime-flag t
- "Non-nil means that messages are forwarded as attachments.
-
-By default, this option is on which means that the forwarded
-messages are included as attachments. If you would prefer to
-forward your messages verbatim (as text, inline), then turn off
-this option. Forwarding messages verbatim works well for short,
-textual messages, but your recipient won't be able to view any
-non-textual attachments that were in the forwarded message. Be
-aware that if you have \"forw: -mime\" in your MH profile, then
-forwarded messages will always be included as attachments
-regardless of the settings of this option."
- :type 'boolean
- :group 'mh-sending-mail
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-compose-letter-function nil
- "Invoked when starting a new draft.
-
-However, it is the last function called before you edit your
-message. The consequence of this is that you can write a function
-to write and send the message for you. This function is passed
-three arguments: the contents of the TO, SUBJECT, and CC header
-fields."
- :type '(choice (const nil) function)
- :group 'mh-sending-mail
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-compose-prompt-flag nil
- "Non-nil means prompt for header fields when composing a new draft."
- :type 'boolean
- :group 'mh-sending-mail
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-forward-subject-format "%s: %s"
- "Format string for forwarded message subject.
-
-This option is a string which includes two escapes (\"%s\"). The
-first \"%s\" is replaced with the sender of the original message,
-and the second one is replaced with the original \"Subject:\"."
- :type 'string
- :group 'mh-sending-mail
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-insert-x-mailer-flag t
- "Non-nil means append an \"X-Mailer:\" header field to the header.
-
-This header field includes the version of MH-E and Emacs that you
-are using. If you don't want to participate in our marketing, you
-can turn this option off."
- :type 'boolean
- :group 'mh-sending-mail
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-redist-full-contents-flag nil
- "Non-nil means the \"dist\" command needs entire letter for redistribution.
-
-This option must be turned on if \"dist\" requires the whole
-letter for redistribution, which is the case if \"send\" is
-compiled with the BERK option (which many people abhor). If you
-find that MH will not allow you to redistribute a message that
-has been redistributed before, turn off this option."
- :type 'boolean
- :group 'mh-sending-mail
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-reply-default-reply-to nil
- "Sets the person or persons to whom a reply will be sent.
-
-This option is set to \"Prompt\" by default so that you are
-prompted for the recipient of a reply. If you find that most of
-the time that you specify \"cc\" when you reply to a message, set
-this option to \"cc\". Other choices include \"from\", \"to\", or
-\"all\". You can always edit the recipients in the draft."
- :type '(choice (const :tag "Prompt" nil)
- (const "from")
- (const "to")
- (const "cc")
- (const "all"))
- :group 'mh-sending-mail
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-reply-show-message-flag t
- "Non-nil means the MH-Show buffer is displayed when replying.
-
-If you include the message automatically, you can hide the
-MH-Show buffer by turning off this option.
-
-See also `mh-reply'."
- :type 'boolean
- :group 'mh-sending-mail
- :package-version '(MH-E . "7.0"))
-
-;;; Sequences (:group 'mh-sequences)
-
-;; If `mh-unpropagated-sequences' becomes a defcustom, add the following to
-;; the docstring: "Additional sequences that should not to be preserved can be
-;; specified by setting `mh-unpropagated-sequences' appropriately." XXX
-
-(defcustom mh-refile-preserves-sequences-flag t
- "Non-nil means that sequences are preserved when messages are refiled.
-
-If a message is in any sequence (except \"Previous-Sequence:\"
-and \"cur\") when it is refiled, then it will still be in those
-sequences in the destination folder. If this behavior is not
-desired, then turn off this option."
- :type 'boolean
- :group 'mh-sequences
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-tick-seq 'tick
- "The name of the MH sequence for ticked messages.
-
-You can customize this option if you already use the \"tick\"
-sequence for your own use. You can also disable all of the
-ticking functions by choosing the \"Disable Ticking\" item but
-there isn't much advantage to that."
- :type '(choice (const :tag "Disable Ticking" nil)
- symbol)
- :group 'mh-sequences
- :package-version '(MH-E . "7.3"))
-
-(defcustom mh-update-sequences-after-mh-show-flag t
- "Non-nil means flush MH sequences to disk after message is shown\\<mh-folder-mode-map>.
-
-Three sequences are maintained internally by MH-E and pushed out
-to MH when a message is shown. They include the sequence
-specified by your \"Unseen-Sequence:\" profile entry, \"cur\",
-and the sequence listed by the option `mh-tick-seq' which is
-\"tick\" by default. If you do not like this behavior, turn off
-this option. You can then update the state manually with the
-\\[mh-execute-commands], \\[mh-quit], or \\[mh-update-sequences]
-commands."
- :type 'boolean
- :group 'mh-sequences
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-allowlist-preserves-sequences-flag t
- "Non-nil means that sequences are preserved when messages are allowlisted.
-
-If a message is in any sequence (except \"Previous-Sequence:\"
-and \"cur\") when it is allowlisted, then it will still be in
-those sequences in the destination folder. If this behavior is
-not desired, then turn off this option."
- :type 'boolean
- :group 'mh-sequences
- :package-version '(MH-E . "8.4"))
-
-;;; Reading Your Mail (:group 'mh-show)
-
-(defcustom mh-bury-show-buffer-flag t
- "Non-nil means show buffer is buried.
-
-One advantage of not burying the show buffer is that one can
-delete the show buffer more easily in an electric buffer list
-because of its proximity to its associated MH-Folder buffer. Try
-running \\[electric-buffer-list] to see what I mean."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-clean-message-header-flag t
- "Non-nil means remove extraneous header fields.
-
-See also `mh-invisible-header-fields-default' and
-`mh-invisible-header-fields'."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode")))
- "Non-nil means attachments are handled\\<mh-folder-mode-map>.
-
-MH-E can handle attachments as well if the Gnus `mm-decode'
-library is present. If so, this option will be on. Otherwise,
-you'll see the MIME body parts rather than text or attachments.
-There isn't much point in turning off this option; however, you
-can inspect it if it appears that the body parts are not being
-interpreted correctly or toggle it with the command
-\\[mh-toggle-mh-decode-mime-flag] to view the raw message.
-
-This option also controls the display of quoted-printable
-messages and other graphical widgets. See the options
-`mh-graphical-smileys-flag' and `mh-graphical-emphasis-flag'."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-display-buttons-for-alternatives-flag nil
- "Non-nil means display buttons for all alternative attachments.
-
-Sometimes, a mail program will produce multiple alternatives of
-the attachment in increasing degree of faithfulness to the
-original content. By default, only the preferred alternative is
-displayed. If this option is on, then the preferred part is shown
-inline and buttons are shown for each of the other alternatives."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-display-buttons-for-inline-parts-flag nil
- "Non-nil means display buttons for all inline attachments\\<mh-folder-mode-map>.
-
-The sender can request that attachments should be viewed inline so
-that they do not really appear like an attachment at all to the
-reader. Most of the time, this is desirable, so by default MH-E
-suppresses the buttons for inline attachments. On the other hand, you
-may receive code or HTML which the sender has added to his message as
-inline attachments so that you can read them in MH-E. In this case, it
-is useful to see the buttons so that you know you don't have to cut
-and paste the code into a file; you can simply save the attachment.
-
-If you want to make the buttons visible for inline attachments, you
-can use the command \\[mh-toggle-mime-buttons] to toggle the
-visibility of these buttons. You can turn on these buttons permanently
-by turning on this option.
-
-MH-E cannot display all attachments inline however. It can display
-text (including HTML) and images."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-do-not-confirm-flag nil
- "Non-nil means non-reversible commands do not prompt for confirmation.
-
-Commands such as `mh-pack-folder' prompt to confirm whether to
-process outstanding moves and deletes or not before continuing.
-Turning on this option means that these actions will be
-performed--which is usually desired but cannot be
-retracted--without question."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-fetch-x-image-url nil
- "Control fetching of \"X-Image-URL:\" header field image.
-
-This option controls the fetching of the \"X-Image-URL:\" header
-field image with the following values:
-
-Ask Before Fetching
- You are prompted before the image is fetched. MH-E will
- remember your reply and will either use the already fetched
- image the next time the same URL is encountered or silently
- skip it if you didn't fetch it the first time. This is a
- good setting.
-
-Never Fetch
- Images are never fetched and only displayed if they are
- already present in the cache. This is the default.
-
-There isn't a value of \"Always Fetch\" for privacy and DOS (denial of
-service) reasons. For example, fetching a URL can tip off a spammer
-that you've read his email (which is why you shouldn't blindly answer
-yes if you've set this option to \"Ask Before Fetching\"). Someone may
-also flood your network and fill your disk drive by sending a torrent
-of messages, each specifying a unique URL to a very large file.
-
-The cache of images is found in the directory \".mhe-x-image-cache\"
-within your MH directory. You can add your own face to the \"From:\"
-field too. See Info node `(mh-e)Picture'.
-
-This setting only has effect if the option `mh-show-use-xface-flag' is
-turned on."
-
- :type '(choice (const :tag "Ask Before Fetching" ask)
- (const :tag "Never Fetch" nil))
- :group 'mh-show
- :package-version '(MH-E . "7.3"))
-
-(defcustom mh-graphical-smileys-flag t
- "Non-nil means graphical smileys are displayed.
-
-It is a long standing custom to inject body language using a
-cornucopia of punctuation, also known as the \"smileys\". MH-E
-can render these as graphical widgets if this option is turned
-on, which it is by default. Smileys include patterns such as :-)
-and ;-).
-
-This option is disabled if the option `mh-decode-mime-flag' is
-turned off."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-graphical-emphasis-flag t
- "Non-nil means graphical emphasis is displayed.
-
-A few typesetting features are indicated in ASCII text with
-certain characters. If your terminal supports it, MH-E can render
-these typesetting directives naturally if this option is turned
-on, which it is by default. For example, _underline_ will be
-underlined, *bold* will appear in bold, /italics/ will appear in
-italics, and so on. See the option `gnus-emphasis-alist' for the
-whole list.
-
-This option is disabled if the option `mh-decode-mime-flag' is
-turned off."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-highlight-citation-style 'gnus
- "Style for highlighting citations.
-
-If the sender of the message has cited other messages in his
-message, then MH-E will highlight these citations to emphasize
-the sender's actual response. This option can be customized to
-change the highlighting style. The \"Multicolor\" method uses a
-different color for each indentation while the \"Monochrome\"
-method highlights all citations in red. To disable highlighting
-of citations entirely, choose \"None\"."
- :type '(choice (const :tag "Multicolor" gnus)
- (const :tag "Monochrome" font-lock)
- (const :tag "None" nil))
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-;; These entries have been intentionally excluded by the developers.
-;; "Comments:" ; RFC 822 (or later) - show this one
-;; "Fax:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
-;; "Mail-System-Version:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
-;; "Mailer:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
-;; "Organization:" ;
-;; "Phone:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
-;; "Reply-By:" ; RFC 2156
-;; "Reply-To:" ; RFC 822 (or later)
-;; "Sender:" ;
-;; "User-Agent:" ; Similar to X-Mailer, so display it.
-;; "X-Mailer:" ;
-;; "X-Operator:" ; Similar to X-Mailer, so display it
-
-;; Keep fields alphabetized with case folding. Use M-:(setq
-;; sort-fold-case t) from the minibuffer to accomplish this.
-;; Mention source, if known.
-(defvar mh-invisible-header-fields-internal
- '(
- "Abuse-Reports-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Accept-Language:"
- "AcceptLanguage:"
- "Accreditor:" ; Habeas
- "Also-Control:" ; H. Spencer: News Article Format and Transmission, June 1994
- "Alternate-recipient:" ; RFC 2156
- "Approved-By:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Approved:" ; RFC 1036
- "Article-Names:" ; H. Spencer: News Article Format and Transmission, June 1994
- "Article-Updates:" ; H. Spencer: News Article Format and Transmission, June 1994
- "Authentication-Results:"
- "Auto-forwarded:" ; RFC 2156
- "Autoforwarded:" ; RFC 2156
- "Bestservhost:"
- "Bounces-To:"
- "Bounces_to:"
- "Bytes:"
- "Cancel-Key:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Cancel-Lock:" ; NNTP posts
- "Comment:" ; Shows up with DomainKeys
- "Content-" ; RFC 2045, 1123, 1766, 1864, 2045, 2110, 2156, 2183, 2912
- "Control:" ; RFC 1036
- "Conversion-With-Loss:" ; RFC 2156
- "Conversion:" ; RFC 2156
- "Delivered-To:" ; Egroups/yahoogroups mailing list manager
- "Delivery-Date:" ; RFC 2156
- "Delivery:"
- "Discarded-X400-" ; RFC 2156
- "Disclose-Recipients:" ; RFC 2156
- "Disposition-Notification-Options:" ; RFC 2298
- "Disposition-Notification-To:" ; RFC 2298
- "Distribution:" ; RFC 1036
- "DKIM-" ; https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
- "DL-Expansion-History:" ; RFC 2156
- "DomainKey-" ; https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
- "DomainKey-Signature:"
- "Encoding:" ; RFC 1505
- "Envelope-to:"
- "Errors-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Expires:" ; RFC 1036
- "Expiry-Date:" ; RFC 2156
- "Face:" ; Gnus Face header
- "Followup-To:" ; RFC 1036
- "For-Approval:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "For-Comment:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "For-Handling:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Forwarded:" ; MH
- "From " ; sendmail
- "Generate-Delivery-Report:" ; RFC 2156
- "Importance:" ; RFC 2156, 2421
- "In-Reply-To:" ; RFC 822 (or later)
- "Incomplete-Copy:" ; RFC 2156
- "Keywords:" ; RFC 822 (or later)
- "Language:" ; RFC 2156
- "Lines:" ; RFC 1036
- "List-" ; RFC 2369, 2919
- "Mail-Copies-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Mail-Followup-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Mail-from:" ; MH
- "Mail-Reply-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Mailing-List:" ; Egroups/yahoogroups mailing list manager
- "Message-Content:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Message-ID:" ; RFC 822 (or later)
- "Message-Type:" ; RFC 2156
- "Mime-Version" ; RFC 2045
- "Msgid:"
- "NNTP-" ; News
- "Obsoletes:" ; RFC 2156
- "Old-Return-Path:"
- "OpenPGP:"
- "Original-Encoded-Information-Types:" ; RFC 2156
- "Original-Lines:" ; mail to news
- "Original-Newsgroups:" ; mail to news
- "Original-NNTP-" ; mail to news
- "Original-Path:" ; mail to news
- "Original-Received:" ; mail to news
- "Original-Recipient:" ; RFC 2298
- "Original-To:" ; mail to news
- "Original-X-" ; mail to news
- "Origination-Client:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Originator:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "P1-Content-Type:" ; X400
- "P1-Message-Id:" ; X400
- "P1-Recipient:" ; X400
- "Path:" ; RFC 1036
- "Pics-Label:" ; W3C
- "Posted-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Precedence:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Prev-Resent" ; MH
- "Prevent-NonDelivery-Report:" ; RFC 2156
- "Priority:" ; RFC 2156
- "Read-Receipt-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Received-SPF:" ; Gmail
- "Received:" ; RFC 822 (or later)
- "References:" ; RFC 822 (or later)
- "Registered-Mail-Reply-Requested-By:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Remailed-" ; MH
- "Replaces:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Replied:" ; MH
- "Resent-" ; RFC 822 (or later)
- "Return-Path:" ; RFC 822 (or later)
- "Return-Receipt-Requested:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Return-Receipt-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Seal-Send-Time:"
- "See-Also:" ; H. Spencer: News Article Format and Transmission, June 1994
- "Sensitivity:" ; RFC 2156, 2421
- "Speech-Act:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Status:" ; sendmail
- "Supersedes:" ; H. Spencer: News Article Format and Transmission, June 1994
- "Telefax:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Thread-"
- "Thread-Index:"
- "Thread-Topic:"
- "Translated-By:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Translation-Of:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "Ua-Content-Id:" ; X400
- "Via:" ; MH
- "X-Abuse-and-DMCA-"
- "X-Abuse-Info:"
- "X-Accept-Language:" ; Netscape/Mozilla
- "X-Ack:"
- "X-ACL-Warn:" ; https://www.exim.org
- "X-Admin:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Administrivia-To:"
- "X-AMAZON" ; Amazon.com
- "X-AnalysisOut:" ; Exchange
- "X-AntiAbuse:" ; cPanel
- "X-Antivirus-Scanner:"
- "X-AOL-IP:" ; AOL WebMail
- "X-Apparently-From:" ; MS Outlook
- "X-Apparently-To:" ; Egroups/yahoogroups mailing list manager
- "X-Attribution:"
- "X-AuditID:"
- "X-Authenticated-Info:" ; Verizon.net?
- "X-Authenticated-Sender:" ; AT&T Message Center (webmail)
- "X-Authentication-Info:" ; verizon.net?
- "X-Authentication-Warning:" ; sendmail
- "X-Authority-Analysis:"
- "X-Auto-Response-Suppress:" ; Exchange
- "X-Barracuda-" ; Barracuda spam scores
- "X-Bayes-Prob:" ; IEEE spam filter
- "X-Beenthere:" ; Mailman mailing list manager
- "X-BFI:"
- "X-Bigfish:"
- "X-Bogosity:" ; bogofilter
- "X-BPS1:" ; http://www.boggletools.com [dead link?]
- "X-BPS2:" ; http://www.boggletools.com [dead link?]
- "X-Brightmail-Tracker:" ; Brightmail
- "X-BrightmailFiltered:" ; Brightmail
- "X-Bugzilla-" ; Bugzilla
- "X-Cam-" ; Cambridge scanners
- "X-Campaign-Id:"
- "X-Campaign:"
- "X-Campaignid:"
- "X-CanIt-Geo:" ; IEEE spam filter
- "X-Cloudmark-SP-" ; Cloudmark (www.cloudmark.com)
- "X-Comment:" ; AT&T Mailennium
- "X-Complaints-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Completed:"
- "X-Confirm-Reading-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Content-Filtered-By:"
- "X-ContentStamp:" ; NetZero
- "X-Country-Chain:" ; http://www.declude.com/x-note.htm [dead link?]
- "X-Cr-Hashedpuzzle:"
- "X-Cr-Puzzleid:"
- "X-Cron-Env:"
- "X-DCC-" ; SpamAssassin
- "X-Declude-" ; http://www.declude.com/x-note.htm [dead link?]
- "X-Dedicated:"
- "X-Delivered"
- "X-Destination-ID:"
- "X-detected-operating-system:" ; GNU.ORG?
- "X-DH-Virus-"
- "X-DMCA"
- "X-DocGen-Version:" ; DocGen
- "X-Domain:"
- "X-Echelon-Distraction"
- "X-EFL-Spamscore:" ; MIT alumni spam filtering
- "X-eGroups-" ; Egroups/yahoogroups mailing list manager
- "X-EID:"
- "X-ELNK-Trace:" ; Earthlink mailer
- "X-EM-" ; Some ecommerce software
- "X-Email-Type-Id:" ; Paypal https://www.paypal.com
- "X-Enigmail-Version:"
- "X-Envelope-Date:" ; GNU mailutils
- "X-Envelope-From:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Envelope-Sender:"
- "X-Envelope-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-EviteMessageId:" ; evite.com
- "X-Evolution:" ; Evolution mail client
- "X-ExtLoop"
- "X-Face:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Facebook" ; Facebook
- "X-FB-SS:"
- "X-fmx-"
- "X-Folder:" ; Spam
- "X-Forwarded-" ; Google+
- "X-From-Line"
- "X-FuHaFi:" ; https://www.gmx.net/
- "X-Generated-By:" ; launchpad.net
- "X-Gmail-" ; Gmail
- "X-Gnus-Mail-Source:" ; gnus
- "X-Google-" ; Google mail
- "X-Google-Sender-Auth:"
- "X-Greylist:" ; milter-greylist-1.2.1
- "X-Habeas-" ; https://www.returnpath.net
- "X-Hashcash:" ; hashcash
- "X-Headers-End:" ; SpamCop
- "X-HPL-"
- "X-HR-"
- "X-HTTP-UserAgent:"
- "X-Hz" ; Hertz
- "X-Identity:" ; http://www.declude.com/x-note.htm [dead link?]
- "X-IEEE-UCE-" ; IEEE spam filter
- "X-Image-URL:"
- "X-IMAP:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Info:" ; NTMail
- "X-IronPort-" ; IronPort AV
- "X-ISI-4-30-3-MailScanner:"
- "X-J2-"
- "X-Jira-Fingerprint:" ; JIRA
- "X-Junkmail-" ; RCN?
- "X-Juno-" ; Juno
- "X-Key:"
- "X-Launchpad-" ; plaunchpad.net
- "X-List-Host:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-List-Subscribe:" ; Unknown mailing list managers
- "X-List-Unsubscribe:" ; Unknown mailing list managers
- "X-Listprocessor-" ; ListProc(tm) by CREN
- "X-Listserver:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Loop:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Lrde-Mailscanner:"
- "X-Lumos-SenderID:" ; Roving ConstantContact
- "X-mail_abuse_inquiries:" ; https://www.salesforce.com
- "X-Mail-from:" ; fastmail.fm
- "X-MAIL-INFO:" ; NetZero
- "X-Mailer_"
- "X-MailFlowPolicy:" ; Cisco Email Security (formerly IronPort; http://www.ironport.com)
- "X-Mailing-List:" ; Unknown mailing list managers
- "X-MailingID:"
- "X-Mailman-Approved-At:" ; Mailman mailing list manager
- "X-Mailman-Version:" ; Mailman mailing list manager
- "X-MailScanner" ; ListProc(tm) by CREN
- "X-Mailutils-Message-Id" ; GNU Mailutils
- "X-Majordomo:" ; Majordomo mailing list manager
- "X-Match:"
- "X-MaxCode-Template:" ; Paypal https://www.paypal.com
- "X-MB-Message-" ; AOL WebMail
- "X-MDaemon-Deliver-To:"
- "X-MDRemoteIP:"
- "X-ME-Bayesian:" ; https://www.newmediadevelopment.net/page.cfm/parent/Client-Area/content/Managing-spam/
- "X-Message-Id"
- "X-Message-Type:"
- "X-MessageWall-Score:" ; Unknown mailing list manager, AUC TeX
- "X-MHE-Checksum:" ; Checksum added during index search
- "X-MIME-Autoconverted:" ; sendmail
- "X-MIMEOLE:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/sendmail
- "X-MIMETrack:"
- "X-Mms-" ; T-Mobile pictures
- "X-Mozilla-Status:" ; Netscape/Mozilla
- "X-MS-" ; MS Outlook
- "X-Msmail-" ; MS Outlook
- "X-MSMail-Priority" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-MXL-Hash:"
- "X-NAI-Spam-" ; Network Associates Inc. SpamKiller
- "X-News:" ; News
- "X-Newsreader:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-No-Archive:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Notes-Item:" ; Lotus Notes Domino structured header
- "X-Notification-" ; Google+
- "X-Notifications:" ; Google+
- "X-OperatingSystem:"
- "X-Oracle-Calendar:" ; Oracle calendar invitations
- "X-ORBL:"
- "X-Orcl-Content-Type:"
- "X-Organization:"
- "X-Original-Arrival-Type:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Original-Complaints-To:"
- "X-Original-Date:" ; SourceForge mailing list manager
- "X-Original-To:"
- "X-Original-Trace:"
- "X-OriginalArrivalTime:" ; Hotmail
- "X-Originating-Email:" ; Hotmail
- "X-Originating-IP:" ; Hotmail
- "X-pair-"
- "X-PGP:"
- "X-PID:"
- "X-PMG-"
- "X-PMX-Version:"
- "X-Policyd-Weight:" ; policyd-weight (Postfix)
- "X-Postfilter:"
- "X-Priority:" ; MS Outlook
- "X-Proofpoint-" ; Proofpoint mail filter
- "X-Provags-ID:"
- "X-PSTN-"
- "X-Qotd-" ; User added
- "X-RCPT-TO:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Received-Date:"
- "X-Received:"
- "X-Report-Abuse-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Request-"
- "X-Resolved-to:" ; fastmail.fm
- "X-Return-Path-Hint:" ; Roving ConstantContact
- "X-RIM-" ; Research In Motion (i.e. BlackBerry)
- "X-RM"
- "X-RocketYMMF:" ; Yahoo
- "X-Roving-" ; Roving ConstantContact
- "X-SA-Exim-" ; Exim SpamAssassin
- "X-Sasl-enc:" ; Apple Mail
- "X-SBClass:" ; Spam
- "X-SBNote:" ; Spam
- "X-SBPass:" ; Spam
- "X-SBRS:"
- "X-SBRule:" ; Spam
- "X-Scanned-By:"
- "X-Sender-ID:" ; Google+
- "X-Sender:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Sendergroup:" ; Cisco Email Security (formerly IronPort; http://www.ironport.com)
- "X-Server-Date:"
- "X-Server-Uuid:"
- "X-Service-Code:"
- "X-SFDC-" ; https://www.salesforce.com
- "X-Sieve:" ; Sieve filtering
- "X-SMFBL:"
- "X-SMHeaderMap:"
- "X-SMTP-"
- "X-Source"
- "X-Spam-" ; SpamAssassin
- "X-Spam:" ; Exchange
- "X-SpamBouncer:" ; Spam
- "X-SPF-"
- "X-Status"
- "X-Submission-Address:"
- "X-Submissions-To:"
- "X-Sun-Charset:"
- "X-Telecom-Digest"
- "X-TM-IMSS-Message-ID:" ; https://www.trendmicro.com
- "X-Trace:"
- "X-UID"
- "X-UIDL:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-Unity"
- "X-UNTD-" ; NetZero
- "X-URI:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-URL:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-USANET-" ; usa.net
- "X-Usenet-Provider"
- "X-UserInfo1:"
- "X-VGI-OESCD:"
- "X-VirtualServer:"
- "X-VirtualServerGroup:"
- "X-Virus-" ;
- "X-Vms-To:"
- "X-VSMLoop:" ; NTMail
- "X-WebTV-Signature:"
- "X-Wss-Id:" ; Worldtalk gateways
- "X-X-Sender:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/
- "X-XPT-XSL-Name:" ; Paypal https://www.paypal.com
- "X-xsi-"
- "X-XWALL-" ; https://www.dataenter.co.at/doc/xwall_undocumented_config.htm
- "X-Y-GMX-Trusted:" ; https://www.gmx.net/
- "X-Yahoo"
- "X-Yahoo-Newman-"
- "X-YMail-"
- "X-ZixNet:"
- "X400-" ; X400
- "Xref:" ; RFC 1036
- )
- "List of default header fields that are not to be shown.
-
-Do not alter this variable directly. Instead, add entries from
-here that you would like to be displayed in
-`mh-invisible-header-fields-default' and add entries to hide in
-`mh-invisible-header-fields'.")
-
-(eval-and-compile
- (unless (fboundp 'mh-invisible-headers)
- (defun mh-invisible-headers ()
- "Temporary definition.
-Real definition, below, uses variables that aren't defined yet."
- nil)))
-
-(defvar mh-delay-invisible-header-generation-flag t
- "Non-nil means to delay the generation of invisible header fields.
-Because the function `mh-invisible-headers' uses both
-`mh-invisible-header-fields' and `mh-invisible-header-fields', it
-cannot be run until both variables have been initialized.")
-
-(defcustom mh-invisible-header-fields nil
- "Additional header fields to hide.
-
-Header fields that you would like to hide that aren't listed in
-`mh-invisible-header-fields-default' can be added to this option
-with a couple of caveats. Regular expressions are not allowed.
-Unique fields should have a \":\" suffix; otherwise, the element
-can be used to render invisible an entire class of fields that
-start with the same prefix.
-
-If you think a header field should be generally ignored, please
-update SF #1916032 (see URL
-`https://sourceforge.net/tracker/index.php?func=detail&aid=1916032&group_id=13357&atid=113357').
-
-See also `mh-clean-message-header-flag'."
-
- :type '(repeat (string :tag "Header field"))
- :set (lambda (symbol value)
- (set-default symbol value)
- (mh-invisible-headers))
- :group 'mh-show
- :package-version '(MH-E . "7.1"))
-
-(defcustom mh-invisible-header-fields-default nil
- "List of hidden header fields.
-
-The header fields listed in this option are hidden, although you
-can check off any field that you would like to see.
-
-Header fields that you would like to hide that aren't listed can
-be added to the option `mh-invisible-header-fields'.
-
-See also `mh-clean-message-header-flag'.
-
-If you think a header field should be added to this list, please
-update SF #1916032 (see URL
-`https://sourceforge.net/tracker/index.php?func=detail&aid=1916032&group_id=13357&atid=113357')."
- :type `(set ,@(mapcar (lambda (x) `(const ,x))
- mh-invisible-header-fields-internal))
- :set (lambda (symbol value)
- (set-default symbol value)
- (mh-invisible-headers))
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defvar mh-invisible-header-fields-compiled nil
- "Regexp matching lines in a message header that are not to be shown.
-Do not alter this variable directly. Instead, customize
-`mh-invisible-header-fields-default' checking for fields normally
-hidden that you wish to display, and add extra entries to hide in
-`mh-invisible-header-fields'.")
-
-(defun mh-invisible-headers ()
- "Make or remake the variable `mh-invisible-header-fields-compiled'.
-Done using `mh-invisible-header-fields-internal' as input, from
-which entries from `mh-invisible-header-fields-default' are
-removed and entries from `mh-invisible-header-fields' are added."
- (let ((fields mh-invisible-header-fields-internal))
- (when mh-invisible-header-fields-default
- ;; Remove entries from `mh-invisible-header-fields-default'
- (setq fields
- (cl-loop for x in fields
- unless (member x mh-invisible-header-fields-default)
- collect x)))
- (when (and (boundp 'mh-invisible-header-fields)
- mh-invisible-header-fields)
- (dolist (x mh-invisible-header-fields)
- (unless (member x fields) (setq fields (cons x fields)))))
- (if fields
- (setq mh-invisible-header-fields-compiled
- (concat
- "^"
- (regexp-opt fields t)))
- (setq mh-invisible-header-fields-compiled nil))))
-
-;; Compile invisible header fields.
-(mh-invisible-headers)
-
-(defcustom mh-lpr-command-format "lpr -J '%s'"
- "Command used to print\\<mh-folder-mode-map>.
-
-This option contains the Unix command line which performs the
-actual printing for the \\[mh-print-msg] command. The string can
-contain one escape, \"%s\", which is replaced by the name of the
-folder and the message number and is useful for print job names.
-I use \"mpage -h\\='%s\\=' -b Letter -H1of -mlrtb -P\" which produces a
-nice header and adds a bit of margin so the text fits within my
-printer's margins.
-
-This option is not used by the commands \\[mh-ps-print-msg] or
-\\[mh-ps-print-msg-file]."
- :type 'string
- :group 'mh-show
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-max-inline-image-height nil
- "Maximum inline image height if \"Content-Disposition:\" is not present.
-
-Some older mail programs do not insert this needed plumbing to
-tell MH-E whether to display the attachments inline or not. If
-this is the case, MH-E will display these images inline if they
-are smaller than the window. However, you might want to allow
-larger images to be displayed inline. To do this, you can change
-the options `mh-max-inline-image-width' and
-`mh-max-inline-image-height' from their default value of zero to
-a large number. The size of your screen is a good choice for
-these numbers."
- :type '(choice (const nil) integer)
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-max-inline-image-width nil
- "Maximum inline image width if \"Content-Disposition:\" is not present.
-
-Some older mail programs do not insert this needed plumbing to
-tell MH-E whether to display the attachments inline or not. If
-this is the case, MH-E will display these images inline if they
-are smaller than the window. However, you might want to allow
-larger images to be displayed inline. To do this, you can change
-the options `mh-max-inline-image-width' and
-`mh-max-inline-image-height' from their default value of zero to
-a large number. The size of your screen is a good choice for
-these numbers."
- :type '(choice (const nil) integer)
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-mhl-format-file nil
- "Specifies the format file to pass to the \"mhl\" program.
-
-Normally MH-E takes care of displaying messages itself (rather than
-calling an MH program to do the work). If you'd rather have \"mhl\"
-display the message (within MH-E), change this option from its default
-value of \"Use Default mhl Format (Printing Only)\".
-
-You can set this option to \"Use Default mhl Format\" to get the same
-output as you would get if you ran \"mhl\" from the shell.
-
-If you have a format file that you want MH-E to use, you can set this
-option to \"Specify an mhl Format File\" and enter the name of your
-format file. Your format file should specify a non-zero value for
-\"overflowoffset\" to allow MH-E to parse the header. Note that
-\"mhl\" is always used for printing and forwarding; in this case, the
-value of this option is consulted if you have specified a format
-file."
- :type '(choice (const :tag "Use Default mhl Format (Printing Only)" nil)
- (const :tag "Use Default mhl Format" t)
- (file :tag "Specify an mhl Format File"))
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-mime-save-parts-default-directory t
- "Default directory to use for \\<mh-folder-mode-map>\\[mh-mime-save-parts].
-
-The default value for this option is \"Prompt Always\" so that
-you are always prompted for the directory in which to save the
-attachments. However, if you usually use the same directory
-within a session, then you can set this option to \"Prompt the
-First Time\" to avoid the prompt each time. you can make this
-directory permanent by choosing \"Directory\" and entering the
-directory's name."
- :type '(choice (const :tag "Prompt the First Time" nil)
- (const :tag "Prompt Always" t)
- directory)
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-print-background-flag nil
- "Non-nil means messages should be printed in the background\\<mh-folder-mode-map>.
-
-Normally messages are printed in the foreground. If this is slow on
-your system, you may elect to turn off this option to print in the
-background.
-
-WARNING: If you do this, do not delete the message until it is printed
-or else the output may be truncated.
-
-This option is not used by the commands \\[mh-ps-print-msg] or
-\\[mh-ps-print-msg-file]."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-show-maximum-size 0
- "Maximum size of message (in bytes) to display automatically.
-
-This option provides an opportunity to skip over large messages
-which may be slow to load. The default value of 0 means that all
-message are shown regardless of size."
- :type 'integer
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-show-use-xface-flag (>= emacs-major-version 21)
- "Non-nil means display face images in MH-show buffers.
-
-MH-E can display the content of \"Face:\", \"X-Face:\", and
-\"X-Image-URL:\" header fields. If any of these fields occur in the
-header of your message, the sender's face will appear in the \"From:\"
-header field. If more than one of these fields appear, then the first
-field found in the order \"Face:\", \"X-Face:\", and \"X-Image-URL:\"
-will be used.
-
-The option `mh-show-use-xface-flag' is used to turn this feature on
-and off. This feature will be turned on by default if your system
-supports it.
-
-The first header field used, if present, is the Gnus-specific
-\"Face:\" field. The \"Face:\" field appeared in Emacs 21.
-For more information, see URL
-`https://quimby.gnus.org/circus/face/'. Next is the traditional
-\"X-Face:\" header field. The display of this field requires the
-\"uncompface\" program (see URL
-`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z').
-
-Finally, MH-E will display images referenced by the \"X-Image-URL:\"
-header field if neither the \"Face:\" nor the \"X-Face:\" fields are
-present. The display of the images requires \"wget\" (see URL
-`https://www.gnu.org/software/wget/wget.html'), \"fetch\", or \"curl\"
-to fetch the image and the \"convert\" program from the ImageMagick
-suite (see URL `https://www.imagemagick.org/'). Of the three header
-fields this is the most efficient in terms of network usage since the
-image doesn't need to be transmitted with every single mail.
-
-The option `mh-fetch-x-image-url' controls the fetching of the
-\"X-Image-URL:\" header field image."
- :type 'boolean
- :group 'mh-show
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-store-default-directory nil
- "Default directory for \\<mh-folder-mode-map>\\[mh-store-msg].
-
-If you would like to change the initial default directory,
-customize this option, change the value from \"Current\" to
-\"Directory\", and then enter the name of the directory for storing
-the content of these messages."
- :type '(choice (const :tag "Current" nil)
- directory)
- :group 'mh-show
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-summary-height nil
- "Number of lines in MH-Folder buffer (including the mode line).
-
-The default value of this option is \"Automatic\" which means
-that the MH-Folder buffer will maintain the same proportional
-size if the frame is resized. If you'd prefer a fixed height,
-then choose the \"Fixed Size\" option and enter the number of
-lines you'd like to see."
- :type '(choice (const :tag "Automatic" nil)
- (integer :tag "Fixed Size"))
- :group 'mh-show
- :package-version '(MH-E . "7.4"))
-
-;;; The Speedbar (:group 'mh-speedbar)
-
-(defcustom mh-speed-update-interval 60
- "Time between speedbar updates in seconds.
-Set to 0 to disable automatic update."
- :type 'integer
- :group 'mh-speedbar
- :package-version '(MH-E . "8.0"))
-
-;;; Threading (:group 'mh-thread)
-
-(defcustom mh-show-threads-flag nil
- "Non-nil means new folders start in threaded mode.
-
-Threading large number of messages can be time consuming so this
-option is turned off by default. If you turn this option on, then
-threading will be done only if the number of messages being
-threaded is less than `mh-large-folder'."
- :type 'boolean
- :group 'mh-thread
- :package-version '(MH-E . "7.1"))
-
-;;; The Tool Bar (:group 'mh-tool-bar)
-
-;; mh-tool-bar-folder-buttons and mh-tool-bar-letter-buttons defined
-;; dynamically in mh-tool-bar.el.
-
-(defcustom mh-tool-bar-search-function 'mh-search
- "Function called by the tool bar search button.
-
-By default, this is set to `mh-search'. You can also choose
-\"Other Function\" from the \"Value Menu\" and enter a function
-of your own choosing."
- :type '(choice (const mh-search)
- (function :tag "Other Function"))
- :group 'mh-tool-bar
- :package-version '(MH-E . "7.0"))
-
-\f
-
-;;; Hooks (:group 'mh-hooks + group where hook described)
-
-(defcustom mh-after-commands-processed-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] after performing outstanding refile and delete requests.
-
-Variables that are useful in this hook include
-`mh-folders-changed', which lists which folders were affected by
-deletes and refiles. This list will always include the current
-folder, which is also available in `mh-current-folder'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-alias-reloaded-hook nil
- "Hook run by `mh-alias-reload' after loading aliases."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-alias
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-annotate-msg-hook nil
- "Hook run when a message is sent and after annotating the scan lines and message.
-Hook functions can access the current folder name with
-`mh-current-folder' and obtain the message numbers of the
-annotated messages with `mh-annotate-list'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-sending-mail
- :package-version '(MH-E . "8.1"))
-
-(defcustom mh-before-commands-processed-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] before performing outstanding refile and delete requests.
-
-Variables that are useful in this hook include `mh-delete-list',
-`mh-refile-list', `mh-blocklist', and `mh-allowlist' which can be
-used to see which changes will be made to the current folder,
-`mh-current-folder'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-before-quit-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-quit] before quitting MH-E.
-
-This hook is called before the quit occurs, so you might use it
-to perform any MH-E operations; you could perform some query and
-abort the quit or call `mh-execute-commands', for example.
-
-See also `mh-quit-hook'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-before-send-letter-hook nil
- "Hook run at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command.
-
-For example, if you want to check your spelling in your message
-before sending, add the `ispell-message' function."
- :type 'hook
- :options '(ispell-message)
- :group 'mh-hooks
- :group 'mh-letter
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-blocklist-msg-hook nil
- "Hook run by \\<mh-letter-mode-map>\\[mh-junk-blocklist] after marking each message for blocklisting."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-show
- :package-version '(MH-E . "8.4"))
-
-(defcustom mh-delete-msg-hook nil
- "Hook run by \\<mh-letter-mode-map>\\[mh-delete-msg] after marking each message for deletion.
-
-For example, a past maintainer of MH-E used this once when he
-kept statistics on his mail usage."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-show
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-find-path-hook nil
- "Hook run by `mh-find-path' after reading the user's MH profile.
-
-This hook can be used the change the value of the variables that
-`mh-find-path' sets if you need to run with different values
-between MH and MH-E."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-e
- :package-version '(MH-E . "7.0"))
-
-(defcustom mh-folder-mode-hook nil
- "Hook run by `mh-folder-mode' when visiting a new folder."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-forward-hook nil
- "Hook run by `mh-forward' on a forwarded letter."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-sending-mail
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-inc-folder-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-inc-folder] after incorporating mail into a folder."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-inc
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-insert-signature-hook nil
- "Hook run by \\<mh-letter-mode-map>\\[mh-insert-signature] after signature has been inserted.
-
-Hook functions may access the actual name of the file or the
-function used to insert the signature with
-`mh-signature-file-name'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-letter
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-kill-folder-suppress-prompt-functions '(mh-search-p)
- "Abnormal hook run at the beginning of \\<mh-folder-mode-map>\\[mh-kill-folder].
-
-The hook functions are called with no arguments and should return
-a non-nil value to suppress the normal prompt when you remove a
-folder. This is useful for folders that are easily regenerated.
-
-The default value of `mh-search-p' suppresses the prompt on
-folders generated by searching.
-
-WARNING: Use this hook with care. If there is a bug in your hook
-which returns t on \"+inbox\" and you hit \\[mh-kill-folder] by
-accident in the \"+inbox\" folder, you will not be happy."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "7.4"))
-
-(defcustom mh-letter-mode-hook nil
- "Hook run by `mh-letter-mode' on a new letter.
-
-This hook allows you to do some processing before editing a
-letter. For example, you may wish to modify the header after
-\"repl\" has done its work, or you may have a complicated
-\"components\" file and need to tell MH-E where the cursor should
-go."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-sending-mail
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-mh-to-mime-hook nil
- "Hook run on the formatted letter by \\<mh-letter-mode-map>\\[mh-mh-to-mime]."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-letter
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-search-mode-hook nil
- "Hook run upon entry to `mh-search-mode'\\<mh-folder-mode-map>.
-
-If you find that you do the same thing over and over when editing
-the search template, you may wish to bind some shortcuts to keys.
-This can be done with this hook which is called when
-\\[mh-search] is run on a new pattern."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-search
- :package-version '(MH-E . "8.0"))
-
-(defcustom mh-pack-folder-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-pack-folder] after renumbering the messages.
-Hook functions can access the current folder name with `mh-current-folder'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "8.2"))
-
-(defcustom mh-quit-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-quit] after quitting MH-E.
-
-This hook is not run in an MH-E context, so you might use it to
-modify the window setup.
-
-See also `mh-before-quit-hook'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-refile-msg-hook nil
- "Hook run by \\<mh-folder-mode-map>\\[mh-refile-msg] after marking each message for refiling."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-folder
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-show-hook nil
- "Hook run after \\<mh-folder-mode-map>\\[mh-show] shows a message.
-
-It is the last thing called after messages are displayed. It's
-used to affect the behavior of MH-E in general or when
-`mh-show-mode-hook' is too early. See `mh-show-mode-hook'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-show
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-show-mode-hook nil
- "Hook run upon entry to `mh-show-mode'.
-
-This hook is called early on in the process of the message display,
-before the message contents have been inserted into the buffer.
-It is usually used to perform some action on the
-buffer itself. See also `mh-show-hook'."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-show
- :package-version '(MH-E . "8.7"))
-
-(defcustom mh-unseen-updated-hook nil
- "Hook run after the unseen sequence has been updated.
-
-The variable `mh-seen-list' can be used by this hook to obtain
-the list of messages which were removed from the unseen
-sequence."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-sequences
- :package-version '(MH-E . "6.0"))
-
-(defcustom mh-allowlist-msg-hook nil
- "Hook run by \\<mh-letter-mode-map>\\[mh-junk-allowlist] after marking each message for allowlisting."
- :type 'hook
- :group 'mh-hooks
- :group 'mh-show
- :package-version '(MH-E . "8.4"))
-
-\f
-
-;;; Faces (:group 'mh-faces + group where faces described)
-
-;; To add a new face:
-;; 1. Add entry to variable mh-face-data.
-;; 2. Create face using defface, accessing face data with function
-;; mh-face-data.
-;; 3. Add inherit argument to function mh-face-data if applicable.
-(defvar mh-face-data
- '((mh-folder-followup
- ((((class color) (background light))
- (:foreground "blue3"))
- (((class color) (background dark))
- (:foreground "LightGoldenRod"))
- (t
- (:bold t))))
- (mh-folder-msg-number
- ((((class color) (min-colors 64) (background light))
- (:foreground "snow4"))
- (((class color) (min-colors 64) (background dark))
- (:foreground "snow3"))
- (((class color) (background light))
- (:foreground "purple"))
- (((class color) (background dark))
- (:foreground "cyan"))))
- (mh-folder-refiled
- ((((class color) (min-colors 64) (background light))
- (:foreground "DarkGoldenrod"))
- (((class color) (min-colors 64) (background dark))
- (:foreground "LightGoldenrod"))
- (((class color))
- (:foreground "yellow" :weight light))
- (((class grayscale) (background light))
- (:foreground "Gray90" :bold t :italic t))
- (((class grayscale) (background dark))
- (:foreground "DimGray" :bold t :italic t))
- (t
- (:bold t :italic t))))
- (mh-folder-subject
- ((((class color) (background light))
- (:foreground "blue4"))
- (((class color) (background dark))
- (:foreground "yellow"))
- (t
- (:bold t))))
- (mh-folder-tick
- ((((class color) (background light))
- (:background "#dddf7e"))
- (((class color) (background dark))
- (:background "#dddf7e"))
- (t
- (:underline t))))
- (mh-folder-to
- ((((class color) (min-colors 64) (background light))
- (:foreground "RosyBrown"))
- (((class color) (min-colors 64) (background dark))
- (:foreground "LightSalmon"))
- (((class color))
- (:foreground "green"))
- (((class grayscale) (background light))
- (:foreground "DimGray" :italic t))
- (((class grayscale) (background dark))
- (:foreground "LightGray" :italic t))
- (t
- (:italic t))))
- (mh-letter-header-field
- ((((class color) (background light))
- (:background "gray90"))
- (((class color) (background dark))
- (:background "gray10"))
- (t
- (:bold t))))
- (mh-search-folder
- ((((class color) (background light))
- (:foreground "dark green" :bold t))
- (((class color) (background dark))
- (:foreground "indian red" :bold t))
- (t
- (:bold t))))
- (mh-show-cc
- ((((class color) (min-colors 64) (background light))
- (:foreground "DarkGoldenrod"))
- (((class color) (min-colors 64) (background dark))
- (:foreground "LightGoldenrod"))
- (((class color))
- (:foreground "yellow" :weight light))
- (((class grayscale) (background light))
- (:foreground "Gray90" :bold t :italic t))
- (((class grayscale) (background dark))
- (:foreground "DimGray" :bold t :italic t))
- (t
- (:bold t :italic t))))
- (mh-show-date
- ((((class color) (min-colors 64) (background light))
- (:foreground "ForestGreen"))
- (((class color) (min-colors 64) (background dark))
- (:foreground "PaleGreen"))
- (((class color))
- (:foreground "green"))
- (((class grayscale) (background light))
- (:foreground "Gray90" :bold t))
- (((class grayscale) (background dark))
- (:foreground "DimGray" :bold t))
- (t
- (:bold t :underline t))))
- (mh-show-from
- ((((class color) (background light))
- (:foreground "red3"))
- (((class color) (background dark))
- (:foreground "cyan"))
- (t
- (:bold t))))
- (mh-show-header
- ((((class color) (min-colors 64) (background light))
- (:foreground "RosyBrown"))
- (((class color) (min-colors 64) (background dark))
- (:foreground "LightSalmon"))
- (((class color))
- (:foreground "green"))
- (((class grayscale) (background light))
- (:foreground "DimGray" :italic t))
- (((class grayscale) (background dark))
- (:foreground "LightGray" :italic t))
- (t
- (:italic t))))
- (mh-show-pgg-bad ((t (:bold t :foreground "DeepPink1"))))
- (mh-show-pgg-good ((t (:bold t :foreground "LimeGreen"))))
- (mh-show-pgg-unknown ((t (:bold t :foreground "DarkGoldenrod2"))))
- (mh-show-signature ((t (:italic t))))
- (mh-show-to
- ((((class color) (background light))
- (:foreground "SaddleBrown"))
- (((class color) (background dark))
- (:foreground "burlywood"))
- (((class grayscale) (background light))
- (:foreground "DimGray" :underline t))
- (((class grayscale) (background dark))
- (:foreground "LightGray" :underline t))
- (t (:underline t))))
- (mh-speedbar-folder
- ((((class color) (background light))
- (:foreground "blue4"))
- (((class color) (background dark))
- (:foreground "light blue"))))
- (mh-speedbar-selected-folder
- ((((class color) (background light))
- (:foreground "red1" :underline t))
- (((class color) (background dark))
- (:foreground "red1" :underline t))
- (t
- (:underline t)))))
- "MH-E face data.
-Used by function `mh-face-data' which returns spec that is
-consumed by `defface'.")
-
-(require 'cus-face)
-
-(defvar mh-inherit-face-flag t
- "Non-nil means that the `defface' :inherit keyword is available.")
-(make-obsolete-variable 'mh-inherit-face-flag nil "29.1")
-
-(defvar mh-min-colors-defined-flag t
- "Non-nil means `defface' supports min-colors display requirement.")
-(make-obsolete-variable 'mh-min-colors-defined-flag nil "29.1")
-
-(defun mh-face-data (face &optional inherit)
- "Return spec for FACE.
-See `defface' for the spec definition.
-
-If INHERIT is non-nil and `defface' supports the :inherit
-keyword, return INHERIT literally; otherwise, return spec for
-FACE from the variable `mh-face-data'. This isn't a perfect
-implementation. In the case that the :inherit keyword is not
-supported, any additional attributes in the inherit parameter are
-not added to the returned spec."
- (or inherit
- (cadr (assq face mh-face-data))
- (error "Could not find %s in mh-face-data" face)))
-
-(defface mh-folder-address
- (mh-face-data 'mh-folder-subject '((t (:inherit mh-folder-subject))))
- "Recipient face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-blocklisted
- (mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-msg-number))))
- "Blocklisted message face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.4"))
-
-(defface mh-folder-body
- (mh-face-data 'mh-folder-msg-number
- '((((class color))
- (:inherit mh-folder-msg-number))
- (t
- (:inherit mh-folder-msg-number :italic t))))
- "Body text face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-cur-msg-number
- (mh-face-data 'mh-folder-msg-number
- '((t (:inherit mh-folder-msg-number :bold t))))
- "Current message number face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-date
- (mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-msg-number))))
- "Date face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-deleted
- (mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-msg-number))))
- "Deleted message face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-followup (mh-face-data 'mh-folder-followup)
- "\"Re:\" face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-msg-number (mh-face-data 'mh-folder-msg-number)
- "Message number face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-refiled (mh-face-data 'mh-folder-refiled)
- "Refiled message face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-sent-to-me-hint
- (mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-date))))
- "Fontification hint face in messages sent directly to us.
-The detection of messages sent to us is governed by the scan
-format `mh-scan-format-nmh' and the regular expression
-`mh-scan-sent-to-me-sender-regexp'."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-sent-to-me-sender
- (mh-face-data 'mh-folder-followup '((t (:inherit mh-folder-followup))))
- "Sender face in messages sent directly to us.
-The detection of messages sent to us is governed by the scan
-format `mh-scan-format-nmh' and the regular expression
-`mh-scan-sent-to-me-sender-regexp'."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-subject (mh-face-data 'mh-folder-subject)
- "Subject face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-tick (mh-face-data 'mh-folder-tick)
- "Ticked message face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-to (mh-face-data 'mh-folder-to)
- "\"To:\" face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.0"))
-
-(defface mh-folder-allowlisted
- (mh-face-data 'mh-folder-refiled '((t (:inherit mh-folder-refiled))))
- "Allowlisted message face."
- :group 'mh-faces
- :group 'mh-folder
- :package-version '(MH-E . "8.4"))
-
-(defface mh-letter-header-field (mh-face-data 'mh-letter-header-field)
- "Editable header field value face in draft buffers."
- :group 'mh-faces
- :group 'mh-letter
- :package-version '(MH-E . "8.0"))
-
-(defface mh-search-folder (mh-face-data 'mh-search-folder)
- "Folder heading face in MH-Folder buffers created by searches."
- :group 'mh-faces
- :group 'mh-search
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-cc (mh-face-data 'mh-show-cc)
- "Face used to highlight \"cc:\" header fields."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-date (mh-face-data 'mh-show-date)
- "Face used to highlight \"Date:\" header fields."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-from (mh-face-data 'mh-show-from)
- "Face used to highlight \"From:\" header fields."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-header (mh-face-data 'mh-show-header)
- "Face used to deemphasize less interesting header fields."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-pgg-bad (mh-face-data 'mh-show-pgg-bad)
- "Bad PGG signature face."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-pgg-good (mh-face-data 'mh-show-pgg-good)
- "Good PGG signature face."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-pgg-unknown (mh-face-data 'mh-show-pgg-unknown)
- "Unknown or untrusted PGG signature face."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-signature (mh-face-data 'mh-show-signature)
- "Signature face."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-subject
- (mh-face-data 'mh-folder-subject '((t (:inherit mh-folder-subject))))
- "Face used to highlight \"Subject:\" header fields."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-to (mh-face-data 'mh-show-to)
- "Face used to highlight \"To:\" header fields."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-show-xface
- (mh-face-data 'mh-show-from '((t (:inherit (mh-show-from highlight)))))
-"X-Face image face.
-The background and foreground are used in the image."
- :group 'mh-faces
- :group 'mh-show
- :package-version '(MH-E . "8.0"))
-
-(defface mh-speedbar-folder (mh-face-data 'mh-speedbar-folder)
- "Basic folder face."
- :group 'mh-faces
- :group 'mh-speedbar
- :package-version '(MH-E . "8.0"))
-
-(defface mh-speedbar-folder-with-unseen-messages
- (mh-face-data 'mh-speedbar-folder
- '((t (:inherit mh-speedbar-folder :bold t))))
- "Folder face when folder contains unread messages."
- :group 'mh-faces
- :group 'mh-speedbar
- :package-version '(MH-E . "8.0"))
-
-(defface mh-speedbar-selected-folder
- (mh-face-data 'mh-speedbar-selected-folder)
- "Selected folder face."
- :group 'mh-faces
- :group 'mh-speedbar
- :package-version '(MH-E . "8.0"))
-
-(defface mh-speedbar-selected-folder-with-unseen-messages
- (mh-face-data 'mh-speedbar-selected-folder
- '((t (:inherit mh-speedbar-selected-folder :bold t))))
- "Selected folder face when folder contains unread messages."
- :group 'mh-faces
- :group 'mh-speedbar
- :package-version '(MH-E . "8.0"))
-
-(provide 'mh-e)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-e.el ends here
+++ /dev/null
-;;; mh-folder.el --- MH-Folder mode -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2003, 2005-2024 Free Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Mode for browsing folders
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-;; Dynamically-created functions not found in mh-loaddefs.el.
-(autoload 'mh-tool-bar-folder-buttons-init "mh-tool-bar")
-(autoload 'mh-tool-bar-init "mh-tool-bar")
-
-(require 'gnus-util)
-(autoload 'message-fetch-field "message")
-
-\f
-
-;;; MH-E Entry Points
-
-;;;###autoload
-(defun mh-rmail (&optional arg)
- "Incorporate new mail with MH.
-Scan an MH folder if ARG is non-nil.
-
-This function is an entry point to MH-E, the Emacs interface to
-the MH mail system."
- (interactive "P")
- (mh-find-path)
- (if arg
- (call-interactively 'mh-visit-folder)
- (unless (get-buffer mh-inbox)
- (mh-visit-folder mh-inbox (symbol-name mh-unseen-seq)))
- (mh-inc-folder)))
-
-;;;###autoload
-(defun mh-nmail (&optional arg)
- "Check for new mail in inbox folder.
-Scan an MH folder if ARG is non-nil.
-
-This function is an entry point to MH-E, the Emacs interface to
-the MH mail system."
- (interactive "P")
- (mh-find-path) ; init mh-inbox
- (if arg
- (call-interactively 'mh-visit-folder)
- (mh-visit-folder mh-inbox)))
-\f
-
-;;; Desktop Integration
-
-(add-to-list 'desktop-buffer-mode-handlers
- '(mh-folder-mode . mh-restore-desktop-buffer))
-
-(defun mh-restore-desktop-buffer (_file-name name _misc)
- "Restore an MH folder buffer specified in a desktop file.
-When desktop creates a buffer, FILE-NAME holds the
-file name to visit, NAME holds the desired buffer
-name, and MISC holds a list of miscellaneous info
-used by the `desktop-buffer-mode-handlers' functions."
- (mh-find-path)
- (mh-visit-folder name)
- (current-buffer))
-
-\f
-
-;;; Variables
-
-(defvar mh-folder-filename nil
- "Full path of directory for this folder.")
-
-(defvar mh-partial-folder-mode-line-annotation "select"
- "Annotation when displaying part of a folder.
-The string is displayed after the folder's name. nil for no
-annotation.")
-
-(defvar mh-last-destination nil
- "Destination of last refile or write command.")
-
-(defvar mh-last-destination-folder nil
- "Destination of last refile command.")
-
-(defvar mh-last-destination-write nil
- "Destination of last write command.")
-
-(defvar mh-first-msg-num nil
- "Number of first message in buffer.")
-
-(defvar mh-last-msg-num nil
- "Number of last msg in buffer.")
-
-(defvar mh-msg-count nil
- "Number of msgs in buffer.")
-
-\f
-
-;;; Sequence Menu
-
-(easy-menu-define
- mh-folder-sequence-menu mh-folder-mode-map "Menu for MH-E folder-sequence."
- '("Sequence"
- ["Add Message to Sequence..." mh-put-msg-in-seq (mh-get-msg-num nil)]
- ["List Sequences for Message" mh-msg-is-in-seq (mh-get-msg-num nil)]
- ["Delete Message from Sequence..." mh-delete-msg-from-seq
- (mh-get-msg-num nil)]
- ["List Sequences in Folder..." mh-list-sequences t]
- ["Delete Sequence..." mh-delete-seq t]
- ["Narrow to Sequence..." mh-narrow-to-seq t]
- ["Widen from Sequence" mh-widen mh-folder-view-stack]
- "--"
- ["Narrow to Subject Sequence" mh-narrow-to-subject t]
- ["Narrow to Tick Sequence" mh-narrow-to-tick
- (and mh-tick-seq (mh-seq-msgs (mh-find-seq mh-tick-seq)))]
- ["Delete Rest of Same Subject" mh-delete-subject t]
- ["Toggle Tick Mark" mh-toggle-tick t]
- "--"
- ["Push State Out to MH" mh-update-sequences t]))
-
-;;; Message Menu
-
-(easy-menu-define
- mh-folder-message-menu mh-folder-mode-map "Menu for MH-E folder-message."
- '("Message"
- ["Show Message" mh-show (mh-get-msg-num nil)]
- ["Show Message with Header" mh-header-display (mh-get-msg-num nil)]
- ["Show Message with Preferred Alternative"
- mh-show-preferred-alternative (mh-get-msg-num nil)]
- ["Next Message" mh-next-undeleted-msg t]
- ["Previous Message" mh-previous-undeleted-msg t]
- ["Go to First Message" mh-first-msg t]
- ["Go to Last Message" mh-last-msg t]
- ["Go to Message by Number..." mh-goto-msg t]
- ["Modify Message" mh-modify t]
- ["Refile Message" mh-refile-msg (mh-get-msg-num nil)]
- ["Delete Message" mh-delete-msg (mh-get-msg-num nil)]
- ["Undo Delete/Refile/Junk" mh-undo (mh-outstanding-commands-p)]
- ["Execute Delete/Refile" mh-execute-commands
- (mh-outstanding-commands-p)]
- "--"
- ["Compose a New Message" mh-send t]
- ["Reply to Message..." mh-reply (mh-get-msg-num nil)]
- ["Forward Message..." mh-forward (mh-get-msg-num nil)]
- ["Redistribute Message..." mh-redistribute (mh-get-msg-num nil)]
- ["Edit Message Again" mh-edit-again (mh-get-msg-num nil)]
- ["Re-edit a Bounced Message" mh-extract-rejected-mail t]
- "--"
- ["Copy Message to Folder..." mh-copy-msg (mh-get-msg-num nil)]
- ["Print Message" mh-print-msg (mh-get-msg-num nil)]
- ["Write Message to File..." mh-write-msg-to-file
- (mh-get-msg-num nil)]
- ["Pipe Message to Command..." mh-pipe-msg (mh-get-msg-num nil)]
- ["Unpack Uuencoded Message..." mh-store-msg (mh-get-msg-num nil)]
- ["Burst Digest Message" mh-burst-digest (mh-get-msg-num nil)]))
-
-;;; Folder Menu
-
-(easy-menu-define
- mh-folder-folder-menu mh-folder-mode-map "Menu for MH-E folder."
- '("Folder"
- ["Incorporate New Mail" mh-inc-folder t]
- ["Toggle Show/Folder" mh-toggle-showing t]
- ["Execute Delete/Refile" mh-execute-commands
- (mh-outstanding-commands-p)]
- ["Rescan Folder" mh-rescan-folder t]
- ["Thread Folder" mh-toggle-threads
- (not (memq 'unthread mh-view-ops))]
- ["Pack Folder" mh-pack-folder t]
- ["Sort Folder" mh-sort-folder t]
- "--"
- ["List Folders" mh-list-folders t]
- ["Visit a Folder..." mh-visit-folder t]
- ["View New Messages" mh-index-new-messages t]
- ["Search..." mh-search t]
- "--"
- ["Quit MH-E" mh-quit t]))
-
-\f
-
-;;; MH-Folder Keys
-
-(suppress-keymap mh-folder-mode-map)
-
-;; Use defalias to make sure the documented primary key bindings
-;; appear in menu lists.
-(defalias 'mh-alt-show #'mh-show)
-(defalias 'mh-alt-refile-msg #'mh-refile-msg)
-(defalias 'mh-alt-send #'mh-send)
-(defalias 'mh-alt-visit-folder #'mh-visit-folder)
-
-;; Save the "b" binding for a future `back'. Maybe?
-(define-keymap :keymap mh-folder-mode-map
- "SPC" #'mh-page-msg
- "!" #'mh-refile-or-write-again
- "'" #'mh-toggle-tick
- "," #'mh-header-display
- "." #'mh-alt-show
- ":" #'mh-show-preferred-alternative
- ";" #'mh-toggle-mh-decode-mime-flag
- ">" #'mh-write-msg-to-file
- "?" #'mh-help
- "E" #'mh-extract-rejected-mail
- "M" #'mh-modify
- "DEL" #'mh-previous-page
- "C-d" #'mh-delete-msg-no-motion
- "TAB" #'mh-index-next-folder
- "<backtab>" #'mh-index-previous-folder
- "C-M-i" #'mh-index-previous-folder
- "ESC <" #'mh-first-msg
- "ESC >" #'mh-last-msg
- "ESC d" #'mh-redistribute
- "RET" #'mh-show
- "^" #'mh-alt-refile-msg
- "c" #'mh-copy-msg
- "d" #'mh-delete-msg
- "e" #'mh-edit-again
- "f" #'mh-forward
- "g" #'mh-goto-msg
- "i" #'mh-inc-folder
- "k" #'mh-delete-subject-or-thread
- "m" #'mh-alt-send
- "n" #'mh-next-undeleted-msg
- "M-n" #'mh-next-unread-msg
- "o" #'mh-refile-msg
- "p" #'mh-previous-undeleted-msg
- "M-p" #'mh-previous-unread-msg
- "q" #'mh-quit
- "r" #'mh-reply
- "s" #'mh-send
- "t" #'mh-toggle-showing
- "u" #'mh-undo
- "v" #'mh-index-visit-folder
- "x" #'mh-execute-commands
- "|" #'mh-pipe-msg
-
- "F" (define-keymap :prefix 'mh-folder-map
- "?" #'mh-prefix-help
- "'" #'mh-index-ticked-messages
- "S" #'mh-sort-folder
- "c" #'mh-catchup
- "f" #'mh-alt-visit-folder
- "k" #'mh-kill-folder
- "l" #'mh-list-folders
- "n" #'mh-index-new-messages
- "o" #'mh-alt-visit-folder
- "p" #'mh-pack-folder
- "q" #'mh-index-sequenced-messages
- "r" #'mh-rescan-folder
- "s" #'mh-search
- "u" #'mh-undo-folder
- "v" #'mh-visit-folder)
-
- "I" mh-inc-spool-map
-
- "J" (define-keymap :prefix 'mh-junk-map
- "?" #'mh-prefix-help
- "a" #'mh-junk-allowlist
- "b" #'mh-junk-blocklist
- "w" #'mh-junk-whitelist)
-
- "P" (define-keymap :prefix 'mh-ps-print-map
- "?" #'mh-prefix-help
- "C" #'mh-ps-print-toggle-color
- "F" #'mh-ps-print-toggle-faces
- "f" #'mh-ps-print-msg-file
- "l" #'mh-print-msg
- "p" #'mh-ps-print-msg)
-
- "S" (define-keymap :prefix 'mh-sequence-map
- "'" #'mh-narrow-to-tick
- "?" #'mh-prefix-help
- "d" #'mh-delete-msg-from-seq
- "k" #'mh-delete-seq
- "l" #'mh-list-sequences
- "n" #'mh-narrow-to-seq
- "p" #'mh-put-msg-in-seq
- "s" #'mh-msg-is-in-seq
- "w" #'mh-widen)
-
- "T" (define-keymap :prefix 'mh-thread-map
- "?" #'mh-prefix-help
- "u" #'mh-thread-ancestor
- "p" #'mh-thread-previous-sibling
- "n" #'mh-thread-next-sibling
- "t" #'mh-toggle-threads
- "d" #'mh-thread-delete
- "o" #'mh-thread-refile)
-
- "/" (define-keymap :prefix 'mh-limit-map
- "'" #'mh-narrow-to-tick
- "?" #'mh-prefix-help
- "c" #'mh-narrow-to-cc
- "g" #'mh-narrow-to-range
- "m" #'mh-narrow-to-from
- "s" #'mh-narrow-to-subject
- "t" #'mh-narrow-to-to
- "w" #'mh-widen)
-
- "X" (define-keymap :prefix 'mh-extract-map
- "?" #'mh-prefix-help
- "s" #'mh-store-msg ;shar
- "u" #'mh-store-msg) ;uuencode
-
- "D" (define-keymap :prefix 'mh-digest-map
- "SPC" #'mh-page-digest
- "?" #'mh-prefix-help
- "DEL" #'mh-page-digest-backwards
- "b" #'mh-burst-digest)
-
- "K" (define-keymap :prefix 'mh-mime-map
- "?" #'mh-prefix-help
- "a" #'mh-mime-save-parts
- "e" #'mh-display-with-external-viewer
- "i" #'mh-folder-inline-mime-part
- "o" #'mh-folder-save-mime-part
- "t" #'mh-toggle-mime-buttons
- "v" #'mh-folder-toggle-mime-part
- "TAB" #'mh-next-button
- "<backtab>" #'mh-prev-button
- "C-M-i" #'mh-prev-button)
-
- "<mouse-2>" #'mh-show-mouse)
-
-;; "C-c /" prefix is used in mh-folder-mode by pgp.el and mailcrypt
-
-\f
-
-;;; MH-Folder Help Messages
-
-;; If you add a new prefix, add appropriate text to the nil key.
-
-;; In general, messages are grouped logically. Taking the main commands for
-;; example, the first line is "ways to view messages," the second line is
-;; "things you can do with messages", and the third is "composing" messages.
-
-;; When adding a new prefix, ensure that the help message contains "what" the
-;; prefix is for. For example, if the word "folder" were not present in the
-;; "F" entry, it would not be clear what these commands operated upon.
-(defvar mh-folder-mode-help-messages
- '((nil "[i]nc, [.]show, [,]show all, [n]ext, [p]revious,\n"
- "[d]elete, [o]refile, e[x]ecute,\n"
- "[s]end, [r]eply,\n"
- "[;]toggle MIME decoding.\n"
- "Prefix characters:\n [F]older, [S]equence, [J]unk, MIME [K]eys,"
- "\n [T]hread, [/]limit, e[X]tract, [D]igest, [I]nc spools.")
-
- (?F "[l]ist; [v]isit folder;\n"
- "[n]ew messages; [']ticked messages; [s]earch;\n"
- "[p]ack; [S]ort; [r]escan; [k]ill")
- (?P "[p]rint message to [f]ile; old-style [l]pr printing;\n"
- "Toggle printing of [C]olors, [F]aces")
- (?S "[p]ut message in sequence, [n]arrow, [']narrow to ticked, [w]iden,\n"
- "[s]equences, [l]ist,\n"
- "[d]elete message from sequence, [k]ill sequence")
- (?T "[t]oggle, [d]elete, [o]refile thread")
- (?/ "Limit to [c]c, ran[g]e, fro[m], [s]ubject, [t]o; [w]iden")
- (?X "un[s]har, [u]udecode message")
- (?D "[b]urst digest")
- (?K "[v]iew, [i]nline, with [e]xternal viewer; \n"
- "[o]utput/save MIME part; save [a]ll parts; \n"
- "[t]oggle buttons; [TAB] next; [SHIFT-TAB] previous")
- (?J "[b]locklist, [a]llowlist message"))
- "Key binding cheat sheet.
-See `mh-set-help'.")
-
-\f
-
-;;; MH-Folder Font Lock
-
-(defvar mh-folder-font-lock-keywords
- (list
- ;; Folders when displaying index buffer
- (list "^\\+.*"
- '(0 'mh-search-folder))
- ;; Marked for refile
- (list (concat mh-scan-refiled-msg-regexp ".*")
- '(0 'mh-folder-refiled))
- ;; Marked for deletion
- (list (concat mh-scan-deleted-msg-regexp ".*")
- '(0 'mh-folder-deleted))
- ;; Marked for blocklisting
- (list (concat mh-scan-blocklisted-msg-regexp ".*")
- '(0 'mh-folder-blocklisted))
- ;; Marked for allowlisting
- (list (concat mh-scan-allowlisted-msg-regexp ".*")
- '(0 'mh-folder-allowlisted))
- ;; After subject
- (list mh-scan-body-regexp
- '(1 'mh-folder-body nil t))
- ;; Subject
- '(mh-folder-font-lock-subject
- (1 'mh-folder-followup append t)
- (2 'mh-folder-subject append t))
- ;; Current message number
- (list mh-scan-cur-msg-number-regexp
- '(1 'mh-folder-cur-msg-number))
- ;; Message number
- (list mh-scan-good-msg-regexp
- '(1 'mh-folder-msg-number))
- ;; Date
- (list mh-scan-date-regexp
- '(1 'mh-folder-date))
- ;; Messages from me (To:)
- (list mh-scan-rcpt-regexp
- '(1 'mh-folder-to)
- '(2 'mh-folder-address))
- ;; Messages to me
- (list mh-scan-sent-to-me-sender-regexp
- '(1 'mh-folder-sent-to-me-hint)
- '(2 'mh-folder-sent-to-me-sender)))
- "Keywords (regular expressions) used to fontify the MH-Folder buffer.")
-
-(defun mh-folder-font-lock-subject (limit)
- "Return MH-E scan subject strings to font-lock between point and LIMIT."
- (if (not (re-search-forward mh-scan-subject-regexp limit t))
- nil
- (if (match-beginning 1)
- (set-match-data (list (match-beginning 1) (match-end 3)
- (match-beginning 1) (match-end 3) nil nil))
- (set-match-data (list (match-beginning 3) (match-end 3)
- nil nil (match-beginning 3) (match-end 3))))
- t))
-
-;; Fontify unseen messages in bold.
-
-(defmacro mh-generate-sequence-font-lock (seq prefix face)
- "Generate the appropriate code to fontify messages in SEQ.
-PREFIX is used to generate unique names for the variables and
-functions defined by the macro. So a different prefix should be
-provided for every invocation.
-FACE is the font-lock face used to display the matching scan lines."
- (let ((cache (intern (format "mh-folder-%s-seq-cache" prefix)))
- (func (intern (format "mh-folder-font-lock-%s" prefix))))
- `(progn
- (defvar ,cache nil
- "Internal cache variable used for font-lock in MH-E.
-Should only be non-nil through font-lock stepping, and nil once
-font-lock is done highlighting.")
- (make-variable-buffer-local ',cache)
-
- (defun ,func (limit)
- "Return unseen message lines to font-lock between point and LIMIT."
- (if (not ,cache) (setq ,cache (mh-seq-msgs (mh-find-seq ,seq))))
- (let ((cur-msg (mh-get-msg-num nil)))
- (cond ((not ,cache)
- nil)
- ((>= (point) limit) ;Presumably at end of buffer
- (setq ,cache nil)
- nil)
- ((member cur-msg ,cache)
- (let ((bpoint (progn (beginning-of-line)(point)))
- (epoint (progn (forward-line 1)(point))))
- (if (<= limit (point)) (setq ,cache nil))
- (set-match-data (list bpoint epoint bpoint epoint))
- t))
- (t
- ;; move forward one line at a time, checking each message
- (while (and (= 0 (forward-line 1))
- (> limit (point))
- (not (member (mh-get-msg-num nil) ,cache))))
- ;; Examine how we must have exited the loop...
- (let ((cur-msg (mh-get-msg-num nil)))
- (cond ((or (<= limit (point))
- (not (member cur-msg ,cache)))
- (setq ,cache nil)
- nil)
- ((member cur-msg ,cache)
- (let ((bpoint (progn (beginning-of-line) (point)))
- (epoint (progn (forward-line 1) (point))))
- (if (<= limit (point)) (setq ,cache nil))
- (set-match-data
- (list bpoint epoint bpoint epoint))
- t))))))))
-
- (setq mh-folder-font-lock-keywords
- (append mh-folder-font-lock-keywords
- (list (list ',func (list 1 '',face 'prepend t))))))))
-
-(mh-generate-sequence-font-lock mh-unseen-seq unseen bold)
-(mh-generate-sequence-font-lock mh-tick-seq tick mh-folder-tick)
-
-\f
-
-;;; MH-Folder Mode
-
-(defmacro mh-remove-xemacs-horizontal-scrollbar ()
- (declare (obsolete nil "29.1"))
- nil)
-
-;; Register mh-folder-mode as supporting which-function-mode...
-(require 'which-func)
-(when (and (boundp 'which-func-modes) (listp which-func-modes))
- (add-to-list 'which-func-modes 'mh-folder-mode))
-
-;; Ensure new buffers won't get this mode if default major-mode is nil.
-(put 'mh-folder-mode 'mode-class 'special)
-
-;; Autoload cookie needed by desktop.el
-;;;###autoload
-(define-derived-mode mh-folder-mode fundamental-mode "MH-Folder"
- "Major MH-E mode for \"editing\" an MH folder scan listing.
-\\<mh-folder-mode-map>
-You can show the message the cursor is pointing to, and step through
-the messages. Messages can be marked for deletion or refiling into
-another folder; these commands are executed all at once with a
-separate command.
-
-Options that control this mode can be changed with
-\\[customize-group]; specify the \"mh\" group. In particular, please
-see the `mh-scan-format-file' option if you wish to modify scan's
-format.
-
-When a folder is visited, the hook `mh-folder-mode-hook' is run.
-
-Ranges
-======
-Many commands that operate on individual messages, such as
-`mh-forward' or `mh-refile-msg' take a RANGE argument. This argument
-can be used in several ways.
-
-If you provide the prefix argument (\\[universal-argument]) to
-these commands, then you will be prompted for the message range.
-This can be any valid MH range which can include messages,
-sequences, and the abbreviations (described in the mh(1) man
-page):
-
-<num1>-<num2>
- Indicates all messages in the range <num1> to <num2>, inclusive.
- The range must be nonempty.
-
-<num>:N
-<num>:+N
-<num>:-N
- Up to N messages beginning with (or ending with) message num. Num
- may be any of the predefined symbols: first, prev, cur, next or
- last.
-
-first:N
-prev:N
-next:N
-last:N
- The first, previous, next or last messages, if they exist.
-
-all
- All of the messages.
-
-For example, a range that shows all of these things is `1 2 3
-5-10 last:5 unseen'.
-
-If the option `transient-mark-mode' is set to t and you set a
-region in the MH-Folder buffer, then the MH-E command will
-perform the operation on all messages in that region.
-
-\\{mh-folder-mode-map}"
- (unless mh-folder-tool-bar-map
- (mh-tool-bar-folder-buttons-init))
- (if (boundp 'tool-bar-map)
- (setq-local tool-bar-map mh-folder-tool-bar-map))
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(mh-folder-font-lock-keywords t))
- (make-local-variable 'desktop-save-buffer)
- (setq desktop-save-buffer t)
- (setq-local
- mh-colors-available-flag (display-color-p)
- ; Do we have colors available
- mh-current-folder (buffer-name) ; Name of folder, a string
- mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs
- mh-folder-filename ; e.g. "/usr/foobar/Mail/inbox/"
- (file-name-as-directory (mh-expand-file-name (buffer-name)))
- mh-display-buttons-for-inline-parts-flag
- mh-display-buttons-for-inline-parts-flag ; Allow for display of buttons to
- ; be toggled.
- mh-arrow-marker (make-marker) ; Marker where arrow is displayed
- overlay-arrow-position nil ; Allow for simultaneous display in
- overlay-arrow-string ">" ; different MH-E buffers.
- mh-showing-mode nil ; Show message also?
- mh-refile-list nil ; List of folder names in mh-seq-list
- mh-delete-list nil ; List of msgs nums to delete
- mh-blocklist nil ; List of messages to process as spam
- mh-allowlist nil ; List of messages to process as ham
- mh-seq-list nil ; Alist of (seq . msgs) nums
- mh-seen-list nil ; List of displayed messages
- mh-next-direction 'forward ; Direction to move to next message
- mh-view-ops () ; Stack that keeps track of the order
- ; in which narrowing/threading has been
- ; carried out.
- mh-folder-view-stack () ; Stack of previous views of the
- ; folder.
- mh-index-data nil ; If the folder was created by a call
- ; to mh-search, this contains info
- ; about the search results.
- mh-index-previous-search nil ; folder, indexer, search-regexp
- mh-index-msg-checksum-map nil ; msg -> checksum map
- mh-index-checksum-origin-map nil ; checksum -> ( orig-folder, orig-msg )
- mh-index-sequence-search-flag nil ; folder resulted from sequence search
- mh-first-msg-num nil ; Number of first msg in buffer
- mh-last-msg-num nil ; Number of last msg in buffer
- mh-msg-count nil ; Number of msgs in buffer
- mh-mode-line-annotation nil ; Indicates message range
- mh-sequence-notation-history (make-hash-table)
- ; Remember what is overwritten by
- ; mh-note-seq.
- imenu-create-index-function 'mh-index-create-imenu-index
- ; Setup imenu support
- mh-previous-window-config nil) ; Previous window configuration
- (setq truncate-lines t)
- (auto-save-mode -1)
- (setq buffer-offer-save t)
- (add-hook 'write-file-functions #'mh-execute-commands nil t)
- (make-local-variable 'revert-buffer-function)
- (make-local-variable 'hl-line-mode) ; avoid pollution
- (hl-line-mode 1)
- (setq revert-buffer-function #'mh-undo-folder)
- (add-to-list 'minor-mode-alist '(mh-showing-mode " Show"))
- (mh-inc-spool-make)
- (mh-set-help mh-folder-mode-help-messages))
-
-\f
-
-;;; MH-Folder Commands
-
-;; Alphabetical.
-;; See also mh-comp.el, mh-junk.el, mh-mime.el, mh-print.el,
-;; mh-search.el, and mh-seq.el.
-
-;;;###mh-autoload
-(defun mh-delete-msg (range)
- "Delete RANGE\\<mh-folder-mode-map>.
-
-To mark a message for deletion, use this command. A \"D\" is
-placed by the message in the scan window, and the next undeleted
-message is displayed. If the previous command had been
-\\[mh-previous-undeleted-msg], then the next message displayed is
-the first undeleted message previous to the message just deleted.
-Use \\[mh-next-undeleted-msg] to force subsequent
-\\[mh-delete-msg] commands to move forward to the next undeleted
-message after deleting the message under the cursor.
-
-The hook `mh-delete-msg-hook' is called after you mark a message
-for deletion. For example, a past maintainer of MH-E used this
-once when he kept statistics on his mail usage.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (interactive (list (mh-interactive-range "Delete")))
- (mh-delete-msg-no-motion range)
- (if (looking-at mh-scan-deleted-msg-regexp)
- (mh-next-msg)))
-
-;;;###mh-autoload
-(defun mh-delete-msg-no-motion (range)
- "Delete RANGE, don't move to next message.
-
-This command marks the RANGE for deletion but leaves the cursor
-at the current message in case you wish to perform other
-operations on the message.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (interactive (list (mh-interactive-range "Delete")))
- (mh-iterate-on-range () range
- (mh-delete-a-msg nil)))
-
-;;;###mh-autoload
-(defun mh-execute-commands ()
- "Perform outstanding operations\\<mh-folder-mode-map>.
-
-If you've marked messages to be refiled, deleted, blocklisted, or
-allowlisted and you want to go ahead and perform these operations
-on these messages, use this command. Many MH-E commands that may
-affect the numbering of the messages (such as
-\\[mh-rescan-folder] or \\[mh-pack-folder]) will ask if you want
-to perform these operations first and then either run this
-command for you or undo the pending operations.
-
-This function runs `mh-before-commands-processed-hook' before the
-commands are processed and `mh-after-commands-processed-hook'
-after the commands are processed."
- (interactive)
- (if mh-folder-view-stack (mh-widen t))
- (mh-process-commands mh-current-folder)
- (mh-set-scan-mode)
- (mh-goto-cur-msg) ; after mh-set-scan-mode for efficiency
- (mh-make-folder-mode-line)
- t) ; return t for write-file-functions
-
-;;;###mh-autoload
-(defun mh-first-msg ()
- "Display first message."
- (interactive)
- (goto-char (point-min))
- (while (and (not (eobp)) (not (looking-at mh-scan-valid-regexp)))
- (forward-line 1)))
-
-;;;###mh-autoload
-(defun mh-goto-msg (number &optional no-error-if-no-message dont-show)
- "Go to a message\\<mh-folder-mode-map>.
-
-You can enter the message NUMBER either before or after typing
-\\[mh-goto-msg]. In the latter case, Emacs prompts you.
-
-In a program, optional non-nil second argument NO-ERROR-IF-NO-MESSAGE
-means return nil instead of signaling an error if message does not
-exist; in this case, the cursor is positioned near where the message
-would have been. Non-nil third argument DONT-SHOW means not to show
-the message."
- (interactive "NGo to message: ")
- (setq number (prefix-numeric-value number))
- (let ((point (point))
- (return-value t))
- (goto-char (point-min))
- (unless (re-search-forward (format (mh-scan-msg-search-regexp) number)
- nil t)
- (goto-char point)
- (unless no-error-if-no-message
- (error "No message %d" number))
- (setq return-value nil))
- (beginning-of-line)
- (or dont-show (not return-value) (mh-maybe-show number))
- return-value))
-
-;;;###mh-autoload
-(defun mh-inc-folder (&optional file folder)
- "Incorporate new mail into a folder.
-
-You can incorporate mail from any file into the current folder by
-specifying a prefix argument; you'll be prompted for the name of
-the FILE to use as well as the destination FOLDER
-
-The hook `mh-inc-folder-hook' is run after incorporating new
-mail.
-
-Do not call this function from outside MH-E; use \\[mh-rmail]
-instead."
- (interactive (list (if current-prefix-arg
- (expand-file-name
- (read-file-name "inc mail from file: "
- mh-user-path)))
- (if current-prefix-arg
- (mh-prompt-for-folder "inc mail into" mh-inbox t))))
- (if (not folder)
- (setq folder mh-inbox))
- (let ((threading-needed-flag nil))
- (let ((config (current-window-configuration)))
- (when (and mh-show-buffer (get-buffer mh-show-buffer))
- (delete-windows-on mh-show-buffer))
- (cond ((not (get-buffer folder))
- (mh-make-folder folder)
- (setq threading-needed-flag mh-show-threads-flag)
- (setq mh-previous-window-config config))
- ((not (eq (current-buffer) (get-buffer folder)))
- (switch-to-buffer folder)
- (setq mh-previous-window-config config))))
- (mh-get-new-mail file)
- (when (and threading-needed-flag
- (save-excursion
- (goto-char (point-min))
- (or (null mh-large-folder)
- (not (equal (forward-line (1+ mh-large-folder)) 0))
- (and (message "Not threading since the number of messages exceeds `mh-large-folder'")
- nil))))
- (mh-toggle-threads))
- (beginning-of-line)
- (when (mh-outstanding-commands-p)
- (mh-notate-deleted-and-refiled))
- (if (and mh-showing-mode (looking-at mh-scan-valid-regexp)) (mh-show))
- (run-hooks 'mh-inc-folder-hook)))
-
-;;;###mh-autoload
-(defun mh-last-msg ()
- "Display last message."
- (interactive)
- (goto-char (point-max))
- (while (and (not (bobp)) (not (looking-at mh-scan-valid-regexp)))
- (forward-line -1))
- (mh-recenter nil))
-
-;;;###mh-autoload
-(defun mh-modify (&optional message)
- "Edit message.
-
-There are times when you need to edit a message. For example, you
-may need to fix a broken Content-Type header field. You can do
-this with this command. It displays the raw message in an
-editable buffer. When you are done editing, save and kill the
-buffer as you would any other.
-
-From a program, edit MESSAGE; nil means edit current message."
- (interactive)
- (let* ((message (or message (mh-get-msg-num t)))
- (msg-filename (mh-msg-filename message))
- edit-buffer)
- (when (not (file-exists-p msg-filename))
- (error "Message %d does not exist" message))
-
- ;; Invalidate the show buffer if it is showing the same message that is
- ;; to be edited.
- (when (and (buffer-live-p (get-buffer mh-show-buffer))
- (equal (with-current-buffer mh-show-buffer
- buffer-file-name)
- msg-filename))
- (mh-invalidate-show-buffer))
-
- ;; Edit message
- (find-file msg-filename)
- (setq edit-buffer (current-buffer))
-
- ;; Set buffer properties
- (mh-letter-mode)
- (use-local-map text-mode-map)
-
- ;; Just show the edit buffer...
- (delete-other-windows)
- (switch-to-buffer edit-buffer)))
-
-;;;###mh-autoload
-(defun mh-next-button (&optional backward-flag)
- "Go to the next button.
-
-If the end of the buffer is reached then the search wraps over to
-the start of the buffer.
-
-If an optional prefix argument BACKWARD-FLAG is given, the cursor
-will move to the previous button."
- (interactive (list current-prefix-arg))
- (unless mh-showing-mode
- (mh-show))
- (mh-in-show-buffer (mh-show-buffer)
- (mh-goto-next-button backward-flag)))
-
-;;;###mh-autoload
-(defun mh-next-undeleted-msg (&optional count wait-after-complaining-flag)
- "Display next message.
-
-This command can be given a prefix argument COUNT to specify how
-many unread messages to skip.
-
-In a program, pause for a second after printing message if we are
-at the last undeleted message and optional argument
-WAIT-AFTER-COMPLAINING-FLAG is non-nil."
- (interactive "p")
- (setq mh-next-direction 'forward)
- (forward-line 1)
- (cond ((re-search-forward mh-scan-good-msg-regexp nil t count)
- (beginning-of-line)
- (mh-maybe-show))
- (t (forward-line -1)
- (message "No more undeleted messages")
- (if wait-after-complaining-flag (sit-for 1)))))
-
-;;;###mh-autoload
-(defun mh-next-unread-msg (&optional count)
- "Display next unread message.
-
-This command can be given a prefix argument COUNT to specify how
-many unread messages to skip."
- (interactive "p")
- (unless (> count 0)
- (error "The function `mh-next-unread-msg' expects positive argument"))
- (setq count (1- count))
- (let ((unread-sequence (reverse (cdr (assoc mh-unseen-seq mh-seq-list))))
- (cur-msg (mh-get-msg-num nil)))
- (cond ((and (not cur-msg) (not (bobp))
- ;; If we are at the end of the buffer back up one line and go
- ;; to unread message after that.
- (progn
- (forward-line -1)
- (setq cur-msg (mh-get-msg-num nil)))
- nil))
- ((or (null unread-sequence) (not cur-msg))
- ;; No unread message or there aren't any messages in buffer...
- (message "No more unread messages"))
- ((progn
- ;; Skip messages
- (while (and unread-sequence (>= cur-msg (car unread-sequence)))
- (setq unread-sequence (cdr unread-sequence)))
- (while (> count 0)
- (setq unread-sequence (cdr unread-sequence))
- (setq count (1- count)))
- (not (car unread-sequence)))
- (message "No more unread messages"))
- (t (cl-loop for msg in unread-sequence
- when (mh-goto-msg msg t) return nil
- finally (message "No more unread messages"))))))
-
-;;;###mh-autoload
-(defun mh-page-msg (&optional lines)
- "Display next page in message.
-
-You can give this command a prefix argument that specifies the
-number of LINES to scroll. This command will also show the next
-undeleted message if it is used at the bottom of a message."
- (interactive "P")
- (if mh-showing-mode
- (if mh-page-to-next-msg-flag
- (if (equal mh-next-direction 'backward)
- (mh-previous-undeleted-msg)
- (mh-next-undeleted-msg))
- (if (mh-in-show-buffer (mh-show-buffer)
- (pos-visible-in-window-p (point-max)))
- (progn
- (message
- "End of message (Type %s to read %s undeleted message)"
- (single-key-description last-input-event)
- (if (equal mh-next-direction 'backward)
- "previous"
- "next"))
- (setq mh-page-to-next-msg-flag t))
- (scroll-other-window lines)))
- (mh-show)))
-
-;;;###mh-autoload
-(defun mh-prev-button ()
- "Go to the previous button.
-
-If the beginning of the buffer is reached then the search wraps
-over to the end of the buffer."
- (interactive)
- (mh-next-button t))
-
-;;;###mh-autoload
-(defun mh-previous-page (&optional lines)
- "Display next page in message.
-
-You can give this command a prefix argument that specifies the
-number of LINES to scroll."
- (interactive "P")
- (mh-in-show-buffer (mh-show-buffer)
- (scroll-down lines)))
-
-;;;###mh-autoload
-(defun mh-previous-undeleted-msg (&optional count wait-after-complaining-flag)
- "Display previous message.
-
-This command can be given a prefix argument COUNT to specify how
-many unread messages to skip.
-
-In a program, pause for a second after printing message if we are
-at the last undeleted message and optional argument
-WAIT-AFTER-COMPLAINING-FLAG is non-nil."
- (interactive "p")
- (setq mh-next-direction 'backward)
- (beginning-of-line)
- (cond ((re-search-backward mh-scan-good-msg-regexp nil t count)
- (mh-maybe-show))
- (t (message "No previous undeleted message")
- (if wait-after-complaining-flag (sit-for 1)))))
-
-;;;###mh-autoload
-(defun mh-previous-unread-msg (&optional count)
- "Display previous unread message.
-
-This command can be given a prefix argument COUNT to specify how
-many unread messages to skip."
- (interactive "p")
- (unless (> count 0)
- (error "The function `mh-previous-unread-msg' expects positive argument"))
- (setq count (1- count))
- (let ((unread-sequence (cdr (assoc mh-unseen-seq mh-seq-list)))
- (cur-msg (mh-get-msg-num nil)))
- (cond ((and (not cur-msg) (not (bobp))
- ;; If we are at the end of the buffer back up one line and go
- ;; to unread message after that.
- (progn
- (forward-line -1)
- (setq cur-msg (mh-get-msg-num nil)))
- nil))
- ((or (null unread-sequence) (not cur-msg))
- ;; No unread message or there aren't any messages in buffer...
- (message "No more unread messages"))
- ((progn
- ;; Skip count messages...
- (while (and unread-sequence (>= (car unread-sequence) cur-msg))
- (setq unread-sequence (cdr unread-sequence)))
- (while (> count 0)
- (setq unread-sequence (cdr unread-sequence))
- (setq count (1- count)))
- (not (car unread-sequence)))
- (message "No more unread messages"))
- (t (cl-loop for msg in unread-sequence
- when (mh-goto-msg msg t) return nil
- finally (message "No more unread messages"))))))
-
-;;;###mh-autoload
-(defun mh-quit ()
- "Quit the current MH-E folder.
-
-When you want to quit using MH-E and go back to editing, you can use
-this command. This buries the buffers of the current MH-E folder and
-restores the buffers that were present when you first ran
-\\[mh-rmail]. It also removes any MH-E working buffers whose name
-begins with \" *mh-\" or \"*MH-E \". You can later restore your MH-E
-session by selecting the \"+inbox\" buffer or by running \\[mh-rmail]
-again.
-
-The two hooks `mh-before-quit-hook' and `mh-quit-hook' are called by
-this function. The former one is called before the quit occurs, so you
-might use it to perform any MH-E operations; you could perform some
-query and abort the quit or call `mh-execute-commands', for example.
-The latter is not run in an MH-E context, so you might use it to
-modify the window setup."
- (interactive)
- (run-hooks 'mh-before-quit-hook)
- (let ((show-buffer (get-buffer mh-show-buffer)))
- (when show-buffer
- (kill-buffer show-buffer)))
- (mh-update-sequences)
- (mh-destroy-postponed-handles)
- (bury-buffer (current-buffer))
-
- ;; Delete all MH-E temporary and working buffers.
- (dolist (buffer (buffer-list))
- (when (or (string-match "^ \\*mh-" (buffer-name buffer))
- (string-match "^\\*MH-E " (buffer-name buffer)))
- (kill-buffer buffer)))
-
- (if mh-previous-window-config
- (set-window-configuration mh-previous-window-config))
- (run-hooks 'mh-quit-hook))
-
-;;;###mh-autoload
-(defun mh-refile-msg (range folder &optional dont-update-last-destination-flag)
- "Refile (output) RANGE into FOLDER.
-
-You are prompted for the folder name. Note that this command can also
-be used to create folders. If you specify a folder that does not
-exist, you will be prompted to create it.
-
-The hook `mh-refile-msg-hook' is called after a message is marked to
-be refiled.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is
-read in interactive use.
-
-In a program, the variables `mh-last-destination' and
-`mh-last-destination-folder' are not updated if
-DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil."
- (interactive (list (mh-interactive-range "Refile")
- (intern (mh-prompt-for-refile-folder))))
- (unless dont-update-last-destination-flag
- (setq mh-last-destination (cons 'refile folder)
- mh-last-destination-folder mh-last-destination))
- (mh-iterate-on-range () range
- (mh-refile-a-msg nil folder))
- (when (looking-at mh-scan-refiled-msg-regexp) (mh-next-msg)))
-
-;;;###mh-autoload
-(defun mh-refile-or-write-again (range &optional interactive-flag)
- "Repeat last output command.
-
-If you are refiling several messages into the same folder, you
-can use this command to repeat the last
-refile (\\[mh-refile-msg]) or write (\\[mh-write-msg-to-file]).
-You can use a range.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is
-read in interactive use.
-
-In a program, a non-nil INTERACTIVE-FLAG means that the function was
-called interactively."
- (interactive (list (mh-interactive-range "Redo") t))
- (if (null mh-last-destination)
- (error "No previous refile or write"))
- (cond ((eq (car mh-last-destination) 'refile)
- (mh-refile-msg range (cdr mh-last-destination))
- (message "Destination folder: %s" (cdr mh-last-destination)))
- (t
- (mh-iterate-on-range msg range
- (apply #'mh-write-msg-to-file msg (cdr mh-last-destination)))
- (mh-next-msg interactive-flag))))
-
-;;;###mh-autoload
-(defun mh-rescan-folder (&optional range dont-exec-pending)
- "Rescan folder\\<mh-folder-mode-map>.
-
-This command is useful to grab all messages in your \"+inbox\" after
-processing your new mail for the first time. If you don't want to
-rescan the entire folder, this command will accept a RANGE. Check the
-documentation of `mh-interactive-range' to see how RANGE is read in
-interactive use.
-
-This command will ask if you want to process refiles or deletes first
-and then either run \\[mh-execute-commands] for you or undo the
-pending refiles and deletes.
-
-In a program, the processing of outstanding commands is not performed
-if DONT-EXEC-PENDING is non-nil."
- (interactive (list (if current-prefix-arg
- (mh-read-range "Rescan" mh-current-folder t nil t
- mh-interpret-number-as-range-flag)
- nil)))
- (setq mh-next-direction 'forward)
- (let ((threaded-flag (memq 'unthread mh-view-ops))
- (msg-num (mh-get-msg-num nil)))
- (mh-scan-folder mh-current-folder (or range "all") dont-exec-pending)
- ;; If there isn't a cur sequence, mh-scan-folder goes to the first message.
- ;; Try to stay where we were.
- (if (null (car (mh-seq-to-msgs 'cur)))
- (mh-goto-msg msg-num t t))
- (cond (threaded-flag (mh-toggle-threads))
- (mh-index-data (mh-index-insert-folder-headers)))))
-
-(defun mh-show-mouse (event)
- "Move point to mouse EVENT and show message."
- (interactive "e")
- (mouse-set-point event)
- (mh-show))
-
-;;;###mh-autoload
-(defun mh-toggle-showing ()
- "Toggle between MH-Folder and MH-Folder Show modes.
-
-This command switches between MH-Folder mode and MH-Folder Show
-mode. MH-Folder mode turns off the associated show buffer so that
-you can perform operations on the messages quickly without
-reading them. This is an excellent way to prune out your junk
-mail or to refile a group of messages to another folder for later
-examination."
- (interactive)
- (if mh-showing-mode
- (mh-set-scan-mode)
- (mh-show)))
-
-;;;###mh-autoload
-(defun mh-undo (range)
- "Undo pending deletes or refiles in RANGE.
-
-If you've deleted a message or refiled it, but changed your mind,
-you can cancel the action before you've executed it. Use this
-command to undo a refile on or deletion of a single message. You
-can also undo refiles and deletes for messages that are found in
-a given RANGE.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (interactive (list (mh-interactive-range "Undo")))
- (cond ((numberp range)
- (let ((original-position (point)))
- (beginning-of-line)
- (while (not (or (looking-at mh-scan-refiled-msg-regexp)
- (looking-at mh-scan-deleted-msg-regexp)
- (looking-at mh-scan-blocklisted-msg-regexp)
- (looking-at mh-scan-allowlisted-msg-regexp)
- (and (eq mh-next-direction 'forward) (bobp))
- (and (eq mh-next-direction 'backward)
- (save-excursion (forward-line) (eobp)))))
- (forward-line (if (eq mh-next-direction 'forward) -1 1)))
- (if (or (looking-at mh-scan-refiled-msg-regexp)
- (looking-at mh-scan-deleted-msg-regexp)
- (looking-at mh-scan-blocklisted-msg-regexp)
- (looking-at mh-scan-allowlisted-msg-regexp))
- (progn
- (mh-undo-msg (mh-get-msg-num t))
- (mh-maybe-show))
- (goto-char original-position)
- (error "Nothing to undo"))))
- (t (mh-iterate-on-range () range
- (mh-undo-msg nil))))
- (if (not (mh-outstanding-commands-p))
- (mh-set-folder-modified-p nil)))
-
-;;;###mh-autoload
-(defun mh-visit-folder (folder &optional range index-data)
- "Visit FOLDER.
-
-When you want to read the messages that you have refiled into folders,
-use this command to visit the folder. You are prompted for the folder
-name.
-
-The folder buffer will show just unseen messages if there are any;
-otherwise, it will show all the messages in the buffer as long there
-are fewer than `mh-large-folder' messages. If there are more, then you
-are prompted for a range of messages to scan.
-
-You can provide a prefix argument in order to specify a RANGE of
-messages to show when you visit the folder. In this case, regions are
-not used to specify the range and `mh-large-folder' is ignored. Check
-the documentation of `mh-interactive-range' to see how RANGE is read
-in interactive use.
-
-Note that this command can also be used to create folders. If you
-specify a folder that does not exist, you will be prompted to create
-it.
-
-Do not call this function from outside MH-E; use \\[mh-rmail] instead.
-
-If, in a program, RANGE is nil (the default), then all messages in
-FOLDER are displayed. If an index buffer is being created then
-INDEX-DATA is used to initialize the index buffer specific data
-structures."
- (interactive (let ((folder-name (mh-prompt-for-folder "Visit" mh-inbox t)))
- (list folder-name
- (mh-read-range "Scan" folder-name t nil
- current-prefix-arg
- mh-interpret-number-as-range-flag))))
- (let ((config (current-window-configuration))
- (current-buffer (current-buffer))
- (threaded-view-flag mh-show-threads-flag))
- (delete-other-windows)
- (when (get-buffer folder)
- (with-current-buffer folder
- (setq threaded-view-flag (memq 'unthread mh-view-ops))))
- (when index-data
- (mh-make-folder folder)
- (setq mh-index-data (car index-data)
- mh-index-msg-checksum-map (make-hash-table :test #'equal)
- mh-index-checksum-origin-map (make-hash-table :test #'equal))
- (mh-index-update-maps folder (cadr index-data))
- (mh-index-create-sequences))
- (mh-scan-folder folder (or range "all"))
- (cond ((and threaded-view-flag
- (save-excursion
- (goto-char (point-min))
- (or (null mh-large-folder)
- (not (equal (forward-line (1+ mh-large-folder)) 0))
- (and (message "Not threading since the number of messages exceeds `mh-large-folder'")
- nil))))
- (mh-toggle-threads))
- (mh-index-data
- (mh-index-insert-folder-headers)))
- (unless (eq current-buffer (current-buffer))
- (setq mh-previous-window-config config)))
- nil)
-
-;;;###mh-autoload
-(defun mh-write-msg-to-file (message file no-header)
- "Append MESSAGE to end of FILE\\<mh-folder-mode-map>.
-
-You are prompted for the filename. If the file already exists,
-the message is appended to it. You can also write the message to
-the file without the header by specifying a prefix argument
-NO-HEADER. Subsequent writes to the same file can be made with
-the command \\[mh-refile-or-write-again]."
- (interactive
- (list (mh-get-msg-num t)
- (let ((default-dir (if (eq 'write (car mh-last-destination-write))
- (file-name-directory
- (car (cdr mh-last-destination-write)))
- default-directory)))
- (read-file-name (format "Save message%s in file: "
- (if current-prefix-arg " body" ""))
- default-dir
- (if (eq 'write (car mh-last-destination-write))
- (car (cdr mh-last-destination-write))
- (expand-file-name "mail.out" default-dir))))
- current-prefix-arg))
- (let ((msg-file-to-output (mh-msg-filename message))
- (output-file (mh-expand-file-name file)))
- (setq mh-last-destination (list 'write file (if no-header 'no-header))
- mh-last-destination-write mh-last-destination)
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (insert-file-contents msg-file-to-output)
- (goto-char (point-min))
- (if no-header (search-forward "\n\n"))
- (append-to-file (point) (point-max) output-file))))
-
-;;;###mh-autoload
-(defun mh-update-sequences ()
- "Flush MH-E's state out to MH.
-
-This function updates the sequence specified by your
-\"Unseen-Sequence:\" profile component, \"cur\", and the sequence
-listed by the `mh-tick-seq' option which is \"tick\" by default.
-The message at the cursor is used for \"cur\"."
- (interactive)
- ;; mh-update-sequences is the opposite of mh-read-folder-sequences,
- ;; which updates MH-E's state from MH.
- (let ((folder-set (mh-update-unseen))
- (new-cur (mh-get-msg-num nil)))
- (if new-cur
- (let ((seq-entry (mh-find-seq 'cur)))
- (mh-remove-cur-notation)
- (if seq-entry
- (setcdr seq-entry (list new-cur))
- (mh-add-msgs-to-seq (list new-cur) 'cur))
- (mh-define-sequence 'cur (list new-cur))
- (beginning-of-line)
- (if (looking-at mh-scan-good-msg-regexp)
- (mh-notate-cur)))
- (or folder-set
- (save-excursion
- ;; psg - mh-current-folder is nil if mh-summary-height < 4 !
- ;; So I added this sanity check.
- (if (stringp mh-current-folder)
- (mh-exec-cmd-quiet t "folder" mh-current-folder "-fast")
- (mh-exec-cmd-quiet t "folder" "-fast")))))))
-
-\f
-
-;;; Support Routines
-
-(defun mh-get-new-mail (maildrop-name)
- "Read new mail from MAILDROP-NAME into the current buffer.
-Return in the current buffer."
- (let ((point-before-inc (point))
- (folder mh-current-folder)
- (new-mail-flag nil))
- (with-mh-folder-updating (t)
- (if maildrop-name
- (message "inc %s -file %s..." folder maildrop-name)
- (message "inc %s..." folder))
- (setq mh-next-direction 'forward)
- (goto-char (point-max))
- (mh-remove-cur-notation)
- (let ((start-of-inc (point)))
- (if maildrop-name
- ;; I think MH 5 used "-ms-file" instead of "-file",
- ;; which would make inc'ing from maildrops fail.
- (mh-exec-cmd-output mh-inc-prog nil folder
- (mh-scan-format)
- "-file" (expand-file-name maildrop-name)
- "-width" (window-width)
- "-truncate")
- (mh-exec-cmd-output mh-inc-prog nil
- (mh-scan-format)
- "-width" (window-width)))
- (if maildrop-name
- (message "inc %s -file %s...done" folder maildrop-name)
- (message "inc %s...done" folder))
- (goto-char start-of-inc)
- (cond ((save-excursion
- (re-search-forward "^inc: no mail" nil t))
- (message "No new mail%s%s" (if maildrop-name " in " "")
- (if maildrop-name maildrop-name "")))
- ((and (when mh-folder-view-stack
- (let ((saved-text (buffer-substring-no-properties
- start-of-inc (point-max))))
- (delete-region start-of-inc (point-max))
- (unwind-protect (mh-widen t)
- (mh-remove-cur-notation)
- (goto-char (point-max))
- (setq start-of-inc (point))
- (insert saved-text)
- (goto-char start-of-inc))))
- nil))
- ((re-search-forward "^inc:" nil t) ; Error messages
- (error "Error incorporating mail"))
- ((and
- (equal mh-scan-format-file t)
- mh-adaptive-cmd-note-flag
- ;; Have we reached an edge condition?
- (save-excursion
- (re-search-forward mh-scan-msg-overflow-regexp nil 0 1))
- (setq start-of-inc (mh-generate-new-cmd-note folder))
- nil))
- (t
- (setq new-mail-flag t)))
- (keep-lines mh-scan-valid-regexp) ; Flush random scan lines
- (let* ((sequences (mh-read-folder-sequences folder t))
- (new-cur (assoc 'cur sequences))
- (new-unseen (assoc mh-unseen-seq sequences)))
- (unless (assoc 'cur mh-seq-list)
- (push (list 'cur) mh-seq-list))
- (unless (assoc mh-unseen-seq mh-seq-list)
- (push (list mh-unseen-seq) mh-seq-list))
- (setcdr (assoc 'cur mh-seq-list) (cdr new-cur))
- (setcdr (assoc mh-unseen-seq mh-seq-list) (cdr new-unseen)))
- (when (equal (point-max) start-of-inc)
- (mh-notate-cur))
- (if new-mail-flag
- (progn
- (mh-make-folder-mode-line)
- (when (mh-speed-flists-active-p)
- (mh-speed-flists t mh-current-folder))
- (when (memq 'unthread mh-view-ops)
- (mh-thread-inc folder start-of-inc))
- (mh-goto-cur-msg))
- (goto-char point-before-inc))
- (mh-notate-user-sequences (cons start-of-inc (point-max)))))))
-
-(defun mh-generate-new-cmd-note (folder)
- "Fix the `mh-cmd-note' value for this FOLDER.
-
-After doing an `mh-get-new-mail' operation in this FOLDER, at least
-one line that looks like a truncated message number was found.
-
-Remove the text added by the last `mh-inc' command. It should be the
-messages cur-last. Call `mh-set-cmd-note', adjusting the notation
-column with the width of the largest message number in FOLDER.
-
-Reformat the message number width on each line in the buffer and trim
-the line length to fit in the window.
-
-Rescan the FOLDER in the range cur-last in order to display the
-messages that were removed earlier. They should all fit in the scan
-line now with no message truncation."
- (save-excursion
- (let ((maxcol (1- (window-width)))
- (old-cmd-note mh-cmd-note)
- mh-cmd-note-fmt
- msgnum)
- ;; Nuke all of the lines just added by the last inc
- (delete-char (- (point-max) (point)))
- ;; Update the current buffer to reflect the new mh-cmd-note
- ;; value needed to display messages.
- (mh-set-cmd-note (mh-msg-num-width-to-column (mh-msg-num-width folder)))
- (setq mh-cmd-note-fmt (concat "%" (format "%d" mh-cmd-note) "d"))
- ;; Cleanup the messages that are in the buffer right now
- (goto-char (point-min))
- (cond ((memq 'unthread mh-view-ops)
- (mh-thread-add-spaces (- mh-cmd-note old-cmd-note)))
- (t (while (re-search-forward (mh-scan-msg-number-regexp) nil 0 1)
- ;; reformat the number to fix in mh-cmd-note columns
- (setq msgnum (string-to-number
- (buffer-substring
- (match-beginning 1) (match-end 1))))
- (replace-match (format mh-cmd-note-fmt msgnum))
- ;; trim the line to fix in the window
- (end-of-line)
- (let ((eol (point)))
- (move-to-column maxcol)
- (if (<= (point) eol)
- (delete-char (- eol (point))))))))
- ;; now re-read the lost messages
- (goto-char (point-max))
- (prog1 (point)
- (mh-regenerate-headers "cur-last" t)))))
-
-;;;###mh-autoload
-(defun mh-goto-cur-msg (&optional minimal-changes-flag)
- "Position the cursor at the current message.
-When optional argument MINIMAL-CHANGES-FLAG is non-nil, the
-function doesn't recenter the folder buffer."
- (let ((cur-msg (car (mh-seq-to-msgs 'cur))))
- (cond ((and cur-msg
- (mh-goto-msg cur-msg t t))
- (unless minimal-changes-flag
- (mh-notate-cur)
- (mh-recenter 0)
- (mh-maybe-show cur-msg)))
- (t
- (setq overlay-arrow-position nil)
- (message "No current message")))))
-
-;;;###mh-autoload
-(defun mh-recenter (arg)
- "Like recenter but with three improvements:
-
-- At the end of the buffer it tries to show fewer empty lines.
-
-- operates only if the current buffer is in the selected window.
- (Commands like `save-some-buffers' can make this false.)
-
-- nil ARG means recenter as if prefix argument had been given."
- (cond ((not (eq (get-buffer-window (current-buffer)) (selected-window)))
- nil)
- ((= (point-max) (save-excursion
- (forward-line (- (/ (window-height) 2) 2))
- (point)))
- (let ((lines-from-end 2))
- (save-excursion
- (while (> (point-max) (progn (forward-line) (point)))
- (cl-incf lines-from-end)))
- (recenter (- lines-from-end))))
- ;; '(4) is the same as C-u prefix argument.
- (t (recenter (or arg '(4))))))
-
-(defun mh-update-unseen ()
- "Synchronize the unseen sequence with MH.
-Return non-nil if the MH folder was set.
-The hook `mh-unseen-updated-hook' is called after the unseen sequence
-is updated."
- (if mh-seen-list
- (let* ((unseen-seq (mh-find-seq mh-unseen-seq))
- (unseen-msgs (mh-seq-msgs unseen-seq)))
- (if unseen-msgs
- (progn
- (mh-undefine-sequence mh-unseen-seq mh-seen-list)
- (run-hooks 'mh-unseen-updated-hook)
- (while mh-seen-list
- (setq unseen-msgs (delq (car mh-seen-list) unseen-msgs))
- (setq mh-seen-list (cdr mh-seen-list)))
- (setcdr unseen-seq unseen-msgs)
- t) ;since we set the folder
- (setq mh-seen-list nil)))))
-
-;;;###mh-autoload
-(defun mh-outstanding-commands-p ()
- "Return non-nil if there are outstanding deletes or refiles."
- (save-excursion
- (when (eq major-mode 'mh-show-mode)
- (set-buffer mh-show-folder-buffer))
- (or mh-delete-list mh-refile-list mh-blocklist mh-allowlist)))
-
-;;;###mh-autoload
-(defun mh-set-folder-modified-p (flag)
- "Mark current folder as modified or unmodified according to FLAG."
- (set-buffer-modified-p flag))
-
-(defun mh-process-commands (folder)
- "Process outstanding commands for FOLDER.
-
-This function runs `mh-before-commands-processed-hook' before the
-commands are processed and `mh-after-commands-processed-hook'
-after the commands are processed."
- (message "Processing deletes and refiles for %s..." folder)
- (set-buffer folder)
- (with-mh-folder-updating (nil)
- ;; Run the before hook -- the refile and delete lists are still valid
- (run-hooks 'mh-before-commands-processed-hook)
-
- ;; Update the unseen sequence if it exists
- (mh-update-unseen)
-
- (let ((redraw-needed-flag mh-index-data)
- (folders-changed (list mh-current-folder))
- (seq-map (and
- (or (and mh-refile-list mh-refile-preserves-sequences-flag)
- (and mh-allowlist
- mh-allowlist-preserves-sequences-flag))
- (mh-create-sequence-map mh-seq-list)))
- (dest-map (and mh-refile-list mh-refile-preserves-sequences-flag
- (make-hash-table)))
- (allow-map (and mh-allowlist mh-allowlist-preserves-sequences-flag
- (make-hash-table))))
- ;; Remove invalid scan lines if we are in an index folder and then remove
- ;; the real messages
- (when mh-index-data
- (mh-index-delete-folder-headers)
- (setq folders-changed
- (append folders-changed (mh-index-execute-commands))))
-
- ;; Then refile messages
- (mapc (lambda (folder-msg-list)
- (let* ((dest-folder (symbol-name (car folder-msg-list)))
- (last (car (mh-translate-range dest-folder "last")))
- (msgs (cdr folder-msg-list)))
- (push dest-folder folders-changed)
- (setq redraw-needed-flag t)
- (apply #'mh-exec-cmd
- "refile" "-src" folder dest-folder
- (mh-coalesce-msg-list msgs))
- (mh-delete-scan-msgs msgs)
- ;; Preserve sequences in destination folder...
- (when mh-refile-preserves-sequences-flag
- (clrhash dest-map)
- (cl-loop
- for i from (1+ (or last 0))
- for msg in (sort (copy-sequence msgs) #'<)
- do (cl-loop for seq-name in (gethash msg seq-map)
- do (push i (gethash seq-name dest-map))))
- (maphash
- #'(lambda (seq msgs)
- ;; Can't be run in the background, since the
- ;; current folder is changed by mark this could
- ;; lead to a race condition with the next refile.
- (apply #'mh-exec-cmd "mark"
- "-sequence" (symbol-name seq) dest-folder
- "-add" (mapcar #'(lambda (x) (format "%s" x))
- (mh-coalesce-msg-list msgs))))
- dest-map))))
- mh-refile-list)
- (setq mh-refile-list ())
-
- ;; Now delete messages
- (cond (mh-delete-list
- (setq redraw-needed-flag t)
- (apply #'mh-exec-cmd "rmm" folder
- (mh-coalesce-msg-list mh-delete-list))
- (mh-delete-scan-msgs mh-delete-list)
- (setq mh-delete-list nil)))
-
- ;; Blocklist messages.
- (when mh-blocklist
- (let ((msg-list (mh-coalesce-msg-list mh-blocklist))
- (dest (mh-junk-blocklist-disposition)))
- (mh-junk-process-blocklist mh-blocklist)
- ;; TODO I wonder why mh-exec-cmd is used instead of the following:
- ;; (mh-refile-a-msg nil (intern dest))
- ;; (mh-delete-a-msg nil)))
- (if (null dest)
- (apply #'mh-exec-cmd "rmm" folder msg-list)
- (apply #'mh-exec-cmd "refile" "-src" folder dest msg-list)
- (push dest folders-changed))
- (setq redraw-needed-flag t)
- (mh-delete-scan-msgs mh-blocklist)
- (setq mh-blocklist nil)))
-
- ;; Allowlist messages.
- (when mh-allowlist
- (let ((msg-list (mh-coalesce-msg-list mh-allowlist))
- (last (car (mh-translate-range mh-inbox "last"))))
- (mh-junk-process-allowlist mh-allowlist)
- (apply #'mh-exec-cmd "refile" "-src" folder mh-inbox msg-list)
- (push mh-inbox folders-changed)
- (setq redraw-needed-flag t)
- (mh-delete-scan-msgs mh-allowlist)
- (when mh-allowlist-preserves-sequences-flag
- (clrhash allow-map)
- (cl-loop for i from (1+ (or last 0))
- for msg in (sort (copy-sequence mh-allowlist) #'<)
- do (cl-loop for seq-name in (gethash msg seq-map)
- do (push i (gethash seq-name allow-map))))
- (maphash
- (lambda (seq msgs)
- ;; Can't be run in background, since the current
- ;; folder is changed by mark this could lead to a
- ;; race condition with the next refile/allowlist.
- (apply #'mh-exec-cmd "mark"
- "-sequence" (symbol-name seq) mh-inbox
- "-add" (mapcar #'(lambda(x) (format "%s" x))
- (mh-coalesce-msg-list msgs))))
- allow-map))
- (setq mh-allowlist nil)))
-
- ;; Don't need to remove sequences since delete and refile do so.
- ;; Mark cur message
- (if (> (buffer-size) 0)
- (mh-define-sequence 'cur (list (or (mh-get-msg-num nil) "last"))))
-
- ;; Redraw folder buffer if needed
- (when (and redraw-needed-flag)
- (when (mh-speed-flists-active-p)
- (apply #'mh-speed-flists t folders-changed))
- (cond ((memq 'unthread mh-view-ops) (mh-thread-inc folder (point-max)))
- (mh-index-data (mh-index-insert-folder-headers))))
-
- (and (buffer-file-name (get-buffer mh-show-buffer))
- (not (file-exists-p (buffer-file-name (get-buffer mh-show-buffer))))
- ;; If "inc" were to put a new msg in this file,
- ;; we would not notice, so mark it invalid now.
- (mh-invalidate-show-buffer))
-
- (setq mh-seq-list (mh-read-folder-sequences mh-current-folder nil))
- (mh-remove-all-notation)
- (mh-notate-user-sequences)
-
- ;; Run the after hook -- now folders-changed is valid,
- ;; but not the lists of specific messages.
- (let ((mh-folders-changed folders-changed))
- (run-hooks 'mh-after-commands-processed-hook)))
-
- (message "Processing deletes and refiles for %s...done" folder)))
-
-(defun mh-delete-scan-msgs (msgs)
- "Delete the scan listing lines for MSGS."
- (save-excursion
- (while msgs
- (when (mh-goto-msg (car msgs) t t)
- (when (memq 'unthread mh-view-ops)
- (mh-thread-forget-message (car msgs)))
- (mh-delete-line 1))
- (setq msgs (cdr msgs)))))
-
-(defun mh-set-scan-mode ()
- "Display the scan listing buffer, but do not show a message."
- (if (get-buffer mh-show-buffer)
- (delete-windows-on mh-show-buffer))
- (mh-showing-mode 0)
- (force-mode-line-update)
- (if mh-recenter-summary-flag
- (mh-recenter nil)))
-
-;;;###mh-autoload
-(defun mh-make-folder-mode-line (&optional _ignored)
- "Set the fields of the mode line for a folder buffer.
-The optional argument is now obsolete and IGNORED. It used to be
-used to pass in what is now stored in the buffer-local variable
-`mh-mode-line-annotation'."
- (save-excursion
- (save-window-excursion
- (mh-first-msg)
- (let ((new-first-msg-num (mh-get-msg-num nil)))
- (when (or (not (memq 'unthread mh-view-ops))
- (null mh-first-msg-num)
- (null new-first-msg-num)
- (< new-first-msg-num mh-first-msg-num))
- (setq mh-first-msg-num new-first-msg-num)))
- (mh-last-msg)
- (let ((new-last-msg-num (mh-get-msg-num nil)))
- (when (or (not (memq 'unthread mh-view-ops))
- (null mh-last-msg-num)
- (null new-last-msg-num)
- (> new-last-msg-num mh-last-msg-num))
- (setq mh-last-msg-num new-last-msg-num)))
- (setq mh-msg-count (if mh-first-msg-num
- (count-lines (point-min) (point-max))
- 0))
- (setq mode-line-buffer-identification
- (list (format " {%%b%s} %s msg%s"
- (if mh-mode-line-annotation
- (format "/%s" mh-mode-line-annotation)
- "")
- (if (zerop mh-msg-count)
- "no"
- (format "%d" mh-msg-count))
- (if (zerop mh-msg-count)
- "s"
- (cond ((> mh-msg-count 1)
- (format "s (%d-%d)" mh-first-msg-num
- mh-last-msg-num))
- (mh-first-msg-num
- (format " (%d)" mh-first-msg-num))
- (""))))))
- (mh-logo-display))))
-
-;;;###mh-autoload
-(defun mh-scan-folder (folder range &optional dont-exec-pending)
- "Scan FOLDER over RANGE.
-
-After the scan is performed, switch to the buffer associated with
-FOLDER.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is
-read in interactive use.
-
-The processing of outstanding commands is not performed if
-DONT-EXEC-PENDING is non-nil."
- (when (stringp range)
- (setq range (delete "" (split-string range "[ \t\n]"))))
- (cond ((null (get-buffer folder))
- (mh-make-folder folder))
- (t
- (unless dont-exec-pending
- (mh-process-or-undo-commands folder)
- (mh-reset-threads-and-narrowing))
- (switch-to-buffer folder)))
- (mh-regenerate-headers range)
- (if (zerop (buffer-size))
- (if (equal range "all")
- (message "Folder %s is empty" folder)
- (message "No messages in %s, range %s" folder range))
- (mh-goto-cur-msg))
- (when (mh-outstanding-commands-p)
- (mh-notate-deleted-and-refiled)))
-
-;;;###mh-autoload
-(defun mh-process-or-undo-commands (folder)
- "If FOLDER has outstanding commands, then either process or discard them.
-Called by functions like `mh-sort-folder', so also invalidate
-show buffer."
- (set-buffer folder)
- (if (mh-outstanding-commands-p)
- (if (or mh-do-not-confirm-flag
- (y-or-n-p
- "Process outstanding deletes and refiles? "))
- (mh-process-commands folder)
- (set-buffer folder)
- (mh-undo-folder)))
- (mh-update-unseen)
- (mh-invalidate-show-buffer))
-
-;;;###mh-autoload
-(defun mh-regenerate-headers (range &optional update)
- "Scan folder over RANGE.
-If UPDATE, append the scan lines, otherwise replace."
- (let ((folder mh-current-folder)
- (range (if (and range (atom range)) (list range) range))
- scan-start)
- (message "Scanning %s..." folder)
- (mh-remove-all-notation)
- (with-mh-folder-updating (nil)
- (if update
- (goto-char (point-max))
- (delete-region (point-min) (point-max))
- (if mh-adaptive-cmd-note-flag
- (mh-set-cmd-note (mh-msg-num-width-to-column (mh-msg-num-width
- folder)))))
- (setq scan-start (point))
- (apply #'mh-exec-cmd-output
- mh-scan-prog nil
- (mh-scan-format)
- "-noclear" "-noheader"
- "-width" (window-width)
- folder range)
- (goto-char scan-start)
- (cond ((or (looking-at "scan: no messages in")
- (looking-at "scan: message set .* does not exist")
- (looking-at "scan: bad message list "))
- (keep-lines mh-scan-valid-regexp)) ; flush common scan output
- ((looking-at "scan: ")) ; keep unexpected error messages
- (t
- (keep-lines mh-scan-valid-regexp))) ; flush random scan output
- (setq mh-seq-list (mh-read-folder-sequences folder nil))
- (mh-notate-user-sequences)
- (or update
- (setq mh-mode-line-annotation
- (if (equal range '("all"))
- nil
- mh-partial-folder-mode-line-annotation)))
- (mh-make-folder-mode-line))
- (message "Scanning %s...done" folder)))
-
-;;;###mh-autoload
-(defun mh-reset-threads-and-narrowing ()
- "Reset all variables pertaining to threads and narrowing.
-Also removes all content from the folder buffer."
- (setq mh-view-ops ())
- (setq mh-folder-view-stack ())
- (setq mh-thread-scan-line-map-stack ())
- (let ((buffer-read-only nil)) (erase-buffer)))
-
-(defun mh-make-folder (name)
- "Create a new mail folder called NAME.
-Make it the current folder."
- (switch-to-buffer name)
- (setq buffer-read-only nil)
- (erase-buffer)
- (if mh-adaptive-cmd-note-flag
- (mh-set-cmd-note (mh-msg-num-width-to-column (mh-msg-num-width name))))
- (setq buffer-read-only t)
- (mh-folder-mode)
- (mh-set-folder-modified-p nil)
- (setq buffer-file-name mh-folder-filename)
- (when (and (not mh-index-data)
- (file-exists-p (concat buffer-file-name mh-index-data-file)))
- (mh-index-read-data))
- (mh-make-folder-mode-line))
-
-;;;###mh-autoload
-(defun mh-next-msg (&optional wait-after-complaining-flag)
- "Move backward or forward to the next undeleted message in the buffer.
-If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and
-we are at the last message, then wait for a second after telling
-the user that there aren't any more unread messages."
- (if (eq mh-next-direction 'forward)
- (mh-next-undeleted-msg 1 wait-after-complaining-flag)
- (mh-previous-undeleted-msg 1 wait-after-complaining-flag)))
-
-;;;###mh-autoload
-(defun mh-prompt-for-refile-folder ()
- "Prompt the user for a folder in which the message should be filed.
-The folder is returned as a string.
-
-The default folder name is generated by the option
-`mh-default-folder-for-message-function' if it is non-nil or
-`mh-folder-from-address'."
- (mh-prompt-for-folder
- "Destination"
- (let ((refile-file (ignore-errors (mh-msg-filename (mh-get-msg-num t)))))
- (if (null refile-file) ""
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (insert-file-contents refile-file)
- (or (and mh-default-folder-for-message-function
- (let ((buffer-file-name refile-file))
- (funcall mh-default-folder-for-message-function)))
- (mh-folder-from-address)
- (and (eq 'refile (car mh-last-destination-folder))
- (symbol-name (cdr mh-last-destination-folder)))
- ""))))
- t))
-
-;;;###mh-autoload
-(defun mh-folder-from-address ()
- "Derive folder name from sender.
-
-The name of the folder is derived as follows:
-
- a) The folder name associated with the first address found in
- the list `mh-default-folder-list' is used. Each element in
- this list contains a \"Check Recipient\" item. If this item is
- turned on, then the address is checked against the recipient
- instead of the sender. This is useful for mailing lists.
-
- b) An alias prefixed by `mh-default-folder-prefix'
- corresponding to the address is used. The prefix is used to
- prevent clutter in your mail directory.
-
-Return nil if a folder name was not derived, or if the variable
-`mh-default-folder-must-exist-flag' is t and the folder does not
-exist."
- ;; Loop for all entries in mh-default-folder-list
- (save-restriction
- (goto-char (point-min))
- (re-search-forward "\n\n" nil 'limit)
- (narrow-to-region (point-min) (point))
- (let ((to/cc (concat (or (message-fetch-field "to") "") ", "
- (or (message-fetch-field "cc") "")))
- (from (or (message-fetch-field "from") ""))
- folder-name)
- (setq folder-name
- (cl-loop for list in mh-default-folder-list
- when (string-match (nth 0 list)
- (if (nth 2 list) to/cc from))
- return (nth 1 list)
- finally return nil))
-
- ;; Make sure a result from `mh-default-folder-list' begins with "+"
- ;; since 'mh-expand-file-name below depends on it
- (when (and folder-name (not (eq (aref folder-name 0) ?+)))
- (setq folder-name (concat "+" folder-name)))
-
- ;; If not, is there an alias for the address?
- (when (not folder-name)
- (let* ((from-header (mh-extract-from-header-value))
- (address (and from-header
- (nth 1 (mail-extract-address-components
- from-header))))
- (alias (and address (mh-alias-address-to-alias address))))
- (when alias
- (setq folder-name
- (and alias (concat "+" mh-default-folder-prefix alias))))))
-
- ;; If mh-default-folder-must-exist-flag set, check that folder exists.
- (if (and folder-name
- (or (not mh-default-folder-must-exist-flag)
- (file-exists-p (mh-expand-file-name folder-name))))
- folder-name))))
-
-;;;###mh-autoload
-(defun mh-delete-a-msg (message)
- "Delete MESSAGE.
-If MESSAGE is nil then the message at point is deleted.
-The hook `mh-delete-msg-hook' is called after you mark a message
-for deletion. For example, a past maintainer of MH-E used this
-once when he kept statistics on his mail usage."
- (save-excursion
- (if (numberp message)
- (mh-goto-msg message nil t)
- (beginning-of-line)
- (setq message (mh-get-msg-num t)))
- (if (looking-at mh-scan-refiled-msg-regexp)
- (error "Message %d is refiled; undo refile before deleting" message))
- (if (looking-at mh-scan-blocklisted-msg-regexp)
- (error "Message %d is blocklisted; undo before deleting" message))
- (if (looking-at mh-scan-allowlisted-msg-regexp)
- (error "Message %d is allowlisted; undo before deleting" message))
- (if (looking-at mh-scan-deleted-msg-regexp)
- nil
- (mh-set-folder-modified-p t)
- (setq mh-delete-list (cons message mh-delete-list))
- (mh-notate nil mh-note-deleted mh-cmd-note)
- (run-hooks 'mh-delete-msg-hook))))
-
-;;;###mh-autoload
-(defun mh-refile-a-msg (message folder)
- "Refile MESSAGE in FOLDER.
-If MESSAGE is nil then the message at point is refiled.
-Folder is a symbol, not a string.
-The hook `mh-refile-msg-hook' is called after a message is marked to
-be refiled."
- (save-excursion
- (if (numberp message)
- (mh-goto-msg message nil t)
- (beginning-of-line)
- (setq message (mh-get-msg-num t)))
- (cond ((looking-at mh-scan-deleted-msg-regexp)
- (error "Message %d is deleted; undo delete before moving" message))
- ((looking-at mh-scan-blocklisted-msg-regexp)
- (error "Message %d is blocklisted; undo before moving" message))
- ((looking-at mh-scan-allowlisted-msg-regexp)
- (error "Message %d is allowlisted; undo before moving" message))
- ((looking-at mh-scan-refiled-msg-regexp)
- (if (y-or-n-p
- (format "Message %d already refiled; copy to %s as well? "
- message folder))
- (mh-exec-cmd "refile" (mh-get-msg-num t) "-link"
- "-src" mh-current-folder
- (symbol-name folder))
- (message "Message not copied")))
- (t
- (mh-set-folder-modified-p t)
- (cond ((null (assoc folder mh-refile-list))
- (push (list folder message) mh-refile-list))
- ((not (member message (cdr (assoc folder mh-refile-list))))
- (push message (cdr (assoc folder mh-refile-list)))))
- (mh-notate nil mh-note-refiled mh-cmd-note)
- (run-hooks 'mh-refile-msg-hook)))))
-
-(defun mh-undo-msg (msg)
- "Undo the deletion, refile, block- or allowlisting of one MSG.
-If MSG is nil then act on the message at point"
- (save-excursion
- (if (numberp msg)
- (mh-goto-msg msg t t)
- (beginning-of-line)
- (setq msg (mh-get-msg-num t)))
- (cond ((memq msg mh-delete-list)
- (setq mh-delete-list (delq msg mh-delete-list)))
- ((memq msg mh-blocklist)
- (setq mh-blocklist (delq msg mh-blocklist)))
- ((memq msg mh-allowlist)
- (setq mh-allowlist (delq msg mh-allowlist)))
- (t
- (dolist (folder-msg-list mh-refile-list)
- (setf (cdr folder-msg-list) (remove msg (cdr folder-msg-list))))
- (setq mh-refile-list (cl-loop for x in mh-refile-list
- unless (null (cdr x)) collect x))))
- (mh-notate nil ? mh-cmd-note)))
-
-;;;###mh-autoload
-(defun mh-msg-filename (msg &optional folder)
- "Return the file name of MSG in FOLDER (default current folder)."
- (expand-file-name (int-to-string msg)
- (if folder
- (mh-expand-file-name folder)
- mh-folder-filename)))
-
-(provide 'mh-folder)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-folder.el ends here
+++ /dev/null
-;;; mh-funcs.el --- MH-E functions not everyone will use right away -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Putting these functions in a separate file lets MH-E start up faster,
-;; since less Lisp code needs to be loaded all at once.
-
-;; Please add the functions in alphabetical order. If only one or two
-;; small support routines are needed, place them with the function;
-;; otherwise, create a separate section for them.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-;;;###mh-autoload
-(defun mh-burst-digest ()
- "Break up digest into separate messages\\<mh-folder-mode-map>.
-
-This command uses the MH command \"burst\" to break out each
-message in the digest into its own message. Using this command,
-you can quickly delete unwanted messages, like this: Once the
-digest is split up, toggle out of MH-Folder Show mode with
-\\[mh-toggle-showing] so that the scan lines fill the screen and
-messages aren't displayed. Then use \\[mh-delete-msg] to quickly
-delete messages that you don't want to read (based on the
-\"Subject:\" header field). You can also burst the digest to
-reply directly to the people who posted the messages in the
-digest. One problem you may encounter is that the \"From:\"
-header fields are preceded with a \">\" so that your reply can't
-create the \"To:\" field correctly. In this case, you must
-correct the \"To:\" field yourself."
- (interactive)
- (let ((digest (mh-get-msg-num t)))
- (mh-process-or-undo-commands mh-current-folder)
- (mh-set-folder-modified-p t) ; lock folder while bursting
- (message "Bursting digest...")
- (mh-exec-cmd "burst" mh-current-folder digest "-inplace")
- (with-mh-folder-updating (t)
- (beginning-of-line)
- (delete-region (point) (point-max)))
- (mh-regenerate-headers (format "%d-last" digest) t)
- (mh-goto-cur-msg)
- (message "Bursting digest...done")))
-
-;;;###mh-autoload
-(defun mh-copy-msg (range folder)
- "Copy RANGE to FOLDER\\<mh-folder-mode-map>.
-
-If you wish to copy a message to another folder, you can use this
-command (see the \"-link\" argument to \"refile\"). Like the
-command \\[mh-refile-msg], this command prompts you for the name
-of the target folder and you can specify a range. Note that
-unlike the command \\[mh-refile-msg], the copy takes place
-immediately. The original copy remains in the current folder.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (interactive (list (mh-interactive-range "Copy")
- (mh-prompt-for-folder "Copy to" "" t)))
- (let ((msg-list (let ((result ()))
- (mh-iterate-on-range msg range
- (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)))
-
-;;;###mh-autoload
-(defun mh-kill-folder ()
- "Remove folder.
-
-Remove all of the messages (files) within the current folder, and
-then remove the folder (directory) itself.
-
-Run the abnormal hook `mh-kill-folder-suppress-prompt-functions'.
-The hook functions are called with no arguments and should return
-a non-nil value to suppress the normal prompt when you remove a
-folder. This is useful for folders that are easily regenerated."
- (interactive)
- (if (or (run-hook-with-args-until-success
- 'mh-kill-folder-suppress-prompt-functions)
- (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))
- (mh-set-folder-modified-p t) ; lock folder to kill it
- (mh-exec-cmd-daemon "rmf" 'mh-rmf-daemon folder)
- (when (and (boundp 'speedbar-buffer) speedbar-buffer)
- (mh-speed-invalidate-map folder))
- (mh-remove-from-sub-folders-cache folder)
- (mh-set-folder-modified-p nil) ; so kill-buffer doesn't complain
- (if (and mh-show-buffer (get-buffer mh-show-buffer))
- (kill-buffer mh-show-buffer))
- (if (get-buffer folder)
- (kill-buffer folder))
- (when window-config
- (set-window-configuration window-config))
- (message "Folder %s removed" folder))
- (message "Folder not removed")))
-
-(defun mh-rmf-daemon (_process output)
- "The rmf PROCESS puts OUTPUT in temporary buffer.
-Display the results only if something went wrong."
- (set-buffer (get-buffer-create mh-temp-buffer))
- (insert-before-markers output)
- (when (save-excursion
- (goto-char (point-min))
- (re-search-forward "^rmf: " (point-max) t))
- (display-buffer mh-temp-buffer)))
-
-;; Shush compiler.
-(defvar view-exit-action)
-
-;;;###mh-autoload
-(defun mh-list-folders ()
- "List mail folders."
- (interactive)
- (let ((temp-buffer mh-folders-buffer))
- (with-output-to-temp-buffer temp-buffer
- (with-current-buffer temp-buffer
- (erase-buffer)
- (message "Listing folders...")
- (mh-exec-cmd-output "folders" t (if mh-recursive-folders-flag
- "-recurse"
- "-norecurse"))
- (goto-char (point-min))
- (view-mode-enter)
- (setq view-exit-action 'kill-buffer)
- (message "Listing folders...done")))))
-
-;;;###mh-autoload
-(defun mh-pack-folder (range)
- "Pack folder\\<mh-folder-mode-map>.
-
-This command packs the folder, removing gaps from the numbering
-sequence. If you don't want to rescan the entire folder
-afterward, this command will accept a RANGE. Check the
-documentation of `mh-interactive-range' to see how RANGE is read
-in interactive use.
-
-This command will ask if you want to process refiles or deletes
-first and then either run \\[mh-execute-commands] for you or undo
-the pending refiles and deletes.
-
-The hook `mh-pack-folder-hook' is run after the folder is packed;
-see its documentation for variables it can use."
- (interactive (list (if current-prefix-arg
- (mh-read-range "Scan" mh-current-folder t nil t
- mh-interpret-number-as-range-flag)
- '("all"))))
- (let ((threaded-flag (memq 'unthread mh-view-ops)))
- (mh-pack-folder-1 range)
- (mh-goto-cur-msg)
- (when mh-index-data
- (mh-index-update-maps mh-current-folder))
- (cond (threaded-flag (mh-toggle-threads))
- (mh-index-data (mh-index-insert-folder-headers))))
- (run-hooks 'mh-pack-folder-hook)
- (message "Packing folder...done"))
-
-(defun mh-pack-folder-1 (range)
- "Close and pack the current folder.
-
-Display RANGE after packing, or the entire folder if RANGE is nil."
- (mh-process-or-undo-commands mh-current-folder)
- (message "Packing folder...")
- (mh-set-folder-modified-p t) ; lock folder while packing
- (save-excursion
- (mh-exec-cmd-quiet t "folder" mh-current-folder "-pack"
- "-norecurse" "-fast"))
- (mh-reset-threads-and-narrowing)
- (mh-regenerate-headers range))
-
-;;;###mh-autoload
-(defun mh-page-digest ()
- "Display next message in digest."
- (interactive)
- (mh-in-show-buffer (mh-show-buffer)
- ;; Go to top of screen (in case user moved point).
- (move-to-window-line 0)
- (let ((case-fold-search nil))
- ;; Search for blank line and then for From:
- (or (and (search-forward "\n\n" nil t)
- (re-search-forward "^From:" nil t))
- (error "No more messages in digest")))
- ;; Go back to previous blank line, then forward to the first non-blank.
- (search-backward "\n\n" nil t)
- (forward-line 2)
- (mh-recenter 0)))
-
-;;;###mh-autoload
-(defun mh-page-digest-backwards ()
- "Display previous message in digest."
- (interactive)
- (mh-in-show-buffer (mh-show-buffer)
- ;; Go to top of screen (in case user moved point).
- (move-to-window-line 0)
- (let ((case-fold-search nil))
- (beginning-of-line)
- (or (and (search-backward "\n\n" nil t)
- (re-search-backward "^From:" nil t))
- (error "No previous message in digest")))
- ;; Go back to previous blank line, then forward to the first non-blank.
- (if (search-backward "\n\n" nil t)
- (forward-line 2))
- (mh-recenter 0)))
-
-;;;###mh-autoload
-(defun mh-pipe-msg (command include-header)
- "Pipe message through shell command COMMAND.
-
-You are prompted for the Unix command through which you wish to
-run your message. If you give a prefix argument INCLUDE-HEADER to
-this command, the message header is included in the text passed
-to the command."
- (interactive
- (list (read-string "Shell command on message: ") current-prefix-arg))
- (let ((msg-file-to-pipe (mh-msg-filename (mh-get-msg-num t)))
- (message-directory default-directory))
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (insert-file-contents msg-file-to-pipe)
- (goto-char (point-min))
- (if (not include-header) (search-forward "\n\n"))
- (let ((default-directory message-directory))
- (shell-command-on-region (point) (point-max) command nil)))))
-
-;;;###mh-autoload
-(defun mh-sort-folder (&optional extra-args)
- "Sort folder.
-
-By default, messages are sorted by date. The option
-`mh-sortm-args' holds extra arguments to pass on to the command
-\"sortm\" when a prefix argument EXTRA-ARGS is used."
- (interactive "P")
- (mh-process-or-undo-commands mh-current-folder)
- (setq mh-next-direction 'forward)
- (mh-set-folder-modified-p t) ; lock folder while sorting
- (message "Sorting folder...")
- (let ((threaded-flag (memq 'unthread mh-view-ops)))
- (mh-exec-cmd "sortm" mh-current-folder (if extra-args mh-sortm-args))
- (when mh-index-data
- (mh-index-update-maps mh-current-folder))
- (message "Sorting folder...done")
- (mh-scan-folder mh-current-folder "all")
- (cond (threaded-flag (mh-toggle-threads))
- (mh-index-data (mh-index-insert-folder-headers)))))
-
-;;;###mh-autoload
-(defun mh-store-msg (directory)
- "Unpack message created with \"uudecode\" or \"shar\".
-
-The default DIRECTORY for extraction is the current directory;
-however, you have a chance to specify a different extraction
-directory. The next time you use this command, the default
-directory is the last directory you used. If you would like to
-change the initial default directory, customize the option
-`mh-store-default-directory', change the value from \"Current\"
-to \"Directory\", and then enter the name of the directory for
-storing the content of these messages."
- (interactive (list (let ((udir (or mh-store-default-directory
- default-directory)))
- (read-directory-name "Store message in directory: "
- udir udir nil))))
- (let ((msg-file-to-store (mh-msg-filename (mh-get-msg-num t))))
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (insert-file-contents msg-file-to-store)
- (mh-store-buffer directory))))
-
-(defun mh-store-buffer (directory)
- "Unpack buffer created with \"uudecode\" or \"shar\".
-
-See `mh-store-msg' for a description of DIRECTORY."
- (interactive (list (let ((udir (or mh-store-default-directory
- default-directory)))
- (read-directory-name "Store buffer in directory: "
- udir udir nil))))
- (let ((store-directory (expand-file-name directory))
- (sh-start (save-excursion
- (goto-char (point-min))
- (if (re-search-forward
- "^#![ \t]*/bin/sh\\|^#\\|^: " nil t)
- (progn
- ;; The "cut here" pattern was removed from above
- ;; because it seemed to hurt more than help.
- ;; But keep this to make it easier to put it back.
- (if (looking-at "^[^a-z0-9\"]*cut here\\b")
- (forward-line 1))
- (beginning-of-line)
- (if (looking-at "^[#:]....+\n\\( ?\n\\)?end$")
- nil ;most likely end of a uuencode
- (point))))))
- (command "sh")
- (uudecode-filename "(unknown filename)")
- log-begin)
- (if (not sh-start)
- (save-excursion
- (goto-char (point-min))
- (if (re-search-forward "^begin [0-7]+ " nil t)
- (setq uudecode-filename
- (buffer-substring (point)
- (progn (end-of-line) (point)))))))
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (setq log-begin (mh-truncate-log-buffer))
- (if (not (file-directory-p store-directory))
- (progn
- (insert "mkdir " directory "\n")
- (call-process "mkdir" nil mh-log-buffer t store-directory)))
- (insert "cd " directory "\n")
- (setq mh-store-default-directory directory)
- (if (not sh-start)
- (progn
- (setq command "uudecode")
- (insert uudecode-filename " being uudecoded...\n"))))
- (set-window-start (display-buffer mh-log-buffer) log-begin) ;watch progress
- (let ((default-directory (file-name-as-directory store-directory)))
- (if (equal (call-process-region sh-start (point-max) command
- nil mh-log-buffer t)
- 0)
- (with-current-buffer mh-log-buffer
- (insert "\n(mh-store finished)\n"))
- (error "Error occurred during execution of %s" command)))))
-
-;;;###mh-autoload
-(defun mh-undo-folder (&rest _ignored)
- "Undo all refiles and deletes in the current folder.
-Arguments are IGNORED (for `revert-buffer')."
- (interactive)
- (cond ((or mh-do-not-confirm-flag
- (yes-or-no-p "Undo all commands in folder? "))
- (setq mh-delete-list nil
- mh-refile-list nil
- mh-blocklist nil
- mh-allowlist nil
- mh-seq-list nil
- mh-next-direction 'forward)
- (with-mh-folder-updating (nil)
- (mh-remove-all-notation)))
- (t
- (message "Commands not undone"))))
-
-(provide 'mh-funcs)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-funcs.el ends here
+++ /dev/null
-;;; mh-gnus.el --- make MH-E compatible with various versions of Gnus -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2003-2004, 2006-2024 Free Software Foundation, Inc.
-
-;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'mh-e)
-
-(require 'gnus-util)
-(require 'mm-bodies)
-(require 'mm-decode)
-(require 'mm-view)
-(require 'mml)
-
-(defun mh-gnus-local-map-property (map)
- "Return a list suitable for a text property list specifying keymap MAP."
- (declare (obsolete nil "29.1"))
- (list 'keymap map))
-
-(define-obsolete-function-alias 'mh-mm-merge-handles
- #'mm-merge-handles "29.1")
-
-(define-obsolete-function-alias 'mh-mm-set-handle-multipart-parameter
- #'mm-set-handle-multipart-parameter "29.1")
-
-(define-obsolete-function-alias 'mh-mm-inline-text-vcard
- #'mm-inline-text-vcard "29.1")
-
-(define-obsolete-function-alias 'mh-mm-possibly-verify-or-decrypt
- #'mm-possibly-verify-or-decrypt "29.1")
-
-(define-obsolete-function-alias 'mh-mm-handle-multipart-ctl-parameter
- #'mm-handle-multipart-ctl-parameter "29.1")
-
-(define-obsolete-function-alias 'mh-mm-readable-p
- #'mm-readable-p "29.1")
-
-(define-obsolete-function-alias 'mh-mm-long-lines-p
- #'mm-long-lines-p "29.1")
-
-(define-obsolete-function-alias 'mh-mm-keep-viewer-alive-p
- #'mm-keep-viewer-alive-p "29.1")
-
-(define-obsolete-function-alias 'mh-mm-destroy-parts
- #'mm-destroy-parts "29.1")
-
-(define-obsolete-function-alias 'mh-mm-uu-dissect-text-parts
- #'mm-uu-dissect-text-parts "29.1")
-
-(define-obsolete-function-alias 'mh-mml-minibuffer-read-disposition
- #'mml-minibuffer-read-disposition "29.1")
-
-;; This is mm-save-part from Gnus 5.11 since that function in Emacs
-;; 21.2 is buggy (the args to read-file-name are incorrect) and the
-;; version in Emacs 22 is not consistent with C-x C-w in that you
-;; can't just specify a directory and have the right thing happen.
-(defun mh-mm-save-part (handle &optional prompt)
- "Write HANDLE to a file.
-PROMPT overrides the default one used to ask user for a file name."
- (let ((filename (or (mail-content-type-get
- (mm-handle-disposition handle) 'filename)
- (mail-content-type-get
- (mm-handle-type handle) 'name)))
- file)
- (when filename
- (setq filename (gnus-map-function mm-file-name-rewrite-functions
- (file-name-nondirectory filename))))
- (setq file
- (read-file-name (or prompt "Save MIME part to: ")
- (or mm-default-directory default-directory)
- nil nil (or filename "")))
- (setq mm-default-directory (file-name-directory file))
- (and (or (not (file-exists-p file))
- (yes-or-no-p (format "File %s already exists; overwrite? "
- file)))
- (progn
- (mm-save-part-to-file handle file)
- file))))
-
-(defun mh-mm-text-html-renderer ()
- "Find the renderer Gnus is using to display text/html MIME parts."
- (declare (obsolete mm-text-html-renderer "29.1"))
- mm-text-html-renderer)
-
-(provide 'mh-gnus)
-
-;; Local Variables:
-;; no-update-autoloads: t
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-gnus.el ends here
+++ /dev/null
-;;; mh-identity.el --- multiple identify support for MH-E -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2024 Free Software Foundation, Inc.
-
-;; Author: Peter S. Galbraith <psg@debian.org>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Multiple identity support for MH-E.
-
-;; Used to easily set different fields such as From and Organization,
-;; as well as different signature files.
-
-;; Customize the variable `mh-identity-list' and see the Identity menu
-;; in MH-Letter mode. The command `mh-insert-identity' can be used
-;; to manually insert an identity.
-
-;;; Code:
-
-(require 'mh-e)
-
-(autoload 'mml-insert-tag "mml")
-
-(define-obsolete-variable-alias 'mh-identity-pgg-default-user-id
- 'mh-identity-gpg-default-user-id "29.1")
-(defvar-local mh-identity-gpg-default-user-id nil
- "Holds the GPG key ID.
-This is normally set as part of an Identity in
-`mh-identity-list'.")
-
-(defvar mh-identity-menu nil
- "The Identity menu.")
-
-(defalias 'mh-identity-make-menu-no-autoload #'mh-identity-make-menu)
-
-;;;###mh-autoload
-(defun mh-identity-make-menu ()
- "Build the Identity menu.
-This should be called any time `mh-identity-list' or
-`mh-auto-fields-list' change."
- (easy-menu-define mh-identity-menu mh-letter-mode-map
- "MH-E identity menu"
- (append
- '("Identity")
- ;; Dynamically render :type corresponding to `mh-identity-list'
- ;; e.g.:
- ;; ["Home" (mh-insert-identity "Home")
- ;; :style radio :active (not (equal mh-identity-local "Home"))
- ;; :selected (equal mh-identity-local "Home")]
- '(["Insert Auto Fields"
- (mh-insert-auto-fields) mh-auto-fields-list]
- "--")
-
- (mapcar (lambda (arg)
- `[,arg (mh-insert-identity ,arg) :style radio
- :selected (equal mh-identity-local ,arg)])
- (mapcar #'car mh-identity-list))
- '(["None"
- (mh-insert-identity "None") :style radio
- :selected (not mh-identity-local)]
- "--"
- ["Set Default for Session"
- (setq mh-identity-default mh-identity-local) t]
- ["Save as Default"
- (customize-save-variable 'mh-identity-default mh-identity-local) t]
- ["Customize Identities" (customize-variable 'mh-identity-list) t]
- ))))
-
-;;;###mh-autoload
-(defun mh-identity-add-menu ()
- "Add the current Identity menu.
-See `mh-identity-make-menu'."
- (declare (obsolete nil "29.1"))
- nil)
-
-(defvar-local mh-identity-local nil
- "Buffer-local variable that holds the identity currently in use.")
-
-(defun mh-header-field-delete (field value-only)
- "Delete header FIELD, or only its value if VALUE-ONLY is t.
-Return t if anything is deleted."
- (let ((field-colon (if (string-match "^.*:$" field)
- field
- (concat field ":"))))
- (when (mh-goto-header-field field-colon)
- (if (not value-only)
- (beginning-of-line)
- (forward-char))
- (delete-region (point)
- (progn (mh-header-field-end)
- (if (not value-only) (forward-char 1))
- (point)))
- t)))
-
-(defvar mh-identity-signature-start nil
- "Marker for the beginning of a signature inserted by `mh-insert-identity'.")
-(defvar mh-identity-signature-end nil
- "Marker for the end of a signature inserted by `mh-insert-identity'.")
-
-(defun mh-identity-field-handler (field)
- "Return the handler for header FIELD or nil if none set.
-The field name is downcased. If the FIELD begins with the
-character \":\", then it must have a special handler defined in
-`mh-identity-handlers', else return an error since it is not a
-valid header field."
- (or (cdr (assoc-string field mh-identity-handlers t))
- (and (eq (aref field 0) ?:)
- (error "Field %s not found in `mh-identity-handlers'" field))
- (cdr (assoc ":default" mh-identity-handlers))
- 'mh-identity-handler-default))
-
-;;;###mh-autoload
-(defun mh-select-identity (default)
- "Prompt for and return an identity.
-If DEFAULT is non-nil, it will be used if the user doesn't enter a
-different identity.
-
-See `mh-identity-list'."
- (let (identity)
- (setq identity
- (completing-read
- "Identity: "
- (cons '("None")
- (mapcar #'list (mapcar #'car mh-identity-list)))
- nil t default nil default))
- (if (equal identity "None")
- nil
- identity)))
-
-;;;###mh-autoload
-(defun mh-identity-field (identity field)
- "Return the specified FIELD of the given IDENTITY.
-
-See `mh-identity-list'."
- (let* ((pers-list (cadr (assoc identity mh-identity-list)))
- (value (cdr (assoc field pers-list))))
- value))
-
-;;;###mh-autoload
-(defun mh-insert-identity (identity &optional maybe-insert)
- "Insert fields specified by given IDENTITY.
-
-In a program, do not insert fields if MAYBE-INSERT is non-nil,
-`mh-identity-default' is non-nil, and fields have already been
-inserted.
-
-See `mh-identity-list'."
- (interactive
- (list (completing-read
- "Identity: "
- (if mh-identity-local
- (cons '("None")
- (mapcar #'list (mapcar #'car mh-identity-list)))
- (mapcar #'list (mapcar #'car mh-identity-list)))
- nil t)
- nil))
-
- (when (or (not maybe-insert)
- (and (boundp 'mh-identity-default)
- mh-identity-default
- (not mh-identity-local)))
- (save-excursion
- ;;First remove old settings, if any.
- (when mh-identity-local
- (let ((pers-list (cadr (assoc mh-identity-local mh-identity-list))))
- (while pers-list
- (let* ((field (caar pers-list))
- (handler (mh-identity-field-handler field)))
- (funcall handler field 'remove))
- (setq pers-list (cdr pers-list)))))
- ;; Then insert the replacement
- (when (not (equal "None" identity))
- (let ((pers-list (cadr (assoc identity mh-identity-list))))
- (while pers-list
- (let* ((field (caar pers-list))
- (value (cdar pers-list))
- (handler (mh-identity-field-handler field)))
- (funcall handler field 'add value))
- (setq pers-list (cdr pers-list))))))
- ;; Remember what is in use in this buffer
- (if (equal "None" identity)
- (setq mh-identity-local nil)
- (setq mh-identity-local identity))))
-
-;;;###mh-autoload
-(defun mh-identity-handler-gpg-identity (_field action &optional value)
- "Process header FIELD \":pgg-default-user-id\".
-The ACTION is one of `remove' or `add'. If `add', the VALUE is added.
-The buffer-local variable `mh-identity-gpg-default-user-id' is set to
-VALUE when action `add' is selected."
- (cond
- ((or (equal action 'remove)
- (not value)
- (string= value ""))
- (setq mh-identity-gpg-default-user-id nil))
- ((equal action 'add)
- (setq mh-identity-gpg-default-user-id value))))
-
-;;;###mh-autoload
-(defun mh-identity-handler-signature (_field action &optional value)
- "Process header FIELD \":signature\".
-The ACTION is one of `remove' or `add'. If `add', the VALUE is
-added."
- (cond
- ((equal action 'remove)
- (when (and (markerp mh-identity-signature-start)
- (markerp mh-identity-signature-end))
- (delete-region mh-identity-signature-start
- mh-identity-signature-end)))
- (t
- ;; Insert "signature". Nil value means to use `mh-signature-file-name'.
- (when (not (mh-signature-separator-p)) ;...unless already present
- (goto-char (point-max))
- (save-restriction
- (narrow-to-region (point) (point))
- (if (null value)
- (mh-insert-signature)
- (mh-insert-signature value))
- (setq-local mh-identity-signature-start (point-min-marker))
- (set-marker-insertion-type mh-identity-signature-start t)
- (setq-local mh-identity-signature-end (point-max-marker)))))))
-
-(defvar mh-identity-attribution-verb-start nil
- "Marker for the beginning of the attribution verb.")
-(defvar mh-identity-attribution-verb-end nil
- "Marker for the end of the attribution verb.")
-
-;;;###mh-autoload
-(defun mh-identity-handler-attribution-verb (_field action &optional value)
- "Process header FIELD \":attribution-verb\".
-The ACTION is one of `remove' or `add'. If `add', the VALUE is
-added."
- (when (and (markerp mh-identity-attribution-verb-start)
- (markerp mh-identity-attribution-verb-end))
- (delete-region mh-identity-attribution-verb-start
- mh-identity-attribution-verb-end)
- (goto-char mh-identity-attribution-verb-start)
- (cond
- ((equal action 'remove) ; Replace with default
- (mh-identity-insert-attribution-verb nil))
- (t ; Insert attribution verb.
- (mh-identity-insert-attribution-verb value)))))
-
-;;;###mh-autoload
-(defun mh-identity-insert-attribution-verb (value)
- "Insert VALUE as attribution verb, setting up delimiting markers.
-If VALUE is nil, use `mh-extract-from-attribution-verb'."
- (save-restriction
- (narrow-to-region (point) (point))
- (if (null value)
- (insert mh-extract-from-attribution-verb)
- (insert value))
- (setq-local mh-identity-attribution-verb-start (point-min-marker))
- (set-marker-insertion-type mh-identity-attribution-verb-start t)
- (setq-local mh-identity-attribution-verb-end (point-max-marker))))
-
-(defun mh-identity-handler-default (field action top &optional value)
- "Process header FIELD.
-The ACTION is one of `remove' or `add'. If TOP is non-nil, add the
-field and its VALUE at the top of the header, else add it at the
-bottom of the header. If action is `add', the VALUE is added."
- (let ((field-colon (if (string-match "^.*:$" field)
- field
- (concat field ":"))))
- (cond
- ((equal action 'remove)
- (mh-header-field-delete field-colon nil))
- (t
- (cond
- ;; No value, remove field
- ((or (not value)
- (string= value ""))
- (mh-header-field-delete field-colon nil))
- ;; Existing field, replace
- ((mh-header-field-delete field-colon t)
- (insert value))
- ;; Other field, add at end or top
- (t
- (goto-char (point-min))
- (if (not top)
- (mh-goto-header-end 0))
- (insert field-colon " " value "\n")))))))
-
-;;;###mh-autoload
-(defun mh-identity-handler-top (field action &optional value)
- "Process header FIELD.
-The ACTION is one of `remove' or `add'. If `add', the VALUE is
-added. If the field wasn't present, it is added to the top of the
-header."
- (mh-identity-handler-default field action t value))
-
-;;;###mh-autoload
-(defun mh-identity-handler-bottom (field action &optional value)
- "Process header FIELD.
-The ACTION is one of `remove' or `add'. If `add', the VALUE is
-added. If the field wasn't present, it is added to the bottom of
-the header."
- (mh-identity-handler-default field action nil value))
-
-(provide 'mh-identity)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-identity.el ends here
+++ /dev/null
-;;; mh-inc.el --- MH-E "inc" and separate mail spool handling -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2003-2004, 2006-2024 Free Software Foundation, Inc.
-
-;; Author: Peter S. Galbraith <psg@debian.org>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Support for inc. In addition to reading from the system mailbox,
-;; inc can also be used to incorporate mail from multiple spool files
-;; into separate folders. See "C-h v mh-inc-spool-list".
-
-;;; Code:
-
-(require 'mh-e)
-
-(defvar mh-inc-spool-map-help nil
- "Help text for `mh-inc-spool-map'.")
-
-(define-key mh-inc-spool-map "?"
- (lambda ()
- (interactive)
- (if mh-inc-spool-map-help
- (mh-help mh-inc-spool-map-help)
- (mh-ephem-message
- "There are no keys defined yet; customize `mh-inc-spool-list'"))))
-
-;;;###mh-autoload
-(defun mh-inc-spool-make ()
- "Make all commands and defines keys for contents of `mh-inc-spool-list'."
- (setq mh-inc-spool-map-help nil)
- (when mh-inc-spool-list
- (cl-loop for elem in mh-inc-spool-list
- do (let ((spool (nth 0 elem))
- (folder (nth 1 elem))
- (key (nth 2 elem)))
- (progn
- (mh-inc-spool-generator folder spool)
- (mh-inc-spool-def-key key folder))))))
-
-(defalias 'mh-inc-spool-make-no-autoload #'mh-inc-spool-make)
-
-(defun mh-inc-spool-generator (folder spool)
- "Create a command to inc into FOLDER from SPOOL file."
- (defalias (symbol-function (intern (concat "mh-inc-spool-" folder)))
- (lambda ()
- (:documentation (format "Inc spool file %s into folder %s." spool folder))
- (interactive)
- (mh-inc-folder spool (concat "+" folder)))))
-
-(defun mh-inc-spool-def-key (key folder)
- "Define a KEY in `mh-inc-spool-map' to inc FOLDER and collect help string."
- (when (not (= 0 key))
- (define-key mh-inc-spool-map (format "%c" key)
- (intern (concat "mh-inc-spool-" folder)))
- (add-to-list 'mh-inc-spool-map-help
- (concat "[" (char-to-string key) "] inc " folder " folder\n")
- t)))
-
-(provide 'mh-inc)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-inc.el ends here
+++ /dev/null
-;;; mh-junk.el --- MH-E interface to anti-spam measures -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2003-2024 Free Software Foundation, Inc.
-
-;; Author: Satyaki Das <satyaki@theforce.stanford.edu>,
-;; Bill Wohler <wohler@newt.com>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail, spam
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Spam handling in MH-E.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-(autoload 'mail-header-parse-address "mail-parse")
-
-;;;###mh-autoload
-(defun mh-junk-blocklist (range)
- "Blocklist RANGE as spam.
-
-This command trains the spam program in use (see the option
-`mh-junk-program') with the content of RANGE and then handles the
-message(s) as specified by the option `mh-junk-disposition'.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is
-read in interactive use.
-
-For more information about using your particular spam fighting
-program, see:
-
- - `mh-spamassassin-blocklist'
- - `mh-bogofilter-blocklist'
- - `mh-spamprobe-blocklist'"
- (interactive (list (mh-interactive-range "Blocklist")))
- (mh-iterate-on-range () range (mh-junk-blocklist-a-msg nil))
- (if (looking-at mh-scan-blocklisted-msg-regexp)
- (mh-next-msg)))
-
-(defun mh-junk-blocklist-a-msg (message)
- "Blocklist MESSAGE.
-If MESSAGE is nil then the message at point is blocklisted.
-The hook `mh-blocklist-msg-hook' is called after you mark a message
-for blocklisting."
- (save-excursion
- (if (numberp message)
- (mh-goto-msg message nil t)
- (beginning-of-line)
- (setq message (mh-get-msg-num t)))
- (cond ((looking-at mh-scan-refiled-msg-regexp)
- (error "Message %d is refiled; undo refile before blocklisting"
- message))
- ((looking-at mh-scan-deleted-msg-regexp)
- (error "Message %d is deleted; undo delete before blocklisting"
- message))
- ((looking-at mh-scan-allowlisted-msg-regexp)
- (error "Message %d is allowlisted; undo before blocklisting"
- message))
- ((looking-at mh-scan-blocklisted-msg-regexp) nil)
- (t
- (mh-set-folder-modified-p t)
- (setq mh-blocklist (cons message mh-blocklist))
- (if (not (memq message mh-seen-list))
- (setq mh-seen-list (cons message mh-seen-list)))
- (mh-notate nil mh-note-blocklisted mh-cmd-note)
- (run-hooks 'mh-blocklist-msg-hook)))))
-
-;;;###mh-autoload
-(defun mh-junk-blocklist-disposition ()
- "Determines the fate of the selected spam."
- (cond ((null mh-junk-disposition) nil)
- ((equal mh-junk-disposition "") "+")
- ((eq (aref mh-junk-disposition 0) ?+)
- mh-junk-disposition)
- ((eq (aref mh-junk-disposition 0) ?@)
- (concat mh-current-folder "/"
- (substring mh-junk-disposition 1)))
- (t (concat "+" mh-junk-disposition))))
-
-;;;###mh-autoload
-(defun mh-junk-process-blocklist (range)
- "Blocklist RANGE as spam.
-This command trains the spam program in use (see the option
-`mh-junk-program') with the content of RANGE and then handles the
-message(s) as specified by the option `mh-junk-disposition'."
- (let ((blocklist-func (nth 1 (assoc mh-junk-choice mh-junk-function-alist))))
- (unless blocklist-func
- (error "Customize `mh-junk-program' appropriately"))
- (mh-iterate-on-range msg range
- (funcall (symbol-function blocklist-func) msg))))
-
-;;;###mh-autoload
-(defun mh-junk-whitelist (range)
- "Old name for `mh-junk-allowlist'; use \\[mh-junk-allowlist] instead."
- (interactive (list (mh-interactive-range "Allowlist")))
- ;; We do our own message here instead of using "declare obsolete"
- ;; in order to talk about keys instead of function names. Also, it
- ;; lets us bind "J w" to this without the Emacs 29 compiler complaining.
- (when (not (get 'mh-junk-whitelist 'command-execute-obsolete-warned))
- (message "%s is an obsolete key (as of 28.1); use %s instead"
- (substitute-command-keys "\\[mh-junk-whitelist]")
- (substitute-command-keys "\\[mh-junk-allowlist]"))
- (put 'mh-junk-whitelist 'command-execute-obsolete-warned t))
- (mh-junk-allowlist range))
-
-;;;###mh-autoload
-(defun mh-junk-allowlist (range)
- "Allowlist RANGE as ham.
-
-This command reclassifies the RANGE as ham if it has been incorrectly
-classified as spam (see the option `mh-junk-program'). It then
-refiles the message into the \"+inbox\" folder.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (interactive (list (mh-interactive-range "Allowlist")))
- (mh-iterate-on-range () range (mh-junk-allowlist-a-msg nil))
- (if (looking-at mh-scan-allowlisted-msg-regexp)
- (mh-next-msg)))
-
-(defun mh-junk-allowlist-a-msg (message)
- "Allowlist MESSAGE.
-If MESSAGE is nil then the message at point is allowlisted. The
-hook `mh-allowlist-msg-hook' is called after you mark a message
-for allowlisting."
- (save-excursion
- (if (numberp message)
- (mh-goto-msg message nil t)
- (beginning-of-line)
- (setq message (mh-get-msg-num t)))
- (cond ((looking-at mh-scan-refiled-msg-regexp)
- (error "Message %d is refiled; undo refile before allowlisting"
- message))
- ((looking-at mh-scan-deleted-msg-regexp)
- (error "Message %d is deleted; undo delete before allowlisting"
- message))
- ((looking-at mh-scan-blocklisted-msg-regexp)
- (error "Message %d is blocklisted; undo before allowlisting"
- message))
- ((looking-at mh-scan-allowlisted-msg-regexp) nil)
- (t
- (mh-set-folder-modified-p t)
- (setq mh-allowlist (cons message mh-allowlist))
- (mh-notate nil mh-note-allowlisted mh-cmd-note)
- (run-hooks 'mh-allowlist-msg-hook)))))
-
-;;;###mh-autoload
-(defun mh-junk-process-allowlist (range)
- "Allowlist RANGE as ham.
-
-This command reclassifies the RANGE as ham if it were incorrectly
-classified as spam (see the option `mh-junk-program')."
- (let ((allowlist-func (nth 2 (assoc mh-junk-choice mh-junk-function-alist))))
- (unless allowlist-func
- (error "Customize `mh-junk-program' appropriately"))
- (mh-iterate-on-range msg range
- (funcall (symbol-function allowlist-func) msg))))
-
-\f
-
-;; SpamAssassin Interface
-
-(defvar mh-spamassassin-executable (executable-find "spamassassin"))
-(defvar mh-sa-learn-executable (executable-find "sa-learn"))
-
-;;;###mh-autoload
-(defun mh-spamassassin-blocklist (msg)
- "Blocklist MSG with SpamAssassin.
-
-SpamAssassin is one of the more popular spam filtering programs.
-Get it from your local distribution or from the SpamAssassin web
-site at URL `https://spamassassin.apache.org/'.
-
-To use SpamAssassin, add the following recipes to
-\".procmailrc\":
-
- PATH=$PATH:/usr/bin/mh
- MAILDIR=$HOME/`mhparam Path`
-
- # Fight spam with SpamAssassin.
- :0fw
- | spamc
-
- # Anything with a spam level of 10 or more is junked immediately.
- :0:
- * ^X-Spam-Level: ..........
- /dev/null
-
- :0:
- * ^X-Spam-Status: Yes
- spam/.
-
-If you don't use \"spamc\", use \"spamassassin\".
-
-Note that one of the recipes above throws away messages with a
-score greater than or equal to 10. Here's how you can determine a
-value that works best for you.
-
-First, run \"spamassassin -t\" on every mail message in your
-archive and use Gnumeric to verify that the average plus the
-standard deviation of good mail is under 5, the SpamAssassin
-default for \"spam\".
-
-Using Gnumeric, sort the messages by score and view the messages
-with the highest score. Determine the score which encompasses all
-of your interesting messages and add a couple of points to be
-conservative. Add that many dots to the \"X-Spam-Level:\" header
-field above to send messages with that score down the drain.
-
-In the example above, messages with a score of 5-9 are set aside
-in the \"+spam\" folder for later review. The major weakness of
-rules-based filters is a plethora of false positives so it is
-worthwhile to check.
-
-If SpamAssassin classifies a message incorrectly, or is unsure,
-you can use the MH-E commands \\[mh-junk-blocklist] and
-\\[mh-junk-allowlist].
-
-The command \\[mh-junk-blocklist] adds a \"blacklist_from\" entry
-to \"~/spamassassin/user_prefs\", deletes the message, and sends
-the message to the Razor, so that others might not see this spam.
-If the \"sa-learn\" command is available, the message is also
-recategorized as spam.
-
-The command \\[mh-junk-allowlist] adds a \"whitelist_from\" rule
-to the \"~/.spamassassin/user_prefs\" file. If the \"sa-learn\"
-command is available, the message is also recategorized as ham.
-
-Over time, you'll observe that the same host or domain occurs
-repeatedly in the \"blacklist_from\" entries, so you might think
-that you could avoid future spam by blocklisting all mail from a
-particular domain. The utility function
-`mh-spamassassin-identify-spammers' helps you do precisely that.
-This function displays a frequency count of the hosts and domains
-in the \"blacklist_from\" entries from the last blank line in
-\"~/.spamassassin/user_prefs\" to the end of the file. This
-information can be used so that you can replace multiple
-\"blacklist_from\" entries with a single wildcard entry such as:
-
- blacklist_from *@*amazingoffersdirect2u.com"
- (unless mh-spamassassin-executable
- (error "Unable to find the spamassassin executable"))
- (let ((current-folder mh-current-folder)
- (msg-file (mh-msg-filename msg mh-current-folder))
- (sender))
- (message "Reporting message %d as spam with spamassassin..." msg)
- (mh-truncate-log-buffer)
- ;; Put call-process output in log buffer if we are saving it
- ;; (this happens if mh-junk-background is t).
- (with-current-buffer mh-log-buffer
- (call-process mh-spamassassin-executable msg-file mh-junk-background nil
- ;; -R removes from allowlist
- "--report" "-R")
- (when mh-sa-learn-executable
- (message "Recategorizing message %d as spam with sa-learn..." msg)
- (mh-truncate-log-buffer)
- (call-process mh-sa-learn-executable msg-file mh-junk-background nil
- "--spam" "--local" "--no-sync")))
- (message "Blocklisting sender of message %d..." msg)
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (call-process (expand-file-name mh-scan-prog mh-progs)
- nil t nil
- (format "%d" msg) current-folder
- "-format" "%<(mymbox{from})%|%(addr{from})%>")
- (goto-char (point-min))
- (if (search-forward-regexp "^\\(.+\\)$" nil t)
- (progn
- (setq sender (match-string 0))
- (mh-spamassassin-add-rule "blacklist_from" sender)
- (message "Blocklisting sender of message %d...done" msg))
- (message "Blocklisting sender of message %d...not done (from my address)" msg)))))
-
-;;;###mh-autoload
-(defun mh-spamassassin-allowlist (msg)
- "Allowlist MSG with SpamAssassin.
-
-The \\[mh-junk-allowlist] command adds a \"whitelist_from\" rule to
-the \"~/.spamassassin/user_prefs\" file. If the \"sa-learn\" command
-is available, the message is also recategorized as ham.
-
-See `mh-spamassassin-blocklist' for more information."
- (unless mh-spamassassin-executable
- (error "Unable to find the spamassassin executable"))
- (let ((msg-file (mh-msg-filename msg mh-current-folder))
- (show-buffer (get-buffer mh-show-buffer))
- from)
- (with-current-buffer (get-buffer-create mh-temp-buffer)
- (erase-buffer)
- (message "Removing spamassassin markup from message %d..." msg)
- (call-process mh-spamassassin-executable msg-file t nil
- "--remove-markup")
- (if show-buffer
- (kill-buffer show-buffer))
- (write-file msg-file)
- (when mh-sa-learn-executable
- (message "Recategorizing message %d as ham with sa-learn..." msg)
- (mh-truncate-log-buffer)
- ;; Put call-process output in log buffer if we are saving it
- ;; (this happens if mh-junk-background is t).
- (with-current-buffer mh-log-buffer
- (call-process mh-sa-learn-executable msg-file mh-junk-background nil
- "--ham" "--local" "--no-sync")))
- (message "Allowlisting sender of message %d..." msg)
- (setq from
- (car (mail-header-parse-address (mh-get-header-field "From:"))))
- (kill-buffer nil)
- (if (or (null from) (equal from ""))
- (message "Allowlisting sender of message %d...%s"
- msg "not done (cannot identify sender)")
- (mh-spamassassin-add-rule "whitelist_from" from)
- (message "Allowlisting sender of message %d...done" msg)))))
-
-(defun mh-spamassassin-add-rule (rule body)
- "Add a new rule to \"~/.spamassassin/user_prefs\".
-The name of the rule is RULE and its body is BODY."
- (save-window-excursion
- (let* ((line (format "%s\t%s\n" rule body))
- (case-fold-search t)
- (file (expand-file-name "~/.spamassassin/user_prefs"))
- (buffer-exists (find-buffer-visiting file)))
- (find-file file)
- (if (not (search-forward (format "\n%s" line) nil t))
- (progn
- (goto-char (point-max))
- (insert (if (bolp) "" "\n") line)
- (save-buffer)))
- (if (not buffer-exists)
- (kill-buffer nil)))))
-
-;;;###mh-autoload
-(defun mh-spamassassin-identify-spammers ()
- "Identify spammers who are repeat offenders.
-
-This function displays a frequency count of the hosts and domains
-in the \"blacklist_from\" entries from the last blank line in
-\"~/.spamassassin/user_prefs\" to the end of the file. This
-information can be used so that you can replace multiple
-\"blacklist_from\" entries with a single wildcard entry such as:
-
- blacklist_from *@*amazingoffersdirect2u.com"
- (interactive)
- (let* ((file (expand-file-name "~/.spamassassin/user_prefs"))
- (domains (make-hash-table :test 'equal)))
- (find-file file)
- ;; Only consider entries between last blank line and end of file.
- (goto-char (1- (point-max)))
- (search-backward-regexp "^$")
- ;; Perform frequency count.
- (save-excursion
- (while (search-forward-regexp "^blacklist_from\\s-*\\(.*\\)@\\(.*\\)$"
- nil t)
- (let ((host (match-string 2))
- value)
- ;; Remove top-level-domain from hostname.
- (setq host (cdr (reverse (split-string host "\\."))))
- ;; Add counts for each host and domain part.
- (while host
- (setq value (gethash (car host) domains))
- (setf (gethash (car host) domains) (1+ (if (not value) 0 value)))
- (setq host (cdr host))))))
-
- ;; Output
- (delete-other-windows)
- (pop-to-buffer (get-buffer-create "*MH-E Spammer Frequencies*"))
- (erase-buffer)
- (maphash (lambda (key value) ""
- (if (> value 2)
- (insert (format "%s %s\n" key value))))
- domains)
- (sort-numeric-fields 2 (point-min) (point-max))
- (reverse-region (point-min) (point-max))
- (goto-char (point-min))))
-
-\f
-
-;; Bogofilter Interface
-
-(defvar mh-bogofilter-executable (executable-find "bogofilter"))
-
-;;;###mh-autoload
-(defun mh-bogofilter-blocklist (msg)
- "Blocklist MSG with bogofilter.
-
-Bogofilter is a Bayesian spam filtering program. Get it from your
-local distribution or from the bogofilter web site at URL
-`https://bogofilter.sourceforge.io/'.
-
-Bogofilter is taught by running:
-
- bogofilter -n < good-message
-
-on every good message, and
-
- bogofilter -s < spam-message
-
-on every spam message. This is called a full training; three other
-training methods are described in the FAQ that is distributed with
-bogofilter. Note that most Bayesian filters need 1000 to 5000 of each
-type of message to start doing a good job.
-
-To use bogofilter, add the following recipes to \".procmailrc\":
-
- PATH=$PATH:/usr/bin/mh
- MAILDIR=$HOME/`mhparam Path`
-
- # Fight spam with bogofilter.
- :0fw
- | bogofilter -3 -e -p
-
- :0:
- * ^X-Bogosity: Yes, tests=bogofilter
- spam/.
-
- :0:
- * ^X-Bogosity: Unsure, tests=bogofilter
- spam/unsure/.
-
-If bogofilter classifies a message incorrectly, or is unsure, you can
-use the MH-E commands \\[mh-junk-blocklist] and \\[mh-junk-allowlist]
-to update bogofilter's training.
-
-The \"Bogofilter FAQ\" suggests that you run the following
-occasionally to shrink the database:
-
- bogoutil -d wordlist.db | bogoutil -l wordlist.db.new
- mv wordlist.db wordlist.db.prv
- mv wordlist.db.new wordlist.db
-
-The \"Bogofilter tuning HOWTO\" describes how you can fine-tune Bogofilter."
- (unless mh-bogofilter-executable
- (error "Unable to find the bogofilter executable"))
- (message "Blocklisting message %d with bogofilter..." msg)
- (let ((msg-file (mh-msg-filename msg mh-current-folder)))
- (mh-truncate-log-buffer)
- ;; Put call-process output in log buffer if we are saving it
- ;; (this happens if mh-junk-background is t).
- (with-current-buffer mh-log-buffer
- (call-process mh-bogofilter-executable msg-file mh-junk-background
- nil "-s")
- (message "Blocklisting message %d with bogofilter...done" msg))))
-
-;;;###mh-autoload
-(defun mh-bogofilter-allowlist (msg)
- "Allowlist MSG with bogofilter.
-
-See `mh-bogofilter-blocklist' for more information."
- (unless mh-bogofilter-executable
- (error "Unable to find the bogofilter executable"))
- (message "Allowlisting message %d with bogofilter..." msg)
- (let ((msg-file (mh-msg-filename msg mh-current-folder)))
- (mh-truncate-log-buffer)
- ;; Put call-process output in log buffer if we are saving it
- ;; (this happens if mh-junk-background is t).
- (with-current-buffer mh-log-buffer
- (call-process mh-bogofilter-executable msg-file mh-junk-background
- nil "-n")
- (message "Allowlisting message %d with bogofilter...done" msg))))
-
-\f
-
-;; Spamprobe Interface
-
-(defvar mh-spamprobe-executable (executable-find "spamprobe"))
-
-;;;###mh-autoload
-(defun mh-spamprobe-blocklist (msg)
- "Blocklist MSG with SpamProbe.
-
-SpamProbe is a Bayesian spam filtering program. Get it from your
-local distribution or from the SpamProbe web site at URL
-`https://spamprobe.sourceforge.net'.
-
-To use SpamProbe, add the following recipes to \".procmailrc\":
-
- PATH=$PATH:/usr/bin/mh
- MAILDIR=$HOME/`mhparam Path`
-
- # Fight spam with SpamProbe.
- :0
- SCORE=| spamprobe receive
-
- :0 wf
- | formail -I \"X-SpamProbe: $SCORE\"
-
- :0:
- *^X-SpamProbe: SPAM
- spam/.
-
-If SpamProbe classifies a message incorrectly, you can use the
-MH-E commands \\[mh-junk-blocklist] and \\[mh-junk-allowlist] to
-update SpamProbe's training."
- (unless mh-spamprobe-executable
- (error "Unable to find the spamprobe executable"))
- (message "Blocklisting message %d with spamprobe..." msg)
- (let ((msg-file (mh-msg-filename msg mh-current-folder)))
- (mh-truncate-log-buffer)
- ;; Put call-process output in log buffer if we are saving it
- ;; (this happens if mh-junk-background is t).
- (with-current-buffer mh-log-buffer
- (call-process mh-spamprobe-executable msg-file mh-junk-background
- nil "spam")
- (message "Blocklisting message %d with spamprobe...done" msg))))
-
-;;;###mh-autoload
-(defun mh-spamprobe-allowlist (msg)
- "Allowlist MSG with SpamProbe.
-
-See `mh-spamprobe-blocklist' for more information."
- (unless mh-spamprobe-executable
- (error "Unable to find the spamprobe executable"))
- (message "Allowlisting message %d with spamprobe..." msg)
- (let ((msg-file (mh-msg-filename msg mh-current-folder)))
- (mh-truncate-log-buffer)
- ;; Put call-process output in log buffer if we are saving it
- ;; (this happens if mh-junk-background is t).
- (with-current-buffer mh-log-buffer
- (call-process mh-spamprobe-executable msg-file mh-junk-background
- nil "good")
- (message "Allowlisting message %d with spamprobe...done" msg))))
-
-(provide 'mh-junk)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-junk.el ends here
+++ /dev/null
-;;; mh-letter.el --- MH-Letter mode -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 1997, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Mode for composing and sending a draft message.
-
-;; Functions that would ordinarily be in here that are needed by
-;; mh-show.el should be placed in the Message Utilities section in
-;; mh-utils.el. That will help prevent the loading of this file until
-;; a message is actually composed.
-
-;;; Code:
-
-(require 'mh-e)
-
-(require 'gnus-util)
-
-;; Dynamically-created functions not found in mh-loaddefs.el.
-(autoload 'mh-tool-bar-letter-buttons-init "mh-tool-bar")
-(autoload 'mh-tool-bar-init "mh-tool-bar")
-
-(autoload 'mml-insert-tag "mml")
-
-;;; Variables
-
-(defvar mh-letter-complete-function-alist
- '((bcc . mh-alias-letter-expand-alias)
- (cc . mh-alias-letter-expand-alias)
- (dcc . mh-alias-letter-expand-alias)
- (fcc . mh-folder-expand-at-point)
- (from . mh-alias-letter-expand-alias)
- (mail-followup-to . mh-alias-letter-expand-alias)
- (mail-reply-to . mh-alias-letter-expand-alias)
- (reply-to . mh-alias-letter-expand-alias)
- (to . mh-alias-letter-expand-alias))
- "Alist of header fields and completion functions to use.")
-
-\f
-
-;;; Letter Menu
-
-(easy-menu-define
- mh-letter-menu mh-letter-mode-map "Menu for MH-E letter mode."
- '("Letter"
- ["Send This Draft" mh-send-letter t]
- ["Split Current Line" mh-open-line t]
- ["Check Recipient" mh-check-whom t]
- ["Yank Current Message" mh-yank-cur-msg t]
- ["Insert a Message..." mh-insert-letter t]
- ["Insert Signature" mh-insert-signature t]
- ("Encrypt/Sign Message"
- ["Sign Message"
- mh-mml-secure-message-sign mh-pgp-support-flag]
- ["Encrypt Message"
- mh-mml-secure-message-encrypt mh-pgp-support-flag]
- ["Sign+Encrypt Message"
- mh-mml-secure-message-signencrypt mh-pgp-support-flag]
- ["Disable Security"
- mh-mml-unsecure-message mh-pgp-support-flag]
- "--"
- "Security Method"
- ["PGP (MIME)" (setq mh-mml-method-default "pgpmime")
- :style radio
- :selected (equal mh-mml-method-default "pgpmime")]
- ["PGP" (setq mh-mml-method-default "pgp")
- :style radio
- :selected (equal mh-mml-method-default "pgp")]
- ["S/MIME" (setq mh-mml-method-default "smime")
- :style radio
- :selected (equal mh-mml-method-default "smime")]
- "--"
- ["Save Method as Default"
- (customize-save-variable 'mh-mml-method-default mh-mml-method-default) t]
- )
- ["Compose Insertion..." mh-compose-insertion t]
- ["Compose Compressed tar (MH)..."
- mh-mh-compose-external-compressed-tar t]
- ["Compose Get File (MH)..." mh-mh-compose-anon-ftp t]
- ["Compose Forward..." mh-compose-forward t]
- ;; The next two will have to be merged. But I also need to make sure the
- ;; user can't mix tags of both types.
- ["Pull in All Compositions (MH)"
- mh-mh-to-mime (mh-mh-directive-present-p)]
- ["Pull in All Compositions (MML)"
- mh-mml-to-mime (mh-mml-tag-present-p)]
- ["Revert to Non-MIME Edit (MH)"
- mh-mh-to-mime-undo (equal mh-compose-insertion 'mh)]
- ["Kill This Draft" mh-fully-kill-draft t]))
-
-\f
-
-;;; MH-Letter Keys
-
-;; If this changes, modify mh-letter-mode-help-messages accordingly, above.
-(define-keymap :keymap mh-letter-mode-map
- "SPC" #'mh-letter-complete-or-space
- "," #'mh-letter-confirm-address
- "C-c ?" #'mh-help
- "C-c C-\\" #'mh-fully-kill-draft ;if no C-q
- "C-c C-^" #'mh-insert-signature ;if no C-s
- "C-c C-c" #'mh-send-letter
- "C-c C-d" #'mh-insert-identity
- "C-c C-e" #'mh-mh-to-mime
- "C-c C-f C-a" #'mh-to-field
- "C-c C-f C-b" #'mh-to-field
- "C-c C-f C-c" #'mh-to-field
- "C-c C-f C-d" #'mh-to-field
- "C-c C-f C-f" #'mh-to-fcc
- "C-c C-f C-l" #'mh-to-field
- "C-c C-f C-m" #'mh-to-field
- "C-c C-f C-r" #'mh-to-field
- "C-c C-f C-s" #'mh-to-field
- "C-c C-f C-t" #'mh-to-field
- "C-c C-f a" #'mh-to-field
- "C-c C-f b" #'mh-to-field
- "C-c C-f c" #'mh-to-field
- "C-c C-f d" #'mh-to-field
- "C-c C-f f" #'mh-to-fcc
- "C-c C-f l" #'mh-to-field
- "C-c C-f m" #'mh-to-field
- "C-c C-f r" #'mh-to-field
- "C-c C-f s" #'mh-to-field
- "C-c C-f t" #'mh-to-field
- "C-c C-i" #'mh-insert-letter
- "C-c C-m C-e" #'mh-mml-secure-message-encrypt
- "C-c C-m C-f" #'mh-compose-forward
- "C-c C-m C-g" #'mh-mh-compose-anon-ftp
- "C-c C-m TAB" #'mh-compose-insertion
- "C-c C-m C-m" #'mh-mml-to-mime
- "C-c C-m C-n" #'mh-mml-unsecure-message
- "C-c C-m C-s" #'mh-mml-secure-message-sign
- "C-c C-m C-t" #'mh-mh-compose-external-compressed-tar
- "C-c C-m C-u" #'mh-mh-to-mime-undo
- "C-c C-m C-x" #'mh-mh-compose-external-type
- "C-c C-m e e" #'mh-mml-secure-message-encrypt
- "C-c C-m e s" #'mh-mml-secure-message-signencrypt
- "C-c C-m f" #'mh-compose-forward
- "C-c C-m g" #'mh-mh-compose-anon-ftp
- "C-c C-m i" #'mh-compose-insertion
- "C-c C-m m" #'mh-mml-to-mime
- "C-c C-m n" #'mh-mml-unsecure-message
- "C-c C-m s e" #'mh-mml-secure-message-signencrypt
- "C-c C-m s s" #'mh-mml-secure-message-sign
- "C-c C-m t" #'mh-mh-compose-external-compressed-tar
- "C-c C-m u" #'mh-mh-to-mime-undo
- "C-c C-m x" #'mh-mh-compose-external-type
- "C-c C-o" #'mh-open-line
- "C-c C-q" #'mh-fully-kill-draft
- "C-c C-s" #'mh-insert-signature
- "C-c C-t" #'mh-letter-toggle-header-field-display
- "C-c C-w" #'mh-check-whom
- "C-c C-y" #'mh-yank-cur-msg
- "C-c M-d" #'mh-insert-auto-fields
- "C-M-i" #'completion-at-point
- "TAB" #'mh-letter-next-header-field-or-indent
- "<backtab>" #'mh-letter-previous-header-field)
-
-;; "C-c /" prefix is used in mh-letter-mode by pgp.el and mailcrypt.el.
-
-\f
-
-;;; MH-Letter Help Messages
-
-;; Group messages logically, more or less.
-(defvar mh-letter-mode-help-messages
- '((nil
- "Send letter: \\[mh-send-letter] "
- "Open line: \\[mh-open-line]\n"
- "Kill letter: \\[mh-fully-kill-draft] "
- "Check recipients: \\[mh-check-whom]\n\n"
- "Insert:\n"
- " Current message: \\[mh-yank-cur-msg]\n"
- " Attachment: \\[mh-compose-insertion]\n"
- " Message to forward: \\[mh-compose-forward]\n"
- " Signature: \\[mh-insert-signature]\n\n"
- "Security:\n"
- " Encrypt message: \\[mh-mml-secure-message-encrypt]\n"
- " Sign message: \\[mh-mml-secure-message-sign]\n"
- " Sign+Encrypt message: \\[mh-mml-secure-message-signencrypt]"))
- "Key binding cheat sheet.
-
-This is an associative array which is used to show the most
-common commands. The key is a prefix char. The value is one or
-more strings which are concatenated together and displayed in the
-minibuffer if ? is pressed after the prefix character. The
-special key nil is used to display the non-prefixed commands.
-
-The substitutions described in `substitute-command-keys' are
-performed as well.")
-
-\f
-
-;;; MH-Letter Font Lock
-
-(defvar mh-letter-font-lock-keywords
- `(,@(mh-show-font-lock-keywords-with-cite)
- (mh-font-lock-field-data
- (1 'mh-letter-header-field prepend t)))
- "Additional expressions to highlight in MH-Letter buffers.")
-
-(defun mh-font-lock-field-data (limit)
- "Find header field region between point and LIMIT."
- (and (< (point) (mh-letter-header-end))
- (< (point) limit)
- (let ((end (min limit (mh-letter-header-end)))
- (point (point))
- data-end data-begin field)
- (end-of-line)
- (setq data-end (if (re-search-forward "^[^ \t]" end t)
- (match-beginning 0)
- end))
- (goto-char (1- data-end))
- (if (not (re-search-backward "\\(^[^ \t][^:]*\\):[ \t]*" nil t))
- (setq data-begin (point-min))
- (setq data-begin (match-end 0))
- (setq field (match-string 1)))
- (setq data-begin (max point data-begin))
- (goto-char (if (equal point data-end) (1+ data-end) data-end))
- (cond ((and field (mh-letter-skipped-header-field-p field))
- (set-match-data nil)
- nil)
- (t (set-match-data
- (list data-begin data-end data-begin data-end))
- t)))))
-
-(defun mh-letter-header-end ()
- "Find the end of the message header.
-This function is to be used only for font locking. It works by
-searching for `mh-mail-header-separator' in the buffer."
- (save-excursion
- (goto-char (point-min))
- (cond ((equal mh-mail-header-separator "") (point-min))
- ((search-forward (format "\n%s\n" mh-mail-header-separator) nil t)
- (line-beginning-position 0))
- (t (point-min)))))
-
-\f
-
-;;; MH-Letter Mode
-
-;; Ensure new buffers won't get this mode if default major-mode is nil.
-(put 'mh-letter-mode 'mode-class 'special)
-
-;;;###mh-autoload
-(define-derived-mode mh-letter-mode mail-mode "MH-Letter"
- "Mode for composing letters in MH-E\\<mh-letter-mode-map>.
-
-When you have finished composing, type \\[mh-send-letter] to send
-the message using the MH mail handling system.
-
-There are two types of tags used by MH-E when composing MIME
-messages: MML and MH. The option `mh-compose-insertion' controls
-what type of tags are inserted by MH-E commands. These tags can
-be converted to MIME body parts by running \\[mh-mh-to-mime] for
-MH-style directives or \\[mh-mml-to-mime] for MML tags.
-
-Options that control this mode can be changed with
-\\[customize-group]; specify the \"mh-compose\" group.
-
-When a message is composed, the hooks `text-mode-hook',
-`mail-mode-hook', and `mh-letter-mode-hook' are run (in that
-order).
-
-\\{mh-letter-mode-map}"
- (mh-find-path)
- (make-local-variable 'mh-send-args)
- (make-local-variable 'mh-annotate-char)
- (make-local-variable 'mh-annotate-field)
- (make-local-variable 'mh-previous-window-config)
- (make-local-variable 'mh-sent-from-folder)
- (make-local-variable 'mh-sent-from-msg)
- (unless mh-letter-tool-bar-map
- (mh-tool-bar-letter-buttons-init))
- (if (boundp 'tool-bar-map)
- (setq-local tool-bar-map mh-letter-tool-bar-map))
- ;; Set the local value of mh-mail-header-separator according to what is
- ;; present in the buffer...
- (setq-local mh-mail-header-separator
- (save-excursion
- (goto-char (mh-mail-header-end))
- (buffer-substring-no-properties (point) (line-end-position))))
- (make-local-variable 'mail-header-separator)
- (setq mail-header-separator mh-mail-header-separator) ;override sendmail.el
- (mh-set-help mh-letter-mode-help-messages)
- (setq buffer-invisibility-spec '((vanish . t) t))
- (setq-local line-move-ignore-invisible t)
-
- ;; Enable undo since a show-mode buffer might have been reused.
- (buffer-enable-undo)
- (make-local-variable 'font-lock-defaults)
- (cond
- ((or (equal mh-highlight-citation-style 'font-lock)
- (equal mh-highlight-citation-style 'gnus))
- ;; Let's use font-lock even if gnus is used in show-mode. The reason
- ;; is that gnus uses static text properties which are not appropriate
- ;; for a buffer that will be edited. So the choice here is either fontify
- ;; the citations and header...
- (setq font-lock-defaults '(mh-letter-font-lock-keywords t)))
- (t
- ;; ...or the header only
- (setq font-lock-defaults '((mh-show-font-lock-keywords) t))))
- ;; Maybe we want to use the existing Mail menu from mail-mode in
- ;; 9.0; in the mean time, let's remove it since the redundancy will
- ;; only produce confusion.
- (define-key mh-letter-mode-map [menu-bar mail] #'undefined)
- (setq fill-column mh-letter-fill-column)
- (add-hook 'completion-at-point-functions
- #'mh-letter-completion-at-point nil 'local)
- ;; If text-mode-hook turned on auto-fill, tune it for messages
- (when auto-fill-function
- (make-local-variable 'auto-fill-function)
- (setq auto-fill-function #'mh-auto-fill-for-letter)))
-
-\f
-
-;;; MH-Letter Commands
-
-;; Alphabetical.
-;; See also mh-comp.el and mh-mime.el.
-
-(defun mh-check-whom ()
- "Verify recipients, showing expansion of any aliases.
-
-This command expands aliases so you can check the actual address(es)
-in the alias. A new buffer named \"*MH-E Recipients*\" is created with
-the output of \"whom\"."
- (interactive)
- (let ((file-name buffer-file-name))
- (save-buffer)
- (message "Checking recipients...")
- (mh-in-show-buffer (mh-recipients-buffer)
- (bury-buffer (current-buffer))
- (erase-buffer)
- (mh-exec-cmd-output "whom" t file-name))
- (message "Checking recipients...done")))
-
-(defun mh-insert-letter (folder message verbatim)
- "Insert a message.
-
-This command prompts you for the FOLDER and MESSAGE number, which
-defaults to the current message in that folder. It then inserts
-the message, indented by `mh-ins-buf-prefix' (\"> \") unless
-`mh-yank-behavior' is set to one of the supercite flavors in
-which case supercite is used to format the message. Certain
-undesirable header fields (see
-`mh-invisible-header-fields-compiled') are removed before
-insertion.
-
-If given a prefix argument VERBATIM, the header is left intact, the
-message is not indented, and \"> \" is not inserted before each line.
-This command leaves the mark before the letter and point after it."
- (interactive
- (let* ((folder
- (mh-prompt-for-folder "Message from" mh-sent-from-folder nil))
- (default
- (if (equal folder mh-sent-from-folder)
- (or mh-sent-from-msg (nth 0 (mh-translate-range folder "cur")))
- (nth 0 (mh-translate-range folder "cur"))))
- (message
- (read-string (format-prompt "Message number" default)
- nil nil
- (if (numberp default)
- (int-to-string default)
- default))))
- (list folder message current-prefix-arg)))
- (if (equal message "")
- (error "No message number given"))
- (save-restriction
- (narrow-to-region (point) (point))
- (let ((start (point-min)))
- (insert-file-contents
- (expand-file-name message (mh-expand-file-name folder)))
- (when (not verbatim)
- (mh-clean-msg-header start mh-invisible-header-fields-compiled nil)
- (goto-char (point-max)) ;Needed for sc-cite-original
- (push-mark) ;Needed for sc-cite-original
- (goto-char (point-min)) ;Needed for sc-cite-original
- (mh-insert-prefix-string mh-ins-buf-prefix)))))
-
-;;;###mh-autoload
-(defun mh-insert-signature (&optional file)
- "Insert signature in message.
-
-This command inserts your signature at the current cursor location.
-
-By default, the text of your signature is taken from the file
-\"~/.signature\". You can read from other sources by changing the
-option `mh-signature-file-name'.
-
-A signature separator (\"-- \") will be added if the signature block
-does not contain one and `mh-signature-separator-flag' is on.
-
-The hook `mh-insert-signature-hook' is run after the signature is
-inserted. Hook functions may access the actual name of the file or the
-function used to insert the signature with `mh-signature-file-name'.
-
-The signature can also be inserted using Identities (see
-`mh-identity-list').
-
-In a program, you can pass in a signature FILE."
- (interactive)
- (save-excursion
- (insert "\n")
- (let ((mh-signature-file-name (or file mh-signature-file-name))
- (mh-mh-p (mh-mh-directive-present-p))
- (mh-mml-p (mh-mml-tag-present-p)))
- (save-restriction
- (narrow-to-region (point) (point))
- (cond
- ((mh-file-is-vcard-p mh-signature-file-name)
- (if (equal mh-compose-insertion 'mml)
- (insert "<#part type=\"text/x-vcard\" filename=\""
- mh-signature-file-name
- "\" disposition=inline description=VCard>\n<#/part>")
- (insert "#text/x-vcard; name=\""
- (file-name-nondirectory mh-signature-file-name)
- "\" [VCard] " (expand-file-name mh-signature-file-name))))
- (t
- (cond
- (mh-mh-p
- (insert "#\n" "Content-Description: Signature\n"))
- (mh-mml-p
- (mml-insert-tag 'part 'type "text/plain" 'disposition "inline"
- 'description "Signature")))
- (cond ((null mh-signature-file-name))
- ((and (stringp mh-signature-file-name)
- (file-readable-p mh-signature-file-name))
- (insert-file-contents mh-signature-file-name))
- ((functionp mh-signature-file-name)
- (funcall mh-signature-file-name)))))
- (save-restriction
- (widen)
- (run-hooks 'mh-insert-signature-hook))
- (goto-char (point-min))
- (when (and (not (mh-file-is-vcard-p mh-signature-file-name))
- mh-signature-separator-flag
- (> (point-max) (point-min))
- (not (mh-signature-separator-p)))
- (cond (mh-mh-p
- (forward-line 2))
- (mh-mml-p
- (forward-line 1)))
- (insert mh-signature-separator))
- (if (not (> (point-max) (point-min)))
- (message "No signature found")))))
- (force-mode-line-update))
-
-(defun mh-letter-completion-at-point ()
- "Return the completion data at point for MH letters.
-This provides alias and folder completion in header fields according to
-`mh-letter-complete-function-alist' and falls back on
-`mh-letter-complete-function-alist' elsewhere."
- (let ((func (and (mh-in-header-p)
- (cdr (assoc (mh-letter-header-field-at-point)
- mh-letter-complete-function-alist)))))
- (if func
- (or (funcall func) #'ignore)
- mh-letter-complete-function)))
-
-(define-obsolete-function-alias 'mh-letter-complete
- #'completion-at-point "29.1")
-
-(defun mh-letter-complete-or-space (arg)
- "Perform completion or insert space.
-
-Turn on the option `mh-compose-space-does-completion-flag' to use
-this command to perform completion in the header. Otherwise, a
-space is inserted; use a prefix argument ARG to specify more than
-one space."
- (interactive "p")
- (let ((end-of-prev (save-excursion
- (goto-char (mh-beginning-of-word))
- (mh-beginning-of-word -1))))
- (cond ((not mh-compose-space-does-completion-flag)
- (self-insert-command arg))
- ;; FIXME: This > test is redundant now that all the completion
- ;; functions do it anyway.
- ((> (point) end-of-prev) (self-insert-command arg))
- ((let ((mh-letter-complete-function nil))
- (mh-letter-completion-at-point))
- (completion-at-point))
- (t (self-insert-command arg)))))
-
-(defun mh-letter-confirm-address ()
- "Flash alias expansion.
-
-Addresses are separated by a comma; when you press the comma,
-this command flashes the alias expansion in the minibuffer if
-`mh-alias-flash-on-comma' is turned on."
- (interactive)
- (cond ((not (mh-in-header-p)) (self-insert-command 1))
- ((eq (cdr (assoc (mh-letter-header-field-at-point)
- mh-letter-complete-function-alist))
- 'mh-alias-letter-expand-alias)
- (mh-alias-reload-maybe)
- (mh-alias-minibuffer-confirm-address))
- (t (self-insert-command 1))))
-
-(defun mh-letter-next-header-field-or-indent (arg)
- "Cycle to next field.
-
-Within the header of the message, this command moves between
-fields that are highlighted with the face
-`mh-letter-header-field', skipping those fields listed in
-`mh-compose-skipped-header-fields'. After the last field, this
-command then moves point to the message body before cycling back
-to the first field. If point is already past the first line of
-the message body, then this command indents by calling
-`indent-relative' with the given prefix argument ARG."
- (interactive "P")
- (let ((header-end (save-excursion
- (goto-char (mh-mail-header-end))
- (forward-line)
- (point))))
- (if (> (point) header-end)
- (indent-relative arg)
- (mh-letter-next-header-field))))
-
-(defun mh-letter-previous-header-field ()
- "Cycle to the previous header field.
-
-This command moves backwards between the fields and cycles to the
-body of the message after the first field. Unlike the command
-\\[mh-letter-next-header-field-or-indent], it will always take
-point to the last field from anywhere in the body."
- (interactive)
- (let ((header-end (mh-mail-header-end)))
- (if (>= (point) header-end)
- (goto-char header-end)
- (mh-header-field-beginning))
- (cond ((re-search-backward mh-letter-header-field-regexp nil t)
- (if (mh-letter-skipped-header-field-p (match-string 1))
- (mh-letter-previous-header-field)
- (goto-char (match-end 0))
- (mh-letter-skip-leading-whitespace-in-header-field)))
- (t (goto-char header-end)
- (forward-line)))))
-
-(defun mh-open-line ()
- "Insert a newline and leave point before it.
-
-This command is similar to the command \\[open-line] in that it
-inserts a newline after point. It differs in that it also inserts
-the right number of quoting characters and spaces so that the
-next line begins in the same column as it was. This is useful
-when breaking up paragraphs in replies."
- (interactive)
- (let ((column (current-column))
- (prefix (mh-current-fill-prefix)))
- (if (> (length prefix) column)
- (message "Sorry, point seems to be within the line prefix")
- (newline 2)
- (insert prefix)
- (while (> column (current-column))
- (insert " "))
- (forward-line -1))))
-
-(defun mh-to-fcc (&optional folder)
- "Move to \"Fcc:\" header field.
-
-This command will prompt you for the FOLDER name in which to file
-a copy of the draft."
- (interactive (list (mh-prompt-for-folder
- "Fcc"
- (or (and mh-default-folder-for-message-function
- (save-excursion
- (goto-char (point-min))
- (funcall
- mh-default-folder-for-message-function)))
- "")
- t)))
- (let ((last-input-event ?\C-f))
- (expand-abbrev)
- (save-excursion
- (mh-to-field)
- (insert (if (mh-folder-name-p folder)
- (substring folder 1)
- folder)))))
-
-(defvar mh-to-field-choices '(("a" . "Mail-Reply-To:")
- ("b" . "Bcc:")
- ("c" . "Cc:")
- ("d" . "Dcc:")
- ("f" . "Fcc:")
- ("l" . "Mail-Followup-To:")
- ("m" . "From:")
- ("r" . "Reply-To:")
- ("s" . "Subject:")
- ("t" . "To:"))
- "Alist of (final-character . field-name) choices for `mh-to-field'.")
-
-(defun mh-to-field ()
- "Move to specified header field.
-
-The field is indicated by the previous keystroke (the last
-keystroke of the command) according to the list in the variable
-`mh-to-field-choices'.
-Create the field if it does not exist.
-Set the mark to point before moving."
- (interactive)
- (expand-abbrev)
- (let ((target (cdr (or (assoc (char-to-string (logior last-input-event ?`))
- mh-to-field-choices)
- ;; also look for a char for version 4 compat
- (assoc (logior last-input-event ?`)
- mh-to-field-choices))))
- (case-fold-search t))
- (push-mark)
- (cond ((mh-position-on-field target)
- (let ((eol (point)))
- (skip-chars-backward " \t")
- (delete-region (point) eol))
- (if (and (not (eq (logior last-input-event ?`) ?s))
- (save-excursion
- (backward-char 1)
- (not (looking-at "[:,]"))))
- (insert ", ")
- (insert " ")))
- (t
- (if (mh-position-on-field "To:")
- (forward-line 1))
- (insert (format "%s \n" target))
- (backward-char 1)))))
-
-;;;###mh-autoload
-(defun mh-yank-cur-msg ()
- "Insert the current message into the draft buffer.
-
-It is often useful to insert a snippet of text from a letter that
-someone mailed to provide some context for your reply. This
-command does this by adding an attribution, yanking a portion of
-text from the message to which you're replying, and inserting
-`mh-ins-buf-prefix' (`> ') before each line.
-
-The attribution consists of the sender's name and email address
-followed by the content of the option
-`mh-extract-from-attribution-verb'.
-
-You can also turn on the option
-`mh-delete-yanked-msg-window-flag' to delete the window
-containing the original message after yanking it to make more
-room on your screen for your reply.
-
-You can control how the message to which you are replying is
-yanked into your reply using `mh-yank-behavior'.
-
-If this isn't enough, you can gain full control over the
-appearance of the included text by setting `mail-citation-hook'
-to a function that modifies it. For example, if you set this hook
-to `trivial-cite' (which is NOT part of Emacs), set
-`mh-yank-behavior' to \"Body and Header\" (see URL
-`http://shasta.cs.uiuc.edu/~lrclause/tc.html').
-
-Note that if `mail-citation-hook' is set, `mh-ins-buf-prefix' is
-not inserted. If the option `mh-yank-behavior' is set to one of
-the supercite flavors, the hook `mail-citation-hook' is ignored
-and `mh-ins-buf-prefix' is not inserted."
- (interactive)
- (let ((show-buffer))
- (if (and mh-sent-from-folder
- (with-current-buffer mh-sent-from-folder mh-show-buffer)
- (setq show-buffer (with-current-buffer mh-sent-from-folder
- (get-buffer mh-show-buffer)))
- mh-sent-from-msg)
- (let ((to-point (point))
- (to-buffer (current-buffer)))
- (if mh-delete-yanked-msg-window-flag
- (with-current-buffer mh-sent-from-folder
- (delete-windows-on show-buffer)))
- ;; Find displayed message
- (with-current-buffer show-buffer
- (let* ((from-attr (mh-extract-from-attribution))
- (yank-region mark-active)
- (mh-ins-str
- (cond ((and yank-region
- (or (eq 'supercite mh-yank-behavior)
- (eq 'autosupercite mh-yank-behavior)
- (eq t mh-yank-behavior)))
- ;; supercite needs the full header
- (concat
- (buffer-substring (point-min) (mh-mail-header-end))
- "\n"
- (buffer-substring (region-beginning) (region-end))))
- (yank-region
- (buffer-substring (region-beginning) (region-end)))
- ((or (eq 'body mh-yank-behavior)
- (eq 'attribution mh-yank-behavior)
- (eq 'autoattrib mh-yank-behavior))
- (buffer-substring
- (save-excursion
- (goto-char (point-min))
- (mh-goto-header-end 1)
- (point))
- (point-max)))
- ((or (eq 'supercite mh-yank-behavior)
- (eq 'autosupercite mh-yank-behavior)
- (eq t mh-yank-behavior))
- (buffer-substring (point-min) (point-max)))
- (t
- (buffer-substring (point) (point-max))))))
- (with-current-buffer to-buffer
- (save-restriction
- (narrow-to-region to-point to-point)
- (insert (mh-filter-out-non-text mh-ins-str))
- (goto-char (point-max)) ;Needed for sc-cite-original
- (push-mark) ;Needed for sc-cite-original
- (goto-char (point-min)) ;Needed for sc-cite-original
- (mh-insert-prefix-string mh-ins-buf-prefix)
- (when (or (eq 'attribution mh-yank-behavior)
- (eq 'autoattrib mh-yank-behavior))
- (insert from-attr)
- (mh-identity-insert-attribution-verb nil)
- (insert "\n\n"))
- ;; If the user has selected a region, he has already "edited" the
- ;; text, so leave the cursor at the end of the yanked text. In
- ;; either case, leave a mark at the opposite end of the included
- ;; text to make it easy to jump or delete to the other end of the
- ;; text.
- (push-mark)
- (goto-char (point-max))
- (if (null yank-region)
- (mh-exchange-point-and-mark-preserving-active-mark)))))))
- (error "There is no current message"))))
-
-\f
-
-;;; Support Routines
-
-(defun mh-auto-fill-for-letter ()
- "Perform auto-fill for message.
-Header is treated specially by inserting a tab before continuation
-lines."
- (if (mh-in-header-p)
- (let ((fill-prefix "\t"))
- (do-auto-fill))
- (do-auto-fill)))
-
-(defun mh-filter-out-non-text (string)
- "Return STRING but without adornments such as MIME buttons and smileys."
- (with-temp-buffer
- ;; Insert the string to filter
- (insert string)
- (goto-char (point-min))
-
- ;; Remove the MIME buttons
- (let ((can-move-forward t)
- (in-button nil))
- (while can-move-forward
- (cond ((and (not (get-text-property (point) 'mh-data))
- in-button)
- (delete-region (1- (point)) (point))
- (setq in-button nil))
- ((get-text-property (point) 'mh-data)
- (delete-region (point)
- (save-excursion (forward-line) (point)))
- (setq in-button t))
- (t (setq can-move-forward (= (forward-line) 0))))))
-
- ;; Return the contents without properties... This gets rid of emphasis
- ;; and smileys
- (buffer-substring-no-properties (point-min) (point-max))))
-
-(defun mh-current-fill-prefix ()
- "Return the `fill-prefix' on the current line as a string."
- (save-excursion
- (beginning-of-line)
- ;; This assumes that the major-mode sets up adaptive-fill-regexp
- ;; correctly such as mh-letter-mode or sendmail.el's mail-mode. But
- ;; perhaps I should use the variable and simply inserts its value here,
- ;; and set it locally in a let scope. --psg
- (if (re-search-forward adaptive-fill-regexp nil t)
- (match-string 0)
- "")))
-
-;;;###mh-autoload
-(defun mh-letter-next-header-field ()
- "Cycle to the next header field.
-If we are at the last header field go to the start of the message
-body."
- (let ((header-end (mh-mail-header-end)))
- (cond ((>= (point) header-end) (goto-char (point-min)))
- ((< (point) (progn
- (beginning-of-line)
- (re-search-forward mh-letter-header-field-regexp
- (line-end-position) t)
- (point)))
- (beginning-of-line))
- (t (end-of-line)))
- (cond ((re-search-forward mh-letter-header-field-regexp header-end t)
- (if (mh-letter-skipped-header-field-p (match-string 1))
- (mh-letter-next-header-field)
- (mh-letter-skip-leading-whitespace-in-header-field)))
- (t (goto-char header-end)
- (forward-line)))))
-
-;;;###mh-autoload
-(defun mh-position-on-field (field &optional _ignored)
- "Move to the end of the FIELD in the header.
-Move to end of entire header if FIELD not found.
-Returns non-nil if FIELD was found.
-The optional second arg is for pre-version 4 compatibility and is
-IGNORED."
- (cond ((mh-goto-header-field field)
- (mh-header-field-end)
- t)
- ((mh-goto-header-end 0)
- nil)))
-
-(defun mh-letter-header-field-at-point ()
- "Return the header field name at point.
-A symbol is returned whose name is the string obtained by
-downcasing the field name."
- (save-excursion
- (end-of-line)
- (and (re-search-backward mh-letter-header-field-regexp nil t)
- (intern (downcase (match-string 1))))))
-
-(defun mh-folder-expand-at-point ()
- "Do folder name completion in Fcc header field."
- (let* ((beg (mh-beginning-of-word))
- (end (save-excursion
- (goto-char beg)
- (mh-beginning-of-word -1))))
- (when (>= end (point))
- (list beg (if (fboundp 'completion-at-point) end (point))
- #'mh-folder-completion-function))))
-
-;;;###mh-autoload
-(defun mh-complete-word (word choices begin end)
- "Complete WORD from CHOICES.
-Any match found replaces the text from BEGIN to END."
- (let ((completion (try-completion word choices))
- (completions-buffer "*Completions*"))
- (cond ((eq completion t)
- (ignore-errors
- (kill-buffer completions-buffer))
- (message "Completed: %s" word))
- ((null completion)
- (ignore-errors
- (kill-buffer completions-buffer))
- (message "No completion for %s" word))
- ((stringp completion)
- (if (equal word completion)
- (with-output-to-temp-buffer completions-buffer
- (display-completion-list
- (completion-hilit-commonality
- (all-completions word choices)
- ;; The `common-substring' arg only works if it's a prefix.
- (unless (and (functionp choices)
- (let ((bounds
- (funcall choices
- word nil '(boundaries . ""))))
- (and (eq 'boundaries (car-safe bounds))
- (< 0 (cadr bounds)))))
- word))))
- (ignore-errors
- (kill-buffer completions-buffer))
- (delete-region begin end)
- (insert completion))))))
-
-(defun mh-file-is-vcard-p (file)
- "Return t if FILE is a .vcf vcard."
- (let ((case-fold-search t))
- (and (stringp file)
- (file-exists-p file)
- (or (and (not (mh-have-file-command))
- (not (null (string-match "\\.vcf$" file))))
- (string-equal "text/x-vcard" (mh-file-mime-type file))))))
-
-;;;###mh-autoload
-(defun mh-letter-toggle-header-field-display-button (event)
- "Toggle header field display at location of EVENT.
-This function does the same thing as
-`mh-letter-toggle-header-field-display' except that it is
-callable from a mouse button."
- (interactive "e")
- (mh-do-at-event-location event
- (mh-letter-toggle-header-field-display nil)))
-
-(defun mh-extract-from-attribution ()
- "Extract phrase or comment from From header field."
- (save-excursion
- (if (not (mh-goto-header-field "From: "))
- nil
- (skip-chars-forward " ")
- (cond
- ((looking-at "\"\\([^\"\n]+\\)\" \\(<.+>\\)")
- (format "%s %s " (match-string 1)(match-string 2)))
- ((looking-at "\\([^<\n]+<.+>\\)$")
- (format "%s " (match-string 1)))
- ((looking-at "\\([^ ]+@[^ ]+\\) +(\\(.+\\))$")
- (format "%s <%s> " (match-string 2)(match-string 1)))
- ((looking-at " *\\(.+\\)$")
- (format "%s " (match-string 1)))))))
-
-(defun mh-insert-prefix-string (mh-ins-string)
- "Insert prefix string before each line in buffer.
-The inserted letter is cited using `sc-cite-original' if
-`mh-yank-behavior' is one of `supercite' or `autosupercite'.
-Otherwise, simply insert MH-INS-STRING before each line."
- (goto-char (point-min))
- (cond ((or (eq mh-yank-behavior 'supercite)
- (eq mh-yank-behavior 'autosupercite))
- (sc-cite-original))
- (mail-citation-hook
- (run-hooks 'mail-citation-hook))
- (t
- (or (bolp) (forward-line 1))
- (while (< (point) (point-max))
- (insert mh-ins-string)
- (forward-line 1))
- (goto-char (point-min))))) ;leave point like sc-cite-original
-
-(provide 'mh-letter)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-letter.el ends here
+++ /dev/null
-;;; mh-limit.el --- MH-E display limits -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2001-2003, 2006-2024 Free Software Foundation, Inc.
-
-;; Author: Peter S. Galbraith <psg@debian.org>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; "Poor man's threading" by psg.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-(autoload 'message-fetch-field "message")
-
-\f
-
-;;; MH-Folder Commands
-
-;; Alphabetical.
-
-;;;###mh-autoload
-(defun mh-delete-subject ()
- "Delete messages with same subject\\<mh-folder-mode-map>.
-
-To delete messages faster, you can use this command to delete all
-the messages with the same subject as the current message. This
-command puts these messages in a sequence named \"subject\". You
-can undo this action by using \\[mh-undo] with a prefix argument
-and then specifying the \"subject\" sequence."
- (interactive)
- (let ((count (mh-subject-to-sequence nil)))
- (cond
- ((not count) ; No subject line, delete msg anyway
- (mh-delete-msg (mh-get-msg-num t)))
- ((= 0 count) ; No other msgs, delete msg anyway.
- (message "No other messages with same Subject following this one")
- (mh-delete-msg (mh-get-msg-num t)))
- (t ; We have a subject sequence.
- (message "Marked %d messages for deletion" count)
- (mh-delete-msg 'subject)))))
-
-;;;###mh-autoload
-(defun mh-delete-subject-or-thread ()
- "Delete messages with same subject or thread\\<mh-folder-mode-map>.
-
-To delete messages faster, you can use this command to delete all
-the messages with the same subject as the current message. This
-command puts these messages in a sequence named \"subject\". You
-can undo this action by using \\[mh-undo] with a prefix argument
-and then specifying the \"subject\" sequence.
-
-However, if the buffer is displaying a threaded view of the
-folder then this command behaves like \\[mh-thread-delete]."
- (interactive)
- (if (memq 'unthread mh-view-ops)
- (mh-thread-delete)
- (mh-delete-subject)))
-
-;;;###mh-autoload
-(defun mh-narrow-to-cc (&optional pick-expr)
- "Limit to messages with the same \"Cc:\" field.
-With a prefix argument, edit PICK-EXPR.
-
-Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
- (interactive
- (list (mh-edit-pick-expr
- (mh-quote-pick-expr (mh-current-message-header-field 'cc)))))
- (mh-narrow-to-header-field 'cc pick-expr))
-
-;;;###mh-autoload
-(defun mh-narrow-to-from (&optional pick-expr)
- "Limit to messages with the same \"From:\" field.
-With a prefix argument, edit PICK-EXPR.
-
-Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
- (interactive
- (list (mh-edit-pick-expr
- (mh-quote-pick-expr (mh-current-message-header-field 'from)))))
- (mh-narrow-to-header-field 'from pick-expr))
-
-;;;###mh-autoload
-(defun mh-narrow-to-range (range)
- "Limit to RANGE.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use.
-
-Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
- (interactive (list (mh-interactive-range "Narrow to")))
- (when (assoc 'range mh-seq-list) (mh-delete-seq 'range))
- (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range)
- (mh-narrow-to-seq 'range))
-
-;;;###mh-autoload
-(defun mh-narrow-to-subject (&optional pick-expr)
- "Limit to messages with same subject.
-With a prefix argument, edit PICK-EXPR.
-The string Re: is removed from the search.
-
-Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
- (interactive
- (list (mh-edit-pick-expr
- (mh-quote-pick-expr (mh-current-message-header-field 'subject)))))
- (setq pick-expr
- (let ((case-fold-search t))
- (cl-loop for s in pick-expr
- collect (replace-regexp-in-string "re: *" "" s))))
- (mh-narrow-to-header-field 'subject pick-expr))
-
-;;;###mh-autoload
-(defun mh-narrow-to-to (&optional pick-expr)
- "Limit to messages with the same \"To:\" field.
-With a prefix argument, edit PICK-EXPR.
-
-Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
- (interactive
- (list (mh-edit-pick-expr
- (mh-quote-pick-expr (mh-current-message-header-field 'to)))))
- (mh-narrow-to-header-field 'to pick-expr))
-
-\f
-
-;;; Support Routines
-
-(defun mh-subject-to-sequence (all)
- "Put all following messages with same subject in sequence `subject'.
-If arg ALL is t, move to beginning of folder buffer to collect all
-messages.
-If arg ALL is nil, collect only messages from current one on forward.
-
-Return number of messages put in the sequence:
-
- nil -> there was no subject line.
-
- 0 -> there were no later messages with the same
- subject (sequence not made)
-
- >1 -> the total number of messages including current one."
- (if (memq 'unthread mh-view-ops)
- (mh-subject-to-sequence-threaded all)
- (mh-subject-to-sequence-unthreaded all)))
-
-(defun mh-subject-to-sequence-threaded (all)
- "Put all messages with the same subject in the `subject' sequence.
-
-This function works when the folder is threaded. In this
-situation the subject could get truncated and so the normal
-matching doesn't work.
-
-The parameter ALL is non-nil then all the messages in the buffer
-are considered, otherwise only the messages after the current one
-are taken into account."
- (let* ((cur (mh-get-msg-num nil))
- (subject (mh-thread-find-msg-subject cur))
- region msgs)
- (if (null subject)
- (and (message "No subject line") nil)
- (setq region (cons (if all (point-min) (point)) (point-max)))
- (mh-iterate-on-range msg region
- (when (eq (mh-thread-find-msg-subject msg) subject)
- (push msg msgs)))
- (setq msgs (sort msgs #'mh-lessp))
- (if (null msgs)
- 0
- (when (assoc 'subject mh-seq-list)
- (mh-delete-seq 'subject))
- (mh-add-msgs-to-seq msgs 'subject)
- (length msgs)))))
-
-(defvar mh-limit-max-subject-size 41
- "Maximum size of the subject part.
-It would be desirable to avoid hard-coding this.")
-
-(defun mh-subject-to-sequence-unthreaded (all)
- "Put all following messages with same subject in sequence `subject'.
-
-This function only works with an unthreaded folder. If arg ALL is
-t, move to beginning of folder buffer to collect all messages. If
-arg ALL is nil, collect only messages from current one on
-forward.
-
-Return number of messages put in the sequence:
-
- nil -> there was no subject line.
- 0 -> there were no later messages with the same
- subject (sequence not made)
- >1 -> the total number of messages including current one."
- (if (not (eq major-mode 'mh-folder-mode))
- (error "Not in a folder buffer"))
- (save-excursion
- (beginning-of-line)
- (if (or (not (looking-at mh-scan-subject-regexp))
- (not (match-string 3))
- (string-equal "" (match-string 3)))
- (progn (message "No subject line")
- nil)
- (let ((subject (match-string-no-properties 3))
- (list))
- (if (> (length subject) mh-limit-max-subject-size)
- (setq subject (substring subject 0 mh-limit-max-subject-size)))
- (save-excursion
- (if all
- (goto-char (point-min)))
- (while (re-search-forward mh-scan-subject-regexp nil t)
- (let ((this-subject (match-string-no-properties 3)))
- (if (> (length this-subject) mh-limit-max-subject-size)
- (setq this-subject (substring this-subject
- 0 mh-limit-max-subject-size)))
- (if (string-equal this-subject subject)
- (setq list (cons (mh-get-msg-num t) list))))))
- (cond
- (list
- ;; If we created a new sequence, add the initial message to it too.
- (if (not (member (mh-get-msg-num t) list))
- (setq list (cons (mh-get-msg-num t) list)))
- (if (assoc 'subject mh-seq-list) (mh-delete-seq 'subject))
- ;; sort the result into a sequence
- (let ((sorted-list (sort (copy-sequence list) #'mh-lessp)))
- (while sorted-list
- (mh-add-msgs-to-seq (car sorted-list) 'subject nil)
- (setq sorted-list (cdr sorted-list)))
- (safe-length list)))
- (t
- 0))))))
-
-(defun mh-edit-pick-expr (default)
- "With prefix arg edit a pick expression.
-If no prefix arg is given, then return DEFAULT."
- (let ((default-string (cl-loop for x in default concat (format " %s" x))))
- (if (or current-prefix-arg (equal default-string ""))
- (mh-pick-args-list (read-string "Pick expression: "
- default-string))
- default)))
-
-(defun mh-pick-args-list (s)
- "Form list by grouping elements in string S suitable for pick arguments.
-For example, the string \"-subject a b c -from Joe User
-<user@domain.com>\" is converted to (\"-subject\" \"a b c\"
-\"-from\" \"Joe User <user@domain.com>\""
- (let ((full-list (split-string s))
- current-arg collection arg-list)
- (while full-list
- (setq current-arg (car full-list))
- (if (null (string-match "^-" current-arg))
- (setq collection
- (if (null collection)
- current-arg
- (format "%s %s" collection current-arg)))
- (when collection
- (setq arg-list (append arg-list (list collection)))
- (setq collection nil))
- (setq arg-list (append arg-list (list current-arg))))
- (setq full-list (cdr full-list)))
- (when collection
- (setq arg-list (append arg-list (list collection))))
- arg-list))
-
-(defun mh-current-message-header-field (header-field)
- "Return a pick regexp to match HEADER-FIELD of the message at point."
- (let ((num (mh-get-msg-num nil)))
- (when num
- (let ((folder mh-current-folder))
- (with-temp-buffer
- (insert-file-contents-literally (mh-msg-filename num folder))
- (goto-char (point-min))
- (when (search-forward "\n\n" nil t)
- (narrow-to-region (point-min) (point)))
- (let* ((field (or (message-fetch-field (format "%s" header-field))
- ""))
- (field-option (format "-%s" header-field))
- (patterns (cl-loop for x in (split-string field "[ ]*,[ ]*")
- unless (equal x "")
- collect (if (string-match "<\\(.*@.*\\)>" x)
- (match-string 1 x)
- x))))
- (when patterns
- (cl-loop with accum = `(,field-option ,(car patterns))
- for e in (cdr patterns)
- do (setq accum `(,field-option ,e "-or" ,@accum))
- finally return accum))))))))
-
-(defun mh-narrow-to-header-field (_header-field pick-expr)
- "Limit to messages whose HEADER-FIELD match PICK-EXPR.
-The MH command pick is used to do the match."
- (let ((folder mh-current-folder)
- (original (mh-coalesce-msg-list
- (mh-range-to-msg-list (cons (point-min) (point-max)))))
- (msg-list ()))
- (with-temp-buffer
- (apply #'mh-exec-cmd-output "pick" nil folder
- (append original (list "-list") pick-expr))
- (goto-char (point-min))
- (while (not (eobp))
- (let ((num (ignore-errors
- (string-to-number
- (buffer-substring (point) (line-end-position))))))
- (when num (push num msg-list))
- (forward-line))))
- (if (null msg-list)
- (message "No matches")
- (when (assoc 'header mh-seq-list) (mh-delete-seq 'header))
- (mh-add-msgs-to-seq msg-list 'header)
- (mh-narrow-to-seq 'header))))
-
-(provide 'mh-limit)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-limit.el ends here
+++ /dev/null
-;;; mh-mime.el --- MH-E MIME support -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Message composition of MIME message is done with either MH-style
-;; directives for mhn or mhbuild (MH 6.8 or later) or MML (MIME Meta
-;; Language) tags.
-
-;; TODO:
-;; Paragraph code should not fill # lines if MIME enabled.
-;; Implement mh-auto-mh-to-mime (if non-nil, \\[mh-send-letter]
-;; invokes mh-mh-to-mime automatically before sending.)
-;; Actually, instead of mh-auto-mh-to-mime,
-;; should read automhnproc from profile.
-;; MIME option to mh-forward command to move to content-description
-;; insertion point.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-acros)
-(require 'mh-gnus) ;needed because mh-gnus.el not compiled
-
-(require 'font-lock)
-(require 'gnus-util)
-(require 'mailcap)
-(require 'mm-decode)
-(require 'mm-view)
-(require 'mml)
-
-(autoload 'article-emphasize "gnus-art")
-(autoload 'gnus-eval-format "gnus-spec")
-(autoload 'mail-content-type-get "mail-parse")
-(autoload 'mail-decode-encoded-word-region "mail-parse")
-(autoload 'mail-decode-encoded-word-string "mail-parse")
-(autoload 'mail-header-parse-content-type "mail-parse")
-(autoload 'mail-header-strip-cte "mail-parse")
-(autoload 'mail-strip-quoted-names "mail-utils")
-(autoload 'message-options-get "message")
-(autoload 'message-options-set "message")
-(autoload 'message-options-set-recipient "message")
-(autoload 'mm-decode-body "mm-bodies")
-(autoload 'mm-uu-dissect "mm-uu")
-(autoload 'mml-unsecure-message "mml-sec")
-(autoload 'widget-convert-button "wid-edit")
-
-\f
-
-;;; Variables
-
-;; This has to be a macro, since we do: (setf (mh-buffer-data) ...)
-;;;###mh-autoload
-(defmacro mh-buffer-data ()
- "Convenience macro to get the MIME data structures of the current buffer."
- '(gethash (current-buffer) mh-globals-hash))
-
-;; Structure to keep track of MIME handles on a per buffer basis.
-(cl-defstruct (mh-buffer-data (:conc-name mh-mime-)
- (:constructor mh-make-buffer-data))
- (handles ()) ; List of MIME handles
- (handles-cache (make-hash-table)) ; Cache to avoid multiple decodes of
- ; nested messages
- (parts-count 0) ; The button number is generated from
- ; this number
- (part-index-hash (make-hash-table))) ; Avoid incrementing the part number
- ; for nested messages
-
-(defvar mh-mm-inline-media-tests
- `(("image/jpeg"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'jpeg handle)))
- ("image/png"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'png handle)))
- ("image/gif"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'gif handle)))
- ("image/tiff"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'tiff handle)) )
- ("image/xbm"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'xbm handle)))
- ("image/x-xbitmap"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'xbm handle)))
- ("image/xpm"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'xpm handle)))
- ("image/x-pixmap"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'xpm handle)))
- ("image/bmp"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'bmp handle)))
- ("image/x-portable-bitmap"
- mm-inline-image
- (lambda (handle)
- (mm-valid-and-fit-image-p 'pbm handle)))
- ("text/plain" mm-inline-text identity)
- ("text/enriched" mm-inline-text identity)
- ("text/richtext" mm-inline-text identity)
- ("text/x-patch" mm-display-patch-inline
- (lambda (handle)
- (locate-library "diff-mode")))
- ("application/emacs-lisp" mm-display-elisp-inline identity)
- ("application/x-emacs-lisp" mm-display-elisp-inline identity)
- ("text/html"
- mm-inline-text-html
- (lambda (handle)
- mm-text-html-renderer))
- ("text/x-vcard"
- mm-inline-text-vcard
- (lambda (handle)
- (or (featurep 'vcard)
- (locate-library "vcard"))))
- ("message/delivery-status" mm-inline-text identity)
- ("message/rfc822" mh-mm-inline-message identity)
- ;;("message/partial" mm-inline-partial identity)
- ;;("message/external-body" mm-inline-external-body identity)
- ("text/.*" mm-inline-text identity)
- ("audio/wav" mm-inline-audio
- (lambda (handle)
- (and (or (featurep 'nas-sound) (featurep 'native-sound))
- (device-sound-enabled-p))))
- ("audio/au"
- mm-inline-audio
- (lambda (handle)
- (and (or (featurep 'nas-sound) (featurep 'native-sound))
- (device-sound-enabled-p))))
- ("application/pgp-signature" ignore identity)
- ("application/x-pkcs7-signature" ignore identity)
- ("application/pkcs7-signature" ignore identity)
- ("application/x-pkcs7-mime" ignore identity)
- ("application/pkcs7-mime" ignore identity)
- ("multipart/alternative" ignore identity)
- ("multipart/mixed" ignore identity)
- ("multipart/related" ignore identity)
- ;; Disable audio and image
- ("audio/.*" ignore ignore)
- ("image/.*" ignore ignore)
- ;; Default to displaying as text
- (".*" mm-inline-text mm-readable-p))
- "Alist of media types/tests saying whether types can be displayed inline.")
-
-(defvar mh-mime-save-parts-directory nil
- "Default to use for `mh-mime-save-parts-default-directory'.
-Set from last use.")
-
-;; Copied from gnus-art.el (should be checked for other cool things that can
-;; be added to the buttons)
-(defvar mh-mime-button-commands
- '((mh-press-button "\r" "Toggle Display")))
-(defvar mh-mime-button-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] #'mh-push-button)
- (dolist (c mh-mime-button-commands)
- (define-key map (cadr c) (car c)))
- map))
-(defvar mh-mime-button-line-format-alist
- '((?T long-type ?s)
- (?d description ?s)
- (?p index ?s)
- (?e dots ?s)))
-(defvar mh-mime-button-line-format "%{%([%p. %d%T]%)%}%e\n")
-(defvar mh-mime-security-button-pressed nil)
-(defvar mh-mime-security-button-line-format "%{%([[%t:%i]%D]%)%}\n")
-(defvar mh-mime-security-button-end-line-format "%{%([[End of %t]%D]%)%}\n")
-(defvar mh-mime-security-button-line-format-alist
- '((?t type ?s)
- (?i info ?s)
- (?d details ?s)
- (?D pressed-details ?s)))
-(defvar mh-mime-security-button-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" #'mh-press-button)
- (define-key map [mouse-2] #'mh-push-button)
- map))
-
-\f
-
-;;; MH-Folder Commands
-
-;; Alphabetical.
-
-;;;###mh-autoload
-(defun mh-display-with-external-viewer (part-index)
- "View attachment externally.
-
-If Emacs does not know how to view an attachment, you could save
-it into a file and then run some program to open it. It is
-easier, however, to launch the program directly from MH-E with
-this command. While you'll most likely use this to view
-spreadsheets and documents, it is also useful to use your browser
-to view HTML attachments with higher fidelity than what Emacs can
-provide.
-
-This command displays the attachment associated with the button
-under the cursor. If the cursor is not located over a button,
-then the cursor first moves to the next button, wrapping to the
-beginning of the message if necessary. You can provide a numeric
-prefix argument PART-INDEX to view the attachment labeled with
-that number.
-
-This command tries to provide a reasonable default for the viewer
-by calling the Emacs function `mailcap-mime-info'. This function
-usually reads the file \"/etc/mailcap\"."
- (interactive "P")
- (when (consp part-index) (setq part-index (car part-index)))
- (mh-folder-mime-action
- part-index
- (lambda ()
- (let* ((part (get-text-property (point) 'mh-data))
- (type (mm-handle-media-type part))
- (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x))))
- (mailcap-mime-info type 'all)))
- (def (caar methods))
- (prompt (format-prompt "Viewer" def))
- (method (completing-read prompt methods nil nil nil nil def))
- (folder mh-show-folder-buffer)
- (buffer-read-only nil))
- (when (string-match "^[^% \t]+$" method)
- (setq method (concat method " %s")))
- (mh-flet
- ((mm-handle-set-external-undisplayer
- (handle function)
- (mh-handle-set-external-undisplayer folder handle function)))
- (unwind-protect (mm-display-external part method)
- (set-buffer-modified-p nil)))))
- nil))
-
-;;;###mh-autoload
-(defun mh-folder-inline-mime-part (part-index)
- "Show attachment verbatim.
-
-You can view the raw contents of an attachment with this command.
-This command displays (or hides) the contents of the attachment
-associated with the button under the cursor verbatim. If the
-cursor is not located over a button, then the cursor first moves
-to the next button, wrapping to the beginning of the message if
-necessary.
-
-You can also provide a numeric prefix argument PART-INDEX to view
-the attachment labeled with that number."
- (interactive "P")
- (when (consp part-index) (setq part-index (car part-index)))
- (mh-folder-mime-action part-index #'mh-mime-inline-part nil))
-
-(defun mh-mime-inline-part ()
- "Toggle display of the raw MIME part."
- (interactive)
- (let* ((buffer-read-only nil)
- (data (get-text-property (point) 'mh-data))
- (inserted-flag (get-text-property (point) 'mh-mime-inserted))
- (displayed-flag (mm-handle-displayed-p data))
- (point (point))
- start end)
- (cond ((and data (not inserted-flag) (not displayed-flag))
- (let ((contents (mm-get-part data)))
- (add-text-properties (line-beginning-position)
- (line-end-position) '(mh-mime-inserted t))
- (setq start (point-marker))
- (forward-line 1)
- (mm-insert-inline data contents)
- (setq end (point-marker))
- (add-text-properties
- start (progn (goto-char start) (line-end-position))
- `(mh-region (,start . ,end)))))
- ((and data (or inserted-flag displayed-flag))
- (mh-press-button)
- (message "MIME part already inserted")))
- (goto-char point)
- (set-buffer-modified-p nil)))
-
-;;;###mh-autoload
-(defun mh-folder-save-mime-part (part-index)
- "Save (output) attachment.
-
-This command saves the attachment associated with the button under the
-cursor. If the cursor is not located over a button, then the cursor
-first moves to the next button, wrapping to the beginning of the
-message if necessary.
-
-You can also provide a numeric prefix argument PART-INDEX to save the
-attachment labeled with that number.
-
-This command prompts you for a filename and suggests a specific name
-if it is available."
- (interactive "P")
- (when (consp part-index) (setq part-index (car part-index)))
- (mh-folder-mime-action part-index #'mh-mime-save-part nil))
-
-(defun mh-mime-save-part ()
- "Save MIME part at point."
- (interactive)
- (let ((data (get-text-property (point) 'mh-data)))
- (when data
- (let ((mm-default-directory
- (file-name-as-directory (or mh-mime-save-parts-directory
- default-directory))))
- (mh-mm-save-part data)
- (setq mh-mime-save-parts-directory mm-default-directory)))))
-
-;;;###mh-autoload
-(defun mh-folder-toggle-mime-part (part-index)
- "View attachment.
-
-This command displays (or hides) the attachment associated with
-the button under the cursor. If the cursor is not located over a
-button, then the cursor first moves to the next button, wrapping
-to the beginning of the message if necessary. This command has
-the advantage over related commands of working from the MH-Folder
-buffer.
-
-You can also provide a numeric prefix argument PART-INDEX to view
-the attachment labeled with that number. If Emacs does not know
-how to display the attachment, then Emacs offers to save the
-attachment in a file."
- (interactive "P")
- (when (consp part-index) (setq part-index (car part-index)))
- (mh-folder-mime-action part-index #'mh-press-button t))
-
-;;;###mh-autoload
-(defun mh-mime-save-parts (prompt)
- "Save attachments.
-
-You can save all of the attachments at once with this command.
-The attachments are saved in the directory specified by the
-option `mh-mime-save-parts-default-directory' unless you use a
-prefix argument PROMPT in which case you are prompted for the
-directory. These directories may be superseded by MH profile
-components, since this function calls on \"mhstore\" (\"mhn\") to
-do the work."
- (interactive "P")
- (let ((msg (if (eq major-mode 'mh-show-mode)
- (mh-show-buffer-message-number)
- (mh-get-msg-num t)))
- (folder (if (eq major-mode 'mh-show-mode)
- mh-show-folder-buffer
- mh-current-folder))
- (command (if (mh-variant-p 'nmh) "mhstore" "mhn"))
- (directory
- (cond
- ((and (or prompt
- (equal nil mh-mime-save-parts-default-directory)
- (equal t mh-mime-save-parts-default-directory))
- (not mh-mime-save-parts-directory))
- (read-directory-name "Store in directory: " nil nil t))
- ((and (or prompt
- (equal t mh-mime-save-parts-default-directory))
- mh-mime-save-parts-directory)
- (read-directory-name "Store in directory: "
- mh-mime-save-parts-directory nil t))
- ((stringp mh-mime-save-parts-default-directory)
- mh-mime-save-parts-default-directory)
- (t
- mh-mime-save-parts-directory))))
- (if (and (equal directory "") mh-mime-save-parts-directory)
- (setq directory mh-mime-save-parts-directory))
- (if (not (file-directory-p directory))
- (message "No directory specified")
- (if (equal nil mh-mime-save-parts-default-directory)
- (setq mh-mime-save-parts-directory directory))
- (with-current-buffer (get-buffer-create mh-log-buffer)
- (let (default-directory)
- (cd directory)
- (setq mh-mime-save-parts-directory directory)
- (let ((initial-size (mh-truncate-log-buffer)))
- (apply #'call-process
- (expand-file-name command mh-progs) nil t nil
- (mh-list-to-string (list folder msg "-auto"
- (if (not (mh-variant-p 'nmh))
- "-store"))))
- (if (> (buffer-size) initial-size)
- (save-window-excursion
- (switch-to-buffer-other-window mh-log-buffer)
- (sit-for 3)))))))))
-
-;;;###mh-autoload
-(defun mh-toggle-mh-decode-mime-flag ()
- "Toggle the value of `mh-decode-mime-flag'."
- (interactive)
- (setq mh-decode-mime-flag (not mh-decode-mime-flag))
- (mh-show nil t)
- (message "%s" (if mh-decode-mime-flag
- "Processing attachments normally"
- "Displaying raw message")))
-
-;;;###mh-autoload
-(defun mh-toggle-mime-buttons ()
- "Toggle option `mh-display-buttons-for-inline-parts-flag'."
- (interactive)
- (setq mh-display-buttons-for-inline-parts-flag
- (not mh-display-buttons-for-inline-parts-flag))
- (mh-show nil t))
-
-\f
-
-;;; MIME Display Routines
-
-(defun mh-mm-inline-message (handle)
- "Display message, HANDLE.
-The function decodes the message and displays it. It avoids
-decoding the same message multiple times."
- (let ((b (point))
- (clean-message-header mh-clean-message-header-flag)
- (invisible-headers mh-invisible-header-fields-compiled)
- ) ;; (visible-headers nil)
- (save-excursion
- (save-restriction
- (narrow-to-region b b)
- (mm-insert-part handle)
- (mh-mime-display
- (or (gethash handle (mh-mime-handles-cache (mh-buffer-data)))
- (setf (gethash handle (mh-mime-handles-cache (mh-buffer-data)))
- (let ((handles (mm-dissect-buffer nil)))
- (if handles
- (mm-uu-dissect-text-parts handles)
- (setq handles (mm-uu-dissect)))
- (setf (mh-mime-handles (mh-buffer-data))
- (mm-merge-handles
- handles (mh-mime-handles (mh-buffer-data))))
- handles))))
-
- (goto-char (point-min))
- (mh-show-xface)
- (cond (clean-message-header
- (mh-clean-msg-header (point-min)
- invisible-headers
- nil) ;; visible-headers
- (goto-char (point-min)))
- (t
- (mh-start-of-uncleaned-message)))
- (mh-decode-message-header)
- (mh-show-addr)
- ;; The other highlighting types don't need anything special
- (when (eq mh-highlight-citation-style 'gnus)
- (mh-gnus-article-highlight-citation))
- (goto-char (point-min))
- (insert "\n------- Forwarded Message\n\n")
- (mh-display-smileys)
- (mh-display-emphasis)
- (mm-handle-set-undisplayer
- handle
- (let ((beg (point-min-marker))
- (end (point-max-marker)))
- (lambda ()
- (let ((inhibit-read-only t))
- (delete-region beg end)))))))))
-
-;;;###mh-autoload
-(defun mh-decode-message-header ()
- "Decode RFC2047 encoded message header fields."
- (when mh-decode-mime-flag
- (let ((buffer-read-only nil))
- (mail-decode-encoded-word-region (point-min) (mh-mail-header-end)))))
-
-;;;###mh-autoload
-(defun mh-decode-message-subject ()
- "Decode RFC2047 encoded message header fields."
- (when mh-decode-mime-flag
- (save-excursion
- (let ((buffer-read-only nil))
- (mail-decode-encoded-word-region
- (progn (mh-goto-header-field "Subject:") (point))
- (progn (mh-header-field-end) (point)))))))
-
-;;;###mh-autoload
-(defun mh-mime-display (&optional pre-dissected-handles)
- "Display (and possibly decode) MIME handles.
-Optional argument, PRE-DISSECTED-HANDLES is a list of MIME
-handles. If present they are displayed otherwise the buffer is
-parsed and then displayed."
- (let ((handles ())
- (folder mh-show-folder-buffer)
- (raw-message-data (buffer-string)))
- (mh-flet
- ((mm-handle-set-external-undisplayer
- (handle function)
- (mh-handle-set-external-undisplayer folder handle function)))
- (goto-char (point-min))
- (unless (search-forward "\n\n" nil t)
- (goto-char (point-max))
- (insert "\n\n"))
-
- (condition-case err
- (progn
- ;; If needed dissect the current buffer
- (if pre-dissected-handles
- (setq handles pre-dissected-handles)
- (if (setq handles (mm-dissect-buffer nil))
- (mm-uu-dissect-text-parts handles)
- (setq handles (mm-uu-dissect)))
- (setf (mh-mime-handles (mh-buffer-data))
- (mm-merge-handles handles
- (mh-mime-handles (mh-buffer-data))))
- (unless handles
- (mh-decode-message-body)))
-
- (cond ((and handles
- (or (not (stringp (car handles)))
- (cdr handles)))
- ;; Go to start of message body
- (goto-char (point-min))
- (or (search-forward "\n\n" nil t)
- (goto-char (point-max)))
-
- ;; Delete the body
- (delete-region (point) (point-max))
-
- ;; Display the MIME handles
- (mh-mime-display-part handles))
- (t
- (mh-signature-highlight))))
- (error
- (message "Could not display body: %s" (error-message-string err))
- (delete-region (point-min) (point-max))
- (insert raw-message-data))))))
-
-(defun mh-decode-message-body ()
- "Decode message based on charset.
-If message has been encoded for transfer take that into account."
- (let (ct charset cte)
- (goto-char (point-min))
- (re-search-forward "\n\n" nil t)
- (save-restriction
- (narrow-to-region (point-min) (point))
- (setq ct (ignore-errors (mail-header-parse-content-type
- (message-fetch-field "Content-Type" t)))
- charset (mail-content-type-get ct 'charset)
- cte (message-fetch-field "Content-Transfer-Encoding")))
- (when (stringp cte) (setq cte (mail-header-strip-cte cte)))
- (when (or (not ct) (equal (car ct) "text/plain"))
- (save-restriction
- (narrow-to-region (min (1+ (mh-mail-header-end)) (point-max))
- (point-max))
- (mm-decode-body charset
- (and cte (intern (downcase cte)))
- (car ct))))))
-
-(defun mh-mime-display-part (handle)
- "Decides the viewer to call based on the type of HANDLE."
- (cond ((null handle)
- nil)
- ((not (stringp (car handle)))
- (mh-mime-display-single handle))
- ((equal (car handle) "multipart/alternative")
- (mh-mime-display-alternative (cdr handle)))
- ((and mh-pgp-support-flag
- (or (equal (car handle) "multipart/signed")
- (equal (car handle) "multipart/encrypted")))
- (mh-mime-display-security handle))
- (t
- (mh-mime-display-mixed (cdr handle)))))
-
-(defun mh-mime-display-mixed (handles)
- "Display the list of MIME parts, HANDLES recursively."
- (mapcar #'mh-mime-display-part handles))
-
-(defun mh-mime-display-alternative (handles)
- "Choose among the alternatives, HANDLES the part that will be displayed.
-If no part is preferred then all the parts are displayed."
- (let* ((preferred (mm-preferred-alternative handles))
- (others (cl-loop for x in handles unless (eq x preferred) collect x)))
- (cond ((and preferred
- (stringp (car preferred)))
- (mh-mime-display-part preferred)
- (mh-mime-maybe-display-alternatives others))
- (preferred
- (save-restriction
- (narrow-to-region (point) (if (eobp) (point) (1+ (point))))
- (mh-mime-display-single preferred)
- (mh-mime-maybe-display-alternatives others)
- (goto-char (point-max))))
- (t
- (mh-mime-display-mixed handles)))))
-
-(defun mh-mime-maybe-display-alternatives (alternatives)
- "Show buttons for ALTERNATIVES.
-If `mh-display-buttons-for-alternatives-flag' is non-nil then
-display buttons for alternative parts that are usually
-suppressed."
- (when (and mh-display-buttons-for-alternatives-flag alternatives)
- (insert "\n----------------------------------------------------\n")
- (insert "Alternatives:\n")
- (dolist (x alternatives)
- (insert "\n")
- (mh-insert-mime-button x (mh-mime-part-index x) nil))
- (insert "\n----------------------------------------------------\n")))
-
-(defun mh-mime-display-security (handle)
- "Display PGP encrypted/signed message, HANDLE."
- (save-restriction
- (narrow-to-region (point) (point))
- (insert "\n")
- (mh-insert-mime-security-button handle)
- (mh-mime-display-mixed (cdr handle))
- (insert "\n")
- (let ((mh-mime-security-button-line-format
- mh-mime-security-button-end-line-format))
- (mh-insert-mime-security-button handle))
- (mm-set-handle-multipart-parameter
- handle 'mh-region (cons (point-min-marker) (point-max-marker)))))
-
-(defun mh-mime-display-single (handle)
- "Display a leaf node, HANDLE in the MIME tree."
- (let* ((type (mm-handle-media-type handle))
- (small-image-flag (mh-small-image-p handle))
- (attachmentp (equal (car (mm-handle-disposition handle))
- "attachment"))
- (inlinep (and (equal (car (mm-handle-disposition handle)) "inline")
- (mm-automatic-display-p handle)
- (mm-inlinable-p handle)
- (mm-inlined-p handle)))
- (displayp (or inlinep ; show if inline OR
- (mh-inline-vcard-p handle); inline vcard OR
- (and (not attachmentp) ; if not an attachment
- (or small-image-flag ; and small image
- ; and user wants inline
- (and (not (equal
- (mm-handle-media-supertype handle)
- "image"))
- (mm-automatic-display-p handle)
- (mm-inlinable-p handle)
- (mm-inlined-p handle)))))))
- (save-restriction
- (narrow-to-region (point) (if (eobp) (point) (1+ (point))))
- (cond ((and mh-pgp-support-flag
- (equal type "application/pgp-signature"))
- nil) ; skip signatures as they are already handled...
- ((not displayp)
- (insert "\n")
- (mh-insert-mime-button handle (mh-mime-part-index handle) nil))
- ((and displayp
- (not mh-display-buttons-for-inline-parts-flag))
- (or (mm-display-part handle)
- (mm-display-part handle))
- (mh-signature-highlight handle))
- ((and displayp
- mh-display-buttons-for-inline-parts-flag)
- (insert "\n")
- (mh-insert-mime-button handle (mh-mime-part-index handle) nil)
- (forward-line -1)
- (mh-mm-display-part handle)))
- (goto-char (point-max)))))
-
-;; There is a bug in Gnus inline image display due to which an extra line
-;; gets inserted every time it is viewed. To work around that problem we are
-;; using an extra property 'mh-region to remember the region that is added
-;; when the button is clicked. The region is then deleted to make sure that
-;; no extra lines get inserted.
-(defun mh-mm-display-part (handle)
- "Toggle display of button for MIME part, HANDLE."
- (beginning-of-line)
- (let ((id (get-text-property (point) 'mh-part))
- (point (point))
- (window (selected-window))
- (mail-parse-charset 'nil)
- (mail-parse-ignored-charsets nil)
- region buffer-read-only)
- (save-excursion
- (unwind-protect
- (let ((win (get-buffer-window (current-buffer) t)))
- (when win
- (select-window win))
- (goto-char point)
-
- (if (mm-handle-displayed-p handle)
- ;; This will remove the part.
- (progn
- ;; Delete the button and displayed part (if any)
- (let ((region (get-text-property point 'mh-region)))
- (when region
- (remove-images (car region) (cdr region)))
- (mm-display-part handle)
- (when region
- (delete-region (car region) (cdr region))))
- ;; Delete button (if it still remains). This happens for
- ;; externally displayed parts where the previous step does
- ;; nothing.
- (unless (eolp)
- (delete-region (point) (progn (forward-line) (point)))))
- (save-restriction
- (delete-region (point) (progn (forward-line 1) (point)))
- (narrow-to-region (point) (point))
- ;; Maybe we need another unwind-protect here.
- (when (equal (mm-handle-media-supertype handle) "image")
- (insert "\n"))
- (when (and (not (eq (ignore-errors (mm-display-part handle))
- 'inline))
- (equal (mm-handle-media-supertype handle)
- "image"))
- (goto-char (point-min))
- (delete-char 1))
- (when (equal (mm-handle-media-supertype handle) "text")
- (when (eq mh-highlight-citation-style 'gnus)
- (mh-gnus-article-highlight-citation))
- (mh-display-smileys)
- (mh-display-emphasis)
- (mh-signature-highlight handle))
- (setq region (cons (progn (goto-char (point-min))
- (point-marker))
- (progn (goto-char (point-max))
- (point-marker)))))))
- (when (window-live-p window)
- (select-window window))
- (goto-char point)
- (beginning-of-line)
- (mh-insert-mime-button handle id (mm-handle-displayed-p handle))
- (goto-char point)
- (when region
- (add-text-properties (line-beginning-position)
- (line-end-position)
- `(mh-region ,region)))))))
-
-(defun mh-mime-part-index (handle)
- "Generate the button number for MIME part, HANDLE.
-Notice that a hash table is used to display the same number when
-buttons need to be displayed multiple times (for instance when
-nested messages are opened)."
- (or (gethash handle (mh-mime-part-index-hash (mh-buffer-data)))
- (setf (gethash handle (mh-mime-part-index-hash (mh-buffer-data)))
- (cl-incf (mh-mime-parts-count (mh-buffer-data))))))
-
-(defun mh-small-image-p (handle)
- "Decide whether HANDLE is a \"small\" image that can be displayed inline.
-This is only useful if a Content-Disposition header is not present."
- (let ((media-test (caddr (assoc (car (mm-handle-type handle))
- mh-mm-inline-media-tests)))
- (mm-inline-large-images t))
- (and media-test
- (equal (mm-handle-media-supertype handle) "image")
- (funcall media-test handle) ; Since mm-inline-large-images is T,
- ; this only tells us if the image is
- ; something that emacs can display
- (let ((image (mm-get-image handle)))
- (let ((size (and (fboundp 'image-size) (image-size image))))
- (and size
- (< (cdr size) (or mh-max-inline-image-height
- (1- (window-height))))
- (< (car size) (or mh-max-inline-image-width
- (window-width)))))))))
-
-(defun mh-inline-vcard-p (handle)
- "Decide if HANDLE is a vcard that must be displayed inline."
- (let ((type (mm-handle-type handle)))
- (and (or (featurep 'vcard) (fboundp 'vcard-pretty-print))
- (consp type)
- (equal (car type) "text/x-vcard")
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (not (mh-signature-separator-p)))))))
-
-(defun mh-signature-highlight (&optional handle)
- "Highlight message signature in HANDLE.
-The optional argument, HANDLE is a MIME handle if the function is
-being used to highlight the signature in a MIME part."
- (let ((regexp
- (cond ((not handle) "^-- $")
- ((not (and (equal (mm-handle-media-supertype handle) "text")
- (equal (mm-handle-media-subtype handle) "html")))
- "^-- $")
- ((eq mm-text-html-renderer 'lynx) "^ --$")
- (t "^--$"))))
- (save-excursion
- (goto-char (point-max))
- (when (re-search-backward regexp nil t)
- (let ((ov (make-overlay (point) (point-max))))
- (overlay-put ov 'face 'mh-show-signature)
- (overlay-put ov 'evaporate t))))))
-
-\f
-
-;;; Button Display
-
-(defun mh-insert-mime-button (handle index displayed)
- "Insert MIME button for HANDLE.
-INDEX is the part number that will be DISPLAYED. It is also used
-by commands like \"K v\" which operate on individual MIME parts."
- ;; The button could be displayed by a previous decode. In that case
- ;; undisplay it if we need a hidden button.
- (when (and (mm-handle-displayed-p handle) (not displayed))
- (mm-display-part handle))
- (let ((name (or (mail-content-type-get (mm-handle-type handle) 'name)
- (mail-content-type-get (mm-handle-disposition handle)
- 'filename)
- (mail-content-type-get (mm-handle-type handle) 'url)
- ""))
- (type (mm-handle-media-type handle))
- begin end)
- (if (string-match ".*/" name) (setq name (substring name (match-end 0))))
- ;; These vars are passed by dynamic-scoping to
- ;; mh-mime-button-line-format-alist via gnus-eval-format.
- (mh-dlet* ((index index)
- (description (mail-decode-encoded-word-string
- (or (mm-handle-description handle) "")))
- (dots (if (or displayed (mm-handle-displayed-p handle))
- " " "..."))
- (long-type (concat type (and (not (equal name ""))
- (concat "; " name)))))
- (unless (equal description "")
- (setq long-type (concat " --- " long-type)))
- (unless (bolp) (insert "\n"))
- (setq begin (point))
- (gnus-eval-format
- mh-mime-button-line-format mh-mime-button-line-format-alist
- `(keymap ,mh-mime-button-map
- mh-callback mh-mm-display-part
- mh-part ,index
- mh-data ,handle)))
- (setq end (point))
- (widget-convert-button
- 'link begin end
- :mime-handle handle
- :action 'mh-widget-press-button
- :button-keymap mh-mime-button-map
- :help-echo
- "Mouse-2 click or press RET (in show buffer) to toggle display")
- (dolist (ov (overlays-in begin end))
- (overlay-put ov 'evaporate t))))
-
-(defun mh-insert-mime-security-button (handle)
- "Display buttons for PGP message, HANDLE."
- (let* ((protocol (mm-handle-multipart-ctl-parameter handle 'protocol))
- (crypto-type (or (nth 2 (assoc protocol mm-verify-function-alist))
- (nth 2 (assoc protocol mm-decrypt-function-alist))
- "Unknown"))
- begin end face)
- ;; These vars are passed by dynamic-scoping to
- ;; mh-mime-security-button-line-format-alist via gnus-eval-format.
- (mh-dlet* ((type (concat crypto-type
- (if (equal (car handle) "multipart/signed")
- " Signed" " Encrypted")
- " Part"))
- (info (or (mm-handle-multipart-ctl-parameter
- handle 'gnus-info)
- "Undecided"))
- (details (mm-handle-multipart-ctl-parameter
- handle 'gnus-details))
- pressed-details)
- (setq details (if details (concat "\n" details) ""))
- (setq pressed-details (if mh-mime-security-button-pressed details ""))
- (setq face (mh-mime-security-button-face info))
- (unless (bolp) (insert "\n"))
- (setq begin (point))
- (gnus-eval-format
- mh-mime-security-button-line-format
- mh-mime-security-button-line-format-alist
- `(keymap ,mh-mime-security-button-map
- mh-button-pressed ,mh-mime-security-button-pressed
- mh-callback mh-mime-security-press-button
- mh-line-format ,mh-mime-security-button-line-format
- mh-data ,handle))
- (setq end (point))
- (widget-convert-button 'link begin end
- :mime-handle handle
- :action 'mh-widget-press-button
- :button-keymap mh-mime-security-button-map
- :button-face face
- :help-echo "Mouse-2 click or press RET (in show buffer) to see security details.")
- (dolist (ov (overlays-in begin end))
- (overlay-put ov 'evaporate t))
- (when (equal info "Failed")
- (let* ((type (if (equal (car handle) "multipart/signed")
- "verification" "decryption"))
- (warning (if (equal type "decryption")
- "(passphrase may be incorrect)" "")))
- (message "%s %s failed %s" crypto-type type warning))))))
-
-(defun mh-mime-security-button-face (info)
- "Return the button face to use for encrypted/signed mail based on INFO."
- (cond ((string-match "OK" info) ;Decrypted mail
- 'mh-show-pgg-good)
- ((string-match "Failed" info) ;Decryption failed or signature invalid
- 'mh-show-pgg-bad)
- ((string-match "Undecided" info);Unprocessed mail
- 'mh-show-pgg-unknown)
- ((string-match "Untrusted" info);Key not trusted
- 'mh-show-pgg-unknown)
- (t
- 'mh-show-pgg-good)))
-
-\f
-
-;;; Button Handlers
-
-(defun mh-folder-mime-action (part-index action include-security-flag)
- "Go to PART-INDEX and carry out ACTION.
-
-If PART-INDEX is nil then go to the next part in the buffer. The
-search for the next buffer wraps around if end of buffer is reached.
-If argument INCLUDE-SECURITY-FLAG is non-nil then include security
-info buttons when searching for a suitable parts."
- (unless mh-showing-mode
- (mh-show))
- (mh-in-show-buffer (mh-show-buffer)
- (let ((criterion
- (cond (part-index
- (lambda (p)
- (let ((part (get-text-property p 'mh-part)))
- (and (integerp part) (= part part-index)))))
- (t (lambda (p)
- (if include-security-flag
- (get-text-property p 'mh-data)
- (integerp (get-text-property p 'mh-part)))))))
- (point (point)))
- (cond ((and (get-text-property point 'mh-part)
- (or (null part-index)
- (= (get-text-property point 'mh-part) part-index)))
- (funcall action))
- ((and (get-text-property point 'mh-data)
- include-security-flag
- (null part-index))
- (funcall action))
- (t
- (mh-goto-next-button nil criterion)
- (if (= (point) point)
- (message "No matching MIME part found")
- (funcall action)))))))
-
-;;;###mh-autoload
-(defun mh-goto-next-button (backward-flag &optional criterion)
- "Search for next button satisfying criterion.
-
-If BACKWARD-FLAG is non-nil search backward in the buffer for a mime
-button.
-If CRITERION is a function or a symbol which has a function binding
-then that function must return non-nil at the button we stop."
- (unless (or (and (symbolp criterion) (fboundp criterion))
- (functionp criterion))
- (setq criterion (lambda (_) t)))
- ;; Move to the next button in the buffer satisfying criterion
- (goto-char (or (save-excursion
- (beginning-of-line)
- ;; Find point before current button
- (let ((point-before-current-button
- (save-excursion
- (while (get-text-property (point) 'mh-data)
- (unless (= (forward-line
- (if backward-flag 1 -1))
- 0)
- (if backward-flag
- (goto-char (point-min))
- (goto-char (point-max)))))
- (point))))
- ;; Skip over current button
- (while (and (get-text-property (point) 'mh-data)
- (not (if backward-flag (bobp) (eobp))))
- (forward-line (if backward-flag -1 1)))
- ;; Stop at next MIME button if any exists.
- (cl-block loop
- (while (/= (progn
- (unless (= (forward-line
- (if backward-flag -1 1))
- 0)
- (if backward-flag
- (goto-char (point-max))
- (goto-char (point-min)))
- (beginning-of-line))
- (point))
- point-before-current-button)
- (when (and (get-text-property (point) 'mh-data)
- (funcall criterion (point)))
- (cl-return-from loop (point))))
- nil)))
- (point))))
-
-(defun mh-widget-press-button (widget _el)
- "Callback for widget, WIDGET.
-Parameter EL is unused."
- (goto-char (widget-get widget :from))
- (mh-press-button))
-
-(defun mh-press-button ()
- "View contents of button.
-
-This command is a toggle so if you use it again on the same
-attachment, the attachment is hidden."
- (interactive)
- (let ((mm-inline-media-tests mh-mm-inline-media-tests)
- (data (get-text-property (point) 'mh-data))
- (function (get-text-property (point) 'mh-callback))
- (buffer-read-only nil)
- (folder mh-show-folder-buffer))
- (mh-flet
- ((mm-handle-set-external-undisplayer
- (handle function)
- (mh-handle-set-external-undisplayer folder handle function)))
- (when (and function (eolp))
- (backward-char))
- (unwind-protect (and function (funcall function data))
- (set-buffer-modified-p nil)))))
-
-(defun mh-push-button (event)
- "Click MIME button for EVENT.
-
-If the MIME part is visible then it is removed. Otherwise the
-part is displayed. This function is called when the mouse is used
-to click the MIME button."
- (interactive "e")
- (mh-do-at-event-location event
- (let ((folder mh-show-folder-buffer)
- (mm-inline-media-tests mh-mm-inline-media-tests)
- (data (get-text-property (point) 'mh-data))
- (function (get-text-property (point) 'mh-callback)))
- (mh-flet
- ((mm-handle-set-external-undisplayer
- (handle func)
- (mh-handle-set-external-undisplayer folder handle func)))
- (and function (funcall function data))))))
-
-(defun mh-handle-set-external-undisplayer (folder handle function)
- "Replacement for `mm-handle-set-external-undisplayer'.
-
-This is only called in recent versions of Gnus. The MIME handles
-are stored in data structures corresponding to MH-E folder buffer
-FOLDER instead of in Gnus (as in the original). The MIME part,
-HANDLE is associated with the undisplayer FUNCTION."
- (if (mm-keep-viewer-alive-p handle)
- (let ((new-handle (copy-sequence handle)))
- (mm-handle-set-undisplayer new-handle function)
- (mm-handle-set-undisplayer handle nil)
- (with-current-buffer folder
- (push new-handle (mh-mime-handles (mh-buffer-data)))))
- (mm-handle-set-undisplayer handle function)))
-
-(defun mh-mime-security-press-button (handle)
- "Callback from security button for part HANDLE."
- (if (mm-handle-multipart-ctl-parameter handle 'gnus-info)
- (mh-mime-security-show-details handle)
- (let ((region (mm-handle-multipart-ctl-parameter handle 'mh-region))
- point)
- (setq point (point))
- (goto-char (car region))
- (delete-region (car region) (cdr region))
- (with-current-buffer (mm-handle-multipart-ctl-parameter handle 'buffer)
- (let* ((mm-verify-option 'known)
- (mm-decrypt-option 'known)
- (new (mm-possibly-verify-or-decrypt (cdr handle) handle)))
- (unless (eq new (cdr handle))
- (mm-destroy-parts (cdr handle))
- (setcdr handle new))))
- (mh-mime-display-security handle)
- (goto-char point))))
-
-;; I rewrote the security part because Gnus doesn't seem to ever minimize
-;; the button. That is once the mime-security button is pressed there seems
-;; to be no way of getting rid of the inserted text.
-(defun mh-mime-security-show-details (handle)
- "Toggle display of detailed security info for HANDLE."
- (let ((details (mm-handle-multipart-ctl-parameter handle 'gnus-details)))
- (when details
- (let ((mh-mime-security-button-pressed
- (not (get-text-property (point) 'mh-button-pressed)))
- (mh-mime-security-button-line-format
- (get-text-property (point) 'mh-line-format)))
- (forward-char -1)
- (while (eq (get-text-property (point) 'mh-line-format)
- mh-mime-security-button-line-format)
- (forward-char -1))
- (forward-char)
- (save-restriction
- (narrow-to-region (point) (point))
- (mh-insert-mime-security-button handle))
- (delete-region
- (point)
- (or (text-property-not-all
- (point) (point-max)
- 'mh-line-format mh-mime-security-button-line-format)
- (point-max)))
- (forward-line -1)))))
-
-\f
-
-;;; Miscellaneous Article Washing
-
-;;;###mh-autoload
-(defun mh-add-missing-mime-version-header ()
- "Some mail programs don't put a MIME-Version header.
-I have seen this only in spam, so maybe we shouldn't fix
-this ;-)"
- (save-excursion
- (goto-char (point-min))
- (re-search-forward "\n\n" nil t)
- (save-restriction
- (narrow-to-region (point-min) (point))
- (when (and (message-fetch-field "content-type")
- (not (message-fetch-field "mime-version")))
- (goto-char (point-min))
- (insert "MIME-Version: 1.0\n")))))
-
-;;;###mh-autoload
-(defun mh-display-smileys ()
- "Display smileys."
- (when (and mh-graphical-smileys-flag (mh-small-show-buffer-p))
- (smiley-region (point-min) (point-max))))
-
-;;;###mh-autoload
-(defun mh-display-emphasis ()
- "Display graphical emphasis."
- (when (and mh-graphical-emphasis-flag (mh-small-show-buffer-p))
- (mh-flet
- ((article-goto-body ())) ; shadow this function to do nothing
- (save-excursion
- (goto-char (point-min))
- (article-emphasize)))))
-
-(defun mh-small-show-buffer-p ()
- "Check if show buffer is small.
-This is used to decide if smileys and graphical emphasis should be
-displayed."
- (>= 64000 (buffer-size)))
-
-\f
-
-;;; MH-Letter Commands
-
-;; MH-E commands are alphabetical; specific support routines follow command.
-
-;;;###mh-autoload
-(defun mh-compose-forward (&optional description folder range)
- "Add tag to forward a message.
-
-You are prompted for a content DESCRIPTION, the name of the
-FOLDER in which the messages to forward are located, and a RANGE
-of messages, which defaults to the current message in that
-folder. Check the documentation of `mh-interactive-range' to see
-how RANGE is read in interactive use.
-
-The option `mh-compose-insertion' controls what type of tags are inserted."
- (interactive
- (let* ((description
- (mml-minibuffer-read-description))
- (folder
- (mh-prompt-for-folder "Message from"
- mh-sent-from-folder nil))
- (default
- (if (and (equal folder mh-sent-from-folder)
- (numberp mh-sent-from-msg))
- mh-sent-from-msg
- (nth 0 (mh-translate-range folder "cur"))))
- (range
- (mh-read-range "Forward" folder
- (or (and default
- (number-to-string default))
- t)
- t t)))
- (list description folder range)))
- (let ((messages (mapconcat #'identity (mh-list-to-string range) " ")))
- (dolist (message (mh-translate-range folder messages))
- (if (equal mh-compose-insertion 'mml)
- (mh-mml-forward-message description folder (format "%s" message))
- (mh-mh-forward-message description folder (format "%s" message))))))
-
-;;;###mh-autoload
-(defun mh-mml-forward-message (description folder message)
- "Forward a message as attachment.
-
-The function will prompt the user for a DESCRIPTION, a FOLDER and
-MESSAGE number."
- (let ((msg (if (and (equal message "") (numberp mh-sent-from-msg))
- mh-sent-from-msg
- (string-to-number message))))
- (cond ((integerp msg)
- (mml-attach-file (format "%s%s/%d"
- mh-user-path (substring folder 1) msg)
- "message/rfc822"
- (if (string= "" description) nil description)
- "inline"))
- (t (error "The message number, %s, is not an integer" msg)))))
-
-(defun mh-mh-forward-message (&optional description folder messages)
- "Add tag to forward a message.
-You are prompted for a content DESCRIPTION, the name of the
-FOLDER in which the messages to forward are located, and the
-MESSAGES' numbers.
-
-See also \\[mh-mh-to-mime]."
- (interactive (list
- (mml-minibuffer-read-description)
- (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
- (read-string (format-prompt "Messages" mh-sent-from-msg))))
- (beginning-of-line)
- (insert "#forw [")
- (and description
- (not (string= description ""))
- (insert description))
- (insert "]")
- (and folder
- (not (string= folder ""))
- (insert " " folder))
- (if (and messages
- (not (string= messages "")))
- (let ((start (point)))
- (insert " " messages)
- (subst-char-in-region start (point) ?, ? ))
- (if (numberp mh-sent-from-msg)
- (insert " " (int-to-string mh-sent-from-msg))))
- (insert "\n"))
-
-;;;###mh-autoload
-(defun mh-compose-insertion (&optional inline)
- "Add tag to include a file such as an image or sound.
-
-You are prompted for the filename containing the object, the
-media type if it cannot be determined automatically, and a
-content description. If you're using MH-style directives, you
-will also be prompted for additional attributes.
-
-The option `mh-compose-insertion' controls what type of tags are
-inserted. Optional argument INLINE means make it an inline
-attachment."
- (interactive "P")
- (if (equal mh-compose-insertion 'mml)
- (if inline
- (mh-mml-attach-file "inline")
- (mh-mml-attach-file))
- (call-interactively 'mh-mh-attach-file)))
-
-(defun mh-mml-attach-file (&optional disposition)
- "Add a tag to insert a MIME message part from a file.
-
-You are prompted for the filename containing the object, the
-media type if it cannot be determined automatically, a content
-description and the DISPOSITION of the attachment.
-
-This is basically `mml-attach-file' from Gnus, modified such that a prefix
-argument yields an \"inline\" disposition and Content-Type is determined
-automatically."
- (let* ((file (mml-minibuffer-read-file "Attach file: "))
- (type (mh-minibuffer-read-type file))
- (description (mml-minibuffer-read-description))
- (dispos (or disposition
- (mml-minibuffer-read-disposition type))))
- (mml-insert-empty-tag 'part 'type type 'filename file
- 'disposition dispos 'description description)))
-
-(defun mh-mh-attach-file (filename type description attributes)
- "Add a tag to insert a MIME message part from a file.
-You are prompted for the FILENAME containing the object, the
-media TYPE if it cannot be determined automatically, and a
-content DESCRIPTION. In addition, you are also prompted for
-additional ATTRIBUTES.
-
-See also \\[mh-mh-to-mime]."
- (interactive (let ((filename (mml-minibuffer-read-file "Attach file: ")))
- (list
- filename
- (mh-minibuffer-read-type filename)
- (mml-minibuffer-read-description)
- (read-string "Attributes: "
- (concat "name=\""
- (file-name-nondirectory filename)
- "\"")))))
- (mh-mh-compose-type filename type description attributes))
-
-(defun mh-mh-compose-type (filename type
- &optional description attributes comment)
- "Insert an MH-style directive to insert a file.
-The file specified by FILENAME is encoded as TYPE. An optional
-DESCRIPTION is used as the Content-Description field, optional
-set of ATTRIBUTES and an optional COMMENT can also be included."
- (beginning-of-line)
- (insert "#" type)
- (and attributes
- (insert "; " attributes))
- (and comment
- (insert " (" comment ")"))
- (insert " [")
- (and description
- (insert description))
- (insert "] " (expand-file-name filename))
- (insert "\n"))
-
-;;;###mh-autoload
-(defun mh-mh-compose-anon-ftp (host filename type description)
- "Add tag to include anonymous ftp reference to a file.
-
-You can have your message initiate an \"ftp\" transfer when the
-recipient reads the message. You are prompted for the remote HOST
-and FILENAME, the media TYPE, and the content DESCRIPTION.
-
-See also \\[mh-mh-to-mime]."
- (interactive (list
- (read-string "Remote host: ")
- (read-string "Remote filename: ")
- (mh-minibuffer-read-type "DUMMY-FILENAME")
- (mml-minibuffer-read-description)))
- (mh-mh-compose-external-type "anon-ftp" host filename
- type description))
-
-;;;###mh-autoload
-(defun mh-mh-compose-external-compressed-tar (host filename description)
- "Add tag to include anonymous ftp reference to a compressed tar file.
-
-In addition to retrieving the file via anonymous \"ftp\" as per
-the command \\[mh-mh-compose-anon-ftp], the file will also be
-uncompressed and untarred. You are prompted for the remote HOST
-and FILENAME and the content DESCRIPTION.
-
-See also \\[mh-mh-to-mime]."
- (interactive (list
- (read-string "Remote host: ")
- (read-string "Remote filename: ")
- (mml-minibuffer-read-description)))
- (mh-mh-compose-external-type "anon-ftp" host filename
- "application/octet-stream"
- description
- "type=tar; conversions=x-compress"
- "mode=image"))
-
-;; RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One:
-;; Format of Internet Message Bodies.
-;; RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two:
-;; Media Types.
-;; RFC 2049 - Multipurpose Internet Mail Extensions (MIME) Part Five:
-;; Conformance Criteria and Examples.
-;; RFC 2017 - Definition of the URL MIME External-Body Access-Type
-;; RFC 1738 - Uniform Resource Locators (URL)
-(defvar mh-access-types
- '(("anon-ftp") ; RFC2046 Anonymous File Transfer Protocol
- ("file") ; RFC1738 Host-specific file names
- ("ftp") ; RFC2046 File Transfer Protocol
- ("gopher") ; RFC1738 The Gopher Protocol
- ("http") ; RFC1738 Hypertext Transfer Protocol
- ("https") ; RFC2818 HTTP Over TLS
- ("local-file") ; RFC2046 Local file access
- ("mail-server") ; RFC2046 mail-server Electronic mail address
- ("mailto") ; RFC1738 Electronic mail address
- ("news") ; RFC1738 Usenet news
- ("nntp") ; RFC1738 Usenet news using NNTP access
- ("prospero") ; RFC1738 Prospero Directory Service
- ("telnet") ; RFC1738 Telnet
- ("tftp") ; RFC2046 Trivial File Transfer Protocol
- ("url") ; RFC2017 URL scheme MIME access-type Protocol
- ("wais")) ; RFC1738 Wide Area Information Servers
- "Valid MIME access-type values.")
-
-;;;###mh-autoload
-(defun mh-mh-compose-external-type (access-type host filename type
- &optional description
- attributes parameters
- comment)
- "Add tag to refer to a remote file.
-
-This command is a general utility for referencing external files.
-In fact, all of the other commands that insert directives to
-access external files call this command. You are prompted for the
-ACCESS-TYPE, remote HOST and FILENAME, and content TYPE. If you
-provide a prefix argument, you are also prompted for a content
-DESCRIPTION, ATTRIBUTES, PARAMETERS, and a COMMENT.
-
-See also \\[mh-mh-to-mime]."
- (interactive (list
- (completing-read "Access type: " mh-access-types)
- (read-string "Remote host: ")
- (read-string "Remote filename: ")
- (mh-minibuffer-read-type "DUMMY-FILENAME")
- (if current-prefix-arg (mml-minibuffer-read-description))
- (if current-prefix-arg (read-string "Attributes: "))
- (if current-prefix-arg (read-string "Parameters: "))
- (if current-prefix-arg (read-string "Comment: "))))
- (beginning-of-line)
- (insert "#@" type)
- (and attributes
- (insert "; " attributes))
- (and comment
- (insert " (" comment ") "))
- (insert " [")
- (and description
- (insert description))
- (insert "] ")
- (insert "access-type=" access-type "; ")
- (insert "site=" host)
- (insert "; name=" (file-name-nondirectory filename))
- (let ((directory (file-name-directory filename)))
- (and directory
- (insert "; directory=\"" directory "\"")))
- (and parameters
- (insert "; " parameters))
- (insert "\n"))
-
-(defvar mh-mh-to-mime-args nil
- "Extra arguments for \\[mh-mh-to-mime] to pass to the \"mhbuild\" command.
-The arguments are passed to \"mhbuild\" if \\[mh-mh-to-mime] is
-given a prefix argument. Normally default arguments to
-\"mhbuild\" are specified in the MH profile.")
-
-;;;###mh-autoload
-(defun mh-mh-to-mime (&optional extra-args)
- "Compose MIME message from MH-style directives.
-
-Typically, you send a message with attachments just like any other
-message. However, you may take a sneak preview of the MIME encoding if
-you wish by running this command.
-
-If you wish to pass additional arguments to \"mhbuild\" (\"mhn\")
-to affect how it builds your message, use the option
-`mh-mh-to-mime-args'. For example, you can build a consistency
-check into the message by setting `mh-mh-to-mime-args' to
-\"-check\". The recipient of your message can then run \"mhbuild
--check\" on the message--\"mhbuild\" (\"mhn\") will complain if
-the message has been corrupted on the way. This command only
-consults this option when given a prefix argument EXTRA-ARGS.
-
-The hook `mh-mh-to-mime-hook' is called after the message has been
-formatted.
-
-The effects of this command can be undone by running
-\\[mh-mh-to-mime-undo]."
- (interactive "*P")
- (mh-mh-quote-unescaped-sharp)
- (save-buffer)
- (message "Running %s..." (if (mh-variant-p 'nmh) "mhbuild" "mhn"))
- (cond
- ((mh-variant-p 'nmh)
- (mh-exec-cmd-error nil
- "mhbuild"
- (if extra-args mh-mh-to-mime-args)
- buffer-file-name))
- (t
- (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name)
- "mhn"
- (if extra-args mh-mh-to-mime-args)
- buffer-file-name)))
- (revert-buffer t t t)
- (message "Running %s...done" (if (mh-variant-p 'nmh) "mhbuild" "mhn"))
- (run-hooks 'mh-mh-to-mime-hook))
-
-(defun mh-mh-quote-unescaped-sharp ()
- "Quote \"#\" characters that haven't been quoted for \"mhbuild\".
-If the \"#\" character is present in the first column, but it isn't
-part of a MH-style directive then \"mhbuild\" gives an error.
-This function will quote all such characters."
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "^#" nil t)
- (beginning-of-line)
- (unless (mh-mh-directive-present-p (point) (line-end-position))
- (insert "#"))
- (goto-char (line-end-position)))))
-
-;;;###mh-autoload
-(defun mh-mh-to-mime-undo (noconfirm)
- "Undo effects of \\[mh-mh-to-mime].
-
-It does this by reverting to a backup file. You are prompted to
-confirm this action, but you can avoid the confirmation by adding
-a prefix argument NOCONFIRM."
- (interactive "*P")
- (if (null buffer-file-name)
- (error "Buffer does not seem to be associated with any file"))
- (let ((backup-strings '("," "#"))
- backup-file)
- (while (and backup-strings
- (not (file-exists-p
- (setq backup-file
- (concat (file-name-directory buffer-file-name)
- (car backup-strings)
- (file-name-nondirectory buffer-file-name)
- ".orig")))))
- (setq backup-strings (cdr backup-strings)))
- (or backup-strings
- (error "Backup file for %s no longer exists" buffer-file-name))
- (or noconfirm
- (yes-or-no-p (format "Revert buffer from file %s? "
- backup-file))
- (error "Revert not confirmed"))
- (let ((buffer-read-only nil))
- (erase-buffer)
- (insert-file-contents backup-file))
- (after-find-file nil nil nil nil t)))
-
-;; Shush compiler.
-(defvar mh-identity-gpg-default-user-id)
-
-;;;###mh-autoload
-(defun mh-mml-secure-message-encrypt (method)
- "Add tag to encrypt the message.
-
-A proper multipart message is created for you when you send the
-message. Use the command \\[mh-mml-unsecure-message] to remove
-this tag. Use a prefix argument METHOD to be prompted for one of
-the possible security methods (see `mh-mml-method-default')."
- (interactive (list (mh-mml-query-cryptographic-method)))
- (mh-secure-message method "encrypt" mh-identity-gpg-default-user-id))
-
-;;;###mh-autoload
-(defun mh-mml-secure-message-sign (method)
- "Add tag to sign the message.
-
-A proper multipart message is created for you when you send the
-message. Use the command \\[mh-mml-unsecure-message] to remove
-this tag. Use a prefix argument METHOD to be prompted for one of
-the possible security methods (see `mh-mml-method-default')."
- (interactive (list (mh-mml-query-cryptographic-method)))
- (mh-secure-message method "sign" mh-identity-gpg-default-user-id))
-
-;;;###mh-autoload
-(defun mh-mml-secure-message-signencrypt (method)
- "Add tag to encrypt and sign the message.
-
-A proper multipart message is created for you when you send the
-message. Use the command \\[mh-mml-unsecure-message] to remove
-this tag. Use a prefix argument METHOD to be prompted for one of
-the possible security methods (see `mh-mml-method-default')."
- (interactive (list (mh-mml-query-cryptographic-method)))
- (mh-secure-message method "signencrypt" mh-identity-gpg-default-user-id))
-
-(defvar mh-mml-cryptographic-method-history ())
-
-(defun mh-mml-query-cryptographic-method ()
- "Read the cryptographic method to use."
- (if current-prefix-arg
- (let ((def (or (car mh-mml-cryptographic-method-history)
- mh-mml-method-default)))
- (completing-read (format-prompt "Method" def)
- '(("pgp") ("pgpmime") ("smime"))
- nil t nil 'mh-mml-cryptographic-method-history def))
- mh-mml-method-default))
-
-(defun mh-secure-message (method mode &optional _identity)
- "Add tag to encrypt or sign message.
-
-METHOD should be one of: \"pgpmime\", \"pgp\", \"smime\".
-MODE should be one of: \"sign\", \"encrypt\", \"signencrypt\", \"none\".
-IDENTITY is optionally the default-user-id to use."
- (if (not mh-pgp-support-flag)
- (error "Your version of Gnus does not support PGP/GPG")
- ;; Check the arguments
- (let ((valid-methods (list "pgpmime" "pgp" "smime"))
- (valid-modes (list "sign" "encrypt" "signencrypt" "none")))
- (if (not (member method valid-methods))
- (error "Method %s is invalid" method))
- (if (not (member mode valid-modes))
- (error "Mode %s is invalid" mode))
- (mml-unsecure-message)
- (if (not (string= mode "none"))
- (save-excursion
- (goto-char (point-min))
- (mh-goto-header-end 1)
- (if mh-identity-gpg-default-user-id
- (mml-insert-tag 'secure 'method method 'mode mode
- 'sender mh-identity-gpg-default-user-id)
- (mml-insert-tag 'secure 'method method 'mode mode)))))))
-
-;;;###mh-autoload
-(defun mh-mml-to-mime ()
- "Compose MIME message from MML tags.
-
-Typically, you send a message with attachments just like any
-other message. However, you may take a sneak preview of the MIME
-encoding if you wish by running this command.
-
-This action can be undone by running \\[undo]."
- (interactive)
- (require 'message)
- (when mh-pgp-support-flag
- ;; PGP requires actual e-mail addresses, not aliases.
- ;; Parse the recipients and sender from the message.
- (message-options-set-recipient)
- ;; Do an alias lookup on sender (if From field is present).
- (when (message-options-get 'message-sender)
- (message-options-set 'message-sender
- (mail-strip-quoted-names
- (mh-alias-expand
- (message-options-get 'message-sender)))))
- ;; Do an alias lookup on recipients
- (message-options-set 'message-recipients
- (mapconcat
- (lambda (ali)
- (mail-strip-quoted-names (mh-alias-expand ali)))
- (split-string (message-options-get 'message-recipients) "[, ]+")
- ", ")))
- (let ((saved-text (buffer-string))
- (buffer (current-buffer))
- (modified-flag (buffer-modified-p)))
- (condition-case err (mml-to-mime)
- (error
- (with-current-buffer buffer
- (delete-region (point-min) (point-max))
- (insert saved-text)
- (set-buffer-modified-p modified-flag))
- (error (error-message-string err))))))
-
-;;;###mh-autoload
-(defun mh-mml-unsecure-message ()
- "Remove any secure message tags."
- (interactive)
- (if (not mh-pgp-support-flag)
- (error "Your version of Gnus does not support PGP/GPG")
- (mml-unsecure-message)))
-
-\f
-
-;;; Support Routines for MH-Letter Commands
-
-;;;###mh-autoload
-(defun mh-mml-tag-present-p ()
- "Check if the current buffer has text which may be a MML tag."
- (save-excursion
- (goto-char (point-min))
- (re-search-forward
- (concat
- "\\(<#\\(mml\\|part\\)\\(.\\|\n\\)*>[ \n\t]*<#/\\(mml\\|part\\)>\\|"
- "^<#secure.+>$\\)")
- nil t)))
-
-(defvar mh-media-type-regexp
- (concat (regexp-opt '("text" "image" "audio" "video" "application"
- "multipart" "message") t)
- "/[-.+a-zA-Z0-9]+")
- "Regexp matching valid media types used in MIME attachment compositions.")
-
-;;;###mh-autoload
-(defun mh-mh-directive-present-p (&optional begin end)
- "Check if the text between BEGIN and END might be a MH-style directive.
-The optional argument BEGIN defaults to the beginning of the
-buffer, while END defaults to the end of the buffer."
- (unless begin (setq begin (point-min)))
- (unless end (setq end (point-max)))
- (save-excursion
- (cl-block search-for-mh-directive
- (goto-char begin)
- (while (re-search-forward "^#" end t)
- (let ((s (buffer-substring-no-properties
- (point) (line-end-position))))
- (cond ((equal s ""))
- ((string-match "^forw[ \t\n]+" s)
- (cl-return-from search-for-mh-directive t))
- (t (let ((first-token (car (split-string s "[ \t;@]"))))
- (when (and first-token
- (string-match mh-media-type-regexp
- first-token))
- (cl-return-from search-for-mh-directive t)))))))
- nil)))
-
-(defun mh-minibuffer-read-type (filename &optional default)
- "Return the content type associated with the given FILENAME.
-If the \"file\" command exists and recognizes the given file,
-then its value is returned; otherwise, the user is prompted for
-a type (see `mailcap-mime-types').
-Optional argument DEFAULT is returned if a type isn't entered."
- (mailcap-parse-mimetypes)
- (let* ((default (or default
- (mm-default-file-type filename)
- "application/octet-stream"))
- (probed-type (mh-file-mime-type filename))
- (type (or (and (not (equal probed-type "application/octet-stream"))
- probed-type)
- (completing-read
- (format-prompt "Content type" default)
- (mapcar #'list (mailcap-mime-types))))))
- (if (not (equal type ""))
- type
- default)))
-
-;;;###mh-autoload
-(defun mh-file-mime-type (filename)
- "Return MIME type of FILENAME from file command.
-Returns nil if file command not on system."
- (cond
- ((not (mh-have-file-command))
- nil) ;no file command, exit now
- ((not (and (file-exists-p filename)
- (file-readable-p filename)))
- nil) ;no file or not readable, ditto
- (t
- (let ((tmp-buffer (get-buffer-create mh-temp-buffer)))
- (with-current-buffer tmp-buffer
- (unwind-protect
- (progn
- (call-process "file" nil '(t nil) nil "-b" "-i"
- (expand-file-name filename))
- (goto-char (point-min))
- (if (not (re-search-forward mh-media-type-regexp nil t))
- nil
- (mh-file-mime-type-substitute (match-string 0) filename)))
- (kill-buffer tmp-buffer)))))))
-
-(defvar mh-file-mime-type-substitutions
- '(("application/msword" "\\.xls" "application/ms-excel")
- ("application/msword" "\\.ppt" "application/ms-powerpoint")
- ("text/plain" "\\.vcf" "text/x-vcard")
- ("text/rtf" "\\.rtf" "application/rtf")
- ("application/x-zip" "\\.sxc" "application/vnd.sun.xml.calc")
- ("application/x-zip" "\\.sxd" "application/vnd.sun.xml.draw")
- ("application/x-zip" "\\.sxi" "application/vnd.sun.xml.impress")
- ("application/x-zip" "\\.sxw" "application/vnd.sun.xml.writer")
- ("application/x-zip" "\\.odg" "application/vnd.oasis.opendocument.graphics")
- ("application/x-zip" "\\.odi" "application/vnd.oasis.opendocument.image")
- ("application/x-zip" "\\.odp"
- "application/vnd.oasis.opendocument.presentation")
- ("application/x-zip" "\\.ods"
- "application/vnd.oasis.opendocument.spreadsheet")
- ("application/x-zip" "\\.odt" "application/vnd.oasis.opendocument.text"))
- "Substitutions to make for Content-Type returned from file command.
-The first element is the Content-Type returned by the file command.
-The second element is a regexp matching the file name, usually the
-extension.
-The third element is the Content-Type to replace with.")
-
-(defun mh-file-mime-type-substitute (content-type filename)
- "Return possibly changed CONTENT-TYPE on the FILENAME.
-Substitutions are made from the `mh-file-mime-type-substitutions'
-variable."
- (let ((subst mh-file-mime-type-substitutions)
- (type) (match) (answer content-type)
- (case-fold-search t))
- (while subst
- (setq type (car (car subst))
- match (elt (car subst) 1))
- (if (and (string-equal content-type type)
- (string-match match filename))
- (setq answer (elt (car subst) 2)
- subst nil)
- (setq subst (cdr subst))))
- answer))
-
-(defvar mh-have-file-command 'undefined
- "Cached value of function `mh-have-file-command'.
-Do not reference this variable directly as it might not have been
-initialized. Always use the command `mh-have-file-command'.")
-
-;;;###mh-autoload
-(defun mh-have-file-command ()
- "Return t if `file' command is on the system.
-\"file -i\" is used to get MIME type of composition insertion."
- (when (eq mh-have-file-command 'undefined)
- (setq mh-have-file-command
- (and (executable-find "file") ; file command exists
- ; and accepts -i and -b args.
- (zerop (call-process "file" nil nil nil "-i" "-b"
- (expand-file-name "inc" mh-progs))))))
- mh-have-file-command)
-
-\f
-
-;;; MIME Cleanup
-
-;;;###mh-autoload
-(defun mh-mime-cleanup ()
- "Free the decoded MIME parts."
- (let ((mime-data (gethash (current-buffer) mh-globals-hash)))
- (remove-images (point-min) (point-max))
- (when mime-data
- (mm-destroy-parts (mh-mime-handles mime-data))
- (remhash (current-buffer) mh-globals-hash))))
-
-;;;###mh-autoload
-(defun mh-destroy-postponed-handles ()
- "Free MIME data for externally displayed MIME parts."
- (let ((mime-data (mh-buffer-data)))
- (when mime-data
- (mm-destroy-parts (mh-mime-handles mime-data)))
- (remhash (current-buffer) mh-globals-hash)))
-
-(provide 'mh-mime)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-mime.el ends here
+++ /dev/null
-;;; mh-print.el --- MH-E printing support -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2003-2024 Free Software Foundation, Inc.
-
-;; Author: Jeffrey C Honig <jch@honig.net>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-(require 'ps-print)
-
-(defvar mh-ps-print-color-option ps-print-color-p
- "Specify how buffer's text color is printed.
-
-Valid values are:
-
- nil - Do not print colors.
- t - Print colors.
- black-white - Print colors on black/white printer.
- See also `ps-black-white-faces'.
-
-Any other value is treated as t. This variable is initialized
-from `ps-print-color-p'.")
-
-(defvar mh-ps-print-func 'ps-spool-buffer-with-faces
- "Function to use to spool a buffer.
-
-Sensible choices are the functions `ps-spool-buffer' and
-`ps-spool-buffer-with-faces'.")
-
-;;;###mh-autoload
-(defun mh-ps-print-msg (range)
- "Print RANGE\\<mh-folder-mode-map>.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is
-read in interactive use.
-
-This command will print inline text attachments but will not decrypt
-messages. However, when a message is displayed in an MH-Show buffer,
-then that buffer is used verbatim for printing with the caveat that
-only text attachments, if opened inline, are printed. Therefore,
-encrypted messages can be printed by showing and decrypting them
-first.
-
-MH-E uses the \"ps-print\" package to do the printing, so you can
-customize the printing further by going to the `ps-print'
-customization group. This command does not use the options
-`mh-lpr-command-format' or `mh-print-background-flag'. See also the
-commands \\[mh-ps-print-toggle-color] and
-\\[mh-ps-print-toggle-faces]."
- (interactive (list (mh-interactive-range "Print")))
- (mh-ps-print-range range nil))
-
-(defun mh-ps-print-range (range file)
- "Print RANGE to FILE.
-
-This is the function that actually does the work.
-If FILE is nil, then the messages are spooled to the printer."
- (mh-iterate-on-range msg range
- (mh-ps-spool-msg msg)
- (mh-notate msg mh-note-printed mh-cmd-note))
- (ps-despool file))
-
-(defun mh-ps-spool-msg (msg)
- "Spool MSG."
- (let* ((folder mh-current-folder)
- (buffer (mh-in-show-buffer (mh-show-buffer)
- (if (not (equal (mh-msg-filename msg folder)
- buffer-file-name))
- (get-buffer-create mh-temp-buffer)))))
- (unwind-protect
- (save-excursion
- (if buffer
- (let ((mh-show-buffer buffer))
- (mh-display-msg msg folder)))
- (mh-ps-spool-buffer (if buffer buffer mh-show-buffer)))
- (if buffer
- (kill-buffer buffer)))))
-
-(defun mh-ps-spool-buffer (buffer)
- "Spool BUFFER."
- (with-current-buffer buffer
- (let ((ps-print-color-p mh-ps-print-color-option)
- (ps-left-header
- (list
- (concat "(" (mh-get-header-field "Subject:") ")")
- (concat "(" (mh-get-header-field "From:") ")")))
- (ps-right-header
- (list
- "/pagenumberstring load"
- (concat "(" (mh-get-header-field "Date:") ")"))))
- (funcall mh-ps-print-func))))
-
-;;;###mh-autoload
-(defun mh-ps-print-msg-file (range file)
- "Print RANGE to FILE\\<mh-folder-mode-map>.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is
-read in interactive use.
-
-This command will print inline text attachments but will not decrypt
-messages. However, when a message is displayed in an MH-Show buffer,
-then that buffer is used verbatim for printing with the caveat that
-only text attachments, if opened inline, are printed. Therefore,
-encrypted messages can be printed by showing and decrypting them
-first.
-
-MH-E uses the \"ps-print\" package to do the printing, so you can
-customize the printing further by going to the `ps-print'
-customization group. This command does not use the options
-`mh-lpr-command-format' or `mh-print-background-flag'. See also the
-commands \\[mh-ps-print-toggle-color] and
-\\[mh-ps-print-toggle-faces]."
- (interactive (list (mh-interactive-range "Print") (mh-ps-print-preprint 1)))
- (mh-ps-print-range range file))
-
-(defun mh-ps-print-preprint (arg)
- "Provide a better default file name for `ps-print-preprint'.
-Pass along the prefix ARG to it."
- (let ((buffer-file-name (format "mh-%s" (substring (buffer-name) 1))))
- (ps-print-preprint arg)))
-
-;;;###mh-autoload
-(defun mh-ps-print-toggle-faces ()
- "Toggle whether printing is done with faces or not.
-
-When faces are enabled, the printed message will look very
-similar to the message in the MH-Show buffer."
- (interactive)
- (if (eq mh-ps-print-func 'ps-spool-buffer-with-faces)
- (progn
- (setq mh-ps-print-func 'ps-spool-buffer)
- (message "Printing without faces"))
- (setq mh-ps-print-func 'ps-spool-buffer-with-faces)
- (message "Printing with faces")))
-
-;;;###mh-autoload
-(defun mh-ps-print-toggle-color ()
- "Toggle whether color is used in printing messages.
-
-Colors are emulated on black-and-white printers with shades of
-gray. This might produce illegible output, even if your screen
-colors only use shades of gray. If this is the case, try using
-this command to toggle between color, no color, and a black and
-white representation of the colors and see which works best. You
-change this setting permanently by customizing the option
-`ps-print-color-p'."
- (interactive)
- (if (eq mh-ps-print-color-option nil)
- (progn
- (setq mh-ps-print-color-option 'black-white)
- (message "Colors will be printed as black & white"))
- (if (eq mh-ps-print-color-option 'black-white)
- (progn
- (setq mh-ps-print-color-option t)
- (message "Colors will be printed"))
- (setq mh-ps-print-color-option nil)
- (message "Colors will not be printed"))))
-
-;; Old non-PS based printing
-;;;###mh-autoload
-(defun mh-print-msg (range)
- "Print RANGE the old fashioned way\\<mh-folder-mode-map>.
-
-The message is formatted with \"mhl\" (see option
-`mh-mhl-format-file') and printed with the \"lpr\" command (see
-option `mh-lpr-command-format').
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use.
-
-Consider using \\[mh-ps-print-msg] instead."
- (interactive (list (mh-interactive-range "Print")))
- (message "Printing...")
- (let (msgs)
- ;; Gather message numbers and add them to "printed" sequence.
- (mh-iterate-on-range msg range
- (mh-add-msgs-to-seq msg 'printed t)
- (mh-notate nil mh-note-printed mh-cmd-note)
- (push msg msgs))
- (setq msgs (nreverse msgs))
- ;; Print scan listing if we have more than one message.
- (if (> (length msgs) 1)
- (let* ((msgs-string
- (mapconcat #'identity (mh-list-to-string
- (mh-coalesce-msg-list msgs))
- " "))
- (lpr-command
- (format mh-lpr-command-format
- (cond ((listp range)
- (format "Folder: %s, Messages: %s"
- mh-current-folder msgs-string))
- ((symbolp range)
- (format "Folder: %s, Sequence: %s"
- mh-current-folder range)))))
- (scan-command
- (format "scan %s | %s" msgs-string lpr-command)))
- (if mh-print-background-flag
- (mh-exec-cmd-daemon shell-file-name nil "-c" scan-command)
- (call-process shell-file-name nil nil nil "-c" scan-command))))
- ;; Print the messages
- (dolist (msg msgs)
- (let* ((mhl-command (format "%s %s %s"
- (expand-file-name "mhl" mh-lib-progs)
- (if mh-mhl-format-file
- (format " -form %s" mh-mhl-format-file)
- "")
- (mh-msg-filename msg)))
- (lpr-command
- (format mh-lpr-command-format
- (format "%s/%s" mh-current-folder msg)))
- (print-command
- (format "%s | %s" mhl-command lpr-command)))
- (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)))))
- (message "Printing...done"))
-
-(provide 'mh-print)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-print.el ends here
+++ /dev/null
-;;; mh-scan.el --- MH-E scan line constants and utilities -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 1997, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file contains constants and a few functions for interpreting
-;; scan lines.
-
-;;; Code:
-
-(require 'mh-e)
-
-\f
-
-;;; Scan Formats
-
-;; The following scan formats are passed to the scan program if the setting of
-;; `mh-scan-format-file' is t. They are identical except the later one makes
-;; use of the nmh `decode' function to decode RFC 2047 encodings. If you just
-;; want to change the column of the notations, use the `mh-set-cmd-note'
-;; function.
-
-(defcustom mh-scan-format-mh
- (concat
- "%4(msg)"
- "%<(cur)+%| %>"
- "%<{replied}-"
- "%?(nonnull(comp{to}))%<(mymbox{to})t%>"
- "%?(nonnull(comp{cc}))%<(mymbox{cc})c%>"
- "%?(nonnull(comp{bcc}))%<(mymbox{bcc})b%>"
- "%?(nonnull(comp{newsgroups}))n%>"
- "%<(zero) %>"
- "%02(mon{date})/%02(mday{date})%<{date} %|*%>"
- "%<(mymbox{from})%<{to}To:%14(friendly{to})%>%>"
- "%<(zero)%17(friendly{from})%> "
- "%{subject}%<{body}<<%{body}%>")
- "Scan format string for MH.
-This string is passed to the scan program via the -format
-argument. This format is identical to the default except that
-additional hints for fontification have been added to the fifth
-column (remember that in Emacs, the first column is 0).
-
-The values of the fifth column, in priority order, are: \"-\" if
-the message has been replied to, t if an address on the To: line
-matches one of the mailboxes of the current user, \"c\" if the Cc:
-line matches, \"b\" if the Bcc: line matches, and \"n\" if a
-non-empty Newsgroups: header is present."
- :group 'mh-scan-line-formats
- :type 'string)
-
-(defcustom mh-scan-format-nmh
- (concat
- "%4(msg)"
- "%<(cur)+%| %>"
- "%<{replied}-"
- "%?(nonnull(comp{to}))%<(mymbox{to})t%>"
- "%?(nonnull(comp{cc}))%<(mymbox{cc})c%>"
- "%?(nonnull(comp{bcc}))%<(mymbox{bcc})b%>"
- "%?(nonnull(comp{newsgroups}))n%>"
- "%<(zero) %>"
- "%02(mon{date})/%02(mday{date})%<{date} %|*%>"
- "%<(mymbox{from})%<{to}To:%14(decode(friendly{to}))%>%>"
- "%<(zero)%17(decode(friendly{from}))%> "
- "%(decode{subject})%<{body}<<%{body}%>")
- "Scan format string for nmh.
-This string is passed to the scan program via the -format arg.
-This format is identical to the default except that additional
-hints for fontification have been added to the fifth
-column (remember that in Emacs, the first column is 0).
-
-The values of the fifth column, in priority order, are: \"-\" if
-the message has been replied to, t if an address on the To: field
-matches one of the mailboxes of the current user, \"c\" if the Cc:
-field matches, \"b\" if the Bcc: field matches, and \"n\" if a
-non-empty Newsgroups: field is present."
- :group 'mh-scan-line-formats
- :type 'string)
-
-\f
-
-;;; Regular Expressions
-
-;; Alphabetical.
-
-(defvar mh-scan-allowlisted-msg-regexp "^\\( *[0-9]+\\)A"
- "This regular expression matches allowlisted (non-spam) messages.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\)A\".
-
-This expression includes the leading space within parenthesis
-since it looks better to highlight it as well. The highlighting
-is done with the face `mh-folder-allowlisted'. This regular
-expression should be correct as it is needed by non-fontification
-functions. See also `mh-note-allowlisted'.")
-
-(defvar mh-scan-blocklisted-msg-regexp "^\\( *[0-9]+\\)B"
- "This regular expression matches blocklisted (spam) messages.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\)B\".
-
-This expression includes the leading space within parenthesis
-since it looks better to highlight it as well. The highlighting
-is done with the face `mh-folder-blocklisted'. This regular
-expression should be correct as it is needed by non-fontification
-functions. See also `mh-note-blocklisted'.")
-
-(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)"
- "This regular expression matches the message body fragment.
-
-Note that the default setting of `mh-folder-font-lock-keywords'
-expects this expression to contain at least one parenthesized
-expression which matches the body text as in the default of
-\"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is
-not correct, the body fragment will not be highlighted with the
-face `mh-folder-body'.")
-
-(defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*"
- "This regular expression matches the current message.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\+\\\\).*\".
-
-This expression includes the leading space and current message
-marker \"+\" within the parenthesis since it looks better to
-highlight these items as well. The highlighting is done with the
-face `mh-folder-cur-msg-number'. This regular expression should
-be correct as it is needed by non-fontification functions. See
-also `mh-note-cur'.")
-
-(defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)"
- "This regular expression matches a valid date.
-
-It must not be anchored to the beginning or the end of the line.
-Note that the default setting of `mh-folder-font-lock-keywords'
-expects this expression to contain only one parenthesized
-expression which matches the date field as in the default of
-\"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}. If this regular expression
-is not correct, the date will not be highlighted with the face
-`mh-folder-date'.")
-
-(defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D"
- "This regular expression matches deleted messages.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\)D\".
-
-This expression includes the leading space within the parenthesis
-since it looks better to highlight it as well. The highlighting
-is done with the face `mh-folder-deleted'. This regular
-expression should be correct as it is needed by non-fontification
-functions. See also `mh-note-deleted'.")
-
-(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^^DBA0-9]"
- "This regular expression matches \"good\" messages.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\)[^^DBA0-9]\".
-
-This expression includes the leading space within the parenthesis
-since it looks better to highlight it as well. The highlighting
-is done with the face `mh-folder-msg-number'. This regular
-expression should be correct as it is needed by non-fontification
-functions.")
-
-(defvar mh-scan-msg-format-regexp "%\\([0-9]*\\)(msg)"
- "This regular expression finds the message number width in a scan format.
-
-Note that the message number must be placed in a parenthesized
-expression as in the default of \"%\\\\([0-9]*\\\\)(msg)\". This
-variable is only consulted if `mh-scan-format-file' is set to
-\"Use MH-E scan Format\".")
-
-(defvar mh-scan-msg-format-string "%d"
- "This is a format string for width of the message number in a scan format.
-
-Use \"0%d\" for zero-filled message numbers. This variable is only
-consulted if `mh-scan-format-file' is set to \"Use MH-E scan
-Format\".")
-
-(defvar mh-scan-msg-number-regexp "^ *\\([0-9]+\\)"
- "This regular expression extracts the message number.
-
-It must match from the beginning of the line. Note that the
-message number must be placed in a parenthesized expression as in
-the default of \"^ *\\\\([0-9]+\\\\)\".")
-
-(defvar mh-scan-msg-overflow-regexp "^[?0-9][0-9]"
- "This regular expression matches overflowed message numbers.")
-
-(defvar mh-scan-msg-search-regexp "^[^0-9]*%d[^0-9]"
- "This regular expression matches a particular message.
-
-It is a format string; use \"%d\" to represent the location of the
-message number within the expression as in the default of
-\"^[^0-9]*%d[^0-9]\".")
-
-(defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)"
- "This regular expression specifies the recipient in messages you sent.
-
-Note that the default setting of `mh-folder-font-lock-keywords'
-expects this expression to contain two parenthesized expressions.
-The first is expected to match the \"To:\" that the default scan
-format file generates. The second is expected to match the
-recipient's name as in the default of
-\"\\\\(To:\\\\)\\\\(..............\\\\)\". If this regular
-expression is not correct, the \"To:\" string will not be
-highlighted with the face `mh-folder-to' and the recipient will
-not be highlighted with the face `mh-folder-address'")
-
-(defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^"
- "This regular expression matches refiled messages.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\)\\\\^\".
-
-This expression includes the leading space within the parenthesis
-since it looks better to highlight it as well. The highlighting
-is done with the face `mh-folder-refiled'. This regular
-expression should be correct as it is needed by non-fontification
-functions. See also `mh-note-refiled'.")
-
-(defvar mh-scan-sent-to-me-sender-regexp
- "^ *[0-9]+.\\([bct]\\).....[ ]*\\(..................\\)"
- "This regular expression matches messages sent to us.
-
-Note that the default setting of `mh-folder-font-lock-keywords'
-expects this expression to contain at least two parenthesized
-expressions. The first should match the fontification hint (see
-`mh-scan-format-nmh') and the second should match the user name
-as in the default of
-
- ^ *[0-9]+.\\\\([bct]\\\\).....[ ]*\\\\(..................\\\\)
-
-If this regular expression is not correct, the notation hints
-will not be highlighted with the face `mh-folder-sent-to-me-hint'
-and the sender will not be highlighted with the face
-`mh-folder-sent-to-me-sender'.")
-
-(defvar mh-scan-subject-regexp
- "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)"
- "This regular expression matches the subject.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least three parenthesized expressions.
-The first is expected to match the \"Re:\" string, if any, and is
-highlighted with the face `mh-folder-followup'. The second
-matches an optional bracketed number after \"Re:\", such as in
-\"Re[2]:\" (and is thus a sub-expression of the first expression)
-and the third is expected to match the subject line itself which
-is highlighted with the face `mh-folder-subject'. For example,
-the default (broken on multiple lines for readability) is
-
- ^ *[0-9]+........[ ]*...................
- \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)*
- \\\\([^<\\n]*\\\\)
-
-This regular expression should be correct as it is needed by
-non-fontification functions.")
-
-(defvar mh-scan-valid-regexp "^ *[0-9]"
- "This regular expression describes a valid scan line.
-
-This is used to eliminate error messages that are occasionally
-produced by \"inc\".")
-
-\f
-
-;;; Widths, Offsets and Columns
-
-(defvar-local mh-cmd-note 4
- "Column for notations.
-
-This variable should be set with the function `mh-set-cmd-note'.
-This variable may be updated dynamically if
-`mh-adaptive-cmd-note-flag' is on.
-
-Note that columns in Emacs start with 0.")
-
-(defvar mh-scan-cmd-note-width 1
- "Number of columns consumed by the cmd-note field in `mh-scan-format'.
-
-This column will have one of the values:
-
- \" \", \"^\", \"D\", \"B\", \"A\", \"+\"
-
-where
-
- \" \" is the default value,
- \"^\" is the `mh-note-refiled' character,
- \"D\" is the `mh-note-deleted' character,
- \"B\" is the `mh-note-blocklisted' character,
- \"A\" is the `mh-note-allowlisted' character, and
- \"+\" is the `mh-note-cur' character.")
-
-(defvar mh-scan-destination-width 1
- "Number of columns consumed by the destination field in `mh-scan-format'.
-
-This column will have one of \" \", \"%\", \"-\", \"t\", \"c\", \"b\", or \"n\"
-in it.
-
- \" \" blank space is the default character.
- \"%\" indicates that the message in a named MH sequence.
- \"-\" indicates that the message has been annotated with a replied field.
- \"t\" indicates that the message contains mymbox in the To: field.
- \"c\" indicates that the message contains mymbox in the Cc: field.
- \"b\" indicates that the message contains mymbox in the Bcc: field.
- \"n\" indicates that the message contains a Newsgroups: field.")
-
-(defvar mh-scan-date-width 5
- "Number of columns consumed by the date field in `mh-scan-format'.
-This column will typically be of the form mm/dd.")
-
-(defvar mh-scan-date-flag-width 1
- "Number of columns consumed to flag (in)valid dates in `mh-scan-format'.
-This column will have \" \" for valid and \"*\" for invalid or
-missing dates.")
-
-(defvar mh-scan-from-mbox-width 17
- "Number of columns consumed with the \"From:\" line in `mh-scan-format'.
-This column will have a friendly name or e-mail address of the
-originator, or a \"To: address\" for outgoing e-mail messages.")
-
-(defvar mh-scan-from-mbox-sep-width 2
- "Number of columns consumed by whitespace after from-mbox in `mh-scan-format'.
-This column will only ever have spaces in it.")
-
-(defvar mh-scan-field-destination-offset
- (+ mh-scan-cmd-note-width)
- "The offset from the `mh-cmd-note' for the destination column.")
-
-(defvar mh-scan-field-from-start-offset
- (+ mh-scan-cmd-note-width
- mh-scan-destination-width
- mh-scan-date-width
- mh-scan-date-flag-width)
- "The offset from the `mh-cmd-note' to find the start of \"From:\" address.")
-
-(defvar mh-scan-field-from-end-offset
- (+ mh-scan-field-from-start-offset mh-scan-from-mbox-width)
- "The offset from the `mh-cmd-note' to find the end of \"From:\" address.")
-
-(defvar mh-scan-field-subject-start-offset
- (+ mh-scan-cmd-note-width
- mh-scan-destination-width
- mh-scan-date-width
- mh-scan-date-flag-width
- mh-scan-from-mbox-width
- mh-scan-from-mbox-sep-width)
- "The offset from the `mh-cmd-note' to find the start of the subject.")
-
-\f
-
-;;; Notation
-
-;; Alphabetical.
-
-(defvar mh-note-allowlisted ?A
- "Messages that have been allowlisted are marked by this character.
-See also `mh-scan-allowlisted-msg-regexp'.")
-
-(defvar mh-note-blocklisted ?B
- "Messages that have been blocklisted are marked by this character.
-See also `mh-scan-blocklisted-msg-regexp'.")
-
-(defvar mh-note-copied ?C
- "Messages that have been copied are marked by this character.")
-
-(defvar mh-note-cur ?+
- "The current message (in MH, not in MH-E) is marked by this character.
-See also `mh-scan-cur-msg-number-regexp'.")
-
-(defvar mh-note-deleted ?D
- "Messages that have been deleted are marked by this character.
-See also `mh-scan-deleted-msg-regexp'.")
-
-(defvar mh-note-dist ?R
- "Messages that have been redistributed are marked by this character.")
-
-(defvar mh-note-forw ?F
- "Messages that have been forwarded are marked by this character.")
-
-(defvar mh-note-printed ?P
- "Messages that have been printed are marked by this character.")
-
-(defvar mh-note-refiled ?^
- "Messages that have been refiled are marked by this character.
-See also `mh-scan-refiled-msg-regexp'.")
-
-(defvar mh-note-repl ?-
- "Messages that have been replied to are marked by this character.")
-
-(defvar mh-note-seq ?%
- "Messages in a user-defined sequence are marked by this character.
-
-Messages in the \"search\" sequence are marked by this character as
-well.")
-
-\f
-
-;;; Utilities
-
-;;;###mh-autoload
-(defun mh-scan-msg-number-regexp ()
- "Return value of variable `mh-scan-msg-number-regexp'."
- mh-scan-msg-number-regexp)
-
-;;;###mh-autoload
-(defun mh-scan-msg-search-regexp ()
- "Return value of variable `mh-scan-msg-search-regexp'."
- mh-scan-msg-search-regexp)
-
-;;;###mh-autoload
-(defun mh-set-cmd-note (column)
- "Set `mh-cmd-note' to COLUMN.
-Note that columns in Emacs start with 0."
- (setq mh-cmd-note column))
-
-;;;###mh-autoload
-(defun mh-scan-format ()
- "Return the output format argument for the scan program."
- (if (equal mh-scan-format-file t)
- (list "-format" (if (mh-variant-p 'nmh 'gnu-mh)
- (list (mh-update-scan-format
- mh-scan-format-nmh mh-cmd-note))
- (list (mh-update-scan-format
- mh-scan-format-mh mh-cmd-note))))
- (if (not (equal mh-scan-format-file nil))
- (list "-form" mh-scan-format-file))))
-
-(defun mh-update-scan-format (fmt width)
- "Return a scan format with the (msg) width in the FMT replaced with WIDTH.
-
-The message number width portion of the format is discovered
-using `mh-scan-msg-format-regexp'. Its replacement is controlled
-with `mh-scan-msg-format-string'."
- (or (and
- (string-match mh-scan-msg-format-regexp fmt)
- (let ((begin (match-beginning 1))
- (end (match-end 1)))
- (concat (substring fmt 0 begin)
- (format mh-scan-msg-format-string width)
- (substring fmt end))))
- fmt))
-
-;;;###mh-autoload
-(defun mh-msg-num-width (folder)
- "Return the width of the largest message number in this FOLDER."
- (or mh-progs (mh-find-path))
- (let ((tmp-buffer (get-buffer-create mh-temp-buffer))
- (width 0))
- (with-current-buffer tmp-buffer
- (erase-buffer)
- (apply #'call-process
- (expand-file-name mh-scan-prog mh-progs) nil '(t nil) nil
- (list folder "last" "-format" "%(msg)"))
- (goto-char (point-min))
- (if (re-search-forward mh-scan-msg-number-regexp nil 0 1)
- (setq width (length (buffer-substring
- (match-beginning 1) (match-end 1))))))
- width))
-
-;;;###mh-autoload
-(defun mh-msg-num-width-to-column (width)
- "Return the column for notations given message number WIDTH.
-Note that columns in Emacs start with 0.
-
-If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this
-means that either `mh-scan-format-mh' or `mh-scan-format-nmh' is
-in use. This function therefore assumes that the first column is
-empty (to provide room for the cursor), the following WIDTH
-columns contain the message number, and the column for notations
-comes after that."
- (if (eq mh-scan-format-file t)
- (max (1+ width) 2)
- (error "%s %s" "Can't call `mh-msg-num-width-to-column' when"
- "`mh-scan-format-file' is not set to \"Use MH-E scan Format\"")))
-
-(provide 'mh-scan)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-scan.el ends here
+++ /dev/null
-;;; mh-search.el --- MH-Search mode -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Indexed search by Satyaki Das <satyaki@theforce.stanford.edu>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Mode used to compose search criteria.
-
-;; (1) The following search engines are supported:
-;; swish++
-;; swish-e
-;; mairix
-;; namazu
-;; pick
-;; grep
-
-;; (2) To use this package, you first have to build an index. Please
-;; read the documentation for `mh-search' to get started. That
-;; documentation will direct you to the specific instructions for
-;; your particular searcher.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-letter)
-
-(require 'gnus-util)
-(require 'imenu)
-
-(defvar mh-searcher nil
- "Cached value of chosen search program.")
-
-(defvar mh-search-function nil
- "Function which executes the search program.")
-
-(defvar mh-search-next-result-function nil
- "Function to parse the next line of output.
-Expected to return a list of three strings: name of the folder,
-message number, and optionally the match.")
-
-(defvar mh-search-regexp-builder nil
- "Function used to construct search regexp.")
-
-(defvar mh-index-folder "+mhe-index"
- "Folder that contains the folders resulting from the index searches.")
-
-(defvar mh-flists-results-folder "sequence"
- "Subfolder for `mh-index-folder' where flists output is placed.")
-
-(defvar mh-flists-sequence)
-
-(defvar mh-flists-called-flag nil)
-
-\f
-
-;;; MH-Folder Commands
-
-;;;###mh-autoload
-(defun mh-search (folder search-regexp
- &optional redo-search-flag window-config)
- "Search your MH mail.
-
-This command helps you find messages in your entire corpus of
-mail. You can search for messages to or from a particular person
-or about a particular subject. In fact, you can also search for
-messages containing selected strings in any arbitrary header
-field or any string found within the messages.
-
-Out of the box, MH-E uses \"pick\" to find messages. With a
-little extra effort, you can set an indexing program which
-rewards you with extremely quick results. The drawback is that
-sometimes the index does not contain the words you're looking
-for. You can still use \"pick\" in these situations.
-
-You are prompted for the FOLDER to search. This can be \"all\" to
-search all folders. Note that the search works recursively on the
-listed folder.
-
-Next, an MH-Search buffer appears where you can enter search
-criteria SEARCH-REGEXP.
-
- From:
- To:
- Cc:
- Date:
- Subject:
- --------
-
-Edit this template by entering your search criteria in an
-appropriate header field that is already there, or create a new
-field yourself. If the string you're looking for could be
-anywhere in a message, then place the string underneath the row
-of dashes.
-
-As an example, let's say that we want to find messages from
-Ginnean about horseback riding in the Kosciusko National
-Park (Australia) during January, 1994. Normally we would start
-with a broad search and narrow it down if necessary to produce a
-manageable amount of data, but we'll cut to the chase and create
-a fairly restrictive set of criteria as follows:\\<mh-search-mode-map>
-
- From: ginnean
- To:
- Cc:
- Date: Jan 1994
- Subject:
- --------
- horse
- kosciusko
-
-As with MH-Letter mode, MH-Search provides commands like
-\\[mh-to-field] to help you fill in the blanks.\\<mh-folder-mode-map>
-
-If you find that you do the same thing over and over when editing
-the search template, you may wish to bind some shortcuts to keys.
-This can be done with the variable `mh-search-mode-hook', which is
-called when \\[mh-search] is run on a new pattern.\\<mh-search-mode-map>
-
-To perform the search, type \\[mh-index-do-search].
-
-Sometimes you're searching for text that is either not indexed,
-or hasn't been indexed yet. In this case you can override the
-default method with the pick method by running the command
-\\[mh-pick-do-search].
-
-The messages that are found are put in a temporary sub-folder of
-\"+mhe-index\" and are displayed in an MH-Folder buffer. This
-buffer is special because it displays messages from multiple
-folders; each set of messages from a given folder has a heading
-with the folder name.\\<mh-folder-mode-map>
-
-The appearance of the heading can be modified by customizing the
-face `mh-search-folder'. You can jump back and forth between the
-headings using the commands \\[mh-index-next-folder] and
-\\[mh-index-previous-folder].
-
-In addition, the command \\[mh-index-visit-folder] can be used to
-visit the folder of the message at point. Initially, only the
-messages that matched the search criteria are displayed in the
-folder. While the temporary buffer has its own set of message
-numbers, the actual messages numbers are shown in the visited
-folder. Thus, the command \\[mh-index-visit-folder] is useful to
-find the actual message number of an interesting message, or to
-view surrounding messages with the command \\[mh-rescan-folder].
-
-Because this folder is temporary, you'll probably get in the
-habit of killing it when you're done with \\[mh-kill-folder].
-
-You can regenerate the results by running this command with a
-prefix argument REDO-SEARCH-FLAG.
-
-Note: This command uses an \"X-MHE-Checksum:\" header field to
-cache the MD5 checksum of a message. This means that if an
-incoming message already contains an \"X-MHE-Checksum:\" field,
-that message might not be found by this command. The following
-\"procmail\" recipe avoids this problem by renaming the existing
-header field:
-
- :0 wf
- | formail -R \"X-MHE-Checksum\" \"X-Old-MHE-Checksum\"
-
-Configuring Indexed Searches
-
-The command \\[mh-search] runs the command defined by the option
-`mh-search-program'. The default value is \"Auto-detect\" which
-means that MH-E will automatically choose one of \"swish++\",
-\"swish-e\", \"mairix\", \"namazu\", \"pick\" and \"grep\" in
-that order. If, for example, you have both \"swish++\" and
-\"mairix\" installed and you want to use \"mairix\", then you can
-set this option to \"mairix\".
-
-The documentation for the following commands describe how to set
-up the various indexing programs to use with MH-E.
-
- - `mh-swish++-execute-search'
- - `mh-swish-execute-search'
- - `mh-mairix-execute-search'
- - `mh-namazu-execute-search'
- - `mh-pick-execute-search'
- - `mh-grep-execute-search'
-
-In a program, if FOLDER is \"+\" or nil, then mail in all folders
-are searched. Optional argument WINDOW-CONFIG stores the window
-configuration that will be restored after the user quits the
-folder containing the index search results."
- (interactive
- (list (progn
- (mh-find-path)
- ;; Yes, we do want to call mh-search-choose every time in case the
- ;; user has switched the searcher manually.
- (unless (mh-search-choose (and current-prefix-arg
- mh-index-previous-search
- (cadr mh-index-previous-search)))
- (error "No search program found"))
- (or (and current-prefix-arg mh-index-sequence-search-flag)
- (and current-prefix-arg (car mh-index-previous-search))
- (mh-prompt-for-folder "Search" "+" nil "all" t)))
- (or (and current-prefix-arg (caddr mh-index-previous-search))
- mh-search-regexp-builder
- (read-string (format "%s regexp: "
- (upcase-initials (symbol-name mh-searcher)))))
- current-prefix-arg
- (if (and (not (and current-prefix-arg
- (caddr mh-index-previous-search)))
- mh-search-regexp-builder)
- (current-window-configuration)
- nil)))
- (cl-block mh-search
- ;; Redoing a sequence search?
- (when (and redo-search-flag mh-index-data mh-index-sequence-search-flag
- (not mh-flists-called-flag))
- (let ((mh-flists-called-flag t))
- (apply #'mh-index-sequenced-messages mh-index-previous-search))
- (cl-return-from mh-search))
- ;; We have fancy query parsing.
- (when (symbolp search-regexp)
- (mh-search-folder folder window-config)
- (cl-return-from mh-search))
- ;; Begin search proper.
- (mh-checksum-choose)
- (let ((result-count 0)
- (old-window-config (or window-config mh-previous-window-config))
- (previous-search mh-index-previous-search)
- (index-folder (format "%s/%s" mh-index-folder
- (mh-index-generate-pretty-name search-regexp))))
- ;; Create a new folder for the search results or recreate the old one...
- (if (and redo-search-flag mh-index-previous-search)
- (let ((buffer-name (buffer-name (current-buffer))))
- (mh-process-or-undo-commands buffer-name)
- (save-excursion (mh-exec-cmd-quiet nil "rmf" buffer-name))
- (mh-exec-cmd-quiet nil "folder" "-create" "-fast" buffer-name)
- (setq index-folder buffer-name))
- (setq index-folder (mh-index-new-folder index-folder search-regexp)))
-
- (let ((folder-path (format "%s%s" mh-user-path (substring folder 1)))
- (folder-results-map (make-hash-table :test #'equal))
- (origin-map (make-hash-table :test #'equal)))
- ;; Run search program...
- (message "Executing %s... " mh-searcher)
- (funcall mh-search-function folder-path search-regexp)
-
- ;; Parse searcher output.
- (message "Processing %s output... " mh-searcher)
- (goto-char (point-min))
- (cl-loop for next-result = (funcall mh-search-next-result-function)
- while next-result
- do (unless (eq next-result 'error)
- (unless (gethash (car next-result) folder-results-map)
- (setf (gethash (car next-result) folder-results-map)
- (make-hash-table :test #'equal)))
- (setf (gethash (cadr next-result)
- (gethash (car next-result) folder-results-map))
- t)))
-
- ;; Copy the search results over.
- (maphash (lambda (folder msgs)
- (let ((cur (car (mh-translate-range folder "cur")))
- (msgs (sort (cl-loop
- for msg being the hash-keys of msgs
- collect msg)
- #'<)))
- (mh-exec-cmd "refile" msgs "-src" folder
- "-link" index-folder)
- ;; Restore cur to old value, that refile changed
- (when cur
- (mh-exec-cmd-quiet nil "mark" folder "-add" "-zero"
- "-sequence"
- "cur" (format "%s" cur)))
- (cl-loop for msg in msgs
- do (cl-incf result-count)
- (setf (gethash result-count origin-map)
- (cons folder msg)))))
- folder-results-map)
-
- ;; Visit the results folder.
- (mh-visit-folder index-folder () (list folder-results-map origin-map))
-
- (goto-char (point-min))
- (forward-line)
- (mh-update-sequences)
- (mh-recenter nil)
-
- ;; Update the speedbar, if needed.
- (when (mh-speed-flists-active-p)
- (mh-speed-flists t mh-current-folder))
-
- ;; Maintain history.
- (when (or (and redo-search-flag previous-search) window-config)
- (setq mh-previous-window-config old-window-config))
- (setq mh-index-previous-search (list folder mh-searcher search-regexp))
-
- ;; Write out data to disk.
- (unless mh-flists-called-flag (mh-index-write-data))
-
- (message "%s found %s matches in %s folders"
- (upcase-initials (symbol-name mh-searcher))
- (cl-loop for msg-hash being the hash-values of mh-index-data
- sum (hash-table-count msg-hash))
- (cl-loop for msg-hash being the hash-values of mh-index-data
- count (> (hash-table-count msg-hash) 0)))))))
-
-(defun mh-search-folder (folder window-config)
- "Search FOLDER for messages matching a pattern.
-
-In a program, argument WINDOW-CONFIG is the current window
-configuration and is used when the search folder is dismissed."
- (interactive (list (mh-prompt-for-folder "Search" mh-current-folder nil nil t)
- (current-window-configuration)))
- ;; FIXME: `pick-folder' is unused!
- (let () ;; (pick-folder (if (equal folder "+") mh-current-folder folder))
- (switch-to-buffer-other-window "search-pattern")
- (if (or (zerop (buffer-size))
- (not (y-or-n-p "Reuse pattern? ")))
- (mh-make-pick-template)
- (message ""))
- (setq-local mh-current-folder folder
- mh-previous-window-config window-config)
- (message "%s" (substitute-command-keys
- (concat "Type \\[mh-index-do-search] to search messages, "
- "\\[mh-pick-do-search] to use pick, "
- "\\[mh-help] for help")))))
-
-(defun mh-make-pick-template ()
- "Initialize the current buffer with a template for a pick pattern."
- (let ((inhibit-read-only t)) (erase-buffer))
- (insert "From: \n"
- "To: \n"
- "Cc: \n"
- "Date: \n"
- "Subject: \n"
- "---------\n")
- (mh-search-mode)
- (goto-char (point-min))
- (dotimes (_ 5)
- (add-text-properties (point) (1+ (point)) '(front-sticky t))
- (add-text-properties (- (line-end-position) 2)
- (1- (line-end-position))
- '(rear-nonsticky t))
- (add-text-properties (point) (1- (line-end-position)) '(read-only t))
- (forward-line))
- (add-text-properties (point) (1+ (point)) '(front-sticky t))
- (add-text-properties (point) (1- (line-end-position)) '(read-only t))
- (goto-char (point-max)))
-
-;; Sequence Searches
-
-;;;###mh-autoload
-(defun mh-index-new-messages (folders)
- "Display unseen messages.
-
-If you use a program such as \"procmail\" to use \"rcvstore\" to file
-your incoming mail automatically, you can display new, unseen,
-messages using this command. All messages in the \"unseen\"
-sequence from the folders in `mh-new-messages-folders' are
-listed.
-
-With a prefix argument, enter a space-separated list of FOLDERS,
-or nothing to search all folders."
- (interactive
- (list (if current-prefix-arg
- (split-string (read-string "Search folder(s) (default all): "))
- mh-new-messages-folders)))
- (mh-index-sequenced-messages folders mh-unseen-seq))
-
-;;;###mh-autoload
-(defun mh-index-ticked-messages (folders)
- "Display ticked messages.
-
-All messages in `mh-tick-seq' from the folders in
-`mh-ticked-messages-folders' are listed.
-
-With a prefix argument, enter a space-separated list of FOLDERS,
-or nothing to search all folders."
- (interactive
- (list (if current-prefix-arg
- (split-string (read-string "Search folder(s) (default all): "))
- mh-ticked-messages-folders)))
- (mh-index-sequenced-messages folders mh-tick-seq))
-
-(defvar mh-mairix-folder)
-(defvar mh-flists-search-folders)
-
-;;;###mh-autoload
-(defun mh-index-sequenced-messages (folders sequence)
- "Display messages in any sequence.
-
-All messages from the FOLDERS in `mh-new-messages-folders' in the
-SEQUENCE you provide are listed. With a prefix argument, enter a
-space-separated list of folders at the prompt, or nothing to
-search all folders."
- (interactive
- (list (if current-prefix-arg
- (split-string (read-string "Search folder(s) (default all): "))
- mh-new-messages-folders)
- (mh-read-seq-default "Search" nil)))
- (unless sequence (setq sequence mh-unseen-seq))
- (let* ((mh-flists-search-folders folders)
- (mh-flists-sequence sequence)
- (mh-flists-called-flag t)
- (mh-searcher 'flists)
- (mh-search-function 'mh-flists-execute)
- (mh-search-next-result-function 'mh-mairix-next-result)
- (mh-mairix-folder mh-user-path)
- (mh-search-regexp-builder nil)
- (new-folder (format "%s/%s/%s" mh-index-folder
- mh-flists-results-folder sequence))
- (window-config (if (equal new-folder mh-current-folder)
- mh-previous-window-config
- (current-window-configuration)))
- (redo-flag nil)
- message)
- (cond ((buffer-live-p (get-buffer new-folder))
- ;; The destination folder is being visited. Trick `mh-search'
- ;; into thinking that the folder resulted from a previous search.
- (set-buffer new-folder)
- (setq mh-index-previous-search (list folders mh-searcher sequence))
- (setq redo-flag t))
- ((mh-folder-exists-p new-folder)
- ;; Folder exists but we don't have it open. That means they are
- ;; stale results from an old flists search. Clear it out.
- (mh-exec-cmd-quiet nil "rmf" new-folder)))
- (setq message (mh-search "+" mh-flists-results-folder
- redo-flag window-config)
- mh-index-sequence-search-flag t
- mh-index-previous-search (list folders mh-searcher sequence))
- (mh-index-write-data)
- (when (stringp message) (message "%s" message))))
-
-(defvar mh-flists-search-folders)
-
-(defun mh-flists-execute (&rest _ignored)
- "Execute flists.
-Search for messages belonging to `mh-flists-sequence' in the
-folders specified by `mh-flists-search-folders'. If
-`mh-recursive-folders-flag' is t, then the folders are searched
-recursively. All arguments are IGNORED."
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (unless (executable-find "sh")
- (error "Didn't find sh"))
- (with-temp-buffer
- (let ((seq (symbol-name mh-flists-sequence)))
- (insert "for folder in `" (expand-file-name "flists" mh-progs) " "
- (cond ((eq mh-flists-search-folders t)
- (mh-quote-for-shell mh-inbox))
- ((eq mh-flists-search-folders nil) "")
- ((listp mh-flists-search-folders)
- (cl-loop for folder in mh-flists-search-folders
- concat
- (concat " " (mh-quote-for-shell folder)))))
- (if mh-recursive-folders-flag " -recurse" "")
- " -sequence " seq " -noshowzero -fast` ; do\n"
- (expand-file-name "mhpath" mh-progs) " \"+$folder\" " seq "\n"
- "done\n"))
- (call-process-region
- (point-min) (point-max) "sh" nil (get-buffer mh-temp-index-buffer))))
-
-;; Navigation
-
-;;;###mh-autoload
-(defun mh-index-next-folder (&optional backward-flag)
- "Jump to the next folder marker.
-
-With non-nil optional argument BACKWARD-FLAG, jump to the previous
-group of results."
- (interactive "P")
- (if (null mh-index-data)
- (message "Only applicable in an MH-E index search buffer")
- (let ((point (point)))
- (forward-line (if backward-flag 0 1))
- (cond ((if backward-flag
- (re-search-backward "^\\+" (point-min) t)
- (re-search-forward "^\\+" (point-max) t))
- (beginning-of-line))
- ((and (if backward-flag
- (goto-char (point-max))
- (goto-char (point-min)))
- nil))
- ((if backward-flag
- (re-search-backward "^\\+" (point-min) t)
- (re-search-forward "^\\+" (point-max) t))
- (beginning-of-line))
- (t (goto-char point))))))
-
-;;;###mh-autoload
-(defun mh-index-previous-folder ()
- "Jump to the previous folder marker."
- (interactive)
- (mh-index-next-folder t))
-
-;;;###mh-autoload
-(defun mh-index-visit-folder ()
- "Visit original folder from where the message at point was found."
- (interactive)
- (unless mh-index-data
- (error "Not in an index folder"))
- (let (folder msg)
- (save-excursion
- (cond ((and (bolp) (eolp))
- (ignore-errors (forward-line -1))
- (setq msg (mh-get-msg-num t)))
- ((equal (char-after (line-beginning-position)) ?+)
- (setq folder (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position))))
- (t (setq msg (mh-get-msg-num t)))))
- (when (not folder)
- (setq folder (car (gethash (gethash msg mh-index-msg-checksum-map)
- mh-index-checksum-origin-map))))
- (when (or (not (get-buffer folder))
- (y-or-n-p (format "Reuse buffer displaying %s? " folder)))
- (mh-visit-folder
- folder (cl-loop
- for x being the hash-keys of (gethash folder mh-index-data)
- when (mh-msg-exists-p x folder) collect x)))))
-
-\f
-
-;;; Search Menu
-
-(easy-menu-define
- mh-pick-menu mh-search-mode-map "Menu for MH-E Search."
- '("Search"
- ["Perform Search" mh-index-do-search t]
- ["Search with pick" mh-pick-do-search t]))
-
-\f
-
-;;; MH-Search Keys
-
-;; If this changes, modify mh-search-mode-help-messages accordingly, below.
-(define-keymap :keymap mh-search-mode-map
- "C-c ?" #'mh-help
- "C-c C-c" #'mh-index-do-search
- "C-c C-p" #'mh-pick-do-search
- "C-c C-f C-b" #'mh-to-field
- "C-c C-f C-c" #'mh-to-field
- "C-c C-f C-m" #'mh-to-field
- "C-c C-f C-s" #'mh-to-field
- "C-c C-f C-t" #'mh-to-field
- "C-c C-f b" #'mh-to-field
- "C-c C-f c" #'mh-to-field
- "C-c C-f m" #'mh-to-field
- "C-c C-f s" #'mh-to-field
- "C-c C-f t" #'mh-to-field)
-
-\f
-
-;;; MH-Search Help Messages
-
-;; Group messages logically, more or less.
-(defvar mh-search-mode-help-messages
- '((nil
- "Perform search: \\[mh-index-do-search]\n"
- "Search with pick: \\[mh-pick-do-search]\n\n"
- "Move to a field by typing C-c C-f C-<field>\n"
- "where <field> is the first letter of the desired field\n"
- "(except for From: which uses \"m\")."))
- "Key binding cheat sheet.
-
-This is an associative array which is used to show the most common
-commands. The key is a prefix char. The value is one or more strings
-which are concatenated together and displayed in the minibuffer if ?
-is pressed after the prefix character. The special key nil is used to
-display the non-prefixed commands.
-
-The substitutions described in `substitute-command-keys' are performed
-as well.")
-
-\f
-
-;;; MH-Search Mode
-
-(put 'mh-search-mode 'mode-class 'special)
-
-(define-derived-mode mh-search-mode fundamental-mode "MH-Search"
- "Mode for creating search templates in MH-E.
-\\<mh-search-mode-map>
-Edit this template by entering your search criteria in an
-appropriate header field that is already there, or create a new
-field yourself. If the string you're looking for could be
-anywhere in a message, then place the string underneath the row
-of dashes.
-
-To perform the search, type \\[mh-index-do-search].
-
-Sometimes you're searching for text that is either not indexed,
-or hasn't been indexed yet. In this case you can override the
-default method with the pick method by running the command
-\\[mh-pick-do-search].
-
-The hook `mh-search-mode-hook' is called upon entry to this mode.
-
-\\{mh-search-mode-map}"
-
- (mh-set-help mh-search-mode-help-messages))
-
-\f
-
-;;; MH-Search Commands
-
-(defun mh-index-do-search (&optional searcher)
- "Find messages using `mh-search-program'.
-If optional argument SEARCHER is present, use it instead of
-`mh-search-program'."
- (interactive)
- (unless (mh-search-choose searcher) (error "No search program found"))
- (let* ((regexp-list (mh-pick-parse-search-buffer))
- (pattern (funcall mh-search-regexp-builder regexp-list)))
- (if pattern
- (mh-search mh-current-folder pattern nil mh-previous-window-config)
- (error "No search terms"))))
-
-(defun mh-pick-do-search ()
- "Find messages using \"pick\".
-
-Uses the pick method described in `mh-pick-execute-search'."
- (interactive)
- (mh-index-do-search 'pick))
-
-(defun mh-pick-parse-search-buffer ()
- "Parse the search buffer contents.
-The function returns an alist. The car of each element is either
-the header name to search in or nil to search the whole message.
-The cdr of the element is the pattern to search."
- (save-excursion
- (let ((pattern-list ())
- (in-body-flag nil)
- start begin)
- (goto-char (point-min))
- (while (not (eobp))
- (if (search-forward "--------" (line-end-position) t)
- (setq in-body-flag t)
- (beginning-of-line)
- (setq begin (point))
- (setq start (if in-body-flag
- (point)
- (search-forward ":" (line-end-position) t)
- (point)))
- (push (cons (and (not in-body-flag)
- (intern (downcase
- (buffer-substring-no-properties
- begin (1- start)))))
- (mh-index-parse-search-regexp
- (buffer-substring-no-properties
- start (line-end-position))))
- pattern-list))
- (forward-line))
- pattern-list)))
-
-(defun mh-index-parse-search-regexp (input-string)
- "Construct parse tree for INPUT-STRING.
-All occurrences of &, |, ! and ~ in INPUT-STRING are replaced by
-AND, OR and NOT as appropriate. Then the resulting string is
-parsed."
- (let (input)
- (with-temp-buffer
- (insert input-string)
- ;; replace tabs
- (mh-replace-string "\t" " ")
- ;; synonyms of AND
- (mh-replace-string " AND " " and ")
- (mh-replace-string "&" " and ")
- (mh-replace-string " -and " " and ")
- ;; synonyms of OR
- (mh-replace-string " OR " " or ")
- (mh-replace-string "|" " or ")
- (mh-replace-string " -or " " or ")
- ;; synonyms of NOT
- (mh-replace-string " NOT " " not ")
- (mh-replace-string "!" " not ")
- (mh-replace-string "~" " not ")
- (mh-replace-string " -not " " not ")
- ;; synonyms of left brace
- (mh-replace-string "(" " ( ")
- (mh-replace-string " -lbrace " " ( ")
- ;; synonyms of right brace
- (mh-replace-string ")" " ) ")
- (mh-replace-string " -rbrace " " ) ")
- ;; get the normalized input
- (setq input (format "( %s )" (buffer-substring (point-min) (point-max)))))
-
- (let ((tokens (mh-index-add-implicit-ops (split-string input)))
- (op-stack ())
- (operand-stack ())
- oper1)
- (dolist (token tokens)
- (cond ((equal token "(") (push 'paren op-stack))
- ((equal token "not") (push 'not op-stack))
- ((equal token "or") (push 'or op-stack))
- ((equal token "and") (push 'and op-stack))
- ((equal token ")")
- (cl-multiple-value-setq (op-stack operand-stack)
- (cl-values-list (mh-index-evaluate op-stack operand-stack)))
- (when (eq (car op-stack) 'not)
- (setq op-stack (cdr op-stack))
- (push `(not ,(pop operand-stack)) operand-stack))
- (when (eq (car op-stack) 'and)
- (setq op-stack (cdr op-stack))
- (setq oper1 (pop operand-stack))
- (push `(and ,(pop operand-stack) ,oper1) operand-stack)))
- ((eq (car op-stack) 'not)
- (setq op-stack (cdr op-stack))
- (push `(not ,token) operand-stack)
- (when (eq (car op-stack) 'and)
- (setq op-stack (cdr op-stack))
- (setq oper1 (pop operand-stack))
- (push `(and ,(pop operand-stack) ,oper1) operand-stack)))
- ((eq (car op-stack) 'and)
- (setq op-stack (cdr op-stack))
- (push `(and ,(pop operand-stack) ,token) operand-stack))
- (t (push token operand-stack))))
- (prog1 (pop operand-stack)
- (when (or op-stack operand-stack)
- (error "Invalid regexp: %s" input))))))
-
-(defun mh-index-add-implicit-ops (tokens)
- "Add implicit operators in the list TOKENS."
- (let ((result ())
- (literal-seen nil)
- current)
- (while tokens
- (setq current (pop tokens))
- (cond ((or (equal current ")") (equal current "and") (equal current "or"))
- (setq literal-seen nil)
- (push current result))
- ((and literal-seen
- (push "and" result)
- (setq literal-seen nil)
- nil))
- (t
- (push current result)
- (unless (or (equal current "(") (equal current "not"))
- (setq literal-seen t)))))
- (nreverse result)))
-
-(defun mh-index-evaluate (op-stack operand-stack)
- "Read expression till starting paren based on OP-STACK and OPERAND-STACK."
- (cl-block mh-index-evaluate
- (let (op oper1)
- (while op-stack
- (setq op (pop op-stack))
- (cond ((eq op 'paren)
- (cl-return-from mh-index-evaluate (list op-stack operand-stack)))
- ((eq op 'not)
- (push `(not ,(pop operand-stack)) operand-stack))
- ((or (eq op 'and) (eq op 'or))
- (setq oper1 (pop operand-stack))
- (push `(,op ,(pop operand-stack) ,oper1) operand-stack))))
- (error "Ran out of tokens"))))
-
-\f
-
-;;; Indexing Functions
-
-;; Support different search programs
-(defvar mh-search-choices
- '((swish++
- mh-swish++-binary mh-swish++-execute-search mh-swish++-next-result
- mh-swish++-regexp-builder)
- (swish
- mh-swish-binary mh-swish-execute-search mh-swish-next-result nil)
- (mairix
- mh-mairix-binary mh-mairix-execute-search mh-mairix-next-result
- mh-mairix-regexp-builder)
- (namazu
- mh-namazu-binary mh-namazu-execute-search mh-namazu-next-result nil)
- (pick
- mh-pick-binary mh-pick-execute-search mh-pick-next-result
- mh-pick-regexp-builder)
- (grep
- mh-grep-binary mh-grep-execute-search mh-grep-next-result nil))
- "List of possible searcher choices.")
-
-(defun mh-search-choose (&optional searcher)
- "Choose a searching function.
-The side-effects of this function are that the variables
-`mh-searcher', `mh-search-function', and
-`mh-search-next-result-function' are set according to the first
-searcher in `mh-search-choices' present on the system. If
-optional argument SEARCHER is present, use it instead of
-`mh-search-program'."
- (cl-block nil
- (let ((program-alist (cond (searcher
- (list (assoc searcher mh-search-choices)))
- (mh-search-program
- (list
- (assoc mh-search-program mh-search-choices)))
- (t mh-search-choices))))
- (while program-alist
- (let* ((current (pop program-alist))
- (executable (symbol-value (cadr current))))
- (when executable
- (setq mh-searcher (car current))
- (setq mh-search-function (nth 2 current))
- (setq mh-search-next-result-function (nth 3 current))
- (setq mh-search-regexp-builder (nth 4 current))
- (cl-return mh-searcher))))
- nil)))
-
-;;; Swish++
-
-(defvar mh-swish++-binary (or (executable-find "search++")
- (executable-find "search")))
-(defvar mh-swish++-directory ".swish++")
-(defvar mh-swish-folder nil)
-
-(defun mh-swish++-execute-search (folder-path search-regexp)
- "Execute swish++.
-
-In the examples below, replace \"/home/user/Mail\" with the path to
-your MH directory.
-
-First create the directory \"/home/user/Mail/.swish++\". Then create
-the file \"/home/user/Mail/.swish++/swish++.conf\" with the following
-contents:
-
- IncludeMeta Bcc Cc Comments Content-Description From Keywords
- IncludeMeta Newsgroups Resent-To Subject To
- IncludeMeta Message-Id References In-Reply-To
- IncludeFile Mail *
- IndexFile /home/user/Mail/.swish++/swish++.index
-
-Use the following command line to generate the swish index. Run
-this daily from cron:
-
- find /home/user/Mail -path /home/user/Mail/mhe-index -prune \\
- -o -path /home/user/Mail/.swish++ -prune \\
- -o -name \"[0-9]*\" -print \\
- | index -c /home/user/Mail/.swish++/swish++.conf -
-
-This command does not index the folders that hold the results of your
-searches in \"+mhe-index\" since they tend to be ephemeral and the
-original messages are indexed anyway.
-
-On some systems (Debian GNU/Linux, for example), use \"index++\"
-instead of \"index\".
-
-In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP is
-used to search."
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (unless mh-swish++-binary
- (error "Set `mh-swish++-binary' appropriately"))
- (call-process mh-swish++-binary nil '(t nil) nil
- "-m" "10000"
- (format "-i%s%s/swish++.index"
- mh-user-path mh-swish++-directory)
- search-regexp)
- (goto-char (point-min))
- (setq mh-swish-folder
- (let ((last-char (substring folder-path (1- (length folder-path)))))
- (if (equal last-char "/")
- folder-path
- (format "%s/" folder-path)))))
-
-(defalias 'mh-swish++-next-result #'mh-swish-next-result)
-
-(defun mh-swish++-regexp-builder (regexp-list)
- "Generate query for swish++.
-REGEXP-LIST is an alist of fields and values."
- (let ((regexp ""))
- (dolist (elem regexp-list)
- (when (cdr elem)
- (setq regexp (concat regexp " and "
- (if (car elem) "(" "")
- (if (car elem) (symbol-name (car elem)) "")
- (if (car elem) " = " "")
- (mh-swish++-print-regexp (cdr elem))
- (if (car elem) ")" "")))))
- (substring regexp 4)))
-
-(defun mh-swish++-print-regexp (expr)
- "Return infix expression corresponding to EXPR."
- (cond ((atom expr) (format "%s" expr))
- ((eq (car expr) 'not)
- (format "(not %s)" (mh-swish++-print-regexp (cadr expr))))
- (t (format "(%s %s %s)" (mh-swish++-print-regexp (cadr expr))
- (symbol-name (car expr))
- (mh-swish++-print-regexp (caddr expr))))))
-
-;;; Swish
-
-(defvar mh-swish-binary (executable-find "swish-e"))
-(defvar mh-swish-directory ".swish")
-
-(defun mh-swish-execute-search (folder-path search-regexp)
- "Execute swish-e.
-
-In the examples below, replace \"/home/user/Mail\" with the path
-to your MH directory.
-
-First create the directory \"/home/user/Mail/.swish\". Then
-create the file \"/home/user/Mail/.swish/config\" with the
-following contents:
-
- DefaultContents TXT*
- IndexDir /home/user/Mail
- IndexFile /home/user/Mail/.swish/index
- IndexName \"Mail Index\"
- IndexDescription \"Mail Index\"
- IndexPointer \"http://nowhere\"
- IndexAdmin \"nobody\"
- #MetaNames automatic
- IndexReport 3
- FollowSymLinks no
- UseStemming no
- IgnoreTotalWordCountWhenRanking yes
- WordCharacters abcdefghijklmnopqrstuvwxyz0123456789-
- BeginCharacters abcdefghijklmnopqrstuvwxyz
- EndCharacters abcdefghijklmnopqrstuvwxyz0123456789
- IgnoreLimit 50 1000
- IndexComments 0
- FileRules filename contains \\D
- FileRules pathname contains /home/user/Mail/.swish
- FileRules pathname contains /home/user/Mail/mhe-index
-
-This configuration does not index the folders that hold the
-results of your searches in \"+mhe-index\" since they tend to be
-ephemeral and the original messages are indexed anyway.
-
-If there are any directories you would like to ignore, append
-lines like the following to \"config\":
-
- FileRules pathname contains /home/user/Mail/scripts
-
-Use the following command line to generate the swish index. Run
-this daily from cron:
-
- swish-e -c /home/user/Mail/.swish/config
-
-In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
-is used to search."
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (unless mh-swish-binary
- (error "Set `mh-swish-binary' appropriately"))
- (call-process mh-swish-binary nil '(t nil) nil
- "-w" search-regexp
- "-f" (format "%s%s/index" mh-user-path mh-swish-directory))
- (goto-char (point-min))
- (setq mh-swish-folder
- (let ((last-char (substring folder-path (1- (length folder-path)))))
- (if (equal last-char "/")
- folder-path
- (format "%s/" folder-path)))))
-
-(defun mh-swish-next-result ()
- "Get the next result from swish output."
- (prog1
- (cl-block nil
- (when (or (eobp) (equal (char-after (point)) ?.))
- (cl-return nil))
- (when (equal (char-after (point)) ?#)
- (cl-return 'error))
- (let* ((start (search-forward " " (line-end-position) t))
- (end (search-forward " " (line-end-position) t)))
- (unless (and start end)
- (cl-return 'error))
- (setq end (1- end))
- (unless (file-exists-p (buffer-substring-no-properties start end))
- (cl-return 'error))
- (unless (search-backward "/" start t)
- (cl-return 'error))
- (list (let* ((s (buffer-substring-no-properties start (1+ (point)))))
- (unless (string-match mh-swish-folder s)
- (cl-return 'error))
- (if (and (string-match mh-user-path s)
- (< (match-end 0) (1- (length s))))
- (format "+%s"
- (substring s (match-end 0) (1- (length s))))
- (cl-return 'error)))
- (let* ((s (buffer-substring-no-properties (1+ (point)) end))
- (n (ignore-errors (string-to-number s))))
- (or n (cl-return 'error)))
- nil)))
- (forward-line)))
-
-;;; Mairix
-
-(defvar mh-mairix-binary (executable-find "mairix"))
-(defvar mh-mairix-directory ".mairix")
-(defvar mh-mairix-folder nil)
-
-(defun mh-mairix-execute-search (folder-path search-regexp-list)
- "Execute mairix.
-
-In the examples below, replace \"/home/user/Mail\" with the path
-to your MH directory.
-
-First create the directory \"/home/user/Mail/.mairix\". Then
-create the file \"/home/user/Mail/.mairix/config\" with the
-following contents:
-
- base=/home/user/Mail
-
- # List of folders that should be indexed. 3 dots at the end means there
- # are subfolders within the folder
- mh=archive...:inbox:drafts:news:sent:trash
-
- vfolder_format=mh
- database=/home/user/Mail/.mairix/database
-
-Use the following command line to generate the mairix index. Run
-this daily from cron:
-
- mairix -f /home/user/Mail/.mairix/config
-
-In a program, FOLDER-PATH is the directory in which
-SEARCH-REGEXP-LIST is used to search."
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (unless mh-mairix-binary
- (error "Set `mh-mairix-binary' appropriately"))
- (apply #'call-process mh-mairix-binary nil '(t nil) nil
- "-r" "-f" (format "%s%s/config" mh-user-path mh-mairix-directory)
- search-regexp-list)
- (goto-char (point-min))
- (setq mh-mairix-folder
- (let ((last-char (substring folder-path (1- (length folder-path)))))
- (if (equal last-char "/")
- folder-path
- (format "%s/" folder-path)))))
-
-(defun mh-mairix-next-result ()
- "Return next result from mairix output."
- (prog1
- (cl-block nil
- (when (or (eobp) (and (bolp) (eolp)))
- (cl-return nil))
- (unless (eq (char-after) ?/)
- (cl-return 'error))
- (let ((start (point))
- end msg-start)
- (setq end (line-end-position))
- (unless (search-forward mh-mairix-folder end t)
- (cl-return 'error))
- (goto-char (match-beginning 0))
- (unless (equal (point) start)
- (cl-return 'error))
- (goto-char end)
- (unless (search-backward "/" start t)
- (cl-return 'error))
- (setq msg-start (1+ (point)))
- (goto-char start)
- (unless (search-forward mh-user-path end t)
- (cl-return 'error))
- (list (format "+%s" (buffer-substring-no-properties
- (point) (1- msg-start)))
- (string-to-number
- (buffer-substring-no-properties msg-start end))
- nil)))
- (forward-line)))
-
-(defun mh-mairix-regexp-builder (regexp-list)
- "Generate query for mairix.
-REGEXP-LIST is an alist of fields and values."
- (let ((result ()))
- (dolist (pair regexp-list)
- (when (cdr pair)
- (push
- (concat
- (cond ((eq (car pair) 'to) "t:")
- ((eq (car pair) 'from) "f:")
- ((eq (car pair) 'cc) "c:")
- ((eq (car pair) 'to-or-cc) "tc:")
- ((eq (car pair) 'address) "a:")
- ((eq (car pair) 'subject) "s:")
- ((eq (car pair) 'subject-or-body) "bs:")
- ((eq (car pair) 'date) "d:")
- ((eq (car pair) 'message-id) "m:")
- ((eq (car pair) 'message-body) "b:")
- ((eq (car pair) 'message-size) "z:")
- ((eq (car pair) 'message-attachment-name) "n:")
- ((eq (car pair) 'message-flags) "F:")
- (t ""))
- (let ((sop (cdr (mh-mairix-convert-to-sop* (cdr pair))))
- (final ""))
- (dolist (conjunct sop)
- (let ((expr-list (cdr conjunct))
- (expr-string ""))
- (dolist (e expr-list)
- (setq expr-string (concat expr-string ","
- (if (atom e) "" "~")
- (if (atom e) e (cadr e)))))
- (setq final (concat final "/" (substring expr-string 1)))))
- (substring final 1)))
- result)))
- result))
-
-(defun mh-mairix-convert-to-sop* (expr)
- "Convert EXPR to sum of product form."
- (cond ((atom expr) `(or (and ,expr)))
- ((eq (car expr) 'or)
- (cons 'or
- (cl-loop for e in (mapcar #'mh-mairix-convert-to-sop* (cdr expr))
- append (cdr e))))
- ((eq (car expr) 'and)
- (let ((conjuncts (mapcar #'mh-mairix-convert-to-sop* (cdr expr)))
- result next-factor)
- (setq result (pop conjuncts))
- (while conjuncts
- (setq next-factor (pop conjuncts))
- (setq result (let ((res ()))
- (dolist (t1 (cdr result))
- (dolist (t2 (cdr next-factor))
- (push `(and ,@(cdr t1) ,@(cdr t2)) res)))
- (cons 'or res))))
- result))
- ((atom (cadr expr)) `(or (and ,expr)))
- ((eq (caadr expr) 'not) (mh-mairix-convert-to-sop* (cadadr expr)))
- ((eq (caadr expr) 'and) (mh-mairix-convert-to-sop*
- `(or ,@(mapcar (lambda (x) `(not ,x))
- (cdadr expr)))))
- ((eq (caadr expr) 'or) (mh-mairix-convert-to-sop*
- `(and ,@(mapcar (lambda (x) `(not ,x))
- (cdadr expr)))))
- (t (error "Unreachable: %s" expr))))
-
-;;; Namazu
-
-(defvar mh-namazu-binary (executable-find "namazu"))
-(defvar mh-namazu-directory ".namazu")
-(defvar mh-namazu-folder nil)
-
-(defun mh-namazu-execute-search (folder-path search-regexp)
- "Execute namazu.
-
-In the examples below, replace \"/home/user/Mail\" with the path to
-your MH directory.
-
-First create the directory \"/home/user/Mail/.namazu\". Then create
-the file \"/home/user/Mail/.namazu/mknmzrc\" with the following
-contents:
-
- package conf; # Don't remove this line!
- $ADDRESS = \\='user@localhost\\=';
- $ALLOW_FILE = \"[0-9]*\";
- $EXCLUDE_PATH = \"^/home/user/Mail/(mhe-index|spam)\";
-
-This configuration does not index the folders that hold the results of
-your searches in \"+mhe-index\" since they tend to be ephemeral and
-the original messages are indexed anyway.
-
-Use the following command line to generate the namazu index. Run this
-daily from cron:
-
- mknmz -f /home/user/Mail/.namazu/mknmzrc -O /home/user/Mail/.namazu \\
- -q /home/user/Mail
-
-In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
-is used to search."
- (let ((namazu-index-directory
- (format "%s%s" mh-user-path mh-namazu-directory)))
- (unless (file-exists-p namazu-index-directory)
- (error "Namazu directory %s not present" namazu-index-directory))
- (unless (executable-find mh-namazu-binary)
- (error "Set `mh-namazu-binary' appropriately"))
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (call-process mh-namazu-binary nil '(t nil) nil
- "-alR" search-regexp namazu-index-directory)
- (goto-char (point-min))
- (setq mh-namazu-folder
- (let ((last (substring folder-path (1- (length folder-path)))))
- (if (equal last "/")
- folder-path
- (format "%s/" folder-path))))))
-
-(defun mh-namazu-next-result ()
- "Get the next result from namazu output."
- (prog1
- (cl-block nil
- (when (eobp) (cl-return nil))
- (let ((file-name (buffer-substring-no-properties
- (point) (line-end-position))))
- (unless (equal (string-match mh-namazu-folder file-name) 0)
- (cl-return 'error))
- (unless (file-exists-p file-name)
- (cl-return 'error))
- (string-match mh-user-path file-name)
- (let* ((folder/msg (substring file-name (match-end 0)))
- (mark (mh-search-from-end ?/ folder/msg)))
- (unless mark (cl-return 'error))
- (list (format "+%s" (substring folder/msg 0 mark))
- (let ((n (ignore-errors (string-to-number
- (substring folder/msg (1+ mark))))))
- (or n (cl-return 'error)))
- nil))))
- (forward-line)))
-
-;;; Pick
-
-(defvar mh-index-pick-folder)
-(defvar mh-pick-binary "pick")
-(defconst mh-pick-single-dash '(cc date from subject to)
- "Search components that are supported by single-dash option in pick.")
-
-(defun mh-pick-execute-search (folder-path search-regexp)
- "Execute pick.
-
-Read \"pick(1)\" or the section Finding Messages with pick in the
-MH book to find out more about how to enter the criteria (see URL
-`http://www.ics.uci.edu/~mh/book/mh/finpic.htm').
-
-In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
-is used to search."
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (let ((folders
- (mh-folder-list (substring folder-path (length mh-user-path)))))
- (cl-loop for folder in folders do
- (setq folder (concat "+" folder))
- (insert folder "\n")
- (apply #'call-process (expand-file-name "pick" mh-progs)
- nil '(t nil) nil folder "-list" search-regexp)))
- (goto-char (point-min)))
-
-(defun mh-pick-next-result ()
- "Return the next pick search result."
- (prog1
- (cl-block nil
- (when (eobp) (cl-return nil))
- (when (search-forward-regexp "^\\+" (line-end-position) t)
- (setq mh-index-pick-folder
- (buffer-substring-no-properties (line-beginning-position)
- (line-end-position)))
- (cl-return 'error))
- (unless (search-forward-regexp "^[1-9][0-9]*$" (line-end-position) t)
- (cl-return 'error))
- (list mh-index-pick-folder
- (string-to-number
- (buffer-substring-no-properties (line-beginning-position)
- (line-end-position)))
- nil))
- (forward-line)))
-
-;; All implementations of pick have special options -cc, -date, -from and
-;; -subject that allow searching for corresponding components. Any other
-;; component is searched using option --COMPNAME, for example: `pick
-;; --x-mailer mh-e'. Mailutils "pick" supports this option using a certain
-;; kludge, but it prefers the following syntax for this purpose:
-;; "--component=COMPNAME --pattern=PATTERN".
-;; -- Sergey Poznyakoff, Aug 2003
-(defun mh-pick-regexp-builder (pattern-list)
- "Generate pick search expression from PATTERN-LIST."
- (let ((result ()))
- (dolist (pattern pattern-list)
- (when (cdr pattern)
- (setq result `(,@result "-and" "-lbrace"
- ,@(mh-pick-construct-regexp
- (if (and (mh-variant-p 'gnu-mh) (car pattern))
- (format "--pattern=%s" (cdr pattern))
- (cdr pattern))
- (if (car pattern)
- (cond
- ((mh-variant-p 'gnu-mh)
- (format "--component=%s" (car pattern)))
- ((member (car pattern) mh-pick-single-dash)
- (format "-%s" (car pattern)))
- (t
- (format "--%s" (car pattern))))
- "-search"))
- "-rbrace"))))
- (cdr result)))
-
-(defun mh-pick-construct-regexp (expr component)
- "Construct pick compatible expression corresponding to EXPR.
-COMPONENT is the component to search."
- (cond ((atom expr) (list component expr))
- ((eq (car expr) 'and)
- `("-lbrace" ,@(mh-pick-construct-regexp (cadr expr) component) "-and"
- ,@(mh-pick-construct-regexp (caddr expr) component) "-rbrace"))
- ((eq (car expr) 'or)
- `("-lbrace" ,@(mh-pick-construct-regexp (cadr expr) component) "-or"
- ,@(mh-pick-construct-regexp (caddr expr) component) "-rbrace"))
- ((eq (car expr) 'not)
- `("-lbrace" "-not" ,@(mh-pick-construct-regexp (cadr expr) component)
- "-rbrace"))
- (t (error "Unknown operator %s seen" (car expr)))))
-
-;;; Grep
-
-(defvar mh-grep-binary (executable-find "grep"))
-
-(defun mh-grep-execute-search (folder-path search-regexp)
- "Execute grep.
-
-Unlike the other search methods, this method does not use the
-MH-Search buffer. Instead, you simply enter a regular expression
-in the minibuffer. For help in constructing regular expressions,
-see your man page for \"grep\".
-
-In a program, FOLDER-PATH is the directory in which SEARCH-REGEXP
-is used to search."
- (set-buffer (get-buffer-create mh-temp-index-buffer))
- (erase-buffer)
- (call-process mh-grep-binary nil '(t nil) nil
- "-i" "-r" search-regexp folder-path)
- (goto-char (point-min)))
-
-(defun mh-grep-next-result ()
- "Read the next result.
-Parse it and return the message folder, message index and the
-match. If no other matches left then return nil. If the current
-record is invalid return `error'."
- (prog1
- (cl-block nil
- (when (eobp)
- (cl-return nil))
- (let ((eol-pos (line-end-position))
- (bol-pos (line-beginning-position))
- folder-start msg-end)
- (goto-char bol-pos)
- (unless (search-forward mh-user-path eol-pos t)
- (cl-return 'error))
- (setq folder-start (point))
- (unless (search-forward ":" eol-pos t)
- (cl-return 'error))
- (let ((match (buffer-substring-no-properties (point) eol-pos)))
- (forward-char -1)
- (setq msg-end (point))
- (unless (search-backward "/" folder-start t)
- (cl-return 'error))
- (list (format "+%s" (buffer-substring-no-properties
- folder-start (point)))
- (let ((n (ignore-errors (string-to-number
- (buffer-substring-no-properties
- (1+ (point)) msg-end)))))
- (or n (cl-return 'error)))
- match))))
- (forward-line)))
-
-\f
-
-;;; Folder Utilities
-
-;;;###mh-autoload
-(defun mh-index-group-by-folder ()
- "Partition the messages based on source folder.
-Returns an alist with the folder names in the car and the cdr
-being the list of messages originally from that folder."
- (save-excursion
- (goto-char (point-min))
- (let ((result-table (make-hash-table :test #'equal)))
- (cl-loop for msg being the hash-keys of mh-index-msg-checksum-map
- do (push msg (gethash (car (gethash
- (gethash msg
- mh-index-msg-checksum-map)
- mh-index-checksum-origin-map))
- result-table)))
- (cl-loop for x being the hash-keys of result-table
- collect (cons x (nreverse (gethash x result-table)))))))
-
-;;;###mh-autoload
-(defun mh-index-insert-folder-headers ()
- "Annotate the search results with original folder names."
- (let ((cur-msg (mh-get-msg-num nil))
- (old-buffer-modified-flag (buffer-modified-p))
- (buffer-read-only nil)
- current-folder last-folder)
- (goto-char (point-min))
- (while (not (eobp))
- (setq current-folder (car (gethash (gethash (mh-get-msg-num nil)
- mh-index-msg-checksum-map)
- mh-index-checksum-origin-map)))
- (when (and current-folder (not (equal current-folder last-folder)))
- (insert (if last-folder "\n" "") current-folder "\n")
- (setq last-folder current-folder))
- (forward-line))
- (when cur-msg
- (mh-notate-cur)
- (mh-goto-msg cur-msg t))
- (set-buffer-modified-p old-buffer-modified-flag))
- (mh-index-create-imenu-index))
-
-;;;###mh-autoload
-(defun mh-index-delete-folder-headers ()
- "Delete the folder headers."
- (let ((cur-msg (mh-get-msg-num nil))
- (old-buffer-modified-flag (buffer-modified-p))
- (buffer-read-only nil))
- (while (and (not cur-msg) (not (eobp)))
- (forward-line)
- (setq cur-msg (mh-get-msg-num nil)))
- (goto-char (point-min))
- (while (not (eobp))
- (if (or (char-equal (char-after) ?+) (char-equal (char-after) 10))
- (delete-region (point) (progn (forward-line) (point)))
- (forward-line)))
- (when cur-msg (mh-goto-msg cur-msg t t))
- (set-buffer-modified-p old-buffer-modified-flag)))
-
-(require 'which-func)
-
-;;;###mh-autoload
-(defun mh-index-create-imenu-index ()
- "Create alist of folder names and positions in index folder buffers."
- (save-excursion
- (if (boundp 'which-func-mode)
- (setq which-func-mode t))
- (let ((alist ()))
- (goto-char (point-min))
- (while (re-search-forward "^\\+" nil t)
- (save-excursion
- (beginning-of-line)
- (push (cons (buffer-substring-no-properties
- (point) (line-end-position))
- (point-marker))
- alist)))
- (setq imenu--index-alist (nreverse alist)))))
-
-;;;###mh-autoload
-(defun mh-search-p ()
- "Non-nil means that this folder was generated by searching."
- mh-index-data)
-
-(defvar mh-speed-flists-inhibit-flag)
-
-;;;###mh-autoload
-(defun mh-index-execute-commands ()
- "Perform the outstanding operations on the actual messages.
-The copies in the searched folder are then deleted, refiled,
-blocklisted and allowlisted to get the desired result. Before
-processing the messages we make sure that the message is
-identical to the one that the user has marked in the index
-buffer."
- (save-excursion
- (let ((folders ())
- (mh-speed-flists-inhibit-flag t))
- (maphash
- (lambda (folder msgs)
- (push folder folders)
- (if (not (get-buffer folder))
- ;; If source folder not open, just delete the messages...
- (apply #'mh-exec-cmd "rmm" folder (mh-coalesce-msg-list msgs))
- ;; Otherwise delete the messages in the source buffer...
- (with-current-buffer folder
- (let ((old-refile-list mh-refile-list)
- (old-delete-list mh-delete-list)
- (old-blocklist mh-blocklist)
- (old-allowlist mh-allowlist))
- (setq mh-refile-list nil
- mh-delete-list msgs
- mh-blocklist nil
- mh-allowlist nil)
- (unwind-protect (mh-execute-commands)
- (setq mh-refile-list
- (mapcar (lambda (x)
- (cons (car x)
- (cl-loop for y in (cdr x)
- unless (memq y msgs)
- collect y)))
- old-refile-list)
- mh-delete-list
- (cl-loop for x in old-delete-list
- unless (memq x msgs) collect x)
- mh-blocklist
- (cl-loop for x in old-blocklist
- unless (memq x msgs) collect x)
- mh-allowlist
- (cl-loop for x in old-allowlist
- unless (memq x msgs) collect x))
- (mh-set-folder-modified-p (mh-outstanding-commands-p))
- (when (mh-outstanding-commands-p)
- (mh-notate-deleted-and-refiled)))))))
- (mh-index-matching-source-msgs (append (cl-loop for x in mh-refile-list
- append (cdr x))
- mh-delete-list
- mh-blocklist
- mh-allowlist)
- t))
- folders)))
-
-(defun mh-index-generate-pretty-name (string)
- "Given STRING generate a name which is suitable for use as a folder name.
-White space from the beginning and end are removed. All spaces in
-the name are replaced with underscores and all / are replaced
-with $. If STRING is longer than 20 it is truncated too. STRING
-could be a list of strings in which case they are concatenated to
-construct the base name."
- (with-temp-buffer
- (if (stringp string)
- (insert string)
- (when (car string) (insert (car string)))
- (dolist (s (cdr string))
- (insert "_" s)))
- (setq string (mh-replace-string "-lbrace" " "))
- (setq string (mh-replace-string "-rbrace" " "))
- (setq string (mh-replace-string "-search" " "))
- (subst-char-in-region (point-min) (point-max) ?\( ? t)
- (subst-char-in-region (point-min) (point-max) ?\) ? t)
- (subst-char-in-region (point-min) (point-max) ?- ? t)
- (goto-char (point-min))
- (while (and (not (eobp)) (memq (char-after) '(? ?\t ?\n ?\r ?_)))
- (delete-char 1))
- (goto-char (point-max))
- (while (and (not (bobp)) (memq (char-before) '(? ?\t ?\n ?\r ?_)))
- (delete-char -1))
- (subst-char-in-region (point-min) (point-max) ? ?_ t)
- (subst-char-in-region (point-min) (point-max) ?\t ?_ t)
- (subst-char-in-region (point-min) (point-max) ?\n ?_ t)
- (subst-char-in-region (point-min) (point-max) ?\r ?_ t)
- (subst-char-in-region (point-min) (point-max) ?/ ?$ t)
- (let ((out (truncate-string-to-width (buffer-string) 20)))
- (cond ((eq mh-searcher 'flists)
- (format "%s/%s" mh-flists-results-folder mh-flists-sequence))
- ((equal out mh-flists-results-folder) (concat out "1"))
- (t out)))))
-
-(defun mh-folder-exists-p (folder)
- "Check if FOLDER exists."
- (and (mh-folder-name-p folder)
- (save-excursion
- (with-temp-buffer
- (mh-exec-cmd-output "folder" nil "-fast" "-nocreate" folder)
- (goto-char (point-min))
- ;; Strip + from folder; use optional + in regexp.
- (looking-at (format "+?%s" (substring folder 1)))))))
-
-(defun mh-msg-exists-p (msg folder)
- "Check if MSG exists in FOLDER."
- (file-exists-p (format "%s%s/%s" mh-user-path (substring folder 1) msg)))
-
-(defun mh-index-new-folder (name search-regexp)
- "Return a folder name based on NAME for search results of SEARCH-REGEXP.
-
-If folder NAME already exists and was generated for the same
-SEARCH-REGEXP then it is reused.
-
-Otherwise if the folder NAME was generated from a different
-search then check if NAME-2 can be used. Otherwise try NAME-3.
-This is repeated till we find a new folder name.
-
-If the folder returned doesn't exist then it is created."
- (unless (mh-folder-name-p name)
- (error "The argument should be a valid MH folder name"))
- (let ((chosen-name
- (cl-loop for i from 1
- for candidate = (if (equal i 1) name (format "%s-%s" name i))
- when (or (not (mh-folder-exists-p candidate))
- (equal (mh-index-folder-search-regexp candidate)
- search-regexp))
- return candidate)))
- ;; Do pending refiles/deletes...
- (when (get-buffer chosen-name)
- (mh-process-or-undo-commands chosen-name))
- ;; Recreate folder...
- (save-excursion (mh-exec-cmd-quiet nil "rmf" chosen-name))
- (mh-exec-cmd-quiet nil "folder" "-create" "-fast" chosen-name)
- (mh-remove-from-sub-folders-cache chosen-name)
- (when (and (boundp 'speedbar-buffer) speedbar-buffer)
- (mh-speed-add-folder chosen-name))
- chosen-name))
-
-(defun mh-index-folder-search-regexp (folder)
- "If FOLDER was created by an index search, return the search regexp.
-Return nil if FOLDER doesn't exist or the .mhe_index file is
-garbled."
- (ignore-errors
- (with-temp-buffer
- (insert-file-contents
- (format "%s%s/%s" mh-user-path (substring folder 1) mh-index-data-file))
- (goto-char (point-min))
- (forward-list 3)
- (cadr (read (current-buffer))))))
-
-\f
-
-;;; Sequence Support
-
-;;;###mh-autoload
-(defun mh-index-create-sequences ()
- "Mirror sequences present in source folders in index folder."
- (let ((seq-hash (make-hash-table :test #'equal))
- (seq-list ()))
- (cl-loop for folder being the hash-keys of mh-index-data
- do (setf (gethash folder seq-hash)
- (mh-create-sequence-map
- (mh-read-folder-sequences folder nil))))
- (dolist (msg (mh-translate-range mh-current-folder "all"))
- (let* ((checksum (gethash msg mh-index-msg-checksum-map))
- (pair (gethash checksum mh-index-checksum-origin-map))
- (ofolder (car pair))
- (omsg (cdr pair)))
- (cl-loop for seq in (ignore-errors
- (gethash omsg (gethash ofolder seq-hash)))
- do (if (assoc seq seq-list)
- (push msg (cdr (assoc seq seq-list)))
- (push (list seq msg) seq-list)))))
- (cl-loop for seq in seq-list
- do (apply #'mh-exec-cmd "mark" mh-current-folder
- "-sequence" (symbol-name (car seq)) "-add"
- (mapcar (lambda (x) (format "%s" x)) (cdr seq))))))
-
-;;;###mh-autoload
-(defun mh-create-sequence-map (seq-list)
- "Return a map from msg number to list of sequences in which it is present.
-SEQ-LIST is an assoc list whose keys are sequence names and whose
-cdr is the list of messages in that sequence."
- (cl-loop with map = (make-hash-table)
- for seq in seq-list
- when (and (not (memq (car seq) (mh-unpropagated-sequences)))
- (mh-valid-seq-p (car seq)))
- do (cl-loop for msg in (cdr seq)
- do (push (car seq) (gethash msg map)))
- finally return map))
-
-;;;###mh-autoload
-(defun mh-index-add-to-sequence (seq msgs)
- "Add to SEQ the messages in the list MSGS.
-This function updates the source folder sequences. Also makes an
-attempt to update the source folder buffer if we have it open."
- ;; Don't need to do anything for cur
- (save-excursion
- (when (and (not (memq seq (mh-unpropagated-sequences)))
- (mh-valid-seq-p seq))
- (let ((folders ())
- (mh-speed-flists-inhibit-flag t))
- (maphash (lambda (folder msgs)
- (push folder folders)
- ;; Add messages to sequence in source folder...
- (apply #'mh-exec-cmd-quiet nil "mark" folder
- "-add" "-nozero" "-sequence" (symbol-name seq)
- (mapcar (lambda (x) (format "%s" x))
- (mh-coalesce-msg-list msgs)))
- ;; Update source folder buffer if we have it open...
- (when (get-buffer folder)
- (with-current-buffer folder
- (mh-put-msg-in-seq msgs seq))))
- (mh-index-matching-source-msgs msgs))
- folders))))
-
-;;;###mh-autoload
-(defun mh-index-delete-from-sequence (seq msgs)
- "Delete from SEQ the messages in MSGS.
-This function updates the source folder sequences. Also makes an
-attempt to update the source folder buffer if present."
- (save-excursion
- (when (and (not (memq seq (mh-unpropagated-sequences)))
- (mh-valid-seq-p seq))
- (let ((folders ())
- (mh-speed-flists-inhibit-flag t))
- (maphash (lambda (folder msgs)
- (push folder folders)
- ;; Remove messages from sequence in source folder...
- (apply #'mh-exec-cmd-quiet nil "mark" folder
- "-del" "-nozero" "-sequence" (symbol-name seq)
- (mapcar (lambda (x) (format "%s" x))
- (mh-coalesce-msg-list msgs)))
- ;; Update source folder buffer if we have it open...
- (when (get-buffer folder)
- (with-current-buffer folder
- (mh-delete-msg-from-seq msgs seq t))))
- (mh-index-matching-source-msgs msgs))
- folders))))
-
-(defvar mh-unpropagated-sequences '(cur range subject search)
- "List of sequences that aren't preserved.")
-
-(defun mh-unpropagated-sequences ()
- "Return a list of sequences that aren't propagated to the source folders.
-It is just the sequences in the variable
-`mh-unpropagated-sequences' in addition to the
-Previous-Sequence (see mh-profile 5)."
- (if mh-previous-seq
- (cons mh-previous-seq mh-unpropagated-sequences)
- mh-unpropagated-sequences))
-
-(defun mh-index-matching-source-msgs (msgs &optional delete-from-index-data)
- "Return a table of original messages and folders for messages in MSGS.
-If optional argument DELETE-FROM-INDEX-DATA is non-nil, then each
-of the messages, whose counter-part is found in some source
-folder, is removed from `mh-index-data'."
- (let ((table (make-hash-table :test #'equal)))
- (dolist (msg msgs)
- (let* ((checksum (gethash msg mh-index-msg-checksum-map))
- (pair (gethash checksum mh-index-checksum-origin-map)))
- (when (and checksum (car pair) (cdr pair)
- (mh-index-match-checksum (cdr pair) (car pair) checksum))
- (push (cdr pair) (gethash (car pair) table))
- (when delete-from-index-data
- (remhash (cdr pair) (gethash (car pair) mh-index-data))))))
- table))
-
-(defun mh-index-match-checksum (msg folder checksum)
- "Check if MSG in FOLDER has X-MHE-Checksum header value of CHECKSUM."
- (with-temp-buffer
- (mh-exec-cmd-output mh-scan-prog nil "-width" "80"
- "-format" "%{x-mhe-checksum}\n" folder msg)
- (goto-char (point-min))
- (string-equal (buffer-substring-no-properties
- (point) (line-end-position))
- checksum)))
-
-\f
-
-;;; Serialization of Index Data
-
-(defun mh-index-write-data ()
- "Write index data to file."
- (ignore-errors
- (unless (eq major-mode 'mh-folder-mode)
- (error "Can't be called from folder in \"%s\"" major-mode))
- (let ((data mh-index-data)
- (msg-checksum-map mh-index-msg-checksum-map)
- (checksum-origin-map mh-index-checksum-origin-map)
- (previous-search mh-index-previous-search)
- (sequence-search-flag mh-index-sequence-search-flag)
- (outfile (concat buffer-file-name mh-index-data-file))
- (print-length nil)
- (print-level nil))
- (with-temp-file outfile
- (mh-index-write-hashtable
- data (lambda (x) (cl-loop for y being the hash-keys of x collect y)))
- (mh-index-write-hashtable msg-checksum-map #'identity)
- (mh-index-write-hashtable checksum-origin-map #'identity)
- (pp previous-search (current-buffer)) (insert "\n")
- (pp sequence-search-flag (current-buffer)) (insert "\n")))))
-
-(defun mh-index-write-hashtable (table proc)
- "Write TABLE to `current-buffer'.
-PROC is used to serialize the values corresponding to the hash
-table keys."
- (pp (cl-loop for x being the hash-keys of table
- collect (cons x (funcall proc (gethash x table))))
- (current-buffer))
- (insert "\n"))
-
-;;;###mh-autoload
-(defun mh-index-read-data ()
- "Read index data from file."
- (ignore-errors
- (unless (eq major-mode 'mh-folder-mode)
- (error "Can't be called from folder in \"%s\"" major-mode))
- (let ((infile (concat buffer-file-name mh-index-data-file))
- t1 t2 t3 t4 t5)
- (with-temp-buffer
- (insert-file-contents-literally infile)
- (goto-char (point-min))
- (setq t1 (mh-index-read-hashtable
- (lambda (data)
- (cl-loop with table = (make-hash-table :test #'equal)
- for x in data do (setf (gethash x table) t)
- finally return table)))
- t2 (mh-index-read-hashtable #'identity)
- t3 (mh-index-read-hashtable #'identity)
- t4 (read (current-buffer))
- t5 (read (current-buffer))))
- (setq mh-index-data t1
- mh-index-msg-checksum-map t2
- mh-index-checksum-origin-map t3
- mh-index-previous-search t4
- mh-index-sequence-search-flag t5))))
-
-(defun mh-index-read-hashtable (proc)
- "From BUFFER read a hash table serialized as a list.
-PROC is used to convert the value to actual data."
- (cl-loop with table = (make-hash-table :test #'equal)
- for pair in (read (current-buffer))
- do (setf (gethash (car pair) table) (funcall proc (cdr pair)))
- finally return table))
-
-\f
-
-;;; Checksum Routines
-
-;; A few different checksum programs are supported. The supported
-;; programs are:
-
-;; 1. md5sum
-;; 2. md5
-;; 3. openssl
-
-;; To add support for your favorite checksum program add a clause to
-;; the cond statement in mh-checksum-choose. This should set the
-;; variable mh-checksum-cmd to the command line needed to run the
-;; checksum program and should set mh-checksum-parser to a function
-;; which returns a cons cell containing the message number and
-;; checksum string.
-
-(defvar mh-checksum-cmd)
-(defvar mh-checksum-parser)
-
-(defun mh-checksum-choose ()
- "Check if a program to create a checksum is present."
- (unless (boundp 'mh-checksum-cmd)
- (let ((exec-path (append '("/sbin" "/usr/sbin") exec-path)))
- (cond ((executable-find "md5sum")
- (setq mh-checksum-cmd (list (executable-find "md5sum")))
- (setq mh-checksum-parser #'mh-md5sum-parser))
- ((executable-find "openssl")
- (setq mh-checksum-cmd (list (executable-find "openssl") "md5"))
- (setq mh-checksum-parser #'mh-openssl-parser))
- ((executable-find "md5")
- (setq mh-checksum-cmd (list (executable-find "md5")))
- (setq mh-checksum-parser #'mh-md5-parser))
- (t (error "No suitable checksum program"))))))
-
-(defun mh-md5sum-parser ()
- "Parse md5sum output."
- (let ((begin (line-beginning-position))
- (end (line-end-position))
- first-space last-slash)
- (setq first-space (search-forward " " end t))
- (goto-char end)
- (setq last-slash (search-backward "/" begin t))
- (cond ((and first-space last-slash)
- (cons (string-to-number (buffer-substring-no-properties
- (1+ last-slash) end))
- (buffer-substring-no-properties begin (1- first-space))))
- (t (cons nil nil)))))
-
-(defun mh-openssl-parser ()
- "Parse openssl output."
- (let ((begin (line-beginning-position))
- (end (line-end-position))
- last-space last-slash)
- (goto-char end)
- (setq last-space (search-backward " " begin t))
- (setq last-slash (search-backward "/" begin t))
- (cond ((and last-slash last-space)
- (cons (string-to-number (buffer-substring-no-properties
- (1+ last-slash) (1- last-space)))
- (buffer-substring-no-properties (1+ last-space) end))))))
-
-(defalias 'mh-md5-parser #'mh-openssl-parser)
-
-;;;###mh-autoload
-(defun mh-index-update-maps (folder &optional origin-map)
- "Annotate all as yet unannotated messages in FOLDER with their MD5 hash.
-As a side effect msg -> checksum map is updated. Optional
-argument ORIGIN-MAP is a hash table which maps each message in the
-index folder to the original folder and message from whence it
-was copied. If present the checksum -> (origin-folder,
-origin-index) map is updated too."
- (clrhash mh-index-msg-checksum-map)
- ;; Clear temp buffer
- (with-current-buffer (get-buffer-create mh-temp-checksum-buffer)
- (erase-buffer)
- ;; Run scan to check if any messages needs MD5 annotations at all
- (with-temp-buffer
- (mh-exec-cmd-output mh-scan-prog nil "-width" "80"
- "-format" "%(msg)\n%{x-mhe-checksum}\n"
- folder "all")
- (goto-char (point-min))
- (let (msg checksum)
- (while (not (eobp))
- (setq msg (buffer-substring-no-properties
- (point) (line-end-position)))
- (forward-line)
- (save-excursion
- (cond ((not (string-match "^[0-9]*$" msg)))
- ((eolp)
- ;; need to compute checksum
- (set-buffer mh-temp-checksum-buffer)
- (insert mh-user-path (substring folder 1) "/" msg "\n"))
- (t
- ;; update maps
- (setq checksum (buffer-substring-no-properties
- (point) (line-end-position)))
- (let ((msg (string-to-number msg)))
- (set-buffer folder)
- (mh-index-update-single-msg msg checksum origin-map)))))
- (forward-line))))
- ;; Run checksum program if needed
- (unless (and (eobp) (bobp))
- (apply #'mh-xargs mh-checksum-cmd)
- (goto-char (point-min))
- (while (not (eobp))
- (let* ((intermediate (funcall mh-checksum-parser))
- (msg (car intermediate))
- (checksum (cdr intermediate)))
- (when msg
- ;; annotate
- (mh-exec-cmd "anno" folder msg "-component" "X-MHE-Checksum"
- "-nodate" "-text" checksum "-inplace")
- ;; update maps
- (with-current-buffer folder
- (mh-index-update-single-msg msg checksum origin-map)))
- (forward-line)))))
- (mh-index-write-data))
-
-(defun mh-index-update-single-msg (msg checksum origin-map)
- "Update various maps for one message.
-MSG is an index folder message, CHECKSUM its MD5 hash and
-ORIGIN-MAP, if non-nil, a hash table containing which maps each
-message in the index folder to the folder and message that it was
-copied from. The function updates the hash tables
-`mh-index-msg-checksum-map' and `mh-index-checksum-origin-map'.
-
-This function should only be called in the appropriate index
-folder buffer."
- (cond ((gethash checksum mh-index-checksum-origin-map)
- (when origin-map
- (let* ((intermediate (gethash msg origin-map))
- (ofolder (car intermediate))
- (omsg (cdr intermediate)))
- ;; This is most probably a duplicate. So eliminate it.
- (call-process "rm" nil nil nil
- (format "%s%s/%s" mh-user-path
- (substring mh-current-folder 1) msg))
- (when (gethash ofolder mh-index-data)
- (remhash omsg (gethash ofolder mh-index-data))))))
- (t
- (setf (gethash msg mh-index-msg-checksum-map) checksum)
- (when (and origin-map (gethash msg origin-map))
- (setf (gethash checksum mh-index-checksum-origin-map)
- (gethash msg origin-map))))))
-
-
-(provide 'mh-search)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-search.el ends here
+++ /dev/null
-;;; mh-seq.el --- MH-E sequences support -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Sequences are stored in the alist `mh-seq-list' in the form:
-;; ((seq-name msgs ...) (seq-name msgs ...) ...)
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-(require 'font-lock)
-
-;;; Variables
-
-(defvar mh-last-seq-used nil
- "Name of seq to which a msg was last added.")
-
-(defvar-local mh-non-seq-mode-line-annotation nil
- "Saved value of `mh-mode-line-annotation' when narrowed to a seq.")
-
-(defvar mh-internal-seqs '(answered cur deleted forwarded printed))
-
-;;; Macros
-
-(defsubst mh-make-seq (name msgs)
- "Create sequence NAME with the given MSGS."
- (cons name msgs))
-
-(defsubst mh-seq-name (sequence)
- "Extract sequence name from the given SEQUENCE."
- (car sequence))
-
-\f
-
-;;; MH-Folder Commands
-
-;; Alphabetical.
-
-;;;###mh-autoload
-(defun mh-catchup (range)
- "Delete RANGE from the \"unseen\" sequence.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (interactive (list (mh-interactive-range "Catchup"
- (cons (point-min) (point-max)))))
- (mh-delete-msg-from-seq range mh-unseen-seq))
-
-;;;###mh-autoload
-(defun mh-delete-msg-from-seq (range sequence &optional internal-flag)
- "Delete RANGE from SEQUENCE.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use.
-
-In a program, non-nil INTERNAL-FLAG means do not inform MH of the
-change."
- (interactive (list (mh-interactive-range "Delete")
- (mh-read-seq-default "Delete from" t)
- nil))
- (let ((entry (mh-find-seq sequence))
- (user-sequence-flag (not (mh-internal-seq sequence)))
- (folders-changed (list mh-current-folder))
- (msg-list ()))
- (when entry
- (mh-iterate-on-range msg range
- (push msg msg-list)
- ;; Calling "mark" repeatedly takes too long. So we will pretend here
- ;; that we are just modifying an internal sequence...
- (when (memq msg (cdr entry))
- (mh-remove-sequence-notation msg (not user-sequence-flag)))
- (mh-delete-a-msg-from-seq msg sequence t))
- ;; ... and here we will "mark" all the messages at one go.
- (unless internal-flag (mh-undefine-sequence sequence msg-list))
- (when (and mh-index-data (not internal-flag))
- (setq folders-changed
- (append folders-changed
- (mh-index-delete-from-sequence sequence msg-list))))
- (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p))
- (apply #'mh-speed-flists t folders-changed)))))
-
-;;;###mh-autoload
-(defun mh-delete-seq (sequence)
- "Delete SEQUENCE.
-
-You are prompted for the sequence to delete. Note that this
-deletes only the sequence, not the messages in the sequence. If
-you want to delete the messages, use \"\\[universal-argument]
-\\[mh-delete-msg]\"."
- (interactive (list (mh-read-seq-default "Delete" t)))
- (let ((msg-list (mh-seq-to-msgs sequence))
- (internal-flag (mh-internal-seq sequence))
- (folders-changed (list mh-current-folder)))
- (mh-iterate-on-range msg sequence
- (mh-remove-sequence-notation msg internal-flag))
- (mh-undefine-sequence sequence '("all"))
- (mh-delete-seq-locally sequence)
- (when mh-index-data
- (setq folders-changed
- (append folders-changed
- (mh-index-delete-from-sequence sequence msg-list))))
- (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p))
- (apply #'mh-speed-flists t folders-changed))))
-
-;; Shush compiler.
-(defvar view-exit-action)
-
-;;;###mh-autoload
-(defun mh-list-sequences ()
- "List all sequences in folder.
-
-The list appears in a buffer named \"*MH-E Sequences*\"."
- (interactive)
- (let ((folder mh-current-folder)
- (temp-buffer mh-sequences-buffer)
- (seq-list mh-seq-list)
- (max-len 0))
- (with-output-to-temp-buffer temp-buffer
- (with-current-buffer temp-buffer
- (erase-buffer)
- (message "Listing sequences ...")
- (insert "Sequences in folder " folder ":\n")
- (let ((seq-list seq-list))
- (while seq-list
- (setq max-len
- (max (length (symbol-name (mh-seq-name (pop seq-list))))
- max-len)))
- (setq max-len (+ 2 max-len)))
- (while seq-list
- (let ((name (mh-seq-name (car seq-list)))
- (sorted-seq-msgs
- (mh-coalesce-msg-list
- (sort (copy-sequence (mh-seq-msgs (car seq-list))) #'<)))
- name-spec)
- (insert (setq name-spec (format (format "%%%ss:" max-len) name)))
- (while sorted-seq-msgs
- (let ((next-element (format " %s" (pop sorted-seq-msgs))))
- (when (>= (+ (current-column) (length next-element))
- (window-width))
- (insert "\n")
- (insert (format (format "%%%ss" (length name-spec)) "")))
- (insert next-element)))
- (insert "\n"))
- (setq seq-list (cdr seq-list)))
- (goto-char (point-min))
- (view-mode-enter)
- (setq view-exit-action 'kill-buffer)
- (message "Listing sequences...done")))))
-
-;;;###mh-autoload
-(defun mh-msg-is-in-seq (message)
- "Display the sequences in which the current message appears.
-
-Use a prefix argument to display the sequences in which another
-MESSAGE appears."
- (interactive "P")
- (if (not message)
- (setq message (mh-get-msg-num t)))
- (let* ((dest-folder (cl-loop for seq in mh-refile-list
- when (member message (cdr seq)) return (car seq)
- finally return nil))
- (deleted-flag (unless dest-folder (member message mh-delete-list))))
- (message "Message %d%s is in sequences: %s"
- message
- (cond (dest-folder (format " (to be refiled to %s)" dest-folder))
- (deleted-flag " (to be deleted)")
- (t ""))
- (mapconcat #'concat
- (mh-list-to-string (mh-seq-containing-msg message t))
- " "))))
-
-;;;###mh-autoload
-(defun mh-narrow-to-seq (sequence)
- "Restrict display to messages in SEQUENCE.
-
-You are prompted for the name of the sequence. What this command
-does is show only those messages that are in the selected
-sequence in the MH-Folder buffer. In addition, it limits further
-MH-E searches to just those messages.
-
-When you want to widen the view to all your messages again, use
-\\[mh-widen]."
- (interactive (list (mh-read-seq "Narrow to" t)))
- (with-mh-folder-updating (t)
- (cond ((mh-seq-to-msgs sequence)
- (mh-remove-all-notation)
- (let ((eob (point-max))
- (msg-at-cursor (mh-get-msg-num nil)))
- (push mh-thread-scan-line-map mh-thread-scan-line-map-stack)
- (setq mh-thread-scan-line-map (make-hash-table :test #'eql))
- (mh-copy-seq-to-eob sequence)
- (push (buffer-substring-no-properties (point-min) eob)
- mh-folder-view-stack)
- (delete-region (point-min) eob)
- (mh-notate-deleted-and-refiled)
- (mh-notate-cur)
- (when msg-at-cursor (mh-goto-msg msg-at-cursor t t))
- (setq mh-non-seq-mode-line-annotation mh-mode-line-annotation)
- (setq mh-mode-line-annotation (symbol-name sequence))
- (mh-make-folder-mode-line)
- (mh-recenter nil)
- (when (and (boundp 'tool-bar-mode) tool-bar-mode)
- (setq-local tool-bar-map
- mh-folder-seq-tool-bar-map)
- (when (buffer-live-p (get-buffer mh-show-buffer))
- (with-current-buffer mh-show-buffer
- (setq-local tool-bar-map
- mh-show-seq-tool-bar-map))))
- (push 'widen mh-view-ops)))
- (t
- (error "No messages in sequence %s" (symbol-name sequence))))))
-
-;;;###mh-autoload
-(defun mh-narrow-to-tick ()
- "Limit to ticked messages.
-
-What this command does is show only those messages that are in
-the \"tick\" sequence (which you can customize via the
-`mh-tick-seq' option) in the MH-Folder buffer. In addition, it
-limits further MH-E searches to just those messages. When you
-want to widen the view to all your messages again, use
-\\[mh-widen]."
- (interactive)
- (cond ((not mh-tick-seq)
- (error "Enable ticking by customizing `mh-tick-seq'"))
- ((null (mh-seq-msgs (mh-find-seq mh-tick-seq)))
- (message "No messages in %s sequence" mh-tick-seq))
- (t (mh-narrow-to-seq mh-tick-seq))))
-
-;;;###mh-autoload
-(defun mh-put-msg-in-seq (range sequence)
- "Add RANGE to SEQUENCE\\<mh-folder-mode-map>.
-
-Give this command a RANGE and you can add all the messages in a
-sequence to another sequence (for example,
-\"\\[universal-argument] \\[mh-put-msg-in-seq] SourceSequence RET
-DestSequence RET\"). Check the documentation of
-`mh-interactive-range' to see how RANGE is read in interactive
-use."
- (interactive (list (mh-interactive-range "Add messages from")
- (mh-read-seq-default "Add to" nil)))
- (unless (mh-valid-seq-p sequence)
- (error "Can't put message in invalid sequence %s" sequence))
- (let* ((internal-seq-flag (mh-internal-seq sequence))
- (original-msgs (mh-seq-msgs (mh-find-seq sequence)))
- (folders (list mh-current-folder))
- (msg-list (mh-range-to-msg-list range)))
- (mh-add-msgs-to-seq msg-list sequence nil t)
- (mh-iterate-on-range m range
- (unless (memq m original-msgs)
- (mh-add-sequence-notation m internal-seq-flag)))
- (if (not internal-seq-flag)
- (setq mh-last-seq-used sequence))
- (when mh-index-data
- (setq folders
- (append folders (mh-index-add-to-sequence sequence msg-list))))
- (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p))
- (apply #'mh-speed-flists t folders))))
-
-;;;###mh-autoload
-(defun mh-toggle-tick (range)
- "Toggle tick mark of RANGE.
-
-This command adds messages to the \"tick\" sequence (which you can customize
-via the option `mh-tick-seq'). This sequence can be viewed later with the
-\\[mh-index-ticked-messages] command.
-
-Check the documentation of `mh-interactive-range' to see how RANGE is read in
-interactive use."
- (interactive (list (mh-interactive-range "Tick")))
- (unless mh-tick-seq
- (error "Enable ticking by customizing `mh-tick-seq'"))
- (let* ((tick-seq (mh-find-seq mh-tick-seq))
- (tick-seq-msgs (mh-seq-msgs tick-seq))
- (ticked ())
- (unticked ()))
- (mh-iterate-on-range msg range
- (cond ((member msg tick-seq-msgs)
- (push msg unticked)
- (setcdr tick-seq (delq msg (cdr tick-seq)))
- (when (null (cdr tick-seq)) (setq mh-last-seq-used nil))
- (mh-remove-sequence-notation msg (mh-colors-in-use-p)))
- (t
- (push msg ticked)
- (setq mh-last-seq-used mh-tick-seq)
- (let ((mh-seq-list (cons `(,mh-tick-seq ,msg) mh-seq-list)))
- (mh-add-sequence-notation msg (mh-colors-in-use-p))))))
- (mh-add-msgs-to-seq ticked mh-tick-seq nil t)
- (mh-undefine-sequence mh-tick-seq unticked)
- (when mh-index-data
- (mh-index-add-to-sequence mh-tick-seq ticked)
- (mh-index-delete-from-sequence mh-tick-seq unticked))))
-
-;;;###mh-autoload
-(defun mh-widen (&optional all-flag)
- "Remove last restriction.
-
-Each limit or sequence restriction can be undone in turn with
-this command. Give this command a prefix argument ALL-FLAG to
-remove all limits and sequence restrictions."
- (interactive "P")
- (let ((msg (mh-get-msg-num nil)))
- (when mh-folder-view-stack
- (cond (all-flag
- (while (cdr mh-view-ops)
- (setq mh-view-ops (cdr mh-view-ops)))
- (when (eq (car mh-view-ops) 'widen)
- (setq mh-view-ops (cdr mh-view-ops))))
- ((mh-valid-view-change-operation-p 'widen) nil)
- ((memq 'widen mh-view-ops)
- (while (not (eq (car mh-view-ops) 'widen))
- (setq mh-view-ops (cdr mh-view-ops)))
- (setq mh-view-ops (cdr mh-view-ops)))
- (t (error "Widening is not applicable")))
- ;; If ALL-FLAG is non-nil then rewind stacks
- (when all-flag
- (while (cdr mh-thread-scan-line-map-stack)
- (setq mh-thread-scan-line-map-stack
- (cdr mh-thread-scan-line-map-stack)))
- (while (cdr mh-folder-view-stack)
- (setq mh-folder-view-stack (cdr mh-folder-view-stack))))
- (setq mh-thread-scan-line-map (pop mh-thread-scan-line-map-stack))
- (with-mh-folder-updating (t)
- (delete-region (point-min) (point-max))
- (insert (pop mh-folder-view-stack))
- (mh-remove-all-notation)
- (setq mh-mode-line-annotation mh-non-seq-mode-line-annotation)
- (mh-make-folder-mode-line))
- (if msg
- (mh-goto-msg msg t t))
- (mh-notate-deleted-and-refiled)
- (mh-notate-user-sequences)
- (mh-notate-cur)
- (mh-recenter nil)))
- (when (and (null mh-folder-view-stack) (boundp 'tool-bar-mode) tool-bar-mode)
- (setq-local tool-bar-map mh-folder-tool-bar-map)
- (when (buffer-live-p (get-buffer mh-show-buffer))
- (with-current-buffer mh-show-buffer
- (setq-local tool-bar-map mh-show-tool-bar-map)))))
-
-\f
-
-;;; Support Routines
-
-(defvar mh-sequence-history ())
-
-;;;###mh-autoload
-(defun mh-read-seq-default (prompt not-empty)
- "Read and return sequence name with default narrowed or previous sequence.
-PROMPT is the prompt to use when reading. If NOT-EMPTY is non-nil
-then a non-empty sequence is read."
- (mh-read-seq prompt not-empty
- (or mh-last-seq-used
- (car (mh-seq-containing-msg (mh-get-msg-num nil) nil)))))
-
-(defun mh-read-seq (prompt not-empty &optional default)
- "Read and return a sequence name.
-Prompt with PROMPT, raise an error if the sequence is empty and
-the NOT-EMPTY flag is non-nil, and supply an optional DEFAULT
-sequence. A reply of `%' defaults to the first sequence
-containing the current message."
- (let* ((input (completing-read (format-prompt "%s sequence" default prompt)
- (mh-seq-names mh-seq-list)
- nil nil nil 'mh-sequence-history))
- (seq (cond ((equal input "%")
- (car (mh-seq-containing-msg (mh-get-msg-num t) nil)))
- ((equal input "") default)
- (t (intern input))))
- (msgs (mh-seq-to-msgs seq)))
- (if (and (null msgs) not-empty)
- (error "No messages in sequence %s" seq))
- seq))
-
-(defun mh-internal-seq (name)
- "Return non-nil if NAME is the name of an internal MH-E sequence."
- (or (memq name mh-internal-seqs)
- (eq name mh-unseen-seq)
- (and (mh-colors-in-use-p) mh-tick-seq (eq name mh-tick-seq))
- (eq name mh-previous-seq)
- (mh-folder-name-p name)))
-
-;;;###mh-autoload
-(defun mh-valid-seq-p (name)
- "Return non-nil if NAME is a valid MH sequence name."
- (and (symbolp name)
- (string-match "^[a-zA-Z][a-zA-Z0-9]*$" (symbol-name name))))
-
-;;;###mh-autoload
-(defun mh-find-seq (name)
- "Return sequence NAME."
- (assoc name mh-seq-list))
-
-;;;###mh-autoload
-(defun mh-seq-to-msgs (seq)
- "Return a list of the messages in SEQ."
- (mh-seq-msgs (mh-find-seq seq)))
-
-(defun mh-seq-containing-msg (msg &optional include-internal-flag)
- "Return a list of the sequences containing MSG.
-If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences
-in list."
- (let ((l mh-seq-list)
- (seqs ()))
- (while l
- (and (memq msg (mh-seq-msgs (car l)))
- (or include-internal-flag
- (not (mh-internal-seq (mh-seq-name (car l)))))
- (setq seqs (cons (mh-seq-name (car l)) seqs)))
- (setq l (cdr l)))
- seqs))
-
-;;;###mh-autoload
-(defun mh-define-sequence (seq msgs)
- "Define the SEQ to contain the list of MSGS.
-Do not mark pseudo-sequences or empty sequences.
-Signals an error if SEQ is an invalid name."
- (if (and msgs
- (mh-valid-seq-p seq)
- (not (mh-folder-name-p seq)))
- (save-excursion
- (mh-exec-cmd-error nil "mark" mh-current-folder "-add" "-zero"
- "-sequence" (symbol-name seq)
- (mh-coalesce-msg-list msgs)))))
-
-;;;###mh-autoload
-(defun mh-undefine-sequence (seq msgs)
- "Remove from the SEQ the list of MSGS."
- (when (and (mh-valid-seq-p seq) msgs)
- (apply #'mh-exec-cmd "mark" mh-current-folder "-delete"
- "-sequence" (symbol-name seq) (mh-coalesce-msg-list msgs))))
-
-;;;###mh-autoload
-(defun mh-add-msgs-to-seq (msgs seq &optional internal-flag dont-annotate-flag)
- "Add MSGS to SEQ.
-
-Remove duplicates and keep sequence sorted. If optional
-INTERNAL-FLAG is non-nil, do not mark the message in the scan
-listing or inform MH of the addition.
-
-If DONT-ANNOTATE-FLAG is non-nil then the annotations in the
-folder buffer are not updated."
- (let ((entry (mh-find-seq seq))
- (internal-seq-flag (mh-internal-seq seq)))
- (if (and msgs (atom msgs)) (setq msgs (list msgs)))
- (if (null entry)
- (setq mh-seq-list
- (cons (mh-make-seq seq (mh-canonicalize-sequence msgs))
- mh-seq-list))
- (if msgs (setcdr entry (mh-canonicalize-sequence
- (append msgs (mh-seq-msgs entry))))))
- (unless internal-flag
- (mh-add-to-sequence seq msgs)
- (when (not dont-annotate-flag)
- (mh-iterate-on-range msg msgs
- (unless (memq msg (cdr entry))
- (mh-add-sequence-notation msg internal-seq-flag)))))))
-
-(defun mh-add-to-sequence (seq msgs)
- "The sequence SEQ is augmented with the messages in MSGS."
- ;; Add to a SEQUENCE each message the list of MSGS.
- (if (and (mh-valid-seq-p seq) (not (mh-folder-name-p seq)))
- (if msgs
- (apply #'mh-exec-cmd "mark" mh-current-folder "-add"
- "-sequence" (symbol-name seq)
- (mh-coalesce-msg-list msgs)))))
-
-(defun mh-canonicalize-sequence (msgs)
- "Sort MSGS in decreasing order and remove duplicates."
- (let* ((sorted-msgs (sort (copy-sequence msgs) #'>))
- (head sorted-msgs))
- (while (cdr head)
- (if (= (car head) (cadr head))
- (setcdr head (cddr head))
- (setq head (cdr head))))
- sorted-msgs))
-
-(defun mh-delete-a-msg-from-seq (msg sequence internal-flag)
- "Delete MSG from SEQUENCE.
-If INTERNAL-FLAG is non-nil, then do not inform MH of the
-change."
- (let ((entry (mh-find-seq sequence)))
- (when (and entry (memq msg (mh-seq-msgs entry)))
- (if (not internal-flag)
- (mh-undefine-sequence sequence (list msg)))
- (setcdr entry (delq msg (mh-seq-msgs entry))))))
-
-(defun mh-delete-seq-locally (seq)
- "Remove MH-E's record of SEQ."
- (let ((entry (mh-find-seq seq)))
- (setq mh-seq-list (delq entry mh-seq-list))))
-
-(defun mh-copy-seq-to-eob (seq)
- "Copy SEQ to the end of the buffer."
- ;; It is quite involved to write something which will work at any place in
- ;; the buffer, so we will write something which works only at the end of
- ;; the buffer. If we ever need to insert sequences in the middle of the
- ;; buffer, this will need to be fixed.
- (save-excursion
- (let* ((msgs (mh-seq-to-msgs seq))
- (coalesced-msgs (mh-coalesce-msg-list msgs)))
- (goto-char (point-max))
- (save-restriction
- (narrow-to-region (point) (point))
- (mh-regenerate-headers coalesced-msgs t)
- (cond ((memq 'unthread mh-view-ops)
- ;; Populate restricted scan-line map
- (mh-remove-all-notation)
- (mh-iterate-on-range msg (cons (point-min) (point-max))
- (setf (gethash msg mh-thread-scan-line-map)
- (mh-thread-parse-scan-line)))
- ;; Remove scan lines and read results from pre-computed tree
- (delete-region (point-min) (point-max))
- (mh-thread-print-scan-lines
- (mh-thread-generate mh-current-folder ()))
- (mh-notate-user-sequences))
- (mh-index-data
- (mh-index-insert-folder-headers)))))))
-
-;;;###mh-autoload
-(defun mh-valid-view-change-operation-p (op)
- "Check if the view change operation can be performed.
-OP is one of `widen' and `unthread'."
- (cond ((eq (car mh-view-ops) op)
- (pop mh-view-ops))
- (t nil)))
-
-\f
-
-;;; Ranges
-
-(defvar mh-range-seq-names)
-(defvar mh-range-history ())
-(defvar mh-range-completion-map (copy-keymap minibuffer-local-completion-map))
-(define-key mh-range-completion-map " " #'self-insert-command)
-
-;;;###mh-autoload
-(defun mh-interactive-range (range-prompt &optional default)
- "Return interactive specification for message, sequence, range or region.
-By convention, the name of this argument is RANGE.
-
-If variable `transient-mark-mode' is non-nil and the mark is active,
-then this function returns a cons-cell of the region.
-
-If optional prefix argument is provided, then prompt for message range
-with RANGE-PROMPT. A list of messages in that range is returned.
-
-If a MH range is given, say something like last:20, then a list
-containing the messages in that range is returned.
-
-If DEFAULT non-nil then it is returned.
-
-Otherwise, the message number at point is returned.
-
-This function is usually used with `mh-iterate-on-range' in order to
-provide a uniform interface to MH-E functions."
- (cond ((and transient-mark-mode mark-active) (cons (region-beginning) (region-end)))
- (current-prefix-arg (mh-read-range range-prompt nil nil t t))
- (default default)
- (t (mh-get-msg-num t))))
-
-;;;###mh-autoload
-(defun mh-read-range (prompt &optional folder default
- expand-flag ask-flag number-as-range-flag)
- "Read a message range with PROMPT.
-
-If FOLDER is non-nil then a range is read from that folder, otherwise
-use `mh-current-folder'.
-
-If DEFAULT is a string then use that as default range to return. If
-DEFAULT is nil then ask user with default answer a range based on the
-sequences that seem relevant. Finally if DEFAULT is t, try to avoid
-prompting the user. Unseen messages, if present, are returned. If the
-folder has fewer than `mh-large-folder' messages then \"all\" messages
-are returned. Finally as a last resort prompt the user.
-
-If EXPAND-FLAG is non-nil then a list of message numbers corresponding
-to the input is returned. If this list is empty then an error is
-raised. If EXPAND-FLAG is nil just return the input string. In this
-case we don't check if the range is empty.
-
-If ASK-FLAG is non-nil, then the user is always queried for a range of
-messages. If ASK-FLAG is nil, then the function checks if the unseen
-sequence is non-empty. If that is the case, `mh-unseen-seq', or the
-list of messages in it depending on the value of EXPAND, is returned.
-Otherwise if the folder has fewer than `mh-large-folder' messages then
-the list of messages corresponding to \"all\" is returned. If neither
-of the above holds then as a last resort the user is queried for a
-range of messages.
-
-If NUMBER-AS-RANGE-FLAG is non-nil, then if a number, N is read as
-input, it is interpreted as the range \"last:N\".
-
-This function replaces the existing function `mh-read-msg-range'.
-Calls to:
-
- (mh-read-msg-range folder flag)
-
-should be replaced with:
-
- (mh-read-range \"Suitable prompt\" folder t nil flag
- mh-interpret-number-as-range-flag)"
- (setq default (or default mh-last-seq-used
- (car (mh-seq-containing-msg (mh-get-msg-num nil) t)))
- prompt (format "%s range" prompt))
- (let* ((folder (or folder mh-current-folder))
- (guess (eq default t))
- (counts (and guess (mh-folder-size folder)))
- (unseen (and counts (> (cadr counts) 0)))
- (large (and counts mh-large-folder (> (car counts) mh-large-folder)))
- (default (cond ((and guess large) (format "last:%s" mh-large-folder))
- ((and guess (not large)) "all")
- ((stringp default) default)
- ((symbolp default) (symbol-name default))))
- (prompt (cond ((and guess large default)
- (format-prompt "%s (folder has %s messages)"
- default prompt (car counts)))
- (default
- (format-prompt prompt default))))
- (minibuffer-local-completion-map mh-range-completion-map)
- (seq-list (if (eq folder mh-current-folder)
- mh-seq-list
- (mh-read-folder-sequences folder nil)))
- (mh-range-seq-names
- (append '(("first") ("last") ("all") ("prev") ("next"))
- (mh-seq-names seq-list)))
- (input (cond ((and (not ask-flag) unseen) (symbol-name mh-unseen-seq))
- ((and (not ask-flag) (not large)) "all")
- (t (completing-read prompt
- 'mh-range-completion-function nil nil
- nil 'mh-range-history default))))
- msg-list)
- (when (and number-as-range-flag
- (string-match "^[ \t]*\\([0-9]+\\)[ \t]*$" input))
- (setq input (concat "last:" (match-string 1 input))))
- (cond ((not expand-flag) input)
- ((assoc (intern input) seq-list)
- (cdr (assoc (intern input) seq-list)))
- ((setq msg-list (mh-translate-range folder input)) msg-list)
- (t (error "No messages in range %s" input)))))
-
-;;;###mh-autoload
-(defun mh-range-to-msg-list (range)
- "Return a list of messages for RANGE.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use."
- (let (msg-list)
- (mh-iterate-on-range msg range
- (push msg msg-list))
- (nreverse msg-list)))
-
-;;;###mh-autoload
-(defun mh-translate-range (folder expr)
- "In FOLDER, translate the string EXPR to a list of messages numbers."
- (save-excursion
- (let ((strings (delete "" (split-string expr "[ \t\n]")))
- (result ()))
- (ignore-errors
- (apply #'mh-exec-cmd-quiet nil "mhpath" folder strings)
- (set-buffer mh-temp-buffer)
- (goto-char (point-min))
- (while (re-search-forward "/\\([0-9]*\\)$" nil t)
- (push (string-to-number (match-string 1)) result))
- (nreverse result)))))
-
-(defun mh-range-completion-function (string predicate flag)
- "Programmable completion of message ranges.
-STRING is the user input that is to be completed. PREDICATE if non-nil is a
-function used to filter the possible choices and FLAG determines whether the
-completion is over."
- (let* ((candidates mh-range-seq-names)
- (last-char (and (not (equal string ""))
- (aref string (1- (length string)))))
- (last-word (cond ((null last-char) "")
- ((memq last-char '(? ?- ?:)) "")
- (t (car (last (split-string string "[ -:]+"))))))
- (prefix (substring string 0 (- (length string) (length last-word)))))
- (cond ((eq flag nil)
- (let ((res (try-completion last-word candidates predicate)))
- (cond ((null res) nil)
- ((eq res t) t)
- (t (concat prefix res)))))
- ((eq flag t)
- (all-completions last-word candidates predicate))
- ((eq flag 'lambda)
- (cl-loop for x in candidates
- when (equal x last-word) return t
- finally return nil)))))
-
-(defun mh-seq-names (seq-list)
- "Return an alist containing the names of the SEQ-LIST."
- (mapcar (lambda (entry) (list (symbol-name (mh-seq-name entry))))
- seq-list))
-
-(defun mh-folder-size (folder)
- "Find size of FOLDER."
- (if mh-flists-present-flag
- (mh-folder-size-flist folder)
- (mh-folder-size-folder folder)))
-
-(defun mh-folder-size-flist (folder)
- "Find size of FOLDER using \"flist\"."
- (with-temp-buffer
- (call-process (expand-file-name "flist" mh-progs) nil t nil "-showzero"
- "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq))
- (goto-char (point-min))
- (cl-multiple-value-bind (folder unseen total)
- (cl-values-list
- (mh-parse-flist-output-line
- (buffer-substring (point) (line-end-position))))
- (list total unseen folder))))
-
-(defun mh-folder-size-folder (folder)
- "Find size of FOLDER using \"folder\"."
- (with-temp-buffer
- (let ((u (length (cdr (assoc mh-unseen-seq
- (mh-read-folder-sequences folder nil))))))
- (call-process (expand-file-name "folder" mh-progs) nil t nil
- "-norecurse" folder)
- (goto-char (point-min))
- (if (re-search-forward " has \\([0-9]+\\) " nil t)
- (list (string-to-number (match-string 1)) u folder)
- (list 0 u folder)))))
-
-;;;###mh-autoload
-(defun mh-parse-flist-output-line (line &optional current-folder)
- "Parse LINE to generate folder name, unseen messages and total messages.
-If CURRENT-FOLDER is non-nil then it contains the current folder
-name and it is used to avoid problems in corner cases involving
-folders whose names end with a `+' character."
- (with-temp-buffer
- (insert line)
- (goto-char (point-max))
- (let (folder unseen total p)
- (when (search-backward " out of " (point-min) t)
- (setq total (string-to-number
- (buffer-substring-no-properties
- (match-end 0) (line-end-position))))
- (when (search-backward " in sequence " (point-min) t)
- (setq p (point))
- (when (search-backward " has " (point-min) t)
- (setq unseen (string-to-number (buffer-substring-no-properties
- (match-end 0) p)))
- (while (eq (char-after) ? )
- (backward-char))
- (setq folder (buffer-substring-no-properties
- (point-min) (1+ (point))))
- (when (and (equal (aref folder (1- (length folder))) ?+)
- (equal current-folder folder))
- (setq folder (substring folder 0 (1- (length folder)))))
- (list (format "+%s" folder) unseen total)))))))
-
-;;;###mh-autoload
-(defun mh-read-folder-sequences (folder save-refiles)
- "Read and return the predefined sequences for a FOLDER.
-If SAVE-REFILES is non-nil, then keep the sequences
-that note messages to be refiled."
- (let ((seqs ()))
- (cond (save-refiles
- (mapc (lambda (seq) ; Save the refiling sequences
- (if (mh-folder-name-p (mh-seq-name seq))
- (setq seqs (cons seq seqs))))
- mh-seq-list)))
- (save-excursion
- (if (eq 0 (mh-exec-cmd-quiet nil "mark" folder "-list"))
- (progn
- ;; look for name in line of form "cur: 4" or "myseq (private): 23"
- (while (re-search-forward "^[^: ]+" nil t)
- (setq seqs (cons (mh-make-seq (intern (buffer-substring
- (match-beginning 0)
- (match-end 0)))
- (mh-read-msg-list))
- seqs)))
- (delete-region (point-min) (point))))) ; avoid race with
- ; mh-process-daemon
- seqs))
-
-(defun mh-read-msg-list ()
- "Return a list of message numbers from point to the end of the line.
-Expands ranges into set of individual numbers."
- (let ((msgs ())
- (end-of-line (line-end-position))
- num)
- (while (re-search-forward "[0-9]+" end-of-line t)
- (setq num (string-to-number (buffer-substring (match-beginning 0)
- (match-end 0))))
- (cond ((looking-at "-") ; Message range
- (forward-char 1)
- (re-search-forward "[0-9]+" end-of-line t)
- (let ((num2 (string-to-number
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (if (< num2 num)
- (error "Bad message range: %d-%d" num num2))
- (while (<= num num2)
- (setq msgs (cons num msgs))
- (setq num (1+ num)))))
- ((not (zerop num)) ;"pick" outputs "0" to mean no match
- (setq msgs (cons num msgs)))))
- msgs))
-
-\f
-
-;;; Notation
-
-;;;###mh-autoload
-(defun mh-notate (msg notation offset)
- "Mark MSG with the character NOTATION at position OFFSET.
-Null MSG means the message at cursor.
-If NOTATION is nil then no change in the buffer occurs."
- (save-excursion
- (if (or (null msg)
- (mh-goto-msg msg t t))
- (with-mh-folder-updating (t)
- (beginning-of-line)
- (forward-char offset)
- (let* ((change-stack-flag
- (and (equal offset
- (+ mh-cmd-note mh-scan-field-destination-offset))
- (not (eq notation mh-note-seq))))
- (msg (and change-stack-flag (or msg (mh-get-msg-num nil))))
- (stack (and msg (gethash msg mh-sequence-notation-history)))
- (notation (or notation (char-after))))
- (if stack
- ;; The presence of the stack tells us that we don't need to
- ;; notate the message, since the notation would be replaced
- ;; by a sequence notation. So we will just put the notation
- ;; at the bottom of the stack. If the sequence is deleted,
- ;; the correct notation will be shown.
- (setf (gethash msg mh-sequence-notation-history)
- (reverse (cons notation (cdr (reverse stack)))))
- ;; Since we don't have any sequence notations in the way, just
- ;; notate the scan line.
- (delete-char 1)
- (insert notation))
- (when change-stack-flag
- (mh-thread-update-scan-line-map msg notation offset)))))))
-
-;;;###mh-autoload
-(defun mh-notate-cur ()
- "Mark the MH sequence cur.
-In addition to notating the current message with `mh-note-cur'
-the function uses `overlay-arrow-position' to put a marker in the
-fringe."
- (let ((cur (car (mh-seq-to-msgs 'cur))))
- (when (and cur (mh-goto-msg cur t t))
- (beginning-of-line)
- (when (looking-at mh-scan-good-msg-regexp)
- (mh-notate nil mh-note-cur mh-cmd-note))
- (setq mh-arrow-marker (set-marker mh-arrow-marker (point)))
- (setq overlay-arrow-position mh-arrow-marker))))
-
-;;;###mh-autoload
-(defun mh-remove-cur-notation ()
- "Remove old cur notation."
- (let ((cur-msg (car (mh-seq-to-msgs 'cur))))
- (save-excursion
- (when (and cur-msg
- (mh-goto-msg cur-msg t t)
- (looking-at mh-scan-cur-msg-number-regexp))
- (mh-notate nil ? mh-cmd-note)
- (setq overlay-arrow-position nil)))))
-
-;; FIXME? We may want to clear all notations and add one for current-message
-;; and process user sequences.
-;;;###mh-autoload
-(defun mh-notate-deleted-and-refiled ()
- "Notate messages marked for deletion or refiling.
-Messages to be deleted are given by `mh-delete-list' while
-messages to be refiled are present in `mh-refile-list'."
- (let ((refiled-hash (make-hash-table))
- (deleted-hash (make-hash-table)))
- (dolist (msg mh-delete-list)
- (setf (gethash msg deleted-hash) t))
- (dolist (dest-msg-list mh-refile-list)
- (dolist (msg (cdr dest-msg-list))
- (setf (gethash msg refiled-hash) t)))
- (mh-iterate-on-messages-in-region msg (point-min) (point-max)
- (cond ((gethash msg refiled-hash)
- (mh-notate nil mh-note-refiled mh-cmd-note))
- ((gethash msg deleted-hash)
- (mh-notate nil mh-note-deleted mh-cmd-note))))))
-
-;;;###mh-autoload
-(defun mh-notate-user-sequences (&optional range)
- "Mark user-defined sequences in RANGE.
-
-Check the documentation of `mh-interactive-range' to see how
-RANGE is read in interactive use; if nil all messages are
-notated."
- (unless range
- (setq range (cons (point-min) (point-max))))
- (let ((seqs mh-seq-list)
- (msg-hash (make-hash-table)))
- (dolist (seq seqs)
- (dolist (msg (mh-seq-msgs seq))
- (push (car seq) (gethash msg msg-hash))))
- (mh-iterate-on-range msg range
- (cl-loop for seq in (gethash msg msg-hash)
- do (mh-add-sequence-notation msg (mh-internal-seq seq))))))
-
-(defun mh-add-sequence-notation (msg internal-seq-flag)
- "Add sequence notation to the MSG on the current line.
-If INTERNAL-SEQ-FLAG is non-nil, then refontify the scan line if
-font-lock is turned on."
- (with-mh-folder-updating (t)
- (save-excursion
- (beginning-of-line)
- (if internal-seq-flag
- (progn
- ;; Change the buffer so that if transient-mark-mode is active
- ;; and there is an active region it will get deactivated as in
- ;; the case of user sequences.
- (mh-notate nil nil mh-cmd-note)
- (when font-lock-mode
- (font-lock-fontify-region (point) (line-end-position))))
- (forward-char (+ mh-cmd-note mh-scan-field-destination-offset))
- (let ((stack (gethash msg mh-sequence-notation-history)))
- (setf (gethash msg mh-sequence-notation-history)
- (cons (char-after) stack)))
- (mh-notate nil mh-note-seq
- (+ mh-cmd-note mh-scan-field-destination-offset))))))
-
-(defun mh-remove-sequence-notation (msg internal-seq-flag &optional all)
- "Remove sequence notation from the MSG on the current line.
-If INTERNAL-SEQ-FLAG is non-nil, then `font-lock' was used to
-highlight the sequence. In that case, no notation needs to be removed.
-Otherwise the effect of inserting `mh-note-seq' needs to be reversed.
-If ALL is non-nil, then all sequence marks on the scan line are
-removed."
- (with-mh-folder-updating (t)
- ;; This takes care of internal sequences...
- (mh-notate nil nil mh-cmd-note)
- (unless internal-seq-flag
- ;; ... and this takes care of user sequences.
- (let ((stack (gethash msg mh-sequence-notation-history)))
- (while (and all (cdr stack))
- (setq stack (cdr stack)))
- (when stack
- (save-excursion
- (beginning-of-line)
- (forward-char (+ mh-cmd-note mh-scan-field-destination-offset))
- (delete-char 1)
- (insert (car stack))))
- (setf (gethash msg mh-sequence-notation-history) (cdr stack))))))
-
-;;;###mh-autoload
-(defun mh-remove-all-notation ()
- "Remove all notations on all scan lines that MH-E introduces."
- (save-excursion
- (setq overlay-arrow-position nil)
- (goto-char (point-min))
- (mh-iterate-on-range msg (cons (point-min) (point-max))
- (mh-notate nil ? mh-cmd-note)
- (mh-remove-sequence-notation msg nil t))
- (clrhash mh-sequence-notation-history)))
-
-\f
-
-;; XXX Unused, delete, or create bind key?
-(defun mh-rename-seq (sequence new-name)
- "Rename SEQUENCE to have NEW-NAME."
- (interactive (list (mh-read-seq "Old" t)
- (intern (read-string "New sequence name: "))))
- (let ((old-seq (mh-find-seq sequence)))
- (or old-seq
- (error "Sequence %s does not exist" sequence))
- ;; Create new sequence first, since it might raise an error.
- (mh-define-sequence new-name (mh-seq-msgs old-seq))
- (mh-undefine-sequence sequence (mh-seq-msgs old-seq))
- (rplaca old-seq new-name)))
-
-(provide 'mh-seq)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-seq.el ends here
+++ /dev/null
-;;; mh-show.el --- MH-Show mode -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 1997, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Mode for showing messages.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-mime)
-(require 'mh-scan)
-
-;; Dynamically-created function not found in mh-loaddefs.el.
-(autoload 'mh-tool-bar-init "mh-tool-bar")
-
-(require 'font-lock)
-(require 'gnus-cite)
-(require 'gnus-util)
-(require 'goto-addr)
-
-(autoload 'mh-make-buffer-data "mh-mime") ;can't be automatically generated
-
-\f
-
-;;; MH-Folder Commands
-
-(defvar mh-showing-with-headers nil
- "If non-nil, MH-Show buffer contains message with all header fields.
-If nil, MH-Show buffer contains message processed normally.")
-
-;;;###mh-autoload
-(defun mh-show (&optional message redisplay-flag)
- "Display message\\<mh-folder-mode-map>.
-
-If the message under the cursor is already displayed, this command
-scrolls to the beginning of the message. MH-E normally hides a lot of
-the superfluous header fields that mailers add to a message, but if
-you wish to see all of them, use the command \\[mh-header-display].
-
-Two hooks can be used to control how messages are displayed. The
-first hook, `mh-show-mode-hook', is called early on in the
-process of the message display. It is usually used to perform
-some action on the message's buffer. The second hook,
-`mh-show-hook', is the last thing called after messages are
-displayed. It's used to affect the behavior of MH-E in general or
-when `mh-show-mode-hook' is too early.
-
-From a program, optional argument MESSAGE can be used to display an
-alternative message. The optional argument REDISPLAY-FLAG forces the
-redisplay of the message even if the show buffer was already
-displaying the correct message.
-
-See the \"mh-show\" customization group for a litany of options that
-control what displayed messages look like."
- (interactive (list nil t))
- (when (or redisplay-flag
- (and mh-showing-with-headers
- (or mh-mhl-format-file mh-clean-message-header-flag)))
- (mh-invalidate-show-buffer))
- (mh-show-msg message))
-
-;;;###mh-autoload
-(defun mh-header-display ()
- "Display message with all header fields\\<mh-folder-mode-map>.
-
-Use the command \\[mh-show] to show the message normally again."
- (interactive)
- (and (not mh-showing-with-headers)
- (or mh-mhl-format-file mh-clean-message-header-flag)
- (mh-invalidate-show-buffer))
- (let ((mh-decode-mime-flag nil)
- (mh-mhl-format-file nil)
- (mh-clean-message-header-flag nil))
- (mh-show-msg nil)
- (mh-in-show-buffer (mh-show-buffer)
- (goto-char (point-min))
- (mh-recenter 0))
- (setq mh-showing-with-headers t)))
-
-;;;###mh-autoload
-(defun mh-show-preferred-alternative ()
- "Display message with the default preferred alternative.
-This is as if `mm-discouraged-alternatives' is set to nil.
-
-Use the command \\[mh-show] to show the message normally again."
- (interactive)
- (let
- ((mm-discouraged-alternatives))
- (mh-show nil t)))
-
-\f
-
-;;; Support Routines for MH-Folder Commands
-
-;;;###mh-autoload
-(defun mh-maybe-show (&optional msg)
- "Display message at cursor, but only if in show mode.
-If optional arg MSG is non-nil, display that message instead."
- (if mh-showing-mode (mh-show msg)))
-
-(defun mh-show-msg (msg)
- "Show MSG.
-
-The hook `mh-show-hook' is called after the message has been
-displayed."
- (if (not msg)
- (setq msg (mh-get-msg-num t)))
- (mh-showing-mode t)
- (setq mh-page-to-next-msg-flag nil)
- (let ((folder mh-current-folder)
- (folders (list mh-current-folder))
- (clean-message-header mh-clean-message-header-flag)
- (show-window (get-buffer-window mh-show-buffer))
- (display-mime-buttons-flag mh-display-buttons-for-inline-parts-flag))
- (if (not (eq (next-window (minibuffer-window)) (selected-window)))
- (delete-other-windows)) ; force ourselves to the top window
- (mh-in-show-buffer (mh-show-buffer)
- (setq mh-display-buttons-for-inline-parts-flag display-mime-buttons-flag)
- (if (and show-window
- (equal (mh-msg-filename msg folder) buffer-file-name))
- (progn ;just back up to start
- (goto-char (point-min))
- (if (not clean-message-header)
- (mh-start-of-uncleaned-message)))
- (mh-display-msg msg folder)))
- (unless (window-full-height-p) ; not vertically split
- (shrink-window (- (window-height) (or mh-summary-height
- (mh-summary-height)))))
- (mh-recenter nil)
- ;; The following line is a nop which forces update of the scan line so
- ;; that font-lock will update it (if needed)...
- (mh-notate nil nil mh-cmd-note)
- (if (not (memq msg mh-seen-list))
- (setq mh-seen-list (cons msg mh-seen-list)))
- (when mh-update-sequences-after-mh-show-flag
- (mh-update-sequences)
- (when mh-index-data
- (setq folders
- (append (mh-index-delete-from-sequence mh-unseen-seq (list msg))
- folders)))
- (when (mh-speed-flists-active-p)
- (apply #'mh-speed-flists t folders)))
- (run-hooks 'mh-show-hook)))
-
-;;;###mh-autoload
-(defun mh-start-of-uncleaned-message ()
- "Position uninteresting headers off the top of the window."
- (let ((case-fold-search t))
- (re-search-forward
- "^To:\\|^Cc:\\|^From:\\|^Subject:\\|^Date:" nil t)
- (beginning-of-line)
- (mh-recenter 0)))
-
-(defvar mh-show-buffer-mode-line-buffer-id " {show-%s} %d"
- "Format string to produce `mode-line-buffer-identification' for show buffers.
-
-First argument is folder name. Second is message number.")
-
-;;;###mh-autoload
-(defun mh-display-msg (msg-num folder-name)
- "Display MSG-NUM of FOLDER-NAME.
-Sets the current buffer to the show buffer."
- (let ((folder (mh-msg-folder folder-name)))
- (set-buffer folder)
- ;; When Gnus uses external displayers it has to keep handles longer. So
- ;; we will delete these handles when mh-quit is called on the folder. It
- ;; would be nicer if there are weak pointers in Emacs Lisp, then we could
- ;; get the garbage collector to do this for us.
- (unless (mh-buffer-data)
- (setf (mh-buffer-data) (mh-make-buffer-data)))
- ;; Bind variables in folder buffer in case they are local
- (let ((formfile mh-mhl-format-file)
- (clean-message-header mh-clean-message-header-flag)
- (invisible-headers mh-invisible-header-fields-compiled)
- ;; (visible-headers nil)
- (msg-filename (mh-msg-filename msg-num folder-name))
- (show-buffer mh-show-buffer)
- (mm-inline-media-tests mh-mm-inline-media-tests))
- (if (not (file-exists-p msg-filename))
- (error "Message %d does not exist" msg-num))
- (if (and (> mh-show-maximum-size 0)
- (> (elt (file-attributes msg-filename) 7)
- mh-show-maximum-size)
- (not (y-or-n-p
- (format
- "Message %d (%d bytes) exceeds %d bytes. Display it? "
- msg-num (elt (file-attributes msg-filename) 7)
- mh-show-maximum-size))))
- (error "Message %d not displayed" msg-num))
- (set-buffer show-buffer)
- (cond ((not (equal msg-filename buffer-file-name))
- (mh-unvisit-file)
- (setq buffer-read-only nil)
- ;; Cleanup old mime handles
- (mh-mime-cleanup)
- (erase-buffer)
- ;; Changing contents, so this hook needs to be reinitialized.
- ;; pgp.el uses this.
- (kill-local-variable 'write-contents-functions)
- (font-lock-mode -1)
- (mh-show-mode)
- (if formfile
- (mh-exec-lib-cmd-output "mhl" "-nobell" "-noclear"
- (if (stringp formfile)
- (list "-form" formfile))
- msg-filename)
- (insert-file-contents-literally msg-filename))
- ;; Use mm to display buffer
- (when (and mh-decode-mime-flag (not formfile))
- (mh-add-missing-mime-version-header)
- (setf (mh-buffer-data) (mh-make-buffer-data))
- (mh-mime-display))
- (mh-show-unquote-From)
- (mh-show-xface)
- (mh-show-addr)
- ;; Header cleanup
- (goto-char (point-min))
- (cond (clean-message-header
- (mh-clean-msg-header (point-min)
- invisible-headers
- nil) ;; visible-headers
- (goto-char (point-min)))
- (t
- (mh-start-of-uncleaned-message)))
- (mh-decode-message-header)
- ;; the parts of visiting we want to do (no locking)
- (or (eq buffer-undo-list t) ;don't save undo info for prev msgs
- (setq buffer-undo-list nil))
- (set-buffer-auto-saved)
- ;; the parts of set-visited-file-name we want to do (no locking)
- (setq buffer-file-name msg-filename)
- (setq buffer-backed-up nil)
- (auto-save-mode 1)
- (set-mark nil)
- (when (and mh-decode-mime-flag (not formfile))
- (mh-display-smileys)
- (mh-display-emphasis))
- (set-buffer-modified-p nil)
- (setq buffer-read-only t)
- (setq mh-show-folder-buffer folder)
- (setq mode-line-buffer-identification
- (list (format mh-show-buffer-mode-line-buffer-id
- folder-name msg-num)))
- (mh-logo-display)
- (set-buffer folder)
- (setq mh-showing-with-headers nil))))))
-
-(defun mh-msg-folder (folder-name)
- "Return the name of the buffer for FOLDER-NAME."
- folder-name)
-
-;;;###mh-autoload
-(defun mh-clean-msg-header (start invisible-headers visible-headers)
- "Flush extraneous lines in message header.
-
-Header is cleaned from START to the end of the message header.
-INVISIBLE-HEADERS contains a regular expression specifying lines
-to delete from the header. VISIBLE-HEADERS contains a regular
-expression specifying the lines to display. INVISIBLE-HEADERS is
-ignored if VISIBLE-HEADERS is non-nil."
- ;; XXX Note that MH-E no longer supports the `mh-visible-headers'
- ;; variable, so this function could be trimmed of this feature too."
- (let ((case-fold-search t)
- (buffer-read-only nil))
- (save-restriction
- (goto-char start)
- (if (search-forward "\n\n" nil 'move)
- (backward-char 1))
- (narrow-to-region start (point))
- (goto-char (point-min))
- (if visible-headers
- (while (< (point) (point-max))
- (cond ((looking-at visible-headers)
- (forward-line 1)
- (while (looking-at "[ \t]") (forward-line 1)))
- (t
- (mh-delete-line 1)
- (while (looking-at "[ \t]")
- (mh-delete-line 1)))))
- (while (re-search-forward invisible-headers nil t)
- (beginning-of-line)
- (mh-delete-line 1)
- (while (looking-at "[ \t]")
- (mh-delete-line 1)))))
- (let ((mh-compose-skipped-header-fields ()))
- (mh-letter-hide-all-skipped-fields))
- (unlock-buffer)))
-
-;;;###mh-autoload
-(defun mh-invalidate-show-buffer ()
- "Invalidate the show buffer so we must update it to use it."
- (if (get-buffer mh-show-buffer)
- (with-current-buffer mh-show-buffer
- (mh-unvisit-file))))
-
-(defun mh-unvisit-file ()
- "Separate current buffer from the message file it was visiting."
- (or (not (buffer-modified-p))
- (null buffer-file-name) ;we've been here before
- (yes-or-no-p (format "Message %s modified; discard changes? "
- (file-name-nondirectory buffer-file-name)))
- (error "Changes preserved"))
- (clear-visited-file-modtime)
- (unlock-buffer)
- (setq buffer-file-name nil))
-
-(defun mh-summary-height ()
- "Return ideal value for the variable `mh-summary-height'.
-The current frame height is taken into consideration."
- (or (and (> (frame-height) 24)
- (min 10 (/ (frame-height) 6)))
- 4))
-
-\f
-
-;; Infrastructure to generate show-buffer functions from folder functions.
-;; Should we be restoring the mark in the folder buffer after the
-;; operation has been carried out?
-(defmacro mh-defun-show-buffer (function original-function
- &optional dont-return)
- "Define FUNCTION to run ORIGINAL-FUNCTION in folder buffer.
-If the buffer we start in is still visible and DONT-RETURN is nil
-then switch to it after that."
- `(defun ,function ()
- ,(format "Calls %s from the message's folder.\n%s\nSee `%s' for more info.\n"
- original-function
- (if dont-return ""
- "When function completes, returns to the show buffer if it is
-still visible.\n")
- original-function)
- (interactive)
- (when (buffer-live-p (get-buffer mh-show-folder-buffer))
- (let ((config (current-window-configuration))
- (folder-buffer mh-show-folder-buffer)
- (normal-exit nil)
- ,@(if dont-return () '((cur-buffer-name (buffer-name)))))
- (pop-to-buffer mh-show-folder-buffer nil)
- (unless (equal (buffer-name
- (window-buffer (frame-first-window (selected-frame))))
- folder-buffer)
- (delete-other-windows))
- (mh-goto-cur-msg t)
- (deactivate-mark)
- (unwind-protect
- (prog1 (call-interactively (function ,original-function))
- (setq normal-exit t))
- (deactivate-mark)
- (when (eq major-mode 'mh-folder-mode)
- (when (fboundp 'hl-line-highlight)
- (hl-line-highlight)))
- (cond ((not normal-exit)
- (set-window-configuration config))
- ,(if dont-return
- '(t (setq mh-previous-window-config config))
- '((and (get-buffer cur-buffer-name)
- (window-live-p (get-buffer-window
- (get-buffer cur-buffer-name))))
- (pop-to-buffer (get-buffer cur-buffer-name) nil)))))))))
-
-;; Generate interactive functions for the show buffer from the corresponding
-;; folder functions.
-(mh-defun-show-buffer mh-show-previous-undeleted-msg
- mh-previous-undeleted-msg)
-(mh-defun-show-buffer mh-show-next-undeleted-msg
- mh-next-undeleted-msg)
-(mh-defun-show-buffer mh-show-quit mh-quit)
-(mh-defun-show-buffer mh-show-delete-msg mh-delete-msg)
-(mh-defun-show-buffer mh-show-refile-msg mh-refile-msg)
-(mh-defun-show-buffer mh-show-undo mh-undo)
-(mh-defun-show-buffer mh-show-execute-commands mh-execute-commands)
-(mh-defun-show-buffer mh-show-reply mh-reply t)
-(mh-defun-show-buffer mh-show-redistribute mh-redistribute)
-(mh-defun-show-buffer mh-show-forward mh-forward t)
-(mh-defun-show-buffer mh-show-header-display mh-header-display)
-(mh-defun-show-buffer mh-show-refile-or-write-again
- mh-refile-or-write-again)
-(mh-defun-show-buffer mh-show-show mh-show)
-(mh-defun-show-buffer mh-show-show-preferred-alternative mh-show-preferred-alternative)
-(mh-defun-show-buffer mh-show-write-message-to-file
- mh-write-msg-to-file)
-(mh-defun-show-buffer mh-show-extract-rejected-mail
- mh-extract-rejected-mail t)
-(mh-defun-show-buffer mh-show-delete-msg-no-motion
- mh-delete-msg-no-motion)
-(mh-defun-show-buffer mh-show-first-msg mh-first-msg)
-(mh-defun-show-buffer mh-show-last-msg mh-last-msg)
-(mh-defun-show-buffer mh-show-copy-msg mh-copy-msg)
-(mh-defun-show-buffer mh-show-edit-again mh-edit-again t)
-(mh-defun-show-buffer mh-show-goto-msg mh-goto-msg)
-(mh-defun-show-buffer mh-show-inc-folder mh-inc-folder)
-(mh-defun-show-buffer mh-show-delete-subject-or-thread
- mh-delete-subject-or-thread)
-(mh-defun-show-buffer mh-show-delete-subject mh-delete-subject)
-(mh-defun-show-buffer mh-show-print-msg mh-print-msg)
-(mh-defun-show-buffer mh-show-send mh-send t)
-(mh-defun-show-buffer mh-show-toggle-showing mh-toggle-showing t)
-(mh-defun-show-buffer mh-show-pipe-msg mh-pipe-msg t)
-(mh-defun-show-buffer mh-show-sort-folder mh-sort-folder)
-(mh-defun-show-buffer mh-show-visit-folder mh-visit-folder t)
-(mh-defun-show-buffer mh-show-rescan-folder mh-rescan-folder)
-(mh-defun-show-buffer mh-show-pack-folder mh-pack-folder)
-(mh-defun-show-buffer mh-show-kill-folder mh-kill-folder t)
-(mh-defun-show-buffer mh-show-list-folders mh-list-folders t)
-(mh-defun-show-buffer mh-show-undo-folder mh-undo-folder)
-(mh-defun-show-buffer mh-show-delete-msg-from-seq
- mh-delete-msg-from-seq)
-(mh-defun-show-buffer mh-show-delete-seq mh-delete-seq)
-(mh-defun-show-buffer mh-show-list-sequences mh-list-sequences)
-(mh-defun-show-buffer mh-show-narrow-to-seq mh-narrow-to-seq)
-(mh-defun-show-buffer mh-show-put-msg-in-seq mh-put-msg-in-seq)
-(mh-defun-show-buffer mh-show-msg-is-in-seq mh-msg-is-in-seq)
-(mh-defun-show-buffer mh-show-widen mh-widen)
-(mh-defun-show-buffer mh-show-narrow-to-subject mh-narrow-to-subject)
-(mh-defun-show-buffer mh-show-narrow-to-from mh-narrow-to-from)
-(mh-defun-show-buffer mh-show-narrow-to-cc mh-narrow-to-cc)
-(mh-defun-show-buffer mh-show-narrow-to-range mh-narrow-to-range)
-(mh-defun-show-buffer mh-show-narrow-to-to mh-narrow-to-to)
-(mh-defun-show-buffer mh-show-store-msg mh-store-msg)
-(mh-defun-show-buffer mh-show-page-digest mh-page-digest)
-(mh-defun-show-buffer mh-show-page-digest-backwards
- mh-page-digest-backwards)
-(mh-defun-show-buffer mh-show-burst-digest mh-burst-digest)
-(mh-defun-show-buffer mh-show-page-msg mh-page-msg)
-(mh-defun-show-buffer mh-show-previous-page mh-previous-page)
-(mh-defun-show-buffer mh-show-modify mh-modify t)
-(mh-defun-show-buffer mh-show-next-button mh-next-button)
-(mh-defun-show-buffer mh-show-prev-button mh-prev-button)
-(mh-defun-show-buffer mh-show-toggle-mime-part mh-folder-toggle-mime-part)
-(mh-defun-show-buffer mh-show-save-mime-part mh-folder-save-mime-part)
-(mh-defun-show-buffer mh-show-inline-mime-part mh-folder-inline-mime-part)
-(mh-defun-show-buffer mh-show-toggle-threads mh-toggle-threads)
-(mh-defun-show-buffer mh-show-thread-delete mh-thread-delete)
-(mh-defun-show-buffer mh-show-thread-refile mh-thread-refile)
-(mh-defun-show-buffer mh-show-update-sequences mh-update-sequences)
-(mh-defun-show-buffer mh-show-next-unread-msg mh-next-unread-msg)
-(mh-defun-show-buffer mh-show-previous-unread-msg mh-previous-unread-msg)
-(mh-defun-show-buffer mh-show-thread-ancestor mh-thread-ancestor)
-(mh-defun-show-buffer mh-show-thread-next-sibling mh-thread-next-sibling)
-(mh-defun-show-buffer mh-show-thread-previous-sibling
- mh-thread-previous-sibling)
-(mh-defun-show-buffer mh-show-index-visit-folder mh-index-visit-folder t)
-(mh-defun-show-buffer mh-show-toggle-tick mh-toggle-tick)
-(mh-defun-show-buffer mh-show-narrow-to-tick mh-narrow-to-tick)
-(mh-defun-show-buffer mh-show-junk-allowlist mh-junk-allowlist)
-(mh-defun-show-buffer mh-show-junk-whitelist mh-junk-whitelist)
-(mh-defun-show-buffer mh-show-junk-blocklist mh-junk-blocklist)
-(mh-defun-show-buffer mh-show-index-new-messages mh-index-new-messages)
-(mh-defun-show-buffer mh-show-index-ticked-messages mh-index-ticked-messages)
-(mh-defun-show-buffer mh-show-index-sequenced-messages
- mh-index-sequenced-messages)
-(mh-defun-show-buffer mh-show-catchup mh-catchup)
-(mh-defun-show-buffer mh-show-ps-print-toggle-color mh-ps-print-toggle-color)
-(mh-defun-show-buffer mh-show-ps-print-toggle-faces mh-ps-print-toggle-faces)
-(mh-defun-show-buffer mh-show-ps-print-msg-file mh-ps-print-msg-file)
-(mh-defun-show-buffer mh-show-ps-print-msg mh-ps-print-msg)
-(mh-defun-show-buffer mh-show-toggle-mime-buttons mh-toggle-mime-buttons)
-(mh-defun-show-buffer mh-show-display-with-external-viewer
- mh-display-with-external-viewer)
-
-\f
-
-;;; Sequence Menu
-
-(easy-menu-define
- mh-show-sequence-menu mh-show-mode-map "Menu for MH-E folder-sequence."
- '("Sequence"
- ["Add Message to Sequence..." mh-show-put-msg-in-seq t]
- ["List Sequences for Message" mh-show-msg-is-in-seq t]
- ["Delete Message from Sequence..." mh-show-delete-msg-from-seq t]
- ["List Sequences in Folder..." mh-show-list-sequences t]
- ["Delete Sequence..." mh-show-delete-seq t]
- ["Narrow to Sequence..." mh-show-narrow-to-seq t]
- ["Widen from Sequence" mh-show-widen t]
- "--"
- ["Narrow to Subject Sequence" mh-show-narrow-to-subject t]
- ["Narrow to Tick Sequence" mh-show-narrow-to-tick
- (with-current-buffer mh-show-folder-buffer
- (and mh-tick-seq (mh-seq-msgs (mh-find-seq mh-tick-seq))))]
- ["Delete Rest of Same Subject" mh-show-delete-subject t]
- ["Toggle Tick Mark" mh-show-toggle-tick t]
- "--"
- ["Push State Out to MH" mh-show-update-sequences t]))
-
-;;; Message Menu
-
-(easy-menu-define
- mh-show-message-menu mh-show-mode-map "Menu for MH-E folder-message."
- '("Message"
- ["Show Message" mh-show-show t]
- ["Show Message with Header" mh-show-header-display t]
- ["Show Message with Preferred Alternative"
- mh-show-show-preferred-alternative t]
- ["Next Message" mh-show-next-undeleted-msg t]
- ["Previous Message" mh-show-previous-undeleted-msg t]
- ["Go to First Message" mh-show-first-msg t]
- ["Go to Last Message" mh-show-last-msg t]
- ["Go to Message by Number..." mh-show-goto-msg t]
- ["Modify Message" mh-show-modify t]
- ["Delete Message" mh-show-delete-msg t]
- ["Refile Message" mh-show-refile-msg t]
- ["Undo Delete/Refile" mh-show-undo t]
- ["Process Delete/Refile" mh-show-execute-commands t]
- "--"
- ["Compose a New Message" mh-send t]
- ["Reply to Message..." mh-show-reply t]
- ["Forward Message..." mh-show-forward t]
- ["Redistribute Message..." mh-show-redistribute t]
- ["Edit Message Again" mh-show-edit-again t]
- ["Re-edit a Bounced Message" mh-show-extract-rejected-mail t]
- "--"
- ["Copy Message to Folder..." mh-show-copy-msg t]
- ["Print Message" mh-show-print-msg t]
- ["Write Message to File..." mh-show-write-msg-to-file t]
- ["Pipe Message to Command..." mh-show-pipe-msg t]
- ["Unpack Uuencoded Message..." mh-show-store-msg t]
- ["Burst Digest Message" mh-show-burst-digest t]))
-
-;;; Folder Menu
-
-(easy-menu-define
- mh-show-folder-menu mh-show-mode-map "Menu for MH-E folder."
- '("Folder"
- ["Incorporate New Mail" mh-show-inc-folder t]
- ["Toggle Show/Folder" mh-show-toggle-showing t]
- ["Execute Delete/Refile" mh-show-execute-commands t]
- ["Rescan Folder" mh-show-rescan-folder t]
- ["Thread Folder" mh-show-toggle-threads t]
- ["Pack Folder" mh-show-pack-folder t]
- ["Sort Folder" mh-show-sort-folder t]
- "--"
- ["List Folders" mh-show-list-folders t]
- ["Visit a Folder..." mh-show-visit-folder t]
- ["View New Messages" mh-show-index-new-messages t]
- ["Search..." mh-search t]
- "--"
- ["Quit MH-E" mh-quit t]))
-
-\f
-
-;;; MH-Show Keys
-
-(define-keymap :keymap mh-show-mode-map
- "SPC" #'mh-show-page-msg
- "!" #'mh-show-refile-or-write-again
- "'" #'mh-show-toggle-tick
- "," #'mh-show-header-display
- "." #'mh-show-show
- ":" #'mh-show-show-preferred-alternative
- ">" #'mh-show-write-message-to-file
- "?" #'mh-help
- "E" #'mh-show-extract-rejected-mail
- "M" #'mh-show-modify
- "DEL" #'mh-show-previous-page
- "C-d" #'mh-show-delete-msg-no-motion
- "TAB" #'mh-show-next-button
- "<backtab>" #'mh-show-prev-button
- "C-M-i" #'mh-show-prev-button
- "ESC d" #'mh-show-redistribute
- "^" #'mh-show-refile-msg
- "c" #'mh-show-copy-msg
- "d" #'mh-show-delete-msg
- "e" #'mh-show-edit-again
- "f" #'mh-show-forward
- "g" #'mh-show-goto-msg
- "i" #'mh-show-inc-folder
- "k" #'mh-show-delete-subject-or-thread
- "m" #'mh-show-send
- "n" #'mh-show-next-undeleted-msg
- "M-n" #'mh-show-next-unread-msg
- "o" #'mh-show-refile-msg
- "p" #'mh-show-previous-undeleted-msg
- "M-p" #'mh-show-previous-unread-msg
- "q" #'mh-show-quit
- "r" #'mh-show-reply
- "s" #'mh-show-send
- "t" #'mh-show-toggle-showing
- "u" #'mh-show-undo
- "x" #'mh-show-execute-commands
- "v" #'mh-show-index-visit-folder
- "|" #'mh-show-pipe-msg
-
- "F" (define-keymap :prefix 'mh-show-folder-map
- "?" #'mh-prefix-help
- "'" #'mh-index-ticked-messages
- "S" #'mh-show-sort-folder
- "c" #'mh-show-catchup
- "f" #'mh-show-visit-folder
- "k" #'mh-show-kill-folder
- "l" #'mh-show-list-folders
- "n" #'mh-index-new-messages
- "o" #'mh-show-visit-folder
- "p" #'mh-show-pack-folder
- "q" #'mh-show-index-sequenced-messages
- "r" #'mh-show-rescan-folder
- "s" #'mh-search
- "t" #'mh-show-toggle-threads
- "u" #'mh-show-undo-folder
- "v" #'mh-show-visit-folder)
-
- "S" (define-keymap :prefix 'mh-show-sequence-map
- "'" #'mh-show-narrow-to-tick
- "?" #'mh-prefix-help
- "d" #'mh-show-delete-msg-from-seq
- "k" #'mh-show-delete-seq
- "l" #'mh-show-list-sequences
- "n" #'mh-show-narrow-to-seq
- "p" #'mh-show-put-msg-in-seq
- "s" #'mh-show-msg-is-in-seq
- "w" #'mh-show-widen)
-
- "I" mh-inc-spool-map
-
- "J" (define-keymap :prefix 'mh-show-junk-map
- "?" #'mh-prefix-help
- "a" #'mh-show-junk-allowlist
- "b" #'mh-show-junk-blocklist
- "w" #'mh-show-junk-whitelist)
-
- "P" (define-keymap :prefix 'mh-show-ps-print-map
- "?" #'mh-prefix-help
- "C" #'mh-show-ps-print-toggle-color
- "F" #'mh-show-ps-print-toggle-faces
- "f" #'mh-show-ps-print-msg-file
- "l" #'mh-show-print-msg
- "p" #'mh-show-ps-print-msg)
-
- "T" (define-keymap :prefix 'mh-show-thread-map
- "?" #'mh-prefix-help
- "u" #'mh-show-thread-ancestor
- "p" #'mh-show-thread-previous-sibling
- "n" #'mh-show-thread-next-sibling
- "t" #'mh-show-toggle-threads
- "d" #'mh-show-thread-delete
- "o" #'mh-show-thread-refile)
-
- "/" (define-keymap :prefix 'mh-show-limit-map
- "'" #'mh-show-narrow-to-tick
- "?" #'mh-prefix-help
- "c" #'mh-show-narrow-to-cc
- "g" #'mh-show-narrow-to-range
- "m" #'mh-show-narrow-to-from
- "s" #'mh-show-narrow-to-subject
- "t" #'mh-show-narrow-to-to
- "w" #'mh-show-widen)
-
- "X" (define-keymap :prefix 'mh-show-extract-map
- "?" #'mh-prefix-help
- "s" #'mh-show-store-msg
- "u" #'mh-show-store-msg)
-
- "D" (define-keymap :prefix 'mh-show-digest-map
- "?" #'mh-prefix-help
- "SPC" #'mh-show-page-digest
- "DEL" #'mh-show-page-digest-backwards
- "b" #'mh-show-burst-digest)
-
- "K" (define-keymap :prefix 'mh-show-mime-map
- "?" #'mh-prefix-help
- "a" #'mh-mime-save-parts
- "e" #'mh-show-display-with-external-viewer
- "v" #'mh-show-toggle-mime-part
- "o" #'mh-show-save-mime-part
- "i" #'mh-show-inline-mime-part
- "t" #'mh-show-toggle-mime-buttons
- "TAB" #'mh-show-next-button
- "<backtab>" #'mh-show-prev-button
- "C-M-i" #'mh-show-prev-button))
-
-\f
-
-;;; MH-Show Font Lock
-
-(defun mh-header-field-font-lock (field limit)
- "Return the value of a header field FIELD to font-lock.
-Argument LIMIT limits search."
- (if (= (point) limit)
- nil
- (let* ((mail-header-end (mh-mail-header-end))
- (lesser-limit (if (< mail-header-end limit) mail-header-end limit))
- (case-fold-search t))
- (when (and (< (point) mail-header-end) ;Only within header
- (re-search-forward (format "^%s" field) lesser-limit t))
- (let ((match-one-b (match-beginning 0))
- (match-one-e (match-end 0)))
- (mh-header-field-end)
- (if (> (point) limit) ;Don't search for end beyond limit
- (goto-char limit))
- (set-match-data (list match-one-b match-one-e
- (1+ match-one-e) (point)))
- t)))))
-
-(defun mh-header-to-font-lock (limit)
- "Return the value of a header field To to font-lock.
-Argument LIMIT limits search."
- (mh-header-field-font-lock "To:" limit))
-
-(defun mh-header-cc-font-lock (limit)
- "Return the value of a header field cc to font-lock.
-Argument LIMIT limits search."
- (mh-header-field-font-lock "cc:" limit))
-
-(defun mh-header-subject-font-lock (limit)
- "Return the value of a header field Subject to font-lock.
-Argument LIMIT limits search."
- (mh-header-field-font-lock "Subject:" limit))
-
-(defun mh-letter-header-font-lock (limit)
- "Return the entire mail header to font-lock.
-Argument LIMIT limits search."
- (if (= (point) limit)
- nil
- (let* ((mail-header-end (save-match-data (mh-mail-header-end)))
- (lesser-limit (if (< mail-header-end limit) mail-header-end limit)))
- (when (mh-in-header-p)
- (set-match-data (list 1 lesser-limit))
- (goto-char lesser-limit)
- t))))
-
-(defun mh-show-font-lock-fontify-region (beg end loudly)
- "Limit font-lock in `mh-show-mode' to the header.
-
-Used when the option `mh-highlight-citation-style' is set to
-\"Gnus\", leaving the body to be dealt with by Gnus highlighting.
-The region between BEG and END is given over to be fontified and
-LOUDLY controls if a user sees a message about the fontification
-operation."
- (let ((header-end (mh-mail-header-end)))
- (cond
- ((and (< beg header-end)(< end header-end))
- (font-lock-default-fontify-region beg end loudly))
- ((and (< beg header-end)(>= end header-end))
- (font-lock-default-fontify-region beg header-end loudly))
- (t
- nil))))
-
-(defvar mh-show-font-lock-keywords
- '(("^\\(From:\\|Sender:\\)\\(.*\\)"
- (1 'default)
- (2 'mh-show-from))
- (mh-header-to-font-lock
- (0 'default)
- (1 'mh-show-to))
- (mh-header-cc-font-lock
- (0 'default)
- (1 'mh-show-cc))
- ("^\\(Reply-To:\\|Return-Path:\\)\\(.*\\)$"
- (1 'default)
- (2 'mh-show-from))
- (mh-header-subject-font-lock
- (0 'default)
- (1 'mh-show-subject))
- ("^\\(Apparently-To:\\|Newsgroups:\\)\\(.*\\)"
- (1 'default)
- (2 'mh-show-cc))
- ("^\\(In-Reply-To\\|Date\\):\\(.*\\)$"
- (1 'default)
- (2 'mh-show-date))
- (mh-letter-header-font-lock
- (0 'mh-show-header append t)))
- "Additional expressions to highlight in MH-Show buffers.")
-
-;;;###mh-autoload
-(defun mh-show-font-lock-keywords ()
- "Return variable `mh-show-font-lock-keywords'."
- mh-show-font-lock-keywords)
-
-(defvar mh-show-font-lock-keywords-with-cite
- (let* ((cite-chars "[>|}]")
- (cite-prefix "A-Za-z")
- (cite-suffix (concat cite-prefix "0-9_.@-`'\"")))
- (append
- mh-show-font-lock-keywords
- (list
- ;; Use MATCH-ANCHORED to effectively anchor the regexp left side.
- `(,cite-chars
- (,(concat "\\=[ \t]*"
- "\\(\\([" cite-prefix "]+[" cite-suffix "]*\\)?"
- "\\(" cite-chars "[ \t]*\\)\\)+"
- "\\(.*\\)")
- (beginning-of-line) (end-of-line)
- (2 font-lock-constant-face nil t)
- (4 font-lock-comment-face nil t))))))
- "Additional expressions to highlight in MH-Show buffers.")
-
-;;;###mh-autoload
-(defun mh-show-font-lock-keywords-with-cite ()
- "Return variable `mh-show-font-lock-keywords-with-cite'."
- mh-show-font-lock-keywords-with-cite)
-
-\f
-
-;;; MH-Show Mode
-
-;; Ensure new buffers won't get this mode if default major-mode is nil.
-(put 'mh-show-mode 'mode-class 'special)
-
-;;;###mh-autoload
-(define-derived-mode mh-show-mode text-mode "MH-Show"
- "Major mode for showing messages in MH-E.
-\\<mh-show-mode-map>
-Email addresses and URLs in the message are highlighted if the
-option `goto-address-highlight-p' is on, which it is by default.
-To view the web page for a highlighted URL or to send a message
-using a highlighted email address, use the middle mouse button or
-\\[goto-address-at-point]. See Info node `(mh-e)Sending Mail' to
-see how to configure Emacs to send the message using MH-E.
-
-The hook `mh-show-mode-hook' is called upon entry to this mode.
-
-See also `mh-folder-mode'.
-
-\\{mh-show-mode-map}"
- (if (boundp 'tool-bar-map)
- (setq-local tool-bar-map mh-show-tool-bar-map))
- (setq-local mail-header-separator mh-mail-header-separator)
- (setq paragraph-start (default-value 'paragraph-start))
- (setq buffer-invisibility-spec '((vanish . t) t))
- (setq-local line-move-ignore-invisible t)
- (make-local-variable 'font-lock-defaults)
- ;;(setq-local font-lock-support-mode nil)
- (cond
- ((equal mh-highlight-citation-style 'font-lock)
- (setq font-lock-defaults '(mh-show-font-lock-keywords-with-cite t)))
- ((equal mh-highlight-citation-style 'gnus)
- (setq font-lock-defaults '((mh-show-font-lock-keywords)
- t nil nil nil
- (font-lock-fontify-region-function
- . mh-show-font-lock-fontify-region)))
- (mh-gnus-article-highlight-citation))
- (t
- (setq font-lock-defaults '(mh-show-font-lock-keywords t))))
- (when mh-decode-mime-flag
- (add-hook 'kill-buffer-hook #'mh-mime-cleanup nil t))
- (make-local-variable 'mh-show-folder-buffer)
- (buffer-disable-undo)
- (use-local-map mh-show-mode-map))
-
-\f
-
-;;; Support Routines
-
-(defun mh-show-unquote-From ()
- "Decode >From at beginning of lines for `mh-show-mode'."
- (save-excursion
- (let ((modified (buffer-modified-p))
- (case-fold-search nil)
- (buffer-read-only nil))
- (goto-char (mh-mail-header-end))
- (while (re-search-forward "^>From" nil t)
- (replace-match "From"))
- (set-buffer-modified-p modified))))
-
-;;;###mh-autoload
-(defun mh-show-addr ()
- "Use `goto-address'."
- (goto-address))
-
-;;;###mh-autoload
-(defun mh-gnus-article-highlight-citation ()
- "Highlight cited text in current buffer using Gnus."
- (interactive)
- ;; Don't allow Gnus to create buttons while highlighting, maybe this is bad
- ;; style?
- (mh-flet
- ((gnus-article-add-button (&rest _args) nil))
- (let* ((modified (buffer-modified-p))
- (gnus-article-buffer (buffer-name))
- (gnus-cite-face-list `(,@(cdr gnus-cite-face-list)
- ,(car gnus-cite-face-list))))
- (gnus-article-highlight-citation t)
- (set-buffer-modified-p modified))))
-
-(provide 'mh-show)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-show.el ends here
+++ /dev/null
-;;; mh-speed.el --- MH-E speedbar support -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2024 Free Software Foundation, Inc.
-
-;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Future versions should only use flists.
-
-;;; Code:
-
-(require 'mh-e)
-
-(require 'gnus-util)
-(require 'speedbar)
-(require 'timer)
-
-;; Global variables.
-(defvar mh-speed-refresh-flag nil)
-(defvar mh-speed-last-selected-folder nil)
-(defvar mh-speed-folder-map (make-hash-table :test #'equal))
-(defvar mh-speed-flists-cache (make-hash-table :test #'equal))
-(defvar mh-speed-flists-process nil)
-(defvar mh-speed-flists-timer nil)
-(defvar mh-speed-partial-line "")
-
-\f
-
-;;; Speedbar Hook
-
-(unless (member 'mh-speed-stealth-update
- (cdr (assoc "files" speedbar-stealthy-function-list)))
- ;; Is changing constant lists in elisp safe?
- (setq speedbar-stealthy-function-list
- (copy-tree speedbar-stealthy-function-list))
- (push 'mh-speed-stealth-update
- (cdr (assoc "files" speedbar-stealthy-function-list))))
-
-\f
-
-;;; Speedbar Menus
-
-(defvar mh-folder-speedbar-menu-items
- '("--"
- ["Visit Folder" mh-speed-view
- (with-current-buffer speedbar-buffer
- (get-text-property (line-beginning-position) 'mh-folder))]
- ["Expand Nested Folders" mh-speed-expand-folder
- (and (get-text-property (line-beginning-position) 'mh-children-p)
- (not (get-text-property (line-beginning-position) 'mh-expanded)))]
- ["Contract Nested Folders" mh-speed-contract-folder
- (and (get-text-property (line-beginning-position) 'mh-children-p)
- (get-text-property (line-beginning-position) 'mh-expanded))]
- ["Refresh Speedbar" mh-speed-refresh t])
- "Extra menu items for speedbar.")
-
-(defvar mh-show-speedbar-menu-items mh-folder-speedbar-menu-items)
-(defvar mh-letter-speedbar-menu-items mh-folder-speedbar-menu-items)
-
-\f
-
-;;; Speedbar Keys
-
-(defvar mh-folder-speedbar-key-map (speedbar-make-specialized-keymap)
- "Specialized speedbar keymap for MH-E buffers.")
-
-(define-keymap :keymap mh-folder-speedbar-key-map
- "+" #'mh-speed-expand-folder
- "-" #'mh-speed-contract-folder
- "RET" #'mh-speed-view
- "r" #'mh-speed-refresh)
-
-(defvar mh-show-speedbar-key-map mh-folder-speedbar-key-map)
-(defvar mh-letter-speedbar-key-map mh-folder-speedbar-key-map)
-
-\f
-
-;;; Speedbar Commands
-
-;; Alphabetical.
-
-(defalias 'mh-speed-contract-folder #'mh-speed-toggle)
-
-(defalias 'mh-speed-expand-folder #'mh-speed-toggle)
-
-(defun mh-speed-refresh ()
- "Regenerates the list of folders in the speedbar.
-
-Run this command if you've added or deleted a folder, or want to
-update the unseen message count before the next automatic
-update."
- (interactive)
- (mh-speed-flists t)
- (mh-speed-invalidate-map ""))
-
-(defun mh-speed-stealth-update (&optional force)
- "Do stealth update.
-With non-nil FORCE, the update is always carried out."
- (cond ((with-current-buffer speedbar-buffer
- (get-text-property (point-min) 'mh-level))
- ;; Execute this hook and *don't* run anything else
- (mh-speed-update-current-folder force)
- nil)
- ;; Otherwise on to your regular programming
- (t t)))
-
-(defun mh-speed-toggle (&rest _ignored)
- "Toggle the display of child folders in the speedbar.
-The optional arguments from speedbar are IGNORED."
- (interactive)
- (beginning-of-line)
- (let ((parent (get-text-property (point) 'mh-folder))
- (kids-p (get-text-property (point) 'mh-children-p))
- (expanded (get-text-property (point) 'mh-expanded))
- (level (get-text-property (point) 'mh-level))
- (point (point))
- start-region)
- (speedbar-with-writable
- (cond ((not kids-p) nil)
- (expanded
- (forward-line)
- (setq start-region (point))
- (while (and (get-text-property (point) 'mh-level)
- (> (get-text-property (point) 'mh-level) level))
- (let ((folder (get-text-property (point) 'mh-folder)))
- (when (gethash folder mh-speed-folder-map)
- (set-marker (gethash folder mh-speed-folder-map) nil)
- (remhash folder mh-speed-folder-map)))
- (forward-line))
- (delete-region start-region (point))
- (forward-line -1)
- (speedbar-change-expand-button-char ?+)
- (add-text-properties
- (line-beginning-position) (1+ (line-beginning-position))
- '(mh-expanded nil)))
- (t
- (forward-line)
- (mh-speed-add-buttons parent (1+ level))
- (goto-char point)
- (speedbar-change-expand-button-char ?-)
- (add-text-properties
- (line-beginning-position) (1+ (line-beginning-position))
- '(mh-expanded t)))))))
-
-(defun mh-speed-view (&rest _ignored)
- "Visits the selected folder just as if you had used \\<mh-folder-mode-map>\\[mh-visit-folder].
-The optional arguments from speedbar are IGNORED."
- (interactive)
- (let* ((folder (get-text-property (line-beginning-position) 'mh-folder))
- (range (and (stringp folder)
- (mh-read-range "Scan" folder t nil nil
- mh-interpret-number-as-range-flag))))
- (when (stringp folder)
- (dframe-with-attached-buffer
- (mh-visit-folder folder range)
- (delete-other-windows)))))
-
-\f
-
-;;; Support Routines
-
-;;;###mh-autoload
-(defun mh-folder-speedbar-buttons (_buffer)
- "Interface function to create MH-E speedbar buffer.
-BUFFER is the MH-E buffer for which the speedbar buffer is to be
-created."
- (unless (get-text-property (point-min) 'mh-level)
- (erase-buffer)
- (clrhash mh-speed-folder-map)
- (speedbar-make-tag-line 'bracket ?+ 'mh-speed-toggle nil " " 'ignore nil
- 'mh-speedbar-folder 0)
- (forward-line -1)
- (setf (gethash nil mh-speed-folder-map)
- (set-marker (or (gethash nil mh-speed-folder-map) (make-marker))
- (1+ (line-beginning-position))))
- (add-text-properties
- (line-beginning-position) (1+ (line-beginning-position))
- '(mh-folder nil mh-expanded nil mh-children-p t mh-level 0))
- (mh-speed-stealth-update t)
- (when (> mh-speed-update-interval 0)
- (mh-speed-flists nil))))
-
-;;;###mh-autoload
-(defalias 'mh-show-speedbar-buttons #'mh-folder-speedbar-buttons)
-;;;###mh-autoload
-(defalias 'mh-letter-speedbar-buttons #'mh-folder-speedbar-buttons)
-
-(defmacro mh-speed-select-attached-frame ()
- "Compatibility macro to handle speedbar versions 0.11a and 0.14beta4."
- (cond ((fboundp 'dframe-select-attached-frame)
- '(dframe-select-attached-frame speedbar-frame))
- ((boundp 'speedbar-attached-frame)
- '(select-frame speedbar-attached-frame))
- (t (error "Installed speedbar version not supported by MH-E"))))
-
-(defun mh-speed-update-current-folder (force)
- "Update speedbar highlighting of the current folder.
-The function tries to be smart so that work done is minimized.
-The currently highlighted folder is cached and no highlighting
-happens unless it changes.
-Also highlighting is suspended while the speedbar frame is selected.
-Otherwise you get the disconcerting behavior of folders popping open
-on their own when you are trying to navigate around in the speedbar
-buffer.
-
-The update is always carried out if FORCE is non-nil."
- (let* ((lastf (selected-frame))
- (newcf (save-excursion
- (mh-speed-select-attached-frame)
- (prog1 (mh-speed-extract-folder-name (buffer-name))
- (select-frame lastf))))
- (lastb (current-buffer))
- (case-fold-search t))
- (when (or force
- (and mh-speed-refresh-flag (not (eq lastf speedbar-frame)))
- (and (stringp newcf)
- (equal (substring newcf 0 1) "+")
- (not (equal newcf mh-speed-last-selected-folder))))
- (setq mh-speed-refresh-flag nil)
- (select-frame speedbar-frame)
- (set-buffer speedbar-buffer)
-
- ;; Remove highlight from previous match...
- (mh-speed-highlight mh-speed-last-selected-folder 'mh-speedbar-folder)
-
- ;; If we found a match highlight it...
- (when (mh-speed-goto-folder newcf)
- (mh-speed-highlight newcf 'mh-speedbar-selected-folder))
-
- (setq mh-speed-last-selected-folder newcf)
- (speedbar-position-cursor-on-line)
- (set-window-point (frame-first-window speedbar-frame) (point))
- (set-buffer lastb)
- (select-frame lastf))
- (when (eq lastf speedbar-frame)
- (setq mh-speed-refresh-flag t))))
-
-(defun mh-speed-highlight (folder face)
- "Set FOLDER to FACE."
- (save-excursion
- (speedbar-with-writable
- (goto-char (gethash folder mh-speed-folder-map (point)))
- (beginning-of-line)
- (if (re-search-forward "([1-9][0-9]*/[0-9]+)" (line-end-position) t)
- (setq face (mh-speed-bold-face face))
- (setq face (mh-speed-normal-face face)))
- (beginning-of-line)
- (when (re-search-forward "\\[.\\] " (line-end-position) t)
- (put-text-property (point) (line-end-position) 'face face)))))
-
-(defun mh-speed-normal-face (face)
- "Return normal face for given FACE."
- (cond ((eq face 'mh-speedbar-folder-with-unseen-messages)
- 'mh-speedbar-folder)
- ((eq face 'mh-speedbar-selected-folder-with-unseen-messages)
- 'mh-speedbar-selected-folder)
- (t face)))
-
-(defun mh-speed-bold-face (face)
- "Return bold face for given FACE."
- (cond ((eq face 'mh-speedbar-folder)
- 'mh-speedbar-folder-with-unseen-messages)
- ((eq face 'mh-speedbar-selected-folder)
- 'mh-speedbar-selected-folder-with-unseen-messages)
- (t face)))
-
-(defun mh-speed-goto-folder (folder)
- "Move point to line containing FOLDER.
-The function will expand out parent folders of FOLDER if needed."
- (let ((prefix folder)
- (suffix-list ())
- (last-slash t))
- (while (and (not (gethash prefix mh-speed-folder-map)) last-slash)
- (setq last-slash (mh-search-from-end ?/ prefix))
- (when (integerp last-slash)
- (push (substring prefix (1+ last-slash)) suffix-list)
- (setq prefix (substring prefix 0 last-slash))))
- (let ((prefix-position (gethash prefix mh-speed-folder-map)))
- (if prefix-position
- (goto-char prefix-position)
- (goto-char (point-min))
- (mh-speed-toggle)
- (unless (get-text-property (point) 'mh-expanded)
- (mh-speed-toggle))
- (goto-char (gethash prefix mh-speed-folder-map))))
- (while suffix-list
- ;; We always need at least one toggle. We need two if the directory list
- ;; is stale since a folder was added.
- (when (equal prefix (get-text-property (line-beginning-position)
- 'mh-folder))
- (mh-speed-toggle)
- (unless (get-text-property (point) 'mh-expanded)
- (mh-speed-toggle)))
- (setq prefix (format "%s/%s" prefix (pop suffix-list)))
- (goto-char (gethash prefix mh-speed-folder-map (point))))
- (beginning-of-line)
- (equal folder (get-text-property (point) 'mh-folder))))
-
-(defun mh-speed-extract-folder-name (buffer)
- "Given an MH-E BUFFER find the folder that should be highlighted.
-Do the right thing for the different kinds of buffers that MH-E
-uses."
- (with-current-buffer buffer
- (cond ((eq major-mode 'mh-folder-mode)
- mh-current-folder)
- ((eq major-mode 'mh-show-mode)
- (set-buffer mh-show-folder-buffer)
- mh-current-folder)
- ((eq major-mode 'mh-letter-mode)
- (when (string-match mh-user-path buffer-file-name)
- (let* ((rel-path (substring buffer-file-name (match-end 0)))
- (directory-end (mh-search-from-end ?/ rel-path)))
- (when directory-end
- (format "+%s" (substring rel-path 0 directory-end)))))))))
-
-(defun mh-speed-add-buttons (folder level)
- "Add speedbar button for FOLDER which is at indented by LEVEL amount."
- (let ((folder-list (mh-sub-folders folder)))
- (mapc
- (lambda (f)
- (let* ((folder-name (format "%s%s%s" (or folder "+")
- (if folder "/" "") (car f)))
- (counts (gethash folder-name mh-speed-flists-cache)))
- (speedbar-with-writable
- (speedbar-make-tag-line
- 'bracket (if (cdr f) ?+ ? )
- 'mh-speed-toggle nil
- (format "%s%s"
- (car f)
- (if counts
- (format " (%s/%s)" (car counts) (cdr counts))
- ""))
- 'mh-speed-view nil
- (if (and counts (> (car counts) 0))
- 'mh-speedbar-folder-with-unseen-messages
- 'mh-speedbar-folder)
- level)
- (save-excursion
- (forward-line -1)
- (setf (gethash folder-name mh-speed-folder-map)
- (set-marker (or (gethash folder-name mh-speed-folder-map)
- (make-marker))
- (1+ (line-beginning-position))))
- (add-text-properties
- (line-beginning-position) (1+ (line-beginning-position))
- `(mh-folder ,folder-name
- mh-expanded nil
- mh-children-p ,(not (not (cdr f)))
- ,@(if counts `(mh-count
- (,(car counts) . ,(cdr counts))) ())
- mh-level ,level))))))
- folder-list)))
-
-(defvar mh-speed-current-folder nil)
-(defvar mh-speed-flists-folder nil)
-
-(defmacro mh-process-kill-without-query (process)
- "PROCESS can be killed without query on Emacs exit."
- (declare (obsolete set-process-query-on-exit-flag "29.1"))
- `(set-process-query-on-exit-flag ,process nil))
-
-;;;###mh-autoload
-(defun mh-speed-flists (force &rest folders)
- "Execute flists -recurse and update message counts.
-If FORCE is non-nil the timer is reset.
-
-Any number of optional FOLDERS can be specified. If specified,
-flists is run only for that one folder."
- (interactive (list t))
- (when force
- (when mh-speed-flists-timer
- (cancel-timer mh-speed-flists-timer)
- (setq mh-speed-flists-timer nil))
- (when (and (processp mh-speed-flists-process)
- (not (eq (process-status mh-speed-flists-process) 'exit)))
- (set-process-filter mh-speed-flists-process t)
- (kill-process mh-speed-flists-process)
- (setq mh-speed-partial-line "")
- (setq mh-speed-flists-process nil)))
- (setq mh-speed-flists-folder folders)
- (unless mh-speed-flists-timer
- (setq mh-speed-flists-timer
- (run-at-time
- nil (if (> mh-speed-update-interval 0)
- mh-speed-update-interval
- nil)
- (lambda ()
- (unless (and (processp mh-speed-flists-process)
- (not (eq (process-status mh-speed-flists-process)
- 'exit)))
- (setq mh-speed-current-folder
- (concat
- (if mh-speed-flists-folder
- (substring (car (reverse mh-speed-flists-folder)) 1)
- (with-temp-buffer
- (call-process (expand-file-name "folder" mh-progs)
- nil '(t nil) nil "-fast")
- (buffer-substring (point-min) (1- (point-max)))))
- "+"))
- (setq mh-speed-flists-process
- (apply #'start-process "*flists*" nil
- (expand-file-name "flists" mh-progs)
- (if mh-speed-flists-folder "-noall" "-all")
- "-sequence" (symbol-name mh-unseen-seq)
- (or mh-speed-flists-folder '("-recurse"))))
- ;; Run flists on all folders the next time around...
- (setq mh-speed-flists-folder nil)
- (set-process-query-on-exit-flag mh-speed-flists-process nil)
- (set-process-filter mh-speed-flists-process
- #'mh-speed-parse-flists-output)))))))
-
-;; Copied from mh-make-folder-list-filter...
-;; XXX Refactor to use mh-make-folder-list-filer?
-(defun mh-speed-parse-flists-output (_process output)
- "Parse the incremental results from flists.
-PROCESS is the flists process and OUTPUT is the results that must
-be handled next."
- (let ((prevailing-match-data (match-data))
- (position 0)
- line-end line folder unseen total)
- (unwind-protect
- (while (setq line-end (string-search "\n" output position))
- (setq line (format "%s%s"
- mh-speed-partial-line
- (substring output position line-end))
- mh-speed-partial-line "")
- (cl-multiple-value-setq (folder unseen total)
- (cl-values-list
- (mh-parse-flist-output-line line mh-speed-current-folder)))
- (when (and folder unseen total
- (let ((old-pair (gethash folder mh-speed-flists-cache)))
- (or (not (equal (car old-pair) unseen))
- (not (equal (cdr old-pair) total)))))
- (setf (gethash folder mh-speed-flists-cache) (cons unseen total))
- (when (buffer-live-p (get-buffer speedbar-buffer))
- (with-current-buffer speedbar-buffer
- (speedbar-with-writable
- (when (get-text-property (point-min) 'mh-level)
- (let ((pos (gethash folder mh-speed-folder-map))
- face)
- (when pos
- (goto-char pos)
- (goto-char (line-beginning-position))
- (cond
- ((null (get-text-property (point) 'mh-count))
- (goto-char (line-end-position))
- (setq face (get-text-property (1- (point)) 'face))
- (insert (format " (%s/%s)" unseen total))
- (mh-speed-highlight 'unknown face)
- (goto-char (line-beginning-position))
- (add-text-properties (point) (1+ (point))
- `(mh-count (,unseen . ,total))))
- ((not (equal (get-text-property (point) 'mh-count)
- (cons unseen total)))
- (goto-char (line-end-position))
- (setq face (get-text-property (1- (point)) 'face))
- (re-search-backward " " (line-beginning-position) t)
- (delete-region (point) (line-end-position))
- (insert (format " (%s/%s)" unseen total))
- (mh-speed-highlight 'unknown face)
- (goto-char (line-beginning-position))
- (add-text-properties
- (point) (1+ (point))
- `(mh-count (,unseen . ,total))))))))))))
- (setq position (1+ line-end)))
- (set-match-data prevailing-match-data))
- (setq mh-speed-partial-line (substring output position))))
-
-;;;###mh-autoload
-(defun mh-speed-invalidate-map (folder)
- "Remove FOLDER from various optimization caches."
- (interactive (list ""))
- (with-current-buffer speedbar-buffer
- (let* ((speedbar-update-flag nil)
- (last-slash (mh-search-from-end ?/ folder))
- (parent (if last-slash (substring folder 0 last-slash) nil))
- (parent-position (gethash parent mh-speed-folder-map))
- (parent-change nil))
- (when parent-position
- (let ((parent-kids (mh-sub-folders parent)))
- (cond ((null parent-kids)
- (setq parent-change ?+))
- ((and (null (cdr parent-kids))
- (equal (if last-slash
- (substring folder (1+ last-slash))
- (substring folder 1))
- (caar parent-kids)))
- (setq parent-change ? ))))
- (goto-char parent-position)
- (when (equal (get-text-property (line-beginning-position) 'mh-folder)
- parent)
- (when (get-text-property (line-beginning-position) 'mh-expanded)
- (mh-speed-toggle))
- (when parent-change
- (speedbar-with-writable
- (mh-speedbar-change-expand-button-char parent-change)
- (add-text-properties
- (line-beginning-position) (1+ (line-beginning-position))
- `(mh-children-p ,(equal parent-change ?+)))))
- (mh-speed-highlight mh-speed-last-selected-folder 'mh-speedbar-folder)
- (setq mh-speed-last-selected-folder nil)
- (setq mh-speed-refresh-flag t)))
- (when (equal folder "")
- (mh-clear-sub-folders-cache)))))
-
-;; Make it slightly more general to allow for [ ] buttons to be
-;; changed to [+].
-(defun mh-speedbar-change-expand-button-char (char)
- "Change the expansion button character to CHAR for the current line."
- (save-excursion
- (beginning-of-line)
- (if (re-search-forward "\\[.\\]" (line-end-position) t)
- (speedbar-with-writable
- (backward-char 2)
- (delete-char 1)
- (insert-char char 1 t)
- (put-text-property (point) (1- (point)) 'invisible nil)
- ;; make sure we fix the image on the text here.
- (when (fboundp 'speedbar-insert-image-button-maybe)
- (speedbar-insert-image-button-maybe (- (point) 2) 3))))))
-
-;;;###mh-autoload
-(defun mh-speed-add-folder (folder)
- "Add FOLDER since it is being created.
-The function invalidates the latest ancestor that is present."
- (with-current-buffer speedbar-buffer
- (let ((speedbar-update-flag nil)
- (last-slash (mh-search-from-end ?/ folder))
- (ancestor folder)
- (ancestor-pos nil))
- (cl-block while-loop
- (while last-slash
- (setq ancestor (substring ancestor 0 last-slash))
- (setq ancestor-pos (gethash ancestor mh-speed-folder-map))
- (when ancestor-pos
- (cl-return-from while-loop))
- (setq last-slash (mh-search-from-end ?/ ancestor))))
- (unless ancestor-pos (setq ancestor nil))
- (goto-char (or ancestor-pos (gethash nil mh-speed-folder-map)))
- (speedbar-with-writable
- (mh-speedbar-change-expand-button-char ?+)
- (add-text-properties
- (line-beginning-position) (1+ (line-beginning-position))
- '(mh-children-p t)))
- (when (get-text-property (line-beginning-position) 'mh-expanded)
- (mh-speed-toggle))
- (setq mh-speed-refresh-flag t))))
-
-(provide 'mh-speed)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-speed.el ends here
+++ /dev/null
-;;; mh-thread.el --- MH-E threading support -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2004, 2006-2024 Free Software Foundation, Inc.
-
-;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; The threading portion of this files tries to implement the
-;; algorithm described at:
-;; https://www.jwz.org/doc/threading.html
-;; It also begins to implement the threading section of the IMAP -
-;; SORT and THREAD Extensions RFC at:
-;; https://tools.ietf.org/html/rfc5256
-;; The implementation lacks the reference and subject canonicalization
-;; of the RFC.
-
-;; In the presentation buffer, children messages are shown indented
-;; with either [ ] or < > around them. Square brackets ([ ]) denote
-;; that the algorithm can point out some headers which when taken
-;; together implies that the unindented message is an ancestor of the
-;; indented message. If no such proof exists then angles (< >) are
-;; used.
-
-;; If threading is slow on your machine, compile this file. Of all the
-;; files in MH-E, this one really benefits from compilation.
-
-;; Some issues and problems are as follows:
-
-;; (1) Scan truncates the fields at length 512. So longer
-;; references: headers get mutilated. The same kind of MH
-;; format string works when composing messages. Is there a way
-;; to avoid this? My scan command is as follows:
-;; scan +folder -width 10000 \
-;; -format "%(msg)\n%{message-id}\n%{references}\n%{subject}\n"
-;; I would really appreciate it if someone would help me with this.
-
-;; (2) Implement heuristics to recognize message identifiers in
-;; In-Reply-To: header. Right now it just assumes that the last
-;; text between angles (< and >) is the message identifier.
-;; There is the chance that this will incorrectly use an email
-;; address like a message identifier.
-
-;; (3) Error checking of found message identifiers should be done.
-
-;; (4) Since this breaks the assumption that message indices
-;; increase as one goes down the buffer, the binary search
-;; based mh-goto-msg doesn't work. I have a simpler replacement
-;; which may be less efficient.
-
-;; (5) Better canonicalizing for message identifier and subject
-;; strings.
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-scan)
-
-(cl-defstruct (mh-thread-message (:conc-name mh-message-)
- (:constructor mh-thread-make-message))
- (id nil)
- (references ())
- (subject "")
- (subject-re-p nil))
-
-(cl-defstruct (mh-thread-container (:conc-name mh-container-)
- (:constructor mh-thread-make-container))
- message parent children
- (real-child-p t))
-
-(defvar-local mh-thread-id-hash nil
- "Hash table used to canonicalize message identifiers.")
-
-(defvar-local mh-thread-subject-hash nil
- "Hash table used to canonicalize subject strings.")
-
-(defvar-local mh-thread-id-table nil
- "Thread ID table maps from message identifiers to message containers.")
-
-(defvar-local mh-thread-index-id-map nil
- "Table to look up message identifier from message index.")
-
-(defvar-local mh-thread-id-index-map nil
- "Table to look up message index number from message identifier.")
-
-(defvar-local mh-thread-subject-container-hash nil
- "Hash table used to group messages by subject.")
-
-(defvar-local mh-thread-duplicates nil
- "Hash table used to associate messages with the same message identifier.")
-
-(defvar-local mh-thread-history ()
- "Variable to remember the transformations to the thread tree.
-When new messages are added, these transformations are rewound,
-then the links are added from the newly seen messages. Finally
-the transformations are redone to get the new thread tree. This
-makes incremental threading easier.")
-
-(defvar mh-thread-body-width nil
- "Width of scan substring that contains subject and body of message.")
-
-\f
-
-;;; MH-Folder Commands
-
-;;;###mh-autoload
-(defun mh-thread-ancestor (&optional thread-root-flag)
- "Display ancestor of current message.
-
-If you do not care for the way a particular thread has turned,
-you can move up the chain of messages with this command. This
-command can also take a prefix argument THREAD-ROOT-FLAG to jump
-to the message that started everything."
- (interactive "P")
- (beginning-of-line)
- (cond ((not (memq 'unthread mh-view-ops))
- (error "Folder isn't threaded"))
- ((eobp)
- (error "No message at point")))
- (let ((current-level (mh-thread-current-indentation-level)))
- (cond (thread-root-flag
- (while (mh-thread-immediate-ancestor))
- (mh-maybe-show))
- ((equal current-level 0)
- (message "Message has no ancestor"))
- (t (mh-thread-immediate-ancestor)
- (mh-maybe-show)))))
-
-;;;###mh-autoload
-(defun mh-thread-delete ()
- "Delete thread."
- (interactive)
- (cond ((not (memq 'unthread mh-view-ops))
- (error "Folder isn't threaded"))
- ((eobp)
- (error "No message at point"))
- (t (let ((region (mh-thread-find-children)))
- (mh-iterate-on-messages-in-region () (car region) (cadr region)
- (mh-delete-a-msg nil))
- (mh-next-msg)))))
-
-;;;###mh-autoload
-(defun mh-thread-next-sibling (&optional previous-flag)
- "Display next sibling.
-
-With non-nil optional argument PREVIOUS-FLAG jump to the previous
-sibling."
- (interactive)
- (cond ((not (memq 'unthread mh-view-ops))
- (error "Folder isn't threaded"))
- ((eobp)
- (error "No message at point")))
- (beginning-of-line)
- (let ((point (point))
- (done nil)
- (my-level (mh-thread-current-indentation-level)))
- (while (and (not done)
- (equal (forward-line (if previous-flag -1 1)) 0)
- (not (eobp)))
- (let ((level (mh-thread-current-indentation-level)))
- (cond ((equal level my-level)
- (setq done 'success))
- ((< level my-level)
- (message "No %s sibling" (if previous-flag "previous" "next"))
- (setq done 'failure)))))
- (cond ((eq done 'success) (mh-maybe-show))
- ((eq done 'failure) (goto-char point))
- (t (message "No %s sibling" (if previous-flag "previous" "next"))
- (goto-char point)))))
-
-;;;###mh-autoload
-(defun mh-thread-previous-sibling ()
- "Display previous sibling."
- (interactive)
- (mh-thread-next-sibling t))
-
-;;;###mh-autoload
-(defun mh-thread-refile (folder)
- "Refile (output) thread into FOLDER."
- (interactive (list (intern (mh-prompt-for-refile-folder))))
- (cond ((not (memq 'unthread mh-view-ops))
- (error "Folder isn't threaded"))
- ((eobp)
- (error "No message at point"))
- (t (let ((region (mh-thread-find-children)))
- (mh-iterate-on-messages-in-region () (car region) (cadr region)
- (mh-refile-a-msg nil folder))
- (mh-next-msg)))))
-
-;;;###mh-autoload
-(defun mh-toggle-threads ()
- "Toggle threaded view of folder."
- (interactive)
- (let ((msg-at-point (mh-get-msg-num nil))
- (old-buffer-modified-flag (buffer-modified-p))
- (buffer-read-only nil))
- (cond ((memq 'unthread mh-view-ops)
- (unless (mh-valid-view-change-operation-p 'unthread)
- (error "Can't unthread folder"))
- (let ((msg-list ()))
- (goto-char (point-min))
- (while (not (eobp))
- (let ((index (mh-get-msg-num nil)))
- (when index
- (push index msg-list)))
- (forward-line))
- (mh-scan-folder mh-current-folder
- (mapcar (lambda (x) (format "%s" x))
- (mh-coalesce-msg-list msg-list))
- t))
- (when mh-index-data
- (mh-index-insert-folder-headers)
- (mh-notate-cur)))
- (t (mh-thread-folder)
- (push 'unthread mh-view-ops)))
- (when msg-at-point (mh-goto-msg msg-at-point t t))
- (set-buffer-modified-p old-buffer-modified-flag)
- (mh-recenter nil)))
-
-\f
-
-;;; Support Routines
-
-(defun mh-thread-current-indentation-level ()
- "Find the number of spaces by which current message is indented."
- (save-excursion
- (let ((address-start-offset (+ mh-cmd-note
- mh-scan-field-from-start-offset))
- (level 0))
- (beginning-of-line)
- (forward-char address-start-offset)
- (while (char-equal (char-after) ? )
- (cl-incf level)
- (forward-char))
- level)))
-
-(defun mh-thread-immediate-ancestor ()
- "Jump to immediate ancestor in thread tree."
- (beginning-of-line)
- (let ((point (point))
- (ancestor-level (- (mh-thread-current-indentation-level) 2))
- (done nil))
- (if (< ancestor-level 0)
- nil
- (while (and (not done) (equal (forward-line -1) 0))
- (when (equal ancestor-level (mh-thread-current-indentation-level))
- (setq done t)))
- (unless done
- (goto-char point))
- done)))
-
-(defun mh-thread-find-children ()
- "Return a region containing the current message and its children.
-The result is returned as a list of two elements. The first is
-the point at the start of the region and the second is the point
-at the end."
- (beginning-of-line)
- (if (eobp)
- nil
- (let ((address-start-offset (+ mh-cmd-note
- mh-scan-field-from-start-offset))
- (level (mh-thread-current-indentation-level))
- spaces begin)
- (setq begin (point))
- (setq spaces (format (format "%%%ss" (1+ level)) ""))
- (forward-line)
- (cl-block nil
- (while (not (eobp))
- (forward-char address-start-offset)
- (unless (equal (string-match spaces (buffer-substring-no-properties
- (point) (line-end-position)))
- 0)
- (beginning-of-line)
- (backward-char)
- (cl-return))
- (forward-line)))
- (list begin (point)))))
-
-\f
-
-;;; Thread Creation
-
-(defun mh-thread-folder ()
- "Generate thread view of folder."
- (message "Threading %s..." (buffer-name))
- (mh-thread-initialize)
- (goto-char (point-min))
- (mh-remove-all-notation)
- (let ((msg-list ()))
- (mh-iterate-on-range msg (cons (point-min) (point-max))
- (setf (gethash msg mh-thread-scan-line-map) (mh-thread-parse-scan-line))
- (push msg msg-list))
- (let* ((range (mh-coalesce-msg-list msg-list))
- (thread-tree (mh-thread-generate (buffer-name) range)))
- (delete-region (point-min) (point-max))
- (mh-thread-print-scan-lines thread-tree)
- (mh-notate-user-sequences)
- (mh-notate-deleted-and-refiled)
- (mh-notate-cur)
- (message "Threading %s...done" (buffer-name)))))
-
-;;;###mh-autoload
-(defun mh-thread-inc (folder start-point)
- "Update thread tree for FOLDER.
-All messages after START-POINT are added to the thread tree."
- (mh-thread-rewind-pruning)
- (mh-remove-all-notation)
- (goto-char start-point)
- (let ((msg-list ()))
- (while (not (eobp))
- (let ((index (mh-get-msg-num nil)))
- (when (numberp index)
- (push index msg-list)
- (setf (gethash index mh-thread-scan-line-map)
- (mh-thread-parse-scan-line)))
- (forward-line)))
- (let ((thread-tree (mh-thread-generate folder msg-list))
- (buffer-read-only nil)
- (old-buffer-modified-flag (buffer-modified-p)))
- (delete-region (point-min) (point-max))
- (mh-thread-print-scan-lines thread-tree)
- (mh-notate-user-sequences)
- (mh-notate-deleted-and-refiled)
- (mh-notate-cur)
- (set-buffer-modified-p old-buffer-modified-flag))))
-
-(defmacro mh-thread-initialize-hash (var test)
- "Initialize the hash table in VAR.
-TEST is the test to use when creating a new hash table."
- (unless (symbolp var) (error "Expected a symbol: %s" var))
- `(if ,var (clrhash ,var) (setq ,var (make-hash-table :test ,test))))
-
-(defun mh-thread-initialize ()
- "Make new hash tables, or clear them if already present."
- (mh-thread-initialize-hash mh-thread-id-hash #'equal)
- (mh-thread-initialize-hash mh-thread-subject-hash #'equal)
- (mh-thread-initialize-hash mh-thread-id-table #'eq)
- (mh-thread-initialize-hash mh-thread-id-index-map #'eq)
- (mh-thread-initialize-hash mh-thread-index-id-map #'eql)
- (mh-thread-initialize-hash mh-thread-scan-line-map #'eql)
- (mh-thread-initialize-hash mh-thread-subject-container-hash #'eq)
- (mh-thread-initialize-hash mh-thread-duplicates #'eq)
- (setq mh-thread-history ()))
-
-(defsubst mh-thread-id-container (id)
- "Given ID, return the corresponding container in `mh-thread-id-table'.
-If no container exists then a suitable container is created and
-the id-table is updated."
- (when (not id)
- (error "1"))
- (or (gethash id mh-thread-id-table)
- (setf (gethash id mh-thread-id-table)
- (let ((message (mh-thread-make-message :id id)))
- (mh-thread-make-container :message message)))))
-
-(defsubst mh-thread-remove-parent-link (child)
- "Remove parent link of CHILD if it exists."
- (let* ((child-container (if (mh-thread-container-p child)
- child (mh-thread-id-container child)))
- (parent-container (mh-container-parent child-container)))
- (when parent-container
- (setf (mh-container-children parent-container)
- (cl-loop for elem in (mh-container-children parent-container)
- unless (eq child-container elem) collect elem))
- (setf (mh-container-parent child-container) nil))))
-
-(defsubst mh-thread-add-link (parent child &optional at-end-p)
- "Add links so that PARENT becomes a parent of CHILD.
-Doesn't make any changes if CHILD is already an ancestor of
-PARENT. If optional argument AT-END-P is non-nil, the CHILD is
-added to the end of the children list of PARENT."
- (let ((parent-container (cond ((null parent) nil)
- ((mh-thread-container-p parent) parent)
- (t (mh-thread-id-container parent))))
- (child-container (if (mh-thread-container-p child)
- child (mh-thread-id-container child))))
- (when (and parent-container
- (not (mh-thread-ancestor-p child-container parent-container))
- (not (mh-thread-ancestor-p parent-container child-container)))
- (mh-thread-remove-parent-link child-container)
- (cond ((not at-end-p)
- (push child-container (mh-container-children parent-container)))
- ((null (mh-container-children parent-container))
- (push child-container (mh-container-children parent-container)))
- (t (let ((last-child (mh-container-children parent-container)))
- (while (cdr last-child)
- (setq last-child (cdr last-child)))
- (setcdr last-child (cons child-container nil)))))
- (setf (mh-container-parent child-container) parent-container))
- (unless parent-container
- (mh-thread-remove-parent-link child-container))))
-
-(defun mh-thread-rewind-pruning ()
- "Restore the thread tree to its state before pruning."
- (while mh-thread-history
- (let ((action (pop mh-thread-history)))
- (cond ((eq (car action) 'DROP)
- (mh-thread-remove-parent-link (cadr action))
- (mh-thread-add-link (caddr action) (cadr action)))
- ((eq (car action) 'PROMOTE)
- (let ((node (cadr action))
- (parent (caddr action))
- (children (cdddr action)))
- (dolist (child children)
- (mh-thread-remove-parent-link child)
- (mh-thread-add-link node child))
- (mh-thread-add-link parent node)))
- ((eq (car action) 'SUBJECT)
- (let ((node (cadr action)))
- (mh-thread-remove-parent-link node)
- (setf (mh-container-real-child-p node) t)))))))
-
-(defun mh-thread-ancestor-p (ancestor successor)
- "Return t if ANCESTOR is really an ancestor of SUCCESSOR and nil otherwise.
-In the limit, the function returns t if ANCESTOR and SUCCESSOR
-are the same containers."
- (cl-block nil
- (while successor
- (when (eq ancestor successor) (cl-return t))
- (setq successor (mh-container-parent successor)))
- nil))
-
-;; Another and may be better approach would be to generate all the info from
-;; the scan which generates the threading info. For now this will have to do.
-;;;###mh-autoload
-(defun mh-thread-parse-scan-line (&optional string)
- "Parse a scan line.
-If optional argument STRING is given then that is assumed to be
-the scan line. Otherwise uses the line at point as the scan line
-to parse."
- (let* ((string (or string (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position))))
- (address-start (+ mh-cmd-note mh-scan-field-from-start-offset))
- (body-start (+ mh-cmd-note mh-scan-field-from-end-offset))
- (first-string (substring string 0 address-start)))
- (list first-string
- (substring string address-start (- body-start 2))
- (substring string body-start)
- string)))
-
-(defsubst mh-thread-canonicalize-id (id)
- "Produce canonical string representation for ID.
-This allows cheap string comparison with EQ."
- (or (and (equal id "") (copy-sequence ""))
- (gethash id mh-thread-id-hash)
- (setf (gethash id mh-thread-id-hash) id)))
-
-(defsubst mh-thread-prune-subject (subject)
- "Prune leading Re:'s, Fwd:'s etc. and trailing (fwd)'s from SUBJECT.
-If the result after pruning is not the empty string then it is
-canonicalized so that subjects can be tested for equality with
-eq. This is done so that all the messages without a subject are
-not put into a single thread."
- (let ((case-fold-search t)
- (subject-pruned-flag nil))
- ;; Prune subject leader
- (while (or (string-match "^[ \t]*\\(re\\|fwd?\\)\\(\\[[0-9]*\\]\\)?:[ \t]*"
- subject)
- (string-match "^[ \t]*\\[[^\\]][ \t]*" subject))
- (setq subject-pruned-flag t)
- (setq subject (substring subject (match-end 0))))
- ;; Prune subject trailer
- (while (or (string-match "(fwd)$" subject)
- (string-match "[ \t]+$" subject))
- (setq subject-pruned-flag t)
- (setq subject (substring subject 0 (match-beginning 0))))
- ;; Canonicalize subject only if it is non-empty
- (cond ((equal subject "") (list subject subject-pruned-flag))
- (t (list
- (or (gethash subject mh-thread-subject-hash)
- (setf (gethash subject mh-thread-subject-hash) subject))
- subject-pruned-flag)))))
-
-(defsubst mh-thread-group-by-subject (roots)
- "Group the set of message containers, ROOTS based on subject.
-Bug: Check for and make sure that something without Re: is made
-the parent in preference to something that has it."
- (clrhash mh-thread-subject-container-hash)
- (let ((results ()))
- (dolist (root roots)
- (let* ((subject (mh-thread-container-subject root))
- (parent (gethash subject mh-thread-subject-container-hash)))
- (cond (parent (mh-thread-remove-parent-link root)
- (mh-thread-add-link parent root t)
- (setf (mh-container-real-child-p root) nil)
- (push `(SUBJECT ,root) mh-thread-history))
- (t
- (setf (gethash subject mh-thread-subject-container-hash) root)
- (push root results)))))
- (nreverse results)))
-
-(defun mh-thread-container-subject (container)
- "Return the subject of CONTAINER.
-If CONTAINER is empty return the subject info of one of its
-children."
- (cond ((and (mh-container-message container)
- (mh-message-id (mh-container-message container)))
- (mh-message-subject (mh-container-message container)))
- (t (cl-block nil
- (dolist (kid (mh-container-children container))
- (when (and (mh-container-message kid)
- (mh-message-id (mh-container-message kid)))
- (let ((kid-message (mh-container-message kid)))
- (cl-return (mh-message-subject kid-message)))))
- (error "This can't happen")))))
-
-(defsubst mh-thread-update-id-index-maps (id index)
- "Message with id, ID is the message in INDEX.
-The function also checks for duplicate messages (that is multiple
-messages with the same ID). These messages are put in the
-`mh-thread-duplicates' hash table."
- (let ((old-index (gethash id mh-thread-id-index-map)))
- (when old-index (push old-index (gethash id mh-thread-duplicates)))
- (setf (gethash id mh-thread-id-index-map) index)
- (setf (gethash index mh-thread-index-id-map) id)))
-
-(defsubst mh-thread-get-message-container (message)
- "Return container which has MESSAGE in it.
-If there is no container present then a new container is
-allocated."
- (let* ((id (mh-message-id message))
- (container (gethash id mh-thread-id-table)))
- (cond (container (setf (mh-container-message container) message)
- container)
- (t (setf (gethash id mh-thread-id-table)
- (mh-thread-make-container :message message))))))
-
-(defsubst mh-thread-get-message (id subject-re-p subject refs)
- "Return appropriate message.
-Otherwise update message already present to have the proper ID,
-SUBJECT-RE-P, SUBJECT and REFS fields."
- (let* ((container (gethash id mh-thread-id-table))
- (message (if container (mh-container-message container) nil)))
- (cond (message
- (setf (mh-message-subject-re-p message) subject-re-p)
- (setf (mh-message-subject message) subject)
- (setf (mh-message-id message) id)
- (setf (mh-message-references message) refs)
- message)
- (container
- (setf (mh-container-message container)
- (mh-thread-make-message :id id :references refs
- :subject subject
- :subject-re-p subject-re-p)))
- (t (let ((message (mh-thread-make-message :id id :references refs
- :subject-re-p subject-re-p
- :subject subject)))
- (prog1 message
- (mh-thread-get-message-container message)))))))
-
-(defvar mh-message-id-regexp "^<.*@.*>$"
- "Regexp to recognize whether a string is a message identifier.")
-
-;;;###mh-autoload
-(defun mh-thread-generate (folder msg-list)
- "Scan FOLDER to get info for threading.
-Only information about messages in MSG-LIST are added to the tree."
- (with-temp-buffer
- (mh-thread-set-tables folder)
- (when msg-list
- (apply
- #'call-process (expand-file-name mh-scan-prog mh-progs) nil '(t nil) nil
- "-width" "10000" "-format"
- "%(msg)\n%{message-id}\n%{references}\n%{in-reply-to}\n%{subject}\n"
- folder (mapcar (lambda (x) (format "%s" x)) msg-list)))
- (goto-char (point-min))
- (let ((roots ())
- (case-fold-search t))
- (cl-block nil
- (while (not (eobp))
- (cl-block process-message
- (let* ((index-line
- (prog1 (buffer-substring (point) (line-end-position))
- (forward-line)))
- (index (string-to-number index-line))
- (id (prog1 (buffer-substring (point) (line-end-position))
- (forward-line)))
- (refs (prog1
- (buffer-substring (point) (line-end-position))
- (forward-line)))
- (in-reply-to (prog1 (buffer-substring (point)
- (line-end-position))
- (forward-line)))
- (subject (prog1
- (buffer-substring
- (point) (line-end-position))
- (forward-line)))
- (subject-re-p nil))
- (unless (gethash index mh-thread-scan-line-map)
- (cl-return-from process-message))
- (unless (integerp index) (cl-return)) ;Error message here
- (cl-multiple-value-setq (subject subject-re-p)
- (cl-values-list (mh-thread-prune-subject subject)))
- (setq in-reply-to (mh-thread-process-in-reply-to in-reply-to))
- (setq refs
- (cl-loop for x in (append (split-string refs) in-reply-to)
- when (string-match mh-message-id-regexp x)
- collect x))
- (setq id (mh-thread-canonicalize-id id))
- (mh-thread-update-id-index-maps id index)
- (setq refs (mapcar #'mh-thread-canonicalize-id refs))
- (mh-thread-get-message id subject-re-p subject refs)
- (cl-do ((ancestors refs (cdr ancestors)))
- ((null (cdr ancestors))
- (when (car ancestors)
- (mh-thread-remove-parent-link id)
- (mh-thread-add-link (car ancestors) id)))
- (mh-thread-add-link (car ancestors) (cadr ancestors)))))))
- (maphash (lambda (_k v)
- (when (null (mh-container-parent v))
- (push v roots)))
- mh-thread-id-table)
- (setq roots (mh-thread-prune-containers roots))
- (prog1 (setq roots (mh-thread-group-by-subject roots))
- (let ((history mh-thread-history))
- (set-buffer folder)
- (setq mh-thread-history history))))))
-
-(defun mh-thread-set-tables (folder)
- "Use the tables of FOLDER in current buffer."
- (dolist (v '(mh-thread-id-hash
- mh-thread-subject-hash
- mh-thread-id-table
- mh-thread-id-index-map
- mh-thread-index-id-map
- mh-thread-scan-line-map
- mh-thread-subject-container-hash
- mh-thread-duplicates
- mh-thread-history))
- ;; Emacs >= 22.1: (buffer-local-value v folder).
- (set v (with-current-buffer folder (symbol-value v)))))
-
-(defun mh-thread-process-in-reply-to (reply-to-header)
- "Extract message id's from REPLY-TO-HEADER.
-Ideally this should have some regexp which will try to guess if a
-string between < and > is a message id and not an email address.
-For now it will take the last string inside angles."
- (let ((end (mh-search-from-end ?> reply-to-header)))
- (when (numberp end)
- (let ((begin (mh-search-from-end ?< (substring reply-to-header 0 end))))
- (when (numberp begin)
- (list (substring reply-to-header begin (1+ end))))))))
-
-(defun mh-thread-prune-containers (roots)
- "Prune empty containers in the containers ROOTS."
- (let ((dfs-ordered-nodes ())
- (work-list roots))
- (while work-list
- (let ((node (pop work-list)))
- (dolist (child (mh-container-children node))
- (push child work-list))
- (push node dfs-ordered-nodes)))
- (while dfs-ordered-nodes
- (let ((node (pop dfs-ordered-nodes)))
- (cond ((gethash (mh-message-id (mh-container-message node))
- mh-thread-id-index-map)
- ;; Keep it
- (setf (mh-container-children node)
- (mh-thread-sort-containers (mh-container-children node))))
- ((and (mh-container-children node)
- (or (null (cdr (mh-container-children node)))
- (mh-container-parent node)))
- ;; Promote kids
- (let ((children ()))
- (dolist (kid (mh-container-children node))
- (mh-thread-remove-parent-link kid)
- (mh-thread-add-link (mh-container-parent node) kid)
- (push kid children))
- (push `(PROMOTE ,node ,(mh-container-parent node) ,@children)
- mh-thread-history)
- (mh-thread-remove-parent-link node)))
- ((mh-container-children node)
- ;; Promote the first orphan to parent and add the other kids as
- ;; his children
- (setf (mh-container-children node)
- (mh-thread-sort-containers (mh-container-children node)))
- (let ((new-parent (car (mh-container-children node)))
- (other-kids (cdr (mh-container-children node))))
- (mh-thread-remove-parent-link new-parent)
- (dolist (kid other-kids)
- (mh-thread-remove-parent-link kid)
- (setf (mh-container-real-child-p kid) nil)
- (mh-thread-add-link new-parent kid t))
- (push `(PROMOTE ,node ,(mh-container-parent node)
- ,new-parent ,@other-kids)
- mh-thread-history)
- (mh-thread-remove-parent-link node)))
- (t
- ;; Drop it
- (push `(DROP ,node ,(mh-container-parent node))
- mh-thread-history)
- (mh-thread-remove-parent-link node)))))
- (let ((results ()))
- (maphash (lambda (_k v)
- (when (and (null (mh-container-parent v))
- (gethash (mh-message-id (mh-container-message v))
- mh-thread-id-index-map))
- (push v results)))
- mh-thread-id-table)
- (mh-thread-sort-containers results))))
-
-(defun mh-thread-sort-containers (containers)
- "Sort a list of message CONTAINERS to be in ascending order wrt index."
- (sort containers
- (lambda (x y)
- (when (and (mh-container-message x) (mh-container-message y))
- (let* ((id-x (mh-message-id (mh-container-message x)))
- (id-y (mh-message-id (mh-container-message y)))
- (index-x (gethash id-x mh-thread-id-index-map))
- (index-y (gethash id-y mh-thread-id-index-map)))
- (and (integerp index-x) (integerp index-y)
- (< index-x index-y)))))))
-
-(defvar mh-thread-last-ancestor)
-
-;;;###mh-autoload
-(defun mh-thread-print-scan-lines (thread-tree)
- "Print scan lines in THREAD-TREE in threaded mode."
- (let ((mh-thread-body-width (- (window-width) mh-cmd-note
- (1- mh-scan-field-subject-start-offset)))
- (mh-thread-last-ancestor nil))
- (if (null mh-index-data)
- (mh-thread-generate-scan-lines thread-tree -2)
- (cl-loop for x in (mh-index-group-by-folder)
- do (let* ((old-map mh-thread-scan-line-map)
- (mh-thread-scan-line-map (make-hash-table)))
- (setq mh-thread-last-ancestor nil)
- (cl-loop for msg in (cdr x)
- do (let ((v (gethash msg old-map)))
- (when v
- (setf (gethash msg mh-thread-scan-line-map)
- v))))
- (when (> (hash-table-count mh-thread-scan-line-map) 0)
- (insert (if (bobp) "" "\n") (car x) "\n")
- (mh-thread-generate-scan-lines thread-tree -2))))
- (mh-index-create-imenu-index))))
-
-(defun mh-thread-generate-scan-lines (tree level)
- "Generate scan lines.
-TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps
-message indices to the corresponding scan lines and LEVEL used to
-determine indentation of the message."
- (cond ((null tree) nil)
- ((mh-thread-container-p tree)
- (let* ((message (mh-container-message tree))
- (id (mh-message-id message))
- (index (gethash id mh-thread-id-index-map))
- (duplicates (gethash id mh-thread-duplicates))
- (new-level (+ level 2))
- (dupl-flag t)
- (force-angle-flag nil)
- (increment-level-flag nil))
- (dolist (scan-line (mapcar (lambda (x)
- (gethash x mh-thread-scan-line-map))
- (reverse (cons index duplicates))))
- (when scan-line
- (when (and dupl-flag (equal level 0)
- (mh-thread-ancestor-p mh-thread-last-ancestor tree))
- (setq level (+ level 2)
- new-level (+ new-level 2)
- force-angle-flag t))
- (when (equal level 0)
- (setq mh-thread-last-ancestor tree)
- (while (mh-container-parent mh-thread-last-ancestor)
- (setq mh-thread-last-ancestor
- (mh-container-parent mh-thread-last-ancestor))))
- (let* ((lev (if dupl-flag level new-level))
- (square-flag (or (and (mh-container-real-child-p tree)
- (not force-angle-flag)
- dupl-flag)
- (equal lev 0))))
- (insert (car scan-line)
- (format (format "%%%ss" lev) "")
- (if square-flag "[" "<")
- (cadr scan-line)
- (if square-flag "]" ">")
- (truncate-string-to-width
- (caddr scan-line) (- mh-thread-body-width lev))
- "\n"))
- (setq increment-level-flag t)
- (setq dupl-flag nil)))
- (unless increment-level-flag (setq new-level level))
- (dolist (child (mh-container-children tree))
- (mh-thread-generate-scan-lines child new-level))))
- (t (let ((nlevel (+ level 2)))
- (dolist (ch tree)
- (mh-thread-generate-scan-lines ch nlevel))))))
-
-\f
-
-;;; Additional Utilities
-
-;;;###mh-autoload
-(defun mh-thread-update-scan-line-map (msg notation offset)
- "In threaded view update `mh-thread-scan-line-map'.
-MSG is the message being notated with NOTATION at OFFSET."
- (let* ((msg (or msg (mh-get-msg-num nil)))
- (cur-scan-line (and mh-thread-scan-line-map
- (gethash msg mh-thread-scan-line-map)))
- (old-scan-lines (cl-loop for map in mh-thread-scan-line-map-stack
- collect (and map (gethash msg map)))))
- (when cur-scan-line
- (setf (aref (car cur-scan-line) offset) notation))
- (dolist (line old-scan-lines)
- (when line (setf (aref (car line) offset) notation)))))
-
-;;;###mh-autoload
-(defun mh-thread-find-msg-subject (msg)
- "Find canonicalized subject of MSG.
-This function can only be used the folder is threaded."
- (ignore-errors
- (mh-message-subject
- (mh-container-message (gethash (gethash msg mh-thread-index-id-map)
- mh-thread-id-table)))))
-
-;;;###mh-autoload
-(defun mh-thread-add-spaces (count)
- "Add COUNT spaces to each scan line in `mh-thread-scan-line-map'."
- (let ((spaces (format (format "%%%ss" count) "")))
- (while (not (eobp))
- (let* ((msg-num (mh-get-msg-num nil))
- (old-line (nth 3 (gethash msg-num mh-thread-scan-line-map))))
- (when (numberp msg-num)
- (setf (gethash msg-num mh-thread-scan-line-map)
- (mh-thread-parse-scan-line (format "%s%s" spaces old-line)))))
- (forward-line 1))))
-
-;;;###mh-autoload
-(defun mh-thread-forget-message (index)
- "Forget the message INDEX from the threading tables."
- (let* ((id (gethash index mh-thread-index-id-map))
- (id-index (gethash id mh-thread-id-index-map))
- (duplicates (gethash id mh-thread-duplicates)))
- (remhash index mh-thread-index-id-map)
- (remhash index mh-thread-scan-line-map)
- (cond ((and (eql index id-index) (null duplicates))
- (remhash id mh-thread-id-index-map))
- ((eql index id-index)
- (setf (gethash id mh-thread-id-index-map) (car duplicates))
- (setf (gethash (car duplicates) mh-thread-index-id-map) id)
- (setf (gethash id mh-thread-duplicates) (cdr duplicates)))
- (t
- (setf (gethash id mh-thread-duplicates)
- (remove index duplicates))))))
-
-(provide 'mh-thread)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-thread.el ends here
+++ /dev/null
-;;; mh-tool-bar.el --- MH-E tool bar support -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2003, 2005-2024 Free Software Foundation, Inc.
-
-;; Author: Satyaki Das <satyaki@theforce.stanford.edu>
-;; Maintainer: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'mh-e)
-(require 'mh-acros)
-(require 'tool-bar)
-
-;;; Tool Bar Commands
-
-(defun mh-tool-bar-search (&optional _arg)
- "Interactively call `mh-tool-bar-search-function'.
-Optional argument ARG is not used."
- (interactive "P")
- (call-interactively mh-tool-bar-search-function))
-
-(defun mh-tool-bar-customize ()
- "Call `mh-customize' from the tool bar."
- (interactive)
- (mh-customize t))
-
-(defun mh-tool-bar-folder-help ()
- "Visit \"(mh-e)Top\"."
- (interactive)
- (info "(mh-e)Top")
- (delete-other-windows))
-
-(defun mh-tool-bar-letter-help ()
- "Visit \"(mh-e)Editing Drafts\"."
- (interactive)
- (info "(mh-e)Editing Drafts")
- (delete-other-windows))
-
-(defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag)
- "Generate FUNCTION that replies to RECIPIENT.
-If FOLDER-BUFFER-FLAG is nil then the function generated...
-When INCLUDE-FLAG is non-nil, include message body being replied to."
- `(defun ,function (&optional arg)
- ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply."
- recipient)
- (interactive "P")
- ,(if folder-buffer-flag nil '(set-buffer mh-show-folder-buffer))
- (mh-reply (mh-get-msg-num nil) ,recipient arg)))
-
-(mh-tool-bar-reply-generator mh-tool-bar-reply-from "from" t)
-(mh-tool-bar-reply-generator mh-show-tool-bar-reply-from "from" nil)
-(mh-tool-bar-reply-generator mh-tool-bar-reply-to "to" t)
-(mh-tool-bar-reply-generator mh-show-tool-bar-reply-to "to" nil)
-(mh-tool-bar-reply-generator mh-tool-bar-reply-all "all" t)
-(mh-tool-bar-reply-generator mh-show-tool-bar-reply-all "all" nil)
-
-\f
-
-;;; Tool Bar Creation
-
-(defmacro mh-tool-bar-define (defaults &rest buttons)
- "Define a tool bar for MH-E.
-DEFAULTS is the list of buttons that are present by default. It
-is a list of lists where the sublists are of the following form:
-
- (:KEYWORD FUNC1 FUNC2 FUNC3 ...)
-
-Here :KEYWORD is one of :folder or :letter. If it is :folder then
-the default buttons in the folder and show mode buffers are being
-specified. If it is :letter then the default buttons in the
-letter mode are listed. FUNC1, FUNC2, FUNC3, ... are the names of
-the functions that the buttons would execute.
-
-Each element of BUTTONS is a list consisting of four mandatory
-items and one optional item as follows:
-
- (FUNCTION MODES ICON DOC &optional ENABLE-EXPR)
-
-where,
-
- FUNCTION is the name of the function that will be executed when
- the button is clicked.
-
- MODES is a list of symbols. List elements must be from \"folder\",
- \"letter\" and \"sequence\". If \"folder\" is present then the button is
- available in the folder and show buffer. If the name of FUNCTION is
- of the form \"mh-foo\", where foo is some arbitrary string, then we
- check if the function `mh-show-foo' exists. If it exists then that
- function is used in the show buffer. Otherwise the original function
- `mh-foo' is used in the show buffer as well. Presence of \"sequence\"
- is handled similar to the above. The only difference is that the
- button is shown only when the folder is narrowed to a sequence. If
- \"letter\" is present in MODES, then the button is available during
- draft editing and runs FUNCTION when clicked.
-
- ICON is the icon that is drawn in the button.
-
- DOC is the documentation for the button. It is used in tool-tips and
- in providing other help to the user. GNU Emacs uses only the first
- line of the string. So the DOC should be formatted such that the
- first line is useful and complete without the rest of the string.
-
- Optional item ENABLE-EXPR is an arbitrary lisp expression. If it
- evaluates to nil, then the button is inactive, otherwise it is
- active. If it isn't present then the button is always active."
- ;; The following variable names have been carefully chosen to make code
- ;; generation easier. Modifying the names should be done carefully.
- (mh-dlet* (folder-buttons
- folder-docs folder-button-setter sequence-button-setter
- show-buttons show-button-setter show-seq-button-setter
- letter-buttons letter-docs letter-button-setter
- folder-defaults letter-defaults
- folder-vectors show-vectors letter-vectors)
- (dolist (x defaults)
- (cond ((eq (car x) :folder) (setq folder-defaults (cdr x)))
- ((eq (car x) :letter) (setq letter-defaults (cdr x)))))
- (dolist (button buttons)
- (unless (and (listp button)
- (or (equal (length button) 4) (equal (length button) 5)))
- (error "Incorrect MH-E tool-bar button specification: %s" button))
- (let* ((name (nth 0 button))
- (name-str (symbol-name name))
- (icon (nth 2 button))
- (full-doc (nth 3 button))
- (doc (if (string-match "\\(.*\\)\n" full-doc)
- (match-string 1 full-doc)
- full-doc))
- (enable-expr (if (eql (length button) 4) t (nth 4 button)))
- (modes (nth 1 button))
- functions show-sym)
- (when (memq 'letter modes) (setq functions `(:letter ,name)))
- (when (or (memq 'folder modes) (memq 'sequence modes))
- (setq functions
- (append `(,(if (memq 'folder modes) :folder :sequence) ,name)
- functions))
- (setq show-sym
- (if (string-match "\\`mh-\\(.*\\)\\'" name-str)
- (intern (concat "mh-show-" (match-string 1 name-str)))
- name))
- (setq functions
- (append `(,(if (memq 'folder modes) :show :show-seq)
- ,(if (fboundp show-sym) show-sym name))
- functions)))
- (cl-do ((functions functions (cddr functions)))
- ((null functions))
- (let* ((type (car functions))
- (function (cadr functions))
- (type1 (substring (symbol-name type) 1))
- (vector-list (cond ((eq type :show) 'show-vectors)
- ((eq type :show-seq) 'show-vectors)
- ((eq type :letter) 'letter-vectors)
- (t 'folder-vectors)))
- (list (cond ((eq type :letter) 'mh-tool-bar-letter-buttons)
- (t 'mh-tool-bar-folder-buttons)))
- (key (intern (concat "mh-" type1 "-tool-bar-" name-str)))
- (setter (intern (concat type1 "-button-setter")))
- (mbuttons (cond ((eq type :letter) 'letter-buttons)
- ((eq type :show) 'show-buttons)
- ((eq type :show-seq) 'show-buttons)
- (t 'folder-buttons)))
- (docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs)
- ((eq mbuttons 'folder-buttons) 'folder-docs))))
- (add-to-list vector-list `(vector nil ',function t ,full-doc))
- (add-to-list
- setter `(when (member ',name ,list)
- (tool-bar-add-item ,icon ',function ',key
- :help ,doc :enable ',enable-expr)))
- (add-to-list mbuttons name)
- (if docs (add-to-list docs doc))))))
- (setq folder-buttons (nreverse folder-buttons)
- letter-buttons (nreverse letter-buttons)
- show-buttons (nreverse show-buttons)
- letter-docs (nreverse letter-docs)
- folder-docs (nreverse folder-docs)
- folder-vectors (nreverse folder-vectors)
- show-vectors (nreverse show-vectors)
- letter-vectors (nreverse letter-vectors))
- (dolist (x folder-defaults)
- (unless (memq x folder-buttons)
- (error "Folder defaults contains unknown button %s" x)))
- (dolist (x letter-defaults)
- (unless (memq x letter-buttons)
- (error "Letter defaults contains unknown button %s" x)))
- `(eval-and-compile
- (defun mh-buffer-exists-p (mode)
- "Test whether a buffer with major mode MODE is present."
- (cl-loop for buf in (buffer-list)
- when (with-current-buffer buf
- (eq major-mode mode))
- return t))
- ;; Tool bar initialization functions
- (defun mh-tool-bar-folder-buttons-init ()
- (when (mh-buffer-exists-p 'mh-folder-mode)
- (mh--with-image-load-path
- (setq mh-folder-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap)))
- ,@(nreverse folder-button-setter)
- tool-bar-map))
- (setq mh-folder-seq-tool-bar-map
- (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map)))
- ,@(nreverse sequence-button-setter)
- tool-bar-map))
- (setq mh-show-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap)))
- ,@(nreverse show-button-setter)
- tool-bar-map))
- (setq mh-show-seq-tool-bar-map
- (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map)))
- ,@(nreverse show-seq-button-setter)
- tool-bar-map)))))
- (defun mh-tool-bar-letter-buttons-init ()
- (when (mh-buffer-exists-p 'mh-letter-mode)
- (mh--with-image-load-path
- (setq mh-letter-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap)))
- ,@(nreverse letter-button-setter)
- tool-bar-map)))))
- ;; Custom setter functions
- (defun mh-tool-bar-update (mode default-map sequence-map)
- "Update `tool-bar-map' in all buffers of MODE.
-Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise."
- (cl-loop for buf in (buffer-list)
- do (with-current-buffer buf
- (when (eq mode major-mode) ;FIXME: derived-mode-p?
- (let ((map (if mh-folder-view-stack
- sequence-map
- default-map)))
- ;; Yes, make-local-variable is necessary since we
- ;; get here during initialization when loading
- ;; mh-e.el, after the +inbox buffer has been
- ;; created, but before mh-folder-mode has run and
- ;; created the local map.
- (setq-local tool-bar-map map))))))
- (defun mh-tool-bar-folder-buttons-set (symbol value)
- "Construct tool bar for `mh-folder-mode' and `mh-show-mode'."
- (set-default symbol value)
- (mh-tool-bar-folder-buttons-init)
- (mh-tool-bar-update 'mh-folder-mode mh-folder-tool-bar-map
- mh-folder-seq-tool-bar-map)
- (mh-tool-bar-update 'mh-show-mode mh-show-tool-bar-map
- mh-show-seq-tool-bar-map))
- (defun mh-tool-bar-letter-buttons-set (symbol value)
- "Construct tool bar for `mh-letter-mode'."
- (set-default symbol value)
- (mh-tool-bar-letter-buttons-init)
- (mh-tool-bar-update 'mh-letter-mode mh-letter-tool-bar-map
- mh-letter-tool-bar-map))
- ;; Declare customizable tool bars
- (custom-declare-variable
- 'mh-tool-bar-folder-buttons
- '(list ,@(mapcar (lambda (x) `(quote ,x)) folder-defaults))
- "List of buttons to include in MH-Folder tool bar."
- :group 'mh-tool-bar
- :set #'mh-tool-bar-folder-buttons-set
- :type '(set ,@(cl-loop for x in folder-buttons
- for y in folder-docs
- collect `(const :tag ,y ,x)))
- ;;:package-version '(MH-E "7.1")
- )
- (custom-declare-variable
- 'mh-tool-bar-letter-buttons
- '(list ,@(mapcar (lambda (x) `(quote ,x)) letter-defaults))
- "List of buttons to include in MH-Letter tool bar."
- :group 'mh-tool-bar
- :set #'mh-tool-bar-letter-buttons-set
- :type '(set ,@(cl-loop for x in letter-buttons
- for y in letter-docs
- collect `(const :tag ,y ,x)))
- ;;:package-version '(MH-E "7.1")
- ))))
-
-(mh-tool-bar-define
- ((:folder mh-inc-folder mh-mime-save-parts
- mh-previous-undeleted-msg mh-page-msg
- mh-next-undeleted-msg mh-delete-msg mh-refile-msg
- mh-undo mh-execute-commands mh-toggle-tick mh-reply
- mh-alias-grab-from-field mh-send mh-rescan-folder
- mh-tool-bar-search mh-visit-folder
- mh-tool-bar-customize mh-tool-bar-folder-help
- mh-widen)
- (:letter mh-send-letter save-buffer mh-fully-kill-draft
- mh-compose-insertion ispell-message undo
- clipboard-kill-region clipboard-kill-ring-save
- clipboard-yank mh-tool-bar-customize
- mh-tool-bar-letter-help))
- ;; Folder/Show buffer buttons
- (mh-inc-folder (folder) "mail/inbox" "Incorporate new mail in Inbox
-This button runs `mh-inc-folder' which drags any
-new mail into your Inbox folder")
- (mh-mime-save-parts (folder) "attach" "Save MIME parts from this message
-This button runs `mh-mime-save-parts' which saves a message's
-different parts into separate files")
- (mh-previous-undeleted-msg (folder) "left-arrow"
- "Go to the previous undeleted message
-This button runs `mh-previous-undeleted-msg'")
- (mh-page-msg (folder) "next-page" "Page the current message forwards
-This button runs `mh-page-msg'")
- (mh-next-undeleted-msg (folder) "right-arrow" "Go to the next undeleted message
-The button runs `mh-next-undeleted-msg'")
- (mh-delete-msg (folder) "delete" "Mark this message for deletion
-This button runs `mh-delete-msg'")
- (mh-refile-msg (folder) "mail/move" "Refile this message
-This button runs `mh-refile-msg'")
- (mh-undo (folder) "undo" "Undo last operation
-This button runs `undo'"
- (mh-outstanding-commands-p))
- (mh-execute-commands (folder) "data-save" "Perform moves and deletes
-This button runs `mh-execute-commands'"
- (mh-outstanding-commands-p))
- (mh-toggle-tick (folder) "mail/flag-for-followup" "Toggle tick mark
-This button runs `mh-toggle-tick'")
- (mh-toggle-showing (folder) "show" "Toggle showing message
-This button runs `mh-toggle-showing'")
- (mh-reply (folder) "mail/reply" "Reply to this message
-This button runs `mh-reply'")
- (mh-tool-bar-reply-from (folder) "mail/reply-from" "Reply to \"from\"")
- (mh-tool-bar-reply-to (folder) "mail/reply-to" "Reply to \"to\"")
- (mh-tool-bar-reply-all (folder) "mail/reply-all" "Reply to \"all\"")
- (mh-alias-grab-from-field (folder) "contact" "Create alias for sender
-This button runs `mh-alias-grab-from-field'"
- (and (mh-extract-from-header-value)
- (not (mh-alias-for-from-p))))
- (mh-send (folder) "mail/compose" "Compose new message
-This button runs `mh-send'")
- (mh-rescan-folder (folder) "refresh" "Rescan this folder
-This button runs `mh-rescan-folder'")
- (mh-pack-folder (folder) "mail/repack" "Repack this folder
-This button runs `mh-pack-folder'")
- (mh-tool-bar-search (folder) "search" "Search
-This button runs `mh-tool-bar-search-function'")
- (mh-visit-folder (folder) "open" "Visit other folder
-This button runs `mh-visit-folder'")
- ;; Letter buffer buttons
- (mh-send-letter (letter) "mail/send" "Send this letter")
- (save-buffer (letter) "save" "Save current buffer to its file"
- (buffer-modified-p))
- (mh-fully-kill-draft (letter) "delete" "Kill this draft")
- (mh-compose-insertion (letter) "attach" "Insert attachment")
- (ispell-message (letter) "spell" "Check spelling")
- (undo (letter) "undo" "Undo last operation")
- (clipboard-kill-region (letter) "cut"
- "Cut (kill) text in region")
- (clipboard-kill-ring-save (letter) "copy"
- "Copy text in region")
- (clipboard-yank (letter) "paste"
- "Paste (yank) text cut or copied earlier")
- ;; Common buttons
- (mh-tool-bar-customize (folder letter) "preferences" "MH-E Preferences")
- (mh-tool-bar-folder-help (folder) "help" "Help! (general help)
-This button runs `info'")
- (mh-tool-bar-letter-help (letter) "help" "Help! (general help)
-This button runs `info'")
- ;; Folder narrowed to sequence buttons
- (mh-widen (sequence) "zoom-out" "Widen from the sequence
-This button runs `mh-widen'"))
-
-(provide 'mh-tool-bar)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-tool-bar.el ends here
+++ /dev/null
-;;; mh-utils.el --- MH-E general utilities -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993, 1995, 1997, 2000-2024 Free Software Foundation,
-;; Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'mh-e)
-
-(require 'font-lock)
-(require 'mailabbrev)
-
-;;; CL Replacements
-
-;;;###mh-autoload
-(defun mh-search-from-end (char string)
- "Return the position of last occurrence of CHAR in STRING.
-If CHAR is not present in STRING then return nil. The function is
-used in lieu of `search' in the CL package."
- (cl-loop for index from (1- (length string)) downto 0
- when (equal (aref string index) char) return index
- finally return nil))
-
-\f
-
-;;; General Utilities
-
-;;;###mh-autoload
-(defun mh-beginning-of-word (&optional n)
- "Return position of the N th word backwards."
- (unless n (setq n 1))
- (let ((syntax-table (syntax-table)))
- (unwind-protect
- (save-excursion
- (mail-abbrev-make-syntax-table)
- (set-syntax-table mail-abbrev-syntax-table)
- (backward-word n)
- (point))
- (set-syntax-table syntax-table))))
-
-;;;###mh-autoload
-(defun mh-colors-in-use-p ()
- "Check if colors are being used in the folder buffer."
- (and mh-colors-available-flag font-lock-mode))
-
-;;;###mh-autoload
-(defun mh-delete-line (lines)
- "Delete the next LINES lines."
- (delete-region (point) (progn (forward-line lines) (point))))
-
-;;;###mh-autoload
-(defun mh-make-local-vars (&rest pairs)
- "Initialize local variables according to the variable-value PAIRS."
- (declare (obsolete setq-local "29.1"))
- (while pairs
- (set (make-local-variable (car pairs)) (car (cdr pairs)))
- (setq pairs (cdr (cdr pairs)))))
-
-;;;###mh-autoload
-(define-obsolete-function-alias 'mh-mapc #'mapc "29.1")
-
-(defvar mh-pick-regexp-chars ".*$["
- "List of special characters in pick regular expressions.")
-
-;;;###mh-autoload
-(defun mh-quote-pick-expr (pick-expr)
- "Quote `mh-pick-regexp-chars' in PICK-EXPR.
-PICK-EXPR is a list of strings. Return nil if PICK-EXPR is nil."
- (let ((quoted-pick-expr))
- (dolist (string pick-expr)
- (when (and string
- (not (string-equal string "")))
- (cl-loop for i from 0 to (1- (length mh-pick-regexp-chars)) do
- (let ((s (string ?\\ (aref mh-pick-regexp-chars i))))
- (setq string (replace-regexp-in-string s s string t t))))
- (setq quoted-pick-expr (append quoted-pick-expr (list string)))))
- quoted-pick-expr))
-
-;;;###mh-autoload
-(defun mh-replace-string (old new)
- "Replace all occurrences of OLD with NEW in the current buffer.
-Ignores case when searching for OLD."
- (goto-char (point-min))
- (let ((case-fold-search t))
- (while (search-forward old nil t)
- (replace-match new t t))))
-
-\f
-
-;;; Logo Display
-
-;;;###mh-autoload
-(defmacro mh--with-image-load-path (&rest body)
- "Load `image' and eval BODY with `image-load-path' set appropriately."
- (declare (debug t) (indent 0))
- `(progn
- ;; Not preloaded in without-x builds.
- (require 'image)
- (defvar image-load-path)
- (declare-function image-load-path-for-library "image")
- (let* ((load-path (image-load-path-for-library "mh-e" "mh-logo.xpm"))
- (image-load-path (cons (car load-path) image-load-path)))
- ,@body)))
-
-(defvar mh-logo-cache nil)
-
-;;;###mh-autoload
-(defun mh-logo-display ()
- "Modify mode line to display MH-E logo."
- (mh--with-image-load-path
- (add-text-properties
- 0 2
- `(display ,(or mh-logo-cache
- (setq mh-logo-cache
- (find-image '(( :type xpm :ascent center
- :file "mh-logo.xpm" ))))))
- (car mode-line-buffer-identification))))
-
-\f
-
-;;; Read MH Profile
-
-(defvar mh-find-path-run nil
- "Non-nil if `mh-find-path' has been run already.
-Do not access this variable; `mh-find-path' already uses it to
-avoid running more than once.")
-
-;;;###mh-autoload
-(defun mh-find-path ()
- "Set variables from user's MH profile.
-
-This function sets `mh-user-path' from your \"Path:\" MH profile
-component (but defaults to \"Mail\" if one isn't present),
-`mh-draft-folder' from \"Draft-Folder:\", `mh-unseen-seq' from
-\"Unseen-Sequence:\", `mh-previous-seq' from
-\"Previous-Sequence:\", and `mh-inbox' from \"Inbox:\" (defaults
-to \"+inbox\").
-
-The hook `mh-find-path-hook' is run after these variables have
-been set. This hook can be used the change the value of these
-variables if you need to run with different values between MH and
-MH-E."
- (unless mh-find-path-run
- (or mh-variant-in-use (mh-variant-set mh-variant))
- ;; Sanity checks.
- (if (and (getenv "MH")
- (not (file-readable-p (getenv "MH"))))
- (error "MH environment variable contains unreadable file %s"
- (getenv "MH")))
- (if (null (mh-variants))
- (error "Install MH and run install-mh before running MH-E"))
- (if (not (or (getenv "MH") (file-readable-p "~/.mh_profile")))
- (error "Run install-mh before running MH-E"))
- ;; Read MH profile.
- (setq mh-user-path (mh-profile-component "Path"))
- (if (not mh-user-path)
- (setq mh-user-path "Mail"))
- (setq mh-user-path
- (file-name-as-directory
- (expand-file-name mh-user-path (expand-file-name "~"))))
- (mh-set-x-image-cache-directory (expand-file-name ".mhe-x-image-cache"
- mh-user-path))
- (setq mh-draft-folder (mh-profile-component "Draft-Folder"))
- (if mh-draft-folder
- (progn
- (if (not (mh-folder-name-p mh-draft-folder))
- (setq mh-draft-folder (format "+%s" mh-draft-folder)))
- (if (not (file-exists-p (mh-expand-file-name mh-draft-folder)))
- (error
- "Draft folder \"%s\" not found; create it and try again"
- (mh-expand-file-name mh-draft-folder)))))
- (setq mh-inbox (mh-profile-component "Inbox"))
- (cond ((not mh-inbox)
- (setq mh-inbox "+inbox"))
- ((not (mh-folder-name-p mh-inbox))
- (setq mh-inbox (format "+%s" mh-inbox))))
- (setq mh-unseen-seq (mh-profile-component "Unseen-Sequence"))
- (if mh-unseen-seq
- (setq mh-unseen-seq (intern mh-unseen-seq))
- (setq mh-unseen-seq 'unseen)) ;old MH default?
- (setq mh-previous-seq (mh-profile-component "Previous-Sequence"))
- (if mh-previous-seq
- (setq mh-previous-seq (intern mh-previous-seq)))
- (run-hooks 'mh-find-path-hook)
- (mh-collect-folder-names)
- (setq mh-find-path-run t)))
-
-\f
-
-;;; Help Functions
-
-;;;###mh-autoload
-(defun mh-ephem-message (string)
- "Display STRING in the minibuffer momentarily."
- (message "%s" string)
- (sit-for 5)
- (message ""))
-
-(defvar mh-help-default nil
- "Mode to use if messages are not present for the current mode.")
-
-(defvar mh-help-messages nil
- "Help messages for all modes.
-This is an alist of alists. The primary key is a symbol
-representing the mode; the value is described in `mh-set-help'.")
-
-;;;###mh-autoload
-(defun mh-set-help (messages &optional default)
- "Set help messages.
-
-The MESSAGES are assumed to be an associative array. It is used
-to show help for the most common commands in the current mode.
-The key is a prefix char. The value is one or more strings which
-are concatenated together and displayed in a help buffer if ? is
-pressed after the prefix character. The special key nil is used
-to display the non-prefixed commands.
-
-The substitutions described in `substitute-command-keys' are performed as
-well.
-
-If optional argument DEFAULT is non-nil, then these messages will
-be used if help is asked for an unknown mode."
- (add-to-list 'mh-help-messages (cons major-mode messages))
- (if default
- (setq mh-help-default major-mode)))
-
-;;;###mh-autoload
-(defun mh-help (&optional help-messages)
- "Display cheat sheet for the MH-E commands.
-See `mh-set-help' for setting the help messages.
-HELP-MESSAGES are used instead if given.
-This is a list of one or more strings which are concatenated together
-and displayed in a help buffer."
- (interactive)
- (let* ((help (or help-messages
- (cdr (assoc nil (assoc major-mode mh-help-messages)))))
- (text (substitute-command-keys (mapconcat #'identity help ""))))
- (with-electric-help
- (lambda ()
- (insert text))
- mh-help-buffer)))
-
-;;;###mh-autoload
-(defun mh-prefix-help ()
- "Display cheat sheet for the commands of the current prefix in minibuffer."
- (interactive)
- ;; We got here because the user pressed a "?", but he pressed a prefix key
- ;; before that. Since the key vector starts at index 0, the index of the
- ;; last keystroke is length-1 and thus the second to last keystroke is at
- ;; length-2. We use that information to obtain a suitable prefix character
- ;; from the recent keys.
- (let* ((keys (recent-keys))
- (prefix-char (elt keys (- (length keys) 2)))
- (help (cdr (assoc prefix-char (assoc major-mode mh-help-messages)))))
- (mh-help help)))
-
-\f
-
-;;; Message Number Utilities
-
-;;;###mh-autoload
-(defun mh-coalesce-msg-list (messages)
- "Given a list of MESSAGES, return a list of message number ranges.
-This is the inverse of `mh-read-msg-list', which expands ranges.
-Message lists passed to MH programs should be processed by this
-function to avoid exceeding system command line argument limits."
- (let ((msgs (sort (copy-sequence messages) #'mh-greaterp))
- (range-high nil)
- (prev -1)
- (ranges nil))
- (while prev
- (if range-high
- (if (or (not (numberp prev))
- (not (equal (car msgs) (1- prev))))
- (progn ;non-sequential, flush old range
- (if (eq prev range-high)
- (setq ranges (cons range-high ranges))
- (setq ranges (cons (format "%s-%s" prev range-high) ranges)))
- (setq range-high nil))))
- (or range-high
- (setq range-high (car msgs))) ;start new or first range
- (setq prev (car msgs))
- (setq msgs (cdr msgs)))
- ranges))
-
-(defun mh-greaterp (msg1 msg2)
- "Return the greater of two message indicators MSG1 and MSG2.
-Strings are \"smaller\" than numbers.
-Valid values are things like \"cur\", \"last\", 1, and 1820."
- (if (numberp msg1)
- (if (numberp msg2)
- (> msg1 msg2)
- t)
- (if (numberp msg2)
- nil
- (string-lessp msg2 msg1))))
-
-;;;###mh-autoload
-(defun mh-lessp (msg1 msg2)
- "Return the lesser of two message indicators MSG1 and MSG2.
-Strings are \"smaller\" than numbers.
-Valid values are things like \"cur\", \"last\", 1, and 1820."
- (not (mh-greaterp msg1 msg2)))
-
-;;;###mh-autoload
-(defun mh-get-msg-num (error-if-no-message)
- "Return the message number of the displayed message.
-If the argument ERROR-IF-NO-MESSAGE is non-nil, then complain if
-the cursor is not pointing to a message."
- (save-excursion
- (beginning-of-line)
- (cond ((looking-at (mh-scan-msg-number-regexp))
- (string-to-number (buffer-substring (match-beginning 1)
- (match-end 1))))
- (error-if-no-message
- (user-error "Cursor not pointing to message"))
- (t nil))))
-
-\f
-
-;;; Folder Cache and Access
-
-(defvar mh-sub-folders-cache (make-hash-table :test #'equal))
-(defvar mh-current-folder-name nil)
-(defvar mh-flists-partial-line "")
-(defvar mh-flists-process nil)
-
-;;;###mh-autoload
-(defun mh-clear-sub-folders-cache ()
- "Clear `mh-sub-folders-cache'."
- (clrhash mh-sub-folders-cache))
-
-;; Initialize mh-sub-folders-cache...
-(defun mh-collect-folder-names ()
- "Collect folder names by running \"folders\"."
- (unless mh-flists-process
- (setq mh-flists-process
- (mh-exec-cmd-daemon "folders" 'mh-collect-folder-names-filter
- "-recurse" "-fast"))))
-
-(defun mh-collect-folder-names-filter (_process output)
- "Read folder names.
-PROCESS is the flists process that was run to collect folder
-names and the function is called when OUTPUT is available."
- (let ((position 0)
- (prevailing-match-data (match-data))
- line-end folder)
- (unwind-protect
- (while (setq line-end (string-search "\n" output position))
- (setq folder (format "+%s%s"
- mh-flists-partial-line
- (substring output position line-end)))
- (setq mh-flists-partial-line "")
- (unless (equal (aref folder 1) ?.)
- (mh-populate-sub-folders-cache folder))
- (setq position (1+ line-end)))
- (set-match-data prevailing-match-data))
- (setq mh-flists-partial-line (substring output position))))
-
-(defun mh-populate-sub-folders-cache (folder)
- "Tell `mh-sub-folders-cache' about FOLDER."
- (let* ((last-slash (mh-search-from-end ?/ folder))
- (child1 (substring folder (1+ (or last-slash 0))))
- (parent (and last-slash (substring folder 0 last-slash)))
- (parent-slash (and parent (mh-search-from-end ?/ parent)))
- (child2 (and parent (substring parent (1+ (or parent-slash 0)))))
- (grand-parent (and parent-slash (substring parent 0 parent-slash)))
- (cache-entry (gethash parent mh-sub-folders-cache)))
- (unless (cl-loop for x in cache-entry when (equal (car x) child1) return t
- finally return nil)
- (push (list child1) cache-entry)
- (setf (gethash parent mh-sub-folders-cache)
- (sort cache-entry (lambda (x y) (string< (car x) (car y)))))
- (when parent
- (cl-loop for x in (gethash grand-parent mh-sub-folders-cache)
- when (equal (car x) child2)
- do (progn (setf (cdr x) t) (cl-return)))))))
-
-(defun mh-normalize-folder-name (folder &optional empty-string-okay
- dont-remove-trailing-slash
- return-nil-if-folder-empty)
- "Normalizes FOLDER name.
-
-Makes sure that two `/' characters never occur next to each
-other. Also all occurrences of `..' and `.' are suitably
-processed. So \"+inbox/../news\" will be normalized to \"+news\".
-
-If optional argument EMPTY-STRING-OKAY is nil then a `+' is added
-at the front if FOLDER lacks one. If non-nil and FOLDER is the
-empty string then nothing is added.
-
-If optional argument DONT-REMOVE-TRAILING-SLASH is non-nil then a
-trailing `/' if present is retained (if present), otherwise it is
-removed.
-
-If optional argument RETURN-NIL-IF-FOLDER-EMPTY is non-nil, then
-return nil if FOLDER is \"\" or \"+\". This is useful when
-normalizing the folder for the `folders' command which displays
-the directories in / if passed \"+\". This is usually not
-desired. If this argument is non-nil, then EMPTY-STRING-OKAY has
-no effect."
- (cond
- ((if (and (or (equal folder "+") (equal folder ""))
- return-nil-if-folder-empty)
- (setq folder nil)))
- ((stringp folder)
- ;; Replace two or more consecutive '/' characters with a single '/'
- (while (string-match "//" folder)
- (setq folder (replace-match "/" nil t folder)))
- (let* ((length (length folder))
- (trailing-slash-present (and (> length 0)
- (equal (aref folder (1- length)) ?/)))
- (leading-slash-present (and (> length 0)
- (equal (aref folder 0) ?/))))
- (when (and (> length 0) (equal (aref folder 0) ?@)
- (stringp mh-current-folder-name))
- (setq folder (format "%s/%s/" mh-current-folder-name
- (substring folder 1))))
- ;; XXX: Purge empty strings from the list that split-string
- ;; returns. In the code it is assumed that the components list
- ;; has no empty strings.
- (let ((components (delete "" (split-string folder "/")))
- (result ()))
- ;; Remove .. and . from the pathname.
- (dolist (component components)
- (cond ((and (equal component "..") result)
- (pop result))
- ((equal component ".."))
- ((equal component "."))
- (t (push component result))))
- (setq folder "")
- (dolist (component result)
- (setq folder (concat component "/" folder)))
- ;; Remove trailing '/' if needed.
- (unless (and trailing-slash-present dont-remove-trailing-slash)
- (when (not (equal folder ""))
- (setq folder (substring folder 0 (1- (length folder))))))
- (when leading-slash-present
- (setq folder (concat "/" folder)))))
- (cond ((and empty-string-okay (equal folder "")))
- ((equal folder "")
- (setq folder "+"))
- ((not (equal (aref folder 0) ?+))
- (setq folder (concat "+" folder))))))
- folder)
-
-(defmacro mh-children-p (folder)
- "Return t if FOLDER from sub-folders cache has children."
-;; The car of folder is the name, and the cdr is either t or some
-;; sort of count that I do not understand. It's too small to be the
-;; number of messages in the sub-folders and too large to be the
-;; number of sub-folders. XXX
- `(if (cdr ,folder)
- t
- nil))
-
-;;;###mh-autoload
-(defun mh-folder-list (folder)
- "Return FOLDER and its descendants.
-FOLDER may have a + prefix. Returns a list of strings without the
-+ prefix. If FOLDER is nil, then all folders are considered. For
-example, if your Mail directory only contains the folders +inbox,
-+outbox, +lists, and +lists/mh-e, then
-
- (mh-folder-list nil)
- => (\"inbox\" \"lists\" \"lists/mh-e\" \"outbox\")
- (mh-folder-list \"+lists\")
- => (\"lists\" \"lists/mh-e\")
-
-Respects the value of `mh-recursive-folders-flag'. If this flag
-is nil, and the sub-folders have not been explicitly viewed, then
-they will not be returned."
- (let ((folder-list))
- ;; Normalize folder. Strip leading + and trailing slash(es). If no
- ;; folder is specified, ensure it is nil to avoid adding the
- ;; folder to the folder-list and adding a slash to it.
- (when folder
- (setq folder (replace-regexp-in-string "^\\+" "" folder))
- (setq folder (replace-regexp-in-string "/+$" "" folder))
- (if (equal folder "")
- (setq folder nil)))
- ;; Add provided folder to list, unless all folders are asked for.
- ;; Then append slash to separate sub-folders.
- (unless (null folder)
- (setq folder-list (list folder))
- (setq folder (concat folder "/")))
- (cl-loop for f in (mh-sub-folders folder) do
- (setq folder-list
- (append folder-list
- (if (mh-children-p f)
- (mh-folder-list (concat folder (car f)))
- (list (concat folder (car f)))))))
- folder-list))
-
-;;;###mh-autoload
-(defun mh-sub-folders (folder &optional add-trailing-slash-flag)
- "Find the subfolders of FOLDER.
-The function avoids running folders unnecessarily by caching the
-results of the actual folders call.
-
-If optional argument ADD-TRAILING-SLASH-FLAG is non-nil then a
-slash is added to each of the sub-folder names that may have
-nested folders within them."
- ;; In most cases we want to remove a trailing slash. We keep the
- ;; slash for "+/", because it refers to folders in the system root
- ;; directory, whereas "+" refers to the user's top-level folders.
- (let* ((folder (mh-normalize-folder-name folder nil
- (string= folder "+/")
- t))
- (match (gethash folder mh-sub-folders-cache 'no-result))
- (sub-folders (cond ((eq match 'no-result)
- (setf (gethash folder mh-sub-folders-cache)
- (mh-sub-folders-actual folder)))
- (t match))))
- (if add-trailing-slash-flag
- (mapcar (lambda (x)
- (if (cdr x) (cons (concat (car x) "/") (cdr x)) x))
- sub-folders)
- sub-folders)))
-
-;; FIXME: This function does not do well if FOLDER does not exist. It
-;; then changes the context to that folder which causes problems down
-;; the line. Since a folder in the cache could later be deleted, it
-;; would be good for mh-sub-folders-actual to return nil in this case
-;; so that mh-sub-folders could delete it from the cache. This
-;; function could protect itself by using a temporary context.
-(defun mh-sub-folders-actual (folder)
- "Execute the command folders to return the sub-folders of FOLDER.
-Filters out the folder names that start with \".\" so that
-directories that aren't usually mail folders are hidden.
-Expects FOLDER to have already been normalized with
- (mh-normalize-folder-name folder nil nil t)"
- (let ((arg-list `(,(expand-file-name "folders" mh-progs)
- nil (t nil) nil "-noheader" "-norecurse" "-nototal"
- ,@(if (stringp folder) (list folder) ())))
- (current-folder (concat
- (with-temp-buffer
- (call-process (expand-file-name "folder" mh-progs)
- nil '(t nil) nil "-fast")
- (buffer-substring (point-min) (1- (point-max))))
- "+")))
- (with-temp-buffer
- (apply #'call-process arg-list)
- (mh-sub-folders-parse folder current-folder))))
-
-(defun mh-sub-folders-parse (folder current-folder)
- "Parse the results of \"folders FOLDER\" and return a list of sub-folders.
-CURRENT-FOLDER is the result of \"folder -fast\".
-FOLDER will be nil or start with '+'; CURRENT-FOLDER will end with '+'.
-This function is a testable helper of `mh-sub-folders-actual'."
- (let ((results ()))
- (goto-char (point-min))
- (while (not (and (eolp) (bolp)))
- (goto-char (line-end-position))
- (let ((start-pos (line-beginning-position))
- (has-pos (search-backward " has "
- (line-beginning-position) t)))
- (when (integerp has-pos)
- (while (equal (char-after has-pos) ? )
- (cl-decf has-pos))
- (cl-incf has-pos)
- (while (equal (char-after start-pos) ? )
- (cl-incf start-pos))
- (let* ((name (buffer-substring start-pos has-pos))
- (first-char (aref name 0))
- (second-char (and (length> name 1) (aref name 1)))
- (last-char (aref name (1- (length name)))))
- (unless (member first-char '(?. ?# ?,))
- (when (and (equal last-char ?+) (equal name current-folder))
- (setq name (substring name 0 (1- (length name)))))
- ;; nmh outputs double slash in root folder, e.g., "//tmp"
- (when (and (equal first-char ?/) (equal second-char ?/))
- (setq name (substring name 1)))
- (push
- (cons name
- (search-forward "(others)" (line-end-position) t))
- results))))
- (forward-line 1)))
- (setq results (nreverse results))
- (when (stringp folder)
- (setq results (cdr results))
- (let ((folder-name-len (length (format "%s/" (substring folder 1)))))
- (when (equal "+/" folder)
- ;; folder "+/" includes a trailing slash
- (cl-decf folder-name-len))
- (setq results (mapcar (lambda (f)
- (cons (substring (car f) folder-name-len)
- (cdr f)))
- results))))
- results))
-
-;;;###mh-autoload
-(defun mh-remove-from-sub-folders-cache (folder)
- "Remove FOLDER and its parent from `mh-sub-folders-cache'.
-FOLDER should be unconditionally removed from the cache. Also the
-last ancestor of FOLDER present in the cache must be removed as
-well.
-
-To see why this is needed assume we have a folder +foo which has
-a single sub-folder qux. Now we create the folder +foo/bar/baz.
-Here we will need to invalidate the cached sub-folders of +foo,
-otherwise completion on +foo won't tell us about the option
-+foo/bar!"
- (remhash folder mh-sub-folders-cache)
- (cl-block ancestor-found
- (let ((parent folder)
- (one-ancestor-found nil)
- last-slash)
- (while (setq last-slash (mh-search-from-end ?/ parent))
- (setq parent (substring parent 0 last-slash))
- (unless (eq (gethash parent mh-sub-folders-cache 'none) 'none)
- (remhash parent mh-sub-folders-cache)
- (if one-ancestor-found
- (cl-return-from ancestor-found)
- (setq one-ancestor-found t))))
- (remhash nil mh-sub-folders-cache))))
-
-\f
-
-;;; Folder Utilities
-
-;;;###mh-autoload
-(defun mh-folder-name-p (name)
- "Return non-nil if NAME is the name of a folder.
-A name (a string or symbol) can be a folder name if it begins
-with \"+\"."
- (if (symbolp name)
- (eq (aref (symbol-name name) 0) ?+)
- (and (> (length name) 0)
- (eq (aref name 0) ?+))))
-
-;;;###mh-autoload
-(defun mh-expand-file-name (filename &optional default)
- "Expand FILENAME like `expand-file-name', but also handle MH folder names.
-Any filename that starts with `+' is treated as a folder name.
-See `expand-file-name' for description of DEFAULT."
- (if (mh-folder-name-p filename)
- (expand-file-name (substring filename 1) mh-user-path)
- (expand-file-name filename default)))
-
-(defvar mh-folder-hist nil)
-
-;; Shush compiler.
-(defvar mh-speed-flists-cache)
-
-(defvar mh-allow-root-folder-flag nil
- "Non-nil means \"+\" is an acceptable folder name.
-This variable is used to communicate with
-`mh-folder-completion-function'. That function can have exactly
-three arguments so we bind this variable to t or nil.
-
-This variable should never be set.")
-
-(defvar mh-folder-completion-map (copy-keymap minibuffer-local-completion-map))
-(define-key mh-folder-completion-map " " #'minibuffer-complete) ;Why???
-
-(defvar mh-speed-flists-inhibit-flag nil)
-
-;;;###mh-autoload
-(defun mh-speed-flists-active-p ()
- "Check if speedbar is running with message counts enabled."
- (and (featurep 'mh-speed)
- (not mh-speed-flists-inhibit-flag)
- (> (hash-table-count mh-speed-flists-cache) 0)))
-
-;;;###mh-autoload
-(defun mh-folder-completion-function (name predicate flag)
- "Programmable completion for folder names.
-NAME is the partial folder name that has been input. PREDICATE if
-non-nil is a function that is used to filter the possible
-choices. FLAG is nil to indicate `try-completion', t for
-`all-completions', or the symbol lambda for `test-completion'.
-See Info node `(elisp) Programmed Completion' for details."
- (let* ((orig-name name)
- ;; After normalization, name is nil, +, or +something. If a
- ;; trailing slash is present, it is preserved.
- (name (mh-normalize-folder-name name nil t))
- (last-slash (mh-search-from-end ?/ name))
- ;; nil if + or +folder; +folder/ if slash present.
- (last-complete (if last-slash (substring name 0 (1+ last-slash)) nil))
- ;; Either +folder/remainder, +remainder, or "".
- (remainder (cond (last-complete (substring name (1+ last-slash)))
- (name (substring name 1))
- (t ""))))
- (cond ((eq (car-safe flag) 'boundaries)
- (cl-list* 'boundaries
- (let ((slash (mh-search-from-end ?/ orig-name)))
- (if slash (1+ slash)
- (if (string-match "\\`\\+" orig-name) 1 0)))
- (if (cdr flag) (string-search "/" (cdr flag)))))
- ((eq flag nil)
- (let ((try-res
- (try-completion
- remainder
- (mh-sub-folders last-complete t)
- predicate)))
- (cond ((eq try-res nil) nil)
- ((and (eq try-res t) (equal name orig-name)) t)
- ((eq try-res t) name)
- (t (concat (or last-complete "+") try-res)))))
- ((eq flag t)
- (all-completions
- remainder (mh-sub-folders last-complete t) predicate))
- ((eq flag 'lambda)
- ;; FIXME: if name starts with "/", `path' will end
- ;; being a relative name without a leading + nor / !? --Stef
- (let ((path (concat (unless (and (> (length name) 1)
- (eq (aref name 1) ?/))
- mh-user-path)
- (substring name 1))))
- (cond (mh-allow-root-folder-flag (file-directory-p path))
- ((equal path mh-user-path) nil)
- (t (file-directory-p path))))))))
-
-(defun mh-folder-completing-read (prompt default allow-root-folder-flag)
- "Read folder name with PROMPT and default result DEFAULT.
-If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be
-a folder name corresponding to `mh-user-path'."
- (mh-normalize-folder-name
- (let ((minibuffer-local-completion-map mh-folder-completion-map)
- (mh-allow-root-folder-flag allow-root-folder-flag))
- (completing-read prompt 'mh-folder-completion-function nil nil nil
- 'mh-folder-hist default))
- t))
-
-;;;###mh-autoload
-(defun mh-prompt-for-folder (prompt default can-create
- &optional default-string allow-root-folder-flag)
- "Prompt for a folder name with PROMPT.
-Returns the folder's name as a string. DEFAULT is used if the
-folder exists and the user types return. If the CAN-CREATE flag
-is t, then a folder is created if it doesn't already exist. If
-optional argument DEFAULT-STRING is non-nil, use it in the prompt
-instead of DEFAULT. If ALLOW-ROOT-FOLDER-FLAG is non-nil then the
-function will accept the folder +, which means all folders when
-used in searching."
- (if (null default)
- (setq default ""))
- (let* ((default-string (or default-string
- (if (equal default "") nil default)))
- (prompt (format-prompt "%s folder" default-string prompt))
- (mh-current-folder-name mh-current-folder)
- read-name folder-name)
- (while (and (setq read-name (mh-folder-completing-read
- prompt default allow-root-folder-flag))
- (equal read-name "")
- (equal default "")))
- (cond ((or (equal read-name "")
- (and (equal read-name "+") (not allow-root-folder-flag)))
- (setq read-name default))
- ((not (mh-folder-name-p read-name))
- (setq read-name (format "+%s" read-name))))
- (if (or (not read-name) (equal "" read-name))
- (error "No folder specified"))
- (setq folder-name read-name)
- (cond ((and (> (length folder-name) 0)
- (eq (aref folder-name (1- (length folder-name))) ?/))
- (setq folder-name (substring folder-name 0 -1))))
- (let* ((last-slash (mh-search-from-end ?/ folder-name))
- (parent (and last-slash (substring folder-name 0 last-slash)))
- (child (if last-slash
- (substring folder-name (1+ last-slash))
- (substring folder-name 1))))
- (unless (member child
- (mapcar #'car (gethash parent mh-sub-folders-cache)))
- (mh-remove-from-sub-folders-cache folder-name)))
- (let ((new-file-flag
- (not (file-exists-p (mh-expand-file-name folder-name)))))
- (cond ((and new-file-flag
- can-create
- (y-or-n-p
- (format "Folder %s does not exist. Create it? "
- folder-name)))
- (message "Creating %s" folder-name)
- (mh-exec-cmd-error nil "folder" folder-name)
- (mh-remove-from-sub-folders-cache folder-name)
- (when (and (boundp 'speedbar-buffer) speedbar-buffer)
- (mh-speed-add-folder folder-name))
- (message "Creating %s...done" folder-name))
- (new-file-flag
- (error "Folder %s does not exist" folder-name))
- ((not (file-directory-p (mh-expand-file-name folder-name)))
- (error "%s is not a directory"
- (mh-expand-file-name folder-name)))))
- folder-name))
-
-\f
-
-;;; Message Utilities
-
-;; Functions that would ordinarily be in mh-letter.el that are needed
-;; by mh-show.el are found here in order to prevent the loading of
-;; mh-letter.el until a message is actually composed.
-
-;;;###mh-autoload
-(defun mh-in-header-p ()
- "Return non-nil if the point is in the header of a draft message."
- (< (point) (mh-mail-header-end)))
-
-;;;###mh-autoload
-(defun mh-extract-from-header-value ()
- "Extract From: string from header."
- (save-excursion
- (if (not (mh-goto-header-field "From:"))
- nil
- (skip-chars-forward " \t")
- (buffer-substring-no-properties
- (point) (progn (mh-header-field-end)(point))))))
-
-;;;###mh-autoload
-(defun mh-get-header-field (field)
- "Find and return the body of FIELD in the mail header.
-Returns the empty string if the field is not in the header of the
-current buffer."
- (if (mh-goto-header-field field)
- (progn
- (skip-chars-forward " \t") ;strip leading white space in body
- (let ((start (point)))
- (mh-header-field-end)
- (buffer-substring-no-properties start (point))))
- ""))
-
-;;;###mh-autoload
-(defun mh-goto-header-field (field)
- "Move to FIELD in the message header.
-Move to the end of the FIELD name, which should end in a colon.
-Returns t if found, nil if not."
- (goto-char (point-min))
- (let ((case-fold-search t)
- (headers-end (save-excursion
- (mh-goto-header-end 0)
- (point))))
- (re-search-forward (format "^%s" field) headers-end t)))
-
-;;;###mh-autoload
-(defun mh-goto-header-end (arg)
- "Move the cursor ARG lines after the header."
- (if (re-search-forward (concat "^\\(" (regexp-quote mh-mail-header-separator)
- "\\)?$") nil nil)
- (forward-line arg)))
-
-;;;###mh-autoload
-(defun mh-mail-header-end ()
- "Substitute for `mail-header-end' that doesn't widen the buffer.
-
-In MH-E we frequently need to find the end of headers in nested
-messages, where the buffer has been narrowed. This function works
-in this situation."
- (save-excursion
- ;; XXX: The following replaces a call to rfc822-goto-eoh. Occasionally,
- ;; mail headers that MH-E has to read contains lines of the form:
- ;; From xxx@yyy Mon May 10 11:48:07 2004
- ;; In this situation, rfc822-goto-eoh doesn't go to the end of the
- ;; header. The replacement allows From_ lines in the mail header.
- (goto-char (point-min))
- (cl-loop for p = (re-search-forward
- "^\\([:\n]\\|[^: \t\n]+[ \t\n]\\)" nil 'move)
- do (cond ((null p) (cl-return))
- (t (goto-char (match-beginning 0))
- (unless (looking-at "From ") (cl-return))
- (goto-char p))))
- (point)))
-
-;;;###mh-autoload
-(defun mh-header-field-beginning ()
- "Move to the beginning of the current header field.
-Handle RFC 822 (or later) continuation lines."
- (beginning-of-line)
- (while (looking-at "^[ \t]")
- (forward-line -1)))
-
-;;;###mh-autoload
-(defun mh-header-field-end ()
- "Move to the end of the current header field.
-Handle RFC 822 (or later) continuation lines."
- (forward-line 1)
- (while (looking-at "^[ \t]")
- (forward-line 1))
- (backward-char 1)) ;to end of previous line
-
-;;;###mh-autoload
-(defun mh-letter-hide-all-skipped-fields ()
- "Hide all skipped fields."
- (save-excursion
- (goto-char (point-min))
- (save-restriction
- (narrow-to-region (point) (mh-mail-header-end))
- (while (re-search-forward mh-letter-header-field-regexp nil t)
- (if (mh-letter-skipped-header-field-p (match-string 1))
- (mh-letter-toggle-header-field-display -1)
- (mh-letter-toggle-header-field-display 'long))
- (beginning-of-line 2)))))
-
-;;;###mh-autoload
-(defun mh-letter-skipped-header-field-p (field)
- "Check if FIELD is to be skipped."
- (let ((field (downcase field)))
- (cl-loop for x in mh-compose-skipped-header-fields
- when (equal (downcase x) field) return t
- finally return nil)))
-
-(defvar mh-hidden-header-keymap
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] #'mh-letter-toggle-header-field-display-button)
- map))
-
-;;;###mh-autoload
-(defun mh-letter-toggle-header-field-display (arg)
- "Toggle display of header field at point.
-
-Use this command to display truncated header fields. This command
-is a toggle so entering it again will hide the field. This
-command takes a prefix argument ARG: if negative then the field
-is hidden, if positive then the field is displayed."
- (interactive (list nil))
- (when (and (mh-in-header-p)
- (progn
- (end-of-line)
- (re-search-backward mh-letter-header-field-regexp nil t)))
- (let ((buffer-read-only nil)
- (modified-flag (buffer-modified-p))
- (begin (point))
- end)
- (end-of-line)
- (setq end (1- (if (re-search-forward "^[^ \t]" nil t)
- (match-beginning 0)
- (point-max))))
- (goto-char begin)
- ;; Make it clickable...
- (add-text-properties begin end `(keymap ,mh-hidden-header-keymap
- mouse-face highlight))
- (unwind-protect
- (cond ((or (and (not arg)
- (text-property-any begin end 'invisible 'vanish))
- (and (numberp arg)
- (>= arg 0))
- (and (eq arg 'long)
- (> (line-beginning-position 5) end)))
- (remove-text-properties begin end '(invisible nil))
- (search-forward ":" (line-end-position) t)
- (mh-letter-skip-leading-whitespace-in-header-field))
- ;; XXX Redesign to make usable by user. Perhaps use a positive
- ;; numeric prefix to make that many lines visible.
- ((eq arg 'long)
- (end-of-line 4)
- (mh-letter-truncate-header-field end)
- (beginning-of-line))
- (t (end-of-line)
- (mh-letter-truncate-header-field end)
- (beginning-of-line)))
- (set-buffer-modified-p modified-flag)))))
-
-;;;###mh-autoload
-(defun mh-letter-skip-leading-whitespace-in-header-field ()
- "Skip leading whitespace in a header field.
-If the header field doesn't have at least one space after the
-colon then a space character is added."
- (let ((need-space t))
- (while (memq (char-after) '(?\t ?\ ))
- (forward-char)
- (setq need-space nil))
- (when need-space (insert " "))))
-
-(defun mh-letter-truncate-header-field (end)
- "Replace text from current line till END with an ellipsis.
-If the current line is too long truncate a part of it as well."
- (let ((max-len (min (window-width) 62)))
- (when (> (+ (current-column) 4) max-len)
- (backward-char (- (+ (current-column) 5) max-len)))
- (when (> end (point))
- (add-text-properties (point) end '(invisible vanish)))))
-
-;;;###mh-autoload
-(defun mh-signature-separator-p ()
- "Return non-nil if buffer includes \"^-- $\"."
- (save-excursion
- (goto-char (point-min))
- (re-search-forward mh-signature-separator-regexp nil t)))
-
-;;;###mh-autoload
-(define-obsolete-function-alias 'mh-colors-available-p #'display-color-p "29.1")
-
-(provide 'mh-utils)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-utils.el ends here
+++ /dev/null
-;;; mh-xface.el --- MH-E X-Face and Face header field display -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2003, 2005-2024 Free Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'mh-e)
-
-(autoload 'mail-header-parse-address "mail-parse")
-(autoload 'message-fetch-field "message")
-
-(defvar mh-show-xface-function #'mh-face-display-function
- "Determine at run time what function should be called to display X-Face.")
-(make-obsolete-variable 'mh-show-xface-function nil "29.1")
-
-(defvar mh-uncompface-executable (executable-find "uncompface"))
-
-\f
-
-;;; X-Face Display
-
-;;;###mh-autoload
-(defun mh-show-xface ()
- "Display X-Face."
- (when (and window-system mh-show-use-xface-flag
- (or mh-decode-mime-flag mh-mhl-format-file
- mh-clean-message-header-flag))
- (mh-face-display-function)))
-
-(defun mh-face-display-function ()
- "Display a Face, X-Face, or X-Image-URL header field.
-If more than one of these are present, then the first one found
-in this order is used."
- (save-restriction
- (goto-char (point-min))
- (re-search-forward "\n\n" (point-max) t)
- (narrow-to-region (point-min) (point))
- (let* ((case-fold-search t)
- (face (message-fetch-field "face" t))
- (x-face (message-fetch-field "x-face" t))
- (url (message-fetch-field "x-image-url" t))
- raw type)
- (cond (face (setq raw (mh-face-to-png face)
- type 'png))
- (x-face (setq raw (mh-uncompface x-face)
- type 'pbm))
- (url (setq type 'url))
- (t (cl-multiple-value-setq (type raw)
- (cl-values-list (mh-picon-get-image)))))
- (when type
- (goto-char (point-min))
- (when (re-search-forward "^from:" (point-max) t)
- (if (eq type 'url)
- (mh-x-image-url-display url)
- (insert-image (create-image
- raw type t
- :foreground
- (face-foreground 'mh-show-xface nil t)
- :background
- (face-background 'mh-show-xface nil t))
- " ")))))))
-
-(defun mh-face-to-png (data)
- "Convert base64 encoded DATA to png image."
- (with-temp-buffer
- (set-buffer-multibyte nil)
- (insert data)
- (ignore-errors (base64-decode-region (point-min) (point-max)))
- (buffer-string)))
-
-(defun mh-uncompface (data)
- "Run DATA through `uncompface' to generate bitmap."
- (with-temp-buffer
- (set-buffer-multibyte nil)
- (insert data)
- (when (and mh-uncompface-executable
- (equal (call-process-region (point-min) (point-max)
- mh-uncompface-executable t '(t nil))
- 0))
- (mh-icontopbm)
- (buffer-string))))
-
-(defun mh-icontopbm ()
- "Elisp substitute for `icontopbm'."
- (goto-char (point-min))
- (let ((end (point-max)))
- (while (re-search-forward "0x\\(..\\)\\(..\\)," nil t)
- (save-excursion
- (goto-char (point-max))
- (insert (string-to-number (match-string 1) 16))
- (insert (string-to-number (match-string 2) 16))))
- (delete-region (point-min) end)
- (goto-char (point-min))
- (insert "P4\n48 48\n")))
-
-\f
-
-;;; Picon Display
-
-;; XXX: This should be customizable. As a side-effect of setting this
-;; variable, arrange to reset mh-picon-existing-directory-list to 'unset.
-(defvar mh-picon-directory-list
- '("~/.picons" "~/.picons/users" "~/.picons/usenix" "~/.picons/news"
- "~/.picons/domains" "~/.picons/misc"
- "/usr/share/picons/" "/usr/share/picons/users" "/usr/share/picons/usenix"
- "/usr/share/picons/news" "/usr/share/picons/domains"
- "/usr/share/picons/misc")
- "List of directories where picons reside.
-The directories are searched for in the order they appear in the list.")
-
-(defvar mh-picon-existing-directory-list 'unset
- "List of directories to search in.")
-
-(defvar mh-picon-cache (make-hash-table :test #'equal))
-
-(defvar mh-picon-image-types
- (cl-loop for type in '(xpm xbm gif)
- when (ignore-errors
- (image-type-available-p type))
- collect type))
-
-(autoload 'message-tokenize-header "sendmail")
-
-(defun mh-picon-get-image ()
- "Find the best possible match and return contents."
- (mh-picon-set-directory-list)
- (save-restriction
- (let* ((from-field (ignore-errors (car (message-tokenize-header
- (mh-get-header-field "from:")))))
- (from (car (ignore-errors
- (mail-header-parse-address from-field))))
- (host (and from
- (string-match "\\([^+]*\\)\\(\\+.*\\)?@\\(.*\\)" from)
- (downcase (match-string 3 from))))
- (user (and host (downcase (match-string 1 from))))
- (canonical-address (format "%s@%s" user host))
- (cached-value (gethash canonical-address mh-picon-cache))
- (host-list (and host (delete "" (split-string host "\\.")))))
- (cond
- (cached-value cached-value)
- ((not host-list) nil)
- (t
- (let ((match
- (cl-block loop
- ;; u@h search
- (dolist (dir mh-picon-existing-directory-list)
- (cl-loop for type in mh-picon-image-types
- ;; [path]user@host
- for file1 = (format "%s/%s.%s"
- dir canonical-address type)
- when (file-exists-p file1)
- do (cl-return-from loop file1)
- ;; [path]user
- for file2 = (format "%s/%s.%s" dir user type)
- when (file-exists-p file2)
- do (cl-return-from loop file2)
- ;; [path]host
- for file3 = (format "%s/%s.%s" dir host type)
- when (file-exists-p file3)
- do (cl-return-from loop file3)))
- ;; facedb search
- ;; Search order for user@foo.net:
- ;; [path]net/foo/user
- ;; [path]net/foo/user/face
- ;; [path]net/user
- ;; [path]net/user/face
- ;; [path]net/foo/unknown
- ;; [path]net/foo/unknown/face
- ;; [path]net/unknown
- ;; [path]net/unknown/face
- (dolist (u (list user "unknown"))
- (dolist (dir mh-picon-existing-directory-list)
- (cl-loop for x on host-list by #'cdr
- for y = (mh-picon-generate-path x u dir)
- do (cl-loop for type in mh-picon-image-types
- for z1 = (format "%s.%s" y type)
- when (file-exists-p z1)
- do (cl-return-from loop z1)
- for z2 = (format "%s/face.%s"
- y type)
- when (file-exists-p z2)
- do (cl-return-from loop z2))))))))
- (setf (gethash canonical-address mh-picon-cache)
- (mh-picon-file-contents match))))))))
-
-(defun mh-picon-set-directory-list ()
- "Update `mh-picon-existing-directory-list' if needed."
- (when (eq mh-picon-existing-directory-list 'unset)
- (setq mh-picon-existing-directory-list
- (cl-loop for x in mh-picon-directory-list
- when (file-directory-p x) collect x))))
-
-(defun mh-picon-generate-path (host-list user directory)
- "Generate the image file path.
-HOST-LIST is the parsed host address of the email address, USER
-the username and DIRECTORY is the directory relative to which the
-path is generated."
- (cl-loop with acc = ""
- for elem in host-list
- do (setq acc (format "%s/%s" elem acc))
- finally return (format "%s/%s%s" directory acc user)))
-
-(defun mh-picon-file-contents (file)
- "Return details about FILE.
-A list of consisting of a symbol for the type of the file and the
-file contents as a string is returned. If FILE is nil, then both
-elements of the list are nil."
- (if (stringp file)
- (with-temp-buffer
- (set-buffer-multibyte nil)
- (let ((type (and (string-match ".*\\.\\(...\\)$" file)
- (intern (match-string 1 file)))))
- (insert-file-contents-literally file)
- (list type (buffer-string))))
- (list nil nil)))
-
-\f
-
-;;; X-Image-URL Display
-
-(defvar mh-x-image-scaling-function
- (cond ((executable-find "convert")
- 'mh-x-image-scale-with-convert)
- ((and (executable-find "anytopnm") (executable-find "pnmscale")
- (executable-find "pnmtopng"))
- 'mh-x-image-scale-with-pnm)
- (t 'ignore))
- "Function to use to scale image to proper size.")
-
-(defun mh-x-image-scale-with-pnm (input output)
- "Scale image in INPUT file and write to OUTPUT file using pnm tools."
- (let ((res (shell-command-to-string
- (format "anytopnm < %s | pnmscale -xysize 96 48 | pnmtopng > %s"
- input output))))
- (unless (equal res "")
- (delete-file output))))
-
-(defun mh-x-image-scale-with-convert (input output)
- "Scale image in INPUT file and write to OUTPUT file using ImageMagick."
- (call-process "convert" nil nil nil "-geometry" "96x48" input output))
-
-(defvar mh-wget-executable nil)
-(defvar mh-wget-choice
- (or (and (setq mh-wget-executable (executable-find "wget")) 'wget)
- (and (setq mh-wget-executable (executable-find "fetch")) 'fetch)
- (and (setq mh-wget-executable (executable-find "curl")) 'curl)))
-(defvar mh-wget-option
- (cdr (assoc mh-wget-choice '((curl . "-o") (fetch . "-o") (wget . "-O")))))
-(defvar mh-x-image-temp-file nil)
-(defvar mh-x-image-url nil)
-(defvar mh-x-image-marker nil)
-(defvar mh-x-image-url-cache-file nil)
-
-(defun mh-x-image-url-display (url)
- "Display image from location URL.
-If the URL isn't present in the cache then it is fetched with wget."
- (let* ((cache-filename (mh-x-image-url-cache-canonicalize url))
- (state (mh-x-image-get-download-state cache-filename))
- (marker (point-marker)))
- (setq-local mh-x-image-marker marker)
- (cond ((not (mh-x-image-url-sane-p url)))
- ((eq state 'ok)
- (mh-x-image-display cache-filename marker))
- ((or (not mh-wget-executable)
- (eq mh-x-image-scaling-function 'ignore)))
- ((eq state 'never))
- ((not mh-fetch-x-image-url)
- (set-marker marker nil))
- ((eq state 'try-again)
- (mh-x-image-set-download-state cache-filename nil)
- (mh-x-image-url-fetch-image url cache-filename marker
- 'mh-x-image-scale-and-display))
- ((and (eq mh-fetch-x-image-url 'ask)
- (not (y-or-n-p (format "Fetch %s? " url))))
- (mh-x-image-set-download-state cache-filename 'never))
- ((eq state nil)
- (mh-x-image-url-fetch-image url cache-filename marker
- 'mh-x-image-scale-and-display)))))
-
-(defvar mh-x-image-cache-directory nil
- "Directory where X-Image-URL images are cached.")
-
-;;;###mh-autoload
-(defun mh-set-x-image-cache-directory (directory)
- "Set the DIRECTORY where X-Image-URL images are cached.
-This is only done if `mh-x-image-cache-directory' is nil."
- ;; XXX This is the code that used to be in find-user-path. Is there
- ;; a good reason why the variable is set conditionally? Do we expect
- ;; the user to have set this variable directly?
- (unless mh-x-image-cache-directory
- (setq mh-x-image-cache-directory directory)))
-
-(defun mh-x-image-url-cache-canonicalize (url)
- "Canonicalize URL.
-Replace the ?/ character with a ?! character and append .png.
-Also replaces special characters with `url-hexify-string'
-since not all characters, such as :, are valid within Windows
-filenames. In addition, replaces * with %2a. See URL
-`https://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/iitemnamelimits/GetValidCharacters.asp'."
- (format "%s/%s.png" mh-x-image-cache-directory
- (replace-regexp-in-string
- "\\*" "%2a"
- (url-hexify-string
- (with-temp-buffer
- (insert url)
- (mh-replace-string "/" "!")
- (buffer-string))))))
-
-(defun mh-x-image-get-download-state (file)
- "Check the state of FILE by following any symbolic links."
- (unless (file-exists-p mh-x-image-cache-directory)
- (call-process "mkdir" nil nil nil mh-x-image-cache-directory))
- (cond ((file-symlink-p file)
- (intern (file-name-nondirectory (file-chase-links file))))
- ((not (file-exists-p file)) nil)
- (t 'ok)))
-
-(defun mh-x-image-set-download-state (file data)
- "Setup a symbolic link from FILE to DATA."
- (if data
- (make-symbolic-link (symbol-name data) file t)
- (delete-file file)))
-
-(defun mh-x-image-url-sane-p (url)
- "Check if URL is something sensible."
- (let ((len (length url)))
- (cond ((> len 100) nil)
- ((and (>= len 5)
- (equal (substring url 0 5) "http:") t))
- ((and (>= len 6)
- (equal (substring url 0 6) "https:") t))
- (t nil))))
-
-(defun mh-x-image-display (image marker)
- "Display IMAGE at MARKER."
- (with-current-buffer (marker-buffer marker)
- (let ((inhibit-read-only t)
- (buffer-modified-flag (buffer-modified-p)))
- (unwind-protect
- (when (and (file-readable-p image) (not (file-symlink-p image))
- (eq marker mh-x-image-marker))
- (goto-char marker)
- (insert-image (create-image image 'png)))
- (set-buffer-modified-p buffer-modified-flag)))))
-
-(defun mh-x-image-url-fetch-image (url cache-file marker sentinel)
- "Fetch and display the image specified by URL.
-After the image is fetched, it is stored in CACHE-FILE. It will
-be displayed in a buffer and position specified by MARKER. The
-actual display is carried out by the SENTINEL function."
- (if mh-wget-executable
- (let ((buffer (generate-new-buffer mh-temp-fetch-buffer))
- (filename (make-temp-file "mhe-fetch")))
- (with-current-buffer buffer
- (setq-local mh-x-image-url-cache-file cache-file)
- (setq-local mh-x-image-marker marker)
- (setq-local mh-x-image-temp-file filename))
- (set-process-sentinel
- (start-process "*mh-x-image-url-fetch*" buffer
- mh-wget-executable mh-wget-option filename url)
- sentinel))
- ;; Temporary failure
- (mh-x-image-set-download-state cache-file 'try-again)))
-
-(defun mh-x-image-scale-and-display (process _change)
- "When the wget PROCESS terminates scale and display image.
-The argument CHANGE is ignored."
- (when (eq (process-status process) 'exit)
- (let (marker temp-file cache-filename wget-buffer)
- (with-current-buffer (setq wget-buffer (process-buffer process))
- (setq marker mh-x-image-marker
- cache-filename mh-x-image-url-cache-file
- temp-file mh-x-image-temp-file))
- (cond
- ;; Check if we have `convert'
- ((eq mh-x-image-scaling-function 'ignore)
- (message "The \"convert\" program is needed to display X-Image-URL")
- (mh-x-image-set-download-state cache-filename 'try-again))
- ;; Scale fetched image
- ((and (funcall mh-x-image-scaling-function temp-file cache-filename)
- nil))
- ;; Attempt to display image if we have it
- ((file-exists-p cache-filename)
- (mh-x-image-display cache-filename marker))
- ;; We didn't find the image. Should we try to display it the next time?
- (t (mh-x-image-set-download-state cache-filename 'try-again)))
- (ignore-errors
- (set-marker marker nil)
- (delete-process process)
- (kill-buffer wget-buffer)
- (delete-file temp-file)))))
-
-(provide 'mh-xface)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-xface.el ends here
(predicate-description (sort-function . identity))
(search (sort-function . identity))
(keybinding (sort-function . minibuffer-sort-alphabetically))
- (function (sort-function . minibuffer-sort-alphabetically)
+ (function (styles partial-completion substring)
+ (sort-function . minibuffer-sort-alphabetically)
(affixation-function . minibuffer-function-affixation))
(library (sort-function . minibuffer-sort-alphabetically)))
"Default settings for specific completion categories.
"WWW (%d)")
((or (memq major-mode
'(rmail-mode rmail-edit-mode vm-summary-mode vm-mode mail-mode))
- (memq major-mode '(mh-letter-mode mh-show-mode mh-folder-mode))
(memq major-mode
'(gnus-summary-mode message-mode gnus-group-mode
gnus-article-mode score-mode gnus-browse-killed-mode)))
"WWW (%d)")
((or (memq major-mode
'(rmail-mode rmail-edit-mode vm-summary-mode vm-mode mail-mode))
- (memq major-mode '(mh-letter-mode mh-show-mode mh-folder-mode))
(memq major-mode '(gnus-summary-mode message-mode gnus-group-mode
gnus-article-mode score-mode
gnus-browse-killed-mode)))
+++ /dev/null
-;;; mh-compat.el --- make MH-E compatible with various versions of Emacs -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2006-2024 Free Software Foundation, Inc.
-
-;; Author: Bill Wohler <wohler@newt.com>
-;; Keywords: mail
-;; See: mh-e.el
-;; Obsolete-since: 29.1
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-;; This is a good place to gather code that is used for compatibility
-;; between different versions of Emacs. Please document which versions
-;; of Emacs that the defsubst, defalias, or defmacro applies. That
-;; way, it's easy to occasionally go through this file and see which
-;; macros we can retire.
-
-;; Please use mh-gnus.el when providing compatibility with different
-;; versions of Gnus.
-
-;; Items are listed alphabetically.
-
-(eval-when-compile (require 'mh-acros))
-
-(define-obsolete-function-alias 'mh-require #'require "29.1")
-(define-obsolete-function-alias 'mh-assoc-string #'assoc-string "29.1")
-(define-obsolete-function-alias 'mh-cancel-timer #'cancel-timer "29.1")
-
-(define-obsolete-function-alias 'mh-display-color-cells
- #'display-color-cells "29.1")
-
-(defmacro mh-display-completion-list (completions &optional common-substring)
- "Display the list of COMPLETIONS.
-See documentation for `display-completion-list' for a description of the
-arguments COMPLETIONS.
-The optional argument COMMON-SUBSTRING, if non-nil, should be a string
-specifying a common substring for adding the faces
-`completions-first-difference' and `completions-common-part' to
-the completions."
- (declare (obsolete nil "29.1"))
- `(display-completion-list
- (completion-hilit-commonality ,completions
- ,(length common-substring) nil)))
-
-(define-obsolete-function-alias 'mh-face-foreground
- #'face-foreground "29.1")
-
-(define-obsolete-function-alias 'mh-face-background
- #'face-background "29.1")
-
-(define-obsolete-function-alias 'mh-font-lock-add-keywords
- #'font-lock-add-keywords "29.1")
-
-;; Not preloaded in without-x builds.
-(declare-function image-load-path-for-library "image")
-(define-obsolete-function-alias 'mh-image-load-path-for-library
- #'image-load-path-for-library "29.1")
-
-;; Not preloaded in without-x builds.
-(declare-function image-search-load-path "image")
-(define-obsolete-function-alias 'mh-image-search-load-path
- #'image-search-load-path "29.1")
-
-(define-obsolete-function-alias 'mh-line-beginning-position
- #'line-beginning-position "29.1")
-
-(define-obsolete-function-alias 'mh-line-end-position
- #'line-end-position "29.1")
-
-(require 'mailabbrev)
-(define-obsolete-function-alias 'mh-mail-abbrev-make-syntax-table
- #'mail-abbrev-make-syntax-table "29.1")
-
-(define-obsolete-function-alias 'mh-define-obsolete-variable-alias
- #'define-obsolete-variable-alias "29.1")
-
-(define-obsolete-function-alias 'mh-make-obsolete-variable
- #'make-obsolete-variable "29.1")
-
-(define-obsolete-function-alias 'mh-match-string-no-properties
- #'match-string-no-properties "29.1")
-
-(define-obsolete-function-alias 'mh-replace-regexp-in-string
- #'replace-regexp-in-string "29.1")
-
-(define-obsolete-function-alias 'mh-test-completion
- #'test-completion "29.1")
-
-(defconst mh-url-unreserved-chars
- '(
- ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
- ?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z
- ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
- ?- ?_ ?. ?! ?~ ?* ?' ?\( ?\))
- "A list of characters that are _NOT_ reserved in the URL spec.
-This is taken from RFC 2396.")
-(make-obsolete-variable 'mh-url-unreserved-chars 'url-unreserved-chars "29.1")
-
-(define-obsolete-function-alias 'mh-url-hexify-string
- #'url-hexify-string "29.1")
-
-(define-obsolete-function-alias 'mh-view-mode-enter
- #'view-mode-enter "29.1")
-
-(define-obsolete-function-alias 'mh-window-full-height-p
- #'window-full-height-p "29.1")
-
-(defmacro mh-write-file-functions ()
- "Return `write-file-functions'."
- (declare (obsolete nil "29.1"))
- ''write-file-functions)
-
-(provide 'mh-compat)
-
-;; Local Variables:
-;; sentence-end-double-space: nil
-;; End:
-
-;;; mh-compat.el ends here
;;>> One probably wants to do setenv MORE -c when running with
;;>> more-processing enabled.
-(require 'ehelp)
(require 'shell)
(defgroup terminal nil
(define-key map "x" #'te-escape-extended-command)
;;>> What use is this? Why is it in the default terminal-emulator map?
(define-key map "w" #'te-edit)
- (define-key map "?" #'te-escape-help)
- (define-key map (char-to-string help-char) #'te-escape-help)
(setq terminal-escape-map map)))
(defvar te-escape-command-alist nil)
("Switch To Buffer" . switch-to-buffer)
("Other Window" . other-window)
("Kill Buffer" . kill-buffer)
- ("Help" . te-escape-help)
("Set Redisplay Interval" . te-set-redisplay-interval)
)))
nil
(let ((map (make-sparse-keymap)))
(define-key map [t] #'te-more-break-unread)
- (define-key map (char-to-string help-char) #'te-more-break-help)
(define-key map " " #'te-more-break-resume)
(define-key map "\C-l" #'redraw-display)
(define-key map "\C-o" #'te-more-break-flush-pending-output)
(use-local-map terminal-escape-map)
(setq s (read-key-sequence
(if current-prefix-arg
- (format "Emacs Terminal escape[%s for help]> %d "
- (substitute-command-keys
- "\\<terminal-escape-map>\\[te-escape-help]")
+ (format "Emacs Terminal escape> %d "
(prefix-numeric-value current-prefix-arg))
- (format "Emacs Terminal escape[%s for help]> "
- (substitute-command-keys
- "\\<terminal-escape-map>\\[te-escape-help]"))))))
+ "Emacs Terminal escape> "))))
(use-global-map global)
(use-local-map local))
))
-
-(defun te-escape-help ()
- "Provide help on commands available after terminal-escape-char is typed."
- (interactive)
- (message "Terminal emulator escape help...")
- (let ((char (single-key-description terminal-escape-char)))
- (with-electric-help
- (function (lambda ()
- (princ (format "Terminal-emulator escape, invoked by \"%s\"
-Type \"%s\" twice to send a single \"%s\" through.
-
-Other chars following \"%s\" are interpreted as follows:\n"
- char char char char))
-
- (princ (substitute-command-keys "\\{terminal-escape-map}\n"))
- (princ (format "\nSubcommands of \"%s\" (%s)\n"
- (where-is-internal 'te-escape-extended-command
- terminal-escape-map t)
- 'te-escape-extended-command))
- (let ((l (sort (copy-sequence te-escape-command-alist)
- (function (lambda (a b)
- (string< (car a) (car b)))))))
- (while l
- (let ((doc (or (documentation (cdr (car l)))
- "Not documented")))
- (if (string-match "\n" doc)
- ;; just use first line of documentation
- (setq doc (substring doc 0 (match-beginning 0))))
- (princ " \"")
- (princ (car (car l)))
- (princ "\":\n ")
- (princ doc)
- (write-char ?\n))
- (setq l (cdr l))))
- nil)))))
-
-
-
(defun te-escape-extended-command ()
(interactive)
(let ((c (let ((completion-ignore-case t))
(message "Continuing from more break")
(te-more-break-unwind))
-(defun te-more-break-help ()
- "Provide help on commands available in a terminal-emulator **MORE** break"
- (interactive)
- (message "Terminal-emulator more break help...")
- (sit-for 0)
- (with-electric-help
- (function (lambda ()
- (princ "Terminal-emulator more break.\n\n")
- (princ (format "Type \"%s\" (te-more-break-resume)\n%s\n"
- (where-is-internal 'te-more-break-resume
- terminal-more-break-map t)
- (documentation 'te-more-break-resume)))
- (princ (substitute-command-keys "\\{terminal-more-break-map}\n"))
- (princ "Any other key is passed through to the program
-running under the terminal emulator and disables more processing until
-all pending output has been dealt with.")
- nil))))
-
-
(defun te-more-break-advance-one-line ()
"Allow one more line of text to be output before doing another more break."
(interactive)
(setq inhibit-quit t) ;sport death
(use-local-map terminal-map)
(run-hooks 'terminal-mode-hook)
- (message "Entering Emacs terminal-emulator... Type %s %s for help"
- (single-key-description terminal-escape-char)
- (mapconcat #'single-key-description
- (where-is-internal #'te-escape-help terminal-escape-map t)
- " ")))
+ (message "Entering Emacs terminal-emulator..."))
(defun te-parse-program-and-args (s)
(defconst org-info-emacs-documents
'("ada-mode" "auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x"
- "ede" "ediff" "edt" "efaq-w32" "efaq" "eglot" "eieio" "eintr"
+ "ede" "ediff" "efaq-w32" "efaq" "eglot" "eieio" "eintr"
"elisp" "emacs-gnutls" "emacs-mime" "emacs" "epa" "erc" "ert" "eshell"
"eudc" "eww" "flymake" "forms" "gnus" "htmlfontify" "idlwave" "ido" "info"
- "mairix-el" "message" "mh-e" "modus-themes" "newsticker" "nxml-mode" "octave-mode"
+ "mairix-el" "message" "modus-themes" "newsticker" "nxml-mode" "octave-mode"
"org" "pcl-cvs" "pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic"
"ses" "sieve" "smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "transient"
"url" "use-package" "vhdl-mode" "vip" "viper" "vtable" "widget" "wisent" "woman")
+++ /dev/null
-;;; ol-mhe.el --- Links to MH-E Messages -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2004-2024 Free Software Foundation, Inc.
-
-;; Author: Thomas Baumann <thomas dot baumann at ch dot tum dot de>
-;; Keywords: outlines, hypermedia, calendar, text
-;; URL: https://orgmode.org
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; This file implements links to MH-E messages from within Org.
-;; Org mode loads this module by default - if this is not what you want,
-;; configure the variable `org-modules'.
-
-;;; Code:
-
-(require 'org-macs)
-(org-assert-version)
-
-(require 'org-macs)
-(require 'ol)
-
-;; Customization variables
-
-(defcustom org-mhe-search-all-folders nil
- "Non-nil means the search for the mh-message may extend to all folders.
-When non-nil, the search for a message will extend to all other
-folders if it cannot be found in the folder given in the link.
-Searching all folders may be slow with the default pick based
-search but is very efficient with one of the other search engines
-supported by MH-E."
- :group 'org-link-follow
- :type 'boolean)
-
-;; Declare external functions and variables
-(declare-function mh-display-msg "mh-show" (msg-num folder-name))
-(declare-function mh-find-path "mh-utils" ())
-(declare-function mh-get-header-field "mh-utils" (field))
-(declare-function mh-get-msg-num "mh-utils" (error-if-no-message))
-(declare-function mh-header-display "mh-show" ())
-(declare-function mh-index-previous-folder "mh-search" ())
-(declare-function mh-normalize-folder-name "mh-utils"
- (folder &optional empty-string-okay dont-remove-trailing-slash
- return-nil-if-folder-empty))
-(declare-function mh-search "mh-search"
- (folder search-regexp &optional redo-search-flag
- window-config))
-(declare-function mh-search-choose "mh-search" (&optional searcher))
-(declare-function mh-show "mh-show" (&optional message redisplay-flag))
-(declare-function mh-show-buffer-message-number "mh-comp" (&optional buffer))
-(declare-function mh-show-header-display "mh-show" t t)
-(declare-function mh-show-msg "mh-show" (msg))
-(declare-function mh-show-show "mh-show" t t)
-(declare-function mh-visit-folder "mh-folder" (folder &optional
- range index-data))
-(defvar mh-progs)
-(defvar mh-current-folder)
-(defvar mh-show-folder-buffer)
-(defvar mh-index-folder)
-(defvar mh-searcher)
-(defvar mh-search-regexp-builder)
-
-;; Install the link type
-(org-link-set-parameters "mhe" :follow #'org-mhe-open :store #'org-mhe-store-link)
-
-;; Implementation
-(defun org-mhe-store-link (&optional _interactive?)
- "Store a link to an MH-E folder or message."
- (when (or (eq major-mode 'mh-folder-mode)
- (eq major-mode 'mh-show-mode))
- (save-window-excursion
- (let* ((from (org-mhe-get-header "From:"))
- (to (org-mhe-get-header "To:"))
- (message-id (org-mhe-get-header "Message-Id:"))
- (subject (org-mhe-get-header "Subject:"))
- (date (org-mhe-get-header "Date:"))
- link desc)
- (org-link-store-props :type "mh" :from from :to to :date date
- :subject subject :message-id message-id)
- (setq desc (org-link-email-description))
- (setq link (concat "mhe:" (org-mhe-get-message-real-folder) "#"
- (org-unbracket-string "<" ">" message-id)))
- (org-link-add-props :link link :description desc)
- link))))
-
-(defun org-mhe-open (path _)
- "Follow an MH-E message link specified by PATH."
- (let (folder article)
- (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path))
- (error "Error in MH-E link"))
- (setq folder (match-string 1 path)
- article (match-string 3 path))
- (org-mhe-follow-link folder article)))
-
-;;; mh-e integration based on planner-mode
-(defun org-mhe-get-message-real-folder ()
- "Return the name of the real folder for the current message.
-So if you use sequences, it will now work."
- (save-excursion
- (let* ((folder
- (if (eq major-mode 'mh-folder-mode)
- mh-current-folder
- ;; Refer to the show buffer
- mh-show-folder-buffer))
- (end-index
- (if (boundp 'mh-index-folder)
- (min (length mh-index-folder) (length folder))))
- )
- ;; a simple test on mh-index-data does not work, because
- ;; mh-index-data is always nil in a show buffer.
- (if (and (boundp 'mh-index-folder)
- (string= mh-index-folder (substring folder 0 end-index)))
- (if (eq major-mode 'mh-show-mode)
- (save-window-excursion
- (let (pop-up-frames)
- (when (buffer-live-p (get-buffer folder))
- (progn
- (pop-to-buffer folder)
- (org-mhe-get-message-folder-from-index)
- )
- )))
- (org-mhe-get-message-folder-from-index)
- )
- folder
- )
- )))
-
-(defun org-mhe-get-message-folder-from-index ()
- "Return the name of the message folder in an index folder buffer."
- (save-excursion
- (mh-index-previous-folder)
- (if (re-search-forward "^\\(\\+.*\\)$" nil t)
- (message "%s" (match-string 1)))))
-
-(defun org-mhe-get-message-folder ()
- "Return the name of the current message folder.
-Be careful if you use sequences."
- (save-excursion
- (if (eq major-mode 'mh-folder-mode)
- mh-current-folder
- ;; Refer to the show buffer
- mh-show-folder-buffer)))
-
-(defun org-mhe-get-message-num ()
- "Return the number of the current message.
-Be careful if you use sequences."
- (save-excursion
- (if (eq major-mode 'mh-folder-mode)
- (mh-get-msg-num nil)
- ;; Refer to the show buffer
- (mh-show-buffer-message-number))))
-
-(defun org-mhe-get-header (header)
- "Return the field for HEADER of the message in folder mode.
-This will create a show buffer for the corresponding message. If
-you have a better idea of how to do this then please let us know."
- (let* ((folder (org-mhe-get-message-folder))
- (num (org-mhe-get-message-num))
- (buffer (get-buffer-create (concat "show-" folder)))
- (header-field))
- (with-current-buffer buffer
- (mh-display-msg num folder)
- (if (eq major-mode 'mh-folder-mode)
- (mh-header-display)
- (mh-show-header-display))
- (set-buffer buffer)
- (setq header-field (mh-get-header-field header))
- (if (eq major-mode 'mh-folder-mode)
- (mh-show)
- (mh-show-show))
- (org-trim header-field))))
-
-(defun org-mhe-follow-link (folder article)
- "Follow an MH-E link to FOLDER and ARTICLE.
-If ARTICLE is nil FOLDER is shown. If the configuration variable
-`org-mhe-search-all-folders' is t and `mh-searcher' is pick,
-ARTICLE is searched in all folders. Indexed searches (swish++,
-namazu, and others supported by MH-E) will always search in all
-folders."
- (require 'mh-e)
- (require 'mh-search)
- (require 'mh-utils)
- (mh-find-path)
- (if (not article)
- (mh-visit-folder (mh-normalize-folder-name folder))
- (mh-search-choose)
- (if (eq mh-searcher 'pick)
- (progn
- (setq article (org-link-add-angle-brackets article))
- (mh-search folder (list "--message-id" article))
- (when (and org-mhe-search-all-folders
- (not (org-mhe-get-message-real-folder)))
- (kill-buffer)
- (mh-search "+" (list "--message-id" article))))
- (if mh-search-regexp-builder
- (mh-search "+" (funcall mh-search-regexp-builder
- (list (cons 'message-id article))))
- (mh-search "+" article)))
- (if (org-mhe-get-message-real-folder)
- (mh-show-msg 1)
- (kill-buffer)
- (error "Message not found"))))
-
-(provide 'ol-mhe)
-
-;;; ol-mhe.el ends here
:type 'boolean
:group 'lisp)
+(defun elisp-fontify-symbol (type sym len bind)
+ (if (null bind)
+ (when-let ((face (cl-case type
+ (variable 'elisp-free-variable)
+ (function 'font-lock-function-call-face)
+ (defun 'font-lock-function-name-face)
+ (defvar 'font-lock-variable-name-face))))
+ (add-face-text-property sym (+ sym len) face t))
+ (add-face-text-property sym (+ sym len)
+ (if (equal sym bind)
+ 'elisp-binding-variable
+ 'elisp-bound-variable)
+ t)
+ (put-text-property sym (+ sym len 1) 'cursor-sensor-functions
+ ;; Get a fresh list with SYM hardcoded,
+ ;; so that the value is distinguishable
+ ;; from the value in adjacent regions.
+ (elisp-cursor-sensor sym))))
+
(defun elisp-fontify-region-semantically (beg end)
"Fontify symbols between BEG and END according to their semantics."
(save-excursion
(goto-char beg)
(while (< (point) end)
(ignore-errors
- (scope
- (lambda (type sym len bind)
- (if (null bind)
- (when-let ((face (cl-case type
- (variable 'elisp-free-variable)
- (function 'font-lock-function-call-face)
- (defun 'font-lock-function-name-face)
- (defvar 'font-lock-variable-name-face))))
- (add-face-text-property sym (+ sym len) face t))
- (add-face-text-property sym (+ sym len)
- (if (equal sym bind)
- 'elisp-binding-variable
- 'elisp-bound-variable)
- t)
- (put-text-property sym (+ sym len 1) 'cursor-sensor-functions
- ;; Get a fresh list with SYM hardcoded,
- ;; so that the value is distinguishable
- ;; from the value in adjacent regions.
- (elisp-cursor-sensor sym))))
- (current-buffer))))))
+ (scope #'elisp-fontify-symbol (current-buffer))))))
(defun elisp-fontify-region (beg end &optional loudly)
"Fontify ELisp code between BEG and END.
(require 'cl-lib))
(require 'comint) ; Password regexp.
(require 'ansi-color)
-(require 'ehelp)
(require 'ring)
(require 'shell)
(define-key map "\C-u" (lookup-key (current-global-map) "\C-u"))
(define-key map " " 'term-pager-page)
(define-key map "\r" 'term-pager-line)
- (define-key map "?" 'term-pager-help)
- (define-key map "h" 'term-pager-help)
(define-key map "b" 'term-pager-back-page)
(define-key map "\177" 'term-pager-back-line)
(define-key map "q" 'term-pager-discard)
["Goto to beginning" term-pager-bob t]
["Goto to end" term-pager-eob t]
["Discard remaining output" term-pager-discard t]
- ["Disable paging" term-pager-toggle t]
- ["Help" term-pager-help t]))
+ ["Disable paging" term-pager-toggle t]))
(defvar term-raw-escape-map
(let ((map (make-sparse-keymap)))
(interactive)
(if (term-pager-enabled) (term-pager-disable) (term-pager-enable)))
-(defun term-pager-help ()
- "Provide help on commands available in a terminal-emulator **MORE** break."
- (interactive)
- (message "Terminal-emulator pager break help...")
- (sit-for 0)
- (with-electric-help
- (lambda ()
- (princ (substitute-command-keys
-"\\<term-pager-break-map>\
-Terminal-emulator MORE break.\n\
-Type one of the following keys:\n\n\
-\\[term-pager-page]\t\tMove forward one page.\n\
-\\[term-pager-line]\t\tMove forward one line.\n\
-\\[universal-argument] N \\[term-pager-page]\tMove N pages forward.\n\
-\\[universal-argument] N \\[term-pager-line]\tMove N lines forward.\n\
-\\[universal-argument] N \\[term-pager-back-line]\tMove N lines back.\n\
-\\[universal-argument] N \\[term-pager-back-page]\t\tMove N pages back.\n\
-\\[term-pager-bob]\t\tMove to the beginning of the buffer.\n\
-\\[term-pager-eob]\t\tMove to the end of the buffer.\n\
-\\[term-pager-discard]\t\tKill pending output and kill process.\n\
-\\[term-pager-disable]\t\tDisable PAGER handling.\n\n\
-\\{term-pager-break-map}\n\
-Any other key is passed through to the program
-running under the terminal emulator and disables pager processing until
-all pending output has been dealt with."))
- nil)))
-
(defun term-pager-continue (new-count)
(let ((process (get-buffer-process (current-buffer))))
(use-local-map term-pager-old-local-map)
nil Expand the minibuffer and display a short help message
there for a couple of seconds.
t Pop up a new buffer and display a short help message there
- for a couple of seconds.
- electric Pop up a new buffer and display a long help message there.
- User can browse and then exit the help mode."
- :type '(choice (const electric) (const :tag "off" nil) (const :tag "on" t)))
+ for a couple of seconds."
+ :type '(choice (const :tag "off" nil) (const :tag "on" t)))
(defcustom ispell-quietly nil
"Non-nil means suppress messages in `ispell-word'."
\\`C-l' Redraw screen.
\\`C-r' Recursive edit.
\\`C-z' Suspend Emacs or iconify frame."
-
- (if (equal ispell-help-in-bufferp 'electric)
- (progn
- (require 'ehelp)
- (with-electric-help
- (lambda ()
- ;;This shouldn't be necessary: with-electric-help needs
- ;; an optional argument telling it about the smallest
- ;; acceptable window-height of the help buffer.
- ;;(if (< (window-height) 15)
- ;; (enlarge-window
- ;; (- 15 (ispell-adjusted-window-height))))
- (princ
- (substitute-command-keys
- "Selections are:
-
-\\`0'..\\`9' Replace the word with a digit offered in the *Choices* buffer.
-\\`SPC' Accept word this time.
-\\`i' Accept word and insert into private dictionary.
-\\`a' Accept word for this session.
-\\`A' Accept word and place in `buffer-local dictionary'.
-\\`r' Replace word with typed-in value. Rechecked.
-\\`R' Replace word with typed-in value. Query-replaced in buffer. Rechecked.
-\\`?' Show these commands.
-\\`x' Exit spelling buffer. Move cursor to original point.
-\\`X' Exit spelling buffer. Leaves cursor at the current point, and permits
- the aborted check to be completed later.
-\\`q' Quit spelling session (Kills ispell process).
-\\`l' Look up typed-in replacement in alternate dictionary. Wildcards okay.
-\\`u' Like \\`i', but the word is lower-cased first.
-\\`m' Place typed-in value in personal dictionary, then recheck current word.
-\\`C-l' Redraw screen.
-\\`C-r' Recursive edit.
-\\`C-z' Suspend Emacs or iconify frame."))
- nil)))
-
-
- (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; "
- "[i]nsert into private dictionary"))
- (help-2 (concat "[l]ook a word up in alternate dictionary; "
- "e[x/X]it; [q]uit session"))
- (help-3 (concat "[u]ncapitalized insert into dict. "
- "Type `x C-h f ispell-help' for more help")))
- (save-window-excursion
- (if ispell-help-in-bufferp
- (let ((buffer (get-buffer-create "*Ispell Help*")))
- (with-current-buffer buffer
- (insert (concat help-1 "\n" help-2 "\n" help-3)))
- (ispell-display-buffer buffer)
- (sit-for ispell-help-timeout)
- (kill-buffer "*Ispell Help*"))
- (unwind-protect
- (let ((resize-mini-windows 'grow-only))
- (select-window (minibuffer-window))
- (erase-buffer)
- (message nil)
- ;;(set-minibuffer-window (selected-window))
- (enlarge-window 2)
- (insert (concat help-1 "\n" help-2 "\n" help-3))
- (sit-for ispell-help-timeout))
- (erase-buffer)))))))
+ (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; "
+ "[i]nsert into private dictionary"))
+ (help-2 (concat "[l]ook a word up in alternate dictionary; "
+ "e[x/X]it; [q]uit session"))
+ (help-3 (concat "[u]ncapitalized insert into dict. "
+ "Type `x C-h f ispell-help' for more help")))
+ (save-window-excursion
+ (if ispell-help-in-bufferp
+ (let ((buffer (get-buffer-create "*Ispell Help*")))
+ (with-current-buffer buffer
+ (insert (concat help-1 "\n" help-2 "\n" help-3)))
+ (ispell-display-buffer buffer)
+ (sit-for ispell-help-timeout)
+ (kill-buffer "*Ispell Help*"))
+ (unwind-protect
+ (let ((resize-mini-windows 'grow-only))
+ (select-window (minibuffer-window))
+ (erase-buffer)
+ (message nil)
+ ;;(set-minibuffer-window (selected-window))
+ (enlarge-window 2)
+ (insert (concat help-1 "\n" help-2 "\n" help-3))
+ (sit-for ispell-help-timeout))
+ (erase-buffer))))))
(define-obsolete-function-alias 'lookup-words 'ispell-lookup-words "24.4")
(with-no-warnings message-cite-prefix-regexp)
"\\|"
default-prefix))
- ((equal major-mode 'mh-letter-mode) ; mh mail message
- (concat "[^,;&+=\n]+ writes:" "\\|"
- (with-no-warnings
- (ispell-non-empty-string mh-ins-buf-prefix))))
((not internal-messagep) ; Assume nn sent us this message.
(concat "In [a-zA-Z.]+ you write:" "\\|"
"In <[^,;&+=]+> [^,;&+=]+ writes:" "\\|"
((memq (ediff-with-current-buffer x major-mode)
'(rmail-mode
vm-mode
- gnus-article-mode
- mh-show-mode))
+ gnus-article-mode))
x)
((string-match "^[ *]" (buffer-name x)) nil)
((string= "*scratch*" (buffer-name x)) nil)