|
|
1.1 ! root 1: ;; "RMAIL" mail reader for Emacs. ! 2: ;; Copyright (C) 1985, 1988 Free Software Foundation, Inc. ! 3: ! 4: ;; This file is part of GNU Emacs. ! 5: ! 6: ;; GNU Emacs is distributed in the hope that it will be useful, ! 7: ;; but WITHOUT ANY WARRANTY. No author or distributor ! 8: ;; accepts responsibility to anyone for the consequences of using it ! 9: ;; or for whether it serves any particular purpose or works at all, ! 10: ;; unless he says so in writing. Refer to the GNU Emacs General Public ! 11: ;; License for full details. ! 12: ! 13: ;; Everyone is granted permission to copy, modify and redistribute ! 14: ;; GNU Emacs, but only under the conditions described in the ! 15: ;; GNU Emacs General Public License. A copy of this license is ! 16: ;; supposed to have been given to you along with GNU Emacs so you ! 17: ;; can know your rights and responsibilities. It should be in a ! 18: ;; file named COPYING. Among other things, the copyright notice ! 19: ;; and this notice must be preserved on all copies. ! 20: ! 21: ! 22: ;; Global to all RMAIL buffers. It exists primarily for the sake of ! 23: ;; completion. It is better to use strings with the label functions ! 24: ;; and let them worry about making the label. ! 25: ! 26: (defvar rmail-label-obarray (make-vector 47 0)) ! 27: ! 28: ;; Named list of symbols representing valid message attributes in RMAIL. ! 29: ! 30: (defconst rmail-attributes ! 31: (cons 'rmail-keywords ! 32: (mapcar '(lambda (s) (intern s rmail-label-obarray)) ! 33: '("deleted" "answered" "filed" "forwarded" "unseen" "edited")))) ! 34: ! 35: (defconst rmail-deleted-label (intern "deleted" rmail-label-obarray)) ! 36: ! 37: ;; Named list of symbols representing valid message keywords in RMAIL. ! 38: ! 39: (defvar rmail-keywords nil) ! 40: ! 41: (defun rmail-add-label (string) ! 42: "Add LABEL to labels associated with current RMAIL message. ! 43: Completion is performed over known labels when reading." ! 44: (interactive (list (rmail-read-label "Add label"))) ! 45: (rmail-set-label string t)) ! 46: ! 47: (defun rmail-kill-label (string) ! 48: "Remove LABEL from labels associated with current RMAIL message. ! 49: Completion is performed over known labels when reading." ! 50: (interactive (list (rmail-read-label "Remove label"))) ! 51: (rmail-set-label string nil)) ! 52: ! 53: (defun rmail-read-label (prompt) ! 54: (if (not rmail-keywords) (rmail-parse-file-keywords)) ! 55: (let ((result ! 56: (completing-read (concat prompt ! 57: (if rmail-last-label ! 58: (concat " (default " ! 59: (symbol-name rmail-last-label) ! 60: "): ") ! 61: ": ")) ! 62: rmail-label-obarray ! 63: nil ! 64: nil))) ! 65: (if (string= result "") ! 66: rmail-last-label ! 67: (setq rmail-last-label (rmail-make-label result t))))) ! 68: ! 69: (defun rmail-set-label (l state &optional n) ! 70: (rmail-maybe-set-message-counters) ! 71: (if (not n) (setq n rmail-current-message)) ! 72: (aset rmail-summary-vector (1- n) nil) ! 73: (let* ((attribute (rmail-attribute-p l)) ! 74: (keyword (and (not attribute) ! 75: (or (rmail-keyword-p l) ! 76: (rmail-install-keyword l)))) ! 77: (label (or attribute keyword))) ! 78: (if label ! 79: (let ((omax (- (buffer-size) (point-max))) ! 80: (omin (- (buffer-size) (point-min))) ! 81: (buffer-read-only nil) ! 82: (case-fold-search t)) ! 83: (unwind-protect ! 84: (save-excursion ! 85: (widen) ! 86: (goto-char (rmail-msgbeg n)) ! 87: (forward-line 1) ! 88: (if (not (looking-at "[01],")) ! 89: nil ! 90: (let ((start (1+ (point))) ! 91: (bound)) ! 92: (narrow-to-region (point) (progn (end-of-line) (point))) ! 93: (setq bound (point-max)) ! 94: (search-backward ",," nil t) ! 95: (if attribute ! 96: (setq bound (1+ (point))) ! 97: (setq start (1+ (point)))) ! 98: (goto-char start) ! 99: ; (while (re-search-forward "[ \t]*,[ \t]*" nil t) ! 100: ; (replace-match ",")) ! 101: ; (goto-char start) ! 102: (if (re-search-forward ! 103: (concat ", " (rmail-quote-label-name label) ",") ! 104: bound ! 105: 'move) ! 106: (if (not state) (replace-match ",")) ! 107: (if state (insert " " (symbol-name label) ","))) ! 108: (if (eq label rmail-deleted-label) ! 109: (rmail-set-message-deleted-p n state))))) ! 110: (narrow-to-region (- (buffer-size) omin) (- (buffer-size) omax)) ! 111: (if (= n rmail-current-message) (rmail-display-labels))))))) ! 112: ! 113: ;; Commented functions aren't used by RMAIL but might be nice for user ! 114: ;; packages that do stuff with RMAIL. Note that rmail-message-labels-p ! 115: ;; is in rmailsum now. ! 116: ! 117: ;(defun rmail-message-attribute-p (attribute &optional n) ! 118: ; "Returns t if ATTRIBUTE on NTH or current message." ! 119: ; (rmail-message-labels-p (rmail-make-label attribute t) n)) ! 120: ! 121: ;(defun rmail-message-keyword-p (keyword &optional n) ! 122: ; "Returns t if KEYWORD on NTH or current message." ! 123: ; (rmail-message-labels-p (rmail-make-label keyword t) n t)) ! 124: ! 125: ;(defun rmail-message-label-p (label &optional n) ! 126: ; "Returns symbol if LABEL (attribute or keyword) on NTH or current message." ! 127: ; (rmail-message-labels-p (rmail-make-label label t) n 'all)) ! 128: ! 129: ;; Not used by RMAIL but might be nice for user package. ! 130: ! 131: ;(defun rmail-parse-message-labels (&optional n) ! 132: ; "Returns labels associated with NTH or current RMAIL message. ! 133: ;Results is a list of two lists. The first is the message attributes ! 134: ;and the second is the message keywords. Labels are represented as symbols." ! 135: ; (let ((omin (- (buffer-size) (point-min))) ! 136: ; (omax (- (buffer-size) (point-max))) ! 137: ; (result)) ! 138: ; (unwind-protect ! 139: ; (save-excursion ! 140: ; (let ((beg (rmail-msgbeg (or n rmail-current-message)))) ! 141: ; (widen) ! 142: ; (goto-char beg) ! 143: ; (forward-line 1) ! 144: ; (if (looking-at "[01],") ! 145: ; (save-restriction ! 146: ; (narrow-to-region (point) (save-excursion (end-of-line) (point))) ! 147: ; (rmail-nuke-whitespace) ! 148: ; (goto-char (1+ (point-min))) ! 149: ; (list (mail-parse-comma-list) (mail-parse-comma-list)))))) ! 150: ; (narrow-to-region (- (buffer-size) omin) ! 151: ; (- (buffer-size) omax)) ! 152: ; nil))) ! 153: ! 154: (defun rmail-attribute-p (s) ! 155: (let ((symbol (rmail-make-label s))) ! 156: (if (memq symbol (cdr rmail-attributes)) symbol))) ! 157: ! 158: (defun rmail-keyword-p (s) ! 159: (let ((symbol (rmail-make-label s))) ! 160: (if (memq symbol (cdr (rmail-keywords))) symbol))) ! 161: ! 162: (defun rmail-make-label (s &optional forcep) ! 163: (cond ((symbolp s) s) ! 164: (forcep (intern (downcase s) rmail-label-obarray)) ! 165: (t (intern-soft (downcase s) rmail-label-obarray)))) ! 166: ! 167: (defun rmail-force-make-label (s) ! 168: (intern (downcase s) rmail-label-obarray)) ! 169: ! 170: (defun rmail-quote-label-name (label) ! 171: (regexp-quote (symbol-name (rmail-make-label label t)))) ! 172: ! 173: ;; Motion on messages with keywords. ! 174: ! 175: (defun rmail-previous-labeled-message (n label) ! 176: "Show previous message with LABEL. Defaults to last labels used. ! 177: With prefix argument N moves backward N messages with these labels." ! 178: (interactive "p\nsMove to previous msg with labels: ") ! 179: (rmail-next-labeled-message (- n) label)) ! 180: ! 181: (defun rmail-next-labeled-message (n labels) ! 182: "Show next message with LABEL. Defaults to last labels used. ! 183: With prefix argument N moves forward N messages with these labels." ! 184: (interactive "p\nsMove to next msg with labels: ") ! 185: (if (string= labels "") ! 186: (setq labels rmail-last-multi-labels)) ! 187: (or labels ! 188: (error "No labels to find have been specified previously")) ! 189: (setq rmail-last-multi-labels labels) ! 190: (rmail-maybe-set-message-counters) ! 191: (let ((lastwin rmail-current-message) ! 192: (current rmail-current-message) ! 193: (regexp (concat ", ?\\(" ! 194: (mail-comma-list-regexp labels) ! 195: "\\),"))) ! 196: (save-restriction ! 197: (widen) ! 198: (while (and (> n 0) (< current rmail-total-messages)) ! 199: (setq current (1+ current)) ! 200: (if (rmail-message-labels-p current regexp) ! 201: (setq lastwin current n (1- n)))) ! 202: (while (and (< n 0) (> current 1)) ! 203: (setq current (1- current)) ! 204: (if (rmail-message-labels-p current regexp) ! 205: (setq lastwin current n (1+ n))))) ! 206: (rmail-show-message lastwin) ! 207: (if (< n 0) ! 208: (message "No previous message with labels %s" labels)) ! 209: (if (> n 0) ! 210: (message "No following message with labels %s" labels)))) ! 211: ! 212: ;;; Manipulate the file's Labels option. ! 213: ! 214: ;; Return a list of symbols for all ! 215: ;; the keywords (labels) recorded in this file's Labels option. ! 216: (defun rmail-keywords () ! 217: (or rmail-keywords (rmail-parse-file-keywords))) ! 218: ! 219: ;; Set rmail-keywords to a list of symbols for all ! 220: ;; the keywords (labels) recorded in this file's Labels option. ! 221: (defun rmail-parse-file-keywords () ! 222: (save-restriction ! 223: (save-excursion ! 224: (widen) ! 225: (goto-char 1) ! 226: (setq rmail-keywords ! 227: (if (search-forward "\nLabels:" (rmail-msgbeg 1) t) ! 228: (progn ! 229: (narrow-to-region (point) (progn (end-of-line) (point))) ! 230: (goto-char (point-min)) ! 231: (cons 'rmail-keywords ! 232: (mapcar 'rmail-force-make-label ! 233: (mail-parse-comma-list))))))))) ! 234: ! 235: ;; Add WORD to the list in the file's Labels option. ! 236: ;; Any keyword used for the first time needs this done. ! 237: (defun rmail-install-keyword (word) ! 238: (let ((keyword (rmail-make-label word t)) ! 239: (keywords (rmail-keywords))) ! 240: (if (not (or (rmail-attribute-p keyword) ! 241: (rmail-keyword-p keyword))) ! 242: (let ((omin (- (buffer-size) (point-min))) ! 243: (omax (- (buffer-size) (point-max)))) ! 244: (unwind-protect ! 245: (save-excursion ! 246: (widen) ! 247: (goto-char 1) ! 248: (let ((case-fold-search t) ! 249: (buffer-read-only nil)) ! 250: (or (search-forward "\nLabels:" nil t) ! 251: (progn ! 252: (end-of-line) ! 253: (insert "\nLabels:"))) ! 254: (delete-region (point) (progn (end-of-line) (point))) ! 255: (setcdr keywords (cons keyword (cdr keywords))) ! 256: (while (setq keywords (cdr keywords)) ! 257: (insert (symbol-name (car keywords)) ",")) ! 258: (delete-char -1))) ! 259: (narrow-to-region (- (buffer-size) omin) ! 260: (- (buffer-size) omax))))) ! 261: keyword))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.