|
|
1.1 ! root 1: ; This file implements "mhe", the display-oriented front end to the MH mail ! 2: ; system. Documentation is in file mh-doc.ml. ! 3: ; To install this at your site you must edit the variables flagged with ! 4: ; an asterisk below. ! 5: ; ! 6: ; Brian K. Reid, Stanford, April 1982 ! 7: ; ! 8: ; This is version 4 (September 1982); it uses fast-filter-region. ! 9: ; ! 10: ; UCI modification: we don't need fast-filter-region since we have ! 11: ; use-users-shell ! 12: (setq stack-trace-on-error 1) ! 13: (declare-global ;*marks installation constants ! 14: mh-keymap-defined ; T iff keymap exists. ! 15: mh-folder ; string name, e.g. "inbox" ! 16: mh-path ; "/mnt/reid/Mail", or whatever ! 17: mh-progs ;*"/usr/local/lib/mh", or whatever ! 18: bboard-path ;*"/usr/spool/netnews", or whatever ! 19: mh-buffer-filename ; "/mnt/reid/Mail/inbox", or whatever ! 20: t-buffer-filename ; scratch for side effect from mh-folder ! 21: mh-flist ; "inbox,carbons,news", or whatever ! 22: mh-direction ; 1 is up, -1 is down. ! 23: mh-annotate ; are we annotating processed msgs? ! 24: mh-writeable ; is this folder write-enabled? ! 25: mh-last-destination ; destination of last "move" command ! 26: mhe-debug ; are we debugging macro package? ! 27: ) ! 28: ! 29: (argc) ; is this early enough, James? ! 30: (setq mh-keymap-defined 0) ! 31: (setq mhe-debug 0) ! 32: (setq-default mh-annotate 1) ! 33: (setq-default mh-writeable 1) ! 34: (setq bboard-path "/dev/null"); UCI ! 35: (setq mh-path "") ! 36: (setq mh-progs "/usr/uci") ; UCI ! 37: (setq mh-flist "") ! 38: (setq-default right-margin 77) ! 39: (setq-default mh-direction 1) ! 40: (setq pop-up-windows 1) ; mhe requires popup windows! ! 41: ! 42: (declare-buffer-specific ! 43: mh-direction ! 44: mh-buffer-filename ! 45: mh-folder-title ! 46: mh-annotate ! 47: mh-writeable ! 48: backup-before-writing ! 49: wrap-long-lines ! 50: ) ! 51: ! 52: (defun ; (mh "folder" "range") ! 53: (mh folder range ! 54: (temp-use-buffer "cmd-buffer") (erase-buffer) ! 55: (setq backup-before-writing 0) ! 56: (find-path) ! 57: (setq folder (arg 1 (concat ": mh on folder? [" mh-folder "] "))) ! 58: (if (= folder "") ! 59: (setq folder mh-folder)) ! 60: (if (= '+' (string-to-char (substr folder 1 1))) ! 61: (setq folder (substr folder 2 -1))) ! 62: (setq range (arg 2)) ! 63: (setq mh-folder (get-folder-name "??" folder 1)) ! 64: (&mh-read-folder mh-folder range t-buffer-filename mh-folder) ! 65: (progn stop-loop ! 66: (setq stop-loop 0) ! 67: (while (! stop-loop) ! 68: (pop-to-buffer (concat "+" mh-folder)) ! 69: (use-local-map "&mh-keymap") ! 70: (error-occured (recursive-edit)) ! 71: (setq stop-loop (&mh-exit)) ! 72: ) ! 73: ) ! 74: ) ! 75: ) ! 76: ; This function marks a message as being deleted. This mark has two parts. ! 77: ; The letter "D" is placed in column 4 of the header line, and the message ! 78: ; number is added to the text of an "rmm" command that is being assembled ! 79: ; in the command buffer. ! 80: (defun ! 81: (&mh-Mark-file-deleted ! 82: (pop-to-buffer (concat "+" mh-folder)) ! 83: (if (! mh-writeable) ! 84: (error-message "Sorry; this folder is read-only.")) ! 85: (beginning-of-line) ! 86: (goto-character (+ (dot) 3)) ! 87: (if (| (= (following-char) ' ') (= (following-char) '+')) ! 88: (progn ! 89: (delete-next-character) ! 90: (insert-string "D") ! 91: (setq buffer-is-modified 0) ! 92: (temp-use-buffer "cmd-buffer") ! 93: (beginning-of-file) ! 94: (if (error-occured ! 95: (re-search-forward ! 96: (concat "^rmm +" mh-folder))) ! 97: (progn ! 98: (end-of-file) ! 99: (insert-string (concat "rmm +" mh-folder "\n")) ! 100: (backward-character) ! 101: ) ! 102: ) ! 103: (end-of-line) ! 104: (insert-string (concat " " (&mh-get-msgnum))) ! 105: (setq buffer-is-modified 0) ! 106: (pop-to-buffer (concat "+" mh-folder)) ! 107: ) ! 108: ) ! 109: (another-line) ! 110: ) ! 111: ) ! 112: ; These functions create (and make current) a header buffer on a new message ! 113: ; or bboard directory. ! 114: (defun ! 115: (&mh-new-folder which ! 116: (setq which (get-folder-name "New" "" 1)) ! 117: (&mh-read-folder which "" t-buffer-filename which) ! 118: ) ! 119: ! 120: (&mh-bboard which ! 121: (error-message "B: command not implemented at UCI."); UCI ! 122: ;UCI (setq which (get-bboard-name)) ! 123: ;UCI (&mh-read-folder which "" t-buffer-filename t-buffer-filename) ! 124: ;UCI (setq mh-annotate 0) ! 125: ;UCI (setq mh-writeable 0) ! 126: ) ! 127: ) ! 128: ! 129: (defun ! 130: (&mh-remove ! 131: (if (= "+" (substr (current-buffer-name) 1 1)) ! 132: (progn ! 133: (beginning-of-line) ! 134: (&mh-unmark) ! 135: (kill-to-end-of-line) (kill-to-end-of-line) ! 136: (setq buffer-is-modified 0) ! 137: ) ! 138: (error-message "The " (char-to-string (last-key-struck)) " command works only in header windows.") ! 139: ) ! 140: ) ! 141: ! 142: ; This function gets redefined when &mh-move is autoloaded. Shame on me for ! 143: ; giving it a name so similar to the function above. ! 144: (&mh-re-move ! 145: (error-message "I can't repeat the last ^ command because you haven't typed one yet") ! 146: ) ! 147: ! 148: (&mh-summary ! 149: (message ! 150: "nxt prev del ^put !rpt unmrk typ edit mail forw inc repl get bboard ^X^C ?") ! 151: ) ! 152: ! 153: ; This function is redefined when file mh-extras.ml is autoloaded ! 154: (&mh-beep (send-string-to-terminal "")) ! 155: ) ! 156: ; These functions are used to preserve the contents of the kill buffer ! 157: ; across things that we want to be invisible, so that the keyboard-level ! 158: ; user does not have to worry about system functions clobbering the kill ! 159: ; buffer. ! 160: (defun ! 161: (&mh-save-killbuffer ! 162: (save-excursion ! 163: (temp-use-buffer "Kill buffer") ! 164: (temp-use-buffer "Kill save") ! 165: (setq backup-before-writing 0) ! 166: (erase-buffer) ! 167: (yank-buffer "Kill buffer") ! 168: (setq buffer-is-modified 0) ! 169: ) ! 170: ) ! 171: ! 172: (&mh-restore-killbuffer ! 173: (save-excursion ! 174: (temp-use-buffer "Kill buffer") ! 175: (erase-buffer) ! 176: (yank-buffer "Kill save") ! 177: ) ! 178: ) ! 179: ) ! 180: ; These functions move the cursor around in a header buffer, and possibly ! 181: ; also display the message that the cursor now points to. ! 182: (defun ! 183: (&mh-next-line ! 184: (pop-to-buffer (concat "+" mh-folder)) ! 185: (setq mh-direction 1) ! 186: (next-line) (beginning-of-line) ! 187: (if (eobp) ! 188: (progn (previous-line) ! 189: (setq mh-direction -1))) ! 190: ) ! 191: (&mh-previous-line ! 192: (pop-to-buffer (concat "+" mh-folder)) ! 193: (setq mh-direction -1) ! 194: (previous-line) (beginning-of-line) ! 195: (if (bobp) ! 196: (setq mh-direction 1)) ! 197: ) ! 198: ! 199: (another-line old-direction ! 200: (setq old-direction mh-direction) ! 201: (if (> mh-direction 0) ! 202: (&mh-next-line) ! 203: (&mh-previous-line) ! 204: ) ! 205: (if (!= old-direction mh-direction) ! 206: (if (> mh-direction 0) ! 207: (beginning-of-line) ! 208: (&mh-previous-line) ! 209: ) ! 210: ) ! 211: ) ! 212: ! 213: ) ! 214: ; These functions query the user for various things, and error-check the ! 215: ; responses. "get-response" reads a 1-letter response code in the minibuffer. ! 216: ; "get-folder-name" extracts the string name of an MH folder or file. ! 217: ; "get-bboard-name" gets the string name of a bboard file. ! 218: (defun ! 219: (get-response chr ok s c pr ! 220: (setq ok 0) (setq pr (arg 1)) ! 221: (while (! ok) ! 222: (setq chr ! 223: (string-to-char ! 224: (setq c ! 225: (get-tty-string pr) ! 226: ) ! 227: ) ! 228: ) ! 229: ! 230: (setq s (arg 2)) ! 231: (while (> (length s) 0) ! 232: (if (= chr (string-to-char (substr s 1 1))) ! 233: (progn (setq ok 1) (setq s "")) ! 234: (setq s (substr s 2 -1)) ! 235: ) ! 236: ) ! 237: (if (= ok 0) ! 238: (progn (if (!= chr '?') ! 239: (setq pr (concat "Illegal response '" ! 240: (char-to-string chr) ! 241: "'. " (arg 1))) ! 242: (setq pr (arg 3)) ! 243: ) ! 244: ) ! 245: ) ! 246: ) ! 247: (if (& (>= chr 'A') (<= chr 'Z')) ! 248: (+ chr (- 'a' 'A')) ! 249: chr ! 250: ) ! 251: ) ! 252: ! 253: (get-folder-name ; (g-f-n "prompt" "default" can-create) ! 254: exists msgg name defarg ! 255: (setq exists 0) ! 256: (if (> (nargs) 1) (setq defarg (arg 2)) (setq defarg "")) ! 257: (setq msgg (concat (arg 1) " folder name? ")) ! 258: (while (! exists) ! 259: (if (= 0 (length defarg)) ! 260: (setq name (get-tty-string msgg)) ! 261: (setq name defarg) ! 262: ) ! 263: (setq defarg "") ! 264: (if (= 0 (length name)) ! 265: (error-message "Aborted.")) ! 266: (if (!= (string-to-char (substr name 1 1)) '/') ! 267: (setq t-buffer-filename (concat mh-path "/" name)) ! 268: (setq t-buffer-filename name) ! 269: ) ! 270: (setq exists (file-exists t-buffer-filename)) ! 271: (if (& (!= exists 1) (!= (arg 3) 0)) ! 272: (progn ans ! 273: (setq ans (get-response ! 274: (concat "Folder +" name " does not exist. May I create it for you? ") ! 275: "yYnN\" ! 276: "Please answer y or n")) ! 277: (if (= ans 'y') ! 278: (progn ! 279: (message "OK, I will create one for you.") ! 280: (send-to-shell ! 281: (concat "mkdir " t-buffer-filename)) ! 282: (setq exists 1) ! 283: ) ! 284: ) ! 285: ) ! 286: ) ! 287: (if (!= exists 1) ! 288: (setq msgg (concat "Sorry, no such folder as `" name ! 289: "'. Folder name? ")) ! 290: ) ! 291: ) ! 292: name ! 293: ) ! 294: ! 295: (get-bboard-name exists msgg name ! 296: (setq exists 0) ! 297: (setq msgg "BBoard name? ") ! 298: (while (! exists) ! 299: (setq name (get-tty-string msgg)) ! 300: (if (= 0 (length name)) ! 301: (error-message "Aborted.")) ! 302: (if (!= (string-to-char (substr name 1 1)) '/') ! 303: (setq t-buffer-filename (concat bboard-path "/" name)) ! 304: (setq t-buffer-filename name) ! 305: ) ! 306: (setq exists (file-exists t-buffer-filename)) ! 307: (if (!= exists 1) ! 308: (setq msgg (concat "Sorry, no such BBoard as `" name ! 309: "'. BBoard name? ")) ! 310: ) ! 311: ) ! 312: name ! 313: ) ! 314: ) ! 315: ; UCI hack for fast-filter-region ! 316: (defun (fast-filter-region UseUsersShell ! 317: (setq UseUsersShell use-users-shell) ! 318: (setq use-users-shell 0) ! 319: (filter-region ! 320: (arg 1 ": fast-filter-region (through command) ")) ! 321: (setq use-users-shell UseUsersShell) ! 322: ) ! 323: ) ! 324: ; These functions are the initial entry points to mhe. "startup" is ! 325: ; expecting an argv like "emacs -lmh-e.ml -estartup +inbox 100-last ! 326: (defun ! 327: (startup ! 328: (setq stack-trace-on-error 0) ! 329: (mh (if (> (argc) 3) ! 330: (argv 3) ! 331: "") ! 332: (if (> (argc) 4) ! 333: (argv 4) ! 334: "") ! 335: ) ! 336: (error-occured (kill-process "newtime")) ! 337: (exit-emacs) ! 338: ) ! 339: ! 340: (debug-startup ! 341: (setq mh-progs "/usr/local/src/cmd/mh/progs") ! 342: (setq stack-trace-on-error 0) ! 343: (startup) ! 344: ) ! 345: ) ! 346: (load "mh-util.ml") ! 347: (load "mh-shell.ml") ! 348: (load "mh-cache.ml") ! 349: (autoload "&mh-send" "mh-send.ml") ! 350: (autoload "&mh-show" "mh-show.ml") ! 351: (autoload "&mh-edit" "mh-edit.ml") ! 352: (autoload "&mh-repl" "mh-repl.ml") ! 353: (autoload "&mh-inc" "mh-inc.ml") ! 354: (autoload "&mh-help" "mh-help.ml") ! 355: (autoload "&mh-move" "mh-move.ml") ! 356: (autoload "&mh-unmark" "mh-unmark.ml") ! 357: (autoload "&mh-forw" "mh-forw.ml") ! 358: (autoload "&mh-exit" "mh-exit.ml") ! 359: (autoload "annotate" "mh-annot.ml") ! 360: (autoload "mail-mode" "mh-mode.ml") ! 361: (autoload "&mh-extras" "mh-extras.ml") ! 362: (autoload "&mh-xpack" "mh-extras.ml") ! 363: (if (! (is-bound time)) ! 364: (load "time.ml") ! 365: (time) ! 366: ) ! 367: (load "mh-keymap.ml")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.