branch: elpa/casual
commit c13dcf78ea345b0f7abcb2c8317b5b880270a506
Merge: 6787b1bb42 e0b3e68ffa
Author: Charles Choi <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #363 from kickingvegas/299-build-casual-eww
Add EWW support
---
docs/casual.info | Bin 148783 -> 153025 bytes
docs/casual.org | 2 +
docs/eww.org | 104 ++++++++++++
docs/html.org | 2 +-
docs/images/casual-eww-bookmarks-screenshot.png | Bin 0 -> 42926 bytes
docs/images/casual-eww-display-screenshot.png | Bin 0 -> 43366 bytes
docs/images/casual-eww-screenshot.png | Bin 0 -> 131453 bytes
docs/images/casual-eww-settings-screenshot.png | Bin 0 -> 77441 bytes
docs/images/casual-eww-unicode-screenshot.png | Bin 0 -> 76178 bytes
lisp/Makefile | 7 +-
lisp/Makefile-eww.make | 31 ++++
lisp/casual-eww-settings.el | 143 ++++++++++++++++
lisp/casual-eww-utils.el | 123 ++++++++++++++
lisp/casual-eww.el | 180 +++++++++++++++++++++
lisp/casual.el | 5 +-
templates/tests/casual-MODULE-test-utils.el | 2 +-
templates/tests/test-casual-MODULE-settings.el | 2 +-
templates/tests/test-casual-MODULE-utils.el | 2 +-
templates/tests/test-casual-MODULE.el | 2 +-
tests/Makefile | 5 +
.../casual-eww-test-utils.el | 16 +-
tests/test-casual-eww-settings.el | 66 ++++++++
tests/test-casual-eww-utils.el | 97 +++++++++++
tests/test-casual-eww.el | 126 +++++++++++++++
24 files changed, 900 insertions(+), 15 deletions(-)
diff --git a/docs/casual.info b/docs/casual.info
index 7393869b73..2b2678bd8a 100644
Binary files a/docs/casual.info and b/docs/casual.info differ
diff --git a/docs/casual.org b/docs/casual.org
index 8020e8c72d..975a94d1eb 100644
--- a/docs/casual.org
+++ b/docs/casual.org
@@ -155,6 +155,7 @@ Configuration of a particular Casual user interface is
performed per mode. Go to
- [[#editkit-install][EditKit]]
- [[#elisp-install][Elisp]]
- [[#eshell-install][Eshell]]
+- [[#eww-install][EWW]]
- [[#help-install][Help]]
- [[#html-install][HTML]]
- [[#ibuffer-install][IBuffer]]
@@ -271,6 +272,7 @@ The following modes are supported by Casual:
#+INCLUDE: "./editkit.org" :minlevel 2
#+INCLUDE: "./elisp.org" :minlevel 2
#+INCLUDE: "./eshell.org" :minlevel 2
+#+INCLUDE: "./eww.org" :minlevel 2
#+INCLUDE: "./help.org" :minlevel 2
#+INCLUDE: "./html.org" :minlevel 2
#+INCLUDE: "./ibuffer.org" :minlevel 2
diff --git a/docs/eww.org b/docs/eww.org
new file mode 100644
index 0000000000..f152ae9f4e
--- /dev/null
+++ b/docs/eww.org
@@ -0,0 +1,104 @@
+* EWW
+#+CINDEX: EWW
+#+VINDEX: casual-eww-tmenu
+
+Casual EWW is a user interface for Emacs Web Wowser ([[info:eww#Top]]), a web
browser that runs inside Emacs.
+
+[[file:images/casual-eww-screenshot.png]]
+
+** EWW Install
+:PROPERTIES:
+:CUSTOM_ID: eww-install
+:END:
+
+#+CINDEX: EWW Install
+
+In your initialization file, bind the Transient ~casual-eww-tmenu~ to your key
binding of preference.
+
+#+begin_src elisp :lexical no
+ (keymap-set eww-mode-map "C-o" #'casual-eww-tmenu)
+#+end_src
+
+Do so similarly to access ~casual-eww-bookmarks-tmenu~ in the EWW bookmarks
list.
+
+#+begin_src elisp :lexical no
+ (keymap-set eww-bookmark-mode-map "C-o" #'casual-eww-bookmarks-tmenu)
+#+end_src
+
+While not mandatory, the following bindings can make the EWW keymaps
consistent with those used by Casual.
+
+#+BEGIN_SRC elisp :lexical no
+ (keymap-set eww-mode-map "C-o" #'casual-eww-tmenu)
+ (keymap-set eww-mode-map "C-c C-o" #'eww-browse-with-external-browser)
+ (keymap-set eww-mode-map "j" #'shr-next-link)
+ (keymap-set eww-mode-map "k" #'shr-previous-link)
+ (keymap-set eww-mode-map "[" #'eww-previous-url)
+ (keymap-set eww-mode-map "]" #'eww-next-url)
+ (keymap-set eww-mode-map "M-]" #'eww-forward-url)
+ (keymap-set eww-mode-map "M-[" #'eww-back-url)
+ (keymap-set eww-mode-map "n" #'casual-lib-browse-forward-paragraph)
+ (keymap-set eww-mode-map "p" #'casual-lib-browse-backward-paragraph)
+ (keymap-set eww-mode-map "P" #'casual-eww-backward-paragraph-link)
+ (keymap-set eww-mode-map "N" #'casual-eww-forward-paragraph-link)
+ (keymap-set eww-mode-map "M-l" #'eww)
+
+ (keymap-set eww-bookmark-mode-map "C-o" #'casual-eww-bookmarks-tmenu)
+ (keymap-set eww-bookmark-mode-map "p" #'previous-line)
+ (keymap-set eww-bookmark-mode-map "n" #'next-line)
+ (keymap-set eww-bookmark-mode-map "<double-mouse-1>" #'eww-bookmark-browse)
+#+END_SRC
+
+** EWW Usage
+#+CINDEX: EWW Usage
+
+In an EWW window, invoke ~casual-eww-tmenu~ as shown below.
+
+[[file:images/casual-eww-screenshot.png]]
+
+The following sections are offered in the menu:
+
+- History :: Commands for historical navigation.
+
+- Document :: Commands for document navigation (~<link rel="">~) provided the
HTML pages support it.
+ HTML generated from Texinfo ([[info:texinfo#Top]]) supports these commands.
+
+- Navigate :: Commands to navigate within a page.
+
+- Link :: Commands to navigate links within a page.
+
+- Misc :: Miscellaneous commands.
+
+- URL :: Commands associated with the current web page.
+
+- EWW Bookmarks :: Commands associated with EWW bookmarks.
+
+#+TEXINFO: @subheading EWW Settings
+#+VINDEX: casual-eww-settings-tmenu
+
+Customize common EWW settings from this menu. These settings can be persisted
to be used across restarts of Emacs.
+
+[[file:images/casual-eww-settings-screenshot.png]]
+
+
+#+TEXINFO: @subheading EWW Display
+#+VINDEX: casual-eww-display-tmenu
+
+This menu (~casual-eww-display-tmenu~) provides commands to toggle different
display attributes of a web page.
+
+[[file:images/casual-eww-display-screenshot.png]]
+
+
+#+TEXINFO: @subheading EWW Bookmarks
+#+VINDEX: casual-eww-bookmarks-tmenu
+
+This menu (~casual-eww-bookmarks-tmenu~) provides commands for managing the
EWW bookmark list.
+
+[[file:images/casual-eww-bookmarks-screenshot.png]]
+
+Note that the EWW bookmarks list has a very limited feature set.
+
+#+TEXINFO: @subheading EWW Unicode Symbol Support
+
+By enabling “{{{kbd(u)}}} Use Unicode Symbols” from the Settings menu, Casual
EWW will use Unicode symbols as appropriate in its menus.
+
+[[file:images/casual-eww-unicode-screenshot.png]]
diff --git a/docs/html.org b/docs/html.org
index 9862c4240e..1188573f1f 100644
--- a/docs/html.org
+++ b/docs/html.org
@@ -26,7 +26,7 @@ In your initialization file, bind the Transient
~casual-html-tmenu~ to your key
A different binding ({{{kbd(M-m)}}}) is used as ~casual-html-tmenu~ is
intended to work alongside with [[#editkit-install][Casual EditKit]].
-It is convenient to also bind ~casual-html-tag-tmenu~ as well.
+It is convenient to also bind ~casual-html-tags-tmenu~ as well.
#+begin_src elisp :lexical no
(keymap-set html-mode-map "C-c m" #'casual-html-tags-tmenu)
diff --git a/docs/images/casual-eww-bookmarks-screenshot.png
b/docs/images/casual-eww-bookmarks-screenshot.png
new file mode 100644
index 0000000000..328614462e
Binary files /dev/null and b/docs/images/casual-eww-bookmarks-screenshot.png
differ
diff --git a/docs/images/casual-eww-display-screenshot.png
b/docs/images/casual-eww-display-screenshot.png
new file mode 100644
index 0000000000..7714977b8f
Binary files /dev/null and b/docs/images/casual-eww-display-screenshot.png
differ
diff --git a/docs/images/casual-eww-screenshot.png
b/docs/images/casual-eww-screenshot.png
new file mode 100644
index 0000000000..4c6b583ca8
Binary files /dev/null and b/docs/images/casual-eww-screenshot.png differ
diff --git a/docs/images/casual-eww-settings-screenshot.png
b/docs/images/casual-eww-settings-screenshot.png
new file mode 100644
index 0000000000..070ac37779
Binary files /dev/null and b/docs/images/casual-eww-settings-screenshot.png
differ
diff --git a/docs/images/casual-eww-unicode-screenshot.png
b/docs/images/casual-eww-unicode-screenshot.png
new file mode 100644
index 0000000000..9864627585
Binary files /dev/null and b/docs/images/casual-eww-unicode-screenshot.png
differ
diff --git a/lisp/Makefile b/lisp/Makefile
index 68310df6a0..555678feb4 100644
--- a/lisp/Makefile
+++ b/lisp/Makefile
@@ -1,5 +1,5 @@
##
-# Copyright (C) 2024-2025 Charles Y. Choi
+# Copyright (C) 2024-2026 Charles Y. Choi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@ ediff-tests \
editkit-tests \
elisp-tests \
eshell-tests \
+eww-tests \
help-tests \
html-tests \
ibuffer-tests \
@@ -98,6 +99,10 @@ elisp-tests:
eshell-tests:
$(MAKE) -C $(SRC_DIR) -f Makefile-eshell.make tests
+.PHONY: eww-tests
+eww-tests:
+ $(MAKE) -C $(SRC_DIR) -f Makefile-eww.make tests
+
.PHONY: help-tests
help-tests:
$(MAKE) -C $(SRC_DIR) -f Makefile-help.make tests
diff --git a/lisp/Makefile-eww.make b/lisp/Makefile-eww.make
new file mode 100644
index 0000000000..7ff4b138b6
--- /dev/null
+++ b/lisp/Makefile-eww.make
@@ -0,0 +1,31 @@
+##
+# Copyright (C) 2026 Charles Y. Choi
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+include Makefile--defines.make
+
+PACKAGE_NAME=casual-eww
+ELISP_INCLUDES=casual-eww-utils.el \
+casual-eww-settings.el
+ELISP_PACKAGES=
+ELISP_TEST_INCLUDES=casual-eww-test-utils.el
+PACKAGE_PATHS= \
+-L $(EMACS_ELPA_DIR)/compat-current \
+-L $(EMACS_ELPA_DIR)/seq-current \
+-L $(EMACS_ELPA_DIR)/transient-current \
+-L $(EMACS_ELPA_DIR)/cond-let-current \
+-L $(CASUAL_LIB_LISP_DIR)
+
+include Makefile--rules.make
diff --git a/lisp/casual-eww-settings.el b/lisp/casual-eww-settings.el
new file mode 100644
index 0000000000..2ed56e1394
--- /dev/null
+++ b/lisp/casual-eww-settings.el
@@ -0,0 +1,143 @@
+;;; casual-eww-settings.el --- Casual EWW Settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+
+;;; Code:
+(require 'eww)
+(require 'casual-lib)
+
+(transient-define-prefix casual-eww-settings-tmenu ()
+ "Casual EWW settings menu."
+ ["Casual EWW: Settings"
+
+ ["Browsing"
+ ("r" "Retrieve Command" casual-eww--customize-retrieve-command)
+ ("R" "Readable URLs" casual-eww--customize-readable-urls)
+ ("h" "History Limit" casual-eww--customize-history-limit
+ :description (lambda () (format "History Limit (%d)" eww-history-limit)))]
+
+ ["Directory"
+ ("d" "Download" casual-eww--customize-download-directory
+ :description (lambda () (format "Directory (%s)"
(eww--download-directory))))
+ ("b" "Bookmarks" casual-eww--customize-bookmarks-directory
+ :description (lambda () (format "Directory (%s)"
eww-bookmarks-directory)))]
+
+ ["Display"
+ ("f" "Use Fonts" casual-eww--customize-shr-use-fonts
+ :description (lambda () (casual-lib-checkbox-label
+ shr-use-fonts "Use Fonts"))
+ :transient t)
+ ("c" "Use Colors" casual-eww--customize-shr-use-colors
+ :description (lambda () (casual-lib-checkbox-label
+ shr-use-colors "Use Colors"))
+ :transient t)
+ ("i" "Inhibit Images" casual-eww--customize-shr-inhibit-images
+ :description (lambda () (casual-lib-checkbox-label
+ shr-inhibit-images "Inhibit Images"))
+ :transient t)]]
+
+ ["General"
+ :class transient-row
+ (casual-lib-customize-unicode)
+ (casual-lib-customize-hide-navigation)]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ ("a" "About" casual-eww-about :transient nil)
+ ("G" "EWW Group" casual-eww--customize-group)
+ (casual-lib-quit-all)])
+
+(defun casual-eww--customize-group ()
+ "Customize EWW group."
+ (interactive)
+ (customize-group "eww"))
+
+(defun casual-eww--customize-retrieve-command ()
+ "Customize `eww-retrieve-commmand'."
+ (interactive)
+ (customize-variable 'eww-retrieve-command))
+
+(defun casual-eww--customize-readable-urls ()
+ "Customize `eww-readable-urls'."
+ (interactive)
+ (customize-variable 'eww-readable-urls))
+
+(defun casual-eww--customize-download-directory ()
+ "Customize `eww-download-directory'."
+ (interactive)
+ (customize-variable 'eww-download-directory))
+
+(defun casual-eww--customize-bookmarks-directory ()
+ "Customize `eww-bookmarks-directory'."
+ (interactive)
+ (customize-variable 'eww-bookmarks-directory))
+
+(defun casual-eww--customize-history-limit ()
+ "Customize `eww-history-limit'."
+ (interactive)
+ (customize-variable 'eww-history-limit))
+
+(defun casual-eww--customize-shr-use-fonts ()
+ "Customize `shr-use-fonts'."
+ (interactive)
+ (customize-variable 'shr-use-fonts))
+
+(defun casual-eww--customize-shr-use-colors ()
+ "Customize `shr-use-colors'."
+ (interactive)
+ (customize-variable 'shr-use-colors))
+
+(defun casual-eww--customize-shr-inhibit-images ()
+ "Customize `shr-inhibit-images'."
+ (interactive)
+ (customize-variable 'shr-inhibit-images))
+
+(defun casual-eww-about-eww ()
+ "Casual EWW is a Transient menu for Emacs Web Wowser (EWW).
+
+Learn more about using Casual EWW at our discussion group on GitHub.
+Any questions or comments about it should be made there.
+URL `https://github.com/kickingvegas/casual/discussions'
+
+If you find a bug or have an enhancement request, please file an issue.
+Our best effort will be made to answer it.
+URL `https://github.com/kickingvegas/casual/issues'
+
+If you enjoy using Casual EWW, consider making a modest financial
+contribution to help support its development and maintenance.
+URL `https://www.buymeacoffee.com/kickingvegas'
+
+Casual EWW was conceived and crafted by Charles Choi in San Francisco,
+California.
+
+Thank you for using Casual EWW.
+
+Always choose love."
+ (ignore))
+
+(defun casual-eww-about ()
+ "About information for Casual EWW."
+ (interactive)
+ (describe-function #'casual-eww-about-eww))
+
+(provide 'casual-eww-settings)
+;;; casual-eww-settings.el ends here
diff --git a/lisp/casual-eww-utils.el b/lisp/casual-eww-utils.el
new file mode 100644
index 0000000000..49babdbcba
--- /dev/null
+++ b/lisp/casual-eww-utils.el
@@ -0,0 +1,123 @@
+;;; casual-eww-utils.el --- Casual EWW Utils -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+
+;;; Code:
+(require 'eww)
+(require 'casual-lib)
+
+(defconst casual-eww-unicode-db
+ '((:history-back . '("❬" "Back"))
+ (:history-forward . '("❭" "Forward"))
+ (:previous . '("↑" "Previous"))
+ (:next . '("↓" "Next"))
+ (:backward-paragraph . '("¶↑" "Previous ¶"))
+ (:forward-paragraph . '("¶↓" "Next ¶"))
+ (:forward . '("→" "Forward"))
+ (:back . '("←" "Back"))
+ (:link . '("🔗" "Link"))
+ (:top . '("⤒" "Top"))
+ (:history . '("≣" "History"))
+ (:page . '("📄" "Page"))
+ (:scroll-up . '("📄↓" "Scroll Up"))
+ (:scroll-down . '("📄↑" "Scroll Down"))
+ (:follow . '("🚀" "Follow"))
+ (:paragraph . '("¶" "Paragraph"))
+ (:beginning-of-buffer . '("⇱" "Beginning"))
+ (:end-of-buffer . '("⇲" "End"))
+ (:reload . '("⟳" "Reload"))
+ (:kill . '("×" "Close"))
+ (:see-also . '("👀" "See Also")))
+
+ "Unicode symbol DB to use for eww Transient menus.")
+
+(defun casual-eww-unicode-get (key)
+ "Lookup Unicode symbol for KEY in DB.
+
+- KEY symbol used to lookup Unicode symbol in DB.
+
+If the value of customizable variable `casual-lib-use-unicode'
+is non-nil, then the Unicode symbol is returned, otherwise a
+plain ASCII-range string."
+ (casual-lib-unicode-db-get key casual-eww-unicode-db))
+
+(defun casual-eww-info ()
+ "Open Info for Emacs Web Wowser (EWW)."
+ (interactive) (info "(eww) Top"))
+
+
+;; -------------------------------------------------------------------
+;;; Commands
+(defun casual-eww-forward-paragraph-link ()
+ "Move point to first link in next paragraph."
+ (interactive)
+ (casual-lib-browse-forward-paragraph)
+ (shr-next-link))
+
+(defun casual-eww-backward-paragraph-link ()
+ "Move point to first link in previous paragraph."
+ (interactive)
+
+ (let ((current-line-number (line-number-at-pos)))
+ (backward-paragraph)
+ (if (= current-line-number (line-number-at-pos))
+ (backward-paragraph))
+ (shr-next-link)))
+
+
+;; -------------------------------------------------------------------
+;;; Transients
+
+(transient-define-prefix casual-eww-display-tmenu ()
+ "Transient menu for EWW display controls.
+
+Note that only the runtime value of variables is changed. Commands in
+`casual-eww-settings-tmenu' will persistently change a variable's value."
+ ["Casual EWW Display"
+ ("f" "Use Fonts" eww-toggle-fonts
+ :description (lambda () (casual-lib-checkbox-label shr-use-fonts "Use
Fonts"))
+ :transient t)
+ ("c" "Use Colors" eww-toggle-colors
+ :description (lambda () (casual-lib-checkbox-label shr-use-colors "Use
Colors"))
+ :transient t)
+ ("i" "Use Images" eww-toggle-images
+ :description (lambda () (casual-lib-checkbox-label shr-inhibit-images
"Inhibit Images"))
+ :transient t)
+ ("d" "Use Direction" eww-toggle-paragraph-direction
+ :description (lambda ()
+ (format
+ "¶ direction (%s)"
+ (cond
+ ((eq bidi-paragraph-direction 'left-to-right) "L→R")
+ ((eq bidi-paragraph-direction 'right-to-left) "R←L")
+ ((not bidi-paragraph-direction) "Auto")
+ (t "Undefined"))))
+ :transient t)]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ (casual-lib-quit-all)])
+
+
+
+(provide 'casual-eww-utils)
+;;; casual-eww-utils.el ends here
diff --git a/lisp/casual-eww.el b/lisp/casual-eww.el
new file mode 100644
index 0000000000..6113d85a4d
--- /dev/null
+++ b/lisp/casual-eww.el
@@ -0,0 +1,180 @@
+;;; casual-eww.el --- Transient UI for EWW -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides a Transient-based user interface for EWW, a web
browser
+;; for GNU Emacs.
+
+;; INSTALLATION
+
+;; In your initialization file, bind the Transient `casual-eww-tmenu' to your
+;; key binding of preference.
+
+;; (require 'casual-eww) ; optional if using autoloaded menu
+;; (keymap-set eww-mode-map "C-o" #'casual-eww-tmenu)
+
+;; Do so similarly to access `casual-eww-bookmarks-tmenu' in the EWW bookmarks
+;; list.
+
+;; (keymap-set eww-bookmark-mode-map "C-o" #'casual-eww-bookmarks-tmenu)
+
+;; While not mandatory, the following bindings can make the EWW keymaps
+;; consistent with those used by Casual.
+
+;; (keymap-set eww-mode-map "C-o" #'casual-eww-tmenu)
+;; (keymap-set eww-mode-map "C-c C-o" #'eww-browse-with-external-browser)
+;; (keymap-set eww-mode-map "j" #'shr-next-link)
+;; (keymap-set eww-mode-map "k" #'shr-previous-link)
+;; (keymap-set eww-mode-map "[" #'eww-previous-url)
+;; (keymap-set eww-mode-map "]" #'eww-next-url)
+;; (keymap-set eww-mode-map "M-]" #'eww-forward-url)
+;; (keymap-set eww-mode-map "M-[" #'eww-back-url)
+;; (keymap-set eww-mode-map "n" #'casual-lib-browse-forward-paragraph)
+;; (keymap-set eww-mode-map "p" #'casual-lib-browse-backward-paragraph)
+;; (keymap-set eww-mode-map "P" #'casual-eww-backward-paragraph-link)
+;; (keymap-set eww-mode-map "N" #'casual-eww-forward-paragraph-link)
+;; (keymap-set eww-mode-map "M-l" #'eww)
+;; (keymap-set eww-bookmark-mode-map "C-o" #'casual-eww-bookmarks-tmenu)
+;; (keymap-set eww-bookmark-mode-map "p" #'previous-line)
+;; (keymap-set eww-bookmark-mode-map "n" #'next-line)
+;; (keymap-set eww-bookmark-mode-map "<double-mouse-1>" #'eww-bookmark-browse)
+
+;;; Code:
+(require 'bookmark)
+(require 'casual-eww-settings)
+(require 'casual-eww-utils)
+
+;;;###autoload (autoload 'casual-eww-tmenu "casual-eww" nil t)
+(transient-define-prefix casual-eww-tmenu ()
+ "Transient menu for EWW.
+
+EWW (Emacs Web Wowser) is a web browser for GNU Emacs.
+
+See Info node `(eww)Top' for more information on it."
+ :refresh-suffixes t
+ ["Casual EWW"
+ ["History"
+ :pad-keys t
+ ("M-[" "❬" eww-back-url
+ :description (lambda () (casual-eww-unicode-get :history-back))
+ :transient t)
+ ("M-]" "❭" eww-forward-url
+ :description (lambda () (casual-eww-unicode-get :history-forward))
+ :transient t)
+ ("H" "History" eww-list-histories
+ :description (lambda () (casual-eww-unicode-get :history))
+ :transient nil)]
+
+ ["Document"
+ ("[" "←" eww-previous-url
+ :description (lambda () (casual-eww-unicode-get :back))
+ :transient t)
+ ("]" "→" eww-next-url
+ :description (lambda () (casual-eww-unicode-get :forward))
+ :transient t)
+ ("^" "↑" eww-up-url
+ :description (lambda () (casual-eww-unicode-get :previous))
+ :transient t)
+ ("t" "⤒" eww-top-url
+ :description (lambda () (casual-eww-unicode-get :top))
+ :transient t)]
+
+ ["Navigate"
+ :pad-keys t
+ ("p" "↑ ¶" casual-lib-browse-backward-paragraph
+ :description (lambda () (casual-eww-unicode-get :backward-paragraph))
+ :transient t)
+ ("n" "↓ ¶" casual-lib-browse-forward-paragraph
+ :description (lambda () (casual-eww-unicode-get :forward-paragraph))
+ :transient t)
+ ("SPC" "↓ 📄" scroll-up-command
+ :description (lambda () (casual-eww-unicode-get :scroll-up))
+ :transient t)
+ ("S-SPC" "↑ 📄" scroll-down-command
+ :description (lambda () (casual-eww-unicode-get :scroll-down))
+ :transient t)]
+
+ ["🔗"
+ :description (lambda () (casual-eww-unicode-get :link))
+ :pad-keys t
+ ("k" "↑" shr-previous-link
+ :description (lambda () (casual-eww-unicode-get :previous))
+ :transient t)
+ ("j" "↓" shr-next-link
+ :description (lambda () (casual-eww-unicode-get :next))
+ :transient t)
+ ("RET" "🚀" eww-follow-link
+ :description (lambda () (casual-eww-unicode-get :follow))
+ :transient t)]
+
+ ["Misc"
+ :pad-keys t
+ ("D" "Display›" casual-eww-display-tmenu)
+ ("R" "Readable" eww-readable)]]
+
+ ["URL"
+ :pad-keys t
+ [("M-l" "Open…" eww)
+ ("&" "Open External…" eww-browse-with-external-browser)]
+ [("c" "Copy" eww-copy-page-url)
+ ("A" "Copy Alt" eww-copy-alternate-url)]
+ [("d" "Download" eww-download)
+ ("g" "Reload" eww-reload
+ :description (lambda () (casual-eww-unicode-get :reload)))]]
+
+ ["EWW Bookmarks"
+ :class transient-row
+ ("b" "Add" eww-add-bookmark)
+ ("B" "List" eww-list-bookmarks)
+ ("M-n" "Next" eww-next-bookmark :transient t)
+ ("M-p" "Previous" eww-previous-bookmark :transient t)]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ ("," "Settings›" casual-eww-settings-tmenu)
+ ("I" "ⓘ" casual-eww-info)
+ ("J" "Jump to Bookmark…" bookmark-jump)
+ ("q" "Quit" quit-window)
+ (casual-lib-quit-all)])
+
+;;;###autoload (autoload 'casual-eww-bookmarks-tmenu "casual-eww" nil t)
+(transient-define-prefix casual-eww-bookmarks-tmenu ()
+ "Transient menu for EWW bookmarks."
+ :refresh-suffixes t
+
+ ["Casual EWW Bookmarks"
+ ["Bookmark"
+ :pad-keys t
+ ("k" "Kill" eww-bookmark-kill :transient t)
+ ("y" "Yank" eww-bookmark-yank :transient t)
+ ("RET" "Browse" eww-bookmark-browse)]
+
+ ["Navigate"
+ ("p" "Previous" previous-line :transient t)
+ ("n" "Next" next-line :transient t)]]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ ("q" "Quit" quit-window)
+ (casual-lib-quit-all)])
+
+(provide 'casual-eww)
+;;; casual-eww.el ends here
diff --git a/lisp/casual.el b/lisp/casual.el
index 381e8b4965..bc4ac867d9 100644
--- a/lisp/casual.el
+++ b/lisp/casual.el
@@ -1,6 +1,6 @@
;;; casual.el --- Transient user interfaces for various modes -*-
lexical-binding: t; -*-
-;; Copyright (C) 2024-2025 Charles Y. Choi
+;; Copyright (C) 2024-2026 Charles Y. Choi
;; Author: Charles Choi <[email protected]>
;; URL: https://github.com/kickingvegas/casual
@@ -74,6 +74,9 @@
;; An interface for Eshell, a shell-like command interpreter implemented in
;; Emacs Lisp.
+;; - EWW (Elisp library: `casual-eww.el')
+;; An interface for EWW (Emacs Web Wowser), a web browser for GNU Emacs.
+
;; - Help (Elisp library: `casual-help.el')
;; An interface for `help-mode', a major mode for viewing help text and
;; navigating references in it.
diff --git a/templates/tests/casual-MODULE-test-utils.el
b/templates/tests/casual-MODULE-test-utils.el
index 7d9c847e21..aea22cdad6 100644
--- a/templates/tests/casual-MODULE-test-utils.el
+++ b/templates/tests/casual-MODULE-test-utils.el
@@ -1,6 +1,6 @@
;;; casual-$MODULE-test-utils.el --- Casual Test Utils -*-
lexical-binding: t; -*-
-;; Copyright (C) 2025 Charles Y. Choi
+;; Copyright (C) 2026 Charles Y. Choi
;; Author: Charles Choi <[email protected]>
;; Keywords: tools
diff --git a/templates/tests/test-casual-MODULE-settings.el
b/templates/tests/test-casual-MODULE-settings.el
index a5b55b8ba4..fd7ad1589f 100644
--- a/templates/tests/test-casual-MODULE-settings.el
+++ b/templates/tests/test-casual-MODULE-settings.el
@@ -1,6 +1,6 @@
;;; test-casual-$MODULE-settings.el --- Casual Make Settings Tests -*-
lexical-binding: t; -*-
-;; Copyright (C) 2025 Charles Y. Choi
+;; Copyright (C) 2026 Charles Y. Choi
;; Author: Charles Choi <[email protected]>
;; Keywords: tools
diff --git a/templates/tests/test-casual-MODULE-utils.el
b/templates/tests/test-casual-MODULE-utils.el
index 8b36bb9993..765c1353bc 100644
--- a/templates/tests/test-casual-MODULE-utils.el
+++ b/templates/tests/test-casual-MODULE-utils.el
@@ -1,6 +1,6 @@
;;; test-casual-$MODULE-utils.el --- Casual Make Utils Tests -*-
lexical-binding: t; -*-
-;; Copyright (C) 2025 Charles Y. Choi
+;; Copyright (C) 2026 Charles Y. Choi
;; Author: Charles Choi <[email protected]>
;; Keywords: tools
diff --git a/templates/tests/test-casual-MODULE.el
b/templates/tests/test-casual-MODULE.el
index fa47476676..7a74f2aa18 100644
--- a/templates/tests/test-casual-MODULE.el
+++ b/templates/tests/test-casual-MODULE.el
@@ -1,6 +1,6 @@
;;; test-casual-$MODULE.el --- Casual Make Tests -*- lexical-binding: t; -*-
-;; Copyright (C) 2025 Charles Y. Choi
+;; Copyright (C) 2026 Charles Y. Choi
;; Author: Charles Choi <[email protected]>
;; Keywords: tools
diff --git a/tests/Makefile b/tests/Makefile
index f6c53f514d..4db64c8be5 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -31,6 +31,7 @@ ediff-tests \
editkit-tests \
elisp-tests \
eshell-tests \
+eww-tests \
help-tests \
html-tests \
ibuffer-tests \
@@ -57,6 +58,7 @@ ediff-tests \
editkit-tests \
elisp-tests \
eshell-tests \
+eww-tests \
help-tests \
html-tests \
ibuffer-tests \
@@ -109,6 +111,9 @@ elisp-tests:
eshell-tests:
$(MAKE) -C $(SRC_DIR) $@
+eww-tests:
+ $(MAKE) -C $(SRC_DIR) $@
+
help-tests:
$(MAKE) -C $(SRC_DIR) $@
diff --git a/templates/tests/casual-MODULE-test-utils.el
b/tests/casual-eww-test-utils.el
similarity index 70%
copy from templates/tests/casual-MODULE-test-utils.el
copy to tests/casual-eww-test-utils.el
index 7d9c847e21..b8ee8cb649 100644
--- a/templates/tests/casual-MODULE-test-utils.el
+++ b/tests/casual-eww-test-utils.el
@@ -1,6 +1,6 @@
-;;; casual-$MODULE-test-utils.el --- Casual Test Utils -*-
lexical-binding: t; -*-
+;;; casual-eww-test-utils.el --- Casual Test Utils -*- lexical-binding:
t; -*-
-;; Copyright (C) 2025 Charles Y. Choi
+;; Copyright (C) 2026 Charles Y. Choi
;; Author: Charles Choi <[email protected]>
;; Keywords: tools
@@ -27,13 +27,13 @@
(require 'casual-lib)
(require 'kmacro)
-(defun casualt-$MODULE-setup ()
- "Casual $MODULE setup."
+(defun casualt-eww-setup ()
+ "Casual eww setup."
)
-(defun casualt-$MODULE-breakdown ()
- "Casual $MODULE breakdown."
+(defun casualt-eww-breakdown ()
+ "Casual eww breakdown."
)
-(provide 'casual-$MODULE-test-utils)
-;;; casual-$MODULE-test-utils.el ends here
+(provide 'casual-eww-test-utils)
+;;; casual-eww-test-utils.el ends here
diff --git a/tests/test-casual-eww-settings.el
b/tests/test-casual-eww-settings.el
new file mode 100644
index 0000000000..b6b2d2d3ec
--- /dev/null
+++ b/tests/test-casual-eww-settings.el
@@ -0,0 +1,66 @@
+;;; test-casual-eww-settings.el --- Casual Make Settings Tests -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'ert)
+(require 'casual-eww-test-utils)
+(require 'casual-eww-settings)
+
+(ert-deftest test-casual-eww-settings-tmenu ()
+ (let ()
+ (cl-letf ((casualt-mock #'casual-eww--customize-retrieve-command)
+ (casualt-mock #'casual-eww--customize-readable-urls)
+ (casualt-mock #'casual-eww--customize-history-limit)
+ (casualt-mock #'casual-eww--customize-download-directory)
+ (casualt-mock #'casual-eww--customize-bookmarks-directory)
+ (casualt-mock #'casual-eww--customize-shr-use-fonts)
+ (casualt-mock #'casual-eww--customize-shr-use-colors)
+ (casualt-mock #'casual-eww--customize-shr-inhibit-images)
+ (casualt-mock #'casual-eww--customize-group)
+ (casualt-mock #'casual-eww-about))
+
+ (let ((test-vectors
+ '((:binding "r" :command casual-eww--customize-retrieve-command)
+ (:binding "R" :command casual-eww--customize-readable-urls)
+ (:binding "h" :command casual-eww--customize-history-limit)
+ (:binding "d" :command casual-eww--customize-download-directory)
+ (:binding "b" :command
casual-eww--customize-bookmarks-directory)
+ (:binding "f" :command casual-eww--customize-shr-use-fonts)
+ (:binding "c" :command casual-eww--customize-shr-use-colors)
+ (:binding "i" :command casual-eww--customize-shr-inhibit-images)
+ (:binding "G" :command casual-eww--customize-group)
+ (:binding "u" :command
casual-lib-customize-casual-lib-use-unicode)
+ (:binding "n" :command
casual-lib-customize-casual-lib-hide-navigation)
+ (:binding "a" :command casual-eww-about))))
+
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-eww-settings-tmenu
+ '(lambda () (random 5000)))))))
+
+(ert-deftest test-casual-eww-about ()
+ (should (stringp (casual-eww-about))))
+
+(provide 'test-casual-eww-settings)
+;;; test-casual-eww-setttings.el ends here
diff --git a/tests/test-casual-eww-utils.el b/tests/test-casual-eww-utils.el
new file mode 100644
index 0000000000..bcc82be22a
--- /dev/null
+++ b/tests/test-casual-eww-utils.el
@@ -0,0 +1,97 @@
+;;; test-casual-eww-utils.el --- Casual Make Utils Tests -*- lexical-binding:
t; -*-
+
+;; Copyright (C) 2026 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'ert)
+(require 'casual-eww-test-utils)
+(require 'casual-eww-utils)
+
+(ert-deftest test-casual-eww-unicode-get ()
+ (let ((casual-lib-use-unicode nil))
+ (should (string-equal (casual-eww-unicode-get :history-back) "Back"))
+ (should (string-equal (casual-eww-unicode-get :history-forward) "Forward"))
+ (should (string-equal (casual-eww-unicode-get :previous) "Previous"))
+ (should (string-equal (casual-eww-unicode-get :next) "Next"))
+ (should (string-equal (casual-eww-unicode-get :forward-paragraph) "Next
¶"))
+ (should (string-equal (casual-eww-unicode-get :backward-paragraph)
"Previous ¶"))
+ (should (string-equal (casual-eww-unicode-get :forward) "Forward"))
+ (should (string-equal (casual-eww-unicode-get :back) "Back"))
+ (should (string-equal (casual-eww-unicode-get :link) "Link"))
+ (should (string-equal (casual-eww-unicode-get :top) "Top"))
+ (should (string-equal (casual-eww-unicode-get :history) "History"))
+ (should (string-equal (casual-eww-unicode-get :page) "Page"))
+ (should (string-equal (casual-eww-unicode-get :scroll-up) "Scroll Up"))
+ (should (string-equal (casual-eww-unicode-get :scroll-down) "Scroll Down"))
+ (should (string-equal (casual-eww-unicode-get :follow) "Follow"))
+ (should (string-equal (casual-eww-unicode-get :paragraph) "Paragraph"))
+ (should (string-equal (casual-eww-unicode-get :beginning-of-buffer)
"Beginning"))
+ (should (string-equal (casual-eww-unicode-get :end-of-buffer) "End"))
+ (should (string-equal (casual-eww-unicode-get :reload) "Reload"))
+ (should (string-equal (casual-eww-unicode-get :kill) "Close"))
+ (should (string-equal (casual-eww-unicode-get :see-also) "See Also")))
+
+ (let ((casual-lib-use-unicode t))
+ (should (string-equal (casual-eww-unicode-get :history-back) "❬"))
+ (should (string-equal (casual-eww-unicode-get :history-forward) "❭"))
+ (should (string-equal (casual-eww-unicode-get :previous) "↑"))
+ (should (string-equal (casual-eww-unicode-get :next) "↓"))
+ (should (string-equal (casual-eww-unicode-get :forward-paragraph) "¶↓"))
+ (should (string-equal (casual-eww-unicode-get :backward-paragraph) "¶↑"))
+ (should (string-equal (casual-eww-unicode-get :forward) "→"))
+ (should (string-equal (casual-eww-unicode-get :back) "←"))
+ (should (string-equal (casual-eww-unicode-get :link) "🔗"))
+ (should (string-equal (casual-eww-unicode-get :top) "⤒"))
+ (should (string-equal (casual-eww-unicode-get :history) "≣"))
+ (should (string-equal (casual-eww-unicode-get :page) "📄"))
+ (should (string-equal (casual-eww-unicode-get :scroll-up) "📄↓"))
+ (should (string-equal (casual-eww-unicode-get :scroll-down) "📄↑"))
+ (should (string-equal (casual-eww-unicode-get :follow) "🚀"))
+ (should (string-equal (casual-eww-unicode-get :paragraph) "¶"))
+ (should (string-equal (casual-eww-unicode-get :beginning-of-buffer) "⇱"))
+ (should (string-equal (casual-eww-unicode-get :end-of-buffer) "⇲"))
+ (should (string-equal (casual-eww-unicode-get :reload) "⟳"))
+ (should (string-equal (casual-eww-unicode-get :kill) "×"))
+ (should (string-equal (casual-eww-unicode-get :see-also) "👀"))))
+
+(ert-deftest test-casual-eww-display-tmenu ()
+ (let ((tmpfile "casual-eww-display-tmenu.txt"))
+ (casualt-eww-setup)
+ (cl-letf ((casualt-mock #'eww-toggle-fonts)
+ (casualt-mock #'eww-toggle-colors)
+ (casualt-mock #'eww-toggle-images)
+ (casualt-mock #'eww-toggle-paragraph-direction))
+
+ (let ((test-vectors
+ '((:binding "f" :command eww-toggle-fonts)
+ (:binding "c" :command eww-toggle-colors)
+ (:binding "i" :command eww-toggle-images)
+ (:binding "d" :command eww-toggle-paragraph-direction))))
+
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-eww-display-tmenu
+ '(lambda () (random 5000)))))
+ (casualt-eww-breakdown)))
+
+(provide 'test-casual-eww-utils)
+;;; test-casual-eww-utils.el ends here
diff --git a/tests/test-casual-eww.el b/tests/test-casual-eww.el
new file mode 100644
index 0000000000..20c856bd7b
--- /dev/null
+++ b/tests/test-casual-eww.el
@@ -0,0 +1,126 @@
+;;; test-casual-eww.el --- Casual Make Tests -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'ert)
+(require 'casual-eww-test-utils)
+(require 'casual-lib-test-utils)
+(require 'casual-eww)
+
+(ert-deftest test-casual-eww-tmenu ()
+ (let ()
+ (casualt-eww-setup)
+
+ (cl-letf (
+ (casualt-mock #'eww-back-url)
+ (casualt-mock #'eww-forward-url)
+ (casualt-mock #'eww-list-histories)
+ (casualt-mock #'eww-previous-url)
+ (casualt-mock #'eww-next-url)
+ (casualt-mock #'eww-up-url)
+ (casualt-mock #'eww-top-url)
+ (casualt-mock #'casual-lib-browse-backward-paragraph)
+ (casualt-mock #'casual-lib-browse-forward-paragraph)
+ (casualt-mock #'scroll-up-command)
+ (casualt-mock #'scroll-down-command)
+ (casualt-mock #'shr-previous-link)
+ (casualt-mock #'shr-next-link)
+ (casualt-mock #'eww-follow-link)
+ (casualt-mock #'casual-eww-display-tmenu)
+ (casualt-mock #'eww-readable)
+ (casualt-mock #'eww)
+ (casualt-mock #'eww-browse-with-external-browser)
+ (casualt-mock #'eww-copy-page-url)
+ (casualt-mock #'eww-copy-alternate-url)
+ (casualt-mock #'eww-download)
+ (casualt-mock #'eww-reload)
+ (casualt-mock #'eww-add-bookmark)
+ (casualt-mock #'eww-list-bookmarks)
+ (casualt-mock #'eww-next-bookmark)
+ (casualt-mock #'eww-previous-bookmark)
+ (casualt-mock #'casual-eww-settings-tmenu)
+ (casualt-mock #'casual-eww-info)
+ (casualt-mock #'quit-window))
+
+ (let ((test-vectors
+ '((:binding "M-[" :command eww-back-url)
+ (:binding "M-]" :command eww-forward-url)
+ (:binding "H" :command eww-list-histories)
+ (:binding "[" :command eww-previous-url)
+ (:binding "]" :command eww-next-url)
+ (:binding "^" :command eww-up-url)
+ (:binding "t" :command eww-top-url)
+ (:binding "p" :command casual-lib-browse-backward-paragraph)
+ (:binding "n" :command casual-lib-browse-forward-paragraph)
+ (:binding "SPC" :command scroll-up-command)
+ (:binding "S-SPC" :command scroll-down-command)
+ (:binding "k" :command shr-previous-link)
+ (:binding "j" :command shr-next-link)
+ (:binding "RET" :command eww-follow-link)
+ (:binding "D" :command casual-eww-display-tmenu)
+ (:binding "R" :command eww-readable)
+ (:binding "M-l" :command eww)
+ (:binding "&" :command eww-browse-with-external-browser)
+ (:binding "c" :command eww-copy-page-url)
+ (:binding "A" :command eww-copy-alternate-url)
+ (:binding "d" :command eww-download)
+ (:binding "g" :command eww-reload)
+ (:binding "b" :command eww-add-bookmark)
+ (:binding "B" :command eww-list-bookmarks)
+ (:binding "M-n" :command eww-next-bookmark)
+ (:binding "M-p" :command eww-previous-bookmark)
+ (:binding "," :command casual-eww-settings-tmenu)
+ (:binding "I" :command casual-eww-info)
+ (:binding "q" :command quit-window))))
+
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-eww-tmenu
+ '(lambda () (random 5000)))))
+ (casualt-eww-breakdown)))
+
+
+(ert-deftest test-casual-eww-bookmarks-tmenu ()
+ (let ((tmpfile "casual-eww-bookmarks-tmenu.txt"))
+ (casualt-eww-setup)
+ (cl-letf ((casualt-mock #'eww-bookmark-kill)
+ (casualt-mock #'eww-bookmark-yank)
+ (casualt-mock #'eww-bookmark-browse)
+ (casualt-mock #'previous-line)
+ (casualt-mock #'next-line))
+
+ (let ((test-vectors
+ '((:binding "k" :command eww-bookmark-kill)
+ (:binding "y" :command eww-bookmark-yank)
+ (:binding "RET" :command eww-bookmark-browse)
+ (:binding "p" :command previous-line)
+ (:binding "n" :command next-line))))
+
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-eww-bookmarks-tmenu
+ '(lambda () (random 5000)))))
+ (casualt-eww-breakdown)))
+
+(provide 'test-casual-eww)
+;;; test-casual-eww.el ends here