;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;;; Code:
-(eval-when-compile (require 'cl))
+(eval-when-compile
+ (require 'cl)
+ (defvar tool-bar-map))
(require 'gnus)
(require 'gnus-group)
(autoload 'gnus-article-outlook-deuglify-article "deuglify"
"Deuglify broken Outlook (Express) articles and redisplay."
t)
+(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)
(defcustom gnus-kill-summary-on-exit t
"*If non-nil, kill the summary buffer when you exit from it.
(const adopt)
(const empty)))
+(defcustom gnus-summary-make-false-root-always nil
+ "Always make a false dummy root."
+ :group 'gnus-thread
+ :type 'boolean)
+
(defcustom gnus-summary-gather-exclude-subject "^ *$\\|^(none)$"
"*A regexp to match subjects to be excluded from loose thread gathering.
As loose thread gathering is done on subjects only, that means that
:type '(repeat function))
(defcustom gnus-simplify-ignored-prefixes nil
- "*Regexp, matches for which are removed from subject lines when simplifying fuzzily."
+ "*Remove matches for this regexp from subject lines when simplifying fuzzily."
:group 'gnus-thread
:type '(choice (const :tag "off" nil)
regexp))
the end of an article.
If nil, the marking commands do NOT go to the next unread article
-(they go to the next article instead). If `never', commands that
+\(they go to the next article instead). If `never', commands that
usually go to the next unread article, will go to the next article,
whether it is read or not."
:group 'gnus-summary-marks
`gnus-summary-show-thread' by hand or use `gnus-select-article-hook'
to expose hidden threads."
:group 'gnus-thread
- :type 'boolean)
+ :type '(radio (sexp :format "Non-nil\n"
+ :match (lambda (widget value)
+ (not (or (consp value) (functionp value))))
+ :value t)
+ (const nil)
+ (sexp :tag "Predicate specifier" :size 0)))
(defcustom gnus-thread-hide-killed t
"*If non-nil, hide killed threads automatically."
(defcustom gnus-auto-select-next t
"*If non-nil, offer to go to the next group from the end of the previous.
If the value is t and the next newsgroup is empty, Gnus will exit
-summary mode and go back to group mode. If the value is neither nil
-nor t, Gnus will select the following unread newsgroup. In
+summary mode and go back to group mode. If the value is neither nil
+nor t, Gnus will select the following unread newsgroup. In
particular, if the value is the symbol `quietly', the next unread
newsgroup will be selected without any confirmation, and if it is
`almost-quietly', the next group will be selected without any
confirmation if you are located on the last article in the group.
-Finally, if this variable is `slightly-quietly', the `Z n' command
+Finally, if this variable is `slightly-quietly', the `\\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]' command
will go to the next group without confirmation."
:group 'gnus-summary-maneuvering
:type '(choice (const :tag "off" nil)
:group 'gnus-summary-maneuvering
:type 'boolean)
+(defcustom gnus-auto-goto-ignores 'unfetched
+ "*Says how to handle unfetched articles when maneuvering.
+
+This variable can either be the symbols nil (maneuver to any
+article), `undownloaded' (maneuvering while unplugged ignores articles
+that have not been fetched), `always-undownloaded' (maneuvering always
+ignores articles that have not been fetched), `unfetched' (maneuvering
+ignores articles whose headers have not been fetched).
+
+NOTE: The list of unfetched articles will always be nil when plugged
+and, when unplugged, a subset of the undownloaded article list."
+ :group 'gnus-summary-maneuvering
+ :type '(choice (const :tag "None" nil)
+ (const :tag "Undownloaded when unplugged" undownloaded)
+ (const :tag "Undownloaded" always-undownloaded)
+ (const :tag "Unfetched" unfetched)))
+
(defcustom gnus-summary-check-current nil
"*If non-nil, consider the current article when moving.
The \"unread\" movement commands will stay on the same line if the
(integer :tag "height")
(sexp :menu-tag "both" t)))
+(defvar gnus-auto-center-group t
+ "*If non-nil, always center the group buffer.")
+
(defcustom gnus-show-all-headers nil
"*If non-nil, don't hide any headers."
:group 'gnus-article-hiding
:group 'gnus-summary-marks
:type 'character)
-(defcustom gnus-spam-mark ?H
+(defcustom gnus-spam-mark ?$
"*Mark used for spam articles."
:group 'gnus-summary-marks
:type 'character)
:group 'gnus-summary-marks
:type 'character)
-(defcustom gnus-undownloaded-mark ?@
+(defcustom gnus-undownloaded-mark ?-
"*Mark used for articles that weren't downloaded."
:group 'gnus-summary-marks
:type 'character)
+(defcustom gnus-downloaded-mark ?+
+ "*Mark used for articles that were downloaded."
+ :group 'gnus-summary-marks
+ :type 'character)
+
(defcustom gnus-downloadable-mark ?%
"*Mark used for articles that are to be downloaded."
:group 'gnus-summary-marks
: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.
(defcustom gnus-select-article-hook nil
"*A hook called when an article is selected."
:group 'gnus-summary-choose
+ :options '(gnus-agent-fetch-selected-article)
:type 'hook)
(defcustom gnus-visual-mark-article-hook
:group 'gnus-summary
:type 'hook)
+(defcustom gnus-summary-article-move-hook nil
+ "*A hook called after an article is moved, copied, respooled, or crossposted."
+ :group 'gnus-summary
+ :type 'hook)
+
+(defcustom gnus-summary-article-delete-hook nil
+ "*A hook called after an article is deleted."
+ :group 'gnus-summary
+ :type 'hook)
+
+(defcustom gnus-summary-article-expire-hook nil
+ "*A hook called after an article is expired."
+ :group 'gnus-summary
+ :type 'hook)
+
(defcustom gnus-summary-display-arrow
(and (fboundp 'display-graphic-p)
(display-graphic-p))
:group 'gnus-summary-visual
:type 'face)
+(defvar gnus-tmp-downloaded nil)
+
(defcustom gnus-summary-highlight
'(((eq mark gnus-canceled-mark)
. gnus-summary-cancelled-face)
+ ((and uncached (> score default-high))
+ . gnus-summary-high-undownloaded-face)
+ ((and uncached (< score default-low))
+ . gnus-summary-low-undownloaded-face)
+ (uncached
+ . gnus-summary-normal-undownloaded-face)
((and (> score default-high)
(or (eq mark gnus-dormant-mark)
(eq mark gnus-ticked-mark)))
. gnus-summary-low-unread-face)
((eq mark gnus-unread-mark)
. gnus-summary-normal-unread-face)
- ((and (> score default-high) (memq mark (list gnus-downloadable-mark
- gnus-undownloaded-mark)))
- . gnus-summary-high-unread-face)
- ((and (< score default-low) (memq mark (list gnus-downloadable-mark
- gnus-undownloaded-mark)))
- . gnus-summary-low-unread-face)
- ((and (memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
- (memq article gnus-newsgroup-unreads))
- . gnus-summary-normal-unread-face)
- ((memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
- . gnus-summary-normal-read-face)
((> score default-high)
. gnus-summary-high-read-face)
((< score default-low)
default-high: The default score for high scored articles.
default-low: The default score for low scored articles.
below: The score below which articles are automatically marked as read.
-mark: The articles mark."
+mark: The article's mark.
+uncached: Non-nil if the article is uncached."
:group 'gnus-summary-visual
:type '(repeat (cons (sexp :tag "Form" nil)
face)))
(defcustom gnus-alter-header-function nil
"Function called to allow alteration of article header structures.
The function is called with one parameter, the article header vector,
-which it may alter in any way.")
+which it may alter in any way."
+ :type '(choice (const :tag "None" nil)
+ function)
+ :group 'gnus-summary)
(defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
"Variable that says which function should be used to decode a string with encoded words.")
integer))
(defcustom gnus-summary-save-parts-default-mime "image/.*"
- "*A regexp to match MIME parts when saving multiple parts of a message
-with gnus-summary-save-parts (X m). This regexp will be used by default
-when prompting the user for which type of files to save."
+ "*A regexp to match MIME parts when saving multiple parts of a
+message with `gnus-summary-save-parts' (\\<gnus-summary-mode-map>\\[gnus-summary-save-parts]).
+This regexp will be used by default when prompting the user for which
+type of files to save."
:group 'gnus-summary
:type 'regexp)
(defcustom gnus-read-all-available-headers nil
"Whether Gnus should parse all headers made available to it.
-This is mostly relevant for slow backends where the user may
+This is mostly relevant for slow back ends where the user may
wish to widen the summary buffer to include all headers
that were fetched. Say, for nnultimate groups."
:group 'gnus-summary
the MIME-Version header is missed."
:version "21.3"
:type 'boolean
- :group 'gnus-article)
+ :group 'gnus-article-mime)
+
+(defcustom gnus-article-emulate-mime t
+ "If non-nil, use MIME emulation for uuencode and the like.
+This means that Gnus will search message bodies for text that look
+like uuencoded bits, yEncoded bits, and so on, and present that using
+the normal Gnus MIME machinery."
+ :type 'boolean
+ :group 'gnus-article-mime)
;;; Internal variables
(defvar gnus-article-ignored-charsets nil)
(defvar gnus-scores-exclude-files nil)
(defvar gnus-page-broken nil)
-(defvar gnus-inhibit-mime-unbuttonizing nil)
(defvar gnus-original-article nil)
(defvar gnus-article-internal-prepare-hook nil)
"Function called to sort the articles within a thread after it has been gathered together.")
(defvar gnus-summary-save-parts-type-history nil)
-(defvar gnus-summary-save-parts-last-directory nil)
+(defvar gnus-summary-save-parts-last-directory mm-default-directory)
;; Avoid highlighting in kill files.
(defvar gnus-summary-inhibit-highlight nil)
(?M ,(macroexpand '(mail-header-id gnus-tmp-header)) ?s)
(?r ,(macroexpand '(mail-header-references gnus-tmp-header)) ?s)
(?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)
+ (?O gnus-tmp-downloaded ?c)
(?I gnus-tmp-indentation ?s)
(?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s)
(?R gnus-tmp-replied ?c)
(defvar gnus-last-shell-command nil
"Default shell command on article.")
+(defvar gnus-newsgroup-agentized nil
+ "Locally bound in each summary buffer to indicate whether the server has been agentized.")
(defvar gnus-newsgroup-begin nil)
(defvar gnus-newsgroup-end nil)
(defvar gnus-newsgroup-last-rmail nil)
(defvar gnus-newsgroup-data-reverse nil)
(defvar gnus-newsgroup-limit nil)
(defvar gnus-newsgroup-limits nil)
+(defvar gnus-summary-use-undownloaded-faces nil)
(defvar gnus-newsgroup-unreads nil
"Sorted list of unread articles in the current newsgroup.")
(defvar gnus-newsgroup-downloadable nil
"Sorted list of articles in the current newsgroup that can be processed.")
+(defvar gnus-newsgroup-unfetched nil
+ "Sorted list of articles in the current newsgroup whose headers have
+not been fetched into the agent.
+
+This list will always be a subset of gnus-newsgroup-undownloaded.")
+
(defvar gnus-newsgroup-undownloaded nil
- "List of articles in the current newsgroup that haven't been downloaded..")
+ "List of articles in the current newsgroup that haven't been downloaded.")
(defvar gnus-newsgroup-unsendable nil
"List of articles in the current newsgroup that won't be sent.")
(defvar gnus-article-before-search nil)
-(defconst gnus-summary-local-variables
+(defvar gnus-summary-local-variables
'(gnus-newsgroup-name
gnus-newsgroup-begin gnus-newsgroup-end
gnus-newsgroup-last-rmail gnus-newsgroup-last-mail
gnus-newsgroup-expirable
gnus-newsgroup-processable gnus-newsgroup-killed
gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
+ gnus-newsgroup-unfetched
gnus-newsgroup-unsendable gnus-newsgroup-unseen
gnus-newsgroup-seen gnus-newsgroup-articles
gnus-newsgroup-bookmarks gnus-newsgroup-dormant
gnus-cache-removable-articles gnus-newsgroup-cached
gnus-newsgroup-data gnus-newsgroup-data-reverse
gnus-newsgroup-limit gnus-newsgroup-limits
- gnus-newsgroup-charset gnus-newsgroup-display)
+ gnus-newsgroup-charset gnus-newsgroup-display
+ gnus-summary-use-undownloaded-faces)
"Variables that are buffer-local to the summary buffers.")
(defvar gnus-newsgroup-variables nil
")
;; Byte-compiler warning.
-(eval-when-compile (defvar gnus-article-mode-map))
+(eval-when-compile
+ ;; Bind features so that require will believe that gnus-sum has
+ ;; already been loaded (avoids infinite recursion)
+ (let ((features (cons 'gnus-sum features)))
+ ;; Several of the declarations in gnus-sum are needed to load the
+ ;; following files. Right now, these definitions have been
+ ;; compiled but not defined (evaluated). We could either do a
+ ;; eval-and-compile about all of the declarations or evaluate the
+ ;; source file.
+ (if (boundp 'gnus-newsgroup-variables)
+ nil
+ (load "gnus-sum.el" t t t))
+ (require 'gnus)
+ (require 'gnus-agent)
+ (require 'gnus-art)))
;; MIME stuff.
(defun gnus-simplify-whitespace (str)
"Remove excessive whitespace from STR."
- (let ((mystr str))
- ;; Multiple spaces.
- (while (string-match "[ \t][ \t]+" mystr)
- (setq mystr (concat (substring mystr 0 (match-beginning 0))
- " "
- (substring mystr (match-end 0)))))
- ;; Leading spaces.
- (when (string-match "^[ \t]+" mystr)
- (setq mystr (substring mystr (match-end 0))))
- ;; Trailing spaces.
- (when (string-match "[ \t]+$" mystr)
- (setq mystr (substring mystr 0 (match-beginning 0))))
- mystr))
+ ;; Multiple spaces.
+ (while (string-match "[ \t][ \t]+" str)
+ (setq str (concat (substring str 0 (match-beginning 0))
+ " "
+ (substring str (match-end 0)))))
+ ;; Leading spaces.
+ (when (string-match "^[ \t]+" str)
+ (setq str (substring str (match-end 0))))
+ ;; Trailing spaces.
+ (when (string-match "[ \t]+$" str)
+ (setq str (substring str 0 (match-beginning 0))))
+ str)
(defun gnus-simplify-all-whitespace (str)
"Remove all whitespace from STR."
- (let ((mystr str))
- (while (string-match "[ \t\n]+" mystr)
- (setq mystr (replace-match "" nil nil mystr)))
- mystr))
+ (while (string-match "[ \t\n]+" str)
+ (setq str (replace-match "" nil nil str)))
+ str)
(defsubst gnus-simplify-subject-re (subject)
"Remove \"Re:\" from subject lines."
(buffer-string))))
(defsubst gnus-simplify-subject-fully (subject)
- "Simplify a subject string according to gnus-summary-gather-subject-limit."
+ "Simplify a subject string according to `gnus-summary-gather-subject-limit'."
(cond
(gnus-simplify-subject-functions
(gnus-map-function gnus-simplify-subject-functions subject))
(defsubst gnus-subject-equal (s1 s2 &optional simple-first)
"Check whether two subjects are equal.
-If optional argument simple-first is t, first argument is already
+If optional argument SIMPLE-FIRST is t, first argument is already
simplified."
(cond
((null simple-first)
(defvar gnus-article-commands-menu)
-(when t
- ;; Non-orthogonal keys
-
- (gnus-define-keys gnus-summary-mode-map
- " " gnus-summary-next-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- [backspace] gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\M-\C-n" gnus-summary-next-same-subject
- "\M-\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "." gnus-summary-first-unread-article
- "," gnus-summary-best-unread-article
- "\M-s" gnus-summary-search-article-forward
- "\M-r" gnus-summary-search-article-backward
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "j" gnus-summary-goto-article
- "^" gnus-summary-refer-parent-article
- "\M-^" gnus-summary-refer-article
- "u" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "U" gnus-summary-tick-article-backward
- "d" gnus-summary-mark-as-read-forward
- "D" gnus-summary-mark-as-read-backward
- "E" gnus-summary-mark-as-expirable
- "\M-u" gnus-summary-clear-mark-forward
- "\M-U" gnus-summary-clear-mark-backward
- "k" gnus-summary-kill-same-subject-and-select
- "\C-k" gnus-summary-kill-same-subject
- "\M-\C-k" gnus-summary-kill-thread
- "\M-\C-l" gnus-summary-lower-thread
- "e" gnus-summary-edit-article
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "\M-\C-t" gnus-summary-toggle-threads
- "\M-\C-s" gnus-summary-show-thread
- "\M-\C-h" gnus-summary-hide-thread
- "\M-\C-f" gnus-summary-next-thread
- "\M-\C-b" gnus-summary-prev-thread
- [(meta down)] gnus-summary-next-thread
- [(meta up)] gnus-summary-prev-thread
- "\M-\C-u" gnus-summary-up-thread
- "\M-\C-d" gnus-summary-down-thread
- "&" gnus-summary-execute-command
- "c" gnus-summary-catchup-and-exit
- "\C-w" gnus-summary-mark-region-as-read
- "\C-t" gnus-summary-toggle-truncation
- "?" gnus-summary-mark-as-dormant
- "\C-c\M-\C-s" gnus-summary-limit-include-expunged
- "\C-c\C-s\C-n" gnus-summary-sort-by-number
- "\C-c\C-s\C-l" gnus-summary-sort-by-lines
- "\C-c\C-s\C-c" gnus-summary-sort-by-chars
- "\C-c\C-s\C-a" gnus-summary-sort-by-author
- "\C-c\C-s\C-s" gnus-summary-sort-by-subject
- "\C-c\C-s\C-d" gnus-summary-sort-by-date
- "\C-c\C-s\C-i" gnus-summary-sort-by-score
- "\C-c\C-s\C-o" gnus-summary-sort-by-original
- "\C-c\C-s\C-r" gnus-summary-sort-by-random
- "=" gnus-summary-expand-window
- "\C-x\C-s" gnus-summary-reselect-current-group
- "\M-g" gnus-summary-rescan-group
- "w" gnus-summary-stop-page-breaking
- "\C-c\C-r" gnus-summary-caesar-message
- "f" gnus-summary-followup
- "F" gnus-summary-followup-with-original
- "C" gnus-summary-cancel-article
- "r" gnus-summary-reply
- "R" gnus-summary-reply-with-original
- "\C-c\C-f" gnus-summary-mail-forward
- "o" gnus-summary-save-article
- "\C-o" gnus-summary-save-article-mail
- "|" gnus-summary-pipe-output
- "\M-k" gnus-summary-edit-local-kill
- "\M-K" gnus-summary-edit-global-kill
- ;; "V" gnus-version
- "\C-c\C-d" gnus-summary-describe-group
- "q" gnus-summary-exit
- "Q" gnus-summary-exit-no-update
- "\C-c\C-i" gnus-info-find-node
- gnus-mouse-2 gnus-mouse-pick-article
- "m" gnus-summary-mail-other-window
- "a" gnus-summary-post-news
- "i" gnus-summary-news-other-window
- "x" gnus-summary-limit-to-unread
- "s" gnus-summary-isearch-article
- "t" gnus-summary-toggle-header
- "g" gnus-summary-show-article
- "l" gnus-summary-goto-last-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
- "\M-\C-a" gnus-summary-customize-parameters
- "\C-c\C-b" gnus-bug
- "*" gnus-cache-enter-article
- "\M-*" gnus-cache-remove-article
- "\M-&" gnus-summary-universal-argument
- "\C-l" gnus-recenter
- "I" gnus-summary-increase-score
- "L" gnus-summary-lower-score
- "\M-i" gnus-symbolic-argument
- "h" gnus-summary-select-article-buffer
-
- "b" gnus-article-view-part
- "\M-t" gnus-summary-toggle-display-buttonized
-
- "V" gnus-summary-score-map
- "X" gnus-uu-extract-map
- "S" gnus-summary-send-map)
-
- ;; Sort of orthogonal keymap
- (gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
- "t" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "d" gnus-summary-mark-as-read-forward
- "r" gnus-summary-mark-as-read-forward
- "c" gnus-summary-clear-mark-forward
- " " gnus-summary-clear-mark-forward
- "e" gnus-summary-mark-as-expirable
- "x" gnus-summary-mark-as-expirable
- "?" gnus-summary-mark-as-dormant
- "b" gnus-summary-set-bookmark
- "B" gnus-summary-remove-bookmark
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "S" gnus-summary-limit-include-expunged
- "C" gnus-summary-catchup
- "H" gnus-summary-catchup-to-here
- "h" gnus-summary-catchup-from-here
- "\C-c" gnus-summary-catchup-all
- "k" gnus-summary-kill-same-subject-and-select
- "K" gnus-summary-kill-same-subject
- "P" gnus-uu-mark-map)
-
- (gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
- "c" gnus-summary-clear-above
- "u" gnus-summary-tick-above
- "m" gnus-summary-mark-above
- "k" gnus-summary-kill-below)
-
- (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
- "/" gnus-summary-limit-to-subject
- "n" gnus-summary-limit-to-articles
- "w" gnus-summary-pop-limit
- "s" gnus-summary-limit-to-subject
- "a" gnus-summary-limit-to-author
- "u" gnus-summary-limit-to-unread
- "m" gnus-summary-limit-to-marks
- "M" gnus-summary-limit-exclude-marks
- "v" gnus-summary-limit-to-score
- "*" gnus-summary-limit-include-cached
- "D" gnus-summary-limit-include-dormant
- "T" gnus-summary-limit-include-thread
- "d" gnus-summary-limit-exclude-dormant
- "t" gnus-summary-limit-to-age
- "x" gnus-summary-limit-to-extra
- "p" gnus-summary-limit-to-display-predicate
- "E" gnus-summary-limit-include-expunged
- "c" gnus-summary-limit-exclude-childless-dormant
- "C" gnus-summary-limit-mark-excluded-as-read
- "o" gnus-summary-insert-old-articles
- "N" gnus-summary-insert-new-articles)
-
- (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\C-n" gnus-summary-next-same-subject
- "\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "f" gnus-summary-first-unread-article
- "b" gnus-summary-best-unread-article
- "j" gnus-summary-goto-article
- "g" gnus-summary-goto-subject
- "l" gnus-summary-goto-last-article
- "o" gnus-summary-pop-article)
-
- (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
- "k" gnus-summary-kill-thread
- "l" gnus-summary-lower-thread
- "i" gnus-summary-raise-thread
- "T" gnus-summary-toggle-threads
- "t" gnus-summary-rethread-current
- "^" gnus-summary-reparent-thread
- "s" gnus-summary-show-thread
- "S" gnus-summary-show-all-threads
- "h" gnus-summary-hide-thread
- "H" gnus-summary-hide-all-threads
- "n" gnus-summary-next-thread
- "p" gnus-summary-prev-thread
- "u" gnus-summary-up-thread
- "o" gnus-summary-top-thread
- "d" gnus-summary-down-thread
- "#" gnus-uu-mark-thread
- "\M-#" gnus-uu-unmark-thread)
-
- (gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
- "g" gnus-summary-prepare
- "c" gnus-summary-insert-cached-articles)
-
- (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
- "c" gnus-summary-catchup-and-exit
- "C" gnus-summary-catchup-all-and-exit
- "E" gnus-summary-exit-no-update
- "Q" gnus-summary-exit
- "Z" gnus-summary-exit
- "n" gnus-summary-catchup-and-goto-next-group
- "R" gnus-summary-reselect-current-group
- "G" gnus-summary-rescan-group
- "N" gnus-summary-next-group
- "s" gnus-summary-save-newsrc
- "P" gnus-summary-prev-group)
-
- (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
- " " gnus-summary-next-page
- "n" gnus-summary-next-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- "p" gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "b" gnus-summary-beginning-of-article
- "e" gnus-summary-end-of-article
- "^" gnus-summary-refer-parent-article
- "r" gnus-summary-refer-parent-article
- "D" gnus-summary-enter-digest-group
- "R" gnus-summary-refer-references
- "T" gnus-summary-refer-thread
- "g" gnus-summary-show-article
- "s" gnus-summary-isearch-article
- "P" gnus-summary-print-article
- "M" gnus-mailing-list-insinuate
- "t" gnus-article-babel)
-
- (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
- "b" gnus-article-add-buttons
- "B" gnus-article-add-buttons-to-head
- "o" gnus-article-treat-overstrike
- "e" gnus-article-emphasize
- "w" gnus-article-fill-cited-article
- "Q" gnus-article-fill-long-lines
- "C" gnus-article-capitalize-sentences
- "c" gnus-article-remove-cr
- "q" gnus-article-de-quoted-unreadable
- "6" gnus-article-de-base64-unreadable
- "Z" gnus-article-decode-HZ
- "h" gnus-article-wash-html
- "u" gnus-article-unsplit-urls
- "s" gnus-summary-force-verify-and-decrypt
- "f" gnus-article-display-x-face
- "l" gnus-summary-stop-page-breaking
- "r" gnus-summary-caesar-message
- "t" gnus-summary-toggle-header
- "g" gnus-treat-smiley
- "v" gnus-summary-verbose-headers
- "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
- "p" gnus-article-verify-x-pgp-sig
- "d" gnus-article-treat-dumbquotes
- "k" gnus-article-outlook-deuglify-article)
-
- (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
- "a" gnus-article-hide
- "h" gnus-article-hide-headers
- "b" gnus-article-hide-boring-headers
- "s" gnus-article-hide-signature
- "c" gnus-article-hide-citation
- "C" gnus-article-hide-citation-in-followups
- "l" gnus-article-hide-list-identifiers
- "p" gnus-article-hide-pgp
- "B" gnus-article-strip-banner
- "P" gnus-article-hide-pem
- "\C-c" gnus-article-hide-citation-maybe)
-
- (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
- "a" gnus-article-highlight
- "h" gnus-article-highlight-headers
- "c" gnus-article-highlight-citation
- "s" gnus-article-highlight-signature)
-
- (gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
- "f" gnus-article-treat-fold-headers
- "u" gnus-article-treat-unfold-headers
- "n" gnus-article-treat-fold-newsgroups)
-
- (gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
- "x" gnus-article-display-x-face
- "s" gnus-treat-smiley
- "D" gnus-article-remove-images
- "f" gnus-treat-from-picon
- "m" gnus-treat-mail-picon
- "n" gnus-treat-newsgroups-picon)
-
- (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
- "w" gnus-article-decode-mime-words
- "c" gnus-article-decode-charset
- "v" gnus-mime-view-all-parts
- "b" gnus-article-view-part)
-
- (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
- "z" gnus-article-date-ut
- "u" gnus-article-date-ut
- "l" gnus-article-date-local
- "p" gnus-article-date-english
- "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)
- "t" gnus-article-remove-trailing-blank-lines
- "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
- "e" gnus-article-strip-trailing-space
- "w" gnus-article-remove-leading-whitespace)
-
- (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
- "v" gnus-version
- "f" gnus-summary-fetch-faq
- "d" gnus-summary-describe-group
- "h" gnus-summary-describe-briefly
- "i" gnus-info-find-node)
-
- (gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
- "e" gnus-summary-expire-articles
- "\M-\C-e" gnus-summary-expire-articles-now
- "\177" gnus-summary-delete-article
- [delete] gnus-summary-delete-article
- [backspace] gnus-summary-delete-article
- "m" gnus-summary-move-article
- "r" gnus-summary-respool-article
- "w" gnus-summary-edit-article
- "c" gnus-summary-copy-article
- "B" gnus-summary-crosspost-article
- "q" gnus-summary-respool-query
- "t" gnus-summary-respool-trace
- "i" gnus-summary-import-article
- "I" gnus-summary-create-article
- "p" gnus-summary-article-posted-p)
-
- (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
- "o" gnus-summary-save-article
- "m" gnus-summary-save-article-mail
- "F" gnus-summary-write-article-file
- "r" gnus-summary-save-article-rmail
- "f" gnus-summary-save-article-file
- "b" gnus-summary-save-article-body-file
- "h" gnus-summary-save-article-folder
- "v" gnus-summary-save-article-vm
- "p" gnus-summary-pipe-output
- "P" gnus-summary-muttprint
- "s" gnus-soup-add-article)
-
- (gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
- "b" gnus-summary-display-buttonized
- "m" gnus-summary-repair-multipart
- "v" gnus-article-view-part
- "o" gnus-article-save-part
- "c" gnus-article-copy-part
- "C" gnus-article-view-part-as-charset
- "e" gnus-article-view-part-externally
- "E" gnus-article-encrypt-body
- "i" gnus-article-inline-part
- "|" gnus-article-pipe-part)
-
- (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
- "p" gnus-summary-mark-as-processable
- "u" gnus-summary-unmark-as-processable
- "U" gnus-summary-unmark-all-processable
- "v" gnus-uu-mark-over
- "s" gnus-uu-mark-series
- "r" gnus-uu-mark-region
- "g" gnus-uu-unmark-region
- "R" gnus-uu-mark-by-regexp
- "G" gnus-uu-unmark-by-regexp
- "t" gnus-uu-mark-thread
- "T" gnus-uu-unmark-thread
- "a" gnus-uu-mark-all
- "b" gnus-uu-mark-buffer
- "S" gnus-uu-mark-sparse
- "k" gnus-summary-kill-process-mark
- "y" gnus-summary-yank-process-mark
- "w" gnus-summary-save-process-mark
- "i" gnus-uu-invert-processable)
-
- (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
- ;;"x" gnus-uu-extract-any
- "m" gnus-summary-save-parts
- "u" gnus-uu-decode-uu
- "U" gnus-uu-decode-uu-and-save
- "s" gnus-uu-decode-unshar
- "S" gnus-uu-decode-unshar-and-save
- "o" gnus-uu-decode-save
- "O" gnus-uu-decode-save
- "b" gnus-uu-decode-binhex
- "B" gnus-uu-decode-binhex
- "p" gnus-uu-decode-postscript
- "P" gnus-uu-decode-postscript-and-save)
-
- (gnus-define-keys
- (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
- "u" gnus-uu-decode-uu-view
- "U" gnus-uu-decode-uu-and-save-view
- "s" gnus-uu-decode-unshar-view
- "S" gnus-uu-decode-unshar-and-save-view
- "o" gnus-uu-decode-save-view
- "O" gnus-uu-decode-save-view
- "b" gnus-uu-decode-binhex-view
- "B" gnus-uu-decode-binhex-view
- "p" gnus-uu-decode-postscript-view
- "P" gnus-uu-decode-postscript-and-save-view))
+;; Non-orthogonal keys
+
+(gnus-define-keys gnus-summary-mode-map
+ " " gnus-summary-next-page
+ "\177" gnus-summary-prev-page
+ [delete] gnus-summary-prev-page
+ [backspace] gnus-summary-prev-page
+ "\r" gnus-summary-scroll-up
+ "\M-\r" gnus-summary-scroll-down
+ "n" gnus-summary-next-unread-article
+ "p" gnus-summary-prev-unread-article
+ "N" gnus-summary-next-article
+ "P" gnus-summary-prev-article
+ "\M-\C-n" gnus-summary-next-same-subject
+ "\M-\C-p" gnus-summary-prev-same-subject
+ "\M-n" gnus-summary-next-unread-subject
+ "\M-p" gnus-summary-prev-unread-subject
+ "." gnus-summary-first-unread-article
+ "," gnus-summary-best-unread-article
+ "\M-s" gnus-summary-search-article-forward
+ "\M-r" gnus-summary-search-article-backward
+ "<" gnus-summary-beginning-of-article
+ ">" gnus-summary-end-of-article
+ "j" gnus-summary-goto-article
+ "^" gnus-summary-refer-parent-article
+ "\M-^" gnus-summary-refer-article
+ "u" gnus-summary-tick-article-forward
+ "!" gnus-summary-tick-article-forward
+ "U" gnus-summary-tick-article-backward
+ "d" gnus-summary-mark-as-read-forward
+ "D" gnus-summary-mark-as-read-backward
+ "E" gnus-summary-mark-as-expirable
+ "\M-u" gnus-summary-clear-mark-forward
+ "\M-U" gnus-summary-clear-mark-backward
+ "k" gnus-summary-kill-same-subject-and-select
+ "\C-k" gnus-summary-kill-same-subject
+ "\M-\C-k" gnus-summary-kill-thread
+ "\M-\C-l" gnus-summary-lower-thread
+ "e" gnus-summary-edit-article
+ "#" gnus-summary-mark-as-processable
+ "\M-#" gnus-summary-unmark-as-processable
+ "\M-\C-t" gnus-summary-toggle-threads
+ "\M-\C-s" gnus-summary-show-thread
+ "\M-\C-h" gnus-summary-hide-thread
+ "\M-\C-f" gnus-summary-next-thread
+ "\M-\C-b" gnus-summary-prev-thread
+ [(meta down)] gnus-summary-next-thread
+ [(meta up)] gnus-summary-prev-thread
+ "\M-\C-u" gnus-summary-up-thread
+ "\M-\C-d" gnus-summary-down-thread
+ "&" gnus-summary-execute-command
+ "c" gnus-summary-catchup-and-exit
+ "\C-w" gnus-summary-mark-region-as-read
+ "\C-t" gnus-summary-toggle-truncation
+ "?" gnus-summary-mark-as-dormant
+ "\C-c\M-\C-s" gnus-summary-limit-include-expunged
+ "\C-c\C-s\C-n" gnus-summary-sort-by-number
+ "\C-c\C-s\C-l" gnus-summary-sort-by-lines
+ "\C-c\C-s\C-c" gnus-summary-sort-by-chars
+ "\C-c\C-s\C-a" gnus-summary-sort-by-author
+ "\C-c\C-s\C-s" gnus-summary-sort-by-subject
+ "\C-c\C-s\C-d" gnus-summary-sort-by-date
+ "\C-c\C-s\C-i" gnus-summary-sort-by-score
+ "\C-c\C-s\C-o" gnus-summary-sort-by-original
+ "\C-c\C-s\C-r" gnus-summary-sort-by-random
+ "=" gnus-summary-expand-window
+ "\C-x\C-s" gnus-summary-reselect-current-group
+ "\M-g" gnus-summary-rescan-group
+ "w" gnus-summary-stop-page-breaking
+ "\C-c\C-r" gnus-summary-caesar-message
+ "f" gnus-summary-followup
+ "F" gnus-summary-followup-with-original
+ "C" gnus-summary-cancel-article
+ "r" gnus-summary-reply
+ "R" gnus-summary-reply-with-original
+ "\C-c\C-f" gnus-summary-mail-forward
+ "o" gnus-summary-save-article
+ "\C-o" gnus-summary-save-article-mail
+ "|" gnus-summary-pipe-output
+ "\M-k" gnus-summary-edit-local-kill
+ "\M-K" gnus-summary-edit-global-kill
+ ;; "V" gnus-version
+ "\C-c\C-d" gnus-summary-describe-group
+ "q" gnus-summary-exit
+ "Q" gnus-summary-exit-no-update
+ "\C-c\C-i" gnus-info-find-node
+ gnus-mouse-2 gnus-mouse-pick-article
+ "m" gnus-summary-mail-other-window
+ "a" gnus-summary-post-news
+ "i" gnus-summary-news-other-window
+ "x" gnus-summary-limit-to-unread
+ "s" gnus-summary-isearch-article
+ "t" gnus-summary-toggle-header
+ "g" gnus-summary-show-article
+ "l" gnus-summary-goto-last-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
+ "\M-\C-a" gnus-summary-customize-parameters
+ "\C-c\C-b" gnus-bug
+ "*" gnus-cache-enter-article
+ "\M-*" gnus-cache-remove-article
+ "\M-&" gnus-summary-universal-argument
+ "\C-l" gnus-recenter
+ "I" gnus-summary-increase-score
+ "L" gnus-summary-lower-score
+ "\M-i" gnus-symbolic-argument
+ "h" gnus-summary-select-article-buffer
+
+ "b" gnus-article-view-part
+ "\M-t" gnus-summary-toggle-display-buttonized
+
+ "V" gnus-summary-score-map
+ "X" gnus-uu-extract-map
+ "S" gnus-summary-send-map)
+
+;; Sort of orthogonal keymap
+(gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
+ "t" gnus-summary-tick-article-forward
+ "!" gnus-summary-tick-article-forward
+ "d" gnus-summary-mark-as-read-forward
+ "r" gnus-summary-mark-as-read-forward
+ "c" gnus-summary-clear-mark-forward
+ " " gnus-summary-clear-mark-forward
+ "e" gnus-summary-mark-as-expirable
+ "x" gnus-summary-mark-as-expirable
+ "?" gnus-summary-mark-as-dormant
+ "b" gnus-summary-set-bookmark
+ "B" gnus-summary-remove-bookmark
+ "#" gnus-summary-mark-as-processable
+ "\M-#" gnus-summary-unmark-as-processable
+ "S" gnus-summary-limit-include-expunged
+ "C" gnus-summary-catchup
+ "H" gnus-summary-catchup-to-here
+ "h" gnus-summary-catchup-from-here
+ "\C-c" gnus-summary-catchup-all
+ "k" gnus-summary-kill-same-subject-and-select
+ "K" gnus-summary-kill-same-subject
+ "P" gnus-uu-mark-map)
+
+(gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
+ "c" gnus-summary-clear-above
+ "u" gnus-summary-tick-above
+ "m" gnus-summary-mark-above
+ "k" gnus-summary-kill-below)
+
+(gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
+ "/" gnus-summary-limit-to-subject
+ "n" gnus-summary-limit-to-articles
+ "w" gnus-summary-pop-limit
+ "s" gnus-summary-limit-to-subject
+ "a" gnus-summary-limit-to-author
+ "u" gnus-summary-limit-to-unread
+ "m" gnus-summary-limit-to-marks
+ "M" gnus-summary-limit-exclude-marks
+ "v" gnus-summary-limit-to-score
+ "*" gnus-summary-limit-include-cached
+ "D" gnus-summary-limit-include-dormant
+ "T" gnus-summary-limit-include-thread
+ "d" gnus-summary-limit-exclude-dormant
+ "t" gnus-summary-limit-to-age
+ "." gnus-summary-limit-to-unseen
+ "x" gnus-summary-limit-to-extra
+ "p" gnus-summary-limit-to-display-predicate
+ "E" gnus-summary-limit-include-expunged
+ "c" gnus-summary-limit-exclude-childless-dormant
+ "C" gnus-summary-limit-mark-excluded-as-read
+ "o" gnus-summary-insert-old-articles
+ "N" gnus-summary-insert-new-articles)
+
+(gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
+ "n" gnus-summary-next-unread-article
+ "p" gnus-summary-prev-unread-article
+ "N" gnus-summary-next-article
+ "P" gnus-summary-prev-article
+ "\C-n" gnus-summary-next-same-subject
+ "\C-p" gnus-summary-prev-same-subject
+ "\M-n" gnus-summary-next-unread-subject
+ "\M-p" gnus-summary-prev-unread-subject
+ "f" gnus-summary-first-unread-article
+ "b" gnus-summary-best-unread-article
+ "j" gnus-summary-goto-article
+ "g" gnus-summary-goto-subject
+ "l" gnus-summary-goto-last-article
+ "o" gnus-summary-pop-article)
+
+(gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
+ "k" gnus-summary-kill-thread
+ "l" gnus-summary-lower-thread
+ "i" gnus-summary-raise-thread
+ "T" gnus-summary-toggle-threads
+ "t" gnus-summary-rethread-current
+ "^" gnus-summary-reparent-thread
+ "s" gnus-summary-show-thread
+ "S" gnus-summary-show-all-threads
+ "h" gnus-summary-hide-thread
+ "H" gnus-summary-hide-all-threads
+ "n" gnus-summary-next-thread
+ "p" gnus-summary-prev-thread
+ "u" gnus-summary-up-thread
+ "o" gnus-summary-top-thread
+ "d" gnus-summary-down-thread
+ "#" gnus-uu-mark-thread
+ "\M-#" gnus-uu-unmark-thread)
+
+(gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
+ "g" gnus-summary-prepare
+ "c" gnus-summary-insert-cached-articles
+ "d" gnus-summary-insert-dormant-articles)
+
+(gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
+ "c" gnus-summary-catchup-and-exit
+ "C" gnus-summary-catchup-all-and-exit
+ "E" gnus-summary-exit-no-update
+ "Q" gnus-summary-exit
+ "Z" gnus-summary-exit
+ "n" gnus-summary-catchup-and-goto-next-group
+ "R" gnus-summary-reselect-current-group
+ "G" gnus-summary-rescan-group
+ "N" gnus-summary-next-group
+ "s" gnus-summary-save-newsrc
+ "P" gnus-summary-prev-group)
+
+(gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
+ " " gnus-summary-next-page
+ "n" gnus-summary-next-page
+ "\177" gnus-summary-prev-page
+ [delete] gnus-summary-prev-page
+ "p" gnus-summary-prev-page
+ "\r" gnus-summary-scroll-up
+ "\M-\r" gnus-summary-scroll-down
+ "<" gnus-summary-beginning-of-article
+ ">" gnus-summary-end-of-article
+ "b" gnus-summary-beginning-of-article
+ "e" gnus-summary-end-of-article
+ "^" gnus-summary-refer-parent-article
+ "r" gnus-summary-refer-parent-article
+ "D" gnus-summary-enter-digest-group
+ "R" gnus-summary-refer-references
+ "T" gnus-summary-refer-thread
+ "g" gnus-summary-show-article
+ "s" gnus-summary-isearch-article
+ "P" gnus-summary-print-article
+ "M" gnus-mailing-list-insinuate
+ "t" gnus-article-babel)
+
+(gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
+ "b" gnus-article-add-buttons
+ "B" gnus-article-add-buttons-to-head
+ "o" gnus-article-treat-overstrike
+ "e" gnus-article-emphasize
+ "w" gnus-article-fill-cited-article
+ "Q" gnus-article-fill-long-lines
+ "C" gnus-article-capitalize-sentences
+ "c" gnus-article-remove-cr
+ "q" gnus-article-de-quoted-unreadable
+ "6" gnus-article-de-base64-unreadable
+ "Z" gnus-article-decode-HZ
+ "h" gnus-article-wash-html
+ "u" gnus-article-unsplit-urls
+ "s" gnus-summary-force-verify-and-decrypt
+ "f" gnus-article-display-x-face
+ "l" gnus-summary-stop-page-breaking
+ "r" gnus-summary-caesar-message
+ "m" gnus-summary-morse-message
+ "t" gnus-summary-toggle-header
+ "g" gnus-treat-smiley
+ "v" gnus-summary-verbose-headers
+ "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
+ "p" gnus-article-verify-x-pgp-sig
+ "d" gnus-article-treat-dumbquotes)
+
+(gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
+ ;; mnemonic: deuglif*Y*
+ "u" gnus-article-outlook-unwrap-lines
+ "a" gnus-article-outlook-repair-attribution
+ "c" gnus-article-outlook-rearrange-citation
+ "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
+
+(gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
+ "a" gnus-article-hide
+ "h" gnus-article-hide-headers
+ "b" gnus-article-hide-boring-headers
+ "s" gnus-article-hide-signature
+ "c" gnus-article-hide-citation
+ "C" gnus-article-hide-citation-in-followups
+ "l" gnus-article-hide-list-identifiers
+ "B" gnus-article-strip-banner
+ "P" gnus-article-hide-pem
+ "\C-c" gnus-article-hide-citation-maybe)
+
+(gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
+ "a" gnus-article-highlight
+ "h" gnus-article-highlight-headers
+ "c" gnus-article-highlight-citation
+ "s" gnus-article-highlight-signature)
+
+(gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
+ "f" gnus-article-treat-fold-headers
+ "u" gnus-article-treat-unfold-headers
+ "n" gnus-article-treat-fold-newsgroups)
+
+(gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
+ "x" gnus-article-display-x-face
+ "d" gnus-article-display-face
+ "s" gnus-treat-smiley
+ "D" gnus-article-remove-images
+ "f" gnus-treat-from-picon
+ "m" gnus-treat-mail-picon
+ "n" gnus-treat-newsgroups-picon)
+
+(gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
+ "w" gnus-article-decode-mime-words
+ "c" gnus-article-decode-charset
+ "v" gnus-mime-view-all-parts
+ "b" gnus-article-view-part)
+
+(gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
+ "z" gnus-article-date-ut
+ "u" gnus-article-date-ut
+ "l" gnus-article-date-local
+ "p" gnus-article-date-english
+ "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)
+ "t" gnus-article-remove-trailing-blank-lines
+ "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
+ "e" gnus-article-strip-trailing-space
+ "w" gnus-article-remove-leading-whitespace)
+
+(gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
+ "v" gnus-version
+ "f" gnus-summary-fetch-faq
+ "d" gnus-summary-describe-group
+ "h" gnus-summary-describe-briefly
+ "i" gnus-info-find-node
+ "c" gnus-group-fetch-charter
+ "C" gnus-group-fetch-control)
+
+(gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
+ "e" gnus-summary-expire-articles
+ "\M-\C-e" gnus-summary-expire-articles-now
+ "\177" gnus-summary-delete-article
+ [delete] gnus-summary-delete-article
+ [backspace] gnus-summary-delete-article
+ "m" gnus-summary-move-article
+ "r" gnus-summary-respool-article
+ "w" gnus-summary-edit-article
+ "c" gnus-summary-copy-article
+ "B" gnus-summary-crosspost-article
+ "q" gnus-summary-respool-query
+ "t" gnus-summary-respool-trace
+ "i" gnus-summary-import-article
+ "I" gnus-summary-create-article
+ "p" gnus-summary-article-posted-p)
+
+(gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
+ "o" gnus-summary-save-article
+ "m" gnus-summary-save-article-mail
+ "F" gnus-summary-write-article-file
+ "r" gnus-summary-save-article-rmail
+ "f" gnus-summary-save-article-file
+ "b" gnus-summary-save-article-body-file
+ "h" gnus-summary-save-article-folder
+ "v" gnus-summary-save-article-vm
+ "p" gnus-summary-pipe-output
+ "P" gnus-summary-muttprint
+ "s" gnus-soup-add-article)
+
+(gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
+ "b" gnus-summary-display-buttonized
+ "m" gnus-summary-repair-multipart
+ "v" gnus-article-view-part
+ "o" gnus-article-save-part
+ "c" gnus-article-copy-part
+ "C" gnus-article-view-part-as-charset
+ "e" gnus-article-view-part-externally
+ "E" gnus-article-encrypt-body
+ "i" gnus-article-inline-part
+ "|" gnus-article-pipe-part)
+
+(gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
+ "p" gnus-summary-mark-as-processable
+ "u" gnus-summary-unmark-as-processable
+ "U" gnus-summary-unmark-all-processable
+ "v" gnus-uu-mark-over
+ "s" gnus-uu-mark-series
+ "r" gnus-uu-mark-region
+ "g" gnus-uu-unmark-region
+ "R" gnus-uu-mark-by-regexp
+ "G" gnus-uu-unmark-by-regexp
+ "t" gnus-uu-mark-thread
+ "T" gnus-uu-unmark-thread
+ "a" gnus-uu-mark-all
+ "b" gnus-uu-mark-buffer
+ "S" gnus-uu-mark-sparse
+ "k" gnus-summary-kill-process-mark
+ "y" gnus-summary-yank-process-mark
+ "w" gnus-summary-save-process-mark
+ "i" gnus-uu-invert-processable)
+
+(gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
+ ;;"x" gnus-uu-extract-any
+ "m" gnus-summary-save-parts
+ "u" gnus-uu-decode-uu
+ "U" gnus-uu-decode-uu-and-save
+ "s" gnus-uu-decode-unshar
+ "S" gnus-uu-decode-unshar-and-save
+ "o" gnus-uu-decode-save
+ "O" gnus-uu-decode-save
+ "b" gnus-uu-decode-binhex
+ "B" gnus-uu-decode-binhex
+ "p" gnus-uu-decode-postscript
+ "P" gnus-uu-decode-postscript-and-save)
+
+(gnus-define-keys
+ (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
+ "u" gnus-uu-decode-uu-view
+ "U" gnus-uu-decode-uu-and-save-view
+ "s" gnus-uu-decode-unshar-view
+ "S" gnus-uu-decode-unshar-and-save-view
+ "o" gnus-uu-decode-save-view
+ "O" gnus-uu-decode-save-view
+ "b" gnus-uu-decode-binhex-view
+ "B" gnus-uu-decode-binhex-view
+ "p" gnus-uu-decode-postscript-view
+ "P" gnus-uu-decode-postscript-and-save-view)
(defvar gnus-article-post-menu nil)
["Signature" gnus-article-hide-signature t]
["Citation" gnus-article-hide-citation t]
["List identifiers" gnus-article-hide-list-identifiers t]
- ["PGP" gnus-article-hide-pgp t]
["Banner" gnus-article-strip-banner t]
["Boring headers" gnus-article-hide-boring-headers t])
("Highlight"
["Charset" gnus-article-decode-charset t]
["QP" gnus-article-de-quoted-unreadable t]
["Base64" gnus-article-de-base64-unreadable t]
+ ["View MIME buttons" gnus-summary-display-buttonized t]
["View all" gnus-mime-view-all-parts t]
["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
- ["Encrypt body" gnus-article-encrypt-body t]
- ["Extract all parts" gnus-summary-save-parts 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"))]
+ ["Extract all parts..." gnus-summary-save-parts t]
+ ("Multipart"
+ ["Repair multipart" gnus-summary-repair-multipart t]
+ ["Pipe part..." gnus-article-pipe-part t]
+ ["Inline part" gnus-article-inline-part 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 part with charset..." gnus-article-view-part-as-charset t]
+ ["Copy part" gnus-article-copy-part t]
+ ["Save part..." gnus-article-save-part t]
+ ["View part" gnus-article-view-part t]))
("Date"
["Local" gnus-article-date-local t]
["ISO8601" gnus-article-date-iso8601 t]
,@(gnus-summary-menu-split
(mapcar
(lambda (cs)
- ;; Since easymenu under FSF Emacs doesn't allow lambda
- ;; forms for menu commands, we should provide intern'ed
- ;; function symbols.
+ ;; Since easymenu under Emacs doesn't allow
+ ;; lambda forms for menu commands, we should
+ ;; provide intern'ed function symbols.
(let ((command (intern (format "\
gnus-summary-show-article-from-menu-as-charset-%s" cs))))
(fset command
(sort (if (fboundp 'coding-system-list)
(coding-system-list)
(mapcar 'car mm-mime-mule-charset-alist))
- (lambda (a b)
- (string< (symbol-name a)
- (symbol-name b))))))))
+ 'string<)))))
("Washing"
("Remove Blanks"
["Leading" gnus-article-strip-leading-blank-lines t]
["Word wrap" gnus-article-fill-cited-article t]
["Fill long lines" gnus-article-fill-long-lines t]
["Capitalize sentences" gnus-article-capitalize-sentences t]
- ["CR" gnus-article-remove-cr t]
+ ["Remove CR" gnus-article-remove-cr t]
["Quoted-Printable" gnus-article-de-quoted-unreadable t]
["Base64" gnus-article-de-base64-unreadable t]
["Rot 13" gnus-summary-caesar-message
,@(if (featurep 'xemacs) '(t)
'(:help "\"Caesar rotate\" article by 13"))]
- ["Unix pipe" gnus-summary-pipe-message t]
+ ["Morse decode" gnus-summary-morse-message t]
+ ["Unix pipe..." gnus-summary-pipe-message t]
["Add buttons" gnus-article-add-buttons t]
["Add buttons to head" gnus-article-add-buttons-to-head t]
["Stop page breaking" gnus-summary-stop-page-breaking t]
["Unfold headers" gnus-article-treat-unfold-headers t]
["Fold newsgroups" gnus-article-treat-fold-newsgroups t]
["Html" gnus-article-wash-html t]
- ["URLs" gnus-article-unsplit-urls t]
+ ["Unsplit URLs" gnus-article-unsplit-urls t]
["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
- ["HZ" gnus-article-decode-HZ t]
- ["OutlooK deuglify" gnus-article-outlook-deuglify-article t]
+ ["Decode HZ" gnus-article-decode-HZ t]
+ ("(Outlook) Deuglify"
+ ["Unwrap lines" gnus-article-outlook-unwrap-lines t]
+ ["Repair attribution" gnus-article-outlook-repair-attribution t]
+ ["Rearrange citation" gnus-article-outlook-rearrange-citation t]
+ ["Full (Outlook) deuglify"
+ gnus-article-outlook-deuglify-article t])
)
("Output"
- ["Save in default format" gnus-summary-save-article
+ ["Save in default format..." gnus-summary-save-article
,@(if (featurep 'xemacs) '(t)
'(:help "Save article using default method"))]
- ["Save in file" gnus-summary-save-article-file
+ ["Save in file..." gnus-summary-save-article-file
,@(if (featurep 'xemacs) '(t)
'(:help "Save article in file"))]
- ["Save in Unix mail format" gnus-summary-save-article-mail t]
- ["Save in MH folder" gnus-summary-save-article-folder t]
- ["Save in VM folder" gnus-summary-save-article-vm t]
- ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
- ["Save body in file" gnus-summary-save-article-body-file t]
- ["Pipe through a filter" gnus-summary-pipe-output t]
+ ["Save in Unix mail format..." gnus-summary-save-article-mail t]
+ ["Save in MH folder..." gnus-summary-save-article-folder t]
+ ["Save in VM folder..." gnus-summary-save-article-vm t]
+ ["Save in RMAIL mbox..." gnus-summary-save-article-rmail t]
+ ["Save body in file..." gnus-summary-save-article-body-file t]
+ ["Pipe through a filter..." gnus-summary-pipe-output t]
["Add to SOUP packet" gnus-soup-add-article t]
- ["Print with Muttprint" gnus-summary-muttprint t]
+ ["Print with Muttprint..." gnus-summary-muttprint t]
["Print" gnus-summary-print-article t])
("Backend"
["Respool article..." gnus-summary-respool-article t]
["Crosspost article..." gnus-summary-crosspost-article
(gnus-check-backend-function
'request-replace-article gnus-newsgroup-name)]
- ["Import file..." gnus-summary-import-article t]
- ["Create article..." gnus-summary-create-article t]
+ ["Import file..." gnus-summary-import-article
+ (gnus-check-backend-function
+ 'request-accept-article gnus-newsgroup-name)]
+ ["Create article..." gnus-summary-create-article
+ (gnus-check-backend-function
+ 'request-accept-article gnus-newsgroup-name)]
["Check if posted" gnus-summary-article-posted-p t]
["Edit article" gnus-summary-edit-article
(not (gnus-group-read-only-p))]
(easy-menu-define
gnus-summary-thread-menu gnus-summary-mode-map ""
'("Threads"
+ ["Find all messages in thread" gnus-summary-refer-thread t]
["Toggle threading" gnus-summary-toggle-threads t]
["Hide threads" gnus-summary-hide-all-threads t]
["Show threads" gnus-summary-show-all-threads t]
["Catchup all" gnus-summary-catchup-all t]
["Catchup to here" gnus-summary-catchup-to-here t]
["Catchup from here" gnus-summary-catchup-from-here t]
- ["Catchup region" gnus-summary-mark-region-as-read t]
+ ["Catchup region" gnus-summary-mark-region-as-read
+ (gnus-mark-active-p)]
["Mark excluded" gnus-summary-limit-mark-excluded-as-read t])
("Mark Various"
["Tick" gnus-summary-tick-article-forward t]
["Author..." gnus-summary-limit-to-author t]
["Age..." gnus-summary-limit-to-age t]
["Extra..." gnus-summary-limit-to-extra t]
- ["Score" gnus-summary-limit-to-score t]
+ ["Score..." gnus-summary-limit-to-score t]
["Display Predicate" gnus-summary-limit-to-display-predicate t]
["Unread" gnus-summary-limit-to-unread t]
+ ["Unseen" gnus-summary-limit-to-unseen t]
["Non-dormant" gnus-summary-limit-exclude-dormant t]
- ["Articles" gnus-summary-limit-to-articles t]
+ ["Next articles" gnus-summary-limit-to-articles t]
["Pop limit" gnus-summary-pop-limit t]
["Show dormant" gnus-summary-limit-include-dormant t]
["Hide childless dormant"
["Remove all marks" gnus-summary-unmark-all-processable t]
["Mark above" gnus-uu-mark-over t]
["Mark series" gnus-uu-mark-series t]
- ["Mark region" gnus-uu-mark-region t]
- ["Unmark region" gnus-uu-unmark-region t]
+ ["Mark region" gnus-uu-mark-region (gnus-mark-active-p)]
+ ["Unmark region" gnus-uu-unmark-region (gnus-mark-active-p)]
["Mark by regexp..." gnus-uu-mark-by-regexp t]
["Unmark by regexp..." gnus-uu-unmark-by-regexp t]
["Mark all" gnus-uu-mark-all t]
["Kill" gnus-summary-kill-process-mark t]
["Yank" gnus-summary-yank-process-mark
gnus-newsgroup-process-stack]
- ["Save" gnus-summary-save-process-mark t]))
+ ["Save" gnus-summary-save-process-mark t]
+ ["Run command on marked..." gnus-summary-universal-argument t]))
("Scroll article"
["Page forward" gnus-summary-next-page
,@(if (featurep 'xemacs) '(t)
("Help"
["Fetch group FAQ" gnus-summary-fetch-faq t]
["Describe group" gnus-summary-describe-group t]
+ ["Fetch charter" gnus-group-fetch-charter
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Display the charter of the current group"))]
+ ["Fetch control message" gnus-group-fetch-control
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Display the archived control message for the current group"))]
["Read manual" gnus-info-find-node t])
("Modes"
["Pick and read" gnus-pick-mode t]
("Regeneration"
["Regenerate" gnus-summary-prepare t]
["Insert cached articles" gnus-summary-insert-cached-articles t]
+ ["Insert dormant articles" gnus-summary-insert-dormant-articles t]
["Toggle threading" gnus-summary-toggle-threads t])
["See old articles" gnus-summary-insert-old-articles t]
["See new articles" gnus-summary-insert-new-articles t]
["Filter articles..." gnus-summary-execute-command t]
- ["Run command on subjects..." gnus-summary-universal-argument t]
+ ["Run command on articles..." gnus-summary-universal-argument t]
["Search articles forward..." gnus-summary-search-article-forward t]
["Search articles backward..." gnus-summary-search-article-backward t]
["Toggle line truncation" gnus-summary-toggle-truncation t]
respectively.
You can also post articles and send mail from this buffer. To
-follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author
+follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author
of an article, type `\\[gnus-summary-reply]'.
There are approx. one gazillion commands you can execute in this
(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 'pre-command-hook)
+ (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)
(turn-on-gnus-mailing-list-mode)
(defmacro gnus-summary-article-number ()
"The article number of the article on the current line.
-If there isn's an article number here, then we return the current
+If there isn't an article number here, then we return the current
article number."
'(progn
(gnus-summary-skip-intangible)
This is all marks except unread, ticked, dormant, and expirable."
(not (or (= mark gnus-unread-mark)
(= mark gnus-ticked-mark)
+ (= mark gnus-spam-mark)
(= mark gnus-dormant-mark)
(= mark gnus-expirable-mark))))
marks of articles."
`(cond
((memq ,number gnus-newsgroup-unsendable) gnus-unsendable-mark)
- ((memq ,number gnus-newsgroup-undownloaded) gnus-undownloaded-mark)
((memq ,number gnus-newsgroup-downloadable) gnus-downloadable-mark)
((memq ,number gnus-newsgroup-unreads) gnus-unread-mark)
((memq ,number gnus-newsgroup-marked) gnus-ticked-mark)
(point)
(current-buffer))))))
-(defun gnus-summary-buffer-name (group)
- "Return the summary buffer name of GROUP."
- (concat "*Summary " (gnus-group-decoded-name group) "*"))
-
(defun gnus-summary-setup-buffer (group)
"Initialize summary buffer."
(let ((buffer (gnus-summary-buffer-name group))
(let ((gnus-replied-mark 129)
(gnus-score-below-mark 130)
(gnus-score-over-mark 130)
- (gnus-download-mark 131)
+ (gnus-undownloaded-mark 131)
(spec gnus-summary-line-format-spec)
gnus-visual pos)
(save-excursion
(gnus-set-work-buffer)
(let ((gnus-summary-line-format-spec spec)
- (gnus-newsgroup-downloadable '((0 . t))))
+ (gnus-newsgroup-downloadable '(0)))
(gnus-summary-insert-line
[0 "" "" "05 Apr 2001 23:33:09 +0400" "" "" 0 0 "" nil]
- 0 nil 128 t nil "" nil 1)
+ 0 nil t 128 t nil "" nil 1)
(goto-char (point-min))
(setq pos (list (cons 'unread (and (search-forward "\200" nil t)
(- (point) (point-min) 1)))))
(defun gnus-summary-insert-line (gnus-tmp-header
gnus-tmp-level gnus-tmp-current
- gnus-tmp-unread gnus-tmp-replied
+ undownloaded gnus-tmp-unread gnus-tmp-replied
gnus-tmp-expirable gnus-tmp-subject-or-nil
&optional gnus-tmp-dummy gnus-tmp-score
gnus-tmp-process)
((memq gnus-tmp-number gnus-newsgroup-unseen)
gnus-unseen-mark)
(t gnus-no-mark)))
+ (gnus-tmp-downloaded
+ (cond (undownloaded
+ gnus-undownloaded-mark)
+ (gnus-newsgroup-agentized
+ gnus-downloaded-mark)
+ (t
+ gnus-no-mark)))
(gnus-tmp-from (mail-header-from gnus-tmp-header))
(gnus-tmp-name
(cond
(if (= gnus-tmp-lines -1)
(setq gnus-tmp-lines "?")
(setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
- (gnus-put-text-property
+ (gnus-put-text-property
(point)
(progn (eval gnus-summary-line-format-spec) (point))
- 'gnus-number gnus-tmp-number)
+ 'gnus-number gnus-tmp-number)
(when (gnus-visual-p 'summary-highlight 'highlight)
(forward-line -1)
(gnus-run-hooks 'gnus-summary-update-hook)
gnus-empty-thread-mark)
number)))
+(defsubst gnus-summary-line-message-size (head)
+ "Return pretty-printed version of message size.
+This function is intended to be used in
+`gnus-summary-line-format-alist'."
+ (let ((c (or (mail-header-chars head) -1)))
+ (cond ((< c 0) "n/a") ; chars not available
+ ((< c (* 1000 10)) (format "%1.1fk" (/ c 1024.0)))
+ ((< c (* 1000 100)) (format "%dk" (/ c 1024.0)))
+ ((< c (* 1000 10000)) (format "%1.1fM" (/ c (* 1024.0 1024))))
+ (t (format "%dM" (/ c (* 1024.0 1024)))))))
+
+
(defun gnus-summary-set-local-parameters (group)
"Go through the local params of GROUP and set all variable specs in that list."
(let ((params (gnus-group-find-parameter group))
(let ((gnus-newsgroup-dormant nil))
(gnus-summary-initial-limit show-all))
(gnus-summary-initial-limit show-all))
- ;; When untreaded, all articles are always shown.
+ ;; When unthreaded, all articles are always shown.
(setq gnus-newsgroup-limit
(mapcar
(lambda (header) (mail-header-number header))
(progn
(gnus-configure-windows 'summary)
(let ((art (gnus-summary-article-number)))
- (unless (or (memq art gnus-newsgroup-undownloaded)
- (memq art gnus-newsgroup-downloadable))
+ (unless (and (not gnus-plugged)
+ (or (memq art gnus-newsgroup-undownloaded)
+ (memq art gnus-newsgroup-downloadable)))
(gnus-summary-goto-article art))))
;; Don't select any articles.
(gnus-summary-position-point)
(gnus-configure-windows 'summary 'force)
(gnus-set-mode-line 'summary))
- (when (get-buffer-window gnus-group-buffer t)
+ (when (and gnus-auto-center-group
+ (get-buffer-window gnus-group-buffer t))
;; Gotta use windows, because recenter does weird stuff if
;; the current buffer ain't the displayed window.
(let ((owin (selected-window)))
;; Mark this buffer as "prepared".
(setq gnus-newsgroup-prepared t)
(gnus-run-hooks 'gnus-summary-prepared-hook)
+ (unless (gnus-ephemeral-group-p group)
+ (gnus-group-update-group group))
t)))))
(defun gnus-summary-auto-select-subject ()
((eq gnus-auto-select-subject 'first)
;; Do nothing.
)
- ((gnus-functionp gnus-auto-select-subject)
+ ((functionp gnus-auto-select-subject)
(funcall gnus-auto-select-subject))))
(defun gnus-summary-prepare ()
(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."
+ "Simplify subject by the same rules as `gnus-gather-threads-by-subject'."
(setq subject
(cond
;; Truncate the subject.
(setcdr prev (cdr threads))
(setq threads prev))
;; Enter this thread into the hash table.
- (gnus-sethash subject threads hashtb)))
+ (gnus-sethash subject
+ (if gnus-summary-make-false-root-always
+ (progn
+ ;; If you want a dummy root above all
+ ;; threads...
+ (setcar threads (list whole-subject
+ (car threads)))
+ threads)
+ threads)
+ hashtb)))
(setq prev threads)
(setq threads (cdr threads)))
result)))
(setq heads nil)))))
gnus-newsgroup-dependencies)))
+(defsubst gnus-remove-odd-characters (string)
+ "Translate STRING into something that doesn't contain weird characters."
+ (mm-subst-char-in-string
+ ?\r ?\-
+ (mm-subst-char-in-string
+ ?\n ?\- string)))
+
;; This function has to be called with point after the article number
;; on the beginning of the line.
(defsubst gnus-nov-parse-line (number dependencies &optional force-new)
;; overview: [num subject from date id refs chars lines misc]
(unwind-protect
- (progn
+ (let (x)
(narrow-to-region (point) eol)
(unless (eobp)
(forward-char))
(setq header
(make-full-mail-header
number ; number
- (funcall gnus-decode-encoded-word-function
- (nnheader-nov-field)) ; subject
- (funcall gnus-decode-encoded-word-function
- (nnheader-nov-field)) ; from
+ (condition-case () ; subject
+ (gnus-remove-odd-characters
+ (funcall gnus-decode-encoded-word-function
+ (setq x (nnheader-nov-field))))
+ (error x))
+ (condition-case () ; from
+ (gnus-remove-odd-characters
+ (funcall gnus-decode-encoded-word-function
+ (setq x (nnheader-nov-field))))
+ (error x))
(nnheader-nov-field) ; date
(nnheader-nov-read-message-id) ; id
(setq references (nnheader-nov-field)) ; refs
(forward-line 1)))))))
(defun gnus-summary-update-article-line (article header)
- "Update the line for ARTICLE using HEADERS."
+ "Update the line for ARTICLE using HEADER."
(let* ((id (mail-header-id header))
(thread (gnus-id-to-thread id)))
(unless thread
(gnus-summary-goto-subject article)
(let* ((datal (gnus-data-find-list article))
(data (car datal))
- (length (when (cdr datal)
- (- (gnus-data-pos data)
- (gnus-data-pos (cadr datal)))))
(buffer-read-only nil)
(level (gnus-summary-thread-level)))
(gnus-delete-line)
- (gnus-summary-insert-line
- header level nil (gnus-article-mark article)
- (memq article gnus-newsgroup-replied)
- (memq article gnus-newsgroup-expirable)
- ;; Only insert the Subject string when it's different
- ;; from the previous Subject string.
- (if (and
- gnus-show-threads
- (gnus-subject-equal
- (condition-case ()
- (mail-header-subject
- (gnus-data-header
- (cadr
- (gnus-data-find-list
- article
- (gnus-data-list t)))))
- ;; Error on the side of excessive subjects.
- (error ""))
- (mail-header-subject header)))
- ""
- (mail-header-subject header))
- nil (cdr (assq article gnus-newsgroup-scored))
- (memq article gnus-newsgroup-processable))
- (when length
- (gnus-data-update-list
- (cdr datal) (- length (- (gnus-data-pos data) (point))))))))
+ (let ((inserted (- (point)
+ (progn
+ (gnus-summary-insert-line
+ header level nil
+ (memq article gnus-newsgroup-undownloaded)
+ (gnus-article-mark article)
+ (memq article gnus-newsgroup-replied)
+ (memq article gnus-newsgroup-expirable)
+ ;; Only insert the Subject string when it's different
+ ;; from the previous Subject string.
+ (if (and
+ gnus-show-threads
+ (gnus-subject-equal
+ (condition-case ()
+ (mail-header-subject
+ (gnus-data-header
+ (cadr
+ (gnus-data-find-list
+ article
+ (gnus-data-list t)))))
+ ;; Error on the side of excessive subjects.
+ (error ""))
+ (mail-header-subject header)))
+ ""
+ (mail-header-subject header))
+ nil (cdr (assq article gnus-newsgroup-scored))
+ (memq article gnus-newsgroup-processable))
+ (point)))))
+ (when (cdr datal)
+ (gnus-data-update-list
+ (cdr datal)
+ (- (gnus-data-pos data) (gnus-data-pos (cadr datal)) inserted)))))))
(defun gnus-summary-update-article (article &optional iheader)
"Update ARTICLE in the summary buffer."
(when parent
(delq thread parent)))
(if (gnus-summary-insert-subject id header)
- ;; Set the (possibly) new article number in the data structure.
+ ;; Set the (possibly) new article number in the data structure.
(gnus-data-set-number data (gnus-id-to-article id))
(setcar thread old)
nil))))
(if (not gnus-thread-sort-functions)
threads
(gnus-message 8 "Sorting threads...")
- (prog1
- (gnus-sort-threads-1
+ (let ((max-lisp-eval-depth 5000))
+ (prog1 (gnus-sort-threads-1
threads
(gnus-make-sort-function gnus-thread-sort-functions))
- (gnus-message 8 "Sorting threads...done"))))
+ (gnus-message 8 "Sorting threads...done")))))
(defun gnus-sort-articles (articles)
"Sort ARTICLES."
(defun gnus-thread-latest-date (thread)
"Return the highest article date in THREAD."
(let ((previous-time 0))
- (apply 'max (mapcar
- (lambda (header)
- (setq previous-time
- (time-to-seconds
- (mail-header-parse-date
- (condition-case ()
- (mail-header-date header)
- (error previous-time))))))
- (sort
- (message-flatten-list thread)
- (lambda (h1 h2)
- (< (mail-header-number h1)
- (mail-header-number h2))))))))
+ (apply 'max
+ (mapcar
+ (lambda (header)
+ (setq previous-time
+ (condition-case ()
+ (time-to-seconds (mail-header-parse-date
+ (mail-header-date header)))
+ (error previous-time))))
+ (sort
+ (message-flatten-list thread)
+ (lambda (h1 h2)
+ (< (mail-header-number h1)
+ (mail-header-number h2))))))))
(defun gnus-thread-total-score-1 (root)
;; This function find the total score of the thread below ROOT.
(defcustom gnus-sum-thread-tree-root "> "
"With %B spec, used for the root of a thread.
If nil, use subject instead."
- :type 'string
+ :type '(radio (const :format "%v " nil) (string :size 0))
+ :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."
+ :type '(radio (const :format "%v " nil) (string :size 0))
: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."
- :type 'string
+ :type '(radio (const :format "%v " nil) (string :size 0))
:group 'gnus-thread)
(defcustom gnus-sum-thread-tree-vertical "| "
"With %B spec, used for drawing a vertical line."
(let ((gnus-tmp-level 0)
(default-score (or gnus-summary-default-score 0))
(gnus-visual-p (gnus-visual-p 'summary-highlight 'highlight))
+ (building-line-count gnus-summary-display-while-building)
+ (building-count (integerp gnus-summary-display-while-building))
thread number subject stack state gnus-tmp-gathered beg-match
new-roots gnus-tmp-new-adopts thread-end simp-subject
- gnus-tmp-header gnus-tmp-unread
+ gnus-tmp-header gnus-tmp-unread gnus-tmp-downloaded
gnus-tmp-replied gnus-tmp-subject-or-nil
gnus-tmp-dummy gnus-tmp-indentation gnus-tmp-lines gnus-tmp-score
gnus-tmp-score-char gnus-tmp-from gnus-tmp-name
gnus-tmp-number gnus-tmp-opening-bracket gnus-tmp-closing-bracket
tree-stack)
- (setq gnus-tmp-prev-subject nil)
+ (setq gnus-tmp-prev-subject nil
+ gnus-tmp-thread-tree-header-string "")
(if (vectorp (car threads))
;; If this is a straight (sic) list of headers, then a
;; Do the threaded display.
+ (if gnus-summary-display-while-building
+ (switch-to-buffer (buffer-name)))
(while (or threads stack gnus-tmp-new-adopts new-roots)
(if (and (= gnus-tmp-level 0)
((memq number gnus-newsgroup-unseen)
gnus-unseen-mark)
(t gnus-no-mark))
+ gnus-tmp-downloaded
+ (cond ((memq number gnus-newsgroup-undownloaded)
+ gnus-undownloaded-mark)
+ (gnus-newsgroup-agentized
+ gnus-downloaded-mark)
+ (t
+ gnus-no-mark))
gnus-tmp-from (mail-header-from gnus-tmp-header)
gnus-tmp-name
(cond
(substring gnus-tmp-from
(1+ (match-beginning 0)) (1- (match-end 0))))
(t gnus-tmp-from))
+
+ ;; Do the %B string
gnus-tmp-thread-tree-header-string
(cond
((not gnus-show-threads) "")
((zerop gnus-tmp-level)
- (if (cdar thread)
- (or gnus-sum-thread-tree-root subject)
- (or gnus-sum-thread-tree-single-indent subject)))
+ (cond ((cdar thread)
+ (or gnus-sum-thread-tree-root subject))
+ (gnus-tmp-new-adopts
+ (or gnus-sum-thread-tree-false-root subject))
+ (t
+ (or gnus-sum-thread-tree-single-indent subject))))
(t
(concat (apply 'concat
(mapcar (lambda (item)
(if (= gnus-tmp-lines -1)
(setq gnus-tmp-lines "?")
(setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
- (gnus-put-text-property
+ (gnus-put-text-property
(point)
(progn (eval gnus-summary-line-format-spec) (point))
- 'gnus-number number)
+ 'gnus-number number)
(when gnus-visual-p
(forward-line -1)
(gnus-run-hooks 'gnus-summary-update-hook)
(when (nth 1 thread)
(push (list (max 0 gnus-tmp-level)
- (copy-list tree-stack)
+ (copy-sequence tree-stack)
(nthcdr 1 thread))
stack))
(push (if (nth 1 thread) 1 0) tree-stack)
(incf gnus-tmp-level)
(setq threads (if thread-end nil (cdar thread)))
+ (if gnus-summary-display-while-building
+ (if building-count
+ (progn
+ ;; use a set frequency
+ (setq building-line-count (1- building-line-count))
+ (when (= building-line-count 0)
+ (sit-for 0)
+ (setq building-line-count
+ gnus-summary-display-while-building)))
+ ;; always
+ (sit-for 0)))
(unless threads
(setq gnus-tmp-level 0)))))
(gnus-message 7 "Generating summary...done"))
gnus-newsgroup-data)
(gnus-summary-insert-line
header 0 number
+ (memq number gnus-newsgroup-undownloaded)
mark (memq number gnus-newsgroup-replied)
(memq number gnus-newsgroup-expirable)
(mail-header-subject header) nil
(gnus-activate-group group) ; Or we can activate it...
(progn ; Or we bug out.
(when (equal major-mode 'gnus-summary-mode)
- (kill-buffer (current-buffer)))
+ (gnus-kill-buffer (current-buffer)))
(error "Couldn't activate group %s: %s"
group (gnus-status-message group))))
(unless (gnus-request-group group t)
(when (equal major-mode 'gnus-summary-mode)
- (kill-buffer (current-buffer)))
+ (gnus-kill-buffer (current-buffer)))
(error "Couldn't request group %s: %s"
group (gnus-status-message group)))
+ (when gnus-agent
+ ;; The agent may be storing articles that are no longer in the
+ ;; server's active range. If that is the case, the active range
+ ;; needs to be expanded such that the agent's articles can be
+ ;; included in the summary.
+ (let* ((gnus-command-method (gnus-find-method-for-group group))
+ (alist (gnus-agent-load-alist group))
+ (active (gnus-active group)))
+ (if (and (car alist)
+ (< (caar alist) (car active)))
+ (gnus-set-active group (cons (caar alist) (cdr active)))))
+
+ (setq gnus-summary-use-undownloaded-faces
+ (gnus-agent-find-parameter
+ group
+ 'agent-enable-undownloaded-faces)))
+
(setq gnus-newsgroup-name group
gnus-newsgroup-unselected nil
gnus-newsgroup-unreads (gnus-list-of-unread-articles group))
;; Adjust and set lists of article marks.
(when info
(gnus-adjust-marked-articles info))
-
(if (setq articles select-articles)
(setq gnus-newsgroup-unselected
(gnus-sorted-difference gnus-newsgroup-unreads articles))
(gnus-make-hashtable (length articles)))
(gnus-set-global-variables)
;; Retrieve the headers and read them in.
+
(setq gnus-newsgroup-headers (gnus-fetch-headers articles))
;; Kludge to avoid having cached articles nixed out in virtual groups.
(gnus-get-predicate display)))
;; Uses the dynamically bound `number' variable.
-(defvar number)
+(eval-when-compile
+ (defvar number))
(defun gnus-article-marked-p (type &optional article)
(let ((article (or article number)))
(cond
(defun gnus-articles-to-read (group &optional read-all)
"Find out what articles the user wants to read."
- (let* ((articles
+ (let* ((display (gnus-group-find-parameter group 'display))
+ (articles
;; Select all articles if `read-all' is non-nil, or if there
;; are no unread articles.
(if (or read-all
(setq gnus-newsgroup-unselected
(gnus-sorted-difference gnus-newsgroup-unreads articles))
(when gnus-alter-articles-to-read-function
- (setq gnus-newsgroup-unreads
+ (setq articles
(sort
(funcall gnus-alter-articles-to-read-function
- gnus-newsgroup-name gnus-newsgroup-unreads)
+ gnus-newsgroup-name articles)
'<)))
articles)))
'list))
(defun gnus-article-unpropagatable-p (mark)
- "Return whether MARK should be propagated to backend."
+ "Return whether MARK should be propagated to back end."
(memq mark gnus-article-unpropagated-mark-lists))
(defun gnus-adjust-marked-articles (info)
;; Update the number of unread articles.
(setcar entry num)
;; Update the group buffer.
- (gnus-group-update-group group t)))))
+ (unless (gnus-ephemeral-group-p group)
+ (gnus-group-update-group group t))))))
(defvar gnus-newsgroup-none-id 0)
;; Translate all TAB characters into SPACE characters.
(subst-char-in-region (point-min) (point-max) ?\t ? t)
(subst-char-in-region (point-min) (point-max) ?\r ? t)
+ (ietf-drums-unfold-fws)
(gnus-run-hooks 'gnus-parse-headers-hook)
(let ((case-fold-search t)
in-reply-to header p lines chars)
(looking-at "Xref:"))
(search-forward "\nXref:" nil t))
(goto-char (1+ (match-end 0)))
- (setq xref (buffer-substring (point)
- (progn (end-of-line) (point))))
+ (setq xref (buffer-substring (point) (gnus-point-at-eol)))
(mail-header-set-xref headers xref)))))))
(defun gnus-summary-insert-subject (id &optional old-header use-old-header)
(save-excursion
(gnus-group-best-unread-group exclude-group))))
-(defun gnus-summary-find-next (&optional unread article backward undownloaded)
- (if backward (gnus-summary-find-prev)
+(defun gnus-summary-find-next (&optional unread article backward)
+ (if backward
+ (gnus-summary-find-prev unread article)
(let* ((dummy (gnus-summary-article-intangible-p))
(article (or article (gnus-summary-article-number)))
- (arts (gnus-data-find-list article))
+ (data (gnus-data-find-list article))
result)
(when (and (not dummy)
(or (not gnus-summary-check-current)
(not unread)
- (not (gnus-data-unread-p (car arts)))))
- (setq arts (cdr arts)))
+ (not (gnus-data-unread-p (car data)))))
+ (setq data (cdr data)))
(when (setq result
(if unread
(progn
- (while arts
- (when (or (and undownloaded
- (eq gnus-undownloaded-mark
- (gnus-data-mark (car arts))))
- (gnus-data-unread-p (car arts)))
- (setq result (car arts)
- arts nil))
- (setq arts (cdr arts)))
+ (while data
+ (unless (memq (gnus-data-number (car data))
+ (cond
+ ((eq gnus-auto-goto-ignores
+ 'always-undownloaded)
+ gnus-newsgroup-undownloaded)
+ (gnus-plugged
+ nil)
+ ((eq gnus-auto-goto-ignores
+ 'unfetched)
+ gnus-newsgroup-unfetched)
+ ((eq gnus-auto-goto-ignores
+ 'undownloaded)
+ gnus-newsgroup-undownloaded)))
+ (when (gnus-data-unread-p (car data))
+ (setq result (car data)
+ data nil)))
+ (setq data (cdr data)))
result)
- (car arts)))
+ (car data)))
(goto-char (gnus-data-pos result))
(gnus-data-number result)))))
(defun gnus-summary-find-prev (&optional unread article)
(let* ((eobp (eobp))
(article (or article (gnus-summary-article-number)))
- (arts (gnus-data-find-list article (gnus-data-list 'rev)))
+ (data (gnus-data-find-list article (gnus-data-list 'rev)))
result)
(when (and (not eobp)
(or (not gnus-summary-check-current)
(not unread)
- (not (gnus-data-unread-p (car arts)))))
- (setq arts (cdr arts)))
+ (not (gnus-data-unread-p (car data)))))
+ (setq data (cdr data)))
(when (setq result
(if unread
(progn
- (while arts
- (when (gnus-data-unread-p (car arts))
- (setq result (car arts)
- arts nil))
- (setq arts (cdr arts)))
+ (while data
+ (unless (memq (gnus-data-number (car data))
+ (cond
+ ((eq gnus-auto-goto-ignores
+ 'always-undownloaded)
+ gnus-newsgroup-undownloaded)
+ (gnus-plugged
+ nil)
+ ((eq gnus-auto-goto-ignores
+ 'unfetched)
+ gnus-newsgroup-unfetched)
+ ((eq gnus-auto-goto-ignores
+ 'undownloaded)
+ gnus-newsgroup-undownloaded)))
+ (when (gnus-data-unread-p (car data))
+ (setq result (car data)
+ data nil)))
+ (setq data (cdr data)))
result)
- (car arts)))
+ (car data)))
(goto-char (gnus-data-pos result))
(gnus-data-number result))))
If `gnus-auto-center-summary' is nil, or the article buffer isn't
displayed, no centering will be performed."
;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle).
-;; Recenter only when requested. Suggested by popovich@park.cs.columbia.edu.
+ ;; Recenter only when requested. Suggested by popovich@park.cs.columbia.edu.
(interactive)
- (let* ((top (cond ((< (window-height) 4) 0)
- ((< (window-height) 7) 1)
- (t (if (numberp gnus-auto-center-summary)
- gnus-auto-center-summary
- 2))))
- (height (1- (window-height)))
- (bottom (save-excursion (goto-char (point-max))
- (forward-line (- height))
- (point)))
- (window (get-buffer-window (current-buffer))))
- ;; The user has to want it.
- (when gnus-auto-center-summary
+ ;; The user has to want it.
+ (when gnus-auto-center-summary
+ (let* ((top (cond ((< (window-height) 4) 0)
+ ((< (window-height) 7) 1)
+ (t (if (numberp gnus-auto-center-summary)
+ gnus-auto-center-summary
+ 2))))
+ (height (1- (window-height)))
+ (bottom (save-excursion (goto-char (point-max))
+ (forward-line (- height))
+ (point)))
+ (window (get-buffer-window (current-buffer))))
(when (get-buffer-window gnus-article-buffer)
;; Only do recentering when the article buffer is displayed,
- ;; Set the window start to either `bottom', which is the biggest
+ ;; Set the window start to either `bottom', which is the biggest
;; possible valid number, or the second line from the top,
;; whichever is the least.
(let ((top-pos (save-excursion (forward-line (- top)) (point))))
(defun gnus-summary-toggle-truncation (&optional arg)
"Toggle truncation of summary lines.
-With arg, turn line truncation on iff arg is positive."
+With ARG, turn line truncation on if ARG is positive."
(interactive "P")
(setq truncate-lines
(if (null arg) (not truncate-lines)
(> (prefix-numeric-value arg) 0)))
(redraw-display))
+(defun gnus-summary-find-for-reselect ()
+ "Return the number of an article to stay on across a reselect.
+The current article is considered, then following articles, then previous
+articles. An article is sought which is not cancelled and isn't a temporary
+insertion from another group. If there's no such then return a dummy 0."
+ (let (found)
+ (dolist (rev '(nil t))
+ (unless found ; don't demand the reverse list if we don't need it
+ (let ((data (gnus-data-find-list
+ (gnus-summary-article-number) (gnus-data-list rev))))
+ (while (and data (not found))
+ (if (and (< 0 (gnus-data-number (car data)))
+ (not (eq gnus-canceled-mark (gnus-data-mark (car data)))))
+ (setq found (gnus-data-number (car data))))
+ (setq data (cdr data))))))
+ (or found 0)))
+
(defun gnus-summary-reselect-current-group (&optional all rescan)
"Exit and then reselect the current newsgroup.
The prefix argument ALL means to select all articles."
(interactive "P")
(when (gnus-ephemeral-group-p gnus-newsgroup-name)
(error "Ephemeral groups can't be reselected"))
- (let ((current-subject (gnus-summary-article-number))
+ (let ((current-subject (gnus-summary-find-for-reselect))
(group gnus-newsgroup-name))
(setq gnus-newsgroup-begin nil)
- (gnus-summary-exit)
+ (gnus-summary-exit nil 'leave-hidden)
;; We have to adjust the point of group mode buffer because
;; point was moved to the next unread newsgroup by exiting.
(gnus-summary-jump-to-group group)
(gnus-save-newsrc-file)
(gnus-dribble-save)))
-(defun gnus-summary-exit (&optional temporary)
+(defun gnus-summary-exit (&optional temporary leave-hidden)
"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-async-halt-prefetch)
(let* ((group gnus-newsgroup-name)
(quit-config (gnus-group-quit-config gnus-newsgroup-name))
+ (gnus-group-is-exiting-p t)
(mode major-mode)
(group-point nil)
(buf (current-buffer)))
(progn
(gnus-deaden-summary)
(setq mode nil))
- ;; We set all buffer-local variables to nil. It is unclear why
+ ;; We set all buffer-local variables to nil. It is unclear why
;; this is needed, but if we don't, buffer-local variables are
;; not garbage-collected, it seems. This would the lead to en
;; ever-growing Emacs.
(set-buffer gnus-group-buffer)
(gnus-summary-clear-local-variables)
(let ((gnus-summary-local-variables gnus-newsgroup-variables))
- (gnus-summary-clear-local-variables)))
+ (gnus-summary-clear-local-variables))
+ ;; Return to group mode buffer.
+ (when (eq mode 'gnus-summary-mode)
+ (gnus-kill-buffer buf)))
(setq gnus-current-select-method gnus-select-method)
- (pop-to-buffer gnus-group-buffer)
+ (if leave-hidden
+ (set-buffer gnus-group-buffer)
+ (pop-to-buffer gnus-group-buffer))
(if (not quit-config)
(progn
(goto-char group-point)
- (gnus-configure-windows 'group 'force))
+ (unless leave-hidden
+ (gnus-configure-windows 'group 'force)))
(gnus-handle-ephemeral-exit quit-config))
- ;; Return to group mode buffer.
- (when (eq mode 'gnus-summary-mode)
- (gnus-kill-buffer buf))
;; Clear the current group name.
(unless quit-config
(setq gnus-newsgroup-name nil)))))
"Quit reading current newsgroup without updating read article info."
(interactive)
(let* ((group gnus-newsgroup-name)
+ (gnus-group-is-exiting-p t)
+ (gnus-group-is-exiting-without-update-p t)
(quit-config (gnus-group-quit-config group)))
(when (or no-questions
gnus-expert-user
(gnus-y-or-n-p "Discard changes to this group and exit? "))
(gnus-async-halt-prefetch)
- (mapcar 'funcall
- (delq 'gnus-summary-expire-articles
- (copy-sequence gnus-summary-prepare-exit-hook)))
+ (run-hooks 'gnus-summary-prepare-exit-hook)
(when (gnus-buffer-live-p gnus-article-buffer)
(save-excursion
(set-buffer gnus-article-buffer)
(gnus-summary-clear-local-variables)
(let ((gnus-summary-local-variables gnus-newsgroup-variables))
(gnus-summary-clear-local-variables))
- (when (get-buffer gnus-summary-buffer)
- (kill-buffer gnus-summary-buffer)))
+ (gnus-kill-buffer gnus-summary-buffer))
(unless gnus-single-article-buffer
(setq gnus-article-current nil))
(when gnus-use-trees
(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))
(when (equal (gnus-group-group-name) group)
(gnus-group-next-unread-group 1))
(when quit-config
(progn
;; The current article may be from the ephemeral group
;; thus it is best that we reload this article
- (gnus-summary-show-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)))
(list
(when current-prefix-arg
(completing-read
- "Faq dir: " (and (listp gnus-group-faq-directory)
+ "FAQ dir: " (and (listp gnus-group-faq-directory)
(mapcar (lambda (file) (list file))
gnus-group-faq-directory))))))
(let (gnus-faq-buffer)
(defun gnus-summary-next-group (&optional no-article target-group backward)
"Exit current newsgroup and then select next unread newsgroup.
If prefix argument NO-ARTICLE is non-nil, no article is selected
-initially. If NEXT-GROUP, go to this group. If BACKWARD, go to
+initially. If TARGET-GROUP, go to this group. If BACKWARD, go to
previous group instead."
(interactive "P")
;; Stop pre-fetching.
(let ((current-group gnus-newsgroup-name)
(current-buffer (current-buffer))
entered)
- ;; First we semi-exit this group to update Xrefs and all variables.
+ ;; First we semi-exit this group to update Xrefs and all variables.
;; We can't do a real exit, because the window conf must remain
;; the same in case the user is prompted for info, and we don't
;; want the window conf to change before that...
(let ((unreads (gnus-group-group-unread)))
(if (and (or (eq t unreads)
(and unreads (not (zerop unreads))))
- (gnus-summary-read-group
- target-group nil no-article
- (and (buffer-name current-buffer) current-buffer)
- nil backward))
+ (gnus-summary-read-group
+ target-group nil no-article
+ (and (buffer-name current-buffer) current-buffer)
+ nil backward))
(setq entered t)
(setq current-group target-group
target-group nil)))))))
;; Walking around summary lines.
(defun gnus-summary-first-subject (&optional unread undownloaded unseen)
- "Go to the first unread subject.
-If UNREAD is non-nil, go to the first unread article.
-Returns the article selected or nil if there are no unread articles."
+ "Go to the first subject satisfying any non-nil constraint.
+If UNREAD is non-nil, the article should be unread.
+If UNDOWNLOADED is non-nil, the article should be undownloaded.
+If UNSEEN is non-nil, the article should be unseen.
+Returns the article selected or nil if there are no matching articles."
(interactive "P")
- (prog1
- (cond
- ;; Empty summary.
- ((null gnus-newsgroup-data)
- (gnus-message 3 "No articles in the group")
- nil)
- ;; Pick the first article.
- ((not unread)
- (goto-char (gnus-data-pos (car gnus-newsgroup-data)))
- (gnus-data-number (car gnus-newsgroup-data)))
- ;; No unread articles.
- ((null gnus-newsgroup-unreads)
- (gnus-message 3 "No more unread articles")
- nil)
- ;; Find the first unread article.
- (t
- (let ((data gnus-newsgroup-data))
- (while (and data
- (and (not (and undownloaded
- (eq gnus-undownloaded-mark
- (gnus-data-mark (car data)))))
- (if unseen
- (or (not (memq
- (gnus-data-number (car data))
- gnus-newsgroup-unseen))
- (not (gnus-data-unread-p (car data))))
- (not (gnus-data-unread-p (car data))))))
- (setq data (cdr data)))
- (when data
- (goto-char (gnus-data-pos (car data)))
- (gnus-data-number (car data))))))
- (gnus-summary-position-point)))
+ (cond
+ ;; Empty summary.
+ ((null gnus-newsgroup-data)
+ (gnus-message 3 "No articles in the group")
+ nil)
+ ;; Pick the first article.
+ ((not (or unread undownloaded unseen))
+ (goto-char (gnus-data-pos (car gnus-newsgroup-data)))
+ (gnus-data-number (car gnus-newsgroup-data)))
+ ;; Find the first unread article.
+ (t
+ (let ((data gnus-newsgroup-data))
+ (while (and data
+ (let ((num (gnus-data-number (car data))))
+ (or (memq num gnus-newsgroup-unfetched)
+ (not (or (and unread
+ (memq num gnus-newsgroup-unreads))
+ (and undownloaded
+ (memq num gnus-newsgroup-undownloaded))
+ (and unseen
+ (memq num gnus-newsgroup-unseen)))))))
+ (setq data (cdr data)))
+ (prog1
+ (if data
+ (progn
+ (goto-char (gnus-data-pos (car data)))
+ (gnus-data-number (car data)))
+ (gnus-message 3 "No more%s articles"
+ (let* ((r (when unread " unread"))
+ (d (when undownloaded " undownloaded"))
+ (s (when unseen " unseen"))
+ (l (delq nil (list r d s))))
+ (cond ((= 3 (length l))
+ (concat r "," d ", or" s))
+ ((= 2 (length l))
+ (concat (car l) ", or" (cadr l)))
+ ((= 1 (length l))
+ (car l))
+ (t
+ ""))))
+ nil
+ )
+ (gnus-summary-position-point))))))
(defun gnus-summary-next-subject (n &optional unread dont-display)
"Go to next N'th summary line.
(interactive "p")
(gnus-summary-next-subject (- n) t))
+(defun gnus-summary-goto-subjects (articles)
+ "Insert the subject header for ARTICLES in the current buffer."
+ (save-excursion
+ (dolist (article articles)
+ (gnus-summary-goto-subject article t)))
+ (gnus-summary-limit (append articles gnus-newsgroup-limit))
+ (gnus-summary-position-point))
+
(defun gnus-summary-goto-subject (article &optional force silent)
"Go the subject line of ARTICLE.
If FORCE, also allow jumping to articles not currently shown."
'old))))
(defun gnus-summary-force-verify-and-decrypt ()
+ "Display buttons for signed/encrypted parts and verify/decrypt them."
(interactive)
(let ((mm-verify-option 'known)
(mm-decrypt-option 'known)
+ (gnus-article-emulate-mime t)
(gnus-buttonized-mime-types (append (list "multipart/signed"
"multipart/encrypted")
gnus-buttonized-mime-types)))
(let ((keystrokes '((?\C-n (gnus-group-next-unread-group 1))
(?\C-p (gnus-group-prev-unread-group 1))))
(cursor-in-echo-area t)
- keve key group ended)
+ keve key group ended prompt)
(save-excursion
(set-buffer gnus-group-buffer)
(goto-char start)
(gnus-summary-best-group gnus-newsgroup-name)
(gnus-summary-search-group backward gnus-keep-same-level))))
(while (not ended)
- (gnus-message
- 5 "No more%s articles%s" (if unread " unread" "")
- (if (and group
- (not (gnus-ephemeral-group-p gnus-newsgroup-name)))
- (format " (Type %s for %s [%s])"
- (single-key-description cmd) group
- (car (gnus-gethash group gnus-newsrc-hashtb)))
- (format " (Type %s to exit %s)"
- (single-key-description cmd)
- gnus-newsgroup-name)))
+ (setq prompt
+ (format
+ "No more%s articles%s " (if unread " unread" "")
+ (if (and group
+ (not (gnus-ephemeral-group-p gnus-newsgroup-name)))
+ (format " (Type %s for %s [%s])"
+ (single-key-description cmd) group
+ (car (gnus-gethash group gnus-newsrc-hashtb)))
+ (format " (Type %s to exit %s)"
+ (single-key-description cmd)
+ gnus-newsgroup-name))))
;; Confirm auto selection.
- (setq key (car (setq keve (gnus-read-event-char))))
- (setq ended t)
+ (setq key (car (setq keve (gnus-read-event-char prompt)))
+ ended t)
(cond
((assq key keystrokes)
(let ((obuf (current-buffer)))
(and gnus-auto-select-same
(gnus-summary-article-subject))))
-(defun gnus-summary-next-page (&optional lines circular)
+(defun gnus-summary-next-page (&optional lines circular stop)
"Show next page of the selected article.
If at the end of the current article, select the next article.
LINES says how many lines should be scrolled up.
If CIRCULAR is non-nil, go to the start of the article instead of
selecting the next article when reaching the end of the current
-article."
+article.
+
+If STOP is non-nil, just stop when reaching the end of the message.
+
+Also see the variable `gnus-article-skip-boring'."
(interactive "P")
(setq gnus-summary-buffer (current-buffer))
(gnus-set-global-variables)
(gnus-summary-display-article article)
(when article-window
(gnus-eval-in-buffer-window gnus-article-buffer
- (setq endp (gnus-article-next-page lines)))
+ (setq endp (or (gnus-article-next-page lines)
+ (gnus-article-only-boring-p))))
(when endp
- (cond (circular
+ (cond (stop
+ (gnus-message 3 "End of message"))
+ (circular
(gnus-summary-beginning-of-article))
(lines
(gnus-message 3 "End of message"))
Return nil if there are no unseen articles."
(interactive)
(prog1
- (when (gnus-summary-first-subject t t t)
+ (when (gnus-summary-first-subject nil nil t)
(gnus-summary-show-thread)
- (gnus-summary-first-subject t t t))
+ (gnus-summary-first-subject nil nil t))
(gnus-summary-position-point)))
(defun gnus-summary-first-unseen-or-unread-subject ()
- "Place the point on the subject line of the first unseen article.
-Return nil if there are no unseen articles."
+ "Place the 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."
(interactive)
(prog1
- (unless (when (gnus-summary-first-subject t t t)
+ (unless (when (gnus-summary-first-subject nil nil t)
(gnus-summary-show-thread)
- (gnus-summary-first-subject t t t))
+ (gnus-summary-first-subject nil nil t))
(when (gnus-summary-first-subject t)
(gnus-summary-show-thread)
(gnus-summary-first-subject t)))
t))
(prog1
(if (and (stringp article)
- (string-match "@" article))
+ (string-match "@\\|%40" article))
(gnus-summary-refer-article article)
(when (stringp article)
(setq article (string-to-number article)))
days)
(while (not days-got)
(setq days (if younger
- (read-string "Limit to articles within (in days): ")
- (read-string "Limit to articles older than (in days): ")))
+ (read-string "Limit to articles younger than (in days, older when negative): ")
+ (read-string
+ "Limit to articles older than (in days, younger when negative): ")))
(when (> (length days) 0)
(setq days (read days)))
(if (numberp days)
(gnus-summary-limit articles)
(gnus-summary-position-point))))
+(defun gnus-summary-limit-to-unseen ()
+ "Limit to unseen articles."
+ (interactive)
+ (prog1
+ (gnus-summary-limit gnus-newsgroup-unseen)
+ (gnus-summary-position-point)))
+
(defun gnus-summary-limit-include-thread (id)
"Display all the hidden articles that is in the thread with ID in it.
When called interactively, ID is the Message-ID of the current
(gnus-summary-limit (nconc articles gnus-newsgroup-limit))
(gnus-summary-position-point))))
+(defun gnus-summary-insert-dormant-articles ()
+ "Insert all the dormant articles for this group into the current buffer."
+ (interactive)
+ (let ((gnus-verbose (max 6 gnus-verbose)))
+ (if (not gnus-newsgroup-dormant)
+ (gnus-message 3 "No cached articles for this group")
+ (gnus-summary-goto-subjects gnus-newsgroup-dormant))))
+
(defun gnus-summary-limit-include-dormant ()
"Display all the hidden articles that are marked as dormant.
Note that this command only works on a subset of the articles currently
thread)
(defun gnus-cut-threads (threads)
- "Cut off all uninteresting articles from the beginning of threads."
+ "Cut off all uninteresting articles from the beginning of THREADS."
(when (or (eq gnus-fetch-old-headers 'some)
(eq gnus-fetch-old-headers 'invisible)
(numberp gnus-fetch-old-headers)
;; will really go down to a leaf article first, before slowly
;; working its way up towards the root.
(when thread
- (let ((children
+ (let* ((max-lisp-eval-depth 5000)
+ (children
(if (cdr thread)
(apply '+ (mapcar 'gnus-summary-limit-children
(cdr thread)))
(set-buffer gnus-original-article-buffer)
(nnheader-narrow-to-headers)
(unless (setq ref (message-fetch-field "references"))
- (setq ref (message-fetch-field "in-reply-to")))
+ (when (setq ref (message-fetch-field "in-reply-to"))
+ (setq ref (gnus-extract-message-id-from-in-reply-to ref))))
(widen))
(setq ref
;; It's not the current article, so we take a bet on
(let ((id (mail-header-id (gnus-summary-article-header)))
(limit (if limit (prefix-numeric-value limit)
gnus-refer-thread-limit)))
- ;; We want to fetch LIMIT *old* headers, but we also have to
- ;; re-fetch all the headers in the current buffer, because many of
- ;; them may be undisplayed. So we adjust LIMIT.
- (when (numberp limit)
- (incf limit (- gnus-newsgroup-end gnus-newsgroup-begin)))
(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 (eq (gnus-retrieve-headers
- (list gnus-newsgroup-end) gnus-newsgroup-name limit)
+ (if (eq (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))
'nov)
(gnus-build-all-threads)
- (error "Can't fetch thread from backends that don't support NOV"))
+ (error "Can't fetch thread from back ends that don't support NOV"))
(gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name))
(gnus-summary-limit-include-thread id)))
(interactive "sMessage-ID: ")
(when (and (stringp message-id)
(not (zerop (length message-id))))
+ (setq message-id (gnus-replace-in-string message-id " " ""))
;; Construct the correct Message-ID if necessary.
;; Suggested by tale@pawl.rpi.edu.
(unless (string-match "^<" message-id)
(setq message-id (concat "<" message-id)))
(unless (string-match ">$" message-id)
(setq message-id (concat message-id ">")))
+ ;; People often post MIDs from URLs, so unhex it:
+ (unless (string-match "@" message-id)
+ (setq message-id (gnus-url-unhex-string message-id)))
(let* ((header (gnus-id-to-header message-id))
(sparse (and header
(gnus-summary-article-sparse-p
;; We fetch the article.
(catch 'found
(dolist (gnus-override-method (gnus-refer-article-methods))
- (gnus-check-server gnus-override-method)
- ;; Fetch the header, and display the article.
- (when (setq number (gnus-summary-insert-subject message-id))
+ (when (and (gnus-check-server gnus-override-method)
+ ;; Fetch the header,
+ (setq number (gnus-summary-insert-subject message-id)))
+ ;; and display the article.
(gnus-summary-select-article nil nil nil number)
(throw 'found t)))
(gnus-message 3 "Couldn't fetch article %s" message-id)))))))
(defun gnus-refer-article-methods ()
- "Return a list of referrable methods."
+ "Return a list of referable methods."
(cond
;; No method, so we default to current and native.
((null gnus-refer-article-method)
to guess what the document format is."
(interactive "P")
(let ((conf gnus-current-window-configuration))
- (save-excursion
- (gnus-summary-select-article))
+ (save-window-excursion
+ (save-excursion
+ (let (gnus-article-prepare-hook
+ gnus-display-mime-function
+ gnus-break-pages)
+ (gnus-summary-select-article))))
(setq gnus-current-window-configuration conf)
(let* ((name (format "%s-%d"
(gnus-group-prefixed-name
(ogroup gnus-newsgroup-name)
(params (append (gnus-info-params (gnus-get-info ogroup))
(list (cons 'to-group ogroup))
+ (list (cons 'parent-group ogroup))
(list (cons 'save-article-group ogroup))))
(case-fold-search t)
(buf (current-buffer))
(gnus-use-article-prefetch nil)
(gnus-xmas-force-redisplay nil) ;Inhibit XEmacs redisplay.
(gnus-use-trees nil) ;Inhibit updating tree buffer.
+ (gnus-visual nil)
+ (gnus-keep-backlog nil)
+ (gnus-break-pages nil)
+ (gnus-summary-display-arrow nil)
+ (gnus-updated-mode-lines nil)
+ (gnus-auto-center-summary nil)
(sum (current-buffer))
(gnus-display-mime-function nil)
(found nil)
;; We don't want to change current point nor window configuration.
(save-excursion
(save-window-excursion
- (gnus-message 6 "Executing %s..." (key-description command))
-;; We'd like to execute COMMAND interactively so as to give arguments.
- (gnus-execute header regexp
- `(call-interactively ',(key-binding command))
- backward)
- (gnus-message 6 "Executing %s...done" (key-description command)))))
+ (let (gnus-visual
+ gnus-treat-strip-trailing-blank-lines
+ gnus-treat-strip-leading-blank-lines
+ gnus-treat-strip-multiple-blank-lines
+ gnus-treat-hide-boring-headers
+ gnus-treat-fold-newsgroups
+ gnus-article-prepare-hook)
+ (gnus-message 6 "Executing %s..." (key-description command))
+ ;; We'd like to execute COMMAND interactively so as to give arguments.
+ (gnus-execute header regexp
+ `(call-interactively ',(key-binding command))
+ backward)
+ (gnus-message 6 "Executing %s...done" (key-description command))))))
(defun gnus-summary-beginning-of-article ()
"Scroll the article back to the beginning."
(gnus-eval-in-buffer-window gnus-article-buffer
(widen)
(goto-char (point-min))
- (when gnus-page-broken
+ (when gnus-break-pages
(gnus-narrow-to-page))))
(defun gnus-summary-end-of-article ()
(widen)
(goto-char (point-max))
(recenter -3)
- (when gnus-page-broken
+ (when gnus-break-pages
+ (when (re-search-backward page-delimiter nil t)
+ (narrow-to-region (match-end 0) (point-max)))
(gnus-narrow-to-page))))
(defun gnus-summary-print-truncate-and-quote (string &optional len)
"[()]" "\\\\\\&"))
(defun gnus-summary-print-article (&optional filename n)
- "Generate and print a PostScript image of the N next (mail) articles.
+ "Generate and print a PostScript image of the process-marked (mail) articles.
+
+If used interactively, print the current article if none are
+process-marked. With prefix arg, prompt the user for the name of the
+file to save in.
-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.
+When used from Lisp, accept two optional args FILENAME and N. N means
+to print the next N articles. 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 first argument FILENAME is nil, send the image to the
printer. If FILENAME is a string, save the PostScript image in a file with
(progn
(copy-to-buffer buffer (point-min) (point-max))
(set-buffer buffer)
- (gnus-article-delete-invisible-text)
(gnus-remove-text-with-property 'gnus-decoration)
(when (gnus-visual-p 'article-highlight 'highlight)
;; Copy-to-buffer doesn't copy overlay. So redo
;; highlight.
(let ((gnus-article-buffer buffer))
(gnus-article-highlight-citation t)
- (gnus-article-highlight-signature)))
+ (gnus-article-highlight-signature)
+ (gnus-article-emphasize)
+ (gnus-article-delete-invisible-text)))
(let ((ps-left-header
(list
(concat "("
defined in `gnus-summary-show-article-charset-alist', or the charset
input.
If ARG (the prefix) is non-nil and not a number, show the raw article
-without any article massaging functions being run. Normally, the key strokes
-are `C-u g'."
+without any article massaging functions being run. Normally, the key
+strokes are `C-u g'."
(interactive "P")
(cond
((numberp arg)
(interactive "P")
(let ((window (and (gnus-buffer-live-p gnus-article-buffer)
(get-buffer-window gnus-article-buffer t))))
- (when window
- (with-current-buffer gnus-article-buffer
+ (with-current-buffer gnus-article-buffer
+ (widen)
+ (article-narrow-to-head)
+ (let* ((buffer-read-only nil)
+ (inhibit-point-motion-hooks t)
+ (hidden (if (numberp arg)
+ (>= arg 0)
+ (gnus-article-hidden-text-p 'headers)))
+ s e)
+ (delete-region (point-min) (point-max))
+ (with-current-buffer gnus-original-article-buffer
+ (goto-char (setq s (point-min)))
+ (setq e (if (search-forward "\n\n" nil t)
+ (1- (point))
+ (point-max))))
+ (insert-buffer-substring gnus-original-article-buffer s e)
+ (run-hooks 'gnus-article-decode-hook)
+ (if hidden
+ (let ((gnus-treat-hide-headers nil)
+ (gnus-treat-hide-boring-headers nil))
+ (gnus-delete-wash-type 'headers)
+ (gnus-treat-article 'head))
+ (gnus-treat-article 'head))
(widen)
- (article-narrow-to-head)
- (let* ((buffer-read-only nil)
- (inhibit-point-motion-hooks t)
- (hidden (if (numberp arg)
- (>= arg 0)
- (gnus-article-hidden-text-p 'headers)))
- s e)
- (delete-region (point-min) (point-max))
- (with-current-buffer gnus-original-article-buffer
- (goto-char (setq s (point-min)))
- (setq e (if (search-forward "\n\n" nil t)
- (1- (point))
- (point-max))))
- (insert-buffer-substring gnus-original-article-buffer s e)
- (article-decode-encoded-words)
- (if hidden
- (let ((gnus-treat-hide-headers nil)
- (gnus-treat-hide-boring-headers nil))
- (gnus-delete-wash-type 'headers)
- (gnus-treat-article 'head))
- (gnus-treat-article 'head))
- (widen)
- (set-window-start window (goto-char (point-min)))
- (setq gnus-page-broken
- (when gnus-break-pages
- (gnus-narrow-to-page)
- t))
- (gnus-set-mode-line 'article))))))
+ (if window
+ (set-window-start window (goto-char (point-min))))
+ (if gnus-break-pages
+ (gnus-narrow-to-page)
+ (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-set-mode-line 'article)))))
(defun gnus-summary-show-all-headers ()
"Make all header lines visible."
(message-caesar-buffer-body arg)
(set-window-start (get-buffer-window (current-buffer)) start))))))
+(autoload 'unmorse-region "morse"
+ "Convert morse coded text in region to ordinary ASCII text."
+ t)
+
+(defun gnus-summary-morse-message (&optional arg)
+ "Morse decode the current article."
+ (interactive "P")
+ (gnus-summary-select-article)
+ (let ((mail-header-separator ""))
+ (gnus-eval-in-buffer-window gnus-article-buffer
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((pos (window-start))
+ buffer-read-only)
+ (goto-char (point-min))
+ (when (message-goto-body)
+ (gnus-narrow-to-body))
+ (goto-char (point-min))
+ (while (re-search-forward "·" (point-max) t)
+ (replace-match "."))
+ (unmorse-region (point-min) (point-max))
+ (widen)
+ (set-window-start (get-buffer-window (current-buffer)) pos)))))))
+
(defun gnus-summary-stop-page-breaking ()
"Stop page breaking in the current article."
(interactive)
((eq art-group 'junk)
(when (eq action 'move)
(gnus-summary-mark-article article gnus-canceled-mark)
- (gnus-message 4 "Deleted article %s" article)))
+ (gnus-message 4 "Deleted article %s" article)
+ ;; run the delete hook
+ (run-hook-with-args 'gnus-summary-article-delete-hook
+ action
+ (gnus-data-header
+ (assoc article (gnus-data-list nil)))
+ gnus-newsgroup-name nil
+ select-method)))
(t
(let* ((pto-group (gnus-group-prefixed-name
(car art-group) to-method))
(list (cdr art-group)))))
;; See whether the article is to be put in the cache.
- (let ((marks gnus-article-mark-lists)
+ (let ((marks (if (gnus-group-auto-expirable-p to-group)
+ gnus-article-mark-lists
+ (delete '(expirable . expire)
+ (copy-sequence gnus-article-mark-lists))))
(to-article (cdr art-group)))
;; Enter the article into the cache in the new group,
to-group (cdar marks) (list to-article) info)))
(setq marks (cdr marks)))
- (gnus-request-set-mark to-group (list (list (list to-article)
- 'add
- to-marks))))
+ (gnus-request-set-mark
+ to-group (list (list (list to-article) 'add to-marks))))
(gnus-dribble-enter
(concat "(gnus-group-set-info '"
(gnus-request-article-this-buffer article gnus-newsgroup-name)
(nnheader-replace-header "Xref" new-xref)
(gnus-request-replace-article
- article gnus-newsgroup-name (current-buffer)))))
+ article gnus-newsgroup-name (current-buffer))))
+
+ ;; run the move/copy/crosspost/respool hook
+ (run-hook-with-args 'gnus-summary-article-move-hook
+ action
+ (gnus-data-header
+ (assoc article (gnus-data-list nil)))
+ gnus-newsgroup-name
+ to-newsgroup
+ select-method))
;;;!!!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))))
:type 'symbol
:group 'gnus-summary-mail)
+(defcustom gnus-summary-display-while-building nil
+ "If non-nil, show and update the summary buffer as it's being built.
+If the value is t, update the buffer after every line is inserted. If
+the value is an integer (N), update the display every N lines."
+ :group 'gnus-thread
+ :type '(choice (const :tag "off" nil)
+ number
+ (const :tag "frequently" t)))
+
(defun gnus-summary-respool-article (&optional n method)
"Respool the current article.
The article will be squeezed through the mail spooling process again,
(defun gnus-summary-expire-articles (&optional now)
"Expire all articles that are marked as expirable in the current group."
(interactive)
- (when (gnus-check-backend-function
- 'request-expire-articles gnus-newsgroup-name)
+ (when (and (not gnus-group-is-exiting-without-update-p)
+ (gnus-check-backend-function
+ 'request-expire-articles gnus-newsgroup-name))
;; This backend supports expiry.
(let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name))
(expirable (if total
(dolist (article expirable)
(when (and (not (memq article es))
(gnus-data-find article))
- (gnus-summary-mark-article article gnus-canceled-mark))))))
+ (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 ()
This command actually deletes articles. This is not a marking
command. The article will disappear forever from your life, never to
return.
+
If N is negative, delete backwards.
If N is nil and articles have been marked with the process mark,
-delete these instead."
+delete these instead.
+
+If `gnus-novice-user' is non-nil you will be asked for
+confirmation before the articles are deleted."
(interactive "P")
(unless (gnus-check-backend-function 'request-expire-articles
gnus-newsgroup-name)
;; after all.
(unless (memq (car articles) not-deleted)
(gnus-summary-mark-article (car articles) gnus-canceled-mark))
+ (let* ((article (car articles))
+ (id (mail-header-id (gnus-data-header
+ (assoc article (gnus-data-list nil))))))
+ (run-hook-with-args 'gnus-summary-article-delete-hook
+ 'delete id gnus-newsgroup-name nil
+ nil))
(setq articles (cdr articles)))
(when not-deleted
(gnus-message 4 "Couldn't delete articles %s" not-deleted)))
(setq gnus-article-mime-handles nil))))))
(t
(setq force t)))
- (when (and raw (not force) (equal gnus-newsgroup-name "nndraft:drafts"))
- (error "Can't edit the raw article in group nndraft:drafts"))
+ (when (and raw (not force)
+ (member gnus-newsgroup-name '("nndraft:delayed"
+ "nndraft:drafts"
+ "nndraft:queue")))
+ (error "Can't edit the raw article in group %s"
+ gnus-newsgroup-name))
(save-excursion
(set-buffer gnus-summary-buffer)
(let ((mail-parse-charset gnus-newsgroup-charset)
(when (and (not raw) (gnus-buffer-live-p gnus-article-buffer))
(with-current-buffer gnus-article-buffer
(mm-enable-multibyte)))
- (if (equal gnus-newsgroup-name "nndraft:drafts")
+ (if (member gnus-newsgroup-name '("nndraft:delayed" "nndraft:drafts"))
(setq raw t))
(gnus-article-edit-article
(if raw 'ignore
(let ((mbl1 mml-buffer-list))
(setq mml-buffer-list mbl)
(set (make-local-variable 'mml-buffer-list) mbl1))
- (make-local-hook 'kill-buffer-hook)
+ (gnus-make-local-hook 'kill-buffer-hook)
(add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))))
`(lambda (no-highlight)
(let ((mail-parse-charset ',gnus-newsgroup-charset)
(gnus-summary-select-article)
(save-excursion
(set-buffer gnus-original-article-buffer)
- (save-restriction
- (message-narrow-to-head)
- (let ((groups (nnmail-article-group 'identity trace)))
- (unless silent
- (if groups
- (message "This message would go to %s"
- (mapconcat 'car groups ", "))
- (message "This message would go to no groups"))
- groups))))))
+ (let ((groups (nnmail-article-group 'identity trace)))
+ (unless silent
+ (if groups
+ (message "This message would go to %s"
+ (mapconcat 'car groups ", "))
+ (message "This message would go to no groups"))
+ groups)))))
(defun gnus-summary-respool-trace ()
"Trace where the respool algorithm would put this article.
(interactive (list (gnus-summary-article-number)))
(let ((articles (if (listp article) article (list article))))
(dolist (article articles)
+ (unless (numberp article)
+ (error "%s is not a number" article))
(push article gnus-newsgroup-replied)
(let ((buffer-read-only nil))
(when (gnus-summary-goto-subject article nil t)
(not (equal gnus-newsgroup-name (car gnus-article-current))))
(error "No current article selected"))
;; Remove old bookmark, if one exists.
- (let ((old (assq article gnus-newsgroup-bookmarks)))
- (when old
- (setq gnus-newsgroup-bookmarks
- (delq old gnus-newsgroup-bookmarks))))
+ (gnus-pull article gnus-newsgroup-bookmarks)
;; Set the new bookmark, which is on the form
;; (article-number . line-number-in-body).
(push
(count-lines
(min (point)
(save-excursion
- (goto-char (point-min))
- (search-forward "\n\n" nil t)
+ (article-goto-body)
(point)))
(point))))
gnus-newsgroup-bookmarks)
"Remove the bookmark from the current article."
(interactive (list (gnus-summary-article-number)))
;; Remove old bookmark, if one exists.
- (let ((old (assq article gnus-newsgroup-bookmarks)))
- (if old
- (progn
- (setq gnus-newsgroup-bookmarks
- (delq old gnus-newsgroup-bookmarks))
- (gnus-message 6 "Removed bookmark."))
- (gnus-message 6 "No bookmark in current article."))))
+ (if (not (assq article gnus-newsgroup-bookmarks))
+ (gnus-message 6 "No bookmark in current article.")
+ (gnus-pull article gnus-newsgroup-bookmarks)
+ (gnus-message 6 "Removed bookmark.")))
;; Suggested by Daniel Quinlan <quinlan@best.com>.
(defun gnus-summary-mark-as-dormant (n)
If N is negative, mark backwards instead. Mark with MARK, ?r by default.
The difference between N and the actual number of articles marked is
returned.
-Iff NO-EXPIRE, auto-expiry will be inhibited."
+If NO-EXPIRE, auto-expiry will be inhibited."
(interactive "p")
(gnus-summary-show-thread)
(let ((backward (< n 0))
(gnus-summary-goto-unread
(and gnus-summary-goto-unread
(not (eq gnus-summary-goto-unread 'never))
- (not (memq mark (list gnus-unread-mark
+ (not (memq mark (list gnus-unread-mark gnus-spam-mark
gnus-ticked-mark gnus-dormant-mark)))))
(n (abs n))
(mark (or mark gnus-del-mark)))
(gnus-error 1 "Can't mark negative article numbers")
nil)
(setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
- (setq gnus-newsgroup-spam-marked (delq article gnus-newsgroup-spam-marked))
+ (setq gnus-newsgroup-spam-marked
+ (delq article gnus-newsgroup-spam-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))
If MARK is nil, then the default character `?r' is used.
If ARTICLE is nil, then the article on the current line will be
marked.
-Iff NO-EXPIRE, auto-expiry will be inhibited."
+If NO-EXPIRE, auto-expiry will be inhibited."
;; The mark might be a string.
(when (stringp mark)
(setq mark (aref mark 0)))
(gnus-run-hooks 'gnus-summary-update-hook))
t)
+(defun gnus-summary-update-download-mark (article)
+ "Update the download mark."
+ (gnus-summary-update-mark
+ (cond ((memq article gnus-newsgroup-undownloaded)
+ gnus-undownloaded-mark)
+ (gnus-newsgroup-agentized
+ gnus-downloaded-mark)
+ (t
+ gnus-no-mark))
+ 'download)
+ (gnus-summary-update-line t)
+ t)
+
(defun gnus-summary-update-mark (mark type)
(let ((forward (cdr (assq type gnus-summary-mark-positions)))
(buffer-read-only nil))
(gnus-add-to-sorted-list gnus-newsgroup-marked article)))
((= mark gnus-spam-mark)
(setq gnus-newsgroup-spam-marked
- (gnus-add-to-sorted-list gnus-newsgroup-spam-marked article)))
+ (gnus-add-to-sorted-list gnus-newsgroup-spam-marked
+ article)))
((= mark gnus-dormant-mark)
(setq gnus-newsgroup-dormant
(gnus-add-to-sorted-list gnus-newsgroup-dormant article)))
(when (memq gnus-current-article gnus-newsgroup-unreads)
(gnus-summary-mark-article gnus-current-article gnus-read-mark)))
-(defun gnus-summary-mark-read-and-unread-as-read ()
+(defun gnus-summary-mark-read-and-unread-as-read (&optional new-mark)
+ "Intended to be used by `gnus-summary-mark-article-hook'."
+ (let ((mark (gnus-summary-article-mark)))
+ (when (or (gnus-unread-mark-p mark)
+ (gnus-read-mark-p mark))
+ (gnus-summary-mark-article gnus-current-article
+ (or new-mark gnus-read-mark)))))
+
+(defun gnus-summary-mark-current-read-and-unread-as-read (&optional new-mark)
"Intended to be used by `gnus-summary-mark-article-hook'."
(let ((mark (gnus-summary-article-mark)))
(when (or (gnus-unread-mark-p mark)
(gnus-read-mark-p mark))
- (gnus-summary-mark-article gnus-current-article gnus-read-mark))))
+ (gnus-summary-mark-article (gnus-summary-article-number)
+ (or new-mark gnus-read-mark)))))
(defun gnus-summary-mark-unread-as-ticked ()
"Intended to be used by `gnus-summary-mark-article-hook'."
If prefix argument ALL is non-nil, ticked and dormant articles will
also be marked as read.
If QUIETLY is non-nil, no questions will be asked.
+
If TO-HERE is non-nil, it should be a point in the buffer. All
-articles before (after, if REVERSE is set) this point will be marked as read.
+articles before (after, if REVERSE is set) this point will be marked
+as read.
+
Note that this function will only catch up the unread article
in the current summary buffer limitation.
+
The number of articles marked as read is returned."
(interactive "P")
(prog1
(setq gnus-newsgroup-marked nil
gnus-newsgroup-spam-marked nil
gnus-newsgroup-dormant nil))
- (setq gnus-newsgroup-unreads gnus-newsgroup-downloadable))
+ (setq gnus-newsgroup-unreads
+ (gnus-sorted-nunion
+ (gnus-intersection gnus-newsgroup-unreads
+ gnus-newsgroup-downloadable)
+ gnus-newsgroup-unfetched)))
;; We actually mark all articles as canceled, which we
;; have to do when using auto-expiry or adaptive scoring.
(gnus-summary-show-all-threads)
(if (and to-here reverse)
(progn
(goto-char to-here)
- (while (and
- (gnus-summary-mark-article-as-read gnus-catchup-mark)
- (gnus-summary-find-next (not all) nil nil t))))
- (when (gnus-summary-first-subject (not all) t)
+ (gnus-summary-mark-current-read-and-unread-as-read
+ gnus-catchup-mark)
+ (while (gnus-summary-find-next (not all))
+ (gnus-summary-mark-article-as-read gnus-catchup-mark)))
+ (when (gnus-summary-first-subject (not all))
(while (and
(if to-here (< (point) to-here) t)
(gnus-summary-mark-article-as-read gnus-catchup-mark)
- (gnus-summary-find-next (not all) nil nil t)))))
+ (gnus-summary-find-next (not all))))))
(gnus-set-mode-line 'summary))
t))
(gnus-summary-position-point)))
(gnus-summary-position-point))
(defun gnus-summary-catchup-from-here (&optional all)
- "Mark all unticked articles after the current one as read.
+ "Mark all unticked articles after (and including) the current one as read.
If ALL is non-nil, also mark ticked and dormant articles as read."
(interactive "P")
(save-excursion
;; We check that there are unread articles.
(when (or all (gnus-summary-find-next))
(gnus-summary-catchup all t beg nil t)))))
-
(gnus-summary-position-point))
+
(defun gnus-summary-catchup-all (&optional quietly)
- "Mark all articles in this newsgroup as read."
+ "Mark all articles in this newsgroup as read.
+This command is dangerous. Normally, you want \\[gnus-summary-catchup]
+instead, which marks only unread articles as read."
(interactive "P")
(gnus-summary-catchup t quietly))
(gnus-summary-exit))))
(defun gnus-summary-catchup-all-and-exit (&optional quietly)
- "Mark all articles in this newsgroup as read, and then exit."
+ "Mark all articles in this newsgroup as read, and then exit.
+This command is dangerous. Normally, you want \\[gnus-summary-catchup-and-exit]
+instead, which marks only unread articles as read."
(interactive "P")
(gnus-summary-catchup-and-exit t quietly))
(interactive)
(let ((buffer-read-only nil)
(orig (point))
- ;; first goto end then to beg, to have point at beg after let
- (end (progn (end-of-line) (point)))
+ (end (gnus-point-at-eol))
+ ;; Leave point at bol
(beg (progn (beginning-of-line) (point))))
(prog1
;; Any hidden lines here?
gnus-thread-hide-subtree)
(gnus-summary-hide-all-threads
(if (or (consp gnus-thread-hide-subtree)
- (gnus-functionp gnus-thread-hide-subtree))
+ (functionp gnus-thread-hide-subtree))
(gnus-make-predicate gnus-thread-hide-subtree)
nil))))
(gnus-set-mode-line 'summary)
n))
-(defun gnus-summary-pipe-output (&optional arg)
+(defun gnus-summary-pipe-output (&optional arg headers)
"Pipe the current article to a subprocess.
If N is a positive number, pipe the N next articles.
If N is a negative number, pipe the N previous articles.
If N is nil and any articles have been marked with the process mark,
-pipe those articles instead."
- (interactive "P")
+pipe those articles instead.
+If HEADERS (the symbolic prefix), include the headers, too."
+ (interactive (gnus-interactive "P\ny"))
(require 'gnus-art)
- (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe))
+ (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe)
+ (gnus-save-all-headers (or headers gnus-save-all-headers)))
(gnus-summary-save-article arg t))
(let ((buffer (get-buffer "*Shell Command Output*")))
- (if (and buffer
- (with-current-buffer buffer (> (point-max) (point-min))))
- (gnus-configure-windows 'pipe))))
+ (when (and buffer
+ (not (zerop (buffer-size buffer))))
+ (gnus-configure-windows 'pipe))))
(defun gnus-summary-save-article-mail (&optional arg)
"Append the current article to an mail file.
;; Regular expression.
(ignore-errors
(re-search-forward match nil t)))
- ((gnus-functionp match)
+ ((functionp match)
;; Function.
(save-restriction
(widen)
(set-buffer gnus-article-buffer)
(let ((handles (or gnus-article-mime-handles
(mm-dissect-buffer nil gnus-article-loose-mime)
- (mm-uu-dissect))))
+ (and gnus-article-emulate-mime
+ (mm-uu-dissect)))))
(when handles
(gnus-summary-save-parts-1 type dir handles reverse)
(unless gnus-article-mime-handles ;; Don't destroy this case.
(not (string-match type (mm-handle-media-type handle)))
(string-match type (mm-handle-media-type handle)))
(let ((file (expand-file-name
- (file-name-nondirectory
- (or
- (mail-content-type-get
- (mm-handle-disposition handle) 'filename)
- (concat gnus-newsgroup-name
- "." (number-to-string
- (cdr gnus-article-current)))))
+ (gnus-map-function
+ 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)
+ (concat gnus-newsgroup-name
+ "." (number-to-string
+ (cdr gnus-article-current))))))
dir)))
(unless (file-exists-p file)
(mm-save-part-to-file handle file))))))
;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
(when gnus-summary-selected-face
(save-excursion
- (let* ((beg (progn (beginning-of-line) (point)))
- (end (progn (end-of-line) (point)))
+ (let* ((beg (gnus-point-at-bol))
+ (end (gnus-point-at-eol))
;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
(from (if (get-text-property beg gnus-mouse-face-prop)
beg
(setq gnus-newsgroup-selected-overlay (gnus-make-overlay from to))
'face gnus-summary-selected-face))))))
-;; New implementation by Christian Limpach <Christian.Limpach@nice.ch>.
+(defvar gnus-summary-highlight-line-cached nil)
+(defvar gnus-summary-highlight-line-trigger nil)
+
+(defun gnus-summary-highlight-line-0 ()
+ (if (and (eq gnus-summary-highlight-line-trigger
+ gnus-summary-highlight)
+ gnus-summary-highlight-line-cached)
+ gnus-summary-highlight-line-cached
+ (setq gnus-summary-highlight-line-trigger gnus-summary-highlight
+ gnus-summary-highlight-line-cached
+ (let* ((cond (list 'cond))
+ (c cond)
+ (list gnus-summary-highlight))
+ (while list
+ (setcdr c (cons (list (caar list) (list 'quote (cdar list)))
+ nil))
+ (setq c (cdr c)
+ list (cdr list)))
+ (gnus-byte-compile (list 'lambda nil cond))))))
+
(defun gnus-summary-highlight-line ()
"Highlight current line according to `gnus-summary-highlight'."
- (let* ((list gnus-summary-highlight)
- (beg (gnus-point-at-bol))
- (article (gnus-summary-article-number))
- (score (or (cdr (assq (or article gnus-current-article)
+ (let* ((beg (gnus-point-at-bol))
+ (article (or (gnus-summary-article-number) gnus-current-article))
+ (score (or (cdr (assq article
gnus-newsgroup-scored))
gnus-summary-default-score 0))
(mark (or (gnus-summary-article-mark) gnus-unread-mark))
(inhibit-read-only t)
(default gnus-summary-default-score)
(default-high gnus-summary-default-high-score)
- (default-low gnus-summary-default-low-score))
- ;; Eval the cars of the lists until we find a match.
- (while (and list
- (not (eval (caar list))))
- (setq list (cdr list)))
- (let ((face (cdar list)))
+ (default-low gnus-summary-default-low-score)
+ (uncached (and gnus-summary-use-undownloaded-faces
+ (memq article gnus-newsgroup-undownloaded))))
+ (let ((face (funcall (gnus-summary-highlight-line-0))))
(unless (eq face (get-text-property beg 'face))
(gnus-put-text-property-excluding-characters-with-faces
beg (gnus-point-at-eol) 'face
(defun gnus-summary-setup-default-charset ()
"Setup newsgroup default charset."
- (if (equal gnus-newsgroup-name "nndraft:drafts")
+ (if (member gnus-newsgroup-name '("nndraft:delayed" "nndraft:drafts"))
(setq gnus-newsgroup-charset nil)
(let* ((ignored-charsets
(or gnus-newsgroup-ephemeral-ignored-charsets
(mail-header-number h))
gnus-newsgroup-headers)))
(setq gnus-newsgroup-headers
- (merge 'list
- gnus-newsgroup-headers
- (gnus-fetch-headers articles)
- 'gnus-article-sort-by-number))
+ (gnus-merge 'list
+ gnus-newsgroup-headers
+ (gnus-fetch-headers articles)
+ 'gnus-article-sort-by-number))
;; Suppress duplicates?
(when gnus-suppress-duplicates
(gnus-dup-suppress-articles))
(let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
older len)
(setq older
- (gnus-sorted-difference
- (gnus-uncompress-range (list gnus-newsgroup-active))
- old))
- (setq len (length older))
+ ;; Some nntp servers lie about their active range. When
+ ;; this happens, the active range can be in the millions.
+ ;; Use a compressed range to avoid creating a huge list.
+ (gnus-range-difference (list gnus-newsgroup-active) old))
+ (setq len (gnus-range-length older))
(cond
((null older) nil)
((numberp all)
(if (< all len)
- (setq older (last older all))))
- (all nil)
+ (let ((older-range (nreverse older)))
+ (setq older nil)
+
+ (while (> all 0)
+ (let* ((r (pop older-range))
+ (min (if (numberp r) r (car r)))
+ (max (if (numberp r) r (cdr r))))
+ (while (and (<= min max)
+ (> all 0))
+ (push max older)
+ (setq all (1- all)
+ max (1- max))))))
+ (setq older (gnus-uncompress-range older))))
+ (all
+ (setq older (gnus-uncompress-range older)))
(t
- (if (and (numberp gnus-large-newsgroup)
+ (when (and (numberp gnus-large-newsgroup)
(> len gnus-large-newsgroup))
(let* ((cursor-in-echo-area nil)
(initial (gnus-parameter-large-newsgroup-initial
(unless (string-match "^[ \t]*$" input)
(setq all (string-to-number input))
(if (< all len)
- (setq older (last older all))))))))
+ (let ((older-range (nreverse older)))
+ (setq older nil)
+
+ (while (> all 0)
+ (let* ((r (pop older-range))
+ (min (if (numberp r) r (car r)))
+ (max (if (numberp r) r (cdr r))))
+ (while (and (<= min max)
+ (> all 0))
+ (push max older)
+ (setq all (1- all)
+ max (1- max))))))))))
+ (setq older (gnus-uncompress-range older))))
(if (not older)
(message "No old news.")
(gnus-summary-insert-articles older)
(run-hooks 'gnus-sum-load-hook)
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
;;; gnus-sum.el ends here