X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5895d7b92473b639531395df260729998d609653..527769f7ede3788154e709befd8f8127d8b1832a:/lisp/gnus/gnus-sum.el diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 66b661884e..9bae9f981b 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -1,6 +1,6 @@ ;;; gnus-sum.el --- summary mode commands for Gnus -;; Copyright (C) 1996-2011 Free Software Foundation, Inc. +;; Copyright (C) 1996-2013 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news @@ -122,6 +122,7 @@ If t, fetch all the available old headers." "*Use nnir to search an entire server when referring threads. A nil value will only search for thread-related articles in the current group." + :version "24.1" :group 'gnus-thread :type 'boolean) @@ -364,7 +365,7 @@ newsgroups, set the variable to nil in `gnus-select-group-hook'." This variable can either be the symbols `first' (place point on the first subject), `unread' (place point on the subject line of the first unread article), `best' (place point on the subject line of the -higest-scored article), `unseen' (place point on the subject line of +highest-scored article), `unseen' (place point on the subject line of the first unseen article), `unseen-or-unread' (place point on the subject line of the first unseen article or, if all articles have been seen, on the subject line of the first unread article), or a function to be called to @@ -450,7 +451,8 @@ current article is unread." :group 'gnus-summary-maneuvering :type 'boolean) -(defcustom gnus-auto-center-summary 2 +(defcustom gnus-auto-center-summary + (max (or (bound-and-true-p scroll-margin) 0) 2) "*If non-nil, always center the current summary buffer. In particular, if `vertical' do only vertical recentering. If non-nil and non-`vertical', do both horizontal and vertical recentering." @@ -1165,7 +1167,7 @@ using `gnus-ignored-from-addresses'." (defcustom gnus-summary-newsgroup-prefix "=> " "*String prefixed to the Newsgroup field in the summary -line when using `gnus-ignored-from-addresses'." +line when using the option `gnus-ignored-from-addresses'." :version "22.1" :group 'gnus-summary :type 'string) @@ -1242,13 +1244,6 @@ For example: ((1 . cn-gb-2312) (2 . big5))." :type 'boolean :group 'gnus-summary-marks) -(defcustom gnus-propagate-marks nil - "If non-nil, Gnus will store and retrieve marks from the backends. -This means that marks will be stored both in .newsrc.eld and in -the backend, and will slow operation down somewhat." - :type 'boolean - :group 'gnus-summary-marks) - (defcustom gnus-alter-articles-to-read-function nil "Function to be called to alter the list of articles to be selected." :type '(choice (const nil) function) @@ -1371,15 +1366,12 @@ the normal Gnus MIME machinery." (?c (or (mail-header-chars gnus-tmp-header) 0) ?d) (?k (gnus-summary-line-message-size gnus-tmp-header) ?s) (?L gnus-tmp-lines ?s) - (?Z (or ,(gnus-macroexpand-all - '(nnir-article-rsv (mail-header-number gnus-tmp-header))) + (?Z (or (nnir-article-rsv (mail-header-number gnus-tmp-header)) 0) ?d) - (?G (or ,(gnus-macroexpand-all - '(nnir-article-group (mail-header-number gnus-tmp-header))) + (?G (or (nnir-article-group (mail-header-number gnus-tmp-header)) "") ?s) - (?g (or ,(gnus-macroexpand-all - '(gnus-group-short-name - (nnir-article-group (mail-header-number gnus-tmp-header)))) + (?g (or (gnus-group-short-name + (nnir-article-group (mail-header-number gnus-tmp-header))) "") ?s) (?O gnus-tmp-downloaded ?c) (?I gnus-tmp-indentation ?s) @@ -1532,6 +1524,9 @@ This list will always be a subset of gnus-newsgroup-undownloaded.") (defvar gnus-newsgroup-seen nil "Range of seen articles in the current newsgroup.") +(defvar gnus-newsgroup-unexist nil + "Range of unexistent articles in the current newsgroup.") + (defvar gnus-newsgroup-articles nil "List of articles in the current newsgroup.") @@ -1579,6 +1574,7 @@ This list will always be a subset of gnus-newsgroup-undownloaded.") gnus-newsgroup-killed gnus-newsgroup-unseen gnus-newsgroup-seen + gnus-newsgroup-unexist gnus-newsgroup-cached gnus-newsgroup-downloadable gnus-newsgroup-undownloaded @@ -1657,7 +1653,7 @@ For example: This variable is a list of FUNCTION or (REGEXP . FUNCTION). If item is FUNCTION, FUNCTION will be apply to all newsgroups. If item is a -\(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups +\(REGEXP . FUNCTION), FUNCTION will be applied only to the newsgroups whose names match REGEXP. For example: @@ -1827,6 +1823,7 @@ increase the score of each group you read." (gnus-define-keys gnus-summary-mode-map " " gnus-summary-next-page + [?\S-\ ] gnus-summary-prev-page "\177" gnus-summary-prev-page [delete] gnus-summary-prev-page [backspace] gnus-summary-prev-page @@ -1919,7 +1916,8 @@ increase the score of each group you read." "a" gnus-summary-post-news "x" gnus-summary-limit-to-unread "s" gnus-summary-isearch-article - [tab] gnus-summary-widget-forward + "\t" gnus-summary-widget-forward + [backtab] gnus-summary-widget-backward "t" gnus-summary-toggle-header "g" gnus-summary-show-article "l" gnus-summary-goto-last-article @@ -2065,6 +2063,7 @@ increase the score of each group you read." (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map) " " gnus-summary-next-page "n" gnus-summary-next-page + [?\S-\ ] gnus-summary-prev-page "\177" gnus-summary-prev-page [delete] gnus-summary-prev-page "p" gnus-summary-prev-page @@ -2083,7 +2082,8 @@ increase the score of each group you read." "W" gnus-warp-to-article "g" gnus-summary-show-article "s" gnus-summary-isearch-article - [tab] gnus-summary-widget-forward + "\t" gnus-summary-widget-forward + [backtab] gnus-summary-widget-backward "P" gnus-summary-print-article "S" gnus-sticky-article "M" gnus-mailing-list-insinuate @@ -2529,7 +2529,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) ["Unshar and save" gnus-uu-decode-unshar-and-save t] ["Save" gnus-uu-decode-save t] ["Binhex" gnus-uu-decode-binhex t] - ["Postscript" gnus-uu-decode-postscript t] + ["PostScript" gnus-uu-decode-postscript t] ["All MIME parts" gnus-summary-save-parts t]) ("Cache" ["Enter article" gnus-cache-enter-article t] @@ -2835,7 +2835,7 @@ Setter function for custom variables." 'gnus-summary-tool-bar-retro) "Specifies the Gnus summary tool bar. -It can be either a list or a symbol refering to a list. See +It can be either a list or a symbol referring to a list. See `gmm-tool-bar-from-list' for the format of the list. The default key map is `gnus-summary-mode-map'. @@ -2969,16 +2969,10 @@ When FORCE, rebuild the tool bar." 'gnus-summary-mode-map))) (when map ;; Need to set `gnus-summary-tool-bar-map' because `gnus-article-mode' - ;; uses it's value. + ;; uses its value. (setq gnus-summary-tool-bar-map map)))) (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map)) -(defun gnus-score-set-default (var value) - "A version of set that updates the GNU Emacs menu-bar." - (set var value) - ;; It is the message that forces the active status to be updated. - (message "")) - (defun gnus-make-score-map (type) "Make a summary score map of type TYPE." (if t @@ -3062,6 +3056,7 @@ When FORCE, rebuild the tool bar." (declare-function turn-on-gnus-mailing-list-mode "gnus-ml" ()) (defvar bookmark-make-record-function) +(defvar bidi-paragraph-direction) (defun gnus-summary-mode (&optional group) "Major mode for reading articles. @@ -3101,6 +3096,9 @@ The following commands are available: (setq buffer-read-only t ;Disable modification show-trailing-whitespace nil) (setq truncate-lines t) + ;; Force paragraph direction to be left-to-right. Don't make it + ;; bound globally in old Emacsen and XEmacsen. + (set (make-local-variable 'bidi-paragraph-direction) 'left-to-right) (add-to-invisibility-spec '(gnus-sum . t)) (gnus-summary-set-display-table) (gnus-set-default-directory) @@ -3260,13 +3258,6 @@ The following commands are available: "Say whether this article is a sparse article or not." `(memq ,article gnus-newsgroup-ancient)) -(defun gnus-article-parent-p (number) - "Say whether this article is a parent or not." - (let ((data (gnus-data-find-list number))) - (and (cdr data) ; There has to be an article after... - (< (gnus-data-level (car data)) ; And it has to have a higher level. - (gnus-data-level (nth 1 data)))))) - (defun gnus-article-children (number) "Return a list of all children to NUMBER." (let* ((data (gnus-data-find-list number)) @@ -3288,14 +3279,6 @@ The following commands are available: "Say whether this article is intangible or not." '(get-text-property (point) 'gnus-intangible)) -(defun gnus-article-read-p (article) - "Say whether ARTICLE is read or not." - (not (or (memq article gnus-newsgroup-marked) - (memq article gnus-newsgroup-spam-marked) - (memq article gnus-newsgroup-unreads) - (memq article gnus-newsgroup-unselected) - (memq article gnus-newsgroup-dormant)))) - ;; Some summary mode macros. (defmacro gnus-summary-article-number () @@ -3503,7 +3486,8 @@ display only a single character." (current-buffer)))))) (defun gnus-summary-setup-buffer (group) - "Initialize summary buffer." + "Initialize summary buffer. +If the setup was successful, non-nil is returned." (let ((buffer (gnus-summary-buffer-name group)) (dead-name (concat "*Dead Summary " (gnus-group-decoded-name group) "*"))) @@ -3515,8 +3499,8 @@ display only a single character." (set-buffer buffer) (setq gnus-summary-buffer (current-buffer)) (not gnus-newsgroup-prepared)) - ;; Fix by Sudish Joseph - (setq gnus-summary-buffer (set-buffer (gnus-get-buffer-create buffer))) + (set-buffer (gnus-get-buffer-create buffer)) + (setq gnus-summary-buffer (current-buffer)) (gnus-summary-mode group) (when (gnus-group-quit-config group) (set (make-local-variable 'gnus-single-article-buffer) nil)) @@ -3555,7 +3539,7 @@ buffer that was in action when the last article was fetched." (push (eval (car locals)) vlist)) (setq locals (cdr locals))) (setq vlist (nreverse vlist))) - (with-current-buffer gnus-group-buffer + (with-temp-buffer (setq gnus-newsgroup-name name gnus-newsgroup-marked marked gnus-newsgroup-spam-marked spam @@ -3574,11 +3558,7 @@ buffer that was in action when the last article was fetched." (if (consp (car locals)) (set (caar locals) (pop vlist)) (set (car locals) (pop vlist))) - (setq locals (cdr locals)))) - ;; The article buffer also has local variables. - (when (gnus-buffer-live-p gnus-article-buffer) - (set-buffer gnus-article-buffer) - (setq gnus-summary-buffer summary)))))) + (setq locals (cdr locals)))))))) (defun gnus-summary-article-unread-p (article) "Say whether ARTICLE is unread or not." @@ -3680,8 +3660,8 @@ buffer that was in action when the last article was fetched." (defun gnus-summary-from-or-to-or-newsgroups (header gnus-tmp-from) (let ((mail-parse-charset gnus-newsgroup-charset) (ignored-from-addresses (gnus-ignored-from-addresses)) - ; Is it really necessary to do this next part for each summary line? - ; Luckily, doesn't seem to slow things down much. + ;; Is it really necessary to do this next part for each summary line? + ;; Luckily, doesn't seem to slow things down much. (mail-parse-ignored-charsets (with-current-buffer gnus-summary-buffer gnus-newsgroup-ignored-charsets))) @@ -3702,13 +3682,13 @@ buffer that was in action when the last article was fetched." (cdr (assq 'Newsgroups extra-headers)) (and (memq 'Newsgroups gnus-extra-headers) - (eq (car (gnus-find-method-for-group - gnus-newsgroup-name)) 'nntp) + (eq (car (gnus-find-method-for-group + gnus-newsgroup-name)) 'nntp) (gnus-group-real-name gnus-newsgroup-name)))) (concat gnus-summary-newsgroup-prefix newsgroups))))) (gnus-string-mark-left-to-right (inline - (gnus-summary-extract-address-component gnus-tmp-from)))))) + (gnus-summary-extract-address-component gnus-tmp-from)))))) (defun gnus-summary-insert-line (gnus-tmp-header gnus-tmp-level gnus-tmp-current @@ -3931,7 +3911,11 @@ Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"." "Start reading news in newsgroup GROUP. If SHOW-ALL is non-nil, already read articles are also listed. If NO-ARTICLE is non-nil, no article is selected initially. -If NO-DISPLAY, don't generate a summary buffer." +If NO-DISPLAY, don't generate the summary buffer contents. +If KILL-BUFFER, it should be a buffer that's killed once the new +summary buffer has been generated. +If BACKWARD, move point to the previous group in the group buffer +If SELECT-ARTICLES, only select those articles from GROUP." (let (result) (while (and group (null (setq result @@ -4081,9 +4065,10 @@ If NO-DISPLAY, don't generate a summary buffer." gnus-auto-select-first) (progn (let ((art (gnus-summary-article-number))) - (unless (and (not gnus-plugged) - (or (memq art gnus-newsgroup-undownloaded) - (memq art gnus-newsgroup-downloadable))) + (when (and art + gnus-plugged + (not (memq art gnus-newsgroup-undownloaded)) + (not (memq art gnus-newsgroup-downloadable))) (gnus-summary-goto-article art)))) ;; Don't select any articles. (gnus-summary-position-point) @@ -4257,7 +4242,7 @@ If NO-DISPLAY, don't generate a summary buffer." result)) (defun gnus-sort-gathered-threads (threads) - "Sort subtreads inside each gathered thread by `gnus-sort-gathered-threads-function'." + "Sort subthreads inside each gathered thread by `gnus-sort-gathered-threads-function'." (let ((result threads)) (while threads (when (stringp (caar threads)) @@ -4727,7 +4712,7 @@ If LINE, insert the rebuilt thread starting on line LINE." (car headers)))) (defun gnus-parent-headers (in-headers &optional generation) - "Return the headers of the GENERATIONeth parent of HEADERS." + "Return the headers of the GENERATIONth parent of HEADERS." (unless generation (setq generation 1)) (let ((parent t) @@ -5512,6 +5497,8 @@ or a straight list of headers." (cdr (assq number gnus-newsgroup-scored)) (memq number gnus-newsgroup-processable)))))) +(declare-function gnus-parameter-list-identifier "gnus-art" (name) t) + (defun gnus-group-get-list-identifiers (group) "Get list identifier regexp for GROUP." (or (gnus-parameter-list-identifier group) @@ -5676,7 +5663,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." ;; Init the dependencies hash table. (setq gnus-newsgroup-dependencies (gnus-make-hashtable (length articles))) - (gnus-set-global-variables) + (if (gnus-buffer-live-p gnus-group-buffer) + (gnus-set-global-variables) + (set-default 'gnus-newsgroup-name gnus-newsgroup-name)) ;; Retrieve the headers and read them in. (setq gnus-newsgroup-headers (gnus-fetch-headers articles)) @@ -5805,6 +5794,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." "Find out what articles the user wants to read." (let* ((only-read-p t) (articles + (gnus-list-range-difference ;; Select all articles if `read-all' is non-nil, or if there ;; are no unread articles. (if (or read-all @@ -5831,7 +5821,8 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq only-read-p nil) (gnus-sorted-nunion (gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked) - gnus-newsgroup-unreads))) + gnus-newsgroup-unreads)) + (cdr (assq 'unexist (gnus-info-marks (gnus-get-info group)))))) (scored-list (gnus-killed-articles gnus-newsgroup-killed articles)) (scored (length scored-list)) (number (length articles)) @@ -5859,15 +5850,15 @@ If SELECT-ARTICLES, only select those articles from GROUP." (read-string (if only-read-p (format - "How many articles from %s (available %d, default %d): " - (gnus-group-decoded-name - (gnus-group-real-name gnus-newsgroup-name)) - number default) - (format - "How many articles from %s (%d available): " + "How many articles from %s (available %d, default %d): " (gnus-group-decoded-name (gnus-group-real-name gnus-newsgroup-name)) - default)) + number default) + (format + "How many articles from %s (%d default): " + (gnus-group-decoded-name + (gnus-group-real-name gnus-newsgroup-name)) + default)) nil nil (number-to-string default)))) @@ -5920,17 +5911,6 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq articles (cdr articles))) out)) -(defun gnus-uncompress-marks (marks) - "Uncompress the mark ranges in MARKS." - (let ((uncompressed '(score bookmark)) - out) - (while marks - (if (memq (caar marks) uncompressed) - (push (car marks) out) - (push (cons (caar marks) (gnus-uncompress-range (cdar marks))) out)) - (setq marks (cdr marks))) - out)) - (defun gnus-article-mark-to-type (mark) "Return the type of MARK." (or (cadr (assq mark gnus-article-special-mark-lists)) @@ -5958,7 +5938,6 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq mark (car marks) mark-type (gnus-article-mark-to-type mark) var (intern (format "gnus-newsgroup-%s" (car (rassq mark types))))) - ;; We set the variable according to the type of the marks list, ;; and then adjust the marks to a subset of the active articles. (cond @@ -6013,7 +5992,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." (and (numberp (car articles)) (> min (car articles))))) (pop articles)) - (set var articles)))))))) + (set var articles)) + ((eq mark 'unexist) + (set var (cdr marks))))))))) (defun gnus-update-missing-marks (missing) "Go through the list of MISSING articles and remove them from the mark lists." @@ -6089,7 +6070,8 @@ If SELECT-ARTICLES, only select those articles from GROUP." (gnus-active gnus-newsgroup-name) del)) (push (list del 'del (list (cdr type))) delta-marks)))) - (when list + (when (or list + (eq (cdr type) 'unexist)) (push (cons (cdr type) list) newmarked))) (when delta-marks @@ -6277,13 +6259,18 @@ The resulting hash table is returned, or nil if no Xrefs were found." (entry (gnus-group-entry group)) (info (nth 2 entry)) (active (gnus-active group)) + (set-marks + (gnus-method-option-p + (gnus-find-method-for-group group) + 'server-marks)) range) (if (not entry) ;; Group that Gnus doesn't know exists, but still allow the ;; backend to set marks. - (gnus-request-set-mark - group (list (list (gnus-compress-sequence (sort articles #'<)) - 'add '(read)))) + (when set-marks + (gnus-request-set-mark + group (list (list (gnus-compress-sequence (sort articles #'<)) + 'add '(read))))) ;; Normal, subscribed groups. (setq range (gnus-compute-read-articles group articles)) (with-current-buffer gnus-group-buffer @@ -6292,11 +6279,14 @@ The resulting hash table is returned, or nil if no Xrefs were found." (gnus-info-set-marks ',info ',(gnus-info-marks info) t) (gnus-info-set-read ',info ',(gnus-info-read info)) (gnus-get-unread-articles-in-group ',info (gnus-active ,group)) - (gnus-request-set-mark ,group (list (list ',range 'del '(read)))) + (when ,set-marks + (gnus-request-set-mark + ,group (list (list ',range 'del '(read))))) (gnus-group-update-group ,group t)))) ;; Add the read articles to the range. (gnus-info-set-read info range) - (gnus-request-set-mark group (list (list range 'add '(read)))) + (when set-marks + (gnus-request-set-mark group (list (list range 'add '(read))))) ;; Then we have to re-compute how many unread ;; articles there are in this group. (when active @@ -6609,9 +6599,9 @@ too, instead of trying to fetch new headers." ;; article if ID is a number -- so that the next `P' or `N' ;; command will fetch the previous (or next) article even ;; if the one we tried to fetch this time has been canceled. - (when (> number gnus-newsgroup-end) + (unless (and gnus-newsgroup-end (< number gnus-newsgroup-end)) (setq gnus-newsgroup-end number)) - (when (< number gnus-newsgroup-begin) + (unless (and gnus-newsgroup-begin (> number gnus-newsgroup-begin)) (setq gnus-newsgroup-begin number)) (setq gnus-newsgroup-unselected (delq number gnus-newsgroup-unselected))) @@ -7087,7 +7077,7 @@ With ARG, turn line truncation on if ARG is positive." (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 +articles. An article is sought which is not canceled 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)) @@ -7237,7 +7227,8 @@ If FORCE (the prefix), also save the .newsrc file(s)." (gnus-summary-update-info)) (gnus-close-group group) ;; Make sure where we were, and go to next newsgroup. - (set-buffer gnus-group-buffer) + (when (buffer-live-p (get-buffer gnus-group-buffer)) + (set-buffer gnus-group-buffer)) (unless quit-config (gnus-group-jump-to-group group)) (gnus-run-hooks 'gnus-summary-exit-hook) @@ -7262,7 +7253,8 @@ If FORCE (the prefix), also save the .newsrc file(s)." (gnus-kill-buffer buf))) (setq gnus-current-select-method gnus-select-method) - (set-buffer gnus-group-buffer) + (when (gnus-buffer-live-p gnus-group-buffer) + (set-buffer gnus-group-buffer)) (if quit-config (gnus-handle-ephemeral-exit quit-config) (goto-char group-point) @@ -7287,6 +7279,9 @@ If FORCE (the prefix), also save the .newsrc file(s)." (unless quit-config (setq gnus-newsgroup-name nil))))) +(declare-function gnus-article-stop-animations "gnus-art" ()) +(declare-function gnus-stop-downloads "gnus-art" ()) + (defalias 'gnus-summary-quit 'gnus-summary-exit-no-update) (defun gnus-summary-exit-no-update (&optional no-questions) "Quit reading current newsgroup without updating read article info." @@ -7303,6 +7298,7 @@ If FORCE (the prefix), also save the .newsrc file(s)." (when (gnus-buffer-live-p gnus-article-buffer) (with-current-buffer gnus-article-buffer (gnus-article-stop-animations) + (gnus-stop-downloads) (mm-destroy-parts gnus-article-mime-handles) ;; Set it to nil for safety reason. (setq gnus-article-mime-handle-alist nil) @@ -7313,9 +7309,11 @@ If FORCE (the prefix), also save the .newsrc file(s)." (gnus-kill-buffer gnus-original-article-buffer) (setq gnus-article-current nil)) ;; Return to the group buffer. - (gnus-configure-windows 'group 'force) (if (not gnus-kill-summary-on-exit) - (gnus-deaden-summary) + (progn + (gnus-deaden-summary) + (gnus-configure-windows 'group 'force)) + (gnus-configure-windows 'group 'force) (gnus-close-group group) (gnus-kill-buffer gnus-summary-buffer)) (unless gnus-single-article-buffer @@ -7337,8 +7335,9 @@ If FORCE (the prefix), also save the .newsrc file(s)." (defun gnus-handle-ephemeral-exit (quit-config) "Handle movement when leaving an ephemeral group. The state which existed when entering the ephemeral is reset." - (if (not (buffer-name (car quit-config))) - (gnus-configure-windows 'group 'force) + (if (not (buffer-live-p (car quit-config))) + (when (gnus-buffer-live-p gnus-group-buffer) + (gnus-configure-windows 'group 'force)) (set-buffer (car quit-config)) (unless (eq (cdr quit-config) 'group) (setq gnus-current-select-method @@ -7736,10 +7735,6 @@ be displayed." gnus-buttonized-mime-types))) (gnus-summary-select-article nil 'force))) -(defun gnus-summary-set-current-mark (&optional current-mark) - "Obsolete function." - nil) - (defun gnus-summary-next-article (&optional unread subject backward push) "Select the next article. If UNREAD, only unread articles are selected. @@ -7879,6 +7874,8 @@ If UNREAD is non-nil, only unread articles are selected." (and gnus-auto-select-same (gnus-summary-article-subject)))) +(declare-function gnus-article-only-boring-p "gnus-art" ()) + (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. @@ -7892,7 +7889,6 @@ 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) (let ((article (gnus-summary-article-number)) (article-window (get-buffer-window gnus-article-buffer t)) @@ -8213,9 +8209,17 @@ If NOT-MATCHING, excluding articles that have subjects that match a regexp." "Limit the summary buffer to articles that have authors that match a regexp. If NOT-MATCHING, excluding articles that have authors that match a regexp." (interactive - (list (read-string (if current-prefix-arg - "Exclude author (regexp): " - "Limit to author (regexp): ")) + (list (let* ((header (gnus-summary-article-header)) + (default (and header (car (mail-header-parse-address + (mail-header-from header)))))) + (read-string (concat (if current-prefix-arg + "Exclude author (regexp" + "Limit to author (regexp") + (if default + (concat ", default \"" default "\"): ") + "): ")) + nil nil + default)) current-prefix-arg)) (gnus-summary-limit-to-subject from "from" not-matching)) @@ -8439,6 +8443,8 @@ If REVERSE (the prefix), limit to articles that don't match." (interactive "sMatch headers (regexp): \nP") (gnus-summary-limit-to-bodies match reverse t)) +(declare-function article-goto-body "gnus-art" ()) + (defun gnus-summary-limit-to-bodies (match &optional reverse headersp) "Limit the summary buffer to articles that have bodies that match MATCH. If REVERSE (the prefix), limit to articles that don't match." @@ -9032,7 +9038,8 @@ non-numeric or nil fetch the number specified by the 'gnus-article-sort-by-number))) (setq gnus-newsgroup-articles (gnus-sorted-nunion gnus-newsgroup-articles (nreverse article-ids))) - (gnus-summary-limit-include-thread id)))) + (gnus-summary-limit-include-thread id))) + (gnus-summary-show-thread)) (defun gnus-summary-refer-article (message-id) "Fetch an article specified by MESSAGE-ID." @@ -9146,7 +9153,7 @@ To control what happens when you exit the group, see the (list (cons 'save-article-group ogroup)))) (case-fold-search t) (buf (current-buffer)) - dig to-address) + dig to-address charset) (with-current-buffer gnus-original-article-buffer ;; Have the digest group inherit the main mail address of ;; the parent article. @@ -9159,16 +9166,32 @@ To control what happens when you exit the group, see the to-address)))))) (setq dig (nnheader-set-temp-buffer " *gnus digest buffer*")) (insert-buffer-substring gnus-original-article-buffer) - ;; Remove lines that may lead nndoc to misinterpret the - ;; document type. (narrow-to-region (goto-char (point-min)) (or (search-forward "\n\n" nil t) (point))) + ;; Remove lines that may lead nndoc to misinterpret the + ;; document type. (goto-char (point-min)) (delete-matching-lines "^Path:\\|^From ") + ;; Parse charset, and decode content transfer encoding. + (setq charset (mail-content-type-get + (mail-header-parse-content-type + (or (gnus-fetch-field "content-type") "")) + 'charset)) + (let ((encoding (gnus-fetch-field "content-transfer-encoding"))) + (when encoding + (message-remove-header "content-transfer-encoding") + (goto-char (point-max)) + (widen) + (narrow-to-region (point) (point-max)) + (mm-decode-content-transfer-encoding + (intern (downcase (mail-header-strip encoding)))))) (widen)) (unwind-protect - (if (let ((gnus-newsgroup-ephemeral-charset gnus-newsgroup-charset) + (if (let ((gnus-newsgroup-ephemeral-charset + (if charset + (intern (downcase (gnus-strip-whitespace charset))) + gnus-newsgroup-charset)) (gnus-newsgroup-ephemeral-ignored-charsets gnus-newsgroup-ignored-charsets)) (gnus-group-read-ephemeral-group @@ -9246,6 +9269,17 @@ With optional ARG, move across that many fields." (select-window (gnus-get-buffer-window gnus-article-buffer)) (widget-forward arg)) +(defun gnus-summary-widget-backward (arg) + "Move point to the previous field or button in the article. +With optional ARG, move across that many fields." + (interactive "p") + (gnus-summary-select-article) + (gnus-configure-windows 'article) + (select-window (gnus-get-buffer-window gnus-article-buffer)) + (unless (widget-at (point)) + (goto-char (point-max))) + (widget-backward arg)) + (defun gnus-summary-isearch-article (&optional regexp-p) "Do incremental search forward on the current article. If REGEXP-P (the prefix) is non-nil, do regexp isearch." @@ -9541,6 +9575,8 @@ to save in." (ps-spool-buffer-with-faces) (ps-spool-buffer))))) +(declare-function gnus-flush-original-article-buffer "gnus-art" ()) + (defun gnus-summary-show-complete-article () "Show a complete version of the current article. This is only useful if you're looking at a partial version of the @@ -9611,9 +9647,12 @@ C-u g', show the raw article." (when (gnus-summary-goto-subject (cdr gnus-article-current) nil t) (gnus-summary-update-secondary-mark (cdr gnus-article-current)))))) ((not arg) - (require 'shr) - (let ((shr-ignore-cache t)) - ;; Select the article the normal way. + ;; Select the article the normal way. + (if (eq mm-text-html-renderer 'shr) + (progn + (require 'shr) + (let ((shr-ignore-cache t)) + (gnus-summary-select-article nil 'force))) (gnus-summary-select-article nil 'force))) ((equal arg '(16)) ;; C-u C-u g @@ -9634,6 +9673,7 @@ C-u g', show the raw article." (when (gnus-buffer-live-p gnus-article-buffer) (with-current-buffer gnus-article-buffer (gnus-article-stop-animations) + (gnus-stop-downloads) (mm-destroy-parts gnus-article-mime-handles) ;; Set it to nil for safety reason. (setq gnus-article-mime-handle-alist nil) @@ -9660,6 +9700,10 @@ If ARG is a negative number, turn header display off." t))) (gnus-summary-show-article)) +(declare-function article-narrow-to-head "gnus-art" ()) +(declare-function gnus-article-hidden-text-p "gnus-art" (type)) +(declare-function gnus-delete-wash-type "gnus-art" (type)) + (defun gnus-summary-toggle-header (&optional arg) "Show the headers if they are hidden, or hide them if they are shown. If ARG is a positive number, show the entire header. @@ -9769,7 +9813,7 @@ installed for this command to work." (when (message-goto-body) (gnus-narrow-to-body)) (goto-char (point-min)) - (while (search-forward "·" (point-max) t) + (while (search-forward "·" (point-max) t) (replace-match ".")) (unmorse-region (point-min) (point-max)) (widen) @@ -10051,7 +10095,10 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (gnus-add-marked-articles to-group 'expire (list to-article) info)) - (when to-marks + (when (and to-marks + (gnus-method-option-p + (gnus-find-method-for-group to-group) + 'server-marks)) (gnus-request-set-mark to-group (list (list (list to-article) 'add to-marks))))) @@ -10102,17 +10149,20 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (defun gnus-summary-push-marks-to-backend (article) (let ((set nil) + (del nil) (marks gnus-article-mark-lists)) (unless (memq article gnus-newsgroup-unreads) (push 'read set)) (while marks - (when (and (eq (gnus-article-mark-to-type (cdar marks)) 'list) - (memq article (symbol-value - (intern (format "gnus-newsgroup-%s" - (caar marks)))))) - (push (cdar marks) set)) + (if (and (eq (gnus-article-mark-to-type (cdar marks)) 'list) + (memq article (symbol-value + (intern (format "gnus-newsgroup-%s" + (caar marks)))))) + (push (cdar marks) set) + (push (cdar marks) del)) (pop marks)) - (gnus-request-set-mark gnus-newsgroup-name `(((,article) set ,set))))) + (gnus-request-set-mark gnus-newsgroup-name `(((,article) set ,set) + ((,article) del ,del))))) (defun gnus-summary-copy-article (&optional n to-newsgroup select-method) "Copy the current article to some other group. @@ -10265,16 +10315,19 @@ This will be the case if the article has both been mailed and posted." 'request-expire-articles gnus-newsgroup-name)) ;; This backend supports expiry. (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name)) - (expirable (if total - (progn - ;; We need to update the info for - ;; this group for `gnus-list-of-read-articles' - ;; to give us the right answer. - (gnus-run-hooks 'gnus-exit-group-hook) - (gnus-summary-update-info) - (gnus-list-of-read-articles gnus-newsgroup-name)) - (setq gnus-newsgroup-expirable - (sort gnus-newsgroup-expirable '<)))) + (expirable + (gnus-list-range-difference + (if total + (progn + ;; We need to update the info for + ;; this group for `gnus-list-of-read-articles' + ;; to give us the right answer. + (gnus-run-hooks 'gnus-exit-group-hook) + (gnus-summary-update-info) + (gnus-list-of-read-articles gnus-newsgroup-name)) + (setq gnus-newsgroup-expirable + (sort gnus-newsgroup-expirable '<))) + gnus-newsgroup-unexist)) (expiry-wait (if now 'immediate (gnus-group-find-parameter gnus-newsgroup-name 'expiry-wait))) @@ -10883,6 +10936,7 @@ If NO-EXPIRE, auto-expiry will be inhibited." (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)) + (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads)) (cond ((= mark gnus-ticked-mark) (setq gnus-newsgroup-marked (gnus-add-to-sorted-list gnus-newsgroup-marked @@ -11555,6 +11609,7 @@ Returns nil if no thread was there to be shown." (beg (progn (beginning-of-line) (if (bobp) (point) (1- (point))))) (eoi (when end (if (fboundp 'next-single-char-property-change) + ;; Note: XEmacs version of n-s-c-p-c may return nil (or (next-single-char-property-change end 'invisible) (point-max)) (while (progn @@ -11620,10 +11675,10 @@ If PREDICATE is supplied, threads that satisfy this predicate will not be hidden. Returns nil if no threads were there to be hidden." (interactive) + (beginning-of-line) (let ((start (point)) (starteol (line-end-position)) (article (gnus-summary-article-number))) - (goto-char start) ;; Go forward until either the buffer ends or the subthread ends. (when (and (not (eobp)) (or (zerop (gnus-summary-next-thread 1 t)) @@ -11913,7 +11968,7 @@ will not be marked as saved." ;; This is a pseudo-article. (if (assq 'name header) (gnus-copy-file (cdr (assq 'name header))) - (gnus-message 1 "Article %d is unsaveable" article)) + (gnus-message 1 "Article %d is unsavable" article)) ;; This is a real article. (save-window-excursion (gnus-summary-select-article decode decode nil article) @@ -11935,6 +11990,8 @@ will not be marked as saved." (gnus-set-mode-line 'summary) n)) +(declare-function gnus-summary-save-in-pipe "gnus-art" (&optional command raw)) + (defun gnus-summary-pipe-output (&optional n sym) "Pipe the current article to a subprocess. If N is a positive number, pipe the N next articles. @@ -12384,6 +12441,15 @@ If REVERSE, save parts that do not match TYPE." (not (setq header (car (gnus-get-newsgroup-headers nil t))))) () ; Malformed head. (unless (gnus-summary-article-sparse-p (mail-header-number header)) + (when (and (bound-and-true-p gnus-registry-enabled) + (not (gnus-ephemeral-group-p (car where)))) + (gnus-registry-handle-action + (mail-header-id header) nil + (gnus-group-prefixed-name + (car where) + (or gnus-override-method (gnus-find-method-for-group group))) + (mail-header-subject header) + (mail-header-from header))) (when (and (stringp id) (or (not (string= (gnus-group-real-name group) @@ -12487,7 +12553,7 @@ If REVERSE, save parts that do not match TYPE." (memq article gnus-newsgroup-undownloaded) (not (memq article gnus-newsgroup-cached))))) (let ((face (funcall (gnus-summary-highlight-line-0)))) - (unless (eq face (get-text-property beg 'face)) + (unless (eq face (gnus-get-text-property-excluding-characters-with-faces beg 'face)) (gnus-put-text-property-excluding-characters-with-faces beg (point-at-eol) 'face (setq face (if (boundp face) (symbol-value face) face))) @@ -12531,10 +12597,9 @@ UNREAD is a sorted list." (save-excursion (let (setmarkundo) ;; Propagate the read marks to the backend. - (when (and (or gnus-propagate-marks - (gnus-method-option-p - (gnus-find-method-for-group group) - 'server-marks)) + (when (and (gnus-method-option-p + (gnus-find-method-for-group group) + 'server-marks) (gnus-check-backend-function 'request-set-mark group)) (let ((del (gnus-remove-from-range (gnus-info-read info) read)) (add (gnus-remove-from-range read (gnus-info-read info)))) @@ -12742,7 +12807,7 @@ returned." (setq gnus-newsgroup-headers (gnus-merge 'list gnus-newsgroup-headers - (gnus-fetch-headers articles) + (gnus-fetch-headers articles nil t) 'gnus-article-sort-by-number)) (setq gnus-newsgroup-articles (gnus-sorted-nunion gnus-newsgroup-articles articles)) @@ -12795,7 +12860,9 @@ If ALL is a number, fetch this number of articles." ;; 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)) + (gnus-range-difference + (gnus-range-difference (list gnus-newsgroup-active) old) + gnus-newsgroup-unexist)) (setq len (gnus-range-length older)) (cond ((null older) nil) @@ -12829,9 +12896,9 @@ If ALL is a number, fetch this number of articles." (gnus-group-decoded-name gnus-newsgroup-name) (if initial "max" "default") len) - (if initial - (cons (number-to-string initial) - 0))))) + nil nil + (and initial + (number-to-string initial))))) (unless (string-match "^[ \t]*$" input) (setq all (string-to-number input)) (if (< all len) @@ -12879,6 +12946,7 @@ If ALL is a number, fetch this number of articles." (gnus-summary-position-point)) ;;; Bookmark support for Gnus. +(declare-function gnus-article-show-summary "gnus-art" ()) (declare-function bookmark-make-record-default "bookmark" (&optional no-file no-context posn)) (declare-function bookmark-prop-get "bookmark" (bookmark prop)) @@ -12945,7 +13013,7 @@ BOOKMARK is a bookmark name or a bookmark record." (run-hooks 'gnus-sum-load-hook) ;; Local Variables: -;; coding: iso-8859-1 +;; coding: utf-8 ;; End: ;;; gnus-sum.el ends here