;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996,97 Free Software Foundation, Inc.
+;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
;; Keywords: news
(defcustom gnus-simplify-subject-functions nil
"List of functions taking a string argument that simplify subjects.
-The functions are applied recursively."
+The functions are applied recursively.
+
+Useful functions to put in this list include: `gnus-simplify-subject-re',
+`gnus-simplify-subject-fuzzy' and `gnus-simplify-whitespace'."
:group 'gnus-thread
- :type '(repeat (list function)))
+ :type '(repeat function))
(defcustom gnus-simplify-ignored-prefixes nil
"*Regexp, matches for which are removed from subject lines when simplifying fuzzily."
(defcustom gnus-summary-thread-gathering-function
'gnus-gather-threads-by-subject
- "Function used for gathering loose threads.
+ "*Function used for gathering loose threads.
There are two pre-defined functions: `gnus-gather-threads-by-subject',
which only takes Subjects into consideration; and
`gnus-gather-threads-by-references', which compared the References
"*Variable used to suggest where articles are to be moved to.
It uses the same syntax as the `gnus-split-methods' variable."
:group 'gnus-summary-mail
- :type '(repeat (choice (list function)
- (cons regexp (repeat string))
- sexp)))
+ :type '(repeat (choice (list :value (fun) function)
+ (cons :value ("" "") regexp (repeat string))
+ (sexp :value nil))))
(defcustom gnus-unread-mark ?
"*Mark used for unread articles."
:type 'boolean)
(defcustom gnus-summary-dummy-line-format
- "* %(: :%) %S\n"
+ " %(: :%) %S\n"
"*The format specification for the dummy roots in the summary buffer.
It works along the same lines as a normal formatting string,
with some simple extensions.
:group 'gnus-summary-various
:type 'hook)
+(defcustom gnus-summary-prepared-hook nil
+ "*A hook called as the last thing after the summary buffer has been generated."
+ :group 'gnus-summary-various
+ :type 'hook)
+
(defcustom gnus-summary-generate-hook nil
"*A hook run just before generating the summary buffer.
This hook is commonly used to customize threading variables and the
:group 'gnus-summary-visual
:type 'hook)
-;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
(defcustom gnus-structured-field-decoder 'identity
"Function to decode non-ASCII characters in structured field for summary."
:group 'gnus-various
. gnus-summary-high-unread-face)
((and (< score default) (= mark gnus-unread-mark))
. gnus-summary-low-unread-face)
- ((and (= mark gnus-unread-mark))
+ ((= mark gnus-unread-mark)
+ . gnus-summary-normal-unread-face)
+ ((and (> score default) (memq mark (list gnus-downloadable-mark
+ gnus-undownloaded-mark)))
+ . gnus-summary-high-unread-face)
+ ((and (< score default) (memq mark (list gnus-downloadable-mark
+ gnus-undownloaded-mark)))
+ . gnus-summary-low-unread-face)
+ ((memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
. gnus-summary-normal-unread-face)
((> score default)
. gnus-summary-high-read-face)
. gnus-summary-low-read-face)
(t
. gnus-summary-normal-read-face))
- "Controls the highlighting of summary buffer lines.
+ "*Controls the highlighting of summary buffer lines.
A list of (FORM . FACE) pairs. When deciding how a a particular
summary line should be displayed, each form is evaluated. The content
(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))))
" " gnus-summary-next-page
"\177" gnus-summary-prev-page
[delete] gnus-summary-prev-page
+ [backspace] gnus-summary-prev-page
"\r" gnus-summary-scroll-up
"n" gnus-summary-next-unread-article
"p" gnus-summary-prev-unread-article
"\C-c\C-v\C-v" gnus-uu-decode-uu-view
"\C-d" gnus-summary-enter-digest-group
"\M-\C-d" gnus-summary-read-document
+ "\M-\C-e" gnus-summary-edit-parameters
"\C-c\C-b" gnus-bug
"*" gnus-cache-enter-article
"\M-*" gnus-cache-remove-article
"l" gnus-article-date-local
"e" gnus-article-date-lapsed
"o" gnus-article-date-original
+ "i" gnus-article-date-iso8601
"s" gnus-article-date-user)
(gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
"l" gnus-article-strip-leading-blank-lines
"m" gnus-article-strip-multiple-blank-lines
"a" gnus-article-strip-blank-lines
+ "A" gnus-article-strip-all-blank-lines
"s" gnus-article-strip-leading-space)
(gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
["Citation" gnus-article-highlight-citation t])
("Date"
["Local" gnus-article-date-local t]
+ ["ISO8601" gnus-article-date-iso8601 t]
["UT" gnus-article-date-ut t]
["Original" gnus-article-date-original t]
["Lapsed" gnus-article-date-lapsed t]
["Multiple" gnus-article-strip-multiple-blank-lines t]
["Trailing" gnus-article-remove-trailing-blank-lines t]
["All of the above" gnus-article-strip-blank-lines t]
+ ["All" gnus-article-strip-all-blank-lines t]
["Leading space" gnus-article-strip-leading-space t])
["Overstrike" gnus-article-treat-overstrike t]
["Dumb quotes" gnus-article-treat-dumbquotes t]
'request-expire-articles gnus-newsgroup-name)]
["Edit local kill file" gnus-summary-edit-local-kill t]
["Edit main kill file" gnus-summary-edit-global-kill t]
+ ["Edit group parameters" gnus-summary-edit-parameters t]
("Exit"
["Catchup and exit" gnus-summary-catchup-and-exit t]
["Catchup all and exit" gnus-summary-catchup-and-exit t]
["Rescan group" gnus-summary-rescan-group t]
["Update dribble" gnus-summary-save-newsrc t])))
- (run-hooks 'gnus-summary-menu-hook)))
+ (gnus-run-hooks 'gnus-summary-menu-hook)))
(defun gnus-score-set-default (var value)
"A version of set that updates the GNU Emacs menu-bar."
(setq gnus-newsgroup-name group)
(make-local-variable 'gnus-summary-line-format)
(make-local-variable 'gnus-summary-line-format-spec)
+ (make-local-variable 'gnus-summary-dummy-line-format)
+ (make-local-variable 'gnus-summary-dummy-line-format-spec)
(make-local-variable 'gnus-summary-mark-positions)
(make-local-hook 'post-command-hook)
(add-hook 'post-command-hook 'gnus-clear-inboxes-moved nil t)
(make-local-hook 'pre-command-hook)
(add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
- (run-hooks 'gnus-summary-mode-hook)
+ (gnus-run-hooks 'gnus-summary-mode-hook)
(gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
(gnus-update-summary-mark-positions))
(gnus-summary-last-subject))))
(defmacro gnus-summary-article-header (&optional number)
+ "Return the header of article NUMBER."
`(gnus-data-header (gnus-data-find
,(or number '(gnus-summary-article-number)))))
(defmacro gnus-summary-thread-level (&optional number)
+ "Return the level of thread that starts with article NUMBER."
`(if (and (eq gnus-summary-make-false-root 'dummy)
(get-text-property (point) 'gnus-intangible))
0
,(or number '(gnus-summary-article-number))))))
(defmacro gnus-summary-article-mark (&optional number)
+ "Return the mark of article NUMBER."
`(gnus-data-mark (gnus-data-find
,(or number '(gnus-summary-article-number)))))
(defmacro gnus-summary-article-pos (&optional number)
+ "Return the position of the line of article NUMBER."
`(gnus-data-pos (gnus-data-find
,(or number '(gnus-summary-article-number)))))
gnus-summary-default-score 0))
(defun gnus-summary-article-children (&optional number)
+ "Return a list of article numbers that are children of article NUMBER."
(let* ((data (gnus-data-find-list (or number (gnus-summary-article-number))))
(level (gnus-data-level (car data)))
l children)
(nreverse children)))
(defun gnus-summary-article-parent (&optional number)
+ "Return the article number of the parent of article NUMBER."
(let* ((data (gnus-data-find-list (or number (gnus-summary-article-number))
(gnus-data-list t)))
(level (gnus-data-level (car data))))
(= mark gnus-expirable-mark))))
(defmacro gnus-article-mark (number)
+ "Return the MARK of article NUMBER.
+This macro should only be used when computing the mark the \"first\"
+time; i.e., when generating the summary lines. After that,
+`gnus-summary-article-mark' should be used to examine the
+marks of articles."
`(cond
((memq ,number gnus-newsgroup-unsendable) gnus-unsendable-mark)
((memq ,number gnus-newsgroup-undownloaded) gnus-undownloaded-mark)
;; selective display).
(aset table ?\n nil)
(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))
(while (>= (setq i (1- i)) 127)
'gnus-number gnus-tmp-number)
(when (gnus-visual-p 'summary-highlight 'highlight)
(forward-line -1)
- (run-hooks 'gnus-summary-update-hook)
+ (gnus-run-hooks 'gnus-summary-update-hook)
(forward-line 1))))
(defun gnus-summary-update-line (&optional dont-update)
'score))
;; Do visual highlighting.
(when (gnus-visual-p 'summary-highlight 'highlight)
- (run-hooks 'gnus-summary-update-hook)))))
+ (gnus-run-hooks 'gnus-summary-update-hook)))))
(defvar gnus-tmp-new-adopts nil)
(gnus-copy-sequence
(gnus-active gnus-newsgroup-name)))
;; You can change the summary buffer in some way with this hook.
- (run-hooks 'gnus-select-group-hook)
+ (gnus-run-hooks 'gnus-select-group-hook)
;; Set any local variables in the group parameters.
(gnus-summary-set-local-parameters gnus-newsgroup-name)
(gnus-update-format-specifications
((and gnus-newsgroup-scored show-all)
(gnus-summary-limit-include-expunged t))))
;; Function `gnus-apply-kill-file' must be called in this hook.
- (run-hooks 'gnus-apply-kill-hook)
+ (gnus-run-hooks 'gnus-apply-kill-hook)
(if (and (zerop (buffer-size))
(not no-display))
(progn
;; article in the group.
(goto-char (point-min))
(gnus-summary-position-point)
- (gnus-set-mode-line 'summary)
- (gnus-configure-windows 'summary 'force))
+ (gnus-configure-windows 'summary 'force)
+ (gnus-set-mode-line 'summary))
(when (get-buffer-window gnus-group-buffer t)
;; Gotta use windows, because recenter does weird stuff if
;; the current buffer ain't the displayed window.
(select-window owin)))
;; Mark this buffer as "prepared".
(setq gnus-newsgroup-prepared t)
+ (gnus-run-hooks 'gnus-summary-prepared-hook)
t)))))
(defun gnus-summary-prepare ()
(erase-buffer)
(setq gnus-newsgroup-data nil
gnus-newsgroup-data-reverse nil)
- (run-hooks 'gnus-summary-generate-hook)
+ (gnus-run-hooks 'gnus-summary-generate-hook)
;; Generate the buffer, either with threads or without.
(when gnus-newsgroup-headers
(gnus-summary-prepare-threads
(setq gnus-newsgroup-data (nreverse gnus-newsgroup-data))
;; Call hooks for modifying summary buffer.
(goto-char (point-min))
- (run-hooks 'gnus-summary-prepare-hook)))
+ (gnus-run-hooks 'gnus-summary-prepare-hook)))
(defsubst gnus-general-simplify-subject (subject)
"Simply subject by the same rules as gnus-gather-threads-by-subject."
'gnus-number number)
(when gnus-visual-p
(forward-line -1)
- (run-hooks 'gnus-summary-update-hook)
+ (gnus-run-hooks 'gnus-summary-update-hook)
(forward-line 1))
(setq gnus-tmp-prev-subject subject)))
(set-buffer nntp-server-buffer)
;; Translate all TAB characters into SPACE characters.
(subst-char-in-region (point-min) (point-max) ?\t ? t)
- (run-hooks 'gnus-parse-headers-hook)
+ (gnus-run-hooks 'gnus-parse-headers-hook)
(let ((case-fold-search t)
in-reply-to header p lines)
(goto-char (point-min))
(progn
(goto-char p)
(if (search-forward "\nsubject: " nil t)
- ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
(funcall
gnus-unstructured-field-decoder (nnheader-header-value))
"(none)"))
(progn
(goto-char p)
(if (search-forward "\nfrom: " nil t)
- ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
(funcall
gnus-structured-field-decoder (nnheader-header-value))
"(nobody)"))
;; Message-ID.
(progn
(goto-char p)
- (setq id (if (search-forward "\nmessage-id:" nil t)
- (buffer-substring
- (1- (or (search-forward "<" nil t) (point)))
- (or (search-forward ">" nil t) (point)))
+ (setq id (if (re-search-forward
+ "^message-id: *\\(<[^\n\t> ]+>\\)" nil t)
+ ;; We do it this way to make sure the Message-ID
+ ;; is (somewhat) syntactically valid.
+ (buffer-substring (match-beginning 1)
+ (match-end 1))
;; If there was no message-id, we just fake one
;; to make subsequent routines simpler.
(nnheader-generate-fake-message-id))))
(if (and (search-forward "\nin-reply-to: " nil t)
(setq in-reply-to (nnheader-header-value))
(string-match "<[^>]+>" in-reply-to))
- (setq ref (substring in-reply-to (match-beginning 0)
- (match-end 0)))
+ (let (ref2)
+ (setq ref (substring in-reply-to (match-beginning 0)
+ (match-end 0)))
+ (while (string-match "<[^>]+>" in-reply-to (match-end 0))
+ (setq ref2 (substring in-reply-to (match-beginning 0)
+ (match-end 0)))
+ (when (> (length ref2) (length ref))
+ (setq ref ref2))))
(setq ref nil))))
;; Chars.
0
(mail-header-set-id header id))
(setcar (symbol-value id-dep) header))
(set id-dep (list header)))
- (when header
+ (when header
(if (boundp (setq ref-dep (intern (or ref "none") dependencies)))
(setcdr (symbol-value ref-dep)
(nconc (cdr (symbol-value ref-dep))
(setq ref
(buffer-substring
(1+ (point))
- (search-backward "<" beg t)))
+ (or (search-backward "<" beg t) beg)))
(setq ref nil))
(goto-char beg))
(gnus-nov-field)) ; refs
(save-excursion
(set-buffer nntp-server-buffer)
;; Allow the user to mangle the headers before parsing them.
- (run-hooks 'gnus-parse-headers-hook)
+ (gnus-run-hooks 'gnus-parse-headers-hook)
(goto-char (point-min))
(while (not (eobp))
(condition-case ()
(defun gnus-summary-insert-subject (id &optional old-header use-old-header)
"Find article ID and insert the summary line for that article."
- (let ((header (if (and old-header use-old-header)
- old-header (gnus-read-header id)))
+ (let ((header (cond ((and old-header use-old-header)
+ old-header)
+ ((and (numberp id)
+ (gnus-number-to-header id))
+ (gnus-number-to-header id))
+ (t
+ (gnus-read-header id))))
(number (and (numberp id) id))
pos d)
(when header
(delq (setq number (mail-header-number header))
gnus-newsgroup-sparse))
(setq gnus-newsgroup-ancient (delq number gnus-newsgroup-ancient))
+ (push number gnus-newsgroup-limit)
(gnus-rebuild-thread (mail-header-id header))
(gnus-summary-goto-subject number nil t))
(when (and (numberp number)
"Return a list of articles to be worked upon. The prefix argument,
the list of process marked articles, and the current article will be
taken into consideration."
- (cond
- (n
- ;; A numerical prefix has been given.
- (setq n (prefix-numeric-value n))
- (let ((backward (< n 0))
- (n (abs (prefix-numeric-value n)))
- articles article)
- (save-excursion
- (while
- (and (> n 0)
- (push (setq article (gnus-summary-article-number))
- articles)
- (if backward
- (gnus-summary-find-prev nil article)
- (gnus-summary-find-next nil article)))
- (decf n)))
- (nreverse articles)))
- ((gnus-region-active-p)
- ;; Work on the region between point and mark.
- (let ((max (max (point) (mark)))
- articles article)
- (save-excursion
- (goto-char (min (point) (mark)))
- (while
- (and
- (push (setq article (gnus-summary-article-number)) articles)
- (gnus-summary-find-next nil article)
- (< (point) max)))
- (nreverse articles))))
- (gnus-newsgroup-processable
- ;; There are process-marked articles present.
- ;; Save current state.
- (gnus-summary-save-process-mark)
- ;; Return the list.
- (reverse gnus-newsgroup-processable))
- (t
- ;; Just return the current article.
- (list (gnus-summary-article-number)))))
+ (save-excursion
+ (set-buffer gnus-summary-buffer)
+ (cond
+ (n
+ ;; A numerical prefix has been given.
+ (setq n (prefix-numeric-value n))
+ (let ((backward (< n 0))
+ (n (abs (prefix-numeric-value n)))
+ articles article)
+ (save-excursion
+ (while
+ (and (> n 0)
+ (push (setq article (gnus-summary-article-number))
+ articles)
+ (if backward
+ (gnus-summary-find-prev nil article)
+ (gnus-summary-find-next nil article)))
+ (decf n)))
+ (nreverse articles)))
+ ((and (gnus-region-active-p) (mark))
+ (message "region active")
+ ;; Work on the region between point and mark.
+ (let ((max (max (point) (mark)))
+ articles article)
+ (save-excursion
+ (goto-char (min (min (point) (mark))))
+ (while
+ (and
+ (push (setq article (gnus-summary-article-number)) articles)
+ (gnus-summary-find-next nil article)
+ (< (point) max)))
+ (nreverse articles))))
+ (gnus-newsgroup-processable
+ ;; There are process-marked articles present.
+ ;; Save current state.
+ (gnus-summary-save-process-mark)
+ ;; Return the list.
+ (reverse gnus-newsgroup-processable))
+ (t
+ ;; Just return the current article.
+ (list (gnus-summary-article-number))))))
(defun gnus-summary-save-process-mark ()
"Push the current set of process marked articles on the stack."
(defun gnus-summary-update-info (&optional non-destructive)
(save-excursion
(let ((group gnus-newsgroup-name))
- (when gnus-newsgroup-kill-headers
- (setq gnus-newsgroup-killed
- (gnus-compress-sequence
- (nconc
- (gnus-set-sorted-intersection
- (gnus-uncompress-range gnus-newsgroup-killed)
- (setq gnus-newsgroup-unselected
- (sort gnus-newsgroup-unselected '<)))
- (setq gnus-newsgroup-unreads
- (sort gnus-newsgroup-unreads '<)))
- t)))
- (unless (listp (cdr gnus-newsgroup-killed))
- (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
- (let ((headers gnus-newsgroup-headers))
- (when (and (not gnus-save-score)
- (not non-destructive))
- (setq gnus-newsgroup-scored nil))
- ;; Set the new ranges of read articles.
- (save-excursion
+ (when group
+ (when gnus-newsgroup-kill-headers
+ (setq gnus-newsgroup-killed
+ (gnus-compress-sequence
+ (nconc
+ (gnus-set-sorted-intersection
+ (gnus-uncompress-range gnus-newsgroup-killed)
+ (setq gnus-newsgroup-unselected
+ (sort gnus-newsgroup-unselected '<)))
+ (setq gnus-newsgroup-unreads
+ (sort gnus-newsgroup-unreads '<)))
+ t)))
+ (unless (listp (cdr gnus-newsgroup-killed))
+ (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
+ (let ((headers gnus-newsgroup-headers))
+ (when (and (not gnus-save-score)
+ (not non-destructive))
+ (setq gnus-newsgroup-scored nil))
+ ;; Set the new ranges of read articles.
+ (save-excursion
+ (set-buffer gnus-group-buffer)
+ (gnus-undo-force-boundary))
+ (gnus-update-read-articles
+ group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
+ ;; Set the current article marks.
+ (gnus-update-marks)
+ ;; Do the cross-ref thing.
+ (when gnus-use-cross-reference
+ (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)
- (gnus-undo-force-boundary))
- (gnus-update-read-articles
- group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
- ;; Set the current article marks.
- (gnus-update-marks)
- ;; Do the cross-ref thing.
- (when gnus-use-cross-reference
- (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 gnus-newsgroup-name)
- (gnus-group-update-group group))))))
+ (unless (gnus-ephemeral-group-p group)
+ (gnus-group-update-group group)))))))
(defun gnus-summary-save-newsrc (&optional force)
"Save the current number of read/marked articles in the dribble buffer.
"Exit reading current newsgroup, and then return to group selection mode.
gnus-exit-group-hook is called with no arguments if that value is non-nil."
(interactive)
+ (gnus-set-global-variables)
(gnus-kill-save-kill-buffer)
+ (gnus-async-halt-prefetch)
(let* ((group gnus-newsgroup-name)
(quit-config (gnus-group-quit-config gnus-newsgroup-name))
(mode major-mode)
(group-point nil)
(buf (current-buffer)))
- (run-hooks 'gnus-summary-prepare-exit-hook)
+ (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-original-article-buffer)
(gnus-dup-enter-articles))
(when gnus-use-trees
(gnus-tree-close group))
+ ;; Remove entries for this group.
+ (nnmail-purge-split-history (gnus-group-real-name group))
;; Make all changes in this group permanent.
(unless quit-config
- (run-hooks 'gnus-exit-group-hook)
+ (gnus-run-hooks 'gnus-exit-group-hook)
(gnus-summary-update-info)
;; Do adaptive scoring, and possibly save score files.
(when gnus-newsgroup-adaptive
(set-buffer gnus-group-buffer)
(unless quit-config
(gnus-group-jump-to-group group))
- (run-hooks 'gnus-summary-exit-hook)
+ (gnus-run-hooks 'gnus-summary-exit-hook)
(unless (or quit-config
;; If this group has disappeared from the summary
;; buffer, don't skip forwards.
(when (or no-questions
gnus-expert-user
(gnus-y-or-n-p "Discard changes to this group and exit? "))
+ (gnus-async-halt-prefetch)
;; If we have several article buffers, we kill them at exit.
(unless gnus-single-article-buffer
(gnus-kill-buffer gnus-article-buffer)
(defun gnus-kill-or-deaden-summary (buffer)
"Kill or deaden the summary BUFFER."
- (when (and (buffer-name buffer)
- (not gnus-single-article-buffer))
- (save-excursion
- (set-buffer buffer)
- (gnus-kill-buffer gnus-article-buffer)
- (gnus-kill-buffer gnus-original-article-buffer)))
- (cond (gnus-kill-summary-on-exit
- (when (and gnus-use-trees
- (and (get-buffer buffer)
- (buffer-name (get-buffer buffer))))
+ (save-excursion
+ (when (and (buffer-name buffer)
+ (not gnus-single-article-buffer))
+ (save-excursion
+ (set-buffer buffer)
+ (gnus-kill-buffer gnus-article-buffer)
+ (gnus-kill-buffer gnus-original-article-buffer)))
+ (cond (gnus-kill-summary-on-exit
+ (when (and gnus-use-trees
+ (and (get-buffer buffer)
+ (buffer-name (get-buffer buffer))))
+ (save-excursion
+ (set-buffer (get-buffer buffer))
+ (gnus-tree-close gnus-newsgroup-name)))
+ (gnus-kill-buffer buffer))
+ ((and (get-buffer buffer)
+ (buffer-name (get-buffer buffer)))
(save-excursion
- (set-buffer (get-buffer buffer))
- (gnus-tree-close gnus-newsgroup-name)))
- (gnus-kill-buffer buffer))
- ((and (get-buffer buffer)
- (buffer-name (get-buffer buffer)))
- (save-excursion
- (set-buffer buffer)
- (gnus-deaden-summary)))))
+ (set-buffer buffer)
+ (gnus-deaden-summary))))))
(defun gnus-summary-wake-up-the-dead (&rest args)
"Wake up the dead summary buffer."
(when (gnus-buffer-live-p current-buffer)
(set-buffer current-buffer)
(gnus-summary-exit))
- (run-hooks 'gnus-group-no-more-groups-hook))
+ (gnus-run-hooks 'gnus-group-no-more-groups-hook))
;; We try to enter the target group.
(gnus-group-jump-to-group target-group)
(let ((unreads (gnus-group-group-unread)))
(if gnus-summary-display-article-function
(funcall gnus-summary-display-article-function article all-header)
(gnus-article-prepare article all-header))
- (run-hooks 'gnus-select-article-hook)
+ (gnus-run-hooks 'gnus-select-article-hook)
(when (and gnus-current-article
(not (zerop gnus-current-article)))
(gnus-summary-goto-subject gnus-current-article))
(interactive)
(prog1
(when gnus-last-article
- (gnus-summary-goto-article gnus-last-article))
+ (gnus-summary-goto-article gnus-last-article nil t))
(gnus-summary-position-point)))
(defun gnus-summary-pop-article (number)
(gnus-summary-position-point))))
(defun gnus-summary-limit-include-dormant ()
- "Display all the hidden articles that are marked as dormant."
+ "Display all the hidden articles that are marked as dormant.
+Note that this command only works on a subset of the articles currently
+fetched for this group."
(interactive)
(unless gnus-newsgroup-dormant
(error "There are no dormant articles in this group"))
(gnus-summary-article-sparse-p
(mail-header-number header))
(memq (mail-header-number header)
- gnus-newsgroup-limit))))
- (if (and header
- (or (not (gnus-summary-article-sparse-p
- (mail-header-number header)))
- sparse))
- (prog1
- ;; The article is present in the buffer, so we just go to it.
- (gnus-summary-goto-article
- (mail-header-number header) nil t)
- (when sparse
- (gnus-summary-update-article (mail-header-number header))))
+ gnus-newsgroup-limit)))
+ h)
+ (cond
+ ;; If the article is present in the buffer we just go to it.
+ ((and header
+ (or (not (gnus-summary-article-sparse-p
+ (mail-header-number header)))
+ sparse))
+ (prog1
+ (gnus-summary-goto-article
+ (mail-header-number header) nil t)
+ (when sparse
+ (gnus-summary-update-article (mail-header-number header)))))
+ (t
;; We fetch the article
(let ((gnus-override-method
(cond ((gnus-news-group-p gnus-newsgroup-name)
;; Fetch the header, and display the article.
(if (setq number (gnus-summary-insert-subject message-id))
(gnus-summary-select-article nil nil nil number)
- (gnus-message 3 "Couldn't fetch article %s" message-id)))))))
+ (gnus-message 3 "Couldn't fetch article %s" message-id))))))))
+
+(defun gnus-summary-edit-parameters ()
+ "Edit the group parameters of the current group."
+ (gnus-group-edit-group gnus-newsgroup-name 'params))
(defun gnus-summary-enter-digest-group (&optional force)
"Enter an nndoc group based on the current article.
(when gnus-page-broken
(gnus-narrow-to-page))))
-(defun gnus-summary-print-article (&optional filename)
- "Generate and print a PostScript image of the article buffer.
+(defun gnus-summary-print-article (&optional filename n)
+ "Generate and print a PostScript image of the N next (mail) articles.
-If the optional argument FILENAME is nil, send the image to the printer.
-If FILENAME is a string, save the PostScript image in a file with that
-name. If FILENAME is a number, prompt the user for the name of the file
+If N is negative, print the N previous articles. If N is nil and articles
+have been marked with the process mark, print these instead.
+
+If the optional second argument FILENAME is nil, send the image to the
+printer. If FILENAME is a string, save the PostScript image in a file with
+that name. If FILENAME is a number, prompt the user for the name of the file
to save in."
- (interactive (list (ps-print-preprint current-prefix-arg)))
- (gnus-summary-select-article)
- (gnus-eval-in-buffer-window gnus-article-buffer
- (let ((buffer (generate-new-buffer " *print*")))
- (unwind-protect
- (progn
- (copy-to-buffer buffer (point-min) (point-max))
- (set-buffer buffer)
- (gnus-article-delete-invisible-text)
- (run-hooks 'gnus-ps-print-hook)
- (ps-print-buffer-with-faces filename))
- (kill-buffer buffer)))))
+ (interactive (list (ps-print-preprint current-prefix-arg)
+ current-prefix-arg))
+ (dolist (article (gnus-summary-work-articles n))
+ (gnus-summary-select-article nil nil 'pseudo article)
+ (gnus-eval-in-buffer-window gnus-article-buffer
+ (let ((buffer (generate-new-buffer " *print*")))
+ (unwind-protect
+ (progn
+ (copy-to-buffer buffer (point-min) (point-max))
+ (set-buffer buffer)
+ (gnus-article-delete-invisible-text)
+ (let ((ps-left-header
+ (list
+ (concat "("
+ (mail-header-subject gnus-current-headers) ")")
+ (concat "("
+ (mail-header-from gnus-current-headers) ")")))
+ (ps-right-header
+ (list
+ "/pagenumberstring load"
+ (concat "("
+ (mail-header-date gnus-current-headers) ")"))))
+ (gnus-run-hooks 'gnus-ps-print-hook)
+ (ps-print-buffer-with-faces filename)))
+ (kill-buffer buffer))))))
(defun gnus-summary-show-article (&optional arg)
"Force re-fetching of the current article.
(setq e (1- (or (search-forward "\n\n" nil t) (point-max)))))
(insert-buffer-substring gnus-original-article-buffer 1 e)
(let ((article-inhibit-hiding t))
- (run-hooks 'gnus-article-display-hook))
+ (gnus-run-hooks 'gnus-article-display-hook))
(when (or (not hidden) (and (numberp arg) (< arg 0)))
(gnus-article-hide-headers)))))
(when (gnus-visual-p 'page-marker)
(let ((buffer-read-only nil))
(gnus-remove-text-with-property 'gnus-prev)
- (gnus-remove-text-with-property 'gnus-next)))))
+ (gnus-remove-text-with-property 'gnus-next))
+ (setq gnus-page-broken nil))))
(defun gnus-summary-move-article (&optional n to-newsgroup
select-method action)
((eq action 'copy)
(save-excursion
(set-buffer copy-buf)
- (gnus-request-article-this-buffer article gnus-newsgroup-name)
- (gnus-request-accept-article
- to-newsgroup select-method (not articles))))
+ (when (gnus-request-article-this-buffer article gnus-newsgroup-name)
+ (gnus-request-accept-article
+ to-newsgroup select-method (not articles)))))
;; Crosspost the article.
((eq action 'crosspost)
(let ((xref (message-tokenize-header
(gnus-request-replace-article
article gnus-newsgroup-name (current-buffer)))))
+ ;;;!!!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))))
;; We need to update the info for
;; this group for `gnus-list-of-read-articles'
;; to give us the right answer.
- (run-hooks 'gnus-exit-group-hook)
+ (gnus-run-hooks 'gnus-exit-group-hook)
(gnus-summary-update-info)
(gnus-list-of-read-articles gnus-newsgroup-name))
(setq gnus-newsgroup-expirable
;; through the expiry process.
(gnus-message 6 "Expiring articles...")
;; The list of articles that weren't expired is returned.
- (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)))
+ (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
This means that *all* articles that are marked as expirable will be
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? ")
- (error "Phew!"))
+ (unless gnus-expert-user
+ (gnus-yes-or-no-p
+ "Are you really, really, really sure you want to delete all these messages? ")
+ (error "Phew!"))
(gnus-summary-expire-articles t))
;; Suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.
(unless no-highlight
(save-excursion
(set-buffer gnus-article-buffer)
- (run-hooks 'gnus-article-display-hook)
+ (gnus-run-hooks 'gnus-article-display-hook)
(set-buffer gnus-original-article-buffer)
(gnus-request-article
(cdr gnus-article-current)
(car gnus-article-current) (current-buffer))))
;; Prettify the summary buffer line.
(when (gnus-visual-p 'summary-highlight 'highlight)
- (run-hooks 'gnus-visual-mark-article-hook))))
+ (gnus-run-hooks 'gnus-visual-mark-article-hook))))
(defun gnus-summary-edit-wash (key)
"Perform editing command in the article buffer."
(defun gnus-summary-mark-article-as-unread (mark)
"Mark the current article quickly as unread with MARK."
- (let ((article (gnus-summary-article-number)))
- (if (<= article 0)
- (gnus-error 1 "Can't mark negative article numbers")
- (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
- (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
- (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
- (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
- (cond ((= mark gnus-ticked-mark)
- (push article gnus-newsgroup-marked))
- ((= mark gnus-dormant-mark)
- (push article gnus-newsgroup-dormant))
- (t
- (push article gnus-newsgroup-unreads)))
- (setq gnus-newsgroup-reads
- (delq (assq article gnus-newsgroup-reads)
- gnus-newsgroup-reads))
+ (let* ((article (gnus-summary-article-number))
+ (old-mark (gnus-summary-article-mark article)))
+ (if (eq mark old-mark)
+ t
+ (if (<= article 0)
+ (progn
+ (gnus-error 1 "Can't mark negative article numbers")
+ nil)
+ (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+ (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
+ (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
+ (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
+ (cond ((= mark gnus-ticked-mark)
+ (push article gnus-newsgroup-marked))
+ ((= mark gnus-dormant-mark)
+ (push article gnus-newsgroup-dormant))
+ (t
+ (push article gnus-newsgroup-unreads)))
+ (setq gnus-newsgroup-reads
+ (delq (assq article gnus-newsgroup-reads)
+ gnus-newsgroup-reads))
+
+ ;; See whether the article is to be put in the cache.
+ (and gnus-use-cache
+ (vectorp (gnus-summary-article-header article))
+ (save-excursion
+ (gnus-cache-possibly-enter-article
+ gnus-newsgroup-name article
+ (gnus-summary-article-header article)
+ (= mark gnus-ticked-mark)
+ (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
- ;; See whether the article is to be put in the cache.
- (and gnus-use-cache
- (vectorp (gnus-summary-article-header article))
- (save-excursion
- (gnus-cache-possibly-enter-article
- gnus-newsgroup-name article
- (gnus-summary-article-header article)
- (= mark gnus-ticked-mark)
- (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
-
- ;; Fix the mark.
- (gnus-summary-update-mark mark 'unread))
- t))
+ ;; Fix the mark.
+ (gnus-summary-update-mark mark 'unread)
+ t))))
(defun gnus-summary-mark-article (&optional article mark no-expire)
"Mark ARTICLE with MARK. MARK can be any character.
(= mark gnus-duplicate-mark))))
(setq mark gnus-expirable-mark))
(let* ((mark (or mark gnus-del-mark))
- (article (or article (gnus-summary-article-number))))
- (unless article
- (error "No article on current line"))
- (if (or (= mark gnus-unread-mark)
- (= mark gnus-ticked-mark)
- (= mark gnus-dormant-mark))
- (gnus-mark-article-as-unread article mark)
- (gnus-mark-article-as-read article mark))
-
- ;; See whether the article is to be put in the cache.
- (and gnus-use-cache
- (not (= mark gnus-canceled-mark))
- (vectorp (gnus-summary-article-header article))
- (save-excursion
- (gnus-cache-possibly-enter-article
- gnus-newsgroup-name article
- (gnus-summary-article-header article)
- (= mark gnus-ticked-mark)
- (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
-
- (when (gnus-summary-goto-subject article nil t)
- (let ((buffer-read-only nil))
- (gnus-summary-show-thread)
- ;; Fix the mark.
- (gnus-summary-update-mark mark 'unread)
- t))))
+ (article (or article (gnus-summary-article-number)))
+ (old-mark (gnus-summary-article-mark article)))
+ (if (eq mark old-mark)
+ t
+ (unless article
+ (error "No article on current line"))
+ (if (not (if (or (= mark gnus-unread-mark)
+ (= mark gnus-ticked-mark)
+ (= mark gnus-dormant-mark))
+ (gnus-mark-article-as-unread article mark)
+ (gnus-mark-article-as-read article mark)))
+ t
+ ;; See whether the article is to be put in the cache.
+ (and gnus-use-cache
+ (not (= mark gnus-canceled-mark))
+ (vectorp (gnus-summary-article-header article))
+ (save-excursion
+ (gnus-cache-possibly-enter-article
+ gnus-newsgroup-name article
+ (gnus-summary-article-header article)
+ (= mark gnus-ticked-mark)
+ (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
+
+ (when (gnus-summary-goto-subject article nil t)
+ (let ((buffer-read-only nil))
+ (gnus-summary-show-thread)
+ ;; Fix the mark.
+ (gnus-summary-update-mark mark 'unread)
+ t))))))
(defun gnus-summary-update-secondary-mark (article)
"Update the secondary (read, process, cache) mark."
(t gnus-unread-mark))
'replied)
(when (gnus-visual-p 'summary-highlight 'highlight)
- (run-hooks 'gnus-summary-update-hook))
+ (gnus-run-hooks 'gnus-summary-update-hook))
t)
(defun gnus-summary-update-mark (mark type)
(push (cons article mark) gnus-newsgroup-reads)
;; Possibly remove from cache, if that is used.
(when gnus-use-cache
- (gnus-cache-enter-remove-article article))))
+ (gnus-cache-enter-remove-article article))
+ t))
(defun gnus-mark-article-as-unread (article &optional mark)
"Enter ARTICLE in the pertinent lists and remove it from others."
(let ((mark (or mark gnus-ticked-mark)))
- (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)
- gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant)
- gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)
- gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
-
(if (<= article 0)
(progn
(gnus-error 1 "Can't mark negative article numbers")
nil)
+ (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)
+ gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant)
+ gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)
+ gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
+
;; Unsuppress duplicates?
(when gnus-suppress-duplicates
(gnus-dup-unsuppress-article article))
(when all
(setq gnus-newsgroup-marked nil
gnus-newsgroup-dormant nil))
- (setq gnus-newsgroup-unreads nil))
+ (setq gnus-newsgroup-unreads gnus-newsgroup-downloadable))
;; We actually mark all articles as canceled, which we
;; have to do when using auto-expiry or adaptive scoring.
(gnus-summary-show-all-threads)
(gnus-summary-article-header parent-article))))
(unless (and message-id (not (equal message-id "")))
(error "No message-id in desired parent"))
- (gnus-summary-select-article t t nil current-article)
+ ;; We don't want the article to be marked as read.
+ (let (gnus-mark-article-hook)
+ (gnus-summary-select-article t t nil current-article))
(set-buffer gnus-original-article-buffer)
(let ((buf (format "%s" (buffer-string))))
(nnheader-temp-write nil
(cond ((assq 'execute props)
(gnus-execute-command (cdr (assq 'execute props)))))
(let ((gnus-current-article (gnus-summary-article-number)))
- (run-hooks 'gnus-mark-article-hook)))
+ (gnus-run-hooks 'gnus-mark-article-hook)))
(defun gnus-execute-command (command &optional automatic)
(save-excursion
(not (gnus-summary-article-sparse-p (mail-header-number header))))
;; We have found the header.
header
+ ;; If this is a sparse article, we have to nix out its
+ ;; previous entry in the thread hashtb.
+ (when (and header
+ (gnus-summary-article-sparse-p (mail-header-number header)))
+ (let* ((parent (gnus-parent-id (mail-header-references header)))
+ (thread
+ (and parent
+ (gnus-gethash parent gnus-newsgroup-dependencies))))
+ (when thread
+ (delq (assq header thread) thread))))
;; We have to really fetch the header to this article.
(save-excursion
(set-buffer nntp-server-buffer)
(when buffers
(map-y-or-n-p
"Update summary buffer %s? "
- (lambda (buf) (switch-to-buffer buf) (gnus-summary-exit))
+ (lambda (buf)
+ (switch-to-buffer buf)
+ (gnus-summary-exit))
buffers)))))
(gnus-ems-redefine)