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
Ready-made functions include `gnus-article-sort-by-number',
`gnus-article-sort-by-author', `gnus-article-sort-by-subject',
-`gnus-article-sort-by-date' and `gnus-article-sort-by-score'.
+`gnus-article-sort-by-date', `gnus-article-sort-by-random'
+and `gnus-article-sort-by-score'.
When threading is turned on, the variable `gnus-thread-sort-functions'
controls how articles are sorted."
(function-item gnus-article-sort-by-subject)
(function-item gnus-article-sort-by-date)
(function-item gnus-article-sort-by-score)
+ (function-item gnus-article-sort-by-random)
(function :tag "other"))))
(defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
`gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
`gnus-thread-sort-by-date', `gnus-thread-sort-by-score',
`gnus-thread-sort-by-most-recent-number',
-`gnus-thread-sort-by-most-recent-date', and
+`gnus-thread-sort-by-most-recent-date',
+`gnus-thread-sort-by-random', and
`gnus-thread-sort-by-total-score' (see `gnus-thread-score-function').
When threading is turned off, the variable
(function-item gnus-thread-sort-by-date)
(function-item gnus-thread-sort-by-score)
(function-item gnus-thread-sort-by-total-score)
+ (function-item gnus-thread-sort-by-random)
(function :tag "other"))))
(defcustom gnus-thread-score-function '+
. gnus-summary-low-ancient-face)
((eq mark gnus-ancient-mark)
. gnus-summary-normal-ancient-face)
+ (downloaded
+ . gnus-agent-downloaded-article-face)
((and (> score default-high) (eq mark gnus-unread-mark))
. gnus-summary-high-unread-face)
((and (< score default-low) (eq mark gnus-unread-mark))
(?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)
(?I gnus-tmp-indentation ?s)
(?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s)
"\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
"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
"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
"f" gnus-summary-fetch-faq
"d" gnus-summary-describe-group
"h" gnus-summary-describe-briefly
- "i" gnus-info-find-node)
+ "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
["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]
(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]
["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]
["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]
["Pop limit" gnus-summary-pop-limit 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]
+ ["Randomize" gnus-summary-sort-by-random t]
["Original sort" gnus-summary-sort-by-original 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]
marks of articles."
`(cond
((memq ,number gnus-newsgroup-unsendable) gnus-unsendable-mark)
- ((memq ,number gnus-newsgroup-undownloaded) gnus-undownloaded-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)
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', which see."
+ (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))
;; 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
+ (funcall gnus-decode-encoded-word-function
+ (setq x (nnheader-nov-field)))
+ (error x))
+ (condition-case () ; from
+ (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
(gnus-article-sort-by-number
(gnus-thread-header h1) (gnus-thread-header h2)))
+(defsubst gnus-article-sort-by-random (h1 h2)
+ "Sort articles by article number."
+ (zerop (random 2)))
+
+(defun gnus-thread-sort-by-random (h1 h2)
+ "Sort threads by root article number."
+ (gnus-article-sort-by-random
+ (gnus-thread-header h1) (gnus-thread-header h2)))
+
(defsubst gnus-article-sort-by-lines (h1 h2)
"Sort articles by article Lines header."
(< (mail-header-lines h1)
;; 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.
(let ((current-group gnus-newsgroup-name)
(current-buffer (current-buffer))
entered)
- ;; 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...
- (gnus-summary-exit t)
(while (not entered)
;; Then we find what group we are supposed to enter.
(set-buffer gnus-group-buffer)
(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))
+ (progn
+ ;; Now 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...
+ (when (gnus-buffer-live-p current-buffer)
+ (set-buffer current-buffer)
+ (gnus-summary-exit t))
+ (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)))))))
(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
;; 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."
(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)
+ (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)
- (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))))
+ (setq gnus-page-broken
+ (when gnus-break-pages
+ (gnus-narrow-to-page)
+ t))
+ (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)
(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
(interactive "P")
(gnus-summary-sort '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 'random reverse))
+
(defun gnus-summary-sort-by-author (&optional reverse)
"Sort the summary buffer by author name alphabetically.
If `case-fold-search' is non-nil, case of letters is ignored.
(setq gnus-newsgroup-selected-overlay (gnus-make-overlay from to))
'face gnus-summary-selected-face))))))
+(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))))))
+
+(defvar gnus-summary-highlight-line-downloaded-alist nil)
+(defvar gnus-summary-highlight-line-downloaded-cached nil)
+
;; New implementation by Christian Limpach <Christian.Limpach@nice.ch>.
(defun gnus-summary-highlight-line ()
"Highlight current line according to `gnus-summary-highlight'."
(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)
+ (downloaded (and (boundp 'gnus-agent-article-alist)
+ gnus-agent-article-alist
+ ;; Optimized for when gnus-summary-highlight-line is called multiple times for articles in ascending order (i.e. initial generation of summary buffer).
+ (progn
+ (if (and (eq gnus-summary-highlight-line-downloaded-alist gnus-agent-article-alist)
+ (<= (caar gnus-summary-highlight-line-downloaded-cached) article))
+ nil
+ (setq gnus-summary-highlight-line-downloaded-alist gnus-agent-article-alist
+ gnus-summary-highlight-line-downloaded-cached gnus-agent-article-alist))
+ (let (n)
+ (while (and (< (caar gnus-summary-highlight-line-downloaded-cached) article)
+ (setq n (cdr gnus-summary-highlight-line-downloaded-cached)))
+ (setq gnus-summary-highlight-line-downloaded-cached n)))
+ (and (eq (caar gnus-summary-highlight-line-downloaded-cached) article)
+ (cdar gnus-summary-highlight-line-downloaded-cached))))))
+ (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
(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.
+;;; (gnus-sorted-difference
+;;; (gnus-uncompress-range (list gnus-newsgroup-active))
+;;; old)
+ (gnus-uncompress-range
+ (gnus-remove-from-range (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))))
+ (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 nil)
(t
(if (and (numberp gnus-large-newsgroup)
(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)