Subject: bug#34374: 27.0.50; Outside an eww buffer, optionally use new buffer when calling eww instead of reusing *eww*

From: Göktuğ Kayaalp <[email-masked]>
Date: Fri, 08 Feb 2019 00:19:36 +0300

Eww should support conveniently avoiding using the same buffer even when
not in an eww buffer (M-x eww or browse-url).  Currently, in an eww
buffer, ‘eww-open-in-new-buffer’ opens the link under point in a new
buffer, and ‘eww’ reuses the buffer.  When running ‘eww’ outside an eww
buffer, it reuses the ‘*eww*’ buffer.  Attached is a patch where by
default this behaviour is retained, but when a new custom,
‘eww-reuse-buffer’ is truthy (defaults to nil), Eww uses a new buffer
(obtained via ‘generate-new-buffer’) instead, unless the current buffer
is an eww buffer.  The navigation behaviour in eww buffers is retained.

I have manually tested the general use of EWW with this patch applied.
But I haven’t found a test suite for EWW; if I missed it, I can run it,
or any other suggested testing.

In case the patch is good enough to apply as it is, I have my copyright
stuff sorted already.

All the best,
    -gk.

In GNU Emacs 27.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, Xaw3d scroll bars)
 of 2019-02-04 built on alpha
Repository revision: ef17247fe9cab2d59e470daad24314c868248b0a
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12003000
System Description: Debian GNU/Linux buster/sid

Recent messages:
Mark set [3 times]
Mark saved where search started
Mark set
Auto-saving...done
eww-reuse-buffer
Quit [5 times]
eww-reuse-buffer
Saving file /home/g/co/External/emacs/lisp/net/eww.el...
Wrote /home/g/co/External/emacs/lisp/net/eww.el
Finding changes in /home/g/co/External/emacs/lisp/net/eww.el...done
Quit
Configured using:
 'configure --prefix=/home/g/local/emacs --with-x-toolkit=athena
 --with-imagemagick --with-modules --with-file-notification=yes
 --with-gameuser=no --with-mailutils'

Configured features:
XAW3D XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS
GLIB NOTIFY INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT
LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS LUCID X11 XDBE XIM MODULES THREADS
LIBSYSTEMD JSON PDUMPER LCMS2 GMP

Important settings:
  value of $LC_MONETARY: tr_TR.UTF-8
  value of $LC_TIME: tr_TR.UTF-8
  value of $LANG: en_GB.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Diff

Minor modes in effect:
  auto-image-file-mode: t
  show-paren-mode: t
  gk-ucins-entry-mode: t
  global-gk-minor-mode: t
  gk-minor-mode: t
  yas-global-mode: t
  yas-minor-mode: t
  winner-mode: t
  global-whitespace-mode: t
  whitespace-mode: t
  which-key-mode: t
  save-place-mode: t
  persistent-scratch-autosave-mode: t
  global-paren-face-mode: t
  magit-todos-mode: t
  global-magit-file-mode: t
  url-handler-mode: t
  diff-auto-refine-mode: t
  global-git-commit-mode: t
  shell-dirtrack-mode: t
  eval-sexp-fu-flash-mode: t
  auto-insert-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-quote-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow mailalias mail-extr emacsbug dired-aux misearch multi-isearch
