comparison lisp/mail/pmailhdr.el @ 97528:184bb2071e3f

mail/: Add new (temporary) libaries for which to test Rmail/mbox such that Rmail/babyl is not affected. This creates a facility/feature called "pmail" (analagous to "rmail") that can be used independently from Rmail for testing purposes. The plan is to replace the "rmail" files eventually and remove "pmail" entirely at that point. In the interim, interested developers can use either Rmail or Pmail or both (which is not recommended for the casual User or the faint of heart).
author Paul Reilly <pmr@pajato.com>
date Mon, 18 Aug 2008 04:51:28 +0000
parents
children 1b1837ac37e2
comparison
equal deleted inserted replaced
97527:059ec03cfe4e 97528:184bb2071e3f
1 ;;; pmail-header.el --- Header handling code of "PMAIL" mail reader for Emacs
2
3 ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc.
4
5 ;; Maintainer: FSF
6 ;; Keywords: mail
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Commentary:
26
27 ;;; Code:
28
29 (eval-when-compile
30 (require 'mail-utils))
31
32 (defconst pmail-header-attribute-header "X-BABYL-V6-ATTRIBUTES"
33 "The header that stores the Pmail attribute data.")
34
35 (defconst pmail-header-keyword-header "X-BABYL-V6-KEYWORDS"
36 "The header that stores the Pmail keyword data.")
37
38 (defvar pmail-header-overlay-list nil
39 "List of cached overlays used to make headers hidden or visible.")
40
41 (defvar pmail-header-display-state nil
42 "Records the current header display state.
43 nil means headers are displayed, t indicates headers are not displayed.")
44
45 (defun pmail-header-get-limit ()
46 "Return the end of the headers.
47 The current buffer must show one message. If you want to narrow
48 to the headers of a mail by number, use `pmail-narrow-to-header'
49 instead."
50 (save-excursion
51 (goto-char (point-min))
52 (if (search-forward "\n\n" nil t)
53 (1- (point))
54 (error "Invalid message format"))))
55
56 (defun pmail-header-add-header (header value)
57 "Add HEADER to the list of headers and associate VALUE with it.
58 The current buffer, possibly narrowed, contains a single message.
59 If VALUE is nil or the empty string, the header is removed
60 instead."
61 (save-excursion
62 (let* ((inhibit-read-only t)
63 (case-fold-search t)
64 (inhibit-point-motion-hooks t)
65 (buffer-undo-list t)
66 (limit (pmail-header-get-limit))
67 start end)
68 ;; Search for the given header. If found, then set it's value.
69 ;; If not then add the header to the end of the header section.
70 (goto-char (point-min))
71 (if (re-search-forward (format "^%s: " header) limit t)
72 (let ((start (match-beginning 0)))
73 (re-search-forward "\n[^ \t]")
74 (goto-char limit)
75 (delete-region start (1+ (match-beginning 0))))
76 (goto-char limit))
77 (when (> (length value) 0)
78 (insert header ": " value "\n")))))
79
80 (defun pmail-header-contains-keyword-p (keyword)
81 "Return t if KEYWORD exists in the current buffer, nil otherwise."
82 (let ((limit (pmail-header-get-limit)))
83 (goto-char (point-min))
84 (if (re-search-forward (format "^%s: " pmail-header-keyword-header) limit t)
85 ;; Some keywords exist. Now search for the specific keyword.
86 (let ((start (point))
87 (end (progn (end-of-line) (point))))
88 (if (re-search-forward (concat "\\(" keyword ",\\|" keyword "$\\)"))
89 t)))))
90
91 (defun pmail-header-get-header (&rest args)
92 "Return the text value for a header or nil if no such header exists.
93 The arguments ARGS are passed to `mail-fetch-field'. The first
94 argument is the header to get.
95
96 The current buffer, possibly narrowed, contains a single message.
97 Note that it is not necessary to call `pmail-header-show-headers'
98 because `inhibit-point-motion-hooks' is locally bound to t."
99 (save-excursion
100 (save-restriction
101 (let* ((inhibit-point-motion-hooks t)
102 (limit (pmail-header-get-limit)))
103 (narrow-to-region (point-min) limit)
104 (apply 'mail-fetch-field args)))))
105
106 (defun pmail-header-get-keywords ()
107 "Return the keywords in the current message.
108 The current buffer, possibly narrowed, contains a single message."
109 ;; Search for a keyword header and return the comma separated
110 ;; strings as a list.
111 (let ((limit (pmail-header-get-limit)) result)
112 (goto-char (point-min))
113 (if (re-search-forward
114 (format "^%s: " pmail-header-keyword-header) limit t)
115 (save-excursion
116 (save-restriction
117 (narrow-to-region (point) (line-end-position))
118 (goto-char (point-min))
119 (mail-parse-comma-list))))))
120
121 (defun pmail-header-hide-headers ()
122 "Hide ignored headers. All others will be visible.
123 The current buffer, possibly narrowed, contains a single message."
124 (save-excursion
125 (pmail-header-show-headers)
126 (let ((overlay-list pmail-header-overlay-list)
127 (limit (pmail-header-get-limit))
128 (inhibit-point-motion-hooks t)
129 (case-fold-search t)
130 visibility-p)
131 ;; Record the display state as having headers hidden.
132 (setq pmail-header-display-state t)
133 (if pmail-displayed-headers
134 ;; Set the visibility predicate function to ignore headers
135 ;; marked for display.
136 (setq visibility-p 'pmail-header-show-displayed-p)
137 ;; Set the visibility predicate function to hide ignored
138 ;; headers.
139 (setq visibility-p 'pmail-header-hide-ignored-p))
140 ;; Walk through all the headers marking the non-displayed
141 ;; headers as invisible.
142 (goto-char (point-min))
143 (while (re-search-forward "^[^ \t:]+[ :]" limit t)
144 ;; Determine if the current header needs to be hidden.
145 (forward-line 0)
146 (if (not (funcall visibility-p))
147 ;; It does not. Move point away from this header.
148 (progn
149 (forward-line 1)
150 (while (looking-at "[ \t]+")
151 (forward-line 1)))
152 ;; It does. Make this header hidden by setting an overlay
153 ;; with both the invisible and intangible properties set.
154 (let ((start (point)))
155 ;; Move to end and pick upp any continuation lines on folded
156 ;; headers.
157 (forward-line 1)
158 (while (looking-at "[ \t]+")
159 (forward-line 1))
160 (if (car overlay-list)
161 ;; Use one of the cleared, cached overlays.
162 (let ((overlay (car overlay-list)))
163 (move-overlay overlay start (point))
164 (setq overlay-list (cdr overlay-list)))
165 ;; No overlay exists for this header. Create one and
166 ;; add it to the cache.
167 (let ((overlay (make-overlay start (point))))
168 (overlay-put overlay 'invisible t)
169 (overlay-put overlay 'intangible t)
170 (push overlay pmail-header-overlay-list)))))))))
171
172 (defun pmail-header-show-headers ()
173 "Show all headers.
174 The current buffer, possibly narrowed, contains a single message."
175 ;; Remove all the overlays used to control hiding headers.
176 (mapcar 'delete-overlay pmail-header-overlay-list)
177 (setq pmail-header-display-state nil))
178
179 (defun pmail-header-toggle-visibility (&optional arg)
180 "Toggle the visibility of the ignored headers if ARG is nil.
181 Hide the ignored headers if ARG is greater than 0, otherwise show the
182 ignored headers. The current buffer, possibly narrowed, contains a
183 single message."
184 (cond ((eq arg nil)
185 (if pmail-header-display-state
186 (pmail-header-show-headers)
187 (pmail-header-hide-headers)))
188 ((or (eq arg t) (> arg 0))
189 (pmail-header-hide-headers))
190 (t (pmail-header-show-headers))))
191
192 (defun pmail-header-hide-ignored-p ()
193 "Test that the header is one of the headers marked to be ignored."
194 (looking-at pmail-ignored-headers))
195
196 (defun pmail-header-show-displayed-p ()
197 "Test that the header is not one of the headers marked for display."
198 (not (looking-at pmail-displayed-headers)))
199
200 (provide 'pmailhdr)
201
202 ;;; pmailhdr.el ends here