From 71e691a59f04acbd9a03c2d38d7e8971a0ec5115 Mon Sep 17 00:00:00 2001 From: Gnus developers Date: Mon, 4 Oct 2010 22:26:51 +0000 Subject: [PATCH] Merge changes made in Gnus trunk. shr.el: Implement table rendering. shr.el (shr-make-table): Tweak table generation. shr.el (shr-make-table): Fix typo. nnimap.el (nnimap-open-connection): Allow tls as a synonym for ssl. gnus-util.el (gnus-emacs-completing-read): Mapcar collection to list, for XEmacs. nnimap.el (nnimap-close-server): Implement. gnus-salt.el: Remove all gnus-carpal stuff -- it's not useful. nnir.el (nnir-run-imap): Remove spurious space in search string. message.el (message-idna-to-ascii-rhs-1): Don't bug out on addresses without @ signs. gnus-sum.el (gnus-widen-article-window): New variable. shr.el (browse-url): Required. shr.el (shr-ensure-paragraph): Don't insert a new newline after empty-ish lines. shr.el (shr-show-alt-text, shr-browse-image): New commands. gravatar.el (gravatar-retrieved): kill buffer when retrieved. shr.el (shr-browse-url, shr-copy-url): New commands. shr.el (shr-render-td): Protect against too-wide text. spam-report.el (spam-report-url-ping-plain): Don't query about killing the process. nnimap.el (nnimap-finish-retrieve-group-infos): Message while waiting for data. shr.el (shr-tag-blockquote): Ensure paragraph after quote, too. mml-smime.el: Fix gnus-completing-read usage. shr.el (shr-get-image-data): Ensure against the cache file missing. nnimap.el (nnimap-open-connection): Give an error if nnimap-stream is unknown. --- doc/misc/ChangeLog | 4 + doc/misc/gnus-news.texi | 2 + doc/misc/gnus.texi | 79 ++----------- lisp/gnus/ChangeLog | 55 ++++++++- lisp/gnus/gnus-group.el | 4 +- lisp/gnus/gnus-salt.el | 171 ---------------------------- lisp/gnus/gnus-srvr.el | 6 +- lisp/gnus/gnus-sum.el | 14 ++- lisp/gnus/gnus-util.el | 6 +- lisp/gnus/gnus-win.el | 18 +-- lisp/gnus/gnus.el | 7 +- lisp/gnus/gravatar.el | 3 +- lisp/gnus/message.el | 4 +- lisp/gnus/mml-smime.el | 4 +- lisp/gnus/nnimap.el | 15 ++- lisp/gnus/nnir.el | 2 +- lisp/gnus/shr.el | 240 ++++++++++++++++++++++++++++++++++++--- lisp/gnus/spam-report.el | 1 + 18 files changed, 334 insertions(+), 301 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 5c2766c853..b30bb9e502 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,7 @@ +2010-10-04 Lars Magne Ingebrigtsen + + * gnus.texi (Misc Article): Document gnus-widen-article-window. + 2010-10-03 Julien Danjou * emacs-mime.texi (Display Customization): Update diff --git a/doc/misc/gnus-news.texi b/doc/misc/gnus-news.texi index 028539a7fb..1136d52e51 100644 --- a/doc/misc/gnus-news.texi +++ b/doc/misc/gnus-news.texi @@ -356,6 +356,8 @@ moving articles to a group that has not turned auto-expire on. @item NoCeM support has been removed. +@item Carpal mode has been removed. + @end itemize @end itemize diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 00f58b2307..6c20e424f0 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -797,7 +797,6 @@ Various * Compilation:: How to speed Gnus up. * Mode Lines:: Displaying information in the mode lines. * Highlighting and Menus:: Making buffers look all nice and cozy. -* Buttons:: Get tendinitis in ten easy steps! * Daemons:: Gnus can do things behind your back. * Undo:: Some actions can be undone. * Predicate Specifiers:: Specifying predicates. @@ -12847,6 +12846,11 @@ If non-@code{nil}, use the same article buffer for all the groups. (This is the default.) If @code{nil}, each group will have its own article buffer. +@item gnus-widen-article-window +@cindex gnus-widen-article-window +If non-@code{nil}, selecting the article buffer with the @kbd{h} +command will ``widen'' the article window to take the entire frame. + @vindex gnus-article-decode-hook @item gnus-article-decode-hook @cindex @acronym{MIME} @@ -21717,7 +21721,6 @@ four days, Gnus will decay the scores four times, for instance. * Compilation:: How to speed Gnus up. * Mode Lines:: Displaying information in the mode lines. * Highlighting and Menus:: Making buffers look all nice and cozy. -* Buttons:: Get tendinitis in ten easy steps! * Daemons:: Gnus can do things behind your back. * Undo:: Some actions can be undone. * Predicate Specifiers:: Specifying predicates. @@ -22178,8 +22181,7 @@ glitches. Use at your own peril. buffer should be given. Here's an excerpt of this variable: @lisp -((group (vertical 1.0 (group 1.0 point) - (if gnus-carpal (group-carpal 4)))) +((group (vertical 1.0 (group 1.0 point))) (article (vertical 1.0 (summary 0.25 point) (article 1.0)))) @end lisp @@ -22217,7 +22219,6 @@ Here's a more complicated example: @lisp (article (vertical 1.0 (group 4) (summary 0.25 point) - (if gnus-carpal (summary-carpal 4)) (article 1.0))) @end lisp @@ -22228,20 +22229,16 @@ occupy, not a percentage. If the @dfn{split} looks like something that can be @code{eval}ed (to be precise---if the @code{car} of the split is a function or a subr), this split will be @code{eval}ed. If the result is non-@code{nil}, it will -be used as a split. This means that there will be three buffers if -@code{gnus-carpal} is @code{nil}, and four buffers if @code{gnus-carpal} -is non-@code{nil}. +be used as a split. Not complicated enough for you? Well, try this on for size: @lisp (article (horizontal 1.0 (vertical 0.5 - (group 1.0) - (gnus-carpal 4)) + (group 1.0)) (vertical 1.0 (summary 0.25 point) - (summary-carpal 4) (article 1.0)))) @end lisp @@ -22618,62 +22615,6 @@ Hook called after creating the score mode menu. @end table -@node Buttons -@section Buttons -@cindex buttons -@cindex mouse -@cindex click - -Those new-fangled @dfn{mouse} contraptions is very popular with the -young, hep kids who don't want to learn the proper way to do things -these days. Why, I remember way back in the summer of '89, when I was -using Emacs on a Tops 20 system. Three hundred users on one single -machine, and every user was running Simula compilers. Bah! - -Right. - -@vindex gnus-carpal -Well, you can make Gnus display bufferfuls of buttons you can click to -do anything by setting @code{gnus-carpal} to @code{t}. Pretty simple, -really. Tell the chiropractor I sent you. - - -@table @code - -@item gnus-carpal-mode-hook -@vindex gnus-carpal-mode-hook -Hook run in all carpal mode buffers. - -@item gnus-carpal-button-face -@vindex gnus-carpal-button-face -Face used on buttons. - -@item gnus-carpal-header-face -@vindex gnus-carpal-header-face -Face used on carpal buffer headers. - -@item gnus-carpal-group-buffer-buttons -@vindex gnus-carpal-group-buffer-buttons -Buttons in the group buffer. - -@item gnus-carpal-summary-buffer-buttons -@vindex gnus-carpal-summary-buffer-buttons -Buttons in the summary buffer. - -@item gnus-carpal-server-buffer-buttons -@vindex gnus-carpal-server-buffer-buttons -Buttons in the server buffer. - -@item gnus-carpal-browse-buffer-buttons -@vindex gnus-carpal-browse-buffer-buttons -Buttons in the browse buffer. -@end table - -All the @code{buttons} variables are lists. The elements in these list -are either cons cells where the @code{car} contains a text to be displayed and -the @code{cdr} contains a function symbol, or a simple string. - - @node Daemons @section Daemons @cindex demons @@ -26651,10 +26592,6 @@ Buttons}). You can do lots of strange stuff with the Gnus window & frame configuration (@pxref{Window Layout}). -@item -You can click on buttons instead of using the keyboard -(@pxref{Buttons}). - @end itemize diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 33a760eb6f..a2371a51b4 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,11 +1,64 @@ 2010-10-04 Lars Magne Ingebrigtsen + * shr.el (shr-tag-blockquote): Ensure paragraph after quote, too. + (shr-get-image-data): Ensure against the cache file missing. + + * nnimap.el (nnimap-finish-retrieve-group-infos): Message while waiting + for data. + + * spam-report.el (spam-report-url-ping-plain): Don't query about + killing the process. + + * shr.el (shr-render-td): Protect against too-wide text. + +2010-10-04 Julien Danjou + + * mml-smime.el (mml-smime-openssl-encrypt-query): Fix choices. + (mml-smime-openssl-sign-query): Fix gnus-completing-read call. + + * gravatar.el (gravatar-retrieved): Kill buffer when gravatar has been + retrieved. + +2010-10-04 Lars Magne Ingebrigtsen + + * shr.el (browse-url): Required. + (shr-ensure-paragraph): Don't insert a new newline after empty-ish + lines. + (shr-show-alt-text, shr-browse-image): New commands. + (shr-browse-url, shr-copy-url): New commands. + + * gnus-sum.el (gnus-widen-article-window): New variable. + (gnus-summary-select-article-buffer): Use it. + + * message.el (message-idna-to-ascii-rhs-1): Don't bug out on addresses + without @ signs. + +2010-10-04 Michael Welsh Duggan (tiny change) + + * nnir.el (nnir-run-imap): Remove spurious space in search string. + +2010-10-04 Julien Danjou + + * gnus-util.el (gnus-emacs-completing-read): Mapcar collection to list, + for XEmacs. + +2010-10-04 Lars Magne Ingebrigtsen + + * gnus-salt.el: Remove all gnus-carpal stuff -- it's not useful. + + * nnimap.el (nnimap-open-connection): Allow tls as a synonym for ssl. + (nnimap-close-server): Implement. + * shr.el (shr-ensure-paragraph): Fix the non-empty line case. (shr-insert): Tweak line breaking. (shr-insert): Handle
 better.
 	(shr-tag-li): Get 
  • indentation right. (shr-tag-li): Get
  • indentation even righter. (shr-tag-blockquote): Ensure paragraph start. + (shr-make-table): Tweak table generation. + (shr-make-table): Fix typo. + + * shr.el: Implement table rendering. 2010-10-04 Julien Danjou @@ -1458,8 +1511,6 @@ * nnimap.el (nnimap-open-connection): If the user doesn't have a /etc/services, supply some sensible port defaults. - * dgnushack.el: Define netrc-credentials. - 2010-09-17 Julien Danjou * mm-decode.el (mm-text-html-renderer): Document gnus-article-html. diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 2ea5cce784..d9e36ae6ea 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -1186,9 +1186,7 @@ The following commands are available: (defun gnus-group-setup-buffer () (set-buffer (gnus-get-buffer-create gnus-group-buffer)) (unless (eq major-mode 'gnus-group-mode) - (gnus-group-mode) - (when gnus-carpal - (gnus-carpal-setup-buffer 'group)))) + (gnus-group-mode))) (defun gnus-group-name-charset (method group) (if (null method) diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el index 21b9d8954f..a72d594a38 100644 --- a/lisp/gnus/gnus-salt.el +++ b/lisp/gnus/gnus-salt.el @@ -869,177 +869,6 @@ Two predefined functions are available: (set-window-point (gnus-get-buffer-window (current-buffer) t) (cdr region)))))) -;;; -;;; gnus-carpal -;;; - -(defvar gnus-carpal-group-buffer-buttons - '(("next" . gnus-group-next-unread-group) - ("prev" . gnus-group-prev-unread-group) - ("read" . gnus-group-read-group) - ("select" . gnus-group-select-group) - ("catch-up" . gnus-group-catchup-current) - ("new-news" . gnus-group-get-new-news-this-group) - ("toggle-sub" . gnus-group-unsubscribe-current-group) - ("subscribe" . gnus-group-unsubscribe-group) - ("kill" . gnus-group-kill-group) - ("yank" . gnus-group-yank-group) - ("describe" . gnus-group-describe-group) - "list" - ("subscribed" . gnus-group-list-groups) - ("all" . gnus-group-list-all-groups) - ("killed" . gnus-group-list-killed) - ("zombies" . gnus-group-list-zombies) - ("matching" . gnus-group-list-matching) - ("post" . gnus-group-post-news) - ("mail" . gnus-group-mail) - ("local" . (lambda () (interactive) (gnus-group-news 0))) - ("rescan" . gnus-group-get-new-news) - ("browse-foreign" . gnus-group-browse-foreign) - ("exit" . gnus-group-exit))) - -(defvar gnus-carpal-summary-buffer-buttons - '("mark" - ("read" . gnus-summary-mark-as-read-forward) - ("tick" . gnus-summary-tick-article-forward) - ("clear" . gnus-summary-clear-mark-forward) - ("expirable" . gnus-summary-mark-as-expirable) - "move" - ("scroll" . gnus-summary-next-page) - ("next-unread" . gnus-summary-next-unread-article) - ("prev-unread" . gnus-summary-prev-unread-article) - ("first" . gnus-summary-first-unread-article) - ("best" . gnus-summary-best-unread-article) - "article" - ("headers" . gnus-summary-toggle-header) - ("uudecode" . gnus-uu-decode-uu) - ("enter-digest" . gnus-summary-enter-digest-group) - ("fetch-parent" . gnus-summary-refer-parent-article) - "mail" - ("move" . gnus-summary-move-article) - ("copy" . gnus-summary-copy-article) - ("respool" . gnus-summary-respool-article) - "threads" - ("lower" . gnus-summary-lower-thread) - ("kill" . gnus-summary-kill-thread) - "post" - ("post" . gnus-summary-post-news) - ("local" . gnus-summary-news-other-window) - ("mail" . gnus-summary-mail-other-window) - ("followup" . gnus-summary-followup-with-original) - ("reply" . gnus-summary-reply-with-original) - ("cancel" . gnus-summary-cancel-article) - "misc" - ("exit" . gnus-summary-exit) - ("fed-up" . gnus-summary-catchup-and-goto-next-group))) - -(defvar gnus-carpal-server-buffer-buttons - '(("add" . gnus-server-add-server) - ("browse" . gnus-server-browse-server) - ("list" . gnus-server-list-servers) - ("kill" . gnus-server-kill-server) - ("yank" . gnus-server-yank-server) - ("copy" . gnus-server-copy-server) - ("exit" . gnus-server-exit))) - -(defvar gnus-carpal-browse-buffer-buttons - '(("subscribe" . gnus-browse-unsubscribe-current-group) - ("exit" . gnus-browse-exit))) - -(defvar gnus-carpal-group-buffer "*Carpal Group*") -(defvar gnus-carpal-summary-buffer "*Carpal Summary*") -(defvar gnus-carpal-server-buffer "*Carpal Server*") -(defvar gnus-carpal-browse-buffer "*Carpal Browse*") - -(defvar gnus-carpal-attached-buffer nil) - -(defvar gnus-carpal-mode-hook nil - "*Hook run in carpal mode buffers.") - -(defvar gnus-carpal-button-face 'bold - "*Face used on carpal buttons.") - -(defvar gnus-carpal-header-face 'bold-italic - "*Face used on carpal buffer headers.") - -(defvar gnus-carpal-mode-map nil) -(put 'gnus-carpal-mode 'mode-class 'special) - -(if gnus-carpal-mode-map - nil - (setq gnus-carpal-mode-map (make-keymap)) - (suppress-keymap gnus-carpal-mode-map) - (define-key gnus-carpal-mode-map " " 'gnus-carpal-select) - (define-key gnus-carpal-mode-map "\r" 'gnus-carpal-select) - (define-key gnus-carpal-mode-map gnus-mouse-2 'gnus-carpal-mouse-select)) - -(defun gnus-carpal-mode () - "Major mode for clicking buttons. - -All normal editing commands are switched off. -\\ -The following commands are available: - -\\{gnus-carpal-mode-map}" - (interactive) - (kill-all-local-variables) - (setq mode-line-modified (cdr gnus-mode-line-modified)) - (setq major-mode 'gnus-carpal-mode) - (setq mode-name "Gnus Carpal") - (setq mode-line-process nil) - (use-local-map gnus-carpal-mode-map) - (buffer-disable-undo) - (setq buffer-read-only t) - (make-local-variable 'gnus-carpal-attached-buffer) - (gnus-run-mode-hooks 'gnus-carpal-mode-hook)) - -(defun gnus-carpal-setup-buffer (type) - (let ((buffer (symbol-value (intern (format "gnus-carpal-%s-buffer" type))))) - (if (get-buffer buffer) - () - (with-current-buffer (gnus-get-buffer-create buffer) - (gnus-carpal-mode) - (setq gnus-carpal-attached-buffer - (intern (format "gnus-%s-buffer" type))) - (let ((buttons (symbol-value - (intern (format "gnus-carpal-%s-buffer-buttons" - type)))) - (buffer-read-only nil) - button) - (while buttons - (setq button (car buttons) - buttons (cdr buttons)) - (if (stringp button) - (set-text-properties - (point) - (prog2 (insert button) (point) (insert " ")) - (list 'face gnus-carpal-header-face)) - (set-text-properties - (point) - (prog2 (insert (car button)) (point) (insert " ")) - (list 'gnus-callback (cdr button) - 'face gnus-carpal-button-face - gnus-mouse-face-prop 'highlight)))) - (let ((fill-column (- (window-width) 2))) - (fill-region (point-min) (point-max))) - (set-window-point (get-buffer-window (current-buffer)) - (point-min))))))) - -(defun gnus-carpal-select () - "Select the button under point." - (interactive) - (let ((func (get-text-property (point) 'gnus-callback))) - (if (null func) - () - (pop-to-buffer (symbol-value gnus-carpal-attached-buffer)) - (call-interactively func)))) - -(defun gnus-carpal-mouse-select (event) - "Select the button under the mouse pointer." - (interactive "e") - (mouse-set-point event) - (gnus-carpal-select)) - ;;; Allow redefinition of functions. (gnus-ems-redefine) diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el index 2b13f39ddb..b532b74045 100644 --- a/lisp/gnus/gnus-srvr.el +++ b/lisp/gnus/gnus-srvr.el @@ -301,9 +301,7 @@ The following commands are available: "Initialize the server buffer." (unless (get-buffer gnus-server-buffer) (with-current-buffer (gnus-get-buffer-create gnus-server-buffer) - (gnus-server-mode) - (when gnus-carpal - (gnus-carpal-setup-buffer 'server))))) + (gnus-server-mode)))) (defun gnus-server-prepare () (gnus-set-format 'server-mode) @@ -806,8 +804,6 @@ claim them." (funcall gnus-group-prepare-function gnus-level-killed 'ignore 1 'ignore)) (gnus-get-buffer-create gnus-browse-buffer) - (when gnus-carpal - (gnus-carpal-setup-buffer 'browse)) (gnus-configure-windows 'browse) (buffer-disable-undo) (let ((buffer-read-only nil)) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index c77fd1c4aa..a0e38d4f4f 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -474,6 +474,12 @@ If nil, each group will get its own article buffer." :group 'gnus-article-various :type 'boolean) +(defcustom gnus-widen-article-window nil + "If non-nil, selecting the article buffer will display only the article buffer." + :version "24.1" + :group 'gnus-article-various + :type 'boolean) + (defcustom gnus-break-pages t "*If non-nil, do page breaking on articles. The page delimiter is specified by the `gnus-page-delimiter' @@ -3493,8 +3499,6 @@ display only a single character." ;; Fix by Sudish Joseph (setq gnus-summary-buffer (set-buffer (gnus-get-buffer-create buffer))) (gnus-summary-mode group) - (when gnus-carpal - (gnus-carpal-setup-buffer 'summary)) (when (gnus-group-quit-config group) (set (make-local-variable 'gnus-single-article-buffer) nil)) (make-local-variable 'gnus-article-buffer) @@ -6935,7 +6939,11 @@ displayed, no centering will be performed." (error "There is no article buffer for this summary buffer") (unless (get-buffer-window gnus-article-buffer) (gnus-summary-show-article)) - (gnus-configure-windows 'article t) + (gnus-configure-windows + (if gnus-widen-article-window + 'only-article + 'article) + t) (select-window (get-buffer-window gnus-article-buffer)))) (defun gnus-summary-universal-argument (arg) diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index 26d6e2c08b..e4b8f8f87d 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -1602,7 +1602,11 @@ SPEC is a predicate specifier that contains stuff like `or', `and', initial-input history def) "Call standard `completing-read-function'." (let ((completion-styles gnus-completion-styles)) - (completing-read prompt collection nil require-match initial-input history def))) + (completing-read prompt + ;; Old XEmacs (at least 21.4) expect an alist for + ;; collection. + (mapcar 'list collection) + nil require-match initial-input history def))) (defun gnus-ido-completing-read (prompt collection &optional require-match initial-input history def) diff --git a/lisp/gnus/gnus-win.el b/lisp/gnus/gnus-win.el index df883769b7..809e4c339b 100644 --- a/lisp/gnus/gnus-win.el +++ b/lisp/gnus/gnus-win.el @@ -68,12 +68,10 @@ used to display Gnus windows." (defvar gnus-buffer-configuration '((group (vertical 1.0 - (group 1.0 point) - (if gnus-carpal '(group-carpal 4)))) + (group 1.0 point))) (summary (vertical 1.0 - (summary 1.0 point) - (if gnus-carpal '(summary-carpal 4)))) + (summary 1.0 point))) (article (cond (gnus-use-trees @@ -84,16 +82,13 @@ used to display Gnus windows." (t '(vertical 1.0 (summary 0.25 point) - (if gnus-carpal '(summary-carpal 4)) (article 1.0))))) (server (vertical 1.0 - (server 1.0 point) - (if gnus-carpal '(server-carpal 2)))) + (server 1.0 point))) (browse (vertical 1.0 - (browse 1.0 point) - (if gnus-carpal '(browse-carpal 2)))) + (browse 1.0 point))) (message (vertical 1.0 (message 1.0 point))) @@ -145,7 +140,6 @@ used to display Gnus windows." (pipe (vertical 1.0 (summary 0.25 point) - (if gnus-carpal '(summary-carpal 4)) ("*Shell Command Output*" 1.0))) (bug (vertical 1.0 @@ -189,10 +183,6 @@ See the Gnus manual for an explanation of the syntax used.") (edit-group . gnus-group-edit-buffer) (edit-form . gnus-edit-form-buffer) (edit-server . gnus-server-edit-buffer) - (group-carpal . gnus-carpal-group-buffer) - (summary-carpal . gnus-carpal-summary-buffer) - (server-carpal . gnus-carpal-server-buffer) - (browse-carpal . gnus-carpal-browse-buffer) (edit-score . gnus-score-edit-buffer) (message . gnus-message-buffer) (mail . gnus-message-buffer) diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 4a5f0f79d6..069596289e 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -1626,11 +1626,6 @@ slower." (function-item mail-extract-address-components) (function :tag "Other"))) -(defcustom gnus-carpal nil - "*If non-nil, display clickable icons." - :group 'gnus-meta - :type 'boolean) - (defcustom gnus-shell-command-separator ";" "String used to separate shell commands." :group 'gnus-files @@ -2803,7 +2798,7 @@ gnus-registry.el will populate this if it's loaded.") gnus-convert-image-to-gray-x-face gnus-convert-face-to-png gnus-face-from-file) ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree - gnus-tree-open gnus-tree-close gnus-carpal-setup-buffer) + gnus-tree-open gnus-tree-close) ("gnus-srvr" gnus-enter-server-buffer gnus-server-set-info gnus-server-server-name) ("gnus-srvr" gnus-browse-foreign-server) diff --git a/lisp/gnus/gravatar.el b/lisp/gnus/gravatar.el index d4dfb76316..50b0ba1d63 100644 --- a/lisp/gnus/gravatar.el +++ b/lisp/gnus/gravatar.el @@ -125,7 +125,8 @@ You can provide a list of argument to pass to CB in CBARGS." (if (plist-get status :error) ;; Error happened. (apply cb 'error cbargs) - (apply cb (gravatar-data->image) cbargs))) + (apply cb (gravatar-data->image) cbargs)) + (kill-buffer (current-buffer))) (provide 'gravatar) diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index d5a620b3b7..546f13af81 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -5736,7 +5736,9 @@ subscribed address (and not the additional To and Cc header contents)." (mapcar (lambda (rhs) (or (cadr (split-string rhs "@")) "")) (mapcar 'downcase (mapcar - 'cadr + (lambda (elem) + (or (cadr elem) + "")) (mail-extract-address-components field t)))))) ;; Note that `rhs' will be "" if the address does not have ;; the domain part, i.e., if it is a local user's address. diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el index 62e742f93a..188717e592 100644 --- a/lisp/gnus/mml-smime.el +++ b/lisp/gnus/mml-smime.el @@ -162,7 +162,7 @@ Whether the passphrase is cached at all is controlled by (and from (smime-get-key-by-email from))) (smime-get-key-by-email (gnus-completing-read "Sign this part with what signature" - smime-keys nil nil + (mapcar 'car smime-keys) nil nil nil (and (listp (car-safe smime-keys)) (caar smime-keys)))))))) @@ -221,7 +221,7 @@ Whether the passphrase is cached at all is controlled by (while (not done) (ecase (read (gnus-completing-read "Fetch certificate from" - '(("dns") ("ldap") ("file")) t nil nil + '("dns" "ldap" "file") t nil nil "ldap")) (dns (setq certs (append certs (mml-smime-get-dns-cert)))) diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 0aaa797b83..c3c25cbf19 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -316,7 +316,7 @@ textual parts.") (setq port (or nnimap-server-port "imap")) 'starttls)) '("imap")) - ((eq nnimap-stream 'ssl) + ((memq nnimap-stream '(ssl tls)) (open-tls-stream "*nnimap*" (current-buffer) nnimap-address (setq port @@ -324,7 +324,9 @@ textual parts.") (if (netrc-find-service-number "imaps") "imaps" "993")))) - '("143" "993" "imap" "imaps")))) + '("143" "993" "imap" "imaps")) + (t + (error "Unknown stream type: %s" nnimap-stream)))) connection-result login-result credentials) (setf (nnimap-process nnimap-object) (get-buffer-process (current-buffer))) @@ -424,7 +426,10 @@ textual parts.") result)) (deffoo nnimap-close-server (&optional server) - t) + (when (nnoo-change-server 'nnimap server nil) + (ignore-errors + (delete-process (get-buffer-process (nnimap-buffer)))) + t)) (deffoo nnimap-request-close () t) @@ -974,7 +979,7 @@ textual parts.") (nnimap-possibly-change-group nil server)) (with-current-buffer (nnimap-buffer) ;; Wait for the final data to trickle in. - (when (nnimap-wait-for-response (cadar sequences)) + (when (nnimap-wait-for-response (cadar sequences) t) ;; Now we should have all the data we need, no matter whether ;; we're QRESYNCING, fetching all the flags from scratch, or ;; just fetching the last 100 flags per group. @@ -1251,7 +1256,7 @@ textual parts.") (point-min)) t))) (when messagep - (message "Read %dKB" (/ (buffer-size) 1000))) + (message "nnimap read %dk" (/ (buffer-size) 1000))) (nnheader-accept-process-output process) (goto-char (point-max))) openp)) diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index de304bf216..baba9e0098 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el @@ -985,7 +985,7 @@ details on the language and supported extensions" (message "Searching %s..." group) (let ((arts 0) (result - (nnimap-command "UID SEARCH %s" + (nnimap-command "UID SEARCH %s" (if (string= criteria "") qstring (nnir-imap-make-query criteria qstring) diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el index c2c2c2ed28..59d7b784a1 100644 --- a/lisp/gnus/shr.el +++ b/lisp/gnus/shr.el @@ -30,6 +30,8 @@ ;;; Code: +(require 'browse-url) + (defgroup shr nil "Simple HTML Renderer" :group 'mail) @@ -57,6 +59,16 @@ fit these criteria." (defvar shr-width 70) +(defvar shr-map + (let ((map (make-sparse-keymap))) + (define-key map "a" 'shr-show-alt-text) + (define-key map "i" 'shr-browse-image) + (define-key map "I" 'shr-insert-image) + (define-key map "u" 'shr-copy-url) + (define-key map "v" 'shr-browse-url) + (define-key map "\r" 'shr-browse-url) + map)) + (defun shr-transform-dom (dom) (let ((result (list (pop dom)))) (dolist (arg (pop dom)) @@ -97,7 +109,9 @@ fit these criteria." (defun shr-ensure-paragraph () (unless (bobp) (if (bolp) - (unless (eql (char-after (- (point) 2)) ?\n) + (unless (save-excursion + (forward-line -1) + (looking-at " *$")) (insert "\n")) (if (save-excursion (beginning-of-line) @@ -129,17 +143,53 @@ fit these criteria." (defun shr-tag-a (cont) (let ((url (cdr (assq :href cont))) + (start (point)) shr-start) (shr-generic cont) (widget-convert-button - 'link shr-start (point) - :action 'shr-browse-url - :url url - :keymap widget-keymap - :help-echo url))) - -(defun shr-browse-url (widget &rest stuff) - (browse-url (widget-get widget :url))) + 'link (or shr-start start) (point) + :help-echo url) + (put-text-property (or shr-start start) (point) 'keymap shr-map) + (put-text-property (or shr-start start) (point) 'shr-url url))) + +(defun shr-browse-url () + "Browse the URL under point." + (interactive) + (let ((url (get-text-property (point) 'shr-url))) + (if (not url) + (message "No link under point") + (browse-url url)))) + +(defun shr-copy-url () + "Copy the URL under point to the kill ring. +If called twice, then try to fetch the URL and see whether it +redirects somewhere else." + (interactive) + (let ((url (get-text-property (point) 'shr-url))) + (cond + ((not url) + (message "No URL under point")) + ;; Resolve redirected URLs. + ((equal url (car kill-ring)) + (url-retrieve + url + (lambda (a) + (when (and (consp a) + (eq (car a) :redirect)) + (with-temp-buffer + (insert (cadr a)) + (goto-char (point-min)) + ;; Remove common tracking junk from the URL. + (when (re-search-forward ".utm_.*" nil t) + (replace-match "" t t)) + (message "Copied %s" (buffer-string)) + (copy-region-as-kill (point-min) (point-max))))))) + ;; Copy the URL to the kill ring. + (t + (with-temp-buffer + (insert url) + (copy-region-as-kill (point-min) (point-max)) + (message "Copied %s" url)))))) (defun shr-tag-img (cont) (when (and (> (current-column) 0) @@ -162,8 +212,28 @@ fit these criteria." (list (current-buffer) start (point-marker)) t))) (insert " ") + (put-text-property start (point) 'keymap shr-map) + (put-text-property start (point) 'shr-alt alt) + (put-text-property start (point) 'shr-image url) (setq shr-state 'image)))) +(defun shr-show-alt-text () + "Show the ALT text of the image under point." + (interactive) + (let ((text (get-text-property (point) 'shr-alt))) + (if (not text) + (message "No image under point") + (message "%s" text)))) + +(defun shr-browse-image () + "Browse the image under point." + (interactive) + (let ((url (get-text-property (point) 'shr-image))) + (if (not url) + (message "No image under point") + (message "Browsing %s..." url) + (browse-url url)))) + (defun shr-image-fetched (status buffer start end) (when (and (buffer-name buffer) (not (plist-get status :error))) @@ -222,7 +292,8 @@ fit these criteria." (defun shr-tag-blockquote (cont) (shr-ensure-paragraph) (let ((shr-indentation (+ shr-indentation 4))) - (shr-generic cont))) + (shr-generic cont)) + (shr-ensure-paragraph)) (defun shr-ensure-newline () (unless (zerop (current-column)) @@ -254,7 +325,7 @@ fit these criteria." (setq first nil) (when (and (bolp) (> shr-indentation 0)) - (insert (make-string shr-indentation ? ))) + (shr-indent)) ;; The shr-start is a special variable that is used to pass ;; upwards the first point in the buffer where the text really ;; starts. @@ -267,15 +338,20 @@ fit these criteria." (insert " ") (setq shr-state 'space)))))) +(defun shr-indent () + (insert (make-string shr-indentation ? ))) + (defun shr-get-image-data (url) "Get image data for URL. Return a string with image data." (with-temp-buffer (mm-disable-multibyte) - (url-cache-extract (url-cache-create-filename url)) - (when (or (search-forward "\n\n" nil t) - (search-forward "\r\n\r\n" nil t)) - (buffer-substring (point) (point-max))))) + (when (ignore-errors + (url-cache-extract (url-cache-create-filename url)) + t) + (when (or (search-forward "\n\n" nil t) + (search-forward "\r\n\r\n" nil t)) + (buffer-substring (point) (point-max)))))) (defvar shr-list-mode nil) @@ -328,6 +404,140 @@ Return a string with image data." (apply #'shr-fontize-cont cont types) (shr-ensure-paragraph)) +(defun shr-tag-table (cont) + (shr-ensure-paragraph) + (setq cont (or (cdr (assq 'tbody cont)) + cont)) + (let* ((columns (shr-column-specs cont)) + (suggested-widths (shr-pro-rate-columns columns)) + (sketch (shr-make-table cont suggested-widths)) + (sketch-widths (shr-table-widths sketch (length suggested-widths)))) + (shr-insert-table (shr-make-table cont sketch-widths t) sketch-widths))) + +(defun shr-insert-table (table widths) + (shr-insert-table-ruler widths) + (dolist (row table) + (let ((start (point)) + (height (let ((max 0)) + (dolist (column row) + (setq max (max max (cadr column)))) + max))) + (dotimes (i height) + (shr-indent) + (insert "|\n")) + (dolist (column row) + (goto-char start) + (let ((lines (split-string (nth 2 column) "\n"))) + (dolist (line lines) + (when (> (length line) 0) + (end-of-line) + (insert line "|") + (forward-line 1))) + ;; Add blank lines at padding at the bottom of the TD, + ;; possibly. + (dotimes (i (- height (length lines))) + (end-of-line) + (insert (make-string (length (car lines)) ? ) "|") + (forward-line 1))))) + (shr-insert-table-ruler widths))) + +(defun shr-insert-table-ruler (widths) + (shr-indent) + (insert "+") + (dotimes (i (length widths)) + (insert (make-string (aref widths i) ?-) ?+)) + (insert "\n")) + +(defun shr-table-widths (table length) + (let ((widths (make-vector length 0))) + (dolist (row table) + (let ((i 0)) + (dolist (column row) + (aset widths i (max (aref widths i) + (car column))) + (incf i)))) + widths)) + +(defun shr-make-table (cont widths &optional fill) + (let ((trs nil)) + (dolist (row cont) + (when (eq (car row) 'tr) + (let ((i 0) + (tds nil)) + (dolist (column (cdr row)) + (when (memq (car column) '(td th)) + (push (shr-render-td (cdr column) (aref widths i) fill) + tds) + (setq i (1+ i)))) + (push (nreverse tds) trs)))) + (nreverse trs))) + +(defun shr-render-td (cont width fill) + (with-temp-buffer + (let ((shr-width width) + (shr-indentation 0)) + (shr-generic cont)) + (while (re-search-backward "\n *$" nil t) + (delete-region (match-beginning 0) (match-end 0))) + (goto-char (point-min)) + (let ((max 0)) + (while (not (eobp)) + (end-of-line) + (setq max (max max (current-column))) + (forward-line 1)) + (when fill + (goto-char (point-min)) + (while (not (eobp)) + (end-of-line) + (when (> (- width (current-column)) 0) + (insert (make-string (- width (current-column)) ? ))) + (forward-line 1))) + (list max (count-lines (point-min) (point-max)) (buffer-string))))) + +(defun shr-pro-rate-columns (columns) + (let ((total-percentage 0) + (widths (make-vector (length columns) 0))) + (dotimes (i (length columns)) + (incf total-percentage (aref columns i))) + (setq total-percentage (/ 1.0 total-percentage)) + (dotimes (i (length columns)) + (aset widths i (max (truncate (* (aref columns i) + total-percentage + shr-width)) + 10))) + widths)) + +;; Return a summary of the number and shape of the TDs in the table. +(defun shr-column-specs (cont) + (let ((columns (make-vector (shr-max-columns cont) 1))) + (dolist (row cont) + (when (eq (car row) 'tr) + (let ((i 0)) + (dolist (column (cdr row)) + (when (memq (car column) '(td th)) + (let ((width (cdr (assq :width (cdr column))))) + (when (and width + (string-match "\\([0-9]+\\)%" width)) + (aset columns i + (/ (string-to-number (match-string 1 width)) + 100.0))))) + (setq i (1+ i)))))) + columns)) + +(defun shr-count (cont elem) + (let ((i 0)) + (dolist (sub cont) + (when (eq (car sub) elem) + (setq i (1+ i)))) + i)) + +(defun shr-max-columns (cont) + (let ((max 0)) + (dolist (row cont) + (when (eq (car row) 'tr) + (setq max (max max (shr-count (cdr row) 'td))))) + max)) + (provide 'shr) ;;; shr.el ends here diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el index e73444e85c..30e0ae58f0 100644 --- a/lisp/gnus/spam-report.el +++ b/lisp/gnus/spam-report.el @@ -256,6 +256,7 @@ This is initialized based on `user-mail-address'." 80)) (error "Could not open connection to %s" host)) (set-marker (process-mark tcp-connection) (point-min)) + (gnus-set-process-query-on-exit-flag tcp-connection nil) (process-send-string tcp-connection (format "GET %s HTTP/1.1\nUser-Agent: %s\nHost: %s\n\n" -- 2.20.1