;;; gnus-sum.el --- summary mode commands for Gnus
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005 Free Software Foundation, Inc.
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
(eval-when-compile
(require 'cl)
- (defvar tool-bar-map))
+ (defvar tool-bar-mode))
(require 'gnus)
(require 'gnus-group)
(require 'gnus-int)
(require 'gnus-undo)
(require 'gnus-util)
+(require 'gmm-utils)
(require 'mm-decode)
(require 'nnoo)
(defcustom gnus-fetch-old-headers nil
"*Non-nil means that Gnus will try to build threads by grabbing old headers.
-If an unread article in the group refers to an older, already read (or
-just marked as read) article, the old article will not normally be
-displayed in the Summary buffer. If this variable is t, Gnus
-will attempt to grab the headers to the old articles, and thereby
-build complete threads. If it has the value `some', only enough
-headers to connect otherwise loose threads will be displayed. This
-variable can also be a number. In that case, no more than that number
-of old headers will be fetched. If it has the value `invisible', all
+If an unread article in the group refers to an older, already
+read (or just marked as read) article, the old article will not
+normally be displayed in the Summary buffer. If this variable is
+t, Gnus will attempt to grab the headers to the old articles, and
+thereby build complete threads. If it has the value `some', all
+old headers will be fetched but only enough headers to connect
+otherwise loose threads will be displayed. This variable can
+also be a number. In that case, no more than that number of old
+headers will be fetched. If it has the value `invisible', all
old headers will be fetched, but none will be displayed.
-The server has to support NOV for any of this to work."
+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."
:group 'gnus-thread
:type '(choice (const :tag "off" nil)
(const :tag "on" t)
"Q" gnus-summary-exit
"Z" gnus-summary-exit
"n" gnus-summary-catchup-and-goto-next-group
+ "p" gnus-summary-catchup-and-goto-prev-group
"R" gnus-summary-reselect-current-group
"G" gnus-summary-rescan-group
"N" gnus-summary-next-group
'(:help "Mark unread articles in this group as read, then exit"))]
["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
+ ["Catchup and goto prev" gnus-summary-catchup-and-goto-prev-group t]
["Exit group" gnus-summary-exit
,@(if (featurep 'xemacs) '(t)
'(:help "Exit current group, return to group selection mode"))]
(defvar gnus-summary-tool-bar-map nil)
-;; Emacs 21 tool bar. Should be no-op otherwise.
-(defun gnus-summary-make-tool-bar ()
- (if (and (fboundp 'tool-bar-add-item-from-menu)
- (default-value 'tool-bar-mode)
- (not gnus-summary-tool-bar-map))
- (setq gnus-summary-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap))
- (load-path (mm-image-load-path)))
- (tool-bar-add-item-from-menu
- 'gnus-summary-prev-unread "prev-ur" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-next-unread "next-ur" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-post-news "post" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-followup-with-original "fuwo" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-followup "followup" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-reply-with-original "reply-wo" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-reply "reply" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-caesar-message "rot13" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-uu-decode-uu "uu-decode" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-save-article-file "save-aif" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-save-article "save-art" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-uu-post-news "uu-post" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-uu-post-news "uu-post" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-catchup "catchup" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-catchup-and-exit "cu-exit" gnus-summary-mode-map)
- (tool-bar-add-item-from-menu
- 'gnus-summary-exit "exit-summ" gnus-summary-mode-map)
- tool-bar-map)))
- (if gnus-summary-tool-bar-map
- (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map)))
+;; Note: The :set function in the `gnus-summary-tool-bar*' variables will only
+;; affect _new_ message buffers. We might add a function that walks thru all
+;; summary-mode buffers and force the update.
+(defun gnus-summary-tool-bar-update (&optional symbol value)
+ "Update summary mode toolbar.
+Setter function for custom variables."
+ (setq-default gnus-summary-tool-bar-map nil)
+ (when symbol
+ ;; When used as ":set" function:
+ (set-default symbol value))
+ (when (gnus-buffer-live-p gnus-summary-buffer)
+ (with-current-buffer gnus-summary-buffer
+ (gnus-summary-make-tool-bar))))
+
+(defcustom gnus-summary-tool-bar (if (eq gmm-tool-bar-style 'gnome)
+ 'gnus-summary-tool-bar-gnome
+ '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
+`gmm-tool-bar-from-list' for the format of the list. The
+default key map is `gnus-summary-mode-map'.
+
+Pre-defined symbols include `gnus-summary-tool-bar-gnome' and
+`gnus-summary-tool-bar-retro'."
+ :type '(choice (const :tag "GNOME style" gnus-summary-tool-bar-gnome)
+ (const :tag "Retro look" gnus-summary-tool-bar-retro)
+ (repeat :tag "User defined list" gmm-tool-bar-item)
+ (symbol))
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defcustom gnus-summary-tool-bar-gnome
+ '((gnus-summary-post-news "mail/compose" nil)
+ (gnus-summary-insert-new-articles "mail/inbox" nil
+ :visible (or (not gnus-agent)
+ gnus-plugged))
+ (gnus-summary-reply-with-original "mail/reply")
+ (gnus-summary-reply "mail/reply" nil :visible nil)
+ (gnus-summary-followup-with-original "mail/reply-all")
+ (gnus-summary-followup "mail/reply-all" nil :visible nil)
+ (gnus-summary-mail-forward "mail/forward")
+ (gnus-summary-save-article "mail/save")
+ (gnus-summary-search-article-forward "search" nil :visible nil)
+ (gnus-summary-print-article "print")
+ (gnus-summary-tick-article-forward "flag-followup" nil :visible nil)
+ ;; Some new commands that may need more suitable icons:
+ (gnus-summary-save-newsrc "save" nil :visible nil)
+ ;; (gnus-summary-show-article "stock_message-display" nil :visible nil)
+ (gnus-summary-prev-article "left-arrow")
+ (gnus-summary-next-article "right-arrow")
+ (gnus-summary-next-page "next-page")
+ ;; (gnus-summary-enter-digest-group "right_arrow" nil :visible nil)
+ ;;
+ ;; Maybe some sort-by-... could be added:
+ ;; (gnus-summary-sort-by-author "sort-a-z" nil :visible nil)
+ ;; (gnus-summary-sort-by-date "sort-1-9" nil :visible nil)
+ (gnus-summary-mark-as-expirable
+ "delete" nil
+ :visible (gnus-check-backend-function 'request-expire-articles
+ gnus-newsgroup-name))
+ (gnus-summary-mark-as-spam
+ "mail/spam" t
+ :visible (and (fboundp 'spam-group-ham-contents-p)
+ (spam-group-ham-contents-p gnus-newsgroup-name))
+ :help "Mark as spam")
+ (gnus-summary-mark-as-read-forward
+ "mail/not-spam" nil
+ :visible (and (fboundp 'spam-group-spam-contents-p)
+ (spam-group-spam-contents-p gnus-newsgroup-name)))
+ ;;
+ (gnus-summary-exit "exit")
+ (gmm-customize-mode "preferences" t :help "Edit mode preferences")
+ (gnus-info-find-node "help"))
+ "List of functions for the summary tool bar (GNOME style).
+
+See `gmm-tool-bar-from-list' for the format of the list."
+ :type '(repeat gmm-tool-bar-item)
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defcustom gnus-summary-tool-bar-retro
+ '((gnus-summary-prev-unread-article "gnus/prev-ur")
+ (gnus-summary-next-unread-article "gnus/next-ur")
+ (gnus-summary-post-news "gnus/post")
+ (gnus-summary-followup-with-original "gnus/fuwo")
+ (gnus-summary-followup "gnus/followup")
+ (gnus-summary-reply-with-original "gnus/reply-wo")
+ (gnus-summary-reply "gnus/reply")
+ (gnus-summary-caesar-message "gnus/rot13")
+ (gnus-uu-decode-uu "gnus/uu-decode")
+ (gnus-summary-save-article-file "gnus/save-aif")
+ (gnus-summary-save-article "gnus/save-art")
+ (gnus-uu-post-news "gnus/uu-post")
+ (gnus-summary-catchup "gnus/catchup")
+ (gnus-summary-catchup-and-exit "gnus/cu-exit")
+ (gnus-summary-exit "gnus/exit-summ")
+ ;; Some new command that may need more suitable icons:
+ (gnus-summary-print-article "gnus/print" nil :visible nil)
+ (gnus-summary-mark-as-expirable "gnus/close" nil :visible nil)
+ (gnus-summary-save-newsrc "gnus/save" nil :visible nil)
+ ;; (gnus-summary-enter-digest-group "gnus/right_arrow" nil :visible nil)
+ (gnus-summary-search-article-forward "gnus/search" nil :visible nil)
+ ;; (gnus-summary-insert-new-articles "gnus/paste" nil :visible nil)
+ ;; (gnus-summary-toggle-threads "gnus/open" nil :visible nil)
+ ;;
+ (gnus-info-find-node "gnus/help" nil :visible nil))
+ "List of functions for the summary tool bar (retro look).
+
+See `gmm-tool-bar-from-list' for the format of the list."
+ :type '(repeat gmm-tool-bar-item)
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defcustom gnus-summary-tool-bar-zap-list t
+ "List of icon items from the global tool bar.
+These items are not displayed in the Gnus summary mode tool bar.
+
+See `gmm-tool-bar-from-list' for the format of the list."
+ :type 'gmm-tool-bar-zap-list
+ :version "23.0" ;; No Gnus
+ :initialize 'custom-initialize-default
+ :set 'gnus-summary-tool-bar-update
+ :group 'gnus-summary)
+
+(defvar image-load-path)
+
+(defun gnus-summary-make-tool-bar (&optional force)
+ "Make a summary mode tool bar from `gnus-summary-tool-bar'.
+When FORCE, rebuild the tool bar."
+ (when (and (not (featurep 'xemacs))
+ (boundp 'tool-bar-mode)
+ tool-bar-mode
+ (or (not gnus-summary-tool-bar-map) force))
+ (let* ((load-path
+ (gmm-image-load-path-for-library "gnus"
+ "mail/save.xpm"
+ nil t))
+ (image-load-path (cons (car load-path)
+ (when (boundp 'image-load-path)
+ image-load-path)))
+ (map (gmm-tool-bar-from-list gnus-summary-tool-bar
+ gnus-summary-tool-bar-zap-list
+ 'gnus-summary-mode-map)))
+ (when map
+ ;; Need to set `gnus-summary-tool-bar-map' because `gnus-article-mode'
+ ;; uses it's 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."
\\{gnus-summary-mode-map}"
(interactive)
(kill-all-local-variables)
+ (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+ (gnus-summary-make-local-variables))
+ (gnus-summary-make-local-variables)
+ (setq gnus-newsgroup-name group)
(when (gnus-visual-p 'summary-menu 'menu)
(gnus-summary-make-menu-bar)
(gnus-summary-make-tool-bar))
- (gnus-summary-make-local-variables)
- (let ((gnus-summary-local-variables gnus-newsgroup-variables))
- (gnus-summary-make-local-variables))
(gnus-make-thread-indent-array)
(gnus-simplify-mode-line)
(setq major-mode 'gnus-summary-mode)
(setq selective-display-ellipses t) ;Display `...'
(gnus-summary-set-display-table)
(gnus-set-default-directory)
- (setq gnus-newsgroup-name group)
(make-local-variable 'gnus-summary-line-format)
(make-local-variable 'gnus-summary-line-format-spec)
(make-local-variable 'gnus-summary-dummy-line-format)
(aset table ?\r nil)
;; We keep TAB as well.
(aset table ?\t nil)
- ;; We nix out any glyphs over 126 that are not set already.
- (let ((i 256))
+ ;; 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))
+ 160
+ 256)))
(while (>= (setq i (1- i)) 127)
;; Only modify if the entry is nil.
(unless (aref table i)
(inline
(gnus-summary-extract-address-component
(funcall gnus-decode-encoded-word-function to)))))
- ((setq newsgroups (cdr (assq 'Newsgroups extra-headers)))
+ ((setq newsgroups
+ (or
+ (cdr (assq 'Newsgroups extra-headers))
+ (and
+ (eq (car (gnus-find-method-for-group
+ gnus-newsgroup-name)) 'nntp)
+ (gnus-group-real-name gnus-newsgroup-name))))
(concat gnus-summary-newsgroup-prefix newsgroups)))))
(inline (gnus-summary-extract-address-component gnus-tmp-from)))))
(gnus-date-get-time (mail-header-date h1))
(gnus-date-get-time (mail-header-date h2))))
-(defsubst gnus-article-sort-by-date-reverse (h1 h2)
- "Sort articles in reverse order by root article date."
- (gnus-article-sort-by-date h2 h1))
-
(defun gnus-thread-sort-by-date (h1 h2)
"Sort threads by root article date."
(gnus-article-sort-by-date
(let ((max (max (point) (mark)))
articles article)
(save-excursion
- (goto-char (min (min (point) (mark))))
+ (goto-char (min (point) (mark)))
(while
(and
(push (setq article (gnus-summary-article-number)) articles)
(setq nlast (if (atom (cadr read)) (cadr read) (caadr read)))
(setq read (cdr read)))))
;; And add the last unread articles.
- (cond ((< first last)
- (push (cons first last) unread))
- ((= first last)
- (push first unread)))
+ (cond ((not (and first last))
+ nil)
+ ((< first last)
+ (push (cons first last) unread))
+ ((= first last)
+ (push first unread)))
;; Return the sequence of unread articles.
(delq 0 (nreverse unread))))
(when (gnus-summary-goto-subject article)
(gnus-summary-show-thread)
(gnus-summary-goto-subject article)
- (gnus-summary-update-secondary-mark article))))
+ (gnus-summary-update-secondary-mark article)))
+ t)
(defun gnus-summary-set-saved-mark (article)
"Set the process mark on ARTICLE and update the summary line."
(gnus-summary-catchup all))
(gnus-summary-next-group))
+(defun gnus-summary-catchup-and-goto-prev-group (&optional all)
+ "Mark all articles in this group as read and select the previous group.
+If given a prefix, mark all articles, unread as well as ticked, as
+read."
+ (interactive "P")
+ (save-excursion
+ (gnus-summary-catchup all))
+ (gnus-summary-next-group nil nil t))
+
;;;
;;; with article
;;;
(defun gnus-map-articles (predicate articles)
"Map PREDICATE over ARTICLES and return non-nil if any predicate is non-nil."
(apply 'gnus-or (mapcar predicate
- (mapcar 'gnus-summary-article-header articles))))
+ (mapcar (lambda (number)
+ (gnus-summary-article-header number))
+ articles))))
(defun gnus-summary-hide-all-threads (&optional predicate)
"Hide all thread subtrees.