dabbrev eieio-opt speedbar sb-image ezimage dframe help-fns radix-tree
network-stream url-cache vc-filewise sh-script executable vc-git
org-rmail org-mhe org-irc org-info org-gnus nnir org-docview org-bibtex
bibtex org-bbdb org-w3m term disp-table ehelp image-file paren init
gk-feeds man emms-librefm-stream emms-librefm-scrobbler
emms-playlist-limit emms-volume emms-volume-amixer emms-i18n
emms-history emms-score emms-stream-info emms-metaplaylist-mode
emms-bookmarks emms-cue emms-mode-line-icon emms-browser sort
emms-playlist-sort emms-last-played emms-player-xine emms-player-mpd
emms-playing-time emms-lyrics emms-url emms-streams emms-show-all
emms-tag-editor emms-mark emms-mode-line emms-cache emms-info-opusinfo
emms-info-ogginfo emms-info-mp3info emms-info later-do
emms-playlist-mode emms-player-vlc emms-player-mpv emms-player-mplayer
emms-player-simple emms-source-playlist emms-source-file locate
ob-python ob-shell warnings ibuf-macs yasnippet elec-pair zencoding-mode
winner whole-line-or-region whitespace which-key wdired vc-rcs vc-cvs vc
vc-dispatcher tramp-cache tls gnutls time thinks spam spam-stat gnus-uu
yenc gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime dig
solarized color smtpmail sendmail scheme saveplace rmailsum
python-django tree-widget sql view python tramp-sh tramp tramp-loaddefs
trampver tramp-compat hippie-exp pixel-scroll persistent-scratch
perl-mode pdf-tools pdf-sync pdf-outline pdf-links pdf-isearch pdf-misc
pdf-view pdf-cache pdf-util pass-listing password-store paren-face
paredit ox-org ox-hugo ox-blackfriday ox-md ox-groff ox-beamer ox-odt
rng-loc rng-uri rng-parse rng-match rng-dt rng-util rng-pttrn nxml-parse
nxml-ns nxml-enc xmltok nxml-util ox-latex ox-icalendar ox-html table
ox-ascii ox-publish ox org-variable-pitch org-protocol org-mobile
org-agenda org-inlinetask org-eww org-checklist org-capture olivetti
nnfolder multiple-cursors mc-hide-unmatched-lines-mode
mc-separate-operations rectangular-region-mode mc-mark-pop mc-mark-more
mc-cycle-cursors mc-edit-lines multiple-cursors-core mastodon mairix
cus-edit cus-start cus-load magit-todos pcre2el rxt pcase re-builder
hl-todo async grep magit-bookmark magit-imenu git-rebase magit-extras
magit-ediff ediff-merg ediff-wind ediff-diff ediff-mult ediff-help
ediff-init ediff-util ediff magit-subtree magit-submodule magit-obsolete
magit-blame magit-stash magit-bisect magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-tag magit-merge
magit-branch magit-reset magit-collab ghub url-http url-gw nsm url-auth
let-alist magit-files magit-refs magit-status magit package url-handlers
magit-repos magit-apply magit-wip magit-log magit-diff smerge-mode
diff-mode magit-core magit-autorevert autorevert filenotify
magit-process magit-margin magit-mode ls-lisp lua-mode lorem-ipsum js
sgml-mode inf-ruby ruby-mode smie inf-lisp imenu image-dired ido
ibuffer-vc ibuf-ext ibuffer ibuffer-loaddefs hl-line
highlight-parentheses goto-last-change gnus-sum gnus-group gnus-undo
gnus-start gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo
parse-time gnus-spec gnus-int gnus-range gnus-win gk-unilat gk-greek
quail git-commit with-editor cl-extra server magit-git magit-section
magit-utils magit-popup log-edit pcvs-util add-log forecast subr-x
org-element org org-macro org-footnote org-pcomplete org-list org-faces
org-entities noutline outline easy-mmode org-version ob-emacs-lisp ob
ob-tangle org-src ob-ref ob-lob ob-table ob-keys ob-exp ob-comint
ob-core ob-eval org-compat org-macs org-loaddefs solar cal-dst ffap
face-remap f eww mm-url gnus nnheader evil evil-keybindings
evil-integration evil-maps evil-commands reveal flyspell ispell
evil-jumps evil-command-window evil-types evil-search evil-ex shell
pcomplete evil-macros evil-repeat evil-states evil-core evil-common
windmove evil-digraphs evil-vars edmacro kmacro eval-sexp-fu rx
highlight etags multifile xref project epa-mail emms-setup emms
emms-compat elfeed-show elfeed-search wid-edit message rmc format-spec
rfc822 mml mml-sec epa epg epg-config gnus-util rmail rmail-loaddefs
mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util
ietf-drums mail-prsvr mail-utils gmm-utils mailheader shr
text-property-search puny svg dom elfeed-csv elfeed elfeed-curl url
url-proxy url-privacy url-expand url-methods url-history url-cookie
url-domsuf mailcap elfeed-log elfeed-db elfeed-lib url-util time-date
avl-tree generator url-queue url-parse url-vars xml-query xml eimp
dollar doc-view jka-compr image-mode dired-x dired-subtree dired-narrow
delsel dired-hacks-utils dired dired-loaddefs diminish diff desktop
frameset debug backtrace find-func dart-mode s ucs-normalize help-mode
dash copyright compile comint ring cc-mode cc-fonts cc-guess cc-menus
cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs cal-menu calendar
cal-loaddefs browse-url boxquote rect bookmark pp bibliothek derived
goto-addr thingatpt pdf-info tq a bbdb-vcard bbdb-com crm mailabbrev
vcard bbdb easymenu bbdb-site timezone autoinsert auth-source eieio
eieio-core cl-macs eieio-loaddefs password-cache json map seq byte-opt
bytecomp byte-compile cconv apropos ansi-color ace-jump-mode advice cl
gv cl-seq cl-loaddefs cl-lib mule-util tooltip eldoc electric uniquify
ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow isearch timer select
scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932
hebrew greek romanian slovak czech european ethiopic indian cyrillic
chinese composite charscript charprop case-table epa-hook jka-cmpr-hook
help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote threads dbusbind inotify lcms2 dynamic-setting
system-font-setting font-render-setting x-toolkit x multi-tty
make-network-process emacs)

