1 ; This is "mhe", the Emacs-based front end to "mh", which is the Rand Mail
2 ; Handler. MH is a set of programs designed to be called as commands from the
3 ; shell. This system uses single-keystroke commands and maintains a visual
4 ; display of the contents of the message file. I initially wrote it because I
5 ; was drowning in mail and I needed some way to pare out the junk, and it has
6 ; just sort of mushroomed into a real system.
8 ; Brian K. Reid, Stanford University
9 ; Version 1: April 1982
10 ; Version 2: May 1982: new commands added
11 ; Version 3: August 1982: rewrote send-to-shell for increased speed
12 ; Version 4: Added extensive header caching mechanism for increased speed
13 ; Version 5: documentation updated slightly. November 1982
15 ; ------------------------------------------------------------------------
16 ; GETTING IT INSTALLED AT YOUR SITE:
18 ; Mhe consists of about a dozen mlisp files. The primary file is mh-e.ml,
19 ; which in turn loads the others as needed. All of them must be in the
20 ; directory where your Emacs will look for its library files.
22 ; The file mh-e.ml must be edited to reflect the filename paths on your
24 ; mh-progs must be set to the name of the directory
25 ; in which the MH programs are stored, i.e.
26 ; "/usr/local/lib/mh" if the "scan" command
27 ; is /usr/local/lib/mh/scan.
28 ; bboard-path must be set to the name of the directory
29 ; that is the root of your "readnews" tree.
30 ; If your "fa.human-nets" newsgroup is stored
31 ; in /usr/spool/news/fa.human-nets/*, then
32 ; you should set this variable to
33 ; "/usr/spool/news". If you don't use
34 ; readnews, then set it to "/dev/null".
36 ; The MH programs "repl", and "forw" have to be modified to include
37 ; the option "-build", which causes them not to ask the "What now?"
38 ; question at the end, but instead just exit (having built the file). Mhe will
39 ; also be a lot more tolerable if you remove a lot of the warning messages
40 ; from adrparse.c; there's no point making them fatal errors. If you aren't up
41 ; to hacking directly on the MH programs, contact me as Reid@SU-SCORE or
42 ; ucbvax!Shasta!reid, and I will provide you with my version of the code.
43 ; If I weren't so lazy I would propagate these changes back to Rand, but I've
44 ; forgotten the name of the contact there and I can't find our licensing
45 ; agreement to look his name up. Besides, they have probably changed their
46 ; sources out from under me anyhow. I have included a summary of the important
47 ; changes at the end of this documentation.
49 ; Mhe requires Emacs #45 of Fri May 21 1982 or later, because it uses
50 ; buffer-local variables.
51 ; ----------------------------------------------------------------------------
52 ; SETTING UP A NEW MHE USER.
54 ; If you are an mh user, then you can just run mhe with no further ado.
55 ; However, you can speed things up substantially by putting an alias into your
56 ; .cshrc file so that you won't need to spawn a new subshell when you run it:
58 ; alias mhe /usr/local/bin/emacs -lmh-e.ml -estartup $*
60 ; The shell syntax for mhe is
63 ; mhe +inbox first argument is folder name
65 ; mhe +inbox 200:300 second argument is message range
67 ; The folder name defaults to current-folder, and the message range defaults
69 ; ------------------------------------------------------------------------
72 ; Mhe uses the Emacs subprocess facility to run mh commands in a subshell.
73 ; Normally when you use mh, it runs the editor in a subshell; this inverted
74 ; scheme of the editor running mh in the subshell is actually much much
75 ; faster, because editors are slow in starting up but the mh programs are
76 ; pretty fast. When you start mhe, it builds a buffer whose name equals the
77 ; name of the current folder (e.g. "+inbox"), and places a "scan" listing into
78 ; that buffer. Then as you edit your mail, deleting and moving messages, mhe
79 ; builds up a set of shell commands in a buffer called "cmd-buffer". When you
80 ; exit from mhe, it passes the contents of cmd-buffer off to the shell, and
81 ; the deletes and moves are actually processed. If you open another mail file,
82 ; its header is given its own buffer ("+carbons", "+bugs", etc.), and you can
83 ; switch back and forth to them as needed. The Emacs buffer-local context
84 ; mechanism makes everything happen almost perfectly.
86 ; To avoid the overhead of doing a "scan" everytime you run mhe or switch
87 ; folders, mhe maintains a cache of header lines in a file with the same name
88 ; as the buffer; e.g. a file named ~/Mail/inbox/+inbox will hold the header
89 ; cache for folder +inbox. The extended command "scavenge" will regenerate
90 ; this header listing.
92 ; To avoid the overhead of loading the entire 50000-character mhe system on
93 ; startup, most of the command-driven functions are off in autoloaded files,
94 ; so that the first time you use a command you will have to wait for its
95 ; definition to be loaded. This scheme seems to be perfectly acceptable to
96 ; users. However, most people use mhe by running it once in the morning and
97 ; sitting in it all day, so this feature doesn't buy much in the grand scheme.
98 ; ------------------------------------------------------------------------
100 ; MODIFICATIONS TO MH
102 ; Here is a summary of the relevant changes to MH that I have made. Some of
103 ; them are just optimizations.
105 ; (from repl.c; nearly identical changes go into forw.c.)
107 ; short buildflag = 0; /* just building a reply file? */
109 ; "build", 0, /*12 */
111 ; case 12:buildflag++; continue; /* -build */
113 ; drft = m_maildir("reply");
115 ; drft = m_maildir(draft);
117 ; if((!buildflag) & (stat(drft, &stbuf) != -1)) {
118 ; cp = concat("\"", drft, "\" exists; delete (y,n,l) ? ", 0);
121 ; if(m_edit(&ed, drft, NOUSE, msg) < 0)
126 ; if(!(argp = getans("\nWhat now? ", aleqs))) {
131 ; switch(buildflag ? 4 : smatch(*argp, aleqs)) {
132 ; case 0: VOID showfile(drft); /* list */
135 ; In inc.c: (this code makes it possible for you to use an "inc" command
136 ; outside of mhe, like in your .login file, and still have mhe pick up
137 ; the headers of the new messages the next time you run it)
139 ; FILE *in, *aud, *mhe_aud;
141 ; char ..., *mhe_audfile;
143 ; mhe_audfile = m_find("mhe");
144 ; if(!m_find("path")) free(path("./", TFOLDER));
147 ; cp = concat(maildir, "/++", NULLCP);
148 ; i = stat(cp, &stbuf);
149 ; if((mhe_aud = fopen(cp, "a")) == NULL) {
150 ; fprintf(stderr, "Can't append to ");
153 ; VOID chmod(cp, 0600);
159 ; fputs(scanl, mhe_aud);
162 ; VOID fclose(mhe_aud);
165 ; Remove all instances of "goto line", replacing it with "break" if it is in
166 ; the "switch" statement, otherwise just taking it out. This makes it so syntax
167 ; errors will be non-fatal. Remove the
168 ; if(isalnum(*cp))||*cp=="-" || etc.
169 ; statement about 40% of the way through, so that all characters not given
170 ; specific meanings in the switch statement above it will be legal in mail
174 ; ------------------------------------------------------------------------
175 ; these functions let me edit the above documentation without the semicolons.
179 (while (! (| (eobp) (looking-at "^(defun")))
181 (next-line) (beginning-of-line)
187 (while (! (| (eobp) (looking-at "^(defun")))
188 (while (| (looking-at "^; ") (looking-at "^;$"))
189 (delete-next-character)
191 (delete-next-character))