|
|
1.1 ! root 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. ! 7: ; ! 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 ! 14: ; ! 15: ; ------------------------------------------------------------------------ ! 16: ; GETTING IT INSTALLED AT YOUR SITE: ! 17: ; ! 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. ! 21: ; ! 22: ; The file mh-e.ml must be edited to reflect the filename paths on your ! 23: ; system: ! 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". ! 35: ; ! 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. ! 48: ; ! 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. ! 53: ; ! 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: ! 57: ; ! 58: ; alias mhe /usr/local/bin/emacs -lmh-e.ml -estartup $* ! 59: ; ! 60: ; The shell syntax for mhe is ! 61: ; mhe ! 62: ; or ! 63: ; mhe +inbox first argument is folder name ! 64: ; or ! 65: ; mhe +inbox 200:300 second argument is message range ! 66: ; ! 67: ; The folder name defaults to current-folder, and the message range defaults ! 68: ; to "all". ! 69: ; ------------------------------------------------------------------------ ! 70: ; HOW MHE WORKS ! 71: ; ! 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. ! 85: ; ! 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. ! 91: ; ! 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: ; ------------------------------------------------------------------------ ! 99: ; ! 100: ; MODIFICATIONS TO MH ! 101: ; ! 102: ; Here is a summary of the relevant changes to MH that I have made. Some of ! 103: ; them are just optimizations. ! 104: ; ! 105: ; (from repl.c; nearly identical changes go into forw.c.) ! 106: ; ! 107: ; short buildflag = 0; /* just building a reply file? */ ! 108: ; ... ! 109: ; "build", 0, /*12 */ ! 110: ; ... ! 111: ; case 12:buildflag++; continue; /* -build */ ! 112: ; if (buildflag) ! 113: ; drft = m_maildir("reply"); ! 114: ; else ! 115: ; drft = m_maildir(draft); ! 116: ; ... ! 117: ; if((!buildflag) & (stat(drft, &stbuf) != -1)) { ! 118: ; cp = concat("\"", drft, "\" exists; delete (y,n,l) ? ", 0); ! 119: ; ... ! 120: ; if (!buildflag) { ! 121: ; if(m_edit(&ed, drft, NOUSE, msg) < 0) ! 122: ; return; ! 123: ; } ! 124: ; ... ! 125: ; if(!buildflag) { ! 126: ; if(!(argp = getans("\nWhat now? ", aleqs))) { ! 127: ; VOID unlink("@"); ! 128: ; return; ! 129: ; } ! 130: ; ... ! 131: ; switch(buildflag ? 4 : smatch(*argp, aleqs)) { ! 132: ; case 0: VOID showfile(drft); /* list */ ! 133: ; ... ! 134: ; ! 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) ! 138: ; ! 139: ; FILE *in, *aud, *mhe_aud; ! 140: ; ... ! 141: ; char ..., *mhe_audfile; ! 142: ; ... ! 143: ; mhe_audfile = m_find("mhe"); ! 144: ; if(!m_find("path")) free(path("./", TFOLDER)); ! 145: ; ... ! 146: ; if(mhe_audfile) { ! 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 "); ! 151: ; perror(cp); ! 152: ; } else if(i < 0) ! 153: ; VOID chmod(cp, 0600); ! 154: ; } ! 155: ; ... ! 156: ; if(aud) ! 157: ; fputs(scanl, aud); ! 158: ; if(mhe_aud) ! 159: ; fputs(scanl, mhe_aud); ! 160: ; ... ! 161: ; if(mhe_aud) ! 162: ; VOID fclose(mhe_aud); ! 163: ; ! 164: ; In adrparse.c: ! 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 ! 171: ; names. ! 172: ; ! 173: ; ! 174: ; ------------------------------------------------------------------------ ! 175: ; these functions let me edit the above documentation without the semicolons. ! 176: (defun ! 177: (add-semicolons ! 178: (beginning-of-file) ! 179: (while (! (| (eobp) (looking-at "^(defun"))) ! 180: (insert-string "; ") ! 181: (next-line) (beginning-of-line) ! 182: ) ! 183: ) ! 184: ! 185: (remove-semicolons ! 186: (beginning-of-file) ! 187: (while (! (| (eobp) (looking-at "^(defun"))) ! 188: (while (| (looking-at "^; ") (looking-at "^;$")) ! 189: (delete-next-character) ! 190: (if (! (eolp)) ! 191: (delete-next-character)) ! 192: ) ! 193: (next-line) ! 194: ) ! 195: ) ! 196: )
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.