;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-;; Free Software Foundation, Inc.
+
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
(eval-when-compile
(require 'cl)
- (defvar tool-bar-map))
+ (defvar tool-bar-mode))
(require 'gnus)
(require 'gnus-group)
(require 'gnus-int)
(require 'gnus-undo)
(require 'gnus-util)
+(require 'gmm-utils)
(require 'mm-decode)
(require 'nnoo)
(defcustom gnus-fetch-old-headers nil
"*Non-nil means that Gnus will try to build threads by grabbing old headers.
-If an unread article in the group refers to an older, already read (or
-just marked as read) article, the old article will not normally be
-displayed in the Summary buffer. If this variable is t, Gnus
-will attempt to grab the headers to the old articles, and thereby
-build complete threads. If it has the value `some', only enough
-headers to connect otherwise loose threads will be displayed. This
-variable can also be a number. In that case, no more than that number
-of old headers will be fetched. If it has the value `invisible', all
+If an unread article in the group refers to an older, already
+read (or just marked as read) article, the old article will not
+normally be displayed in the Summary buffer. If this variable is
+t, Gnus will attempt to grab the headers to the old articles, and
+thereby build complete threads. If it has the value `some', all
+old headers will be fetched but only enough headers to connect
+otherwise loose threads will be displayed. This variable can
+also be a number. In that case, no more than that number of old
+headers will be fetched. If it has the value `invisible', all
old headers will be fetched, but none will be displayed.
-The server has to support NOV for any of this to work."
+The server has to support NOV for any of this to work.
+
+This feature can seriously impact performance it ignores all
+locally cached header entries."
:group 'gnus-thread
:type '(choice (const :tag "off" nil)
(const :tag "on" t)
number
(sexp :menu-tag "other" t)))
-(defcustom gnus-refer-thread-limit 200
+(defcustom gnus-refer-thread-limit 500
"*The number of old headers to fetch when doing \\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
If t, fetch all the available old headers."
:group 'gnus-thread
If this variable is `adopt', Gnus will make one of the \"children\"
the parent and mark all the step-children as such.
If this variable is `empty', the \"children\" are printed with empty
-subject fields. (Or rather, they will be printed with a string
+subject fields. (Or rather, they will be printed with a string
given by the `gnus-summary-same-subject' variable.)"
:group 'gnus-thread
:type '(choice (const :tag "off" nil)
(defcustom gnus-summary-make-false-root-always nil
"Always make a false dummy root."
- :version "21.4"
+ :version "22.1"
:group 'gnus-thread
:type 'boolean)
"*Default threshold for a high scored article.
An article will be highlighted as high scored if its score is greater
than this score."
- :version "21.4"
+ :version "22.1"
:group 'gnus-score-default
:type 'integer)
"*Default threshold for a low scored article.
An article will be highlighted as low scored if its score is smaller
than this score."
- :version "21.4"
+ :version "22.1"
:group 'gnus-score-default
:type 'integer)
"*If non-nil, hide all threads initially.
This can be a predicate specifier which says which threads to hide.
If threads are hidden, you have to run the command
-`gnus-summary-show-thread' by hand or use `gnus-select-article-hook'
-to expose hidden threads."
+`gnus-summary-show-thread' by hand or select an article."
:group 'gnus-thread
:type '(radio (sexp :format "Non-nil\n"
:match (lambda (widget value)
first subject), `unread' (place point on the subject line of the first
unread article), `best' (place point on the subject line of the
higest-scored article), `unseen' (place point on the subject line of
-the first unseen article), 'unseen-or-unread' (place point on the subject
+the first unseen article), `unseen-or-unread' (place point on the subject
line of the first unseen article or, if all article have been seen, on the
subject line of the first unread article), or a function to be called to
place point on some subject line."
- :version "21.4"
+ :version "22.1"
:group 'gnus-group-select
:type '(choice (const best)
(const unread)
NOTE: The list of unfetched articles will always be nil when plugged
and, when unplugged, a subset of the undownloaded article list."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-maneuvering
:type '(choice (const :tag "None" nil)
(const :tag "Undownloaded when unplugged" undownloaded)
(defcustom gnus-spam-mark ?$
"*Mark used for spam articles."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-marks
:type 'character)
(defcustom gnus-forwarded-mark ?F
"*Mark used for articles that have been forwarded."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-marks
:type 'character)
(defcustom gnus-recent-mark ?N
"*Mark used for articles that are recent."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-marks
:type 'character)
(defcustom gnus-unseen-mark ?.
"*Mark used for articles that haven't been seen."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-marks
:type 'character)
(defcustom gnus-no-mark ? ;Whitespace
"*Mark used for articles that have no other secondary mark."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-marks
:type 'character)
(defcustom gnus-undownloaded-mark ?-
"*Mark used for articles that weren't downloaded."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary-marks
:type 'character)
function; this specifies reversed sort order.
Ready-made functions include `gnus-thread-sort-by-number',
-`gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
-`gnus-thread-sort-by-date', `gnus-thread-sort-by-score',
-`gnus-thread-sort-by-most-recent-number',
-`gnus-thread-sort-by-most-recent-date',
-`gnus-thread-sort-by-random', and
-`gnus-thread-sort-by-total-score' (see `gnus-thread-score-function').
+`gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
+`gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
+`gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
+`gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
+and `gnus-thread-sort-by-total-score' (see
+`gnus-thread-score-function').
When threading is turned off, the variable
`gnus-article-sort-functions' controls how articles are sorted."
:group 'gnus-summary-sort
- :type '(repeat
+ :type '(repeat
(gnus-widget-reversible
(choice (function-item gnus-thread-sort-by-number)
(function-item gnus-thread-sort-by-author)
+ (function-item gnus-thread-sort-by-recipient)
(function-item gnus-thread-sort-by-subject)
(function-item gnus-thread-sort-by-date)
(function-item gnus-thread-sort-by-score)
(defcustom gnus-summary-article-move-hook nil
"*A hook called after an article is moved, copied, respooled, or crossposted."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary
:type 'hook)
(defcustom gnus-summary-article-delete-hook nil
"*A hook called after an article is deleted."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary
:type 'hook)
(defcustom gnus-summary-article-expire-hook nil
"*A hook called after an article is expired."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary
:type 'hook)
(and (fboundp 'display-graphic-p)
(display-graphic-p))
"*If non-nil, display an arrow highlighting the current article."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary
:type 'boolean)
-(defcustom gnus-summary-selected-face 'gnus-summary-selected-face
+(defcustom gnus-summary-selected-face 'gnus-summary-selected
"Face used for highlighting the current article in the summary buffer."
:group 'gnus-summary-visual
:type 'face)
(defcustom gnus-summary-highlight
'(((eq mark gnus-canceled-mark)
- . gnus-summary-cancelled-face)
+ . gnus-summary-cancelled)
((and uncached (> score default-high))
- . gnus-summary-high-undownloaded-face)
+ . gnus-summary-high-undownloaded)
((and uncached (< score default-low))
- . gnus-summary-low-undownloaded-face)
+ . gnus-summary-low-undownloaded)
(uncached
- . gnus-summary-normal-undownloaded-face)
+ . gnus-summary-normal-undownloaded)
((and (> score default-high)
(or (eq mark gnus-dormant-mark)
(eq mark gnus-ticked-mark)))
- . gnus-summary-high-ticked-face)
+ . gnus-summary-high-ticked)
((and (< score default-low)
(or (eq mark gnus-dormant-mark)
(eq mark gnus-ticked-mark)))
- . gnus-summary-low-ticked-face)
+ . gnus-summary-low-ticked)
((or (eq mark gnus-dormant-mark)
(eq mark gnus-ticked-mark))
- . gnus-summary-normal-ticked-face)
+ . gnus-summary-normal-ticked)
((and (> score default-high) (eq mark gnus-ancient-mark))
- . gnus-summary-high-ancient-face)
+ . gnus-summary-high-ancient)
((and (< score default-low) (eq mark gnus-ancient-mark))
- . gnus-summary-low-ancient-face)
+ . gnus-summary-low-ancient)
((eq mark gnus-ancient-mark)
- . gnus-summary-normal-ancient-face)
+ . gnus-summary-normal-ancient)
((and (> score default-high) (eq mark gnus-unread-mark))
- . gnus-summary-high-unread-face)
+ . gnus-summary-high-unread)
((and (< score default-low) (eq mark gnus-unread-mark))
- . gnus-summary-low-unread-face)
+ . gnus-summary-low-unread)
((eq mark gnus-unread-mark)
- . gnus-summary-normal-unread-face)
+ . gnus-summary-normal-unread)
((> score default-high)
- . gnus-summary-high-read-face)
+ . gnus-summary-high-read)
((< score default-low)
- . gnus-summary-low-read-face)
+ . gnus-summary-low-read)
(t
- . gnus-summary-normal-read-face))
+ . gnus-summary-normal-read))
"*Controls the highlighting of summary buffer lines.
A list of (FORM . FACE) pairs. When deciding how a a particular
:group 'gnus-summary)
(defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
- "Variable that says which function should be used to decode a string with encoded words.")
+ "Function used to decode a string with encoded words.")
+
+(defvar gnus-decode-encoded-address-function
+ 'mail-decode-encoded-address-string
+ "Function used to decode addresses with encoded words.")
(defcustom gnus-extra-headers '(To Newsgroups)
"*Extra headers to parse."
:type '(repeat symbol))
(defcustom gnus-ignored-from-addresses
- (and user-mail-address (regexp-quote user-mail-address))
+ (and user-mail-address
+ (not (string= user-mail-address ""))
+ (regexp-quote user-mail-address))
"*Regexp of From headers that may be suppressed in favor of To headers."
:version "21.1"
:group 'gnus-summary
:type 'regexp)
+(defcustom gnus-summary-to-prefix "-> "
+ "*String prefixed to the To field in the summary line when
+using `gnus-ignored-from-addresses'."
+ :version "22.1"
+ :group 'gnus-summary
+ :type 'string)
+
+(defcustom gnus-summary-newsgroup-prefix "=> "
+ "*String prefixed to the Newsgroup field in the summary
+line when using `gnus-ignored-from-addresses'."
+ :version "22.1"
+ :group 'gnus-summary
+ :type 'string)
+
(defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
"List of charsets that should be ignored.
When these charsets are used in the \"charset\" parameter, the
This is mostly relevant for slow back ends where the user may
wish to widen the summary buffer to include all headers
that were fetched. Say, for nnultimate groups."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary
:type '(choice boolean regexp))
(defcustom gnus-summary-muttprint-program "muttprint"
"Command (and optional arguments) used to run Muttprint."
- :version "21.4"
+ :version "22.1"
:group 'gnus-summary
:type 'string)
supply the MIME-Version header or deliberately strip it from the mail.
If non-nil (the default), Gnus will treat some articles as MIME
even if the MIME-Version header is missing."
- :version "21.4"
+ :version "22.1"
:type 'boolean
:group 'gnus-article-mime)
This means that Gnus will search message bodies for text that look
like uuencoded bits, yEncoded bits, and so on, and present that using
the normal Gnus MIME machinery."
- :version "21.4"
+ :version "22.1"
:type 'boolean
:group 'gnus-article-mime)
(defvar gnus-newsgroup-last-mail nil)
(defvar gnus-newsgroup-last-folder nil)
(defvar gnus-newsgroup-last-file nil)
+(defvar gnus-newsgroup-last-directory nil)
(defvar gnus-newsgroup-auto-expire nil)
(defvar gnus-newsgroup-active nil)
gnus-newsgroup-begin gnus-newsgroup-end
gnus-newsgroup-last-rmail gnus-newsgroup-last-mail
gnus-newsgroup-last-folder gnus-newsgroup-last-file
+ gnus-newsgroup-last-directory
gnus-newsgroup-auto-expire gnus-newsgroup-unreads
gnus-newsgroup-unselected gnus-newsgroup-marked
gnus-newsgroup-spam-marked
"," gnus-summary-best-unread-article
"\M-s" gnus-summary-search-article-forward
"\M-r" gnus-summary-search-article-backward
+ "\M-S" gnus-summary-repeat-search-article-forward
+ "\M-R" gnus-summary-repeat-search-article-backward
"<" gnus-summary-beginning-of-article
">" gnus-summary-end-of-article
"j" gnus-summary-goto-article
"Q" gnus-summary-exit-no-update
"\C-c\C-i" gnus-info-find-node
gnus-mouse-2 gnus-mouse-pick-article
+ [follow-link] mouse-face
"m" gnus-summary-mail-other-window
"a" gnus-summary-post-news
"i" gnus-summary-news-other-window
(gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
"/" gnus-summary-limit-to-subject
"n" gnus-summary-limit-to-articles
+ "b" gnus-summary-limit-to-bodies
+ "h" gnus-summary-limit-to-headers
"w" gnus-summary-pop-limit
"s" gnus-summary-limit-to-subject
"a" gnus-summary-limit-to-author
"T" gnus-summary-toggle-threads
"t" gnus-summary-rethread-current
"^" gnus-summary-reparent-thread
+ "\M-^" gnus-summary-reparent-children
"s" gnus-summary-show-thread
"S" gnus-summary-show-all-threads
"h" gnus-summary-hide-thread
"Q" gnus-summary-exit
"Z" gnus-summary-exit
"n" gnus-summary-catchup-and-goto-next-group
+ "p" gnus-summary-catchup-and-goto-prev-group
"R" gnus-summary-reselect-current-group
"G" gnus-summary-rescan-group
"N" gnus-summary-next-group
"e" gnus-article-emphasize
"w" gnus-article-fill-cited-article
"Q" gnus-article-fill-long-lines
+ "L" gnus-article-toggle-truncate-lines
"C" gnus-article-capitalize-sentences
"c" gnus-article-remove-cr
"q" gnus-article-de-quoted-unreadable
"v" gnus-summary-verbose-headers
"a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
"p" gnus-article-verify-x-pgp-sig
- "d" gnus-article-treat-dumbquotes)
+ "d" gnus-article-treat-dumbquotes
+ "i" gnus-summary-idna-message)
(gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
;; mnemonic: deuglif*Y*
"r" gnus-summary-save-article-rmail
"f" gnus-summary-save-article-file
"b" gnus-summary-save-article-body-file
+ "B" gnus-summary-write-article-body-file
"h" gnus-summary-save-article-folder
"v" gnus-summary-save-article-vm
"p" gnus-summary-pipe-output
"m" gnus-summary-repair-multipart
"v" gnus-article-view-part
"o" gnus-article-save-part
+ "O" gnus-article-save-part-and-strip
+ "r" gnus-article-replace-part
+ "d" gnus-article-delete-part
+ "t" gnus-article-view-part-as-type
+ "j" gnus-article-jump-to-part
"c" gnus-article-copy-part
"C" gnus-article-view-part-as-charset
"e" gnus-article-view-part-externally
+ "H" gnus-article-browse-html-article
"E" gnus-article-encrypt-body
"i" gnus-article-inline-part
"|" gnus-article-pipe-part)
["Repair multipart" gnus-summary-repair-multipart t]
["Pipe part..." gnus-article-pipe-part t]
["Inline part" gnus-article-inline-part t]
+ ["View part as type..." gnus-article-view-part-as-type t]
["Encrypt body" gnus-article-encrypt-body
:active (not (gnus-group-read-only-p))
,@(if (featurep 'xemacs) nil
'(:help "Encrypt the message body on disk"))]
["View part externally" gnus-article-view-part-externally t]
+ ["View HTML parts in browser" gnus-article-browse-html-article t]
["View part with charset..." gnus-article-view-part-as-charset t]
["Copy part" gnus-article-copy-part t]
["Save part..." gnus-article-save-part t]
["Emphasis" gnus-article-emphasize t]
["Word wrap" gnus-article-fill-cited-article t]
["Fill long lines" gnus-article-fill-long-lines t]
+ ["Toggle truncate long lines" gnus-article-toggle-truncate-lines t]
["Capitalize sentences" gnus-article-capitalize-sentences t]
["Remove CR" gnus-article-remove-cr t]
["Quoted-Printable" gnus-article-de-quoted-unreadable t]
["Rot 13" gnus-summary-caesar-message
,@(if (featurep 'xemacs) '(t)
'(:help "\"Caesar rotate\" article by 13"))]
+ ["De-IDNA" gnus-summary-idna-message t]
["Morse decode" gnus-summary-morse-message t]
["Unix pipe..." gnus-summary-pipe-message t]
["Add buttons" gnus-article-add-buttons t]
["Unseen" gnus-summary-limit-to-unseen t]
["Replied" gnus-summary-limit-to-replied t]
["Non-dormant" gnus-summary-limit-exclude-dormant t]
- ["Next articles" gnus-summary-limit-to-articles t]
+ ["Next or process marked articles" gnus-summary-limit-to-articles t]
["Pop limit" gnus-summary-pop-limit t]
["Show dormant" gnus-summary-limit-include-dormant t]
["Hide childless dormant"
'(:help "Mark unread articles in this group as read, then exit"))]
["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
+ ["Catchup and goto prev" gnus-summary-catchup-and-goto-prev-group t]
["Exit group" gnus-summary-exit
,@(if (featurep 'xemacs) '(t)
'(:help "Exit current group, return to group selection mode"))]
(defvar gnus-summary-tool-bar-map nil)
-;; Emacs 21 tool bar. Should be no-op otherwise.
-(defun gnus-summary-make-tool-bar ()
- (if (and (fboundp 'tool-bar-add-item-from-menu)
- (default-value 'tool-bar-mode)
- (not gnus-summary-tool-bar-map))
- (setq gnus-summary-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap))
- (load-path (mm-image-load-path)))
- (tool-bar-add-item-from-menu
- 'gnus-summary-prev-unread "prev-ur" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-next-unread "next-ur" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-post-news "post" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-followup-with-original "fuwo" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-followup "followup" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-reply-with-original "reply-wo" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-reply "reply" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-caesar-message "rot13" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-uu-decode-uu "uu-decode" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-save-article-file "save-aif" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-save-article "save-art" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-uu-post-news "uu-post" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-uu-post-news "uu-post" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-catchup "catchup" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-catchup-and-exit "cu-exit" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-exit "exit-summ" gnus-summary-mode-map)
- tool-bar-map)))
- (if gnus-summary-tool-bar-map
- (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map)))
+;; Note: The :set function in the `gnus-summary-tool-bar*' variables will only
+;; affect _new_ message buffers. We might add a function that walks thru all
+;; summary-mode buffers and force the update.
+(defun gnus-summary-tool-bar-update (&optional symbol value)
+ "Update summary mode toolbar.
+Setter function for custom variables."
+ (setq-default gnus-summary-tool-bar-map nil)
+ (when symbol
+ ;; When used as ":set" function:
+ (set-default symbol value))
+ (when (gnus-buffer-live-p gnus-summary-buffer)
+ (with-current-buffer gnus-summary-buffer
+ (gnus-summary-make-tool-bar))))
+
+(defcustom gnus-summary-tool-bar (if (eq gmm-tool-bar-style 'gnome)
+ 'gnus-summary-tool-bar-gnome
+ 'gnus-summary-tool-bar-retro)
+ "Specifies the Gnus summary tool bar.
+
+It can be either a list or a symbol refering to a list. See
+`gmm-tool-bar-from-list' for the format of the list. The
+default key map is `gnus-summary-mode-map'.
+
+Pre-defined symbols include `gnus-summary-tool-bar-gnome' and
+`gnus-summary-tool-bar-retro'."
+ :type '(choice (const :tag "GNOME style" gnus-summary-tool-bar-gnome)
+ (const :tag "Retro look" gnus-summary-tool-bar-retro)
+ (repeat :tag "User defined list" gmm-tool-bar-item)
+ (symbol))
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defcustom gnus-summary-tool-bar-gnome
+ '((gnus-summary-post-news "mail/compose" nil)
+ (gnus-summary-insert-new-articles "mail/inbox" nil
+ :visible (or (not gnus-agent)
+ gnus-plugged))
+ (gnus-summary-reply-with-original "mail/reply")
+ (gnus-summary-reply "mail/reply" nil :visible nil)
+ (gnus-summary-followup-with-original "mail/reply-all")
+ (gnus-summary-followup "mail/reply-all" nil :visible nil)
+ (gnus-summary-mail-forward "mail/forward")
+ (gnus-summary-save-article "mail/save")
+ (gnus-summary-search-article-forward "search" nil :visible nil)
+ (gnus-summary-print-article "print")
+ (gnus-summary-tick-article-forward "flag-followup" nil :visible nil)
+ ;; Some new commands that may need more suitable icons:
+ (gnus-summary-save-newsrc "save" nil :visible nil)
+ ;; (gnus-summary-show-article "stock_message-display" nil :visible nil)
+ (gnus-summary-prev-article "left-arrow")
+ (gnus-summary-next-article "right-arrow")
+ (gnus-summary-next-page "next-page")
+ ;; (gnus-summary-enter-digest-group "right_arrow" nil :visible nil)
+ ;;
+ ;; Maybe some sort-by-... could be added:
+ ;; (gnus-summary-sort-by-author "sort-a-z" nil :visible nil)
+ ;; (gnus-summary-sort-by-date "sort-1-9" nil :visible nil)
+ (gnus-summary-mark-as-expirable
+ "delete" nil
+ :visible (gnus-check-backend-function 'request-expire-articles
+ gnus-newsgroup-name))
+ (gnus-summary-mark-as-spam
+ "mail/spam" t
+ :visible (and (fboundp 'spam-group-ham-contents-p)
+ (spam-group-ham-contents-p gnus-newsgroup-name))
+ :help "Mark as spam")
+ (gnus-summary-mark-as-read-forward
+ "mail/not-spam" nil
+ :visible (and (fboundp 'spam-group-spam-contents-p)
+ (spam-group-spam-contents-p gnus-newsgroup-name)))
+ ;;
+ (gnus-summary-exit "exit")
+ (gmm-customize-mode "preferences" t :help "Edit mode preferences")
+ (gnus-info-find-node "help"))
+ "List of functions for the summary tool bar (GNOME style).
+
+See `gmm-tool-bar-from-list' for the format of the list."
+ :type '(repeat gmm-tool-bar-item)
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defcustom gnus-summary-tool-bar-retro
+ '((gnus-summary-prev-unread-article "gnus/prev-ur")
+ (gnus-summary-next-unread-article "gnus/next-ur")
+ (gnus-summary-post-news "gnus/post")
+ (gnus-summary-followup-with-original "gnus/fuwo")
+ (gnus-summary-followup "gnus/followup")
+ (gnus-summary-reply-with-original "gnus/reply-wo")
+ (gnus-summary-reply "gnus/reply")
+ (gnus-summary-caesar-message "gnus/rot13")
+ (gnus-uu-decode-uu "gnus/uu-decode")
+ (gnus-summary-save-article-file "gnus/save-aif")
+ (gnus-summary-save-article "gnus/save-art")
+ (gnus-uu-post-news "gnus/uu-post")
+ (gnus-summary-catchup "gnus/catchup")
+ (gnus-summary-catchup-and-exit "gnus/cu-exit")
+ (gnus-summary-exit "gnus/exit-summ")
+ ;; Some new command that may need more suitable icons:
+ (gnus-summary-print-article "gnus/print" nil :visible nil)
+ (gnus-summary-mark-as-expirable "gnus/close" nil :visible nil)
+ (gnus-summary-save-newsrc "gnus/save" nil :visible nil)
+ ;; (gnus-summary-enter-digest-group "gnus/right_arrow" nil :visible nil)
+ (gnus-summary-search-article-forward "gnus/search" nil :visible nil)
+ ;; (gnus-summary-insert-new-articles "gnus/paste" nil :visible nil)
+ ;; (gnus-summary-toggle-threads "gnus/open" nil :visible nil)
+ ;;
+ (gnus-info-find-node "gnus/help" nil :visible nil))
+ "List of functions for the summary tool bar (retro look).
+
+See `gmm-tool-bar-from-list' for the format of the list."
+ :type '(repeat gmm-tool-bar-item)
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defcustom gnus-summary-tool-bar-zap-list t
+ "List of icon items from the global tool bar.
+These items are not displayed in the Gnus summary mode tool bar.
+
+See `gmm-tool-bar-from-list' for the format of the list."
+ :type 'gmm-tool-bar-zap-list
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defvar image-load-path)
+
+(defun gnus-summary-make-tool-bar (&optional force)
+ "Make a summary mode tool bar from `gnus-summary-tool-bar'.
+When FORCE, rebuild the tool bar."
+ (when (and (not (featurep 'xemacs))
+ (boundp 'tool-bar-mode)
+ tool-bar-mode
+ (or (not gnus-summary-tool-bar-map) force))
+ (let* ((load-path
+ (gmm-image-load-path-for-library "gnus"
+ "mail/save.xpm"
+ nil t))
+ (image-load-path (cons (car load-path)
+ (when (boundp 'image-load-path)
+ image-load-path)))
+ (map (gmm-tool-bar-from-list gnus-summary-tool-bar
+ gnus-summary-tool-bar-zap-list
+ 'gnus-summary-mode-map)))
+ (when map
+ ;; Need to set `gnus-summary-tool-bar-map' because `gnus-article-mode'
+ ;; uses it's value.
+ (setq gnus-summary-tool-bar-map map))))
+ (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map))
(defun gnus-score-set-default (var value)
"A version of set that updates the GNU Emacs menu-bar."
\\{gnus-summary-mode-map}"
(interactive)
(kill-all-local-variables)
+ (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+ (gnus-summary-make-local-variables))
+ (gnus-summary-make-local-variables)
+ (setq gnus-newsgroup-name group)
(when (gnus-visual-p 'summary-menu 'menu)
(gnus-summary-make-menu-bar)
(gnus-summary-make-tool-bar))
- (gnus-summary-make-local-variables)
- (let ((gnus-summary-local-variables gnus-newsgroup-variables))
- (gnus-summary-make-local-variables))
(gnus-make-thread-indent-array)
(gnus-simplify-mode-line)
(setq major-mode 'gnus-summary-mode)
(setq selective-display-ellipses t) ;Display `...'
(gnus-summary-set-display-table)
(gnus-set-default-directory)
- (setq gnus-newsgroup-name group)
(make-local-variable 'gnus-summary-line-format)
(make-local-variable 'gnus-summary-line-format-spec)
(make-local-variable 'gnus-summary-dummy-line-format)
(make-local-variable 'gnus-summary-mark-positions)
(gnus-make-local-hook 'pre-command-hook)
(add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
- (gnus-run-hooks 'gnus-summary-mode-hook)
+ (gnus-run-mode-hooks 'gnus-summary-mode-hook)
(turn-on-gnus-mailing-list-mode)
(mm-enable-multibyte)
(gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
(aset table ?\r nil)
;; We keep TAB as well.
(aset table ?\t nil)
- ;; We nix out any glyphs over 126 that are not set already.
- (let ((i 256))
+ ;; We nix out any glyphs 127 through 255, or 127 through 159 in
+ ;; Emacs 23 (unicode), that are not set already.
+ (let ((i (if (ignore-errors (= (make-char 'latin-iso8859-1 160) 160))
+ 160
+ 256)))
(while (>= (setq i (1- i)) 127)
;; Only modify if the entry is nil.
(unless (aref table i)
(gnus-summary-mode group)
(when gnus-carpal
(gnus-carpal-setup-buffer 'summary))
- (unless gnus-single-article-buffer
- (make-local-variable 'gnus-article-buffer)
- (make-local-variable 'gnus-article-current)
- (make-local-variable 'gnus-original-article-buffer))
+ (when (gnus-group-quit-config group)
+ (set (make-local-variable 'gnus-single-article-buffer) nil))
+ (make-local-variable 'gnus-article-buffer)
+ (make-local-variable 'gnus-article-current)
+ (make-local-variable 'gnus-original-article-buffer)
(setq gnus-newsgroup-name group)
;; Set any local variables in the group parameters.
(gnus-summary-set-local-parameters gnus-newsgroup-name)
t
(not (cdr (gnus-data-find-list article)))))
-(defun gnus-make-thread-indent-array ()
- (let ((n 200))
- (unless (and gnus-thread-indent-array
- (= gnus-thread-indent-level gnus-thread-indent-array-level))
- (setq gnus-thread-indent-array (make-vector 201 "")
- gnus-thread-indent-array-level gnus-thread-indent-level)
- (while (>= n 0)
- (aset gnus-thread-indent-array n
- (make-string (* n gnus-thread-indent-level) ? ))
- (setq n (1- n))))))
+(defun gnus-make-thread-indent-array (&optional n)
+ (when (or n
+ (progn (setq n 200) nil)
+ (null gnus-thread-indent-array)
+ (/= gnus-thread-indent-level gnus-thread-indent-array-level))
+ (setq gnus-thread-indent-array (make-vector (1+ n) "")
+ gnus-thread-indent-array-level gnus-thread-indent-level)
+ (while (>= n 0)
+ (aset gnus-thread-indent-array n
+ (make-string (* n gnus-thread-indent-level) ?\s))
+ (setq n (1- n)))))
(defun gnus-update-summary-mark-positions ()
"Compute where the summary marks are to go."
newsgroups)
(cond
((setq to (cdr (assq 'To extra-headers)))
- (concat "-> "
+ (concat gnus-summary-to-prefix
(inline
(gnus-summary-extract-address-component
- (funcall gnus-decode-encoded-word-function to)))))
- ((setq newsgroups (cdr (assq 'Newsgroups extra-headers)))
- (concat "=> " newsgroups)))))
+ (funcall gnus-decode-encoded-address-function to)))))
+ ((setq newsgroups
+ (or
+ (cdr (assq 'Newsgroups extra-headers))
+ (and
+ (memq 'Newsgroups gnus-extra-headers)
+ (eq (car (gnus-find-method-for-group
+ gnus-newsgroup-name)) 'nntp)
+ (gnus-group-real-name gnus-newsgroup-name))))
+ (concat gnus-summary-newsgroup-prefix newsgroups)))))
(inline (gnus-summary-extract-address-component gnus-tmp-from)))))
(defun gnus-summary-insert-line (gnus-tmp-header
gnus-tmp-expirable gnus-tmp-subject-or-nil
&optional gnus-tmp-dummy gnus-tmp-score
gnus-tmp-process)
+ (if (>= gnus-tmp-level (length gnus-thread-indent-array))
+ (gnus-make-thread-indent-array (max (* 2 (length gnus-thread-indent-array))
+ gnus-tmp-level)))
(let* ((gnus-tmp-indentation (aref gnus-thread-indent-array gnus-tmp-level))
(gnus-tmp-lines (mail-header-lines gnus-tmp-header))
(gnus-tmp-score (or gnus-tmp-score gnus-summary-default-score 0))
infloop))
(defun gnus-make-threads ()
- "Go through the dependency hashtb and find the roots. Return all threads."
+ "Go through the dependency hashtb and find the roots. Return all threads."
(let (threads)
(while (catch 'infloop
(mapatoms
(error x))
(condition-case () ; from
(gnus-remove-odd-characters
- (funcall gnus-decode-encoded-word-function
+ (funcall gnus-decode-encoded-address-function
(setq x (nnheader-nov-field))))
(error x))
(nnheader-nov-field) ; date
;; First go up in this thread until we find the root.
(setq last-id (gnus-root-id id)
headers (message-flatten-list (gnus-id-to-thread last-id)))
- ;; We have now found the real root of this thread. It might have
+ ;; We have now found the real root of this thread. It might have
;; been gathered into some loose thread, so we have to search
;; through the threads to find the thread we wanted.
(let ((threads gnus-newsgroup-threads)
(1+ (point-at-eol))
(gnus-delete-line)))))))
-(defun gnus-sort-threads-1 (threads func)
+(defun gnus-sort-threads-recursive (threads func)
(sort (mapcar (lambda (thread)
(cons (car thread)
(and (cdr thread)
- (gnus-sort-threads-1 (cdr thread) func))))
+ (gnus-sort-threads-recursive (cdr thread) func))))
threads) func))
+(defun gnus-sort-threads-loop (threads func)
+ (let* ((superthread (cons nil threads))
+ (stack (list (cons superthread threads)))
+ remaining-threads thread)
+ (while stack
+ (setq remaining-threads (cdr (car stack)))
+ (if remaining-threads
+ (progn (setq thread (car remaining-threads))
+ (setcdr (car stack) (cdr remaining-threads))
+ (if (cdr thread)
+ (push (cons thread (cdr thread)) stack)))
+ (setq thread (caar stack))
+ (setcdr thread (sort (cdr thread) func))
+ (pop stack)))
+ (cdr superthread)))
+
(defun gnus-sort-threads (threads)
"Sort THREADS."
(if (not gnus-thread-sort-functions)
threads
(gnus-message 8 "Sorting threads...")
- (let ((max-lisp-eval-depth 5000))
- (prog1 (gnus-sort-threads-1
- threads
- (gnus-make-sort-function gnus-thread-sort-functions))
- (gnus-message 8 "Sorting threads...done")))))
+ (prog1
+ (condition-case nil
+ (let ((max-lisp-eval-depth (max max-lisp-eval-depth 5000)))
+ (gnus-sort-threads-recursive
+ threads (gnus-make-sort-function gnus-thread-sort-functions)))
+ ;; Even after binding max-lisp-eval-depth, the recursive
+ ;; sorter might fail for very long threads. In that case,
+ ;; try using a (less well-tested) non-recursive sorter.
+ (error (gnus-sort-threads-loop
+ threads (gnus-make-sort-function
+ gnus-thread-sort-functions))))
+ (gnus-message 8 "Sorting threads...done"))))
(defun gnus-sort-articles (articles)
"Sort ARTICLES."
(or (cdr (assq 'To (mail-header-extra h2))) ""))))
(or (car extract) (cadr extract)))))
+(defun gnus-thread-sort-by-recipient (h1 h2)
+ "Sort threads by root recipient."
+ (gnus-article-sort-by-recipient
+ (gnus-thread-header h1) (gnus-thread-header h2)))
+
(defsubst gnus-article-sort-by-subject (h1 h2)
"Sort articles by root subject."
(string-lessp
(defcustom gnus-sum-thread-tree-root "> "
"With %B spec, used for the root of a thread.
If nil, use subject instead."
- :version "21.4"
+ :version "22.1"
:type '(radio (const :format "%v " nil) string)
:group 'gnus-thread)
+
(defcustom gnus-sum-thread-tree-false-root "> "
"With %B spec, used for a false root of a thread.
If nil, use subject instead."
- :version "21.4"
+ :version "22.1"
:type '(radio (const :format "%v " nil) string)
:group 'gnus-thread)
+
(defcustom gnus-sum-thread-tree-single-indent ""
"With %B spec, used for a thread with just one message.
If nil, use subject instead."
- :version "21.4"
+ :version "22.1"
:type '(radio (const :format "%v " nil) string)
:group 'gnus-thread)
+
(defcustom gnus-sum-thread-tree-vertical "| "
"With %B spec, used for drawing a vertical line."
- :version "21.4"
+ :version "22.1"
:type 'string
:group 'gnus-thread)
+
(defcustom gnus-sum-thread-tree-indent " "
"With %B spec, used for indenting."
- :version "21.4"
+ :version "22.1"
:type 'string
:group 'gnus-thread)
+
(defcustom gnus-sum-thread-tree-leaf-with-other "+-> "
"With %B spec, used for a leaf with brothers."
- :version "21.4"
+ :version "22.1"
:type 'string
:group 'gnus-thread)
+
(defcustom gnus-sum-thread-tree-single-leaf "\\-> "
"With %B spec, used for a leaf without brothers."
- :version "21.4"
+ :version "22.1"
:type 'string
:group 'gnus-thread)
gnus-tmp-closing-bracket ?\>)
(setq gnus-tmp-opening-bracket ?\[
gnus-tmp-closing-bracket ?\]))
+ (if (>= gnus-tmp-level (length gnus-thread-indent-array))
+ (gnus-make-thread-indent-array
+ (max (* 2 (length gnus-thread-indent-array))
+ gnus-tmp-level)))
(setq
gnus-tmp-indentation
(aref gnus-thread-indent-array gnus-tmp-level)
(when (equal major-mode 'gnus-summary-mode)
(gnus-kill-buffer (current-buffer)))
(error "Couldn't activate group %s: %s"
- group (gnus-status-message group))))
+ (gnus-group-decoded-name group) (gnus-status-message group))))
(unless (gnus-request-group group t)
(when (equal major-mode 'gnus-summary-mode)
(gnus-kill-buffer (current-buffer)))
(error "Couldn't request group %s: %s"
- group (gnus-status-message group)))
+ (gnus-group-decoded-name group) (gnus-status-message group)))
(when gnus-agent
(gnus-agent-possibly-alter-active group (gnus-active group) info)
-
+
(setq gnus-summary-use-undownloaded-faces
(gnus-agent-find-parameter
group
(setq gnus-newsgroup-auto-expire
(gnus-group-auto-expirable-p group))
;; Set up the article buffer now, if necessary.
- (unless gnus-single-article-buffer
+ (unless (and gnus-single-article-buffer
+ (equal gnus-article-buffer "*Article*"))
(gnus-article-setup-buffer))
;; First and last article in this newsgroup.
(when gnus-newsgroup-headers
(let* ((mformat (symbol-value
(intern
(format "gnus-%s-mode-line-format-spec" where))))
- (gnus-tmp-group-name (gnus-group-decoded-name
- gnus-newsgroup-name))
+ (gnus-tmp-group-name (gnus-mode-string-quote
+ (gnus-group-decoded-name
+ gnus-newsgroup-name)))
(gnus-tmp-article-number (or gnus-current-article 0))
(gnus-tmp-unread gnus-newsgroup-unreads)
(gnus-tmp-unread-and-unticked (length gnus-newsgroup-unreads))
(match-end 1)))
(substring xrefs (match-beginning 1) (match-end 1))))
(setq number
- (string-to-int (substring xrefs (match-beginning 2)
+ (string-to-number (substring xrefs (match-beginning 2)
(match-end 2))))
(if (setq entry (gnus-gethash group xref-hashtb))
(setcdr entry (cons number (cdr entry)))
(let ((case-fold-search t)
in-reply-to header p lines chars)
(goto-char (point-min))
- ;; Search to the beginning of the next header. Error messages
+ ;; Search to the beginning of the next header. Error messages
;; do not begin with 2 or 3.
(while (re-search-forward "^[23][0-9]+ " nil t)
(setq id nil
;; This implementation of this function, with nine
;; search-forwards instead of the one re-search-forward and
;; a case (which basically was the old function) is actually
- ;; about twice as fast, even though it looks messier. You
+ ;; about twice as fast, even though it looks messier. You
;; can't have everything, I guess. Speed and elegance
;; doesn't always go hand in hand.
(setq
(progn
(goto-char p)
(if (search-forward "\nfrom:" nil t)
- (funcall gnus-decode-encoded-word-function
+ (funcall gnus-decode-encoded-address-function
(nnheader-header-value))
"(nobody)"))
;; Date.
(allp (cond
((eq gnus-read-all-available-headers t)
t)
- ((stringp gnus-read-all-available-headers)
+ ((and (stringp gnus-read-all-available-headers)
+ group)
(string-match gnus-read-all-available-headers group))
(t
nil)))
(let ((max (max (point) (mark)))
articles article)
(save-excursion
- (goto-char (min (min (point) (mark))))
+ (goto-char (min (point) (mark)))
(while
(and
(push (setq article (gnus-summary-article-number)) articles)
;; possible valid number, or the second line from the top,
;; whichever is the least.
(let ((top-pos (save-excursion (forward-line (- top)) (point))))
+ (message "%s" top-pos)
(if (> bottom top-pos)
;; Keep the second line from the top visible
- (set-window-start window top-pos t)
+ (set-window-start window top-pos)
;; Try to keep the bottom line visible; if it's partially
;; obscured, either scroll one more line to make it fully
;; visible, or revert to using TOP-POS.
(defun gnus-list-of-unread-articles (group)
(let* ((read (gnus-info-read (gnus-get-info group)))
(active (or (gnus-active group) (gnus-activate-group group)))
- (last (cdr active))
+ (last (or (cdr active)
+ (error "Group %s couldn't be activated " group)))
first nlast unread)
;; If none are read, then all are unread.
(if (not read)
(setq nlast (if (atom (cadr read)) (cadr read) (caadr read)))
(setq read (cdr read)))))
;; And add the last unread articles.
- (cond ((< first last)
- (push (cons first last) unread))
- ((= first last)
- (push first unread)))
+ (cond ((not (and first last))
+ nil)
+ ((< first last)
+ (push (cons first last) unread))
+ ((= first last)
+ (push first unread)))
;; Return the sequence of unread articles.
(delq 0 (nreverse unread))))
(gnus-run-hooks 'gnus-summary-prepare-exit-hook)
;; If we have several article buffers, we kill them at exit.
(unless gnus-single-article-buffer
+ (gnus-kill-buffer gnus-article-buffer)
(gnus-kill-buffer gnus-original-article-buffer)
(setq gnus-article-current nil))
(when gnus-use-cache
(gnus-summary-clear-local-variables))
(when (get-buffer gnus-article-buffer)
(bury-buffer gnus-article-buffer))
- ;; We clear the global counterparts of the buffer-local
- ;; variables as well, just to be on the safe side.
- (set-buffer gnus-group-buffer)
- (gnus-summary-clear-local-variables)
- (let ((gnus-summary-local-variables gnus-newsgroup-variables))
- (gnus-summary-clear-local-variables))
;; Return to group mode buffer.
(when (eq mode 'gnus-summary-mode)
(gnus-kill-buffer buf)))
(setq gnus-current-select-method gnus-select-method)
- (if leave-hidden
- (set-buffer gnus-group-buffer)
- (pop-to-buffer gnus-group-buffer))
- (if (not quit-config)
- (progn
- (goto-char group-point)
- (unless leave-hidden
- (gnus-configure-windows 'group 'force)))
- (gnus-handle-ephemeral-exit quit-config))
+ (set-buffer gnus-group-buffer)
+ (if quit-config
+ (gnus-handle-ephemeral-exit quit-config)
+ (goto-char group-point)
+ ;; If gnus-group-buffer is already displayed, make sure we also move
+ ;; the cursor in the window that displays it.
+ (let ((win (get-buffer-window (current-buffer) 0)))
+ (if win (set-window-point win (point))))
+ (unless leave-hidden
+ (gnus-configure-windows 'group 'force)))
;; Clear the current group name.
(unless quit-config
(setq gnus-newsgroup-name nil)))))
(gnus-deaden-summary)
(gnus-close-group group)
(gnus-summary-clear-local-variables)
- (let ((gnus-summary-local-variables gnus-newsgroup-variables))
- (gnus-summary-clear-local-variables))
- (set-buffer gnus-group-buffer)
- (gnus-summary-clear-local-variables)
(let ((gnus-summary-local-variables gnus-newsgroup-variables))
(gnus-summary-clear-local-variables))
(gnus-kill-buffer gnus-summary-buffer))
(gnus-set-global-variables))))
(if (or (eq (cdr quit-config) 'article)
(eq (cdr quit-config) 'pick))
- (progn
- ;; The current article may be from the ephemeral group
- ;; thus it is best that we reload this article
- ;;
- ;; If we're exiting from a large digest, this can be
- ;; extremely slow. So, it's better not to reload it. -- jh.
- ;;(gnus-summary-show-article)
- (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode))
- (gnus-configure-windows 'pick 'force)
- (gnus-configure-windows (cdr quit-config) 'force)))
+ (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode))
+ (gnus-configure-windows 'pick 'force)
+ (gnus-configure-windows (cdr quit-config) 'force))
(gnus-configure-windows (cdr quit-config) 'force))
(when (eq major-mode 'gnus-summary-mode)
- (gnus-summary-next-subject 1 nil t)
(gnus-summary-recenter)
(gnus-summary-position-point))))
(gnus-summary-goto-subject article t)))
(gnus-summary-limit (append articles gnus-newsgroup-limit))
(gnus-summary-position-point))
-
+
(defun gnus-summary-goto-subject (article &optional force silent)
"Go the subject line of ARTICLE.
If FORCE, also allow jumping to articles not currently shown."
(if (and group
(not (gnus-ephemeral-group-p gnus-newsgroup-name)))
(format " (Type %s for %s [%s])"
- (single-key-description cmd) group
+ (single-key-description cmd)
+ (gnus-group-decoded-name group)
(gnus-group-unread group))
(format " (Type %s to exit %s)"
(single-key-description cmd)
- gnus-newsgroup-name))))
+ (gnus-group-decoded-name gnus-newsgroup-name)))))
;; Confirm auto selection.
(setq key (car (setq keve (gnus-read-event-char prompt)))
ended t)
(defun gnus-summary-limit-to-recipient (recipient &optional not-matching)
"Limit the summary buffer to articles with the given RECIPIENT.
+If NOT-MATCHING, exclude RECIPIENT.
+
To and Cc headers are checked. You need to include them in
`nnmail-extra-headers'."
;; Unlike `rmail-summary-by-recipients', doesn't include From.
(if current-prefix-arg "Exclude" "Limit to")))
current-prefix-arg))
(when (not (equal "" recipient))
- (prog1 (let* ((articles1
+ (prog1 (let* ((to
(if (memq 'To nnmail-extra-headers)
(gnus-summary-find-matching
(cons 'extra 'To) recipient 'all nil nil
1 "`To' isn't present in `nnmail-extra-headers'")
(sit-for 1)
nil))
- (articles2
+ (cc
(if (memq 'Cc nnmail-extra-headers)
(gnus-summary-find-matching
(cons 'extra 'Cc) recipient 'all nil nil
1 "`Cc' isn't present in `nnmail-extra-headers'")
(sit-for 1)
nil))
- (articles (nconc articles1 articles2)))
+ (articles
+ (if not-matching
+ ;; We need the numbers that are in both lists:
+ (mapcar (lambda (a)
+ (and (memq a to) a))
+ cc)
+ (nconc to cc))))
(unless articles
(error "Found no matches for \"%s\"" recipient))
(gnus-summary-limit articles))
(gnus-summary-position-point))))
+(defun gnus-summary-limit-strange-charsets-predicate (header)
+ (let ((string (concat (mail-header-subject header)
+ (mail-header-from header)))
+ charset found)
+ (dotimes (i (1- (length string)))
+ (setq charset (format "%s" (char-charset (aref string (1+ i)))))
+ (when (string-match "unicode\\|big\\|japanese" charset)
+ (setq found t)))
+ found))
+
+(defun gnus-summary-limit-to-predicate (predicate)
+ "Limit to articles where PREDICATE returns non-nil.
+PREDICATE will be called with the header structures of the
+articles."
+ (let ((articles nil)
+ (case-fold-search t))
+ (dolist (header gnus-newsgroup-headers)
+ (when (funcall predicate header)
+ (push (mail-header-number header) articles)))
+ (gnus-summary-limit (nreverse articles))))
+
(defun gnus-summary-limit-to-age (age &optional younger-p)
"Limit the summary buffer to articles that are older than (or equal) AGE days.
If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to
(gnus-completing-read-with-default
(symbol-name (car gnus-extra-headers))
(if current-prefix-arg
- "Exclude extra header:"
- "Limit extra header:")
+ "Exclude extra header"
+ "Limit extra header")
(mapcar (lambda (x)
(cons (symbol-name x) x))
gnus-extra-headers)
gnus-duplicate-mark gnus-souped-mark)
'reverse)))
+(defun gnus-summary-limit-to-headers (match &optional reverse)
+ "Limit the summary buffer to articles that have headers that match MATCH.
+If REVERSE (the prefix), limit to articles that don't match."
+ (interactive "sMatch headers (regexp): \nP")
+ (gnus-summary-limit-to-bodies match reverse t))
+
+(defun gnus-summary-limit-to-bodies (match &optional reverse headersp)
+ "Limit the summary buffer to articles that have bodies that match MATCH.
+If REVERSE (the prefix), limit to articles that don't match."
+ (interactive "sMatch body (regexp): \nP")
+ (let ((articles nil)
+ (gnus-select-article-hook nil) ;Disable hook.
+ (gnus-article-prepare-hook nil)
+ (gnus-use-article-prefetch nil)
+ (gnus-keep-backlog nil)
+ (gnus-break-pages nil)
+ (gnus-summary-display-arrow nil)
+ (gnus-updated-mode-lines nil)
+ (gnus-auto-center-summary nil)
+ (gnus-display-mime-function nil))
+ (dolist (data gnus-newsgroup-data)
+ (let (gnus-mark-article-hook)
+ (gnus-summary-select-article t t nil (gnus-data-number data)))
+ (save-excursion
+ (set-buffer gnus-article-buffer)
+ (article-goto-body)
+ (let* ((case-fold-search t)
+ (found (if headersp
+ (re-search-backward match nil t)
+ (re-search-forward match nil t))))
+ (when (or (and found
+ (not reverse))
+ (and (not found)
+ reverse))
+ (push (gnus-data-number data) articles)))))
+ (if (not articles)
+ (message "No messages matched")
+ (gnus-summary-limit articles)))
+ (gnus-summary-position-point))
+
(defun gnus-summary-limit-to-replied (&optional unreplied)
"Limit the summary buffer to replied articles.
If UNREPLIED (the prefix), limit to unreplied articles."
;; will really go down to a leaf article first, before slowly
;; working its way up towards the root.
(when thread
- (let* ((max-lisp-eval-depth 5000)
+ (let* ((max-lisp-eval-depth (max 5000 max-lisp-eval-depth))
(children
(if (cdr thread)
(apply '+ (mapcar 'gnus-summary-limit-children
;; the parent article.
(when (setq to-address (or (gnus-fetch-field "reply-to")
(gnus-fetch-field "from")))
- (setq params (append
- (list (cons 'to-address
- (funcall gnus-decode-encoded-word-function
- to-address))))))
+ (setq params
+ (append
+ (list (cons 'to-address
+ (funcall gnus-decode-encoded-address-function
+ to-address))))))
(setq dig (nnheader-set-temp-buffer " *gnus digest buffer*"))
(insert-buffer-substring gnus-original-article-buffer)
;; Remove lines that may lead nndoc to misinterpret the
(widen)
(isearch-forward regexp-p))))
+(defun gnus-summary-repeat-search-article-forward ()
+ "Repeat the previous search forwards."
+ (interactive)
+ (unless gnus-last-search-regexp
+ (error "No previous search"))
+ (gnus-summary-search-article-forward gnus-last-search-regexp))
+
+(defun gnus-summary-repeat-search-article-backward ()
+ "Repeat the previous search backwards."
+ (interactive)
+ (unless gnus-last-search-regexp
+ (error "No previous search"))
+ (gnus-summary-search-article-forward gnus-last-search-regexp t))
+
(defun gnus-summary-search-article-forward (regexp &optional backward)
"Search for an article containing REGEXP forward.
If BACKWARD, search backward instead."
(defun gnus-summary-caesar-message (&optional arg)
"Caesar rotate the current article by 13.
-The numerical prefix specifies how many places to rotate each letter
-forward."
+With a non-numerical prefix, also rotate headers. A numerical
+prefix specifies how many places to rotate each letter forward."
(interactive "P")
(gnus-summary-select-article)
(let ((mail-header-separator ""))
(widen)
(let ((start (window-start))
buffer-read-only)
- (message-caesar-buffer-body arg)
- (set-window-start (get-buffer-window (current-buffer)) start))))))
-
-(autoload 'unmorse-region "morse"
- "Convert morse coded text in region to ordinary ASCII text."
- t)
+ (if (equal arg '(4))
+ (message-caesar-buffer-body nil t)
+ (message-caesar-buffer-body arg))
+ (set-window-start (get-buffer-window (current-buffer)) start)))))
+ ;; Create buttons and stuff...
+ (gnus-treat-article nil))
+
+(defun gnus-summary-idna-message (&optional arg)
+ "Decode IDNA encoded domain names in the current articles.
+IDNA encoded domain names looks like `xn--bar'. If a string
+remain unencoded after running this function, it is likely an
+invalid IDNA string (`xn--bar' is invalid).
+
+You must have GNU Libidn (`http://www.gnu.org/software/libidn/')
+installed for this command to work."
+ (interactive "P")
+ (if (not (and (condition-case nil (require 'idna)
+ (file-error))
+ (mm-coding-system-p 'utf-8)
+ (executable-find (symbol-value 'idna-program))))
+ (gnus-message
+ 5 "GNU Libidn not installed properly (`idn' or `idna.el' missing)")
+ (gnus-summary-select-article)
+ (let ((mail-header-separator ""))
+ (gnus-eval-in-buffer-window gnus-article-buffer
+ (save-restriction
+ (widen)
+ (let ((start (window-start))
+ buffer-read-only)
+ (while (re-search-forward "\\(xn--[-0-9a-z]+\\)" nil t)
+ (replace-match (idna-to-unicode (match-string 1))))
+ (set-window-start (get-buffer-window (current-buffer)) start)))))))
(defun gnus-summary-morse-message (&optional arg)
"Morse decode the current article."
(crosspost "Crosspost" "Crossposting")))
(copy-buf (save-excursion
(nnheader-set-temp-buffer " *copy article*")))
- art-group to-method new-xref article to-groups)
+ art-group to-method new-xref article to-groups articles-to-update-marks)
(unless (assq action names)
(error "Unknown action %s" action))
;; Read the newsgroup name.
((eq action 'move)
;; Remove this article from future suppression.
(gnus-dup-unsuppress-article article)
- (gnus-request-move-article
- article ; Article to move
- gnus-newsgroup-name ; From newsgroup
- (nth 1 (gnus-find-method-for-group
- gnus-newsgroup-name)) ; Server
- (list 'gnus-request-accept-article
- to-newsgroup (list 'quote select-method)
- (not articles) t) ; Accept form
- (not articles))) ; Only save nov last time
+ (let* ((from-method (gnus-find-method-for-group
+ gnus-newsgroup-name))
+ (to-method (gnus-find-method-for-group
+ to-newsgroup))
+ (move-is-internal (gnus-method-equal from-method to-method)))
+ (gnus-request-move-article
+ article ; Article to move
+ gnus-newsgroup-name ; From newsgroup
+ (nth 1 (gnus-find-method-for-group
+ gnus-newsgroup-name)) ; Server
+ (list 'gnus-request-accept-article
+ to-newsgroup (list 'quote select-method)
+ (not articles) t) ; Accept form
+ (not articles) ; Only save nov last time
+ move-is-internal))) ; is this move internal?
;; Copy the article.
((eq action 'copy)
(save-excursion
(gnus-request-article-this-buffer article gnus-newsgroup-name)
(when (consp (setq art-group
(gnus-request-accept-article
- to-newsgroup select-method (not articles))))
+ to-newsgroup select-method (not articles) t)))
(setq new-xref (concat new-xref " " (car art-group)
":"
(number-to-string (cdr art-group))))
;; it and replace the new article.
(nnheader-replace-header "Xref" new-xref)
(gnus-request-replace-article
- (cdr art-group) to-newsgroup (current-buffer))
+ (cdr art-group) to-newsgroup (current-buffer) t)
art-group))))))
(cond
((not art-group)
(gnus-request-article-this-buffer article gnus-newsgroup-name)
(nnheader-replace-header "Xref" new-xref)
(gnus-request-replace-article
- article gnus-newsgroup-name (current-buffer))))
+ article gnus-newsgroup-name (current-buffer) t)))
;; run the move/copy/crosspost/respool hook
(run-hook-with-args 'gnus-summary-article-move-hook
;;;!!!Why is this necessary?
(set-buffer gnus-summary-buffer)
-
+
(gnus-summary-goto-subject article)
(when (eq action 'move)
(gnus-summary-mark-article article gnus-canceled-mark))))
- (gnus-summary-remove-process-mark article))
+ (push article articles-to-update-marks))
+
+ (apply 'gnus-summary-remove-process-mark articles-to-update-marks)
;; Re-activate all groups that have been moved to.
(save-excursion
(set-buffer gnus-group-buffer)
"If non-nil, show and update the summary buffer as it's being built.
If the value is t, update the buffer after every line is inserted. If
the value is an integer (N), update the display every N lines."
- :version "21.4"
+ :version "22.1"
:group 'gnus-thread
:type '(choice (const :tag "off" nil)
number
gnus-newsgroup-name)))))
(method
(gnus-completing-read-with-default
- methname "What backend do you want to use when respooling?"
+ methname "Backend to use when respooling"
methods nil t nil 'gnus-mail-method-history))
ms)
(cond
(interactive)
(or gnus-expert-user
(gnus-yes-or-no-p
- "Are you really, really, really sure you want to delete all these messages? ")
+ "Are you really, really sure you want to delete all expirable messages? ")
(error "Phew!"))
(gnus-summary-expire-articles t))
;; Suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.
(defun gnus-summary-delete-article (&optional n)
"Delete the N next (mail) articles.
-This command actually deletes articles. This is not a marking
+This command actually deletes articles. This is not a marking
command. The article will disappear forever from your life, never to
return.
`(lambda ()
(let ((mbl mml-buffer-list))
(setq mml-buffer-list nil)
- (mime-to-mml ,'current-handles)
+ (let ((rfc2047-quote-decoded-words-containing-tspecials t))
+ (mime-to-mml ,'current-handles))
(let ((mbl1 mml-buffer-list))
(setq mml-buffer-list mbl)
(set (make-local-variable 'mml-buffer-list) mbl1))
(save-excursion
(save-restriction
(message-narrow-to-head)
- (let ((head (buffer-string))
+ (let ((head (buffer-substring-no-properties
+ (point-min) (point-max)))
header)
(with-temp-buffer
(insert (format "211 %d Article retrieved.\n"
(gnus-summary-goto-subject article)
(gnus-summary-update-secondary-mark article)))
-(defun gnus-summary-remove-process-mark (article)
- "Remove the process mark from ARTICLE and update the summary line."
- (setq gnus-newsgroup-processable (delq article gnus-newsgroup-processable))
- (when (gnus-summary-goto-subject article)
- (gnus-summary-show-thread)
- (gnus-summary-goto-subject article)
- (gnus-summary-update-secondary-mark article)))
+(defun gnus-summary-remove-process-mark (&rest articles)
+ "Remove the process mark from ARTICLES and update the summary line."
+ (dolist (article articles)
+ (setq gnus-newsgroup-processable (delq article gnus-newsgroup-processable))
+ (when (gnus-summary-goto-subject article)
+ (gnus-summary-show-thread)
+ (gnus-summary-goto-subject article)
+ (gnus-summary-update-secondary-mark article)))
+ t)
(defun gnus-summary-set-saved-mark (article)
"Set the process mark on ARTICLE and update the summary line."
gnus-newsgroup-dormant nil))
(setq gnus-newsgroup-unreads
(gnus-sorted-nunion
- (gnus-intersection gnus-newsgroup-unreads
- gnus-newsgroup-downloadable)
+ (gnus-sorted-intersection gnus-newsgroup-unreads
+ gnus-newsgroup-downloadable)
gnus-newsgroup-unfetched)))
;; We actually mark all articles as canceled, which we
;; have to do when using auto-expiry or adaptive scoring.
(gnus-summary-catchup all))
(gnus-summary-next-group))
+(defun gnus-summary-catchup-and-goto-prev-group (&optional all)
+ "Mark all articles in this group as read and select the previous group.
+If given a prefix, mark all articles, unread as well as ticked, as
+read."
+ (interactive "P")
+ (save-excursion
+ (gnus-summary-catchup all))
+ (gnus-summary-next-group nil nil t))
+
;;;
;;; with article
;;;
(error "The current newsgroup does not support article editing"))
(unless (<= (length gnus-newsgroup-processable) 1)
(error "No more than one article may be marked"))
- (save-window-excursion
- (let ((gnus-article-buffer " *reparent*")
- (current-article (gnus-summary-article-number))
- ;; First grab the marked article, otherwise one line up.
- (parent-article (if (not (null gnus-newsgroup-processable))
- (car gnus-newsgroup-processable)
- (save-excursion
- (if (eq (forward-line -1) 0)
- (gnus-summary-article-number)
- (error "Beginning of summary buffer"))))))
- (unless (not (eq current-article parent-article))
- (error "An article may not be self-referential"))
- (let ((message-id (mail-header-id
- (gnus-summary-article-header parent-article))))
- (unless (and message-id (not (equal message-id "")))
- (error "No message-id in desired parent"))
- (gnus-with-article current-article
- (save-restriction
- (goto-char (point-min))
- (message-narrow-to-head)
- (if (re-search-forward "^References: " nil t)
- (progn
- (re-search-forward "^[^ \t]" nil t)
- (forward-line -1)
- (end-of-line)
- (insert " " message-id))
- (insert "References: " message-id "\n"))))
- (set-buffer gnus-summary-buffer)
- (gnus-summary-unmark-all-processable)
- (gnus-summary-update-article current-article)
- (if (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
+ (let ((child (gnus-summary-article-number))
+ ;; First grab the marked article, otherwise one line up.
+ (parent (if (not (null gnus-newsgroup-processable))
+ (car gnus-newsgroup-processable)
+ (save-excursion
+ (if (eq (forward-line -1) 0)
+ (gnus-summary-article-number)
+ (error "Beginning of summary buffer"))))))
+ (gnus-summary-reparent-children parent (list child))))
+
+(defun gnus-summary-reparent-children (parent children)
+ "Make PARENT the parent of CHILDREN.
+When called interactively, PARENT is is current article and
+CHILDREN are the process-marked articles."
+ (interactive
+ (list (gnus-summary-article-number)
+ (gnus-summary-work-articles nil)))
+ (dolist (child children)
+ (save-window-excursion
+ (let ((gnus-article-buffer " *reparent*"))
+ (unless (not (eq parent child))
+ (error "An article may not be self-referential"))
+ (let ((message-id (mail-header-id
+ (gnus-summary-article-header parent))))
+ (unless (and message-id (not (equal message-id "")))
+ (error "No message-id in desired parent"))
+ (gnus-with-article child
+ (save-restriction
+ (goto-char (point-min))
+ (message-narrow-to-head)
+ (if (re-search-forward "^References: " nil t)
+ (progn
+ (re-search-forward "^[^ \t]" nil t)
+ (forward-line -1)
+ (end-of-line)
+ (insert " " message-id))
+ (insert "References: " message-id "\n"))))
+ (set-buffer gnus-summary-buffer)
+ (gnus-summary-unmark-all-processable)
+ (gnus-summary-update-article child)
+ (when (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
(gnus-summary-update-secondary-mark (cdr gnus-article-current)))
- (gnus-summary-rethread-current)
- (gnus-message 3 "Article %d is now the child of article %d"
- current-article parent-article)))))
+ (gnus-summary-rethread-current)
+ (gnus-message 3 "Article %d is now the child of article %d"
+ child parent))))))
(defun gnus-summary-toggle-threads (&optional arg)
"Toggle showing conversation threads.
(defun gnus-map-articles (predicate articles)
"Map PREDICATE over ARTICLES and return non-nil if any predicate is non-nil."
(apply 'gnus-or (mapcar predicate
- (mapcar 'gnus-summary-article-header articles))))
+ (mapcar (lambda (number)
+ (gnus-summary-article-header number))
+ articles))))
(defun gnus-summary-hide-all-threads (&optional predicate)
"Hide all thread subtrees.
If N is a negative number, save the N previous articles.
If N is nil and any articles have been marked with the process mark,
save those articles instead.
-The variable `gnus-default-article-saver' specifies the saver function."
+The variable `gnus-default-article-saver' specifies the saver function.
+
+If the optional second argument NOT-SAVED is non-nil, articles saved
+will not be marked as saved."
(interactive "P")
+ (require 'gnus-art)
(let* ((articles (gnus-summary-work-articles n))
(save-buffer (save-excursion
(nnheader-set-temp-buffer " *Gnus Save*")))
(num (length articles))
+ ;; Whether to save decoded articles or raw articles.
+ (decode (when gnus-article-save-coding-system
+ (get gnus-default-article-saver :decode)))
+ ;; When saving many articles in a single file, use the other
+ ;; function to save articles other than the first one.
+ (saver2 (get gnus-default-article-saver :function))
+ (gnus-prompt-before-saving (if saver2
+ t
+ gnus-prompt-before-saving))
+ (gnus-default-article-saver gnus-default-article-saver)
header file)
(dolist (article articles)
(setq header (gnus-summary-article-header article))
(gnus-message 1 "Article %d is unsaveable" article))
;; This is a real article.
(save-window-excursion
- (let ((gnus-display-mime-function nil)
- (gnus-article-prepare-hook nil))
- (gnus-summary-select-article t nil nil article)))
+ (let ((gnus-display-mime-function (when decode
+ gnus-display-mime-function))
+ (gnus-article-prepare-hook (when decode
+ gnus-article-prepare-hook)))
+ (gnus-summary-select-article t nil nil article)
+ (gnus-summary-goto-subject article)))
(save-excursion
(set-buffer save-buffer)
(erase-buffer)
- (insert-buffer-substring gnus-original-article-buffer))
+ (insert-buffer-substring (if decode
+ gnus-article-buffer
+ gnus-original-article-buffer)))
(setq file (gnus-article-save save-buffer file num))
(gnus-summary-remove-process-mark article)
(unless not-saved
- (gnus-summary-set-saved-mark article))))
+ (gnus-summary-set-saved-mark article)))
+ (when saver2
+ (setq gnus-default-article-saver saver2
+ saver2 nil)))
(gnus-kill-buffer save-buffer)
(gnus-summary-position-point)
(gnus-set-mode-line 'summary)
(gnus-configure-windows 'pipe))))
(defun gnus-summary-save-article-mail (&optional arg)
- "Append the current article to an mail file.
+ "Append the current article to a Unix mail box file.
If N is a positive number, save the N next articles.
If N is a negative number, save the N previous articles.
If N is nil and any articles have been marked with the process mark,
(let ((gnus-default-article-saver 'gnus-summary-save-body-in-file))
(gnus-summary-save-article arg)))
+(defun gnus-summary-write-article-body-file (&optional arg)
+ "Write the current article body to a file, deleting the previous file.
+If N is a positive number, save the N next articles.
+If N is a negative number, save the N previous articles.
+If N is nil and any articles have been marked with the process mark,
+save those articles instead."
+ (interactive "P")
+ (require 'gnus-art)
+ (let ((gnus-default-article-saver 'gnus-summary-write-body-to-file))
+ (gnus-summary-save-article arg)))
+
(defun gnus-summary-muttprint (&optional arg)
"Print the current article using Muttprint.
If N is a positive number, save the N next articles.
(let* ((split-name (gnus-get-split-value gnus-move-split-methods))
(minibuffer-confirm-incomplete nil) ; XEmacs
(prom
- (format "%s %s to:"
+ (format "%s %s to"
prompt
(if (> (length articles) 1)
(format "these %d articles" (length articles))
(error "No such group: %s" to-newsgroup)))
to-newsgroup))
+(defvar gnus-summary-save-parts-counter)
+
(defun gnus-summary-save-parts (type dir n &optional reverse)
"Save parts matching TYPE to DIR.
If REVERSE, save parts that do not match TYPE."
(let ((handles (or gnus-article-mime-handles
(mm-dissect-buffer nil gnus-article-loose-mime)
(and gnus-article-emulate-mime
- (mm-uu-dissect)))))
+ (mm-uu-dissect))))
+ (gnus-summary-save-parts-counter 1))
(when handles
(gnus-summary-save-parts-1 type dir handles reverse)
(unless gnus-article-mime-handles ;; Don't destroy this case.
(mm-handle-disposition handle) 'filename)
(mail-content-type-get
(mm-handle-type handle) 'name)
- (concat gnus-newsgroup-name
- "." (number-to-string
- (cdr gnus-article-current))))))
+ (format "%s.%d.%d" gnus-newsgroup-name
+ (cdr gnus-article-current)
+ gnus-summary-save-parts-counter))))
dir)))
+ (incf gnus-summary-save-parts-counter)
(unless (file-exists-p file)
(mm-save-part-to-file handle file))))))
() ; Malformed head.
(unless (gnus-summary-article-sparse-p (mail-header-number header))
(when (and (stringp id)
- (not (string= (gnus-group-real-name group)
- (car where))))
- ;; If we fetched by Message-ID and the article came
- ;; from a different group, we fudge some bogus article
- ;; numbers for this article.
+ (or
+ (not (string= (gnus-group-real-name group)
+ (car where)))
+ (not (gnus-server-equal gnus-override-method
+ (gnus-group-method group)))))
+ ;; If we fetched by Message-ID and the article came from
+ ;; a different group (or server), we fudge some bogus
+ ;; article numbers for this article.
(mail-header-set-number header gnus-reffed-article-number))
(save-excursion
(set-buffer gnus-summary-buffer)
;; coding: iso-8859-1
;; End:
-;;; arch-tag: 17c6748f-6d00-4d36-bf01-835c42f31235
+;; arch-tag: 17c6748f-6d00-4d36-bf01-835c42f31235
;;; gnus-sum.el ends here