Memory information:
((conses 16 1132574 122251)
 (symbols 48 54836 160)
 (strings 32 248082 22021)
 (string-bytes 1 17577942)
 (vectors 16 107140)
 (vector-slots 8 1980171 171906)
 (floats 8 1038 502)
 (intervals 56 61571 2996)
 (buffers 992 40))

>From dd47aa509a7f7d7548e4c048e42e7dc32a12fbe9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C4=B0=2E=20G=C3=B6ktu=C4=9F=20Kayaalp?= <[email-masked]>
Date: Thu, 7 Feb 2019 14:33:08 +0300
Subject: [PATCH] Support not reusing *eww* buffer when navigating from a
 non-eww one
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/net/eww.el (eww-reuse-buffer): New defcustom.
* lisp/net/eww.el (eww): Use the above to decide whether to use
‘get-buffer-create’ or ‘generate-new-buffer’.
* doc/misc/eww.texi (Basics):
* etc/NEWS: Document the new feature.
---
 doc/misc/eww.texi |  8 +++++++-
 etc/NEWS          |  6 ++++++
 lisp/net/eww.el   | 17 +++++++++++++++--
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi
index b299ea1fb7..cc96909ab3 100644
--- a/doc/misc/eww.texi
+++ b/doc/misc/eww.texi
@@ -98,10 +98,16 @@ Basics
 (@code{eww-copy-page-url}) will copy the current URL to the kill ring.
 
 @findex eww-open-in-new-buffer
+@vindex eww-reuse-buffer
 @kindex M-RET
   The @kbd{M-@key{RET}} command (@code{eww-open-in-new-buffer}) opens the
 URL at point in a new EWW buffer, akin to opening a link in a new
-``tab'' in other browsers.
+``tab'' in other browsers.  If you want this same behavior when
+following links or running @code{eww} in a buffer that is not in
+@code{eww-mode}, set @code{eww-reuse-buffer} to @code{nil}.  Normal
+navigation within an @code{eww-mode} buffer will not be affected, but
+running @kbd{M-x eww} or following a URI with @code{browse-url} family
+of functions will result in new eww buffers.
 
 @findex eww-readable
 @kindex R
diff --git a/etc/NEWS b/etc/NEWS
index 72a6b385a8..5dc4c8b8b2 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -652,6 +652,12 @@ has been executed.
 If set, shr will not render tags with attribute 'aria-hidden="true"'.
 This attribute is meant to tell screen readers to ignore a tag.
 
++++
+*** New option 'eww-reuse-buffer'.
+If set (default), eww will reuse the "*eww*" buffer when called from a
+non-eww buffer.  If not, it will generate a new buffer and use it
+instead.
+
 ** Htmlfontify
 
 *** The functions 'hfy-color', 'hfy-color-vals' and
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 3b7d9d5c2f..2ac4c606de 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -153,6 +153,12 @@ eww-form-checkbox-symbol
                  (const "☐")            ; Unicode BALLOT BOX
                  string))
 
+(defcustom eww-reuse-buffer t
+  "Reuse the *eww* buffer when not in an `eww-mode' buffer."
+  :version "27.1"
+  :group 'eww
+  :type 'boolean)
+
 (defface eww-form-submit
   '((((type x w32 ns) (class color))	; Like default mode line
      :box (:line-width 2 :style released-button)
@@ -250,7 +256,12 @@ eww-suggested-uris
 (defun eww (url)
   "Fetch URL and render the page.
 If the input doesn't look like an URL or a domain name, the
-word(s) will be searched for via `eww-search-prefix'."
+word(s) will be searched for via `eww-search-prefix'.
+
+When the current buffer is not in `eww-mode', if
+`eww-reuse-buffer' is non-nil, the *eww* buffer will be reused if
+available, otherwise generated; if set to nil instead, a new
+buffer will be used in case *eww* is already in use."
   (interactive
    (let* ((uris (eww-suggested-uris))
 	  (prompt (concat "Enter URL or keywords"
@@ -261,7 +272,9 @@ eww
   (pop-to-buffer-same-window
    (if (eq major-mode 'eww-mode)
        (current-buffer)
-     (get-buffer-create "*eww*")))
+     (funcall
+      (if eww-reuse-buffer #'get-buffer-create #'generate-new-buffer)
+      "*eww*")))
   (eww-setup-buffer)
   ;; Check whether the domain only uses "Highly Restricted" Unicode
   ;; IDNA characters.  If not, transform to punycode to indicate that
-- 
2.20.1