;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
The server has to support NOV for any of this to work.
This feature can seriously impact performance it ignores all
-locally cached header entries."
+locally cached header entries. Setting it to t for groups for a
+server that doesn't expire articles (such as news.gmane.org),
+leads to very slow summary generation."
:group 'gnus-thread
:type '(choice (const :tag "off" nil)
(const :tag "on" t)
:type 'boolean
:group 'gnus-summary-marks)
-(defcustom gnus-use-marks t
+(defcustom gnus-propagate-marks t
"If non-nil, do not propagate marks to the backends."
- :version "21.1"
+ :version "23.1" ;; No Gnus
:type 'boolean
:group 'gnus-summary-marks)
:group 'gnus-summary
:type '(choice boolean regexp))
+(defcustom gnus-summary-pipe-output-default-command nil
+ "Command (and optional arguments) used to pipe article to subprocess.
+This will be used as the default command if it is non-nil. The value
+will be updated if you modify it when executing the command
+`gnus-summary-pipe-output' or the function `gnus-summary-save-in-pipe'."
+ :version "23.1" ;; No Gnus
+ :group 'gnus-summary
+ :type '(radio (const :tag "None" nil) (string :tag "Command")))
+
(defcustom gnus-summary-muttprint-program "muttprint"
- "Command (and optional arguments) used to run Muttprint."
+ "Command (and optional arguments) used to run Muttprint.
+The value will be updated if you modify it when executing the command
+`gnus-summary-muttprint'."
:version "22.1"
:group 'gnus-summary
:type 'string)
"?" 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-m\C-n" gnus-summary-sort-by-most-recent-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-t" gnus-summary-sort-by-recipient
"\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-m\C-d" gnus-summary-sort-by-most-recent-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
["Pop article off history" gnus-summary-pop-article t])
("Sort"
["Sort by number" gnus-summary-sort-by-number t]
+ ["Sort by most recent number" gnus-summary-sort-by-most-recent-number t]
["Sort by author" gnus-summary-sort-by-author t]
["Sort by recipient" gnus-summary-sort-by-recipient t]
["Sort by subject" gnus-summary-sort-by-subject t]
["Sort by date" gnus-summary-sort-by-date t]
+ ["Sort by most recent date" gnus-summary-sort-by-most-recent-date t]
["Sort by score" gnus-summary-sort-by-score t]
["Sort by lines" gnus-summary-sort-by-lines t]
["Sort by characters" gnus-summary-sort-by-chars t]
:group 'gnus-summary)
(defvar image-load-path)
+(defvar tool-bar-map)
(defun gnus-summary-make-tool-bar (&optional force)
"Make a summary mode tool bar from `gnus-summary-tool-bar'.
(i 32))
;; Nix out all the control chars...
(while (>= (setq i (1- i)) 0)
- (aset table i [??]))
+ (gnus-put-display-table i [??] table))
;; ... but not newline and cr, of course. (cr is necessary for the
;; selective display).
- (aset table ?\n nil)
- (aset table ?\r nil)
+ (gnus-put-display-table ?\n nil table)
+ (gnus-put-display-table ?\r nil table)
;; We keep TAB as well.
- (aset table ?\t nil)
+ (gnus-put-display-table ?\t nil table)
;; We nix out any glyphs 127 through 255, or 127 through 159 in
;; Emacs 23 (unicode), that are not set already.
(let ((i (if (ignore-errors (= (make-char 'latin-iso8859-1 160) 160))
256)))
(while (>= (setq i (1- i)) 127)
;; Only modify if the entry is nil.
- (unless (aref table i)
- (aset table i [??]))))
+ (unless (gnus-get-display-table i table)
+ (gnus-put-display-table i [??] table))))
(setq buffer-display-table table)))
(defun gnus-summary-set-article-display-arrow (pos)
(if (= gnus-tmp-lines -1)
(setq gnus-tmp-lines "?")
(setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
- (gnus-put-text-property
- (point)
- (progn (eval gnus-summary-line-format-spec) (point))
- 'gnus-number gnus-tmp-number)
+ (condition-case ()
+ (gnus-put-text-property
+ (point)
+ (progn (eval gnus-summary-line-format-spec) (point))
+ 'gnus-number gnus-tmp-number)
+ (error (gnus-message 5 "Error updating the summary line")))
(when (gnus-visual-p 'summary-highlight 'highlight)
(forward-line -1)
(gnus-run-hooks 'gnus-summary-update-hook)
(and (consp elem) ; Has to be a cons.
(consp (cdr elem)) ; The cdr has to be a list.
(symbolp (car elem)) ; Has to be a symbol in there.
+
+ ;; Variables like `gnus-show-threads' that are globally bound,
+ ;; if used as group parameters, need to get to be buffer-local,
+ ;; whereas just parameters like `gcc-self', `timestamp', etc.
+ ;; should not be bound as variables.
+ (boundp (car elem)) ; Has to be already bound
+
(not (memq (car elem) vars))
(ignore-errors ; So we set it.
(push (car elem) vars)
(setq gnus-tmp-lines "?")
(setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
(gnus-put-text-property
- (point)
- (progn (eval gnus-summary-line-format-spec) (point))
+ (point)
+ (progn (eval gnus-summary-line-format-spec) (point))
'gnus-number number)
- (when gnus-visual-p
- (forward-line -1)
- (gnus-run-hooks 'gnus-summary-update-hook)
- (forward-line 1))
+ (when gnus-visual-p
+ (forward-line -1)
+ (gnus-run-hooks 'gnus-summary-update-hook)
+ (forward-line 1))
- (setq gnus-tmp-prev-subject simp-subject)))
+ (setq gnus-tmp-prev-subject simp-subject)))
(when (nth 1 thread)
(push (list (max 0 gnus-tmp-level)
This entails weeding out unwanted dormants, low-scored articles,
fetch-old-headers verbiage, and so on."
;; Most groups have nothing to remove.
- (if (or gnus-inhibit-limiting
- (and (null gnus-newsgroup-dormant)
- (eq gnus-newsgroup-display 'gnus-not-ignore)
- (not (eq gnus-fetch-old-headers 'some))
- (not (numberp gnus-fetch-old-headers))
- (not (eq gnus-fetch-old-headers 'invisible))
- (null gnus-summary-expunge-below)
- (not (eq gnus-build-sparse-threads 'some))
- (not (eq gnus-build-sparse-threads 'more))
- (null gnus-thread-expunge-below)
- (not gnus-use-nocem)))
- () ; Do nothing.
+ (unless (or gnus-inhibit-limiting
+ (and (null gnus-newsgroup-dormant)
+ (eq gnus-newsgroup-display 'gnus-not-ignore)
+ (not (eq gnus-fetch-old-headers 'some))
+ (not (numberp gnus-fetch-old-headers))
+ (not (eq gnus-fetch-old-headers 'invisible))
+ (null gnus-summary-expunge-below)
+ (not (eq gnus-build-sparse-threads 'some))
+ (not (eq gnus-build-sparse-threads 'more))
+ (null gnus-thread-expunge-below)
+ (not gnus-use-nocem)))
(push gnus-newsgroup-limit gnus-newsgroup-limits)
(setq gnus-newsgroup-limit nil)
(mapatoms
(interactive "P")
(gnus-summary-sort 'number reverse))
+(defun gnus-summary-sort-by-most-recent-number (&optional reverse)
+ "Sort the summary buffer by most recent article number.
+Argument REVERSE means reverse order."
+ (interactive "P")
+ (gnus-summary-sort 'most-recent-number reverse))
+
(defun gnus-summary-sort-by-random (&optional reverse)
"Randomize the order in the summary buffer.
Argument REVERSE means to randomize in reverse order."
(interactive "P")
(gnus-summary-sort 'date reverse))
+(defun gnus-summary-sort-by-most-recent-date (&optional reverse)
+ "Sort the summary buffer by most recent date.
+Argument REVERSE means reverse order."
+ (interactive "P")
+ (gnus-summary-sort 'most-recent-date reverse))
+
(defun gnus-summary-sort-by-score (&optional reverse)
"Sort the summary buffer by score.
Argument REVERSE means reverse order."
gnus-display-mime-function))
(gnus-article-prepare-hook (when decode
gnus-article-prepare-hook)))
- (gnus-summary-select-article t nil nil article)
+ (gnus-summary-select-article t t nil article)
(gnus-summary-goto-subject article)))
(with-current-buffer save-buffer
(erase-buffer)
(gnus-set-mode-line 'summary)
n))
-(defun gnus-summary-pipe-output (&optional arg headers)
+(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.
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.
-If HEADERS (the symbolic prefix), include the headers, too."
+The default command to which articles are piped is specified by the
+variable `gnus-summary-pipe-output-default-command'; if it is nil, you
+will be prompted for the command.
+
+The properties `:decode' and `:headers' that are put to the function
+symbol `gnus-summary-save-in-pipe' control whether this function
+decodes articles and what headers to keep (see the doc string for the
+`gnus-default-article-saver' variable). If SYM (the symbolic prefix)
+is neither omitted nor the symbol `r', force including all headers
+regardless of the `:headers' property. If it is the symbol `r',
+articles that are not decoded and include all headers will be piped
+no matter what the properties `:decode' and `:headers' are."
(interactive (gnus-interactive "P\ny"))
(require 'gnus-art)
- (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*")))
- (when (and buffer
- (not (zerop (buffer-size buffer))))
- (gnus-configure-windows 'pipe))))
+ (let* ((articles (gnus-summary-work-articles n))
+ (result-buffer "*Shell Command Output*")
+ (all-headers (not (memq sym '(nil r))))
+ (gnus-save-all-headers (or all-headers gnus-save-all-headers))
+ (raw (eq sym 'r))
+ (headers (get 'gnus-summary-save-in-pipe :headers))
+ command result)
+ (unless (numberp (car articles))
+ (error "No article to pipe"))
+ (setq command (gnus-read-shell-command
+ (concat "Shell command on "
+ (if (cdr articles)
+ (format "these %d articles" (length articles))
+ "this article")
+ ": ")
+ gnus-summary-pipe-output-default-command))
+ (when (string-equal command "")
+ (error "A command is required"))
+ (when all-headers
+ (put 'gnus-summary-save-in-pipe :headers nil))
+ (unwind-protect
+ (while articles
+ (gnus-summary-goto-subject (pop articles))
+ (save-window-excursion (gnus-summary-save-in-pipe command raw))
+ (when (and (get-buffer result-buffer)
+ (not (zerop (buffer-size (get-buffer result-buffer)))))
+ (setq result (concat result (with-current-buffer result-buffer
+ (buffer-string))))))
+ (put 'gnus-summary-save-in-pipe :headers headers))
+ (unless (zerop (length result))
+ (if (with-current-buffer (get-buffer-create result-buffer)
+ (erase-buffer)
+ (insert result)
+ (prog1
+ (and (= (count-lines (point-min) (point)) 1)
+ (progn
+ (end-of-line 0)
+ (<= (current-column)
+ (window-width (minibuffer-window)))))
+ (goto-char (point-min))))
+ (message "%s" (substring result 0 -1))
+ (message nil)
+ (gnus-configure-windows 'pipe)))))
(defun gnus-summary-save-article-mail (&optional arg)
"Append the current article to a Unix mail box file.
(save-excursion
(let (setmarkundo)
;; Propagate the read marks to the backend.
- (when (and gnus-use-marks
+ (when (and gnus-propagate-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))))