;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2011 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
(autoload 'gnus-article-outlook-unwrap-lines "deuglify" nil t)
(autoload 'gnus-article-outlook-repair-attribution "deuglify" nil t)
(autoload 'gnus-article-outlook-rearrange-citation "deuglify" nil t)
+(autoload 'nnir-article-rsv "nnir" nil nil 'macro)
+(autoload 'nnir-article-group "nnir" nil nil 'macro)
(defcustom gnus-kill-summary-on-exit t
"*If non-nil, kill the summary buffer when you exit from it.
:type '(choice number
(sexp :menu-tag "other" t)))
+(defcustom gnus-refer-thread-use-nnir nil
+ "*Use nnir to search an entire server when referring threads. A
+nil value will only search for thread-related articles in the
+current group."
+ :group 'gnus-thread
+ :type 'boolean)
+
(defcustom gnus-summary-make-false-root 'adopt
"*nil means that Gnus won't gather loose threads.
If the root of a thread has expired or been read in a previous
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
-line of the first unseen article or, if all article have been seen, on the
+line of the first unseen article or, if all articles 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 "24.1"
(const unread)
(const first)
(const unseen)
- (const unseen-or-unread)))
+ (const unseen-or-unread)
+ (function :tag "Function to call")))
(defcustom gnus-auto-select-next t
"*If non-nil, offer to go to the next group from the end of the previous.
'mail-decode-encoded-address-string
"Function used to decode addresses with encoded words.")
-(defcustom gnus-extra-headers '(To Newsgroups)
+(defcustom gnus-extra-headers '(To Cc Keywords Gcc Newsgroups)
"*Extra headers to parse."
- :version "21.1"
+ :version "24.1" ; added Cc Keywords Gcc
:group 'gnus-summary
:type '(repeat symbol))
:type 'boolean
:group 'gnus-summary-marks)
-(defcustom gnus-propagate-marks t
- "If non-nil, do not propagate marks to the backends."
- :version "23.1" ;; No Gnus
+(defcustom gnus-propagate-marks nil
+ "If non-nil, Gnus will store and retrieve marks from the backends.
+This means that marks will be stored both in .newsrc.eld and in
+the backend, and will slow operation down somewhat."
:type 'boolean
:group 'gnus-summary-marks)
(?c (or (mail-header-chars gnus-tmp-header) 0) ?d)
(?k (gnus-summary-line-message-size gnus-tmp-header) ?s)
(?L gnus-tmp-lines ?s)
+ (?Z (or ,(gnus-macroexpand-all
+ '(nnir-article-rsv (mail-header-number gnus-tmp-header)))
+ 0) ?d)
+ (?G (or ,(gnus-macroexpand-all
+ '(nnir-article-group (mail-header-number gnus-tmp-header)))
+ "") ?s)
+ (?g (or ,(gnus-macroexpand-all
+ '(gnus-group-short-name
+ (nnir-article-group (mail-header-number gnus-tmp-header))))
+ "") ?s)
(?O gnus-tmp-downloaded ?c)
(?I gnus-tmp-indentation ?s)
(?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s)
(defvar gnus-newsgroup-forwarded nil
"List of articles that have been forwarded in the current newsgroup.")
-(defvar gnus-newsgroup-recent nil
- "List of articles that have are recent in the current newsgroup.")
-
(defvar gnus-newsgroup-expirable nil
"Sorted list of articles in the current newsgroup that can be expired.")
gnus-newsgroup-saved
gnus-newsgroup-replied
gnus-newsgroup-forwarded
- gnus-newsgroup-recent
gnus-newsgroup-expirable
gnus-newsgroup-killed
gnus-newsgroup-unseen
gnus-newsgroup-prepared gnus-summary-highlight-line-function
gnus-current-article gnus-current-headers gnus-have-all-headers
gnus-last-article gnus-article-internal-prepare-hook
+ (gnus-summary-article-delete-hook . global)
+ (gnus-summary-article-move-hook . global)
gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay
gnus-newsgroup-scored gnus-newsgroup-kill-headers
gnus-thread-expunge-below
(while (re-search-forward regexp nil t)
(replace-match (or newtext ""))))
-(defun gnus-simplify-buffer-fuzzy ()
+(defun gnus-simplify-buffer-fuzzy (regexp)
"Simplify string in the buffer fuzzily.
The string in the accessible portion of the current buffer is simplified.
It is assumed to be a single-line subject.
(while (not (eq modified-tick (buffer-modified-tick)))
(setq modified-tick (buffer-modified-tick))
(cond
- ((listp gnus-simplify-subject-fuzzy-regexp)
- (mapc 'gnus-simplify-buffer-fuzzy-step
- gnus-simplify-subject-fuzzy-regexp))
- (gnus-simplify-subject-fuzzy-regexp
- (gnus-simplify-buffer-fuzzy-step gnus-simplify-subject-fuzzy-regexp)))
+ ((listp regexp)
+ (mapc 'gnus-simplify-buffer-fuzzy-step regexp))
+ (regexp
+ (gnus-simplify-buffer-fuzzy-step regexp)))
(gnus-simplify-buffer-fuzzy-step "^ *\\[[-+?*!][-+?*!]\\] *")
(gnus-simplify-buffer-fuzzy-step
"^ *\\(re\\|fw\\|fwd\\)[[{(^0-9]*[])}]?[:;] *")
"Simplify a subject string fuzzily.
See `gnus-simplify-buffer-fuzzy' for details."
(save-excursion
- (gnus-set-work-buffer)
- (let ((case-fold-search t))
- ;; Remove uninteresting prefixes.
- (when (and gnus-simplify-ignored-prefixes
- (string-match gnus-simplify-ignored-prefixes subject))
- (setq subject (substring subject (match-end 0))))
- (insert subject)
- (inline (gnus-simplify-buffer-fuzzy))
- (buffer-string))))
+ (let ((regexp gnus-simplify-subject-fuzzy-regexp))
+ (gnus-set-work-buffer)
+ (let ((case-fold-search t))
+ ;; Remove uninteresting prefixes.
+ (when (and gnus-simplify-ignored-prefixes
+ (string-match gnus-simplify-ignored-prefixes subject))
+ (setq subject (substring subject (match-end 0))))
+ (insert subject)
+ (inline (gnus-simplify-buffer-fuzzy regexp))
+ (buffer-string)))))
(defsubst gnus-simplify-subject-fully (subject)
"Simplify a subject string according to `gnus-summary-gather-subject-limit'."
"a" gnus-summary-post-news
"x" gnus-summary-limit-to-unread
"s" gnus-summary-isearch-article
+ [tab] gnus-summary-widget-forward
"t" gnus-summary-toggle-header
"g" gnus-summary-show-article
"l" gnus-summary-goto-last-article
"D" gnus-summary-enter-digest-group
"R" gnus-summary-refer-references
"T" gnus-summary-refer-thread
+ "W" gnus-warp-to-article
"g" gnus-summary-show-article
"s" gnus-summary-isearch-article
+ [tab] gnus-summary-widget-forward
"P" gnus-summary-print-article
"S" gnus-sticky-article
"M" gnus-mailing-list-insinuate
"a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
"p" gnus-article-verify-x-pgp-sig
"d" gnus-article-treat-dumbquotes
+ "U" gnus-article-treat-non-ascii
"i" gnus-summary-idna-message)
(gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
"d" gnus-article-display-face
"s" gnus-treat-smiley
"D" gnus-article-remove-images
- "W" gnus-html-show-images
+ "W" gnus-article-show-images
"f" gnus-treat-from-picon
"m" gnus-treat-mail-picon
"n" gnus-treat-newsgroups-picon
gnus-article-remove-leading-whitespace t])
["Overstrike" gnus-article-treat-overstrike t]
["Dumb quotes" gnus-article-treat-dumbquotes t]
+ ["Non-ASCII" gnus-article-treat-non-ascii t]
["Emphasis" gnus-article-emphasize t]
["Word wrap" gnus-article-fill-cited-article t]
["Fill long lines" gnus-article-fill-long-lines t]
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)))))
+ (gnus-string-mark-left-to-right
+ (inline
+ (gnus-summary-extract-address-component gnus-tmp-from))))))
(defun gnus-summary-insert-line (gnus-tmp-header
gnus-tmp-level gnus-tmp-current
gnus-forwarded-mark)
((memq gnus-tmp-current gnus-newsgroup-saved)
gnus-saved-mark)
- ((memq gnus-tmp-number gnus-newsgroup-recent)
- gnus-recent-mark)
((memq gnus-tmp-number gnus-newsgroup-unseen)
gnus-unseen-mark)
(t gnus-no-mark)))
((< c (* 1000 10000)) (format "%1.1fM" (/ c (* 1024.0 1024))))
(t (format "%dM" (/ c (* 1024.0 1024)))))))
+(defcustom gnus-user-date-format-alist
+ '(((gnus-seconds-today) . "Today, %H:%M")
+ ((+ 86400 (gnus-seconds-today)) . "Yesterday, %H:%M")
+ (604800 . "%A %H:%M") ; That's one week
+ ((gnus-seconds-month) . "%A %d")
+ ((gnus-seconds-year) . "%B %d")
+ (t . "%b %d %Y")) ; This one is used when no other
+ ; does match
+ "Specifies date format depending on age of article.
+This is an alist of items (AGE . FORMAT). AGE can be a number (of
+seconds) or a Lisp expression evaluating to a number. When the age of
+the article is less than this number, then use `format-time-string'
+with the corresponding FORMAT for displaying the date of the article.
+If AGE is not a number or a Lisp expression evaluating to a
+non-number, then the corresponding FORMAT is used as a default value.
+
+Note that the list is processed from the beginning, so it should be
+sorted by ascending AGE. Also note that items following the first
+non-number AGE will be ignored.
+
+You can use the functions `gnus-seconds-today', `gnus-seconds-month'
+and `gnus-seconds-year' in the AGE spec. They return the number of
+seconds passed since the start of today, of this month, of this year,
+respectively."
+ :version "24.1"
+ :group 'gnus-summary-format
+ :type '(alist :key-type sexp :value-type string))
+
+(defun gnus-user-date (messy-date)
+ "Format the messy-date according to `gnus-user-date-format-alist'.
+Returns \" ? \" if there's bad input or if another error occurs.
+Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"."
+ (condition-case ()
+ (let* ((messy-date (gnus-float-time (gnus-date-get-time messy-date)))
+ (now (gnus-float-time))
+ ;;If we don't find something suitable we'll use this one
+ (my-format "%b %d '%y"))
+ (let* ((difference (- now messy-date))
+ (templist gnus-user-date-format-alist)
+ (top (eval (caar templist))))
+ (while (if (numberp top) (< top difference) (not top))
+ (progn
+ (setq templist (cdr templist))
+ (setq top (eval (caar templist)))))
+ (if (stringp (cdr (car templist)))
+ (setq my-format (cdr (car templist)))))
+ (format-time-string (eval my-format) (seconds-to-time messy-date)))
+ (error " ? ")))
(defun gnus-summary-set-local-parameters (group)
"Go through the local params of GROUP and set all variable specs in that list."
;; (when (and (not (gnus-group-native-p group))
;; (not (gnus-gethash group gnus-newsrc-hashtb)))
;; (error "Dead non-native groups can't be entered"))
- (gnus-message 5 "Retrieving newsgroup: %s..."
+ (gnus-message 7 "Retrieving newsgroup: %s..."
(gnus-group-decoded-name group))
(let* ((new-group (gnus-summary-setup-buffer group))
(quit-config (gnus-group-quit-config group))
(gnus-group-jump-to-group group)
(gnus-group-next-unread-group 1))
(gnus-handle-ephemeral-exit quit-config)))
- (let ((grpinfo (gnus-get-info group)))
- (if (null (gnus-info-read grpinfo))
- (gnus-message 3 "Group %s contains no messages"
- (gnus-group-decoded-name group))
- (gnus-message 3 "Can't select group")))
+ (if (null (gnus-list-of-unread-articles group))
+ (gnus-message 3 "Group %s contains no messages" group)
+ (gnus-message 3 "Can't select group"))
nil)
;; The user did a `C-g' while prompting for number of articles,
;; so we exit this group.
;; gnus-summary-prepare-hook since kill processing may not
;; work with hidden articles.
(gnus-summary-maybe-hide-threads)
+ (gnus-configure-windows 'summary)
(when kill-buffer
(gnus-kill-or-deaden-summary kill-buffer))
(gnus-summary-auto-select-subject)
gnus-newsgroup-unreads
gnus-auto-select-first)
(progn
- (gnus-configure-windows 'summary)
(let ((art (gnus-summary-article-number)))
(unless (and (not gnus-plugged)
(or (memq art gnus-newsgroup-undownloaded)
(setq gnus-newsgroup-prepared t)
(gnus-run-hooks 'gnus-summary-prepared-hook)
(unless (gnus-ephemeral-group-p group)
- (gnus-group-update-group group))
+ (gnus-group-update-group group nil t))
t)))))
(defun gnus-summary-auto-select-subject ()
(while (not (eobp))
(ignore-errors
(setq article (read (current-buffer))
- header (gnus-nov-parse-line article dependencies)))
+ header (gnus-nov-parse-line article dependencies t)))
(when header
(with-current-buffer gnus-summary-buffer
(push header gnus-newsgroup-headers)
(car headers))))
(defun gnus-parent-headers (in-headers &optional generation)
- "Return the headers of the GENERATIONeth parent of HEADERS."
+ "Return the headers of the GENERATIONth parent of HEADERS."
(unless generation
(setq generation 1))
(let ((parent t)
gnus-forwarded-mark)
((memq number gnus-newsgroup-saved)
gnus-saved-mark)
- ((memq number gnus-newsgroup-recent)
- gnus-recent-mark)
((memq number gnus-newsgroup-unseen)
gnus-unseen-mark)
(t gnus-no-mark))
(cdr (assq number gnus-newsgroup-scored))
(memq number gnus-newsgroup-processable))))))
+(defun gnus-group-get-list-identifiers (group)
+ "Get list identifier regexp for GROUP."
+ (or (gnus-parameter-list-identifier group)
+ (if (consp gnus-list-identifiers)
+ (mapconcat 'identity gnus-list-identifiers " *\\|")
+ gnus-list-identifiers)))
+
(defun gnus-summary-remove-list-identifiers ()
"Remove list identifiers in `gnus-list-identifiers' from articles in the current group."
- (let ((regexp (if (consp gnus-list-identifiers)
- (mapconcat 'identity gnus-list-identifiers " *\\|")
- gnus-list-identifiers))
- changed subject)
+ (let ((regexp (gnus-group-get-list-identifiers gnus-newsgroup-name))
+ changed subject)
(when regexp
(setq regexp (concat "^\\(?:R[Ee]: +\\)*\\(" regexp " *\\)"))
(dolist (header gnus-newsgroup-headers)
(substring subject (match-end 1)))))
(mail-header-set-subject header subject))))))
-(defun gnus-fetch-headers (articles)
+(defun gnus-fetch-headers (articles &optional limit force-new dependencies)
"Fetch headers of ARTICLES."
(let ((name (gnus-group-decoded-name gnus-newsgroup-name)))
- (gnus-message 5 "Fetching headers for %s..." name)
+ (gnus-message 7 "Fetching headers for %s..." name)
(prog1
(if (eq 'nov
(setq gnus-headers-retrieved-by
(gnus-retrieve-headers
articles gnus-newsgroup-name
- ;; We might want to fetch old headers, but
- ;; not if there is only 1 article.
- (and (or (and
- (not (eq gnus-fetch-old-headers 'some))
- (not (numberp gnus-fetch-old-headers)))
- (> (length articles) 1))
- gnus-fetch-old-headers))))
+ (or limit
+ ;; We might want to fetch old headers, but
+ ;; not if there is only 1 article.
+ (and (or (and
+ (not (eq gnus-fetch-old-headers 'some))
+ (not (numberp gnus-fetch-old-headers)))
+ (> (length articles) 1))
+ gnus-fetch-old-headers)))))
(gnus-get-newsgroup-headers-xover
- articles nil nil gnus-newsgroup-name t)
- (gnus-get-newsgroup-headers))
- (gnus-message 5 "Fetching headers for %s...done" name))))
+ articles force-new dependencies gnus-newsgroup-name t)
+ (gnus-get-newsgroup-headers dependencies force-new))
+ (gnus-message 7 "Fetching headers for %s...done" name))))
(defun gnus-select-newsgroup (group &optional read-all select-articles)
"Select newsgroup GROUP.
(mm-decode-coding-string group charset)
(mm-decode-coding-string (gnus-status-message group) charset)))
- (when gnus-agent
+ (when (and gnus-agent
+ (gnus-active group))
(gnus-agent-possibly-alter-active group (gnus-active group) info)
(setq gnus-summary-use-undownloaded-faces
(setq gnus-newsgroup-processable nil)
- (gnus-update-read-articles group gnus-newsgroup-unreads)
+ (gnus-update-read-articles group gnus-newsgroup-unreads t)
;; Adjust and set lists of article marks.
(when info
(when gnus-agent
(gnus-agent-get-undownloaded-list))
;; Remove list identifiers from subject
- (when gnus-list-identifiers
- (gnus-summary-remove-list-identifiers))
+ (gnus-summary-remove-list-identifiers)
;; Check whether auto-expire is to be done in this group.
(setq gnus-newsgroup-auto-expire
- (gnus-group-auto-expirable-p group))
+ (and (gnus-group-auto-expirable-p group)
+ (not (gnus-group-read-only-p group))))
;; Set up the article buffer now, if necessary.
(unless (and gnus-single-article-buffer
(equal gnus-article-buffer "*Article*"))
(memq article gnus-newsgroup-forwarded))
((eq type 'seen)
(not (memq article gnus-newsgroup-unseen)))
- ((eq type 'recent)
- (memq article gnus-newsgroup-recent))
(t t))))
(defun gnus-articles-to-read (group &optional read-all)
"Find out what articles the user wants to read."
- (let* ((articles
+ (let* ((only-read-p t)
+ (articles
;; Select all articles if `read-all' is non-nil, or if there
;; are no unread articles.
(if (or read-all
(gnus-uncompress-range (gnus-active group)))
(gnus-cache-articles-in-group group))
;; Select only the "normal" subset of articles.
+ (setq only-read-p nil)
(gnus-sorted-nunion
(gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked)
gnus-newsgroup-unreads)))
(let* ((cursor-in-echo-area nil)
(initial (gnus-parameter-large-newsgroup-initial
gnus-newsgroup-name))
+ (default (if only-read-p
+ (or initial gnus-large-newsgroup)
+ number))
(input
(read-string
- (format
- "How many articles from %s (%s %d): "
- (gnus-group-decoded-name gnus-newsgroup-name)
- (if initial "max" "default")
- number)
- (if initial
- (cons (number-to-string initial)
- 0)))))
+ (if only-read-p
+ (format
+ "How many articles from %s (available %d, default %d): "
+ (gnus-group-decoded-name
+ (gnus-group-real-name gnus-newsgroup-name))
+ number default)
+ (format
+ "How many articles from %s (%d default): "
+ (gnus-group-decoded-name
+ (gnus-group-real-name gnus-newsgroup-name))
+ default))
+ nil
+ nil
+ (number-to-string default))))
(if (string-match "^[ \t]*$" input) number input)))
((and (> scored marked) (< scored number)
(> (- scored number) 20))
(read-string
(format "%s %s (%d scored, %d total): "
"How many articles from"
- (gnus-group-decoded-name group)
+ (gnus-group-decoded-name
+ (gnus-group-real-name gnus-newsgroup-name))
scored number))))
(if (string-match "^[ \t]*$" input)
number input)))
'request-set-mark gnus-newsgroup-name)
(not (gnus-article-unpropagatable-p (cdr type))))
(let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
- (del (gnus-remove-from-range (gnus-copy-sequence old) list))
- (add (gnus-remove-from-range
- (gnus-copy-sequence list) old)))
+ ;; Don't do anything about marks for articles we
+ ;; didn't actually get any headers for.
+ (del
+ (gnus-list-range-intersection
+ gnus-newsgroup-articles
+ (gnus-remove-from-range (gnus-copy-sequence old) list)))
+ (add
+ (gnus-list-range-intersection
+ gnus-newsgroup-articles
+ (gnus-remove-from-range
+ (gnus-copy-sequence list) old))))
(when add
(push (list add 'add (list (cdr type))) delta-marks))
(when del
- ;; Don't delete marks from outside the active range. This
- ;; shouldn't happen, but is a sanity check.
+ ;; Don't delete marks from outside the active range.
+ ;; This shouldn't happen, but is a sanity check.
(setq del (gnus-sorted-range-intersection
(gnus-active gnus-newsgroup-name) del))
(push (list del 'del (list (cdr type))) delta-marks))))
(defun gnus-summary-insert-subject (id &optional old-header use-old-header)
"Find article ID and insert the summary line for that article.
OLD-HEADER can either be a header or a line number to insert
-the subject line on."
+the subject line on.
+If USE-OLD-HEADER is non-nil, then OLD-HEADER should be a header,
+and OLD-HEADER will be used when the summary line is inserted,
+too, instead of trying to fetch new headers."
(let* ((line (and (numberp old-header) old-header))
(old-header (and (vectorp old-header) old-header))
(header (cond ((and old-header use-old-header)
(1+ (point-at-eol))
(gnus-delete-line))))))
;; Remove list identifiers from subject.
- (when gnus-list-identifiers
- (let ((gnus-newsgroup-headers (list header)))
- (gnus-summary-remove-list-identifiers)))
+ (let ((gnus-newsgroup-headers (list header)))
+ (gnus-summary-remove-list-identifiers))
(when old-header
(mail-header-set-number header (mail-header-number old-header)))
(setq gnus-newsgroup-sparse
(defun gnus-summary-select-article-buffer ()
"Reconfigure windows to show the article buffer.
-If `gnus-widen-article-buffer' is set, show only the article
+If `gnus-widen-article-window' is set, show only the article
buffer."
(interactive)
(if (not (gnus-buffer-live-p gnus-article-buffer))
t)))
(unless (listp (cdr gnus-newsgroup-killed))
(setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
- (let ((headers gnus-newsgroup-headers))
+ (let ((headers gnus-newsgroup-headers)
+ (ephemeral-p (gnus-ephemeral-group-p group))
+ info)
+ (unless ephemeral-p
+ (setq info (copy-sequence (gnus-get-info group))
+ info (delq (gnus-info-params info) info)))
;; Set the new ranges of read articles.
(with-current-buffer gnus-group-buffer
(gnus-undo-force-boundary))
(gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
;; Do not switch windows but change the buffer to work.
(set-buffer gnus-group-buffer)
- (unless (gnus-ephemeral-group-p group)
- (gnus-group-update-group group)))))))
+ (unless ephemeral-p
+ (gnus-group-update-group
+ group nil
+ (equal info
+ (setq info (copy-sequence (gnus-get-info group))
+ info (delq (gnus-info-params info) info))))))))))
(defun gnus-summary-save-newsrc (&optional force)
"Save the current number of read/marked articles in the dribble buffer.
(let* ((group gnus-newsgroup-name)
(quit-config (gnus-group-quit-config gnus-newsgroup-name))
(gnus-group-is-exiting-p t)
+ (article-buffer gnus-article-buffer)
+ (original-article-buffer gnus-original-article-buffer)
(mode major-mode)
(group-point nil)
- (buf (current-buffer)))
+ (buf (current-buffer))
+ ;; `gnus-single-article-buffer' is nil buffer-locally in
+ ;; ephemeral group of which summary buffer will be killed,
+ ;; but the global value may be non-nil.
+ (single-article-buffer gnus-single-article-buffer))
(unless quit-config
;; Do adaptive scoring, and possibly save score files.
(when gnus-newsgroup-adaptive
(when (eq mode 'gnus-summary-mode)
(gnus-kill-buffer buf)))
- ;; If we have several article buffers, we kill them at exit.
- (unless gnus-single-article-buffer
- (when (gnus-buffer-live-p gnus-article-buffer)
- (with-current-buffer gnus-article-buffer
- ;; Don't kill sticky article buffers
- (unless (eq major-mode 'gnus-sticky-article-mode)
- (gnus-kill-buffer gnus-article-buffer)
- (setq gnus-article-current nil))))
- (gnus-kill-buffer gnus-original-article-buffer))
-
(setq gnus-current-select-method gnus-select-method)
(set-buffer gnus-group-buffer)
(if quit-config
(if win (set-window-point win (point))))
(unless leave-hidden
(gnus-configure-windows 'group 'force)))
+
+ ;; If we have several article buffers, we kill them at exit.
+ (unless single-article-buffer
+ (when (gnus-buffer-live-p article-buffer)
+ (with-current-buffer article-buffer
+ ;; Don't kill sticky article buffers
+ (unless (eq major-mode 'gnus-sticky-article-mode)
+ (gnus-kill-buffer article-buffer)
+ (setq gnus-article-current nil))))
+ (gnus-kill-buffer original-article-buffer))
+
;; Clear the current group name.
(unless quit-config
(setq gnus-newsgroup-name nil)))))
(run-hooks 'gnus-summary-prepare-exit-hook)
(when (gnus-buffer-live-p gnus-article-buffer)
(with-current-buffer gnus-article-buffer
+ (gnus-article-stop-animations)
(mm-destroy-parts gnus-article-mime-handles)
;; Set it to nil for safety reason.
(setq gnus-article-mime-handle-alist nil)
(gnus-kill-buffer gnus-article-buffer)
(gnus-kill-buffer gnus-original-article-buffer)
(setq gnus-article-current nil))
+ ;; Return to the group buffer.
+ (gnus-configure-windows 'group 'force)
(if (not gnus-kill-summary-on-exit)
(gnus-deaden-summary)
(gnus-close-group group)
(gnus-async-prefetch-remove-group group)
(when (get-buffer gnus-article-buffer)
(bury-buffer gnus-article-buffer))
- ;; Return to the group buffer.
- (gnus-configure-windows 'group 'force)
;; Clear the current group name.
(setq gnus-newsgroup-name nil)
(unless (gnus-ephemeral-group-p group)
- (gnus-group-update-group group))
+ (gnus-group-update-group group nil t))
(when (equal (gnus-group-group-name) group)
(gnus-group-next-unread-group 1))
(when quit-config
(if (not (buffer-name (car quit-config)))
(gnus-configure-windows 'group 'force)
(set-buffer (car quit-config))
+ (unless (eq (cdr quit-config) 'group)
+ (setq gnus-current-select-method
+ (gnus-find-method-for-group gnus-newsgroup-name)))
(cond ((eq major-mode 'gnus-summary-mode)
(gnus-set-global-variables))
((eq major-mode 'gnus-article-mode)
(point
(with-current-buffer gnus-group-buffer
(point)))
+ (current-summary (current-buffer))
(group
(if (eq gnus-keep-same-level 'best)
(gnus-summary-best-group gnus-newsgroup-name)
(gnus-summary-search-group backward gnus-keep-same-level))))
- ;; For some reason, the group window gets selected. We change
- ;; it back.
- (select-window (get-buffer-window (current-buffer)))
;; Select next unread newsgroup automagically.
(cond
((or (not gnus-auto-select-next)
(gnus-summary-next-group nil group backward)))
(t
(when (gnus-key-press-event-p last-input-event)
+ ;; Somehow or other, we may now have selected a different
+ ;; window. Make point go back to the summary buffer.
+ (when (eq current-summary (current-buffer))
+ ;; FIXME: This burps when get-buffer-window returns nil.
+ (select-window (get-buffer-window current-summary 0)))
(gnus-summary-walk-group-buffer
gnus-newsgroup-name cmd unread backward point))))))))
article."
(interactive (list (mail-header-id (gnus-summary-article-header))))
(let ((articles (gnus-articles-in-thread
- (gnus-id-to-thread (gnus-root-id id)))))
+ (gnus-id-to-thread (gnus-root-id id))))
+ ;;we REALLY want the whole thread---this prevents cut-threads
+ ;;from removing the thread we want to include.
+ (gnus-fetch-old-headers nil)
+ (gnus-build-sparse-threads nil))
(prog1
(gnus-summary-limit (nconc articles gnus-newsgroup-limit))
(gnus-summary-limit-include-matching-articles
(gnus-summary-limit (append gnus-newsgroup-dormant gnus-newsgroup-limit))
(gnus-summary-position-point)))
+(defun gnus-summary-include-articles (articles)
+ "Fetch the headers for ARTICLES and then display the summary lines."
+ (let ((gnus-inhibit-demon t)
+ (gnus-agent nil)
+ (gnus-read-all-available-headers t))
+ (setq gnus-newsgroup-headers
+ (gnus-merge
+ 'list gnus-newsgroup-headers
+ (gnus-fetch-headers articles nil t)
+ 'gnus-article-sort-by-number))
+ (setq gnus-newsgroup-articles
+ (gnus-sorted-nunion gnus-newsgroup-articles articles))
+ (gnus-summary-limit (append articles gnus-newsgroup-limit))))
+
(defun gnus-summary-limit-exclude-dormant ()
"Hide all dormant articles."
(interactive)
(gnus-summary-position-point)
n)))
+(defun gnus-delete-duplicate-headers (headers)
+ ;; First remove leading duplicates.
+ (while (and (> (length headers) 1)
+ (= (mail-header-number (car headers))
+ (mail-header-number (cadr headers))))
+ (pop headers))
+ ;; Then the rest.
+ (let ((result headers))
+ (while (> (length headers) 1)
+ (if (= (mail-header-number (car headers))
+ (mail-header-number (cadr headers)))
+ (setcdr headers (cddr headers))
+ (pop headers)))
+ result))
+
(defun gnus-summary-refer-thread (&optional limit)
- "Fetch all articles in the current thread.
-If no backend-specific 'request-thread function is available
-fetch LIMIT (the numerical prefix) old headers. If LIMIT is nil
-fetch what's specified by the `gnus-refer-thread-limit'
-variable."
+ "Fetch all articles in the current thread. For backends that
+know how to search for threads (currently only 'nnimap) a
+non-numeric prefix arg will use nnir to search the entire
+server; without a prefix arg only the current group is
+searched. If the variable `gnus-refer-thread-use-nnir' is
+non-nil the prefix arg has the reverse meaning. If no
+backend-specific 'request-thread function is available fetch
+LIMIT (the numerical prefix) old headers. If LIMIT is
+non-numeric or nil fetch the number specified by the
+`gnus-refer-thread-limit' variable."
(interactive "P")
- (let ((id (mail-header-id (gnus-summary-article-header)))
- (gnus-summary-ignore-duplicates t)
- (limit (if limit (prefix-numeric-value limit)
- gnus-refer-thread-limit)))
- (if (gnus-check-backend-function 'request-thread gnus-newsgroup-name)
- (setq gnus-newsgroup-headers
- (gnus-merge 'list
- gnus-newsgroup-headers
- (gnus-request-thread id)
- 'gnus-article-sort-by-number))
- (unless (eq gnus-fetch-old-headers 'invisible)
- (gnus-message 5 "Fetching headers for %s..." gnus-newsgroup-name)
- ;; Retrieve the headers and read them in.
- (if (numberp limit)
- (gnus-retrieve-headers
- (list (min
- (+ (mail-header-number
- (gnus-summary-article-header))
- limit)
- gnus-newsgroup-end))
- gnus-newsgroup-name (* limit 2))
- ;; gnus-refer-thread-limit is t, i.e. fetch _all_
- ;; headers.
- (gnus-retrieve-headers (list gnus-newsgroup-end)
- gnus-newsgroup-name limit)
- (gnus-message 5 "Fetching headers for %s...done"
- gnus-newsgroup-name))))
- (when (eq gnus-headers-retrieved-by 'nov)
- (gnus-build-all-threads))
- (gnus-summary-limit-include-thread id)))
+ (gnus-warp-to-article)
+ (let* ((header (gnus-summary-article-header))
+ (id (mail-header-id header))
+ (gnus-inhibit-demon t)
+ (gnus-summary-ignore-duplicates t)
+ (gnus-read-all-available-headers t)
+ (gnus-refer-thread-use-nnir
+ (if (and (not (null limit)) (listp limit))
+ (not gnus-refer-thread-use-nnir) gnus-refer-thread-use-nnir))
+ (new-headers
+ (if (gnus-check-backend-function
+ 'request-thread gnus-newsgroup-name)
+ (gnus-request-thread header gnus-newsgroup-name)
+ (let* ((limit (if (numberp limit) (prefix-numeric-value limit)
+ gnus-refer-thread-limit))
+ (last (if (numberp limit)
+ (min (+ (mail-header-number header)
+ limit)
+ gnus-newsgroup-highest)
+ gnus-newsgroup-highest))
+ (subject (gnus-simplify-subject
+ (mail-header-subject header)))
+ (refs (split-string (or (mail-header-references header)
+ "")))
+ (gnus-parse-headers-hook
+ `(lambda () (goto-char (point-min))
+ (keep-lines
+ (regexp-opt ',(append refs (list id subject)))))))
+ (gnus-fetch-headers (list last) (if (numberp limit)
+ (* 2 limit) limit) t))))
+ article-ids)
+ (when (listp new-headers)
+ (dolist (header new-headers)
+ (push (mail-header-number header) article-ids)
+ (when (member (mail-header-number header) gnus-newsgroup-unselected)
+ (push (mail-header-number header) gnus-newsgroup-unreads)
+ (setq gnus-newsgroup-unselected
+ (delete (mail-header-number header)
+ gnus-newsgroup-unselected))))
+ (setq gnus-newsgroup-headers
+ (gnus-delete-duplicate-headers
+ (gnus-merge
+ 'list gnus-newsgroup-headers new-headers
+ 'gnus-article-sort-by-number)))
+ (setq gnus-newsgroup-articles
+ (gnus-sorted-nunion gnus-newsgroup-articles (nreverse article-ids)))
+ (gnus-summary-limit-include-thread id))))
(defun gnus-summary-refer-article (message-id)
"Fetch an article specified by MESSAGE-ID."
(interactive "sMessage-ID: ")
+ (gnus-warp-to-article)
(when (and (stringp message-id)
(not (zerop (length message-id))))
(setq message-id (gnus-replace-in-string message-id " " ""))
(dolist (method gnus-refer-article-method)
(push (if (eq 'current method)
gnus-current-select-method
- method)
+ (if (eq 'nnir (car method))
+ (list
+ 'nnir
+ (or (cadr method)
+ (gnus-method-to-server gnus-current-select-method)))
+ method))
out))
(nreverse out)))
;; One single select method.
(defun gnus-summary-enter-digest-group (&optional force)
"Enter an nndoc group based on the current article.
-If FORCE, force a digest interpretation. If not, try
-to guess what the document format is."
+If FORCE, force a digest interpretation. If not, try to guess
+what the document format is.
+
+To control what happens when you exit the group, see the
+`gnus-auto-select-on-ephemeral-exit' variable."
(interactive "P")
(let ((conf gnus-current-window-configuration))
(save-window-excursion
(t
(error "Couldn't select virtual nndoc group")))))
+(defun gnus-summary-widget-forward (arg)
+ "Move point to the next field or button in the article.
+With optional ARG, move across that many fields."
+ (interactive "p")
+ (gnus-summary-select-article)
+ (gnus-configure-windows 'article)
+ (select-window (gnus-get-buffer-window gnus-article-buffer))
+ (widget-forward arg))
+
(defun gnus-summary-isearch-article (&optional regexp-p)
"Do incremental search forward on the current article.
If REGEXP-P (the prefix) is non-nil, do regexp isearch."
(when (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
(gnus-summary-update-secondary-mark (cdr gnus-article-current))))))
((not arg)
- ;; Select the article the normal way.
- (gnus-summary-select-article nil 'force))
+ (require 'shr)
+ (let ((shr-ignore-cache t))
+ ;; Select the article the normal way.
+ (gnus-summary-select-article nil 'force)))
((equal arg '(16))
;; C-u C-u g
+ (let ((gnus-inhibit-article-treatments t))
+ (gnus-summary-select-article nil 'force)))
+ (t
;; We have to require this here to make sure that the following
;; dynamic binding isn't shadowed by autoloading.
(require 'gnus-async)
;; Destroy any MIME parts.
(when (gnus-buffer-live-p gnus-article-buffer)
(with-current-buffer gnus-article-buffer
+ (gnus-article-stop-animations)
(mm-destroy-parts gnus-article-mime-handles)
;; Set it to nil for safety reason.
(setq gnus-article-mime-handle-alist nil)
(setq gnus-article-mime-handles nil)))
- (gnus-summary-select-article nil 'force)))
- (t
- (let ((gnus-inhibit-article-treatments t))
(gnus-summary-select-article nil 'force))))
(gnus-summary-goto-subject gnus-current-article)
(gnus-summary-position-point))
articles)
(while articles
(setq article (pop articles))
+ ;; Set any marks that may have changed in the summary buffer.
+ (when gnus-preserve-marks
+ (gnus-summary-push-marks-to-backend article))
(setq
art-group
(cond
(move-is-internal (gnus-server-equal from-method to-method)))
(gnus-request-move-article
article ; Article to move
- gnus-newsgroup-name ; From newsgroup
+ gnus-newsgroup-name ; From newsgroup
(nth 1 (gnus-find-method-for-group
gnus-newsgroup-name)) ; Server
(list 'gnus-request-accept-article
(not articles) ; Only save nov last time
(and move-is-internal
to-newsgroup ; Not respooling
- (gnus-group-real-name to-newsgroup))))) ; Is this move internal?
+ ; Is this move internal?
+ (gnus-group-real-name to-newsgroup)))))
;; Copy the article.
((eq action 'copy)
(with-current-buffer copy-buf
- (when (gnus-request-article-this-buffer article gnus-newsgroup-name)
+ (when (gnus-request-article-this-buffer article
+ gnus-newsgroup-name)
(save-restriction
(nnheader-narrow-to-headers)
(dolist (hdr gnus-copy-article-ignored-headers)
;; Crosspost the article.
((eq action 'crosspost)
(let ((xref (message-tokenize-header
- (mail-header-xref (gnus-summary-article-header article))
+ (mail-header-xref (gnus-summary-article-header
+ article))
" ")))
(setq new-xref (concat (gnus-group-real-name gnus-newsgroup-name)
":" (number-to-string article)))
(gnus-request-article-this-buffer article gnus-newsgroup-name)
(when (consp (setq art-group
(gnus-request-accept-article
- to-newsgroup select-method (not articles) t)))
+ to-newsgroup select-method (not articles)
+ t)))
(setq new-xref (concat new-xref " " (car art-group)
":"
(number-to-string (cdr art-group))))
(unless (member to-group to-groups)
(push to-group to-groups))
- (unless (memq article gnus-newsgroup-unreads)
+ (when (and (not (memq article gnus-newsgroup-unreads))
+ (cdr art-group))
(push 'read to-marks)
(gnus-info-set-read
info (gnus-add-to-range (gnus-info-read info)
(marks (if expirable
gnus-article-mark-lists
(delete '(expirable . expire)
- (copy-sequence gnus-article-mark-lists))))
+ (copy-sequence
+ gnus-article-mark-lists))))
(to-article (cdr art-group)))
;; Enter the article into the cache in the new group,
;; if that is required.
- (when gnus-use-cache
+ (when (and to-article
+ gnus-use-cache)
(gnus-cache-possibly-enter-article
to-group to-article
(memq article gnus-newsgroup-marked)
(memq article gnus-newsgroup-dormant)
(memq article gnus-newsgroup-unreads)))
- (when gnus-preserve-marks
+ (when (and gnus-preserve-marks
+ to-article)
;; Copy any marks over to the new group.
(when (and (equal to-group gnus-newsgroup-name)
(not (memq article gnus-newsgroup-unreads)))
;; Mark this article as read in this group.
- (push (cons to-article gnus-read-mark) gnus-newsgroup-reads)
+ (push (cons to-article gnus-read-mark)
+ gnus-newsgroup-reads)
;; Increase the active status of this group.
(setcdr (gnus-active to-group) to-article)
- (setcdr gnus-newsgroup-active to-article))
+ (setcdr gnus-newsgroup-active to-article))
(while marks
(when (eq (gnus-article-mark-to-type (cdar marks)) 'list)
;; If the other group is the same as this group,
;; then we have to add the mark to the list.
(when (equal to-group gnus-newsgroup-name)
- (set (intern (format "gnus-newsgroup-%s" (caar marks)))
+ (set (intern (format "gnus-newsgroup-%s"
+ (caar marks)))
(cons to-article
(symbol-value
(intern (format "gnus-newsgroup-%s"
(gnus-dribble-enter
(concat "(gnus-group-set-info '"
(gnus-prin1-to-string (gnus-get-info to-group))
- ")"))))
+ ")")
+ (concat "^(gnus-group-set-info '(\""
+ (regexp-quote to-group) "\""))))
;; Update the Xref header in this article to point to
;; the new crossposted article we have just created.
to-newsgroup
select-method))
- ;;;!!!Why is this necessary?
+ ;;;!!!Why is this necessary?
(set-buffer gnus-summary-buffer)
(when (eq action 'move)
(gnus-summary-position-point)
(gnus-set-mode-line 'summary)))
+(defun gnus-summary-push-marks-to-backend (article)
+ (let ((set nil)
+ (marks gnus-article-mark-lists))
+ (unless (memq article gnus-newsgroup-unreads)
+ (push 'read set))
+ (while marks
+ (when (and (eq (gnus-article-mark-to-type (cdar marks)) 'list)
+ (memq article (symbol-value
+ (intern (format "gnus-newsgroup-%s"
+ (caar marks))))))
+ (push (cdar marks) set))
+ (pop marks))
+ (gnus-request-set-mark gnus-newsgroup-name `(((,article) set ,set)))))
+
(defun gnus-summary-copy-article (&optional n to-newsgroup select-method)
"Copy the current article to some other group.
If TO-NEWSGROUP is string, do not prompt for a newsgroup to copy to.
latter case, they will be copied into the relevant groups."
(interactive
(list current-prefix-arg
- (let* ((methods (gnus-methods-using 'respool))
+ (let* ((methods (mapcar #'car (gnus-methods-using 'respool)))
(methname
(symbol-name (or gnus-summary-respool-default-method
(car (gnus-find-method-for-group
;; There are expirable articles in this group, so we run them
;; through the expiry process.
(gnus-message 6 "Expiring articles...")
- (unless (gnus-check-group gnus-newsgroup-name)
- (error "Can't open server for %s" gnus-newsgroup-name))
- ;; The list of articles that weren't expired is returned.
- (save-excursion
- (if expiry-wait
- (let ((nnmail-expiry-wait-function nil)
- (nnmail-expiry-wait expiry-wait))
- (setq es (gnus-request-expire-articles
- expirable gnus-newsgroup-name)))
- (setq es (gnus-request-expire-articles
- expirable gnus-newsgroup-name)))
- (unless total
- (setq gnus-newsgroup-expirable es))
- ;; We go through the old list of expirable, and mark all
- ;; really expired articles as nonexistent.
- (unless (eq es expirable) ;If nothing was expired, we don't mark.
- (let ((gnus-use-cache nil))
- (dolist (article expirable)
- (when (and (not (memq article es))
- (gnus-data-find article))
- (gnus-summary-mark-article article gnus-canceled-mark)
- (run-hook-with-args 'gnus-summary-article-expire-hook
- 'delete
- (gnus-data-header
- (assoc article (gnus-data-list nil)))
- gnus-newsgroup-name
- nil
- nil))))))
+ (when (gnus-check-group gnus-newsgroup-name)
+ ;; The list of articles that weren't expired is returned.
+ (save-excursion
+ (if expiry-wait
+ (let ((nnmail-expiry-wait-function nil)
+ (nnmail-expiry-wait expiry-wait))
+ (setq es (gnus-request-expire-articles
+ expirable gnus-newsgroup-name)))
+ (setq es (gnus-request-expire-articles
+ expirable gnus-newsgroup-name)))
+ (unless total
+ (setq gnus-newsgroup-expirable es))
+ ;; We go through the old list of expirable, and mark all
+ ;; really expired articles as nonexistent.
+ (unless (eq es expirable) ;If nothing was expired, we don't mark.
+ (let ((gnus-use-cache nil))
+ (dolist (article expirable)
+ (when (and (not (memq article es))
+ (gnus-data-find article))
+ (gnus-summary-mark-article article gnus-canceled-mark)
+ (run-hook-with-args 'gnus-summary-article-expire-hook
+ 'delete
+ (gnus-data-header
+ (assoc article (gnus-data-list nil)))
+ gnus-newsgroup-name
+ nil
+ nil)))))))
(gnus-message 6 "Expiring articles...done")))))
(defun gnus-summary-expire-articles-now ()
;; The backend might not have been able to delete the article
;; after all.
(unless (memq (car articles) not-deleted)
- (gnus-summary-mark-article (car articles) gnus-canceled-mark))
- (let* ((article (car articles))
- (ghead (gnus-data-header
- (assoc article (gnus-data-list nil)))))
- (run-hook-with-args 'gnus-summary-article-delete-hook
- 'delete ghead gnus-newsgroup-name nil
- nil))
+ (gnus-summary-mark-article (car articles) gnus-canceled-mark)
+ (let* ((article (car articles))
+ (ghead (gnus-data-header
+ (assoc article (gnus-data-list nil)))))
+ (run-hook-with-args 'gnus-summary-article-delete-hook
+ 'delete ghead gnus-newsgroup-name nil
+ nil)))
(setq articles (cdr articles))))
(when not-deleted
(gnus-message 4 "Couldn't delete articles %s" not-deleted)))
gnus-forwarded-mark)
((memq article gnus-newsgroup-saved)
gnus-saved-mark)
- ((memq article gnus-newsgroup-recent)
- gnus-recent-mark)
((memq article gnus-newsgroup-unseen)
gnus-unseen-mark)
(t gnus-no-mark))
(mail-header-subject (gnus-data-header (car data)))))
(t nil)))
(end-point (save-excursion
+ (goto-char (gnus-data-pos (car data)))
(if (gnus-summary-go-to-next-thread)
(point) (point-max))))
articles)
(interactive)
(save-excursion
(goto-char (point-min))
- (let ((end nil))
+ (let ((end nil)
+ (count 0))
(while (not end)
+ (incf count)
+ (when (zerop (mod count 1000))
+ (message "Hiding all threads... %d" count))
(when (or (not predicate)
(gnus-map-articles
predicate (gnus-summary-article-children)))
(let ((ol (gnus-make-overlay starteol (point) nil t nil)))
(gnus-overlay-put ol 'invisible 'gnus-sum)
(gnus-overlay-put ol 'evaporate t)))
- (gnus-summary-goto-subject article))
+ (gnus-summary-goto-subject article)
+ (when (> start (point))
+ (message "Hiding the thread moved us backwards, aborting!")
+ (goto-char (point-max))))
(goto-char start)
nil))))
gnus-summary-save-parts-default-mime)
'gnus-summary-save-parts-type-history)
(setq gnus-summary-save-parts-last-directory
- (read-file-name "Save to directory: "
- gnus-summary-save-parts-last-directory
- nil t))
+ (read-directory-name "Save to directory: "
+ gnus-summary-save-parts-last-directory
+ nil t))
current-prefix-arg))
(gnus-summary-iterate n
(let ((gnus-display-mime-function nil)
mm-file-name-rewrite-functions
(file-name-nondirectory
(or
- (mail-content-type-get
- (mm-handle-disposition handle) 'filename)
- (mail-content-type-get
- (mm-handle-type handle) 'name)
+ (mm-handle-filename handle)
(format "%s.%d.%d" gnus-newsgroup-name
(cdr gnus-article-current)
gnus-summary-save-parts-counter))))
(save-excursion
(let (setmarkundo)
;; Propagate the read marks to the backend.
- (when (and gnus-propagate-marks
+ (when (and (or gnus-propagate-marks
+ (gnus-method-option-p
+ (gnus-find-method-for-group group)
+ 'server-marks))
(gnus-check-backend-function 'request-set-mark group))
(let ((del (gnus-remove-from-range (gnus-info-read info) read))
(add (gnus-remove-from-range read (gnus-info-read info))))
;; Go through all these summary buffers and offer to save them.
(when buffers
(save-excursion
- (map-y-or-n-p
- "Update summary buffer %s? "
- (lambda (buf)
- (switch-to-buffer buf)
- (gnus-summary-exit))
- buffers)))))
+ (if (eq gnus-interactive-exit 'quiet)
+ (dolist (buffer buffers)
+ (switch-to-buffer buffer)
+ (gnus-summary-exit))
+ (map-y-or-n-p
+ "Update summary buffer %s? "
+ (lambda (buf)
+ (switch-to-buffer buf)
+ (gnus-summary-exit))
+ buffers))))))
(defun gnus-summary-setup-default-charset ()
"Setup newsgroup default charset."
gnus-newsgroup-headers
(gnus-fetch-headers articles)
'gnus-article-sort-by-number))
+ (setq gnus-newsgroup-articles
+ (gnus-sorted-nunion gnus-newsgroup-articles articles))
;; Suppress duplicates?
(when gnus-suppress-duplicates
(gnus-dup-suppress-articles))
(when gnus-agent
(gnus-agent-get-undownloaded-list))
;; Remove list identifiers from subject
- (when gnus-list-identifiers
- (gnus-summary-remove-list-identifiers))
+ (gnus-summary-remove-list-identifiers)
;; First and last article in this newsgroup.
(when gnus-newsgroup-headers
(setq gnus-newsgroup-begin
(defun gnus-summary-insert-new-articles ()
"Insert all new articles in this group."
(interactive)
- (prog1
- (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
- (old-high gnus-newsgroup-highest)
- (nnmail-fetched-sources (list t))
- i new)
- (setq gnus-newsgroup-active
- (gnus-copy-sequence
- (gnus-activate-group gnus-newsgroup-name 'scan)))
- (setq i (cdr gnus-newsgroup-active)
- gnus-newsgroup-highest i)
- (while (> i old-high)
- (push i new)
- (decf i))
- (if (not new)
- (message "No gnus is bad news")
- (gnus-summary-insert-articles new)
- (setq gnus-newsgroup-unreads
- (gnus-sorted-nunion gnus-newsgroup-unreads new))
- (gnus-summary-limit (gnus-sorted-nunion old new))))
- (gnus-summary-position-point)))
+ (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
+ (old-high gnus-newsgroup-highest)
+ (nnmail-fetched-sources (list t))
+ (new-active (gnus-activate-group gnus-newsgroup-name 'scan))
+ i new)
+ (unless new-active
+ (error "Couldn't fetch new data"))
+ (setq gnus-newsgroup-active (gnus-copy-sequence new-active))
+ (setq i (cdr gnus-newsgroup-active)
+ gnus-newsgroup-highest i)
+ (while (> i old-high)
+ (push i new)
+ (decf i))
+ (if (not new)
+ (message "No gnus is bad news")
+ (gnus-summary-insert-articles new)
+ (setq gnus-newsgroup-unreads
+ (gnus-sorted-nunion gnus-newsgroup-unreads new))
+ (gnus-summary-limit (gnus-sorted-nunion old new))))
+ (gnus-summary-position-point))
;;; Bookmark support for Gnus.
(declare-function bookmark-make-record-default