X-Git-Url: https://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fgnus-sum.el;h=25fef124fe7e4e62591735209a50ca56074f09b6;hb=564254b91714106dae4a25b0d8839b4d19978b8f;hp=3ffe492555d69aa7203b6b3d51216e6e1c8179de;hpb=6cd2123aa7862c039847f216cc65b5275ffbd64c;p=gnus diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index 3ffe49255..25fef124f 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -1,6 +1,7 @@ ;;; gnus-sum.el --- summary mode commands for Gnus -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -;; 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 ;; Keywords: news @@ -19,8 +20,8 @@ ;; 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: @@ -28,7 +29,7 @@ (eval-when-compile (require 'cl) - (defvar tool-bar-map)) + (defvar tool-bar-mode)) (require 'gnus) (require 'gnus-group) @@ -37,6 +38,7 @@ (require 'gnus-int) (require 'gnus-undo) (require 'gnus-util) +(require 'gmm-utils) (require 'mm-decode) (require 'nnoo) @@ -62,17 +64,21 @@ it will be killed sometime later." (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) @@ -81,7 +87,7 @@ The server has to support NOV for any of this to work." 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-refer-thread]. If t, fetch all the available old headers." :group 'gnus-thread @@ -256,8 +262,7 @@ simplification is selected." "*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) @@ -320,7 +325,7 @@ This variable can either be the symbols `first' (place point on the 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." @@ -780,20 +785,21 @@ Each list item can also be a list `(not F)' where F is a 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) @@ -972,7 +978,7 @@ automatically when it is selected." :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) @@ -981,42 +987,42 @@ automatically when it is selected." (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 @@ -1055,12 +1061,28 @@ which it may alter in any way." :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 @@ -1300,6 +1322,7 @@ the type of the variable (string, integer, character, etc).") (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) @@ -1415,6 +1438,7 @@ This list will always be a subset of gnus-newsgroup-undownloaded.") 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 @@ -1690,6 +1714,8 @@ increase the score of each group you read." "," 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 @@ -1821,6 +1847,7 @@ increase the score of each group you read." (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 "w" gnus-summary-pop-limit "s" gnus-summary-limit-to-subject "a" gnus-summary-limit-to-author @@ -1867,6 +1894,7 @@ increase the score of each group you read." "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 @@ -1891,6 +1919,7 @@ increase the score of each group you read." "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 @@ -1927,6 +1956,7 @@ increase the score of each group you read." "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 @@ -2046,6 +2076,7 @@ increase the score of each group you read." "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 @@ -2057,9 +2088,15 @@ increase the score of each group you read." "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) @@ -2203,11 +2240,13 @@ increase the score of each group you read." ["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] @@ -2262,6 +2301,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) ["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] @@ -2594,6 +2634,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) '(: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"))] @@ -2608,49 +2649,161 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) (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." @@ -2761,12 +2914,13 @@ The following commands are available: \\{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) @@ -2781,7 +2935,6 @@ The following commands are available: (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) @@ -2789,7 +2942,7 @@ The following commands are available: (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) @@ -3162,8 +3315,11 @@ display only a single character." (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) @@ -3203,10 +3359,11 @@ display only a single character." (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) @@ -3375,12 +3532,19 @@ buffer that was in action when the last article was fetched." 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))))) + ((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 @@ -4587,6 +4751,11 @@ using some other form will lead to serious barfage." (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 @@ -4707,33 +4876,39 @@ If nil, use subject instead." :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 "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 "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 "22.1" :type 'string :group 'gnus-thread) + (defcustom gnus-sum-thread-tree-indent " " "With %B spec, used for indenting." :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 "22.1" :type 'string :group 'gnus-thread) + (defcustom gnus-sum-thread-tree-single-leaf "\\-> " "With %B spec, used for a leaf without brothers." :version "22.1" @@ -5721,7 +5896,7 @@ The resulting hash table is returned, or nil if no Xrefs were found." (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))) @@ -6016,7 +6191,8 @@ Return a list of headers that match SEQUENCE (see (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))) @@ -6171,7 +6347,7 @@ current article will be taken into consideration." (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) @@ -6508,10 +6684,12 @@ displayed, no centering will be performed." (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)))) @@ -6673,6 +6851,7 @@ If FORCE (the prefix), also save the .newsrc file(s)." (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 @@ -6732,6 +6911,10 @@ If FORCE (the prefix), also save the .newsrc file(s)." (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. @@ -6807,19 +6990,11 @@ The state which existed when entering the ephemeral is reset." (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)))) @@ -7778,8 +7953,8 @@ articles that are younger than AGE days." (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) @@ -7832,6 +8007,38 @@ If ALL is non-nil, limit strictly to unread articles." gnus-duplicate-mark gnus-souped-mark) 'reverse))) +(defun gnus-summary-limit-to-bodies (match &optional reverse) + "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 (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." @@ -8516,6 +8723,20 @@ If REGEXP-P (the prefix) is non-nil, do regexp isearch." (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." @@ -8953,7 +9174,9 @@ forward." (let ((start (window-start)) buffer-read-only) (message-caesar-buffer-body arg) - (set-window-start (get-buffer-window (current-buffer)) start)))))) + (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. @@ -8981,10 +9204,6 @@ installed for this command to work." (replace-match (idna-to-unicode (match-string 1)))) (set-window-start (get-buffer-window (current-buffer)) start))))))) -(autoload 'unmorse-region "morse" - "Convert morse coded text in region to ordinary ASCII text." - t) - (defun gnus-summary-morse-message (&optional arg) "Morse decode the current article." (interactive "P") @@ -9061,7 +9280,7 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (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. @@ -9106,6 +9325,11 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." ((eq action 'move) ;; Remove this article from future suppression. (gnus-dup-unsuppress-article article) + (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 @@ -9114,7 +9338,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (list 'gnus-request-accept-article to-newsgroup (list 'quote select-method) (not articles) t) ; Accept form - (not articles))) ; Only save nov last time + (not articles) ; Only save nov last time + move-is-internal))) ; is this move internal? ;; Copy the article. ((eq action 'copy) (save-excursion @@ -9264,17 +9489,19 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." ;;;!!!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) (let ((gnus-group-marked to-groups)) (gnus-group-get-new-news-this-group nil t))) - + (gnus-kill-buffer copy-buf) (gnus-summary-position-point) (gnus-set-mode-line 'summary))) @@ -9334,7 +9561,7 @@ latter case, they will be copied into the relevant groups." 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 @@ -9500,7 +9727,7 @@ deleted forever, right now." (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)) @@ -9677,7 +9904,8 @@ groups." (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" @@ -9964,13 +10192,15 @@ the actual number of articles marked is returned." (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." @@ -10540,6 +10770,15 @@ read." (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 ;;; @@ -10632,41 +10871,51 @@ is non-nil or the Subject: of both articles are the same." (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. @@ -10726,7 +10975,9 @@ Returns nil if no thread was there to be shown." (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. @@ -10989,12 +11240,26 @@ 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. -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)) @@ -11005,17 +11270,25 @@ The variable `gnus-default-article-saver' specifies the saver function." (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) @@ -11039,7 +11312,7 @@ If HEADERS (the symbolic prefix), include the headers, too." (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, @@ -11093,6 +11366,17 @@ save those articles instead." (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. @@ -11165,7 +11449,7 @@ save those articles instead." (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)) @@ -11211,6 +11495,8 @@ save those articles instead." (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." @@ -11233,7 +11519,8 @@ 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. @@ -11255,10 +11542,11 @@ If REVERSE, save parts that do not match TYPE." (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)))))) @@ -11413,11 +11701,14 @@ If REVERSE, save parts that do not match TYPE." () ; 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)