2002-01-31 ShengHuo ZHU <zsh@cs.rochester.edu>
+ * nnfolder.el (nnfolder-request-replace-article): Unfold. Don't
+ use mail-header-unfold-field.
+
+ * gnus-cache.el (gnus-summary-insert-cached-articles): Use
+ gnus-summary-limit.
+
+ * gnus-range.el (gnus-add-to-sorted-list): New function.
+ * gnus-sum.el (gnus-mark-article-as-read): Use it.
+ (gnus-mark-article-as-unread): Ditto.
+ (gnus-summary-mark-article-as-unread): Ditto.
+ (gnus-build-get-header): Ditto.
+ (gnus-summary-prepare-threads): Ditto.
+ (gnus-summary-insert-pseudos): Ditto.
+ (gnus-articles-to-read): Use gnus-sorted-union and gnus-sorted-nunion.
+ (gnus-summary-insert-new-articles): Use gnus-sorted-nunion.
+ (gnus-summary-insert-old-articles): Ditto.
+
+ * gnus-msg.el (gnus-posting-styles): Add new format of header.
+ (gnus-configure-posting-styles): Support the new format.
+
+ * mail-source.el (mail-source-bind, mail-source-bind-common): Set
+ edebug-form-spec to (sexp body).
+ Suggested by Joe Wells <jbw@izanami.cee.hw.ac.uk>.
+
* message.el (message-reply-headers): Add doc.
2002-01-30 ShengHuo ZHU <zsh@cs.rochester.edu>
;;; gnus-cache.el --- cache interface for Gnus
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
(interactive)
(let ((cached (sort (copy-sequence gnus-newsgroup-cached) '>))
(gnus-verbose (max 6 gnus-verbose)))
- (unless cached
- (gnus-message 3 "No cached articles for this group"))
- (while cached
- (gnus-summary-goto-subject (pop cached) t))))
+ (if (not cached)
+ (gnus-message 3 "No cached articles for this group")
+ (save-excursion
+ (while cached
+ (gnus-summary-goto-subject (pop cached) t)))
+ (gnus-summary-limit (append gnus-newsgroup-cached gnus-newsgroup-limit))
+ (gnus-summary-position-point))))
(defun gnus-summary-limit-include-cached ()
"Limit the summary buffer to articles that are cached."
See Info node `(gnus)Posting Styles'."
:group 'gnus-message
:type '(repeat (cons (choice (regexp)
- (function)
(variable)
+ (list (const header)
+ (string :tag "Header")
+ (regexp :tag "Regexp"))
+ (function)
(sexp))
(repeat (list
(choice (const signature)
(const address)
(const name)
(const body)
+ (symbol)
(string :tag "Header"))
(choice (string)
(function)
(defcustom gnus-gcc-mark-as-read nil
"If non-nil, automatically mark Gcc articles as read."
+ :version "21.1"
:group 'gnus-message
:type 'boolean)
If it is `all', attach files as external parts;
if a regexp and matches the Gcc group name, attach files as external parts;
If nil, attach files as normal parts."
+ :version "21.1"
:group 'gnus-message
:type '(choice (const nil :tag "None")
(const all :tag "Any")
;; Regexp string match on the group name.
(string-match match group))
((eq match 'header)
+ ;; Obsolete format of header match.
(and (gnus-buffer-live-p gnus-article-copy)
(with-current-buffer gnus-article-copy
(let ((header (message-fetch-field (pop style))))
;; Variable to be checked.
(symbol-value match))))
((listp match)
- ;; This is a form to be evaled.
- (eval match)))
+ (cond
+ ((eq (car match) 'header)
+ ;; New format of header match.
+ (and (gnus-buffer-live-p gnus-article-copy)
+ (with-current-buffer gnus-article-copy
+ (let ((header (message-fetch-field (nth 1 match))))
+ (and header
+ (string-match (nth 2 match) header))))))
+ (t
+ ;; This is a form to be evaled.
+ (eval match)))))
;; We have a match, so we set the variables.
(dolist (attribute style)
(setq element (pop attribute)
(if item (push item range))
(reverse range)))
+;;;###autoload
+(defun gnus-add-to-sorted-list (list num)
+ "Add NUM into sorted LIST by side effect."
+ (let* ((top (cons nil list))
+ (prev top))
+ (while (and list (< (car list) num))
+ (setq prev list
+ list (cdr list)))
+ (unless (eq (car list) num)
+ (setcdr prev (cons num list)))
+ (cdr top)))
+
(provide 'gnus-range)
;;; gnus-range.el ends here
(push header gnus-newsgroup-headers)
(if (memq number gnus-newsgroup-unselected)
(progn
- (push number gnus-newsgroup-unreads)
+ (setq gnus-newsgroup-unselected
+ (gnus-add-to-sorted-list gnus-newsgroup-unreads
+ number))
(setq gnus-newsgroup-unselected
(delq number gnus-newsgroup-unselected)))
(push number gnus-newsgroup-ancient)))))))
(setq gnus-newsgroup-unreads
(delq number gnus-newsgroup-unreads))
(if gnus-newsgroup-auto-expire
- (push number gnus-newsgroup-expirable)
+ (setq gnus-newsgroup-expirable
+ (gnus-add-to-sorted-list
+ gnus-newsgroup-expirable number))
(push (cons number gnus-low-score-mark)
gnus-newsgroup-reads))))
(gnus-uncompress-range (gnus-active group))
(gnus-cache-articles-in-group group))
;; Select only the "normal" subset of articles.
- (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked
- (copy-sequence gnus-newsgroup-unreads))
- '<)))
+ (gnus-sorted-nunion
+ (gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked)
+ gnus-newsgroup-unreads)))
(scored-list (gnus-killed-articles gnus-newsgroup-killed articles))
(scored (length scored-list))
(number (length articles))
(setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
(setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
(cond ((= mark gnus-ticked-mark)
- (push article gnus-newsgroup-marked))
+ (setq gnus-newsgroup-marked
+ (gnus-add-to-sorted-list gnus-newsgroup-marked
+ article)))
((= mark gnus-dormant-mark)
- (push article gnus-newsgroup-dormant))
+ (setq gnus-newsgroup-dormant
+ (gnus-add-to-sorted-list gnus-newsgroup-dormant
+ article)))
(t
- (push article gnus-newsgroup-unreads)))
+ (setq gnus-newsgroup-unreads
+ (gnus-add-to-sorted-list gnus-newsgroup-unreads
+ article))))
(gnus-pull article gnus-newsgroup-reads)
;; See whether the article is to be put in the cache.
"Enter ARTICLE in the pertinent lists and remove it from others."
;; Make the article expirable.
(let ((mark (or mark gnus-del-mark)))
- (if (= mark gnus-expirable-mark)
- (push article gnus-newsgroup-expirable)
- (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)))
+ (setq gnus-newsgroup-expirable
+ (if (= mark gnus-expirable-mark)
+ (gnus-add-to-sorted-list gnus-newsgroup-expirable article)
+ (delq article gnus-newsgroup-expirable)))
;; Remove from unread and marked lists.
(setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
(setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
(gnus-dup-unsuppress-article article))
(cond ((= mark gnus-ticked-mark)
- (push article gnus-newsgroup-marked))
+ (setq gnus-newsgroup-marked
+ (gnus-add-to-sorted-list gnus-newsgroup-marked article)))
((= mark gnus-dormant-mark)
- (push article gnus-newsgroup-dormant))
+ (setq gnus-newsgroup-dormant
+ (gnus-add-to-sorted-list gnus-newsgroup-dormant article)))
(t
- (push article gnus-newsgroup-unreads)))
+ (setq gnus-newsgroup-unreads
+ (gnus-add-to-sorted-list gnus-newsgroup-unreads article))))
(gnus-pull article gnus-newsgroup-reads)
t)))
(gnus-data-enter
after-article gnus-reffed-article-number
gnus-unread-mark b (car pslist) 0 (- e b))
- (push gnus-reffed-article-number gnus-newsgroup-unreads)
+ (setq gnus-newsgroup-unreads
+ (gnus-add-to-sorted-list gnus-newsgroup-unreads
+ gnus-reffed-article-number))
(setq gnus-reffed-article-number (1- gnus-reffed-article-number))
(setq pslist (cdr pslist)))))))
If ALL is a number, fetch this number of articles."
(interactive "P")
(prog1
- (let ((old (mapcar 'car gnus-newsgroup-data))
+ (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
older len)
(setq older
(gnus-sorted-difference
(if (not older)
(message "No old news.")
(gnus-summary-insert-articles older)
- (gnus-summary-limit (gnus-sorted-union older old))))
+ (gnus-summary-limit (gnus-sorted-nunion old older))))
(gnus-summary-position-point)))
(defun gnus-summary-insert-new-articles ()
"Insert all new articles in this group."
(interactive)
(prog1
- (let ((old (mapcar 'car gnus-newsgroup-data))
+ (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
(old-active gnus-newsgroup-active)
(nnmail-fetched-sources (list t))
i new)
(setq new (nreverse new))
(gnus-summary-insert-articles new)
(setq gnus-newsgroup-unreads
- (append gnus-newsgroup-unreads new))
- (gnus-summary-limit (gnus-union old new))))
+ (gnus-sorted-nunion gnus-newsgroup-unreads new))
+ (gnus-summary-limit (gnus-sorted-nunion old new))))
(gnus-summary-position-point)))
(gnus-summary-make-all-marking-commands)
,@body))
(put 'mail-source-bind 'lisp-indent-function 1)
-(put 'mail-source-bind 'edebug-form-spec '(form body))
+(put 'mail-source-bind 'edebug-form-spec '(sexp body))
(defun mail-source-set-1 (source)
(let* ((type (pop source))
,@body))
(put 'mail-source-bind-common 'lisp-indent-function 1)
-(put 'mail-source-bind-common 'edebug-form-spec '(form body))
+(put 'mail-source-bind-common 'edebug-form-spec '(sexp body))
(defun mail-source-value (value)
"Return the value of VALUE."
(goto-char (point-min))
(if (not (looking-at "X-From-Line: "))
(insert "From nobody " (current-time-string) "\n")
- (save-match-data
- (mail-header-unfold-field))
- (replace-match "From "))
+ (replace-match "From ")
+ (forward-line 1)
+ (while (looking-at "[ \t]")
+ (delete-char -1)
+ (forward-line 1)))
(nnfolder-normalize-buffer)
(set-buffer nnfolder-current-buffer)
(goto-char (point-min))
\e$B$=$l$>$l$NMM<0$N:G=i$NMWAG$O\e(B @code{\e$B9gCW\e(B} (match) \e$B$H8F$P$l$^$9!#$b$7$=$l\e(B
\e$B$,J8;zNs$G$"$l$P!"\e(Bgnus \e$B$O$=$l$r%0%k!<%WL>$K@55,I=858=$H$7$F9gCWA`:n$r9T\e(B
-\e$B$$$^$9!#%7%s%\%k\e(B @code{header} \e$B$G$"$l$P!"\e(Bgnus \e$B$O85$N5-;v$NCf$+$i$=$N9gCW\e(B
-\e$B$NCf$N<!$NMWAG$K9gCW$9$k%X%C%@!<$rC5$7!"$=$l$r$=$N9gCW$N:G8e$N@55,I=858=\e(B
-\e$B$HHf3S$7$^$9!#$b$7$=$l$,4X?t$N%7%s%\%k$G$"$l$P!"$=$N4X?t$,0z?tL5$7$G8F$P\e(B
-\e$B$l$^$9!#$=$l$,JQ?t$N%7%s%\%k$G$"$l$P!"$=$NJQ?t$,;2>H$5$l$^$9!#$=$l$,%j%9\e(B
-\e$B%H$G$"$l$P!"$=$N%j%9%H$,\e(B @code{\e$BI>2A\e(B} \e$B$5$l$^$9!#$I$N>l9g$G$b!"$3$l\e(B
-\e$B$,\e(B @code{nil}\e$B$G$J$$CM$r5"$;$P!"MM<0$O\e(B @code{\e$B9gCW$7$?\e(B} \e$B$H8@$$$^$9!#\e(B
+\e$B$$$^$9!#\e(B@code{(header \e$B9gCW\e(B \e$B@55,I=8=\e(B)} \e$B$H$$$&MM<0$G$"$l$P!"\e(Bgnus \e$B$O85$N5-\e(B
+\e$B;v$NCf$+$iL>A0$,9gCW$9$k%X%C%@!<$rC5$7!"$=$l$r@55,I=85$HHf3S$7$^$9!#9gCW\e(B
+\e$B$H@55,I=8=$OJ8;zNs$G$9!#$b$7$=$l$,4X?t$N%7%s%\%k$G$"$l$P!"$=$N4X?t$,0z?t\e(B
+\e$BL5$7$G8F$P$l$^$9!#$=$l$,JQ?t$N%7%s%\%k$G$"$l$P!"$=$NJQ?t$,;2>H$5$l$^$9!#\e(B
+\e$B$=$l$,%j%9%H$G$"$l$P!"$=$N%j%9%H$,\e(B @code{\e$BI>2A\e(B} \e$B$5$l$^$9!#$I$N>l9g$G$b!"\e(B
+\e$B$3$l$,\e(B @code{nil}\e$B$G$J$$CM$r5"$;$P!"MM<0$O\e(B @code{\e$B9gCW$7$?\e(B} \e$B$H8@$$$^$9!#\e(B
\e$B$=$l$>$l$NMM<0$OG$0U$NNL$N\e(B @dfn{\e$BB0@-\e(B} \e$B$r;}$D;v$,$G$-$^$9!#$=$l$>$l$NB0@-\e(B
\e$B$O\e(B @code{(@var{name} @var{value})} \e$B$NBP$K$h$j@.$jN)$C$F$$$^$9!#B0@-L>\e(B
-\e$B$O!"\e(B@code{signature}, @code{signature-file}, @code{address} (\e$B%f!<%6!<$N\e(B
-\e$BEE;R%a!<%k%"%I%l%9\e(B), @code{name} (\e$B%f!<%6!<$NL>A0\e(B) \e$B$^$?$O\e(B @code{body} \e$B$N\e(B
-\e$B$I$l$+$G$"$k;v$,$G$-$^$9!#B0@-L>$OJ8;zNs$^$?$O%7%s%\%k$G$"$k;v$b$G$-$^$9!#\e(B
-\e$B$=$N>l9g$O!"$3$l$O%X%C%@!<L>$H$7$F;H$o$l!"$=$NCM$,5-;v$N%X%C%@!<$KA^F~$5\e(B
-\e$B$l$^$9!#$b$7B0@-L>$,\e(B @code{nil} \e$B$@$C$?$i$=$N%X%C%@!<L>$O:o=|$5$l$^$9!#$b\e(B
-\e$B$7B0@-L>$,\e(B @code{eval} \e$B$@$C$?$i$=$NMM<0$,I>2A$5$l!"7k2L$O<N$F$i$l$^$9!#\e(B
+\e$B$O!"\e(B@code{signature}, @code{signature-file}, @code{address}
+(@code{user-mail-address} \e$B$r>e=q$-$9$k\e(B), @code{name}
+(@code{(user-full-name) \e$B$r>e=q$-$9$k\e(B) \e$B$^$?$O\e(B @code{body} \e$B$N$I$l$+$G$"$k\e(B
+\e$B;v$,$G$-$^$9!#B0@-L>$OJ8;zNs$^$?$O%7%s%\%k$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"\e(B
+\e$B$3$l$O%X%C%@!<L>$H$7$F;H$o$l!"$=$NCM$,5-;v$N%X%C%@!<$KA^F~$5$l$^$9!#$b$7\e(B
+\e$BB0@-L>$,\e(B @code{nil} \e$B$@$C$?$i$=$N%X%C%@!<L>$O:o=|$5$l$^$9!#$b$7B0@-L>$,\e(B
+@code{eval} \e$B$@$C$?$i$=$NMM<0$,I>2A$5$l!"7k2L$O<N$F$i$l$^$9!#\e(B
\e$BB0@-CM$OJ8;zNs\e(B (\e$B$=$N$^$^;H$o$l$^$9\e(B)\e$B!"0z?t$NL5$$4X?t\e(B (\e$BJV$jCM$,;H$o$l$^$9\e(B)\e$B!"\e(B
\e$BJQ?t\e(B (\e$B$=$NCM$,;H$o$l$^$9\e(B) \e$B$^$?$O%j%9%H\e(B (\e$B$=$l$O\e(B @code{\e$BI>2A\e(B} \e$B$5$l$F!"JV$j\e(B
(organization "People's Front Against MWM"))
("^rec.humor"
(signature my-funny-signature-randomizer))
- ((equal (system-name) "gnarly") ;; s \e$B<0\e(B
+ ((equal (system-name) "gnarly") ;; \e$BMM<0\e(B
(signature my-quote-randomizer))
(message-news-p ;; \e$B4X?t%7%s%\%k\e(B
(signature my-news-signature))
(window-system ;; \e$BJQ?t%7%s%\%k\e(B
("X-Window-System" (format "%s" window-system)))
- ;; Larsi \e$B$5$s$KJV;v$r$9$k$H$-$O\e(B
+ ;; Lars \e$B$5$s$KJV;v$r$9$k$H$-$O\e(B
;; Organization \e$B%X%C%@!<$rIU$1$h$&!#\e(B
- (header "to" "larsi.*org"
- (Organization "Somewhere, Inc."))
+ ((header "to" "larsi.*org")
+ (Organization "Somewhere, Inc."))
((posting-from-work-p) ;; \e$B%f!<%6!<$,Dj5A$7$?4X?t\e(B
(signature-file "~/.work-signature")
(address "user@@bar.foo")
The first element in each style is called the @code{match}. If it's a
string, then Gnus will try to regexp match it against the group name.
-If it is the symbol @code{header}, then Gnus will look for header (the
-next element in the match) in the original article , and compare that to
-the last regexp in the match. If it's a function symbol, that function
-will be called with no arguments. If it's a variable symbol, then the
-variable will be referenced. If it's a list, then that list will be
-@code{eval}ed. In any case, if this returns a non-@code{nil} value,
-then the style is said to @dfn{match}.
-
-Each style may contain a arbitrary amount of @dfn{attributes}. Each
+If it is the form @code{(header MATCH REGEXP)}, then Gnus will look in
+the original article for a header whose name is MATCH and compare that
+REGEXP. MATCH and REGEXP are strings. If it's a function symbol, that
+function will be called with no arguments. If it's a variable symbol,
+then the variable will be referenced. If it's a list, then that list
+will be @code{eval}ed. In any case, if this returns a non-@code{nil}
+value, then the style is said to @dfn{match}.
+
+Each style may contain an arbitrary amount of @dfn{attributes}. Each
attribute consists of a @code{(@var{name} @var{value})} pair. The
attribute name can be one of @code{signature}, @code{signature-file},
-@code{address} (user email address), @code{name} (user name) or
-@code{body}. The attribute name can also be a string or a symbol. In
-that case, this will be used as a header name, and the value will be
-inserted in the headers of the article; if the value is @code{nil}, the
-header name will be removed. If the attribute name is @code{eval}, the
-form is evaluated, and the result is thrown away.
+@code{address} (overriding @code{user-mail-address}), @code{name}
+(overriding @code{(user-full-name)}) or @code{body}. The attribute name
+can also be a string or a symbol. In that case, this will be used as a
+header name, and the value will be inserted in the headers of the
+article; if the value is @code{nil}, the header name will be removed.
+If the attribute name is @code{eval}, the form is evaluated, and the
+result is thrown away.
The attribute value can be a string (used verbatim), a function with
zero arguments (the return value will be used), a variable (its value
(organization "People's Front Against MWM"))
("^rec.humor"
(signature my-funny-signature-randomizer))
- ((equal (system-name) "gnarly") ;; a sexp
+ ((equal (system-name) "gnarly") ;; A form
(signature my-quote-randomizer))
- (message-news-p ;; a function symbol
+ (message-news-p ;; A function symbol
(signature my-news-signature))
- (window-system ;; a value symbol
+ (window-system ;; A value symbol
("X-Window-System" (format "%s" window-system)))
;; If I'm replying to Larsi, set the Organization header.
- (header "to" "larsi.*org"
- (Organization "Somewhere, Inc."))
- ((posting-from-work-p) ;; a user defined function
+ ((header "to" "larsi.*org")
+ (Organization "Somewhere, Inc."))
+ ((posting-from-work-p) ;; A user defined function
(signature-file "~/.work-signature")
(address "user@@bar.foo")
(body "You are fired.\n\nSincerely, your boss.")