(require 'gnus-util)
(require 'mm-decode)
(autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
+(autoload 'gnus-cache-write-active "gnus-cache")
(defcustom gnus-kill-summary-on-exit t
"*If non-nil, kill the summary buffer when you exit from it.
:type '(choice (const nil)
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."
+ :group 'gnus-summary
+ :type 'regexp)
+
+
;;; Internal variables
(defvar gnus-article-mime-handles nil)
(defvar gnus-article-decoded-p nil)
+(defvar gnus-article-charset nil)
+(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-sort-gathered-threads-function 'gnus-thread-sort-by-number
"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)
+
;; Avoid highlighting in kill files.
(defvar gnus-summary-inhibit-highlight nil)
(defvar gnus-newsgroup-selected-overlay nil)
"6" gnus-article-de-base64-unreadable
"Z" gnus-article-decode-HZ
"h" gnus-article-wash-html
+ "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-article-hide-headers
+ "t" gnus-summary-toggle-header
"v" gnus-summary-verbose-headers
"H" gnus-article-strip-headers-in-body
"d" gnus-article-treat-dumbquotes)
["Charset" gnus-article-decode-charset t]
["QP" gnus-article-de-quoted-unreadable t]
["Base64" gnus-article-de-base64-unreadable t]
- ["View all" gnus-mime-view-all-parts t])
+ ["View all" gnus-mime-view-all-parts t]
+ ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt])
("Date"
["Local" gnus-article-date-local t]
["ISO8601" gnus-article-date-iso8601 t]
(make-local-hook 'pre-command-hook)
(add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
(gnus-run-hooks 'gnus-summary-mode-hook)
- (mm-enable-multibyte)
+ (mm-enable-multibyte-mule4)
(gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
(gnus-update-summary-mark-positions))
(defun gnus-restore-hidden-threads-configuration (config)
"Restore hidden threads configuration from CONFIG."
- (let (point buffer-read-only)
- (while (setq point (pop config))
- (when (and (< point (point-max))
- (goto-char point)
- (eq (char-after) ?\n))
- (subst-char-in-region point (1+ point) ?\n ?\r)))))
+ (save-excursion
+ (let (point buffer-read-only)
+ (while (setq point (pop config))
+ (when (and (< point (point-max))
+ (goto-char point)
+ (eq (char-after) ?\n))
+ (subst-char-in-region point (1+ point) ?\n ?\r))))))
;; Various summary mode internalish functions.
(cond
((string-match "<[^>]+> *$" gnus-tmp-from)
(let ((beg (match-beginning 0)))
- (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from)
- (substring gnus-tmp-from (1+ (match-beginning 0))
- (1- (match-end 0))))
+ (or (and (string-match "^\".+\"" gnus-tmp-from)
+ (substring gnus-tmp-from 1 (1- (match-end 0))))
(substring gnus-tmp-from 0 beg))))
((string-match "(.+)" gnus-tmp-from)
(substring gnus-tmp-from
result))
(defun gnus-sort-gathered-threads (threads)
- "Sort subtreads inside each gathered thread by article number."
+ "Sort subtreads inside each gathered thread by `gnus-sort-gathered-threads-function'."
(let ((result threads))
(while threads
(when (stringp (caar threads))
(nnheader-nov-read-integer) ; chars
(nnheader-nov-read-integer) ; lines
(unless (eobp)
- (nnheader-nov-field)) ; misc
+ (if (looking-at "Xref: ")
+ (goto-char (match-end 0)))
+ (nnheader-nov-field)) ; Xref
(nnheader-nov-parse-extra)))) ; extra
(widen))
(1+ (gnus-point-at-eol))
(gnus-delete-line)))))))
+(defun gnus-sort-threads-1 (threads func)
+ (sort (mapcar (lambda (thread)
+ (cons (car thread)
+ (and (cdr thread)
+ (gnus-sort-threads-1 (cdr thread) func))))
+ threads) func))
+
(defun gnus-sort-threads (threads)
"Sort THREADS."
(if (not gnus-thread-sort-functions)
threads
(gnus-message 8 "Sorting threads...")
(prog1
- (sort threads (gnus-make-sort-function gnus-thread-sort-functions))
+ (gnus-sort-threads-1
+ threads
+ (gnus-make-sort-function gnus-thread-sort-functions))
(gnus-message 8 "Sorting threads...done"))))
(defun gnus-sort-articles (articles)
(cond
((string-match "<[^>]+> *$" gnus-tmp-from)
(setq beg-match (match-beginning 0))
- (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from)
- (substring gnus-tmp-from (1+ (match-beginning 0))
- (1- (match-end 0))))
+ (or (and (string-match "^\".+\"" gnus-tmp-from)
+ (substring gnus-tmp-from 1 (1- (match-end 0))))
(substring gnus-tmp-from 0 beg-match)))
((string-match "(.+)" gnus-tmp-from)
(substring gnus-tmp-from
(if (string-match "^[ \t]*$" input)
number input)))
(t number))
- (quit nil))))))
+ (quit
+ (message "Quit getting the articles to read")
+ nil))))))
(setq select (if (stringp select) (string-to-number select) select))
(if (or (null select) (zerop select))
select
;; From.
(progn
(goto-char p)
- (if (search-forward "\nfrom: " nil t)
+ (if (or (search-forward "\nfrom: " nil t)
+ (search-forward "\nfrom:" nil t))
(funcall gnus-decode-encoded-word-function
(nnheader-header-value))
"(nobody)"))
(when (gnus-buffer-live-p gnus-article-buffer)
(save-excursion
(set-buffer gnus-article-buffer)
- (mm-destroy-parts gnus-article-mime-handles)))
+ (mm-destroy-parts gnus-article-mime-handles)
+ ;; Set it to nil for safety reason.
+ (setq gnus-article-mime-handle-alist nil)
+ (setq gnus-article-mime-handles nil)))
(gnus-kill-save-kill-buffer)
(gnus-async-halt-prefetch)
(let* ((group gnus-newsgroup-name)
(when (gnus-buffer-live-p gnus-article-buffer)
(save-excursion
(set-buffer gnus-article-buffer)
- (mm-destroy-parts gnus-article-mime-handles)))
+ (mm-destroy-parts gnus-article-mime-handles)
+ ;; Set it to nil for safety reason.
+ (setq gnus-article-mime-handle-alist nil)
+ (setq gnus-article-mime-handles nil)))
;; If we have several article buffers, we kill them at exit.
(unless gnus-single-article-buffer
(gnus-kill-buffer gnus-article-buffer)
(defun gnus-summary-display-article (article &optional all-header)
"Display ARTICLE in article buffer."
(gnus-set-global-variables)
+ (when (gnus-buffer-live-p gnus-article-buffer)
+ (with-current-buffer gnus-article-buffer
+ (setq gnus-article-charset gnus-newsgroup-charset)
+ (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)
+ (mm-enable-multibyte-mule4)))
(if (null article)
nil
(prog1
force)
;; The requested article is different from the current article.
(progn
- (when (gnus-buffer-live-p gnus-article-buffer)
- (with-current-buffer gnus-article-buffer
- (mm-enable-multibyte)))
(gnus-summary-display-article article all-headers)
(when (gnus-buffer-live-p gnus-article-buffer)
- (with-current-buffer gnus-article-buffer
+ (with-current-buffer gnus-article-buffer
(if (not gnus-article-decoded-p) ;; a local variable
- (mm-disable-multibyte))))
+ (mm-disable-multibyte-mule4))))
(when (or all-headers gnus-show-all-headers)
(gnus-article-show-all-headers))
(gnus-article-set-window-start
(gnus-article-show-all-headers))
'old))))
+(defun gnus-summary-force-verify-and-decrypt ()
+ (interactive)
+ (let ((mm-verify-option 'known)
+ (mm-decrypt-option 'known))
+ (gnus-summary-select-article nil 'force)))
+
(defun gnus-summary-set-current-mark (&optional current-mark)
"Obsolete function."
nil)
((eq 'current gnus-refer-article-method)
(list gnus-current-select-method))
;; List of select methods.
- ((not (stringp (cadr gnus-refer-article-method)))
+ ((not (and (symbolp (car gnus-refer-article-method))
+ (assq (car gnus-refer-article-method) nnoo-definition-alist)))
(let (out)
(dolist (method gnus-refer-article-method)
(push (if (eq 'current method)
;; the parent article.
(when (setq to-address (or (message-fetch-field "reply-to")
(message-fetch-field "from")))
- (setq params (append (list (cons 'to-address to-address)))))
+ (setq params (append
+ (list (cons 'to-address
+ (funcall gnus-decode-encoded-word-function
+ 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
(or (cdr (assq arg gnus-summary-show-article-charset-alist))
(read-coding-system "Charset: ")))
(gnus-newsgroup-ignored-charsets 'gnus-all))
- (gnus-summary-select-article nil 'force)))
+ (gnus-summary-select-article nil 'force)
+ (let ((deps gnus-newsgroup-dependencies)
+ head header)
+ (save-excursion
+ (set-buffer gnus-original-article-buffer)
+ (save-restriction
+ (message-narrow-to-head)
+ (setq head (buffer-string)))
+ (with-temp-buffer
+ (insert (format "211 %d Article retrieved.\n"
+ (cdr gnus-article-current)))
+ (insert head)
+ (insert ".\n")
+ (let ((nntp-server-buffer (current-buffer)))
+ (setq header (car (gnus-get-newsgroup-headers deps t))))))
+ (gnus-data-set-header
+ (gnus-data-find (cdr gnus-article-current))
+ header)
+ (gnus-summary-update-article-line
+ (cdr gnus-article-current) header))))
((not arg)
;; Select the article the normal way.
(gnus-summary-select-article nil 'force))
(when (gnus-buffer-live-p gnus-article-buffer)
(save-excursion
(set-buffer gnus-article-buffer)
- (mm-destroy-parts gnus-article-mime-handles)))
+ (mm-destroy-parts gnus-article-mime-handles)
+ ;; Set it to nil for safety reason.
+ (setq gnus-article-mime-handle-alist nil)
+ (setq gnus-article-mime-handles nil)))
(gnus-summary-select-article nil 'force))))
(gnus-summary-goto-subject gnus-current-article)
(gnus-summary-position-point))
(expiry-wait (if now 'immediate
(gnus-group-find-parameter
gnus-newsgroup-name 'expiry-wait)))
+ (nnmail-expiry-target
+ (or (gnus-group-find-parameter gnus-newsgroup-name 'expiry-target)
+ nnmail-expiry-target))
es)
(when expirable
;; There are expirable articles in this group, so we run them
(setq es (gnus-request-expire-articles
expirable gnus-newsgroup-name)))
(setq es (gnus-request-expire-articles
- expirable gnus-newsgroup-name))))
- (unless total
- (setq gnus-newsgroup-expirable es))
- ;; We go through the old list of expirable, and mark all
- ;; really expired articles as nonexistent.
- (unless (eq es expirable) ;If nothing was expired, we don't mark.
- (let ((gnus-use-cache nil))
- (while expirable
- (unless (memq (car expirable) es)
- (when (gnus-data-find (car expirable))
- (gnus-summary-mark-article
- (car expirable) gnus-canceled-mark)))
- (setq expirable (cdr expirable)))))
+ expirable gnus-newsgroup-name)))
+ (unless total
+ (setq gnus-newsgroup-expirable es))
+ ;; We go through the old list of expirable, and mark all
+ ;; really expired articles as nonexistent.
+ (unless (eq es expirable) ;If nothing was expired, we don't mark.
+ (let ((gnus-use-cache nil))
+ (while expirable
+ (unless (memq (car expirable) es)
+ (when (gnus-data-find (car expirable))
+ (gnus-summary-mark-article
+ (car expirable) gnus-canceled-mark)))
+ (setq expirable (cdr expirable))))))
(gnus-message 6 "Expiring articles...done")))))
(defun gnus-summary-expire-articles-now ()
(unless (gnus-check-backend-function 'request-expire-articles
gnus-newsgroup-name)
(error "The current newsgroup does not support article deletion"))
+ (unless (gnus-check-server (gnus-find-method-for-group gnus-newsgroup-name))
+ (error "Couldn't open server"))
;; Compute the list of articles to delete.
(let ((articles (sort (copy-sequence (gnus-summary-work-articles n)) '<))
not-deleted)
(gnus-summary-show-article t)
(when (and (not raw) (gnus-buffer-live-p gnus-article-buffer))
(with-current-buffer gnus-article-buffer
- (mm-enable-multibyte)))
+ (mm-enable-multibyte-mule4)))
(if (equal gnus-newsgroup-name "nndraft:drafts")
(setq raw t))
(gnus-article-edit-article
(add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))))
`(lambda (no-highlight)
(let ((mail-parse-charset ',gnus-newsgroup-charset)
+ (message-options message-options)
+ (message-options-set-recipient)
(mail-parse-ignored-charsets
',gnus-newsgroup-ignored-charsets))
,(if (not raw) '(progn
(unless (and message-id (not (equal message-id "")))
(error "No message-id in desired parent"))
(gnus-with-article current-article
- (goto-char (point-min))
- (if (re-search-forward "^References: " nil t)
- (progn
- (re-search-forward "^[^ \t]" nil t)
- (forward-line -1)
- (end-of-line)
- (insert " " message-id))
- (insert "References: " message-id "\n")))
+ (save-restriction
+ (goto-char (point-min))
+ (message-narrow-to-head)
+ (if (re-search-forward "^References: " nil t)
+ (progn
+ (re-search-forward "^[^ \t]" nil t)
+ (forward-line -1)
+ (end-of-line)
+ (insert " " message-id))
+ (insert "References: " message-id "\n"))))
(set-buffer gnus-summary-buffer)
(gnus-summary-unmark-all-processable)
(gnus-summary-update-article current-article)
thread
`(lambda (t1 t2)
(,thread t2 t1))))
+ (gnus-sort-gathered-threads-function
+ gnus-thread-sort-functions)
(gnus-article-sort-functions
(if (not reverse)
article
(set-buffer gnus-original-article-buffer)
(save-restriction
(nnheader-narrow-to-headers)
- (while methods
+ (while (and methods (not split-name))
(goto-char (point-min))
(setq method (pop methods))
(setq match (car method))
(save-restriction
(widen)
(setq result (eval match)))))
- (setq split-name (append (cdr method) split-name))
+ (setq split-name (cdr method))
(cond ((stringp result)
(push (expand-file-name
result gnus-article-save-directory)
"Save parts matching TYPE to DIR.
If REVERSE, save parts that do not match TYPE."
(interactive
- (list (read-string "Save parts of type: " "image/.*")
- (read-file-name "Save to directory: " nil nil t)
+ (list (read-string "Save parts of type: "
+ (or (car gnus-summary-save-parts-type-history)
+ gnus-summary-save-parts-default-mime)
+ 'gnus-summary-save-parts-type-history)
+ (setq gnus-summary-save-parts-last-directory
+ (read-file-name "Save to directory: "
+ gnus-summary-save-parts-last-directory
+ nil t))
current-prefix-arg))
(gnus-summary-iterate n
(let ((gnus-display-mime-function nil)
(gnus-summary-select-article))
(save-excursion
(set-buffer gnus-article-buffer)
- (let ((handles (or (mm-dissect-buffer) (mm-uu-dissect))))
+ (let ((handles (or gnus-article-mime-handles
+ (mm-dissect-buffer) (mm-uu-dissect))))
(when handles
(gnus-summary-save-parts-1 type dir handles reverse)
- (mm-destroy-parts handles))))))
+ (unless gnus-article-mime-handles ;; Don't destroy this case.
+ (mm-destroy-parts handles)))))))
(defun gnus-summary-save-parts-1 (type dir handle reverse)
(if (stringp (car handle))
(if compute
read
(save-excursion
- (set-buffer gnus-group-buffer)
- (gnus-undo-register
- `(progn
- (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-group-update-group ,group t))))
- ;; Propagate the read marks to the backend.
- (if (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))))
- (when (or add del)
- (unless (gnus-check-group group)
- (error "Can't open server for %s" group))
- (gnus-request-set-mark
- group (delq nil (list (if add (list add 'add '(read)))
- (if del (list del 'del '(read)))))))))
+ (let (setmarkundo)
+ ;; Propagate the read marks to the backend.
+ (when (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))))
+ (when (or add del)
+ (unless (gnus-check-group group)
+ (error "Can't open server for %s" group))
+ (gnus-request-set-mark
+ group (delq nil (list (if add (list add 'add '(read)))
+ (if del (list del 'del '(read))))))
+ (setq setmarkundo
+ `(gnus-request-set-mark
+ ,group
+ ',(delq nil (list
+ (if del (list del 'add '(read)))
+ (if add (list add 'del '(read))))))))))
+ (set-buffer gnus-group-buffer)
+ (gnus-undo-register
+ `(progn
+ (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-group-update-group ,group t)
+ ,setmarkundo))))
;; Enter this list into the group info.
(gnus-info-set-read info read)
;; Set the number of unread articles in gnus-newsrc-hashtb.