X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fgnus-art.el;h=e98f8fc1880a418bbf3a3f4c10c3661e8eb8a64f;hb=6342cefebdccb4123591ce00bdf51a1ed1d65204;hp=e33d71086ca7674446dd4283c2849edfa9505d93;hpb=cb7d257f3a8641f8548906876c806a4a10cbb411;p=gnus diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index e33d71086..e98f8fc18 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -1,5 +1,5 @@ ;;; gnus-art.el --- article mode commands for Gnus -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -50,7 +50,7 @@ (defgroup gnus-article nil "Article display." - :link '(custom-manual "(gnus)The Article Buffer") + :link '(custom-manual "(gnus)Article Buffer") :group 'gnus) (defgroup gnus-article-treat nil @@ -232,7 +232,9 @@ that number. If it is a floating point number, no signature may be longer (in lines) than that number. If it is a function, the function will be called without any parameters, and if it returns nil, there is no signature in the buffer. If it is a string, it will be used as a -regexp. If it matches, the text in question is not a signature." +regexp. If it matches, the text in question is not a signature. + +This can also be a list of the above values." :type '(choice (integer :value 200) (number :value 4.0) (function :value fun) @@ -337,8 +339,6 @@ advertisements. For example: (format format (car spec) (cadr spec)) 2 3 (intern (format "gnus-emphasis-%s" (nth 2 spec))))) types) - ("\\(\\s-\\|^\\)\\(-\\(\\(\\w\\|-[^-]\\)+\\)-\\)\\(\\s-\\|[?!.,;]\\)" - 2 3 gnus-emphasis-strikethru) ("\\(\\s-\\|^\\)\\(_\\(\\(\\w\\|_[^_]\\)+\\)_\\)\\(\\s-\\|[?!.,;]\\)" 2 3 gnus-emphasis-underline))) "*Alist that says how to fontify certain phrases. @@ -408,14 +408,14 @@ Example: (_/*word*/_)." "Face used for displaying highlighted words." :group 'gnus-article-emphasis) -(defcustom gnus-article-time-format "%a, %b %d %Y %T %Z" +(defcustom gnus-article-time-format "%a, %d %b %Y %T %Z" "Format for display of Date headers in article bodies. See `format-time-string' for the possible values. The variable can also be function, which should return a complete Date header. The function is called with one argument, the time, which can be fed to `format-time-string'." - :type '(choice string symbol) + :type '(choice string function) :link '(custom-manual "(gnus)Article Date") :group 'gnus-article-washing) @@ -755,6 +755,7 @@ When nil (the default value), then some MIME parts do not get buttons, as described by the variables `gnus-buttonized-mime-types' and `gnus-unbuttonized-mime-types'." :version "21.3" + :group 'gnus-article-mime :type 'boolean) (defcustom gnus-body-boundary-delimiter "_" @@ -765,7 +766,8 @@ be controlled by `gnus-treat-body-boundary'." :type '(choice (item :tag "None" :value nil) string)) -(defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces") +(defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces" + "/usr/share/picons") "Defines the location of the faces database. For information on obtaining this database of pretty pictures, please see http://www.cs.indiana.edu/picons/ftp/index.html" @@ -794,7 +796,7 @@ on parts -- for instance, adding Vcard info to a database." "An alist of MIME types to functions to display them." :version "21.1" :group 'gnus-article-mime - :type 'alist) + :type '(repeat (cons :format "%v" (string :tag "MIME type") function))) (defcustom gnus-article-date-lapsed-new-header nil "Whether the X-Sent and Date headers can coexist. @@ -894,8 +896,7 @@ See Info node `(gnus)Customizing Articles' for details." (defcustom gnus-treat-emphasize (and (or window-system - (featurep 'xemacs) - (>= (string-to-number emacs-version) 21)) + (featurep 'xemacs)) 50000) "Emphasize text. Valid values are nil, t, `head', `last', an integer or a predicate. @@ -1148,7 +1149,7 @@ See Info node `(gnus)Customizing Articles' for details." :type gnus-article-treat-custom) (put 'gnus-treat-overstrike 'highlight t) -(defcustom gnus-treat-ansi-sequences t +(defcustom gnus-treat-ansi-sequences (if (locate-library "ansi-color") t) "Treat ANSI SGR control sequences. Valid values are nil, t, `head', `last', an integer or a predicate. See Info node `(gnus)Customizing Articles' for details." @@ -1375,6 +1376,13 @@ This requires GNU Libidn, and by default only enabled if it is found." '("January" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December")) +(defvar gnus-button-regexp nil) +(defvar gnus-button-marker-list nil) +;; Regexp matching any of the regexps from `gnus-button-alist'. + +(defvar gnus-button-last nil) +;; The value of `gnus-button-alist' when `gnus-button-regexp' was build. + (defvar article-goto-body-goes-to-point-min-p nil) (defvar gnus-article-wash-types nil) (defvar gnus-article-emphasis-alist nil) @@ -1461,13 +1469,15 @@ Initialized from `text-mode-syntax-table.") (defvar gnus-inhibit-hiding nil) +(defvar gnus-article-edit-mode nil) + ;;; Macros for dealing with the article buffer. (defmacro gnus-with-article-headers (&rest forms) `(save-excursion (set-buffer gnus-article-buffer) (save-restriction - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (inhibit-point-motion-hooks t) (case-fold-search t)) (article-narrow-to-head) @@ -1479,7 +1489,7 @@ Initialized from `text-mode-syntax-table.") (defmacro gnus-with-article-buffer (&rest forms) `(save-excursion (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) ,@forms))) (put 'gnus-with-article-buffer 'lisp-indent-function 0) @@ -1565,25 +1575,35 @@ Initialized from `text-mode-syntax-table.") (interactive) ;; This function might be inhibited. (unless gnus-inhibit-hiding - (save-excursion - (save-restriction - (let ((buffer-read-only nil) - (case-fold-search t) - (max (1+ (length gnus-sorted-header-list))) - (ignored (when (not gnus-visible-headers) - (cond ((stringp gnus-ignored-headers) - gnus-ignored-headers) - ((listp gnus-ignored-headers) - (mapconcat 'identity gnus-ignored-headers - "\\|"))))) - (visible - (cond ((stringp gnus-visible-headers) - gnus-visible-headers) - ((and gnus-visible-headers - (listp gnus-visible-headers)) - (mapconcat 'identity gnus-visible-headers "\\|")))) - (inhibit-point-motion-hooks t) - beg) + (let ((inhibit-read-only nil) + (case-fold-search t) + (max (1+ (length gnus-sorted-header-list))) + (inhibit-point-motion-hooks t) + (cur (current-buffer)) + ignored visible beg) + (save-excursion + ;; `gnus-ignored-headers' and `gnus-visible-headers' may be + ;; group parameters, so we should go to the summary buffer. + (when (prog1 + (condition-case nil + (progn (set-buffer gnus-summary-buffer) t) + (error nil)) + (setq ignored (when (not gnus-visible-headers) + (cond ((stringp gnus-ignored-headers) + gnus-ignored-headers) + ((listp gnus-ignored-headers) + (mapconcat 'identity + gnus-ignored-headers + "\\|")))) + visible (cond ((stringp gnus-visible-headers) + gnus-visible-headers) + ((and gnus-visible-headers + (listp gnus-visible-headers)) + (mapconcat 'identity + gnus-visible-headers + "\\|"))))) + (set-buffer cur)) + (save-restriction ;; First we narrow to just the headers. (article-narrow-to-head) ;; Hide any "From " lines at the beginning of (mail) articles. @@ -1625,7 +1645,7 @@ always hide." (not gnus-show-all-headers)) (save-excursion (save-restriction - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (list gnus-boring-article-headers) (inhibit-point-motion-hooks t) elem) @@ -1779,7 +1799,7 @@ always hide." (defun article-normalize-headers () "Make all header lines 40 characters long." (interactive) - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) column) (save-excursion (save-restriction @@ -1823,7 +1843,7 @@ FROM is a string of characters to translate from; to is a string of characters to translate to." (save-excursion (when (article-goto-body) - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (x (make-string 225 ?x)) (i -1)) (while (< (incf i) (length x)) @@ -1839,7 +1859,7 @@ characters to translate to." MAP is an alist where the elements are on the form (\"from\" \"to\")." (save-excursion (when (article-goto-body) - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) elem) (while (setq elem (pop map)) (save-excursion @@ -1851,7 +1871,7 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." (interactive) (save-excursion (when (article-goto-body) - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (while (search-forward "\b" nil t) (let ((next (char-after)) (previous (char-after (- (point) 2)))) @@ -1877,7 +1897,7 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." (interactive) (save-excursion (when (article-goto-body) - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (ansi-color-apply-on-region (point) (point-max)))))) (defun gnus-article-treat-unfold-headers () @@ -1967,7 +1987,7 @@ unfolded." "Fill lines that are wider than the window width." (interactive) (save-excursion - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (width (window-width (get-buffer-window (current-buffer))))) (save-restriction (article-goto-body) @@ -1987,7 +2007,7 @@ unfolded." "Capitalize the first word in each sentence." (interactive) (save-excursion - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (paragraph-start "^[\n\^L]")) (article-goto-body) (while (not (eobp)) @@ -1998,7 +2018,7 @@ unfolded." "Remove trailing CRs and then translate remaining CRs into LFs." (interactive) (save-excursion - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (goto-char (point-min)) (while (re-search-forward "\r+$" nil t) (replace-match "" t t)) @@ -2010,7 +2030,7 @@ unfolded." "Remove all trailing blank lines from the article." (interactive) (save-excursion - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (goto-char (point-max)) (delete-region (point) @@ -2023,6 +2043,9 @@ unfolded." (forward-line 1) (point)))))) +(eval-when-compile + (defvar gnus-face-properties-alist)) + (defun article-display-face () "Display any Face headers in the header." (interactive) @@ -2046,12 +2069,14 @@ unfolded." (save-restriction (mail-narrow-to-head) (while (gnus-article-goto-header "Face") - (push (mail-header-field-value) faces)))) + (setq faces (nconc faces (list (mail-header-field-value))))))) (while (setq face (pop faces)) (let ((png (gnus-convert-face-to-png face)) image) (when png - (setq image (gnus-create-image png 'png t)) + (setq image + (apply 'gnus-create-image png 'png t + (cdr (assq 'png gnus-face-properties-alist)))) (gnus-article-goto-header "from") (when (bobp) (insert "From: [no `from' set]\n") @@ -2128,14 +2153,12 @@ unfolded." (defun article-decode-mime-words () "Decode all MIME-encoded words in the article." (interactive) - (save-excursion - (set-buffer gnus-article-buffer) + (gnus-with-article-buffer (let ((inhibit-point-motion-hooks t) - buffer-read-only (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets - (save-excursion (set-buffer gnus-summary-buffer) - gnus-newsgroup-ignored-charsets))) + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-ignored-charsets))) (mail-decode-encoded-word-region (point-min) (point-max))))) (defun article-decode-charset (&optional prompt) @@ -2143,7 +2166,7 @@ unfolded." If PROMPT (the prefix), prompt for a coding system to use." (interactive "P") (let ((inhibit-point-motion-hooks t) (case-fold-search t) - buffer-read-only + (inhibit-read-only t) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets (save-excursion (condition-case nil @@ -2193,7 +2216,7 @@ If PROMPT (the prefix), prompt for a coding system to use." (set-buffer gnus-summary-buffer) (error)) gnus-newsgroup-ignored-charsets)) - buffer-read-only) + (inhibit-read-only t)) (save-restriction (article-narrow-to-head) (funcall gnus-decode-header-function (point-min) (point-max))))) @@ -2201,7 +2224,7 @@ If PROMPT (the prefix), prompt for a coding system to use." (defun article-decode-group-name () "Decode group names in `Newsgroups:'." (let ((inhibit-point-motion-hooks t) - buffer-read-only + (inhibit-read-only t) (method (gnus-find-method-for-group gnus-newsgroup-name))) (when (and (or gnus-group-name-charset-method-alist gnus-group-name-charset-group-alist) @@ -2245,18 +2268,16 @@ If PROMPT (the prefix), prompt for a coding system to use." (when gnus-use-idna (save-restriction (let ((inhibit-point-motion-hooks t) - buffer-read-only) + (inhibit-read-only t)) (article-narrow-to-head) (goto-char (point-min)) - (while (re-search-forward "\\(xn--[-A-Za-z0-9.]*\\)[ \t\n\r,>]" nil t) + (while (re-search-forward "@.*\\(xn--[-A-Za-z0-9.]*\\)[ \t\n\r,>]" nil t) (let (ace unicode) (when (save-match-data (and (setq ace (match-string 1)) (save-excursion (and (re-search-backward "^[^ \t]" nil t) (looking-at "From\\|To\\|Cc"))) - (save-excursion (backward-char) - (message-idna-inside-rhs-p)) (setq unicode (idna-to-unicode ace)))) (unless (string= ace unicode) (replace-match unicode nil nil nil 1))))))))) @@ -2268,7 +2289,7 @@ or not. If READ-CHARSET, ask for a coding system." (interactive (list 'force current-prefix-arg)) (save-excursion - (let ((buffer-read-only nil) type charset) + (let ((inhibit-read-only t) type charset) (if (gnus-buffer-live-p gnus-original-article-buffer) (with-current-buffer gnus-original-article-buffer (setq type @@ -2298,7 +2319,7 @@ If FORCE, decode the article whether it is marked as base64 not. If READ-CHARSET, ask for a coding system." (interactive (list 'force current-prefix-arg)) (save-excursion - (let ((buffer-read-only nil) type charset) + (let ((inhibit-read-only t) type charset) (if (gnus-buffer-live-p gnus-original-article-buffer) (with-current-buffer gnus-original-article-buffer (setq type @@ -2333,14 +2354,14 @@ If READ-CHARSET, ask for a coding system." (interactive) (require 'rfc1843) (save-excursion - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (rfc1843-decode-region (point-min) (point-max))))) (defun article-unsplit-urls () "Remove the newlines that some other mailers insert into URLs." (interactive) (save-excursion - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (goto-char (point-min)) (while (re-search-forward "^\\(\\(https?\\|ftp\\)://\\S-+\\) *\n\\(\\S-+\\)" nil t) @@ -2354,7 +2375,7 @@ If READ-CHARSET, ask for a coding system." If READ-CHARSET, ask for a coding system." (interactive "P") (save-excursion - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) charset) (when (gnus-buffer-live-p gnus-original-article-buffer) (with-current-buffer gnus-original-article-buffer @@ -2400,16 +2421,17 @@ If READ-CHARSET, ask for a coding system." (mm-setup-w3m) (save-restriction (narrow-to-region (point) (point-max)) - (let ((w3m-safe-url-regexp (if mm-inline-text-html-with-images - nil - "\\`cid:")) + (let ((w3m-safe-url-regexp mm-w3m-safe-url-regexp) w3m-force-redisplay) (w3m-region (point-min) (point-max))) - (when mm-inline-text-html-with-w3m-keymap + (when (and mm-inline-text-html-with-w3m-keymap + (boundp 'w3m-minor-mode-map) + w3m-minor-mode-map) (add-text-properties (point-min) (point-max) - (nconc (mm-w3m-local-map-property) - '(mm-inline-text-html-with-w3m t)))))) + (list 'keymap w3m-minor-mode-map + ;; Put the mark meaning this part was rendered by emacs-w3m. + 'mm-inline-text-html-with-w3m t))))) (defun article-hide-list-identifiers () "Remove list identifies from the Subject header. @@ -2419,7 +2441,7 @@ The `gnus-list-identifiers' variable specifies what to do." (regexp (if (consp gnus-list-identifiers) (mapconcat 'identity gnus-list-identifiers " *\\|") gnus-list-identifiers)) - buffer-read-only) + (inhibit-read-only t)) (when regexp (save-excursion (save-restriction @@ -2441,7 +2463,7 @@ always hide." (interactive (gnus-article-hidden-arg)) (unless (gnus-article-check-hidden-text 'pem arg) (save-excursion - (let (buffer-read-only end) + (let ((inhibit-read-only t) end) (goto-char (point-min)) ;; Hide the horrendously ugly "header". (when (and (search-forward @@ -2472,18 +2494,25 @@ always hide." (article-really-strip-banner (gnus-parameter-banner gnus-newsgroup-name))) (when gnus-article-address-banner-alist - (article-really-strip-banner - (let ((from (save-restriction - (widen) - (article-narrow-to-head) - (mail-fetch-field "from")))) - (when (and from - (setq from - (caar (mail-header-parse-addresses from)))) - (catch 'found - (dolist (pair gnus-article-address-banner-alist) - (when (string-match (car pair) from) - (throw 'found (cdr pair))))))))))))) + ;; It is necessary to encode from fields before checking, + ;; because `mail-header-parse-addresses' does not work + ;; (reliably) on decoded headers. And more, it is + ;; impossible to use `gnus-fetch-original-field' here, + ;; because `article-strip-banner' may be called in draft + ;; buffers to preview them. + (let ((from (save-restriction + (widen) + (article-narrow-to-head) + (mail-fetch-field "from")))) + (when (and from + (setq from + (caar (mail-header-parse-addresses + (mail-encode-encoded-word-string from))))) + (catch 'found + (dolist (pair gnus-article-address-banner-alist) + (when (string-match (car pair) from) + (throw 'found + (article-really-strip-banner (cdr pair))))))))))))) (defun article-really-strip-banner (banner) "Strip the banner specified by the argument." @@ -2491,7 +2520,7 @@ always hide." (save-restriction (let ((inhibit-point-motion-hooks t) (gnus-signature-limit nil) - buffer-read-only) + (inhibit-read-only t)) (article-goto-body) (cond ((eq banner 'signature) @@ -2511,11 +2540,9 @@ always hide." "Translate article using an online translation service." (interactive) (require 'babel) - (save-excursion - (set-buffer gnus-article-buffer) + (gnus-with-article-buffer (when (article-goto-body) - (let* ((buffer-read-only nil) - (start (point)) + (let* ((start (point)) (end (point-max)) (orig (buffer-substring start end)) (trans (babel-as-string orig))) @@ -2532,7 +2559,7 @@ always hide." (unless (gnus-article-check-hidden-text 'signature arg) (save-excursion (save-restriction - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (when (gnus-article-narrow-to-signature) (gnus-article-hide-text-type (point-min) (point-max) 'signature)))))) @@ -2552,7 +2579,7 @@ always hide." (interactive) (save-excursion (let ((inhibit-point-motion-hooks t) - buffer-read-only) + (inhibit-read-only t)) (when (article-goto-body) (while (and (not (eobp)) (looking-at "[ \t]*$")) @@ -2587,7 +2614,7 @@ Point is left at the beginning of the narrowed-to region." (interactive) (save-excursion (let ((inhibit-point-motion-hooks t) - buffer-read-only) + (inhibit-read-only t)) ;; First make all blank lines empty. (article-goto-body) (while (re-search-forward "^[ \t]+$" nil t) @@ -2606,7 +2633,7 @@ Point is left at the beginning of the narrowed-to region." (interactive) (save-excursion (let ((inhibit-point-motion-hooks t) - buffer-read-only) + (inhibit-read-only t)) (article-goto-body) (while (re-search-forward "^[ \t]+" nil t) (replace-match "" t t))))) @@ -2616,7 +2643,7 @@ Point is left at the beginning of the narrowed-to region." (interactive) (save-excursion (let ((inhibit-point-motion-hooks t) - buffer-read-only) + (inhibit-read-only t)) (article-goto-body) (while (re-search-forward "[ \t]+$" nil t) (replace-match "" t t))))) @@ -2633,7 +2660,7 @@ Point is left at the beginning of the narrowed-to region." (interactive) (save-excursion (let ((inhibit-point-motion-hooks t) - buffer-read-only) + (inhibit-read-only t)) (article-goto-body) (while (re-search-forward "^[ \t]*\n" nil t) (replace-match "" t t))))) @@ -2722,7 +2749,7 @@ means show, 0 means toggle." (defun gnus-article-show-hidden-text (type &optional dummy) "Show all hidden text of type TYPE. Originally it is hide instead of DUMMY." - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (inhibit-point-motion-hooks t)) (gnus-remove-text-properties-when 'article-type type @@ -2787,23 +2814,22 @@ should replace the \"Date:\" one, or should be added below it." (forward-line 1)) (when (and date (not (string= date ""))) (goto-char (point-min)) - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) ;; Delete any old Date headers. (while (re-search-forward date-regexp nil t) (if pos - (delete-region (progn (beginning-of-line) (point)) - (progn (gnus-article-forward-header) - (point))) - (delete-region (progn (beginning-of-line) (point)) + (delete-region (point-at-bol) (progn (gnus-article-forward-header) - (forward-char -1) (point))) + (delete-region (point-at-bol) + (progn (gnus-article-forward-header) + (forward-char -1) + (point))) (setq pos (point)))) (when (and (not pos) (re-search-forward tdate-regexp nil t)) (forward-line 1)) - (when pos - (goto-char pos)) + (gnus-goto-char pos) (insert (article-make-date-line date (or type 'ut))) (unless pos (insert "\n") @@ -2811,10 +2837,8 @@ should replace the \"Date:\" one, or should be added below it." ;; Do highlighting. (beginning-of-line) (when (looking-at "\\([^:]+\\): *\\(.*\\)$") - (put-text-property (match-beginning 1) (1+ (match-end 1)) - 'original-date date) - (put-text-property (match-beginning 1) (1+ (match-end 1)) - 'face bface) + (add-text-properties (match-beginning 1) (1+ (match-end 1)) + (list 'original-date date 'face bface)) (put-text-property (match-beginning 2) (match-end 2) 'face eface)))))))) @@ -2827,22 +2851,21 @@ should replace the \"Date:\" one, or should be added below it." (cond ;; Convert to the local timezone. ((eq type 'local) - (let ((tz (car (current-time-zone time)))) - (format "Date: %s %s%02d%02d" (current-time-string time) - (if (> tz 0) "+" "-") (/ (abs tz) 3600) - (/ (% (abs tz) 3600) 60)))) + (concat "Date: " (message-make-date time))) ;; Convert to Universal Time. ((eq type 'ut) (concat "Date: " - (current-time-string - (let* ((e (parse-time-string date)) - (tm (apply 'encode-time e)) - (ms (car tm)) - (ls (- (cadr tm) (car (current-time-zone time))))) - (cond ((< ls 0) (list (1- ms) (+ ls 65536))) - ((> ls 65535) (list (1+ ms) (- ls 65536))) - (t (list ms ls))))) - " UT")) + (substring + (message-make-date + (let* ((e (parse-time-string date)) + (tm (apply 'encode-time e)) + (ms (car tm)) + (ls (- (cadr tm) (car (current-time-zone time))))) + (cond ((< ls 0) (list (1- ms) (+ ls 65536))) + ((> ls 65535) (list (1+ ms) (- ls 65536))) + (t (list ms ls))))) + 0 -5) + "UT")) ;; Get the original date from the article. ((eq type 'original) (concat "Date: " (if (string-match "\n+$" date) @@ -3006,7 +3029,7 @@ This format is defined by the `gnus-article-time-format' variable." ;; "Show all hidden text in the article buffer." ;; (interactive) ;; (save-excursion -;; (let ((buffer-read-only nil)) +;; (let ((inhibit-read-only t)) ;; (gnus-article-unhide-text (point-min) (point-max))))) (defun article-remove-leading-whitespace () @@ -3014,7 +3037,7 @@ This format is defined by the `gnus-article-time-format' variable." (interactive) (save-excursion (save-restriction - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (article-narrow-to-head) (goto-char (point-min)) (while (re-search-forward "^[^ :]+: \\([ \t]+\\)" nil t) @@ -3031,7 +3054,7 @@ This format is defined by the `gnus-article-time-format' variable." gnus-article-emphasis-alist) (error)) gnus-emphasis-alist)) - (buffer-read-only nil) + (inhibit-read-only t) (props (append '(article-type emphasis) gnus-hidden-properties)) regexp elem beg invisible visible face) @@ -3423,7 +3446,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is (mm-handle-multipart-ctl-parameter mm-security-handle 'gnus-info))))) (when info - (let (buffer-read-only bface eface) + (let ((inhibit-read-only t) bface eface) (save-restriction (message-narrow-to-head) (goto-char (point-max)) @@ -3635,7 +3658,8 @@ commands: (make-local-variable 'gnus-article-ignored-charsets) (gnus-set-default-directory) (buffer-disable-undo) - (setq buffer-read-only t) + (setq buffer-read-only t + show-trailing-whitespace nil) (set-syntax-table gnus-article-mode-syntax-table) (mm-enable-multibyte) (gnus-run-hooks 'gnus-article-mode-hook)) @@ -3730,7 +3754,7 @@ If ALL-HEADERS is non-nil, no headers are hidden." (when (and (boundp 'transient-mark-mode) transient-mark-mode) (setq mark-active nil)) - (if (not (setq result (let ((buffer-read-only nil)) + (if (not (setq result (let ((inhibit-read-only t)) (gnus-request-article-this-buffer article group)))) ;; There is no such article. @@ -3825,7 +3849,8 @@ If ALL-HEADERS is non-nil, no headers are hidden." ;; Hooks for getting information from the article. ;; This hook must be called before being narrowed. (let ((gnus-article-buffer (current-buffer)) - buffer-read-only) + buffer-read-only + (inhibit-read-only t)) (unless (eq major-mode 'gnus-article-mode) (gnus-article-mode)) (setq buffer-read-only nil @@ -3889,9 +3914,6 @@ General format specifiers can also be used. See Info node (defvar gnus-mime-button-map (let ((map (make-sparse-keymap))) - (unless (>= (string-to-number emacs-version) 21) - ;; XEmacs doesn't care. - (set-keymap-parent map gnus-article-mode-map)) (define-key map gnus-mouse-2 'gnus-article-push-button) (define-key map gnus-down-mouse-3 'gnus-mime-button-menu) (dolist (c gnus-mime-button-commands) @@ -3918,8 +3940,7 @@ General format specifiers can also be used. See Info node (defun gnus-mime-view-all-parts (&optional handles) "View all the MIME parts." (interactive) - (save-current-buffer - (set-buffer gnus-article-buffer) + (with-current-buffer gnus-article-buffer (let ((handles (or handles gnus-article-mime-handles)) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets @@ -3929,80 +3950,99 @@ General format specifiers can also be used. See Info node (mm-remove-parts handles) (goto-char (point-min)) (or (search-forward "\n\n") (goto-char (point-max))) - (let (buffer-read-only) + (let ((inhibit-read-only t)) (delete-region (point) (point-max)) (mm-display-parts handles)))))) +(eval-when-compile + (defsubst gnus-article-edit-part (handles) + "Edit an article in order to delete a mime part. +This function is exclusively used by `gnus-mime-save-part-and-strip' +and `gnus-mime-delete-part', and not provided at run-time normally." + (gnus-article-edit-article + `(lambda () + (erase-buffer) + (let ((mail-parse-charset (or gnus-article-charset + ',gnus-newsgroup-charset)) + (mail-parse-ignored-charsets + (or gnus-article-ignored-charsets + ',gnus-newsgroup-ignored-charsets)) + (mbl mml-buffer-list)) + (setq mml-buffer-list nil) + (insert-buffer gnus-original-article-buffer) + (mime-to-mml ',handles) + (setq gnus-article-mime-handles nil) + (let ((mbl1 mml-buffer-list)) + (setq mml-buffer-list mbl) + (set (make-local-variable 'mml-buffer-list) mbl1)) + (gnus-make-local-hook 'kill-buffer-hook) + (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))) + `(lambda (no-highlight) + (let ((mail-parse-charset (or gnus-article-charset + ',gnus-newsgroup-charset)) + (message-options message-options) + (message-options-set-recipient) + (mail-parse-ignored-charsets + (or gnus-article-ignored-charsets + ',gnus-newsgroup-ignored-charsets))) + (mml-to-mime) + (mml-destroy-buffers) + (remove-hook 'kill-buffer-hook + 'mml-destroy-buffers t) + (kill-local-variable 'mml-buffer-list)) + (gnus-summary-edit-article-done + ,(or (mail-header-references gnus-current-headers) "") + ,(gnus-group-read-only-p) + ,gnus-summary-buffer no-highlight))) + (gnus-article-edit-done) + (gnus-summary-expand-window) + (gnus-summary-show-article))) + (defun gnus-mime-save-part-and-strip () "Save the MIME part under point then replace it with an external body." (interactive) (gnus-article-check-buffer) - (let* ((data (get-text-property (point) 'gnus-data)) - file param - (handles gnus-article-mime-handles)) - (if (mm-multiple-handles gnus-article-mime-handles) - (error "This function is not implemented")) - (setq file (and data (mm-save-part data))) - (when file - (with-current-buffer (mm-handle-buffer data) - (erase-buffer) - (insert "Content-Type: " (mm-handle-media-type data)) - (mml-insert-parameter-string (cdr (mm-handle-type data)) - '(charset)) - (insert "\n") - (insert "Content-ID: " (message-make-message-id) "\n") - (insert "Content-Transfer-Encoding: binary\n") - (insert "\n")) - (setcdr data - (cdr (mm-make-handle nil - `("message/external-body" - (access-type . "LOCAL-FILE") - (name . ,file))))) - (set-buffer gnus-summary-buffer) - (gnus-article-edit-article - `(lambda () - (erase-buffer) - (let ((mail-parse-charset (or gnus-article-charset - ',gnus-newsgroup-charset)) - (mail-parse-ignored-charsets - (or gnus-article-ignored-charsets - ',gnus-newsgroup-ignored-charsets)) - (mbl mml-buffer-list)) - (setq mml-buffer-list nil) - (insert-buffer gnus-original-article-buffer) - (mime-to-mml ',handles) - (setq gnus-article-mime-handles nil) - (let ((mbl1 mml-buffer-list)) - (setq mml-buffer-list mbl) - (set (make-local-variable 'mml-buffer-list) mbl1)) - (gnus-make-local-hook 'kill-buffer-hook) - (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))) - `(lambda (no-highlight) - (let ((mail-parse-charset (or gnus-article-charset - ',gnus-newsgroup-charset)) - (message-options message-options) - (message-options-set-recipient) - (mail-parse-ignored-charsets - (or gnus-article-ignored-charsets - ',gnus-newsgroup-ignored-charsets))) - (mml-to-mime) - (mml-destroy-buffers) - (remove-hook 'kill-buffer-hook - 'mml-destroy-buffers t) - (kill-local-variable 'mml-buffer-list)) - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) - ,gnus-summary-buffer no-highlight)))))) + (when (gnus-group-read-only-p) + (error "The current group does not support deleting of parts")) + (when (mm-complicated-handles gnus-article-mime-handles) + (error "\ +The current article has a complicated MIME structure, giving up...")) + (when (gnus-yes-or-no-p "\ +Deleting parts may malfunction or destroy the article; continue? ") + (let* ((data (get-text-property (point) 'gnus-data)) + file param + (handles gnus-article-mime-handles)) + (setq file (and data (mm-save-part data))) + (when file + (with-current-buffer (mm-handle-buffer data) + (erase-buffer) + (insert "Content-Type: " (mm-handle-media-type data)) + (mml-insert-parameter-string (cdr (mm-handle-type data)) + '(charset)) + (insert "\n") + (insert "Content-ID: " (message-make-message-id) "\n") + (insert "Content-Transfer-Encoding: binary\n") + (insert "\n")) + (setcdr data + (cdr (mm-make-handle nil + `("message/external-body" + (access-type . "LOCAL-FILE") + (name . ,file))))) + (set-buffer gnus-summary-buffer) + (gnus-article-edit-part handles))))) (defun gnus-mime-delete-part () "Delete the MIME part under point. Replace it with some information about the removed part." (interactive) (gnus-article-check-buffer) - (unless (and gnus-novice-user - (not (gnus-yes-or-no-p - "Really delete attachment forever? "))) + (when (gnus-group-read-only-p) + (error "The current group does not support deleting of parts")) + (when (mm-complicated-handles gnus-article-mime-handles) + (error "\ +The current article has a complicated MIME structure, giving up...")) + (when (gnus-yes-or-no-p "\ +Deleting parts may malfunction or destroy the article; continue? ") (let* ((data (get-text-property (point) 'gnus-data)) (handles gnus-article-mime-handles) (none "(none)") @@ -4014,8 +4054,8 @@ Replace it with some information about the removed part." (or (mail-content-type-get (mm-handle-disposition data) 'filename) none)) (type (mm-handle-media-type data))) - (if (mm-multiple-handles gnus-article-mime-handles) - (error "This function is not implemented")) + (unless data + (error "No MIME part under point")) (with-current-buffer (mm-handle-buffer data) (let ((bsize (format "%s" (buffer-size)))) (erase-buffer) @@ -4035,47 +4075,7 @@ Replace it with some information about the removed part." (list "attachment") (format "Deleted attachment (%s bytes)" bsize)))))) (set-buffer gnus-summary-buffer) - ;; FIXME: maybe some of the following code (borrowed from - ;; `gnus-mime-save-part-and-strip') isn't necessary? - (gnus-article-edit-article - `(lambda () - (erase-buffer) - (let ((mail-parse-charset (or gnus-article-charset - ',gnus-newsgroup-charset)) - (mail-parse-ignored-charsets - (or gnus-article-ignored-charsets - ',gnus-newsgroup-ignored-charsets)) - (mbl mml-buffer-list)) - (setq mml-buffer-list nil) - (insert-buffer gnus-original-article-buffer) - (mime-to-mml ',handles) - (setq gnus-article-mime-handles nil) - (let ((mbl1 mml-buffer-list)) - (setq mml-buffer-list mbl) - (set (make-local-variable 'mml-buffer-list) mbl1)) - (gnus-make-local-hook 'kill-buffer-hook) - (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))) - `(lambda (no-highlight) - (let ((mail-parse-charset (or gnus-article-charset - ',gnus-newsgroup-charset)) - (message-options message-options) - (message-options-set-recipient) - (mail-parse-ignored-charsets - (or gnus-article-ignored-charsets - ',gnus-newsgroup-ignored-charsets))) - (mml-to-mime) - (mml-destroy-buffers) - (remove-hook 'kill-buffer-hook - 'mml-destroy-buffers t) - (kill-local-variable 'mml-buffer-list)) - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) - ,gnus-summary-buffer no-highlight))))) - ;; Not in `gnus-mime-save-part-and-strip': - (gnus-article-edit-done) - (gnus-summary-expand-window) - (gnus-summary-show-article)) + (gnus-article-edit-part handles)))) (defun gnus-mime-save-part () "Save the MIME part under point." @@ -4227,7 +4227,7 @@ are decompressed." (let* ((handle (or handle (get-text-property (point) 'gnus-data))) contents charset (b (point)) - buffer-read-only) + (inhibit-read-only t)) (when handle (if (and (not arg) (mm-handle-undisplayer handle)) (mm-remove-part handle) @@ -4262,7 +4262,7 @@ specified charset." (let* ((handle (or handle (get-text-property (point) 'gnus-data))) contents charset (b (point)) - buffer-read-only) + (inhibit-read-only t)) (when handle (if (mm-handle-undisplayer handle) (mm-remove-part handle)) @@ -4282,8 +4282,8 @@ specified charset." (mm-inlined-types nil) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets - (save-excursion (set-buffer gnus-summary-buffer) - gnus-newsgroup-ignored-charsets))) + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-ignored-charsets))) (when handle (if (mm-handle-undisplayer handle) (mm-remove-part handle) @@ -4299,9 +4299,9 @@ If no internal viewer is available, use an external viewer." (mm-inline-large-images t) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets - (save-excursion (set-buffer gnus-summary-buffer) - gnus-newsgroup-ignored-charsets)) - buffer-read-only) + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-ignored-charsets)) + (inhibit-read-only t)) (when handle (if (mm-handle-undisplayer handle) (mm-remove-part handle) @@ -4317,8 +4317,7 @@ If no internal viewer is available, use an external viewer." (funcall (cdr action-pair))))) (defun gnus-article-part-wrapper (n function) - (save-current-buffer - (set-buffer gnus-article-buffer) + (with-current-buffer gnus-article-buffer (when (> n (length gnus-article-mime-handle-alist)) (error "No such part")) (gnus-article-goto-part n) @@ -4384,8 +4383,7 @@ N is the numerical prefix." (defun gnus-article-view-part (&optional n) "View MIME part N, which is the numerical prefix." (interactive "P") - (save-current-buffer - (set-buffer gnus-article-buffer) + (with-current-buffer gnus-article-buffer (or (numberp n) (setq n (gnus-article-mime-match-handle-first gnus-article-mime-match-handle-function))) (when (> n (length gnus-article-mime-handle-alist)) @@ -4406,15 +4404,14 @@ N is the numerical prefix." "Display HANDLE and fix MIME button." (let ((id (get-text-property (point) 'gnus-part)) (point (point)) - buffer-read-only) + (inhibit-read-only t)) (forward-line 1) (prog1 (let ((window (selected-window)) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets (if (gnus-buffer-live-p gnus-summary-buffer) - (save-excursion - (set-buffer gnus-summary-buffer) + (with-current-buffer gnus-summary-buffer gnus-newsgroup-ignored-charsets) nil))) (save-excursion @@ -4537,7 +4534,7 @@ N is the numerical prefix." (mm-dissect-buffer nil gnus-article-loose-mime) (and gnus-article-emulate-mime (mm-uu-dissect)))) - buffer-read-only handle name type b e display) + (inhibit-read-only t) handle name type b e display) (when (and (not ihandles) (not gnus-displaying-mime)) ;; Top-level call; we clean up. @@ -4672,11 +4669,9 @@ If displaying \"text/html\" is discouraged \(see (push (cons id handle) gnus-article-mime-handle-alist) (when (or (not display) (not (gnus-unbuttonized-mime-type-p type))) - ;(gnus-article-insert-newline) (gnus-insert-mime-button handle id (list (or display (and not-attachment text)))) (gnus-article-insert-newline) - ;(gnus-article-insert-newline) ;; Remember modify the number of forward lines. (setq move t)) (setq beg (point)) @@ -4732,7 +4727,7 @@ If displaying \"text/html\" is discouraged \(see (let* ((preferred (or preferred (mm-preferred-alternative handles))) (ihandles handles) (point (point)) - handle buffer-read-only from props begend not-pref) + handle (inhibit-read-only t) from props begend not-pref) (save-window-excursion (save-restriction (when ibegend @@ -4803,8 +4798,8 @@ If displaying \"text/html\" is discouraged \(see (gnus-display-mime preferred) (let ((mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets - (save-excursion (set-buffer gnus-summary-buffer) - gnus-newsgroup-ignored-charsets))) + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-ignored-charsets))) (mm-display-part preferred) ;; Do highlighting. (save-excursion @@ -4854,8 +4849,7 @@ is the string to use when it is inactive.") (defun gnus-article-wash-status () "Return a string which display status of article washing." - (save-excursion - (set-buffer gnus-article-buffer) + (with-current-buffer gnus-article-buffer (let ((cite (memq 'cite gnus-article-wash-types)) (headers (memq 'headers gnus-article-wash-types)) (boring (memq 'boring-headers gnus-article-wash-types)) @@ -4904,8 +4898,8 @@ is the string to use when it is inactive.") "Hide unwanted headers if `gnus-have-all-headers' is nil. Provided for backwards compatibility." (when (and (or (not (gnus-buffer-live-p gnus-summary-buffer)) - (not (save-excursion (set-buffer gnus-summary-buffer) - gnus-have-all-headers))) + (not (with-current-buffer gnus-summary-buffer + gnus-have-all-headers))) (not gnus-inhibit-hiding)) (gnus-article-hide-headers))) @@ -4935,7 +4929,7 @@ If given a numerical ARG, move forward ARG pages." (widen) ;; Remove any old next/prev buttons. (when (gnus-visual-p 'page-marker) - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (gnus-remove-text-with-property 'gnus-prev) (gnus-remove-text-with-property 'gnus-next))) (if @@ -4955,7 +4949,7 @@ If given a numerical ARG, move forward ARG pages." (match-beginning 0) (point))) (when (and (gnus-visual-p 'page-marker) - (not (= (point-min) 1))) + (> (point-min) (save-restriction (widen) (point-min)))) (save-excursion (goto-char (point-min)) (gnus-insert-prev-page-button))) @@ -5011,6 +5005,7 @@ Argument LINES specifies lines to be scrolled up." (save-excursion (save-restriction (widen) + (forward-line) (eobp)))) ;Real end-of-buffer? (progn (when gnus-article-over-scroll @@ -5168,11 +5163,13 @@ not have a face in `gnus-article-boring-faces'." (let ((obuf (current-buffer)) (owin (current-window-configuration)) (opoint (point)) - (summary gnus-article-current-summary) - func in-buffer selected) - (if not-restore-window - (pop-to-buffer summary 'norecord) - (switch-to-buffer summary 'norecord)) + win func in-buffer selected new-sum-start new-sum-hscroll) + (cond (not-restore-window + (pop-to-buffer gnus-article-current-summary 'norecord)) + ((setq win (get-buffer-window gnus-article-current-summary)) + (select-window win)) + (t + (switch-to-buffer gnus-article-current-summary 'norecord))) (setq in-buffer (current-buffer)) ;; We disable the pick minor mode commands. (if (and (setq func (let (gnus-pick-mode) @@ -5180,7 +5177,10 @@ not have a face in `gnus-article-boring-faces'." (functionp func)) (progn (call-interactively func) - (setq new-sum-point (point)) + (when (eq win (selected-window)) + (setq new-sum-point (point) + new-sum-start (window-start win) + new-sum-hscroll (window-hscroll win)) (when (eq in-buffer (current-buffer)) (setq selected (gnus-summary-select-article)) (set-buffer obuf) @@ -5192,10 +5192,12 @@ not have a face in `gnus-article-boring-faces'." 1) (set-window-point (get-buffer-window (current-buffer)) (point))) - (let ((win (get-buffer-window gnus-article-current-summary))) - (when win - (set-window-point win new-sum-point)))) ) - (switch-to-buffer gnus-article-buffer) + (when (and (not not-restore-window) + new-sum-point) + (set-window-point win new-sum-point) + (set-window-start win new-sum-start) + (set-window-hscroll win new-sum-hscroll))))) + (set-window-configuration owin) (ding)))))) (defun gnus-article-describe-key (key) @@ -5247,7 +5249,7 @@ the entire article will be yanked." (interactive "P") (let ((article (cdr gnus-article-current)) contents) - (if (not (gnus-mark-active-p)) + (if (not (gnus-region-active-p)) (with-current-buffer gnus-summary-buffer (gnus-summary-reply (list (list article)) wide)) (setq contents (buffer-substring (point) (mark t))) @@ -5266,7 +5268,7 @@ the entire article will be yanked." (interactive) (let ((article (cdr gnus-article-current)) contents) - (if (not (gnus-mark-active-p)) + (if (not (gnus-region-active-p)) (with-current-buffer gnus-summary-buffer (gnus-summary-followup (list (list article)))) (setq contents (buffer-substring (point) (mark t))) @@ -5366,16 +5368,14 @@ If given a prefix, show the hidden text instead." gnus-summary-buffer (get-buffer gnus-summary-buffer) (gnus-buffer-exists-p gnus-summary-buffer) - (eq (cdr (save-excursion - (set-buffer gnus-summary-buffer) + (eq (cdr (with-current-buffer gnus-summary-buffer (assq article gnus-newsgroup-reads))) gnus-canceled-mark)) nil) ;; We first check `gnus-original-article-buffer'. ((and (get-buffer gnus-original-article-buffer) (numberp article) - (save-excursion - (set-buffer gnus-original-article-buffer) + (with-current-buffer gnus-original-article-buffer (and (equal (car gnus-original-article) group) (eq (cdr gnus-original-article) article)))) (insert-buffer-substring gnus-original-article-buffer) @@ -5407,7 +5407,7 @@ If given a prefix, show the hidden text instead." (backend (car (gnus-find-method-for-group gnus-newsgroup-name))) result - (buffer-read-only nil)) + (inhibit-read-only t)) (if (or (not (listp methods)) (and (symbolp (car methods)) (assq (car methods) nnoo-definition-alist))) @@ -5459,7 +5459,7 @@ If given a prefix, show the hidden text instead." (buffer-disable-undo) (setq major-mode 'gnus-original-article-mode) (setq buffer-read-only t)) - (let (buffer-read-only) + (let ((inhibit-read-only t)) (erase-buffer) (insert-buffer-substring gnus-article-buffer)) (setq gnus-original-article (cons group article))) @@ -5493,7 +5493,6 @@ If given a prefix, show the hidden text instead." (defvar gnus-article-edit-done-function nil) (defvar gnus-article-edit-mode-map nil) -(defvar gnus-article-edit-mode nil) ;; Should we be using derived.el for this? (unless gnus-article-edit-mode-map @@ -5558,7 +5557,7 @@ If given a prefix, show the hidden text instead." ["Body" message-goto-body t] ["Signature" message-goto-signature t])) -(define-derived-mode gnus-article-edit-mode text-mode "Article Edit" +(define-derived-mode gnus-article-edit-mode message-mode "Article Edit" "Major mode for editing articles. This is an extended text-mode. @@ -5727,7 +5726,7 @@ The function must take one argument, the string naming the URL." (defcustom gnus-button-ctan-directory-regexp (concat - "\\("; Cannot use `\(?: ... \)' (compatibility with Emacs 20). + "\\(?:" "biblio\\|digests\\|dviware\\|fonts\\|graphics\\|help\\|" "indexing\\|info\\|language\\|macros\\|support\\|systems\\|" "tds\\|tools\\|usergrps\\|web\\|nonfree\\|obsolete" @@ -6060,7 +6059,7 @@ positives are possible." ("\\( \n\t]+\\)>" 0 (>= gnus-button-message-level 0) gnus-url-mailto 2) ;; RFC 2368 (The mailto URL scheme) - ("mailto:\\([-a-z.@_+0-9%=?&]+\\)" + ("\\bmailto:\\([-a-z.@_+0-9%=?&/]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) ("\\bmailto:\\([^ \n\t]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) @@ -6108,8 +6107,9 @@ positives are possible." ("M-x[ \t\n]+apropos-documentation[ \t\n]+RET[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET" 0 (>= gnus-button-emacs-level 1) gnus-button-handle-apropos-documentation 1) ;; The following entries may lead to many false positives so don't enable - ;; them by default (use a high button level): - ("/\\([a-z][-a-z0-9]+\\.el\\)\\>" + ;; them by default (use a high button level). + ("/\\([a-z][-a-z0-9]+\\.el\\)\\>[^.?]" + ;; Exclude [.?] for URLs in gmane.emacs.cvs 1 (>= gnus-button-emacs-level 8) gnus-button-handle-library 1) ("`\\([a-z][-a-z0-9]+\\.el\\)'" 1 (>= gnus-button-emacs-level 8) gnus-button-handle-library 1) @@ -6142,16 +6142,16 @@ positives are possible." (gnus-button-url-regexp 0 (>= gnus-button-browse-level 0) browse-url 0) ;; man pages - ("\\b\\([a-z][a-z]+\\)([1-9])\\W" + ("\\b\\([a-z][a-z]+([1-9])\\)\\W" 0 (and (>= gnus-button-man-level 1) (< gnus-button-man-level 3)) gnus-button-handle-man 1) ;; more man pages: resolv.conf(5), iso_8859-1(7), xterm(1x) - ("\\b\\([a-z][-_.a-z0-9]+\\)([1-9])\\W" + ("\\b\\([a-z][-_.a-z0-9]+([1-9])\\)\\W" 0 (and (>= gnus-button-man-level 3) (< gnus-button-man-level 5)) gnus-button-handle-man 1) ;; even more: Apache::PerlRun(3pm), PDL::IO::FastRaw(3pm), ;; SoWWWAnchor(3iv), XSelectInput(3X11), X(1), X(7) - ("\\b\\([a-z][-+_.:a-z0-9]+\\)([1-9][X1a-z]*)\\W\\|\\b\\(X\\)([1-9])\\W" + ("\\b\\(\\(?:[a-z][-+_.:a-z0-9]+([1-9][X1a-z]*)\\)\\|\\b\\(?:X([1-9])\\)\\)\\W" 0 (>= gnus-button-man-level 5) gnus-button-handle-man 1) ;; MID or mail: To avoid too many false positives we don't try to catch ;; all kind of allowed MIDs or mail addresses. Domain part must contain @@ -6195,7 +6195,7 @@ variable it the real callback function." 0 (>= gnus-button-browse-level 0) browse-url 0) ("^[^:]+:" gnus-button-url-regexp 0 (>= gnus-button-browse-level 0) browse-url 0) - ("^[^:]+:" "\\bmailto:\\([-a-z.@_+0-9%=?&]+\\)" + ("^[^:]+:" "\\bmailto:\\([-a-z.@_+0-9%=?&/]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) ("^[^:]+:" "\\(<\\(url: \\)?\\(nntp\\|news\\):\\([^>\n ]*\\)>\\)" 1 (>= gnus-button-message-level 0) gnus-button-message-id 4)) @@ -6219,13 +6219,6 @@ HEADER is a regexp to match a header. For a fuller explanation, see :inline t (integer :tag "Regexp group"))))) -(defvar gnus-button-regexp nil) -(defvar gnus-button-marker-list nil) -;; Regexp matching any of the regexps from `gnus-button-alist'. - -(defvar gnus-button-last nil) -;; The value of `gnus-button-alist' when `gnus-button-regexp' was build. - ;;; Commands: (defun gnus-article-push-button (event) @@ -6277,51 +6270,43 @@ do the highlighting. See the documentation for those functions." (defun gnus-article-highlight-headers () "Highlight article headers as specified by `gnus-header-face-alist'." (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (save-restriction - (let ((alist gnus-header-face-alist) - (buffer-read-only nil) - (case-fold-search t) - (inhibit-point-motion-hooks t) - entry regexp header-face field-face from hpoints fpoints) - (article-narrow-to-head) - (while (setq entry (pop alist)) - (goto-char (point-min)) - (setq regexp (concat "^\\(" - (if (string-equal "" (nth 0 entry)) - "[^\t ]" - (nth 0 entry)) - "\\)") - header-face (nth 1 entry) - field-face (nth 2 entry)) - (while (and (re-search-forward regexp nil t) - (not (eobp))) - (beginning-of-line) - (setq from (point)) - (unless (search-forward ":" nil t) - (forward-char 1)) - (when (and header-face - (not (memq (point) hpoints))) - (push (point) hpoints) - (gnus-put-text-property from (point) 'face header-face)) - (when (and field-face - (not (memq (setq from (point)) fpoints))) - (push from fpoints) - (if (re-search-forward "^[^ \t]" nil t) - (forward-char -2) - (goto-char (point-max))) - (gnus-put-text-property from (point) 'face field-face)))))))) + (gnus-with-article-headers + (let ((alist gnus-header-face-alist) + entry regexp header-face field-face from hpoints fpoints) + (while (setq entry (pop alist)) + (goto-char (point-min)) + (setq regexp (concat "^\\(" + (if (string-equal "" (nth 0 entry)) + "[^\t ]" + (nth 0 entry)) + "\\)") + header-face (nth 1 entry) + field-face (nth 2 entry)) + (while (and (re-search-forward regexp nil t) + (not (eobp))) + (beginning-of-line) + (setq from (point)) + (unless (search-forward ":" nil t) + (forward-char 1)) + (when (and header-face + (not (memq (point) hpoints))) + (push (point) hpoints) + (gnus-put-text-property from (point) 'face header-face)) + (when (and field-face + (not (memq (setq from (point)) fpoints))) + (push from fpoints) + (if (re-search-forward "^[^ \t]" nil t) + (forward-char -2) + (goto-char (point-max))) + (gnus-put-text-property from (point) 'face field-face))))))) (defun gnus-article-highlight-signature () "Highlight the signature in an article. It does this by highlighting everything after `gnus-signature-separator' using `gnus-signature-face'." (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t)) + (gnus-with-article-buffer + (let ((inhibit-point-motion-hooks t)) (save-restriction (when (and gnus-signature-face (gnus-article-narrow-to-signature)) @@ -6343,10 +6328,8 @@ It does this by highlighting everything after \"External references\" are things like Message-IDs and URLs, as specified by `gnus-button-alist'." (interactive (list 'force)) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) + (gnus-with-article-buffer + (let ((inhibit-point-motion-hooks t) (case-fold-search t) (alist gnus-button-alist) beg entry regexp) @@ -6387,40 +6370,33 @@ specified by `gnus-button-alist'." (defun gnus-article-add-buttons-to-head () "Add buttons to the head of the article." (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (save-restriction - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (case-fold-search t) - (alist gnus-header-button-alist) - entry beg end) - (article-narrow-to-head) - (while alist - ;; Each alist entry. - (setq entry (car alist) - alist (cdr alist)) - (goto-char (point-min)) - (while (re-search-forward (car entry) nil t) - ;; Each header matching the entry. - (setq beg (match-beginning 0)) - (setq end (or (and (re-search-forward "^[^ \t]" nil t) - (match-beginning 0)) - (point-max))) - (goto-char beg) - (while (re-search-forward (eval (nth 1 entry)) end t) - ;; Each match within a header. - (let* ((entry (cdr entry)) - (start (match-beginning (nth 1 entry))) - (end (match-end (nth 1 entry))) - (form (nth 2 entry))) - (goto-char (match-end 0)) - (when (eval form) - (gnus-article-add-button - start end (nth 3 entry) - (buffer-substring (match-beginning (nth 4 entry)) - (match-end (nth 4 entry))))))) - (goto-char end))))))) + (gnus-with-article-headers + (let ((alist gnus-header-button-alist) + entry beg end) + (while alist + ;; Each alist entry. + (setq entry (pop alist)) + (goto-char (point-min)) + (while (re-search-forward (car entry) nil t) + ;; Each header matching the entry. + (setq beg (match-beginning 0)) + (setq end (or (and (re-search-forward "^[^ \t]" nil t) + (match-beginning 0)) + (point-max))) + (goto-char beg) + (while (re-search-forward (eval (nth 1 entry)) end t) + ;; Each match within a header. + (let* ((entry (cdr entry)) + (start (match-beginning (nth 1 entry))) + (end (match-end (nth 1 entry))) + (form (nth 2 entry))) + (goto-char (match-end 0)) + (when (eval form) + (gnus-article-add-button + start end (nth 3 entry) + (buffer-substring (match-beginning (nth 4 entry)) + (match-end (nth 4 entry))))))) + (goto-char end)))))) ;;; External functions: @@ -6441,15 +6417,12 @@ specified by `gnus-button-alist'." ;;; Internal functions: (defun gnus-article-set-globals () - (save-excursion - (set-buffer gnus-summary-buffer) + (with-current-buffer gnus-summary-buffer (gnus-set-global-variables))) (defun gnus-signature-toggle (end) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t)) + (gnus-with-article-buffer + (let ((inhibit-point-motion-hooks t)) (if (text-property-any end (point-max) 'article-type 'signature) (progn (gnus-delete-wash-type 'signature) @@ -6540,6 +6513,10 @@ specified by `gnus-button-alist'." (defun gnus-button-handle-man (url) "Fetch a man page." + (gnus-message 9 "`%s' `%s'" gnus-button-man-handler url) + (when (eq gnus-button-man-handler 'woman) + (setq url (gnus-replace-in-string url "([1-9][X1a-z]*).*\\'" ""))) + (gnus-message 9 "`%s' `%s'" gnus-button-man-handler url) (funcall gnus-button-man-handler url)) (defun gnus-button-handle-info-url (url) @@ -6585,8 +6562,7 @@ specified by `gnus-button-alist'." (defun gnus-button-message-id (message-id) "Fetch MESSAGE-ID." - (save-excursion - (set-buffer gnus-summary-buffer) + (with-current-buffer gnus-summary-buffer (gnus-summary-refer-article message-id))) (defun gnus-button-fetch-group (address) @@ -6666,16 +6642,19 @@ specified by `gnus-button-alist'." (defvar gnus-prev-page-map (let ((map (make-sparse-keymap))) - (unless (>= emacs-major-version 21) - ;; XEmacs doesn't care. - (set-keymap-parent map gnus-article-mode-map)) (define-key map gnus-mouse-2 'gnus-button-prev-page) (define-key map "\r" 'gnus-button-prev-page) map)) +(defvar gnus-next-page-map + (let ((map (make-sparse-keymap))) + (define-key map gnus-mouse-2 'gnus-button-next-page) + (define-key map "\r" 'gnus-button-next-page) + map)) + (defun gnus-insert-prev-page-button () (let ((b (point)) - (buffer-read-only nil)) + (inhibit-read-only t)) (gnus-eval-format gnus-prev-page-line-format nil `(keymap ,gnus-prev-page-map @@ -6690,24 +6669,6 @@ specified by `gnus-button-alist'." :action 'gnus-button-prev-page :button-keymap gnus-prev-page-map))) -(defvar gnus-prev-page-map - (let ((map (make-sparse-keymap))) - (unless (>= emacs-major-version 21) - ;; XEmacs doesn't care. - (set-keymap-parent map gnus-article-mode-map)) - (define-key map gnus-mouse-2 'gnus-button-prev-page) - (define-key map "\r" 'gnus-button-prev-page) - map)) - -(defvar gnus-next-page-map - (let ((map (make-sparse-keymap))) - (unless (>= emacs-major-version 21) - ;; XEmacs doesn't care. - (set-keymap-parent map gnus-article-mode-map)) - (define-key map gnus-mouse-2 'gnus-button-next-page) - (define-key map "\r" 'gnus-button-next-page) - map)) - (defun gnus-button-next-page (&optional args more-args) "Go to the next page." (interactive) @@ -6726,7 +6687,7 @@ specified by `gnus-button-alist'." (defun gnus-insert-next-page-button () (let ((b (point)) - (buffer-read-only nil)) + (inhibit-read-only t)) (gnus-eval-format gnus-next-page-line-format nil `(keymap ,gnus-next-page-map gnus-next t @@ -6761,7 +6722,7 @@ specified by `gnus-button-alist'." "List of methods used to decode headers. 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 +is FUNCTION, FUNCTION will be applied to all newsgroups. If item is a \(REGEXP . FUNCTION), FUNCTION will be only apply to the newsgroups whose names match REGEXP. @@ -6900,7 +6861,7 @@ For example: (setq references (or (mail-header-references gnus-current-headers) "")) (set-buffer gnus-article-buffer) - (let* ((buffer-read-only nil) + (let* ((inhibit-read-only t) (headers (mapcar (lambda (field) (and (save-restriction @@ -6964,8 +6925,6 @@ For example: (defvar gnus-mime-security-button-map (let ((map (make-sparse-keymap))) - (unless (>= (string-to-number emacs-version) 21) - (set-keymap-parent map gnus-article-mode-map)) (define-key map gnus-mouse-2 'gnus-article-push-button) (define-key map "\r" 'gnus-article-press-button) map)) @@ -6980,7 +6939,7 @@ For example: (defun gnus-mime-security-verify-or-decrypt (handle) (mm-remove-parts (cdr handle)) (let ((region (mm-handle-multipart-ctl-parameter handle 'gnus-region)) - point buffer-read-only) + point (inhibit-read-only t)) (if region (goto-char (car region))) (save-restriction @@ -7010,7 +6969,7 @@ For example: (not (get-text-property (point) 'gnus-mime-details))) (gnus-mime-security-button-line-format (get-text-property (point) 'gnus-line-format)) - buffer-read-only) + (inhibit-read-only t)) (forward-char -1) (while (eq (get-text-property (point) 'gnus-line-format) gnus-mime-security-button-line-format) @@ -7120,4 +7079,5 @@ For example: (run-hooks 'gnus-art-load-hook) +;;; arch-tag: 2654516f-6279-48f9-a83b-05c1fa450c33 ;;; gnus-art.el ends here