1 ;;; patch-keywords.el --- Insert action keywords into patch followups.
3 ;; Copyright (C) 2002 Steve Youngs
5 ;; RCS: $Id: patch-keywords.el,v 1.4 2003-08-17 09:34:55 adrian Exp $
6 ;; Author: Steve Youngs <youngs@xemacs.org>
7 ;; Maintainer: Steve Youngs <youngs@xemacs.org>
9 ;; Last-Modified: <2002-03-04 07:18:01 (steve)>
12 ;; This file is part of XEmacs
14 ;; XEmacs is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 2 of the License, or
17 ;; (at your option) any later version.
19 ;; XEmacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with this program; if not, write to the Free Software
26 ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 ;; This file is an aid to mailing followups to patches submitted via
32 ;; email. It adds "Reviewer Action Keywords" to the message. These
33 ;; "keywords" can later be used as an aid to patch tracking.
35 ;; At this stage, this file is probably only useful to anyone who
36 ;; reviews patches submitted to <xemacs-patches@xemacs.org>.
39 ;; - M-x customize-group RET patch-review RET
40 ;; Change things to your liking.
41 ;; - (require 'patch-keywords)
42 ;; In your ~/.xemacs/init.el
44 ;; Then when you are following up to a patch submission, just hit
45 ;; 'M-p'. You'll be prompted for the keywords to apply to the
46 ;; message. You can use the history mechanism to select keywords.
47 ;; Enter a null keyword (just hit 'RET') to terminate the list of
50 ;; The keywords are added to 3 separate places in the message.
51 ;; - In abbreviated form (1st character of each keyword) enclosed
52 ;; in square brackets at the start of the subject header (version
53 ;; numbers are not abbreviated).
55 ;; - In a "X-Reviewer-Action:" header (full keywords).
57 ;; - At line 0, column 0 of the message body.
59 ;; To see how to setup a "X-Reviewer-Action:" header, see
60 ;; `gnus-posting-styles'
62 ;; Many thanks to Adrian Aichner <adrian@xemacs.org> for his ideas,
63 ;; code examples and testing.
68 (autoload 'gnus-continuum-version "gnus"))
71 (defgroup patch-review nil
72 "Patch submission review."
75 (defcustom patch-keywords
85 "List of keywords used for reviewing patches.
87 The default values are the keywords currently used by the XEmacs
90 :type '(repeat (string :tag "Review Action Keyword"))
91 :tag "Action Keywords")
93 (defcustom patch-review-mua 'gnus
94 "The MUA (Mail User Agent) you use for reviewing patches.
96 Currently, the only MUAs that are supported are Gnus and VM. Should
97 we even bother with things like MEW or Rmail?"
102 (item mew\ \(Not\ Supported\))
103 (item rmail\ \(Not\ Supported\)))
106 (defcustom patch-keywords-followup-to "XEmacs Beta <xemacs-beta@xemacs.org>"
107 "The address to put into the \"Mail-Followup-To:\" header.
108 This is so that any further discussions relating to the submitted
109 patch can take place in a separate forum."
112 :tag "Followups Address")
114 ;; I use the bleeding edge Gnus (Oort 0.05), so consequently we have
115 ;; to define a couple of functions that aren't in the XEmacs package
116 ;; version of Gnus (5.8.8). Later on they're wrapped in a version
118 (defun patch-keywords-in-header-p ()
119 "Return t if point is in the header.
120 Same as `message-point-in-header-p' which exists in Gnus Oort, but not
124 (goto-char (point-min))
125 (not (re-search-forward
126 (concat "^" (regexp-quote mail-header-separator) "\n")
129 (defun patch-keywords-message-beginning-of-line (&optional n)
130 "Move point to beginning of header value or to beginning of line.
131 Optional argument N non-nil or 1, move forward N - 1 lines first.
132 Same as `message-beginning-of-line' which exists in Gnus Oort, but not
135 (if (if (< (gnus-continuum-version gnus-version) 5.090004)
136 (patch-keywords-in-header-p)
137 (message-point-in-header-p))
138 (let* ((here (point))
139 (bol (progn (beginning-of-line n) (point)))
140 (eol (gnus-point-at-eol))
141 (eoh (re-search-forward ": *" eol t)))
142 (if (or (not eoh) (equal here eoh))
145 (beginning-of-line n)))
147 (defun patch-keywords-insert-gnus (patch-key)
148 "Insert the action keywords into patch followups.
150 Argument PATCH-KEY A list of action keywords as defined in
151 `patch-keywords'. They may be chosen interactively via the
154 Insert abbreviated (1st char) keywords at the beginning of the subject
155 header. Full keywords into the \"X-Reviewer-Action:\" header, if
156 present, and also at the start of the message body.
158 The \"X-Reviewer-Action:\" header can be easily inserted using
159 `gnus-posting-styles'.
161 This function also sets followups to xemacs-beta@xemacs.org."
164 ((hist patch-keywords)
171 "Enter patch keywords (or RET to finish): " "" 'hist))
173 (setq keys (cons key keys)))
174 (list (mapconcat 'identity (reverse keys) " "))))
175 (if (string-equal patch-key "")
176 (error "Choose at least one patch-key from %s"
177 (mapconcat 'identity patch-keywords ", ")))
179 ;; We need to preserve the original subject header so something
180 ;; like "fix for 21.5 not for 21.4" doesn't turn into "fix for
182 (message-goto-subject)
183 (if (< (gnus-continuum-version gnus-version) 5.090004)
184 (patch-keywords-message-beginning-of-line)
185 (message-beginning-of-line))
186 (re-search-forward ".*$" (eolp) t)
187 (let ((oldsub (match-string 0))
188 (keywords (concat "\\("
189 (regexp-opt patch-keywords)
191 ;; Clear the original subject (reinstate it later)
192 (if (< (gnus-continuum-version gnus-version) 5.090004)
193 (patch-keywords-message-beginning-of-line)
194 (message-beginning-of-line))
195 (if (re-search-forward ".*$" (eolp) t)
197 ;; Insert the long patch keywords
199 (concat "[" patch-key " ]"))
201 ;; Convert to abbreviated patch keywords
202 (if (< (gnus-continuum-version gnus-version) 5.090004)
203 (patch-keywords-message-beginning-of-line)
204 (message-beginning-of-line))
206 (narrow-to-region (point) (point-at-eol))
207 (while (re-search-forward keywords (eolp) t)
208 (let ((keyword (match-string 1)))
210 (string-match "\\`[.0-9]+\\'" keyword))
211 (replace-match (match-string 1))
212 (replace-match (substring (match-string 1) 0 1))))))
213 ;; Reinstate the original subject header after the keywords
215 (insert-string oldsub))
216 ;; Insert keywords into the 'X-Reviewer-Action:' header
218 (if (re-search-forward "^X-Reviewer-Action: " nil t)
219 (insert-string patch-key))
220 ;; Set followups to go to xemacs-beta
221 (if (< (gnus-continuum-version gnus-version) 5.090004)
222 (message-position-on-field "Mail-Followup-To" "From")
223 (message-goto-mail-followup-to))
224 (insert-string patch-keywords-followup-to)
225 ;; Insert the keywords into the body of the message
227 (insert-string patch-key)
228 (insert-string "\n\n")))
230 (defun patch-keywords-insert-vm (patch-key)
231 "Insert the action keywords into patch followups.
233 Argument PATCH-KEY A list of action keywords as defined in
234 `patch-keywords'. They may be chosen interactively via the
237 Insert abbreviated (1st char) keywords at the beginning of the subject
238 header. Full keywords into the \"X-Reviewer-Action:\" header, and
239 also at the start of the message body.
241 This function also sets followups to xemacs-beta@xemacs.org."
244 ((hist patch-keywords)
251 "Enter patch keywords (or RET to finish): " "" 'hist))
253 (setq keys (cons key keys)))
254 (list (mapconcat 'identity (reverse keys) " "))))
255 (if (string-equal patch-key "")
256 (error "Choose at least one patch-key from %s"
257 (mapconcat 'identity patch-keywords ", ")))
259 ;; We need to preserve the original subject header so something
260 ;; like "fix for 21.5 not for 21.4" doesn't turn into "fix for
263 (patch-keywords-message-beginning-of-line)
264 (re-search-forward ".*$" (eolp) t)
265 (let ((oldsub (match-string 0))
266 (keywords (concat "\\("
267 (regexp-opt patch-keywords)
269 ;; Clear the original subject (reinstate it later)
270 (patch-keywords-message-beginning-of-line)
271 (if (re-search-forward ".*$" (eolp) t)
273 ;; Insert the long patch keywords
275 (concat "[" patch-key " ]"))
277 ;; Convert to abbreviated patch keywords
278 (patch-keywords-message-beginning-of-line)
280 (narrow-to-region (point) (point-at-eol))
281 (while (re-search-forward keywords (eolp) t)
282 (let ((keyword (match-string 1)))
284 (string-match "\\`[.0-9]+\\'" keyword))
285 (replace-match (match-string 1))
286 (replace-match (substring (match-string 1) 0 1))))))
287 ;; Reinstate the original subject header after the keywords
289 (insert-string oldsub))
290 ;; Insert keywords into the 'X-Reviewer-Action:' header
292 (insert-string (concat "X-Reviewer-Action: " patch-key "\n"))
293 ;; Set followups to go to xemacs-beta
295 (insert-string "Mail-Followup-To: ")
296 (insert-string (concat patch-keywords-followup-to "\n"))
297 ;; Insert the keywords into the body of the message
299 (insert-string patch-key)
300 (insert-string "\n\n")))
302 ;; Bind 'patch-keywords-insert-MUA' to M-p.
303 (cond ((string= patch-review-mua "gnus")
304 (define-key message-mode-map "\M-p" 'patch-keywords-insert-gnus))
305 ((string= patch-review-mua "vm")
306 (define-key mail-mode-map "\M-p" 'patch-keywords-insert-vm)))
308 (provide 'patch-keywords)
310 ;;; patch-keywords.el ends here
313 ;time-stamp-start: "Last-Modified:[ ]+\\\\?[\"<]+"
314 ;time-stamp-end: "\\\\?[\">]"
315 ;time-stamp-line-limit: 10
316 ;time-stamp-format: "%4y-%02m-%02d %02H:%02M:%02S (%u)"