From d82541199719314b29b75126b7ff4d8bd86086ac Mon Sep 17 00:00:00 2001 From: Mats Lidell Date: Sat, 18 Jul 2026 15:44:53 +0200 Subject: [PATCH 01/10] Update hypb:in-string-p test --- test/hypb-tests.el | 194 ++++++++++++++++++++++++++++++++------------- 1 file changed, 140 insertions(+), 54 deletions(-) diff --git a/test/hypb-tests.el b/test/hypb-tests.el index 4cf70846..b9756144 100644 --- a/test/hypb-tests.el +++ b/test/hypb-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 5-Apr-21 at 18:53:10 -;; Last-Mod: 16-Jul-26 at 17:06:05 by Mats Lidell +;; Last-Mod: 19-Jul-26 at 18:07:00 by Mats Lidell ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -85,62 +85,148 @@ See Emacs bug#74042 related to usage of texi2any." (hy-test-helpers:kill-buffer "*info*"))) (ert-deftest hypb--in-string-p () - "Verify basic quote handing by `hypb:in-string-p'." - (let ((s '(("\"str\"" . text-mode) ;; double-quotes: - ("'str'" . python-mode) ;; Python single-quotes: - ("'''str'''" . python-mode) ;; Python triple single-quotes: - ("\"\"\"str\"\"\"" . python-mode) ;; Python triple double-quotes: - ("``str''" . texinfo-mode))) ;; Texinfo open and close quotes: - (test-num 0) - str - mode) + "Verify basic quote handling by `hypb:in-string-p'. +Verify with and without caching." + (dolist (v '(nil t)) + (let ((s '((" \"str\" " . text-mode) ;; double-quotes: + (" 'str' " . python-mode) ;; Python single-quotes: + (" '''str''' " . python-mode) ;; Python triple single-quotes: + (" \"\"\"str\"\"\" " . python-mode) ;; Python triple double-quotes: + (" ``str'' " . texinfo-mode))) ;; Texinfo open and close quotes: + (test-num 0) + str + mode + (hypb:in-string-cache-disable v)) + (with-temp-buffer + (dolist (v s) + (setq str (car v) + mode (cdr v)) + (erase-buffer) + (funcall mode) + (insert str) + (let ((pos 0) + (response-list '(nil nil nil nil t t t nil nil nil nil))) + (dolist (response response-list) + (setq pos (1+ pos)) + (goto-char pos) + (if (not response) + (progn + (ert-info ((format "Test #%d: At pos %d, char '%c', expected not within \"%s\" in mode: %s" + test-num (point) (char-after (point)) str mode)) + (should-not (hypb:in-string-p)))) + (ert-info ((format "Test #%d: At pos %d, expected within \"%s\" in mode: %s" + test-num (point) str mode)) + (should (hypb:in-string-p)) + (let ((seq (hypb:in-string-p nil t))) + (should (sequencep seq)) + (cl-destructuring-bind (val beg end) seq + (should (stringp val)) + (should (and beg end (= (- end beg) 3)))))))))))))) + +;; hypb:in-string-p tests with multiple strings +;; 'one string with "double \"quoted\" nested" that \' \' ends here'. +(defun hypb--gen-response-list (prefix q1 swq q2 suffix) + "Generate a response list from the prefix, suffix and string with quotes." + (append (make-list (length prefix) nil) + (make-list (length q1) nil) ;; Starting quote regarded as outside quote + (make-list (length swq) t) + (make-list (length q2) t) ;; Ending quote regarded as inside quote + (make-list (length suffix) nil))) + +(ert-deftest hypb--in-string-p--strings-with-quotes () + "Verify that strings containing quotes are identified. +The test string is built by concatenating prefix, mode-start-quote, +string-with-quotes, mode-end-quote, and suffix. Points within prefix +and suffix are checked to be outside of the string. Points within +string-with-quotes is checked to be inside of the string. For each test +string a list of mode settings that are applicable for that test string +are tried. If `hypb:in-string-p' is expected to see point as within +string is generated by `hypb--gen-response-list'." + (let ((prefix " pre ") + (suffix " suff ") + (mode-list '((txt . (text-mode "\"" "\"")) + (py1 . (python-mode "'" "'")) + (py2 . (python-mode "'''" "'''")) + (py3 . (python-mode "\"\"\"" "\"\"\"")) + (tex . (texinfo-mode "``" "''")))) + (swq-list + '(("word" . (txt py1 py2 py3 tex)) + ("wo'rd" . (txt py2 py3 tex)) + ("wo\"rd" . (py1 py2 py3 tex)) + (" \\\"quoted string\\\" " . (txt py1 py2 py3 tex)) + ("\\\"quoted string\\\"" . (txt py1 py2 py3 tex)) + (" \\\"quoted ' string\\\" " . (txt py2 py3 tex)) + (" 'quoted \\\" string' " . (txt py2 py3 tex)) + (" 'quoted string' " . (txt py2 py3 tex)) + (" 'quoted \\\"in quotes\\\" string' " . (txt py2 py3 tex)) + ("'quoted string'" . (txt py2 py3 tex)) + ("'quoted \\\"in quotes\\\" string'" . (txt py2 py3 tex)))) + (test-num 0)) (with-temp-buffer - (dolist (v s) - (setq str (car v) - mode (cdr v)) - (erase-buffer) - (funcall mode) - (insert str) - (goto-char (/ (length str) 2)) - (ert-info ((format "Test #%d: At pos %d, expected within \"%s\" in mode: %s" - test-num (point) str mode)) - (should (hypb:in-string-p)) - (let ((seq (hypb:in-string-p nil t))) - (should (sequencep seq)) - (cl-destructuring-bind (val beg end) seq - (should (stringp val)) - (should (and beg end (= (- end beg) 3)))))))))) + (dolist (swq-word swq-list) + (let ((swq (car swq-word)) + (modes (cdr swq-word))) + (dolist (m modes) + (let* ((mode (nth 0 (alist-get m mode-list))) + (quote1 (nth 1 (alist-get m mode-list))) + (quote2 (nth 2 (alist-get m mode-list))) + (s (concat prefix quote1 swq quote2 suffix))) + (setq test-num (1+ test-num)) + (erase-buffer) + (funcall mode) + (insert s) + (let ((pos 0) + (response-list (hypb--gen-response-list prefix quote1 swq quote2 suffix))) + (dolist (response response-list) + (setq pos (1+ pos)) + (goto-char pos) + (if (not response) + (progn + (ert-info ((format "Test #%d: At pos %d, char '%c', expected not within >|%s|< in mode: %s" + test-num (point) (char-after (point)) s mode)) + (should-not (hypb:in-string-p)))) + (ert-info ((format "Test #%d: At pos %d, char '%c', expected within >|%s|< in mode: %s" + test-num (point) (char-after (point)) s mode)) + (should (hypb:in-string-p)) + (let ((seq (hypb:in-string-p nil t))) + (should (sequencep seq)) + (cl-destructuring-bind (val beg end) seq + (should (stringp val)) + (should (and beg end (= (- end beg) (length swq))))))))))))))))) (ert-deftest hypb--in-string-p--max-lines () - "Verify max lines handling by `hypb:in-string-p'." - (let* ((str "1\n\\\"2\n") - (range (list str 2 8))) - (with-temp-buffer - (insert (format "\"%s\"" str)) - (goto-line 1) (move-to-column 1) - ;; First line. Line starts with quote. - (should-not (hypb:in-string-p 1)) - (should (hypb:in-string-p 2)) - (should (hypb:in-string-p 3)) - (should (hypb:in-string-p 99)) - - ;; With range-flag - (should (equal range (hypb:in-string-p 2 t))) - (should (equal range (hypb:in-string-p 3 t))) - (should (equal range (hypb:in-string-p 99 t))) - - ;; Zero max-lines - (should-not (hypb:in-string-p 0)) - - ;; Second line. No quote on the line. - (goto-line 2) - (should-not (hypb:in-string-p 1)) - (should (hypb:in-string-p 2)) - (should (hypb:in-string-p 3)) - - ;; With range-flag - (should (equal range (hypb:in-string-p 2 t))) - (should (equal range (hypb:in-string-p 3 t)))))) + "Verify max lines handling by `hypb:in-string-p'. +Verify with and without caching." + (dolist (v '(nil t)) + (let* ((str "1\n\\\"2\n") + (range (list str 2 8)) + (hypb:in-string-cache-disable v)) + (with-temp-buffer + (insert (format "\"%s\"" str)) + (goto-line 1) (move-to-column 1) + ;; First line. Line starts with quote. + (should-not (hypb:in-string-p 1)) + (should (hypb:in-string-p 2)) + (should (hypb:in-string-p 3)) + (should (hypb:in-string-p 99)) + + ;; With range-flag + (should (equal range (hypb:in-string-p 2 t))) + (should (equal range (hypb:in-string-p 3 t))) + (should (equal range (hypb:in-string-p 99 t))) + + ;; Zero max-lines + (should-not (hypb:in-string-p 0)) + + ;; Second line. No quote on the line. + (goto-line 2) + (should-not (hypb:in-string-p 1)) + (should (hypb:in-string-p 2)) + (should (hypb:in-string-p 3)) + + ;; With range-flag + (should (equal range (hypb:in-string-p 2 t))) + (should (equal range (hypb:in-string-p 3 t))))))) (ert-deftest hypb--string-count-matches () "Verify `hypb--string-count-matches'." From c0509a99e9b94124dc18aa1d45a62e6edbdc1e73 Mon Sep 17 00:00:00 2001 From: Mats Lidell Date: Mon, 20 Jul 2026 00:19:41 +0200 Subject: [PATCH 02/10] Review comment --- test/hypb-tests.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/hypb-tests.el b/test/hypb-tests.el index b9756144..eeb58e96 100644 --- a/test/hypb-tests.el +++ b/test/hypb-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 5-Apr-21 at 18:53:10 -;; Last-Mod: 19-Jul-26 at 18:07:00 by Mats Lidell +;; Last-Mod: 20-Jul-26 at 00:18:36 by Mats Lidell ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -182,10 +182,10 @@ string is generated by `hypb--gen-response-list'." (goto-char pos) (if (not response) (progn - (ert-info ((format "Test #%d: At pos %d, char '%c', expected not within >|%s|< in mode: %s" + (ert-info ((format "Test #%d: At pos %d, char '%c', expected outside string text >|%s|< in mode: %s" test-num (point) (char-after (point)) s mode)) (should-not (hypb:in-string-p)))) - (ert-info ((format "Test #%d: At pos %d, char '%c', expected within >|%s|< in mode: %s" + (ert-info ((format "Test #%d: At pos %d, char '%c', expected inside string text >|%s|< in mode: %s" test-num (point) (char-after (point)) s mode)) (should (hypb:in-string-p)) (let ((seq (hypb:in-string-p nil t))) From 6d77cbfc23d4902fff4cba9c0352e357136a53b5 Mon Sep 17 00:00:00 2001 From: Mats Lidell Date: Mon, 20 Jul 2026 00:24:57 +0200 Subject: [PATCH 03/10] Fix the other place too --- test/hypb-tests.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/hypb-tests.el b/test/hypb-tests.el index eeb58e96..ff9b9935 100644 --- a/test/hypb-tests.el +++ b/test/hypb-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 5-Apr-21 at 18:53:10 -;; Last-Mod: 20-Jul-26 at 00:18:36 by Mats Lidell +;; Last-Mod: 20-Jul-26 at 00:24:21 by Mats Lidell ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -111,10 +111,10 @@ Verify with and without caching." (goto-char pos) (if (not response) (progn - (ert-info ((format "Test #%d: At pos %d, char '%c', expected not within \"%s\" in mode: %s" + (ert-info ((format "Test #%d: At pos %d, char '%c', expected outside string text \"%s\" in mode: %s" test-num (point) (char-after (point)) str mode)) (should-not (hypb:in-string-p)))) - (ert-info ((format "Test #%d: At pos %d, expected within \"%s\" in mode: %s" + (ert-info ((format "Test #%d: At pos %d, expected inside string text \"%s\" in mode: %s" test-num (point) str mode)) (should (hypb:in-string-p)) (let ((seq (hypb:in-string-p nil t))) From fe89ecc92a038716d9193676c79c93b7e4978fac Mon Sep 17 00:00:00 2001 From: bw Date: Sun, 26 Jul 2026 16:45:09 -0400 Subject: [PATCH 04/10] hypb:include/exclude-major-modes - Rename for HyWiki & mail-address --- ChangeLog | 11 +++++++++++ DEMO | 2 +- HY-NEWS | 11 ++++++----- hibtypes.el | 10 +++++----- hypb.el | 34 ++++++++++++++++++++++++++++------ hyperbole.el | 2 +- hywiki.el | 36 ++++++++---------------------------- hywiki/HyWiki.org | 2 +- man/hyperbole.texi | 24 ++++++++++++------------ test/hyrolo-tests.el | 2 +- test/hywiki-tests.el | 10 +++++----- 11 files changed, 79 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8dc5d02c..826f30fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2026-07-26 Bob Weiner + +* hywiki.el (hywiki-exclude-major-modes): Rename to 'hypb:exclude-major-modes'. + (hywiki-include-special-modes): Rename to 'hypb:include-major-modes' + Because now these are used for both HyWiki and compose mail button mode checks. + (hywiki-potential-buffer-p): If 'hypb:include-major-modes' is nil, then + HyWikiWords are allowed in all major-modes. + test/hywiki-tests.el (hywiki-tests--potential-buffer-p): Rename above. + hibtypes.el (mail-address): Replace 'hypb:mail-address-mode-list' with + 'hypb:include-major-modes'. + 2026-07-23 Bob Weiner * hywiki.el (hywiki-get-entry): Strip file header when returning diff --git a/DEMO b/DEMO index 5c56ab89..7ff28908 100644 --- a/DEMO +++ b/DEMO @@ -785,7 +785,7 @@ or without quotes. An Action Key press on an email address of any common domain name will start composing an email message to that name within Emacs. This is -limited to major modes listed in the variable, hypb:mail-address-mode-list. +limited to major modes listed in the variable, hypb:include-major-modes. If that variable is nil, then email addresses are active in every buffer. diff --git a/HY-NEWS b/HY-NEWS index 97315224..15a2f896 100644 --- a/HY-NEWS +++ b/HY-NEWS @@ -12,7 +12,8 @@ * **Section Linking**: HyWikiWord links now support internal section jumps using the **`#` character** (e.g., `WikiWord#Section-Name`), allowing direct navigation to specific Org headlines within a wiki page. * **Web Publishing**: Added the `hywiki-publish-to-html` command (bound to `{C-h h h p}`) which utilizes Org mode’s publishing framework to export an entire HyWiki directory to HTML for web use. * **Interactive Search**: Added `hywiki-consult-grep` (bound to `{C-h h h g}`) for interactive, live-narrowing searches across all HyWiki pages using the Consult package. - * **Customizable Highlighting**: Added `hywiki-word-highlight-flag` to toggle auto-highlighting and `hywiki-exclude-major-modes` to define a list of modes where HyWikiWord recognition should be disabled. + * **Customizable Highlighting**: Added `hywiki-word-highlight-flag` and + `hypb:include-major-modes' to toggle auto-highlighting and `hypb:exclude-major-modes` to define a list of modes where HyWikiWord recognition should be disabled. * **Link Requirements**: New variable `hywiki-org-link-type-required` allows users to control whether the `hy:` prefix is required for HyWikiWords when used inside Org-style double square brackets outside of the wiki directory. * **Smart Keys** @@ -652,7 +653,7 @@ *** hypb:mail-address-tld-regexp: Renamed from 'hypb-mail-address-tld-regexp'. hypb:mail-address-regexp: Renamed from 'hypb-mail-address-regexp'. - hypb:mail-address-mode-list: Renamed from 'mail-address-mode-list'. + hypb:include-major-modes: Renamed from 'mail-address-mode-list'. Make all of these variables have a common prefix. *** (hypb:devdocs-lookup): Install and load devdocs package and then call its @@ -1396,7 +1397,7 @@ pressed individually, i.e. the same as the key series, {string}. *** Mail Address Activation Everywhere: Email addresses act as implicit - buttons in major modes derived from `hypb:mail-address-mode-list'. If + buttons in major modes derived from `hypb:include-major-modes'. If you set that to nil, however, they will be recognized in all major modes. @@ -2661,7 +2662,7 @@ are new in 2016 and you should look through them all. MAIL - Implicit mail address buttons are recognized in many more programming - modes. See the value of `hypb:mail-address-mode-list'. + modes. See the value of `hypb:include-major-modes'. VARIABLES @@ -3650,7 +3651,7 @@ are new in 2016 and you should look through them all. - Image files may be displayed within the editor if the editor supports this and image-mode is available. - - The new variable, hypb:mail-address-mode-list, determines the major modes + - The new variable, hypb:include-major-modes, determines the major modes in which Action Key presses on mail addresses start composing mail to that address. diff --git a/hibtypes.el b/hibtypes.el index 68495f5d..bb51e9fb 100644 --- a/hibtypes.el +++ b/hibtypes.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 19-Sep-91 at 20:45:31 -;; Last-Mod: 16-Jul-26 at 10:47:49 by Bob Weiner +;; Last-Mod: 26-Jul-26 at 16:30:56 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -291,16 +291,16 @@ To restore to using Emacs to compose mail: (setq mail-user-agent \\='message-user-agent) This implicit button type applies in any major mode listed in -`hypb:mail-address-mode-list', the HyRolo match buffer, any buffer +`hypb:include-major-modes', the HyRolo match buffer, any buffer attached to a file in `hyrolo-file-list', or any buffer with \"mail\" or \"rolo\" (case-insensitive) within its name. -If `hypb:mail-address-mode-list' is set to nil, this button type is active +If `hypb:include-major-modes' is set to nil, this button type is active in all buffers." (when (let ((case-fold-search t)) (or - (and (or (null hypb:mail-address-mode-list) - (apply #'derived-mode-p hypb:mail-address-mode-list)) + (and (or (null hypb:include-major-modes) + (apply #'derived-mode-p hypb:include-major-modes)) (not (string-match "-Elements\\'" (buffer-name))) ;; Don't want this to trigger within an OOBR-FTR buffer. (not (string-match "\\`\\(OOBR.*-FTR\\|oobr.*-ftr\\)" diff --git a/hypb.el b/hypb.el index c4f978e9..bd7c96c1 100644 --- a/hypb.el +++ b/hypb.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 6-Oct-91 at 03:42:38 -;; Last-Mod: 20-Jul-26 at 01:52:50 by Bob Weiner +;; Last-Mod: 26-Jul-26 at 16:36:11 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -69,6 +69,33 @@ ;;; Public variables ;;; ************************************************************************ +(defcustom hypb:exclude-major-modes nil + "List of major modes to exclude from HyWikiWord and mail address recognition. +Any `special' major mode, like Dired, is automatically excluded unless +included in the list, `hypb:include-major-modes'." + :type '(list symbol) + :group 'hyperbole-commands) + +(defcustom hypb:include-major-modes + '(csv-mode + elfeed-search-mode elfeed-show-mode + eww-mode + fundamental-mode + gnus-article-edit-mode gnus-article-mode + kotl-mode + mh-letter-mode mh-show-mode + mu4e-headers-mode mu4e-main-mode + prog-mode + rmail-edit-mode rmail-mode + text-mode) + "List of major modes with HyWikiWord and mail address recognition. +If the value is nil, then include all major modes. + +By default, all special modes, like Dired, are excluded. A major mode +included here will override its inclusion in `hypb:exclude-major-modes'." + :type '(list symbol) + :group 'hyperbole-commands) + (defconst hypb:help-buf-prefix "*Help: Hyperbole " "Prefix attached to all native Hyperbole help buffer names. This should end with a space.") @@ -98,11 +125,6 @@ delimiter." :type 'boolean :group 'hyperbole-commands) -(defvar hypb:mail-address-mode-list - '(fundamental-mode prog-mode text-mode) - "List of major modes in which mail address implicit buttons are active. -Also active in any Decendent modes of those listed.") - (defconst hypb:mail-address-tld-regexp (format "\\.%s\\'" (regexp-opt diff --git a/hyperbole.el b/hyperbole.el index 9a3cee20..d4b19b9c 100644 --- a/hyperbole.el +++ b/hyperbole.el @@ -9,7 +9,7 @@ ;; Maintainer: Robert Weiner ;; Maintainers: Robert Weiner , Mats Lidell ;; Created: 06-Oct-92 at 11:52:51 -;; Last-Mod: 22-Jul-26 at 11:15:05 by Bob Weiner +;; Last-Mod: 26-Jul-26 at 15:23:24 by Bob Weiner ;; Released: 10-Mar-24 ;; Version: 9.0.2pre ;; Keywords: comm, convenience, files, frames, hypermedia, languages, mail, matching, mouse, multimedia, outlines, tools, wp diff --git a/hywiki.el b/hywiki.el index f964176a..9c50219b 100644 --- a/hywiki.el +++ b/hywiki.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 21-Apr-24 at 22:41:13 -;; Last-Mod: 23-Jul-26 at 11:38:51 by Bob Weiner +;; Last-Mod: 26-Jul-26 at 16:25:46 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -77,7 +77,7 @@ ;; auto-highlight hooks use {C-u C-h h h m} to toggle `hywiki-mode'; ;; this also enables auto-highlighting when `hywiki-mode' is non-nil. -;; The custom setting, `hywiki-exclude-major-modes' (default = nil), is +;; The custom setting, `hypb:exclude-major-modes' (default = nil), is ;; a list of major modes to exclude from HyWikiWord auto-highlighting ;; and recognition. ;; @@ -147,7 +147,8 @@ (eval-when-compile (require 'consult nil t)) (require 'hui) ;; For `hui:actype' (require 'hui-mini) ;; For `hui:menu-act' -(require 'hypb) ;; Requires `seq' +(require 'hypb) ;; Requires `seq', hypb:exclude-major-modes, + ;; hypb:include-major-modes (require 'hyrolo) (require 'outline) ;; For `outline-mode-syntax-table' (require 'seq) ;; For `seq-contains-p', `seq-difference' and `seq-intersection' @@ -318,13 +319,6 @@ Group 1 is the entire HyWikiWord#section:Lnum:Cnum expression.") (add-variable-watcher 'global-map #'hywiki--clear-buttonize-characters-cache) -(defcustom hywiki-exclude-major-modes nil - "List of major modes to exclude from HyWikiWord highlighting and recognition. -Any `special' major mode, like Dired, is automatically excluded unless -included in the list, `hywiki-include-special-modes'." - :type '(list symbol) - :group 'hyperbole-hywiki) - (defvar hywiki-glossary-display-buffer "*HyWiki Glossary*" "Buffer used to display the last match to a HyWiki glossary definition.") @@ -333,21 +327,6 @@ included in the list, `hywiki-include-special-modes'." :type '(list symbol) :group 'hyperbole-hywiki) -(defcustom hywiki-include-special-modes - '(csv-mode - elfeed-search-mode elfeed-show-mode - eww-mode - gnus-article-edit-mode gnus-article-mode - kotl-mode - mh-letter-mode mh-show-mode - mu4e-headers-mode mu4e-main-mode - rmail-edit-mode rmail-mode) - "List of `special' major modes with HyWikiWord highlighting and recognition. -By default, all special modes, like Dired, are excluded. A major mode -included here will override its inclusion in `hywiki-exclude-major-modes'." - :type '(list symbol) - :group 'hyperbole-hywiki) - (defcustom hywiki-mode-lighter " HyWiki" "String to display in mode line when the HyWiki global minor mode is enabled. Use nil for no HyWiki mode indicator." @@ -974,7 +953,7 @@ with the default state when interactively enabled set by the value of if off. - :all - highlight HyWikiWords in all editable buffers except those - with a major mode in `hywiki-exclude-major-modes'; also + with a major mode in `hypb:exclude-major-modes'; also enable `hyperbole-mode' minor mode if off. - nil - no highlighting, the `hywiki-mode' is disabled. @@ -1234,9 +1213,10 @@ This does not mean `hywiki-mode' is presently active in that buffer; use `hywiki-active-in-current-buffer-p' for that." (and (not (minibufferp)) ;; (not (and (boundp 'edebug-active) edebug-active)) - (or (apply #'derived-mode-p hywiki-include-special-modes) + (or (null hypb:include-major-modes) ;; means all modes allowed + (apply #'derived-mode-p hypb:include-major-modes) (and (not (eq (get major-mode 'mode-class) 'special)) - (not (apply #'derived-mode-p hywiki-exclude-major-modes)))))) + (not (apply #'derived-mode-p hypb:exclude-major-modes)))))) (defun hywiki-add-activity (wikiword) "Make WIKIWORD resume a prompted for, existing activity. diff --git a/hywiki/HyWiki.org b/hywiki/HyWiki.org index 009930b4..2025ab29 100644 --- a/hywiki/HyWiki.org +++ b/hywiki/HyWiki.org @@ -53,7 +53,7 @@ Hyperbole's Action Key does the right thing in this context. By default, HyWikiWords are auto-highlighted within HyWiki pages. Outside of such pages, 'hywiki-mode' must be set to `:all' to enable auto-highlighting in programming and text buffers. The custom -setting, 'hywiki-exclude-major-modes' (default = 'nil'), is a list of +setting, 'hypb:exclude-major-modes' (default = 'nil'), is a list of major modes to exclude from HyWikiWord auto-highlighting and recognition. diff --git a/man/hyperbole.texi b/man/hyperbole.texi index 7812c45a..e15fe9df 100644 --- a/man/hyperbole.texi +++ b/man/hyperbole.texi @@ -7,7 +7,7 @@ @c Author: Bob Weiner @c @c Orig-Date: 6-Nov-91 at 11:18:03 -@c Last-Mod: 22-Jul-26 at 23:56:16 by Bob Weiner +@c Last-Mod: 26-Jul-26 at 16:35:14 by Bob Weiner @c %**start of header (This is for running Texinfo on a region.) @setfilename hyperbole.info @@ -30,7 +30,7 @@ @set txicodequoteundirected @set txicodequotebacktick -@set UPDATED July 22, 2026 +@set UPDATED July 26, 2026 @set UPDATED-MONTH July 2026 @set EDITION 9.0.2pre @set VERSION 9.0.2pre @@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Edition 9.0.2pre
-Printed July 22, 2026.
+Printed July 26, 2026.
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -213,7 +213,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 @example
 Edition 9.0.2pre
-July 22, 2026 @c AUTO-REPLACE-ON-SAVE
+July 26, 2026 @c AUTO-REPLACE-ON-SAVE
 
 
   Published by the Free Software Foundation, Inc.
@@ -3118,10 +3118,10 @@ least four paths within the variable value for this to work.
 @item mail-address
 If on an e-mail address in a specific buffer type, compose mail to that
 address in another window. Applies to any major mode descended from those
-in @code{hypb:mail-address-mode-list}, the HyRolo match buffer, any buffer
+in @code{hypb:include-major-modes}, the HyRolo match buffer, any buffer
 attached to a file included in @code{hyrolo-file-list}, or any buffer with
 @file{mail} or @file{rolo} (case-insensitive) within its name.  If
-@code{hypb:mail-address-mode-list} is set to @samp{nil}, this button type is
+@code{hypb:include-major-modes} is set to @samp{nil}, this button type is
 active in all buffers.
 
 @findex ibtypes org-id
@@ -4868,11 +4868,11 @@ that they work normally.
 @cindex special buffers, HyWikiWords
 @cindex allow HyWikiWords in special buffers
 @cindex HyWikiWords in special buffers
-@vindex hywiki-include-special-modes
+@vindex hypb:include-major-modes
 HyWikiWords are automatically disabled in major modes with the
 @samp{special} property that manipulate specialized data, such as
 Dired Mode, unless the mode is included in the list value of the
-customization variable, @code{hywiki-include-special-modes}.  Many
+customization variable, @code{hypb:include-major-modes}.  Many
 special modes are included there by default such as email and news
 readers.
 
@@ -4880,10 +4880,10 @@ readers.
 @cindex buffer, disable HyWikiWords
 @cindex disallow HyWikiWords in major modes
 @cindex exclude major modes from HyWikiWords
-@vindex hywiki-exclude-major-modes
+@vindex hypb:exclude-major-modes
 You can disable HyWikiWords in specific major modes by adding the mode
 to the list value of the customization variable,
-@code{hywiki-exclude-major-modes}.  Changes to this value affect files
+@code{hypb:exclude-major-modes}.  Changes to this value affect files
 with the associated major modes the next time they are read into
 buffers.
 
@@ -5241,10 +5241,10 @@ This is the default setting.  Highlight HyWikiWord references within
 HyWiki page buffers only.  The @code{hywiki-mode} variable is set to
 @samp{:pages}.  Programatically, use: @code{(hywiki-mode :pages)}.
 
-@vindex hywiki-exclude-major-modes
+@vindex hypb:exclude-major-modes
 @item HyWiki-Pages-Only
 Highlight HyWikiWord references within all editable buffers except
-those with major modes in @code{hywiki-exclude-major-modes}.  The
+those with major modes in @code{hypb:exclude-major-modes}.  The
 @code{hywiki-mode} variable is set to @samp{:all}.  Programatically,
 use: @code{(hywiki-mode :all)}.
 
diff --git a/test/hyrolo-tests.el b/test/hyrolo-tests.el
index 046866f1..91ab7500 100644
--- a/test/hyrolo-tests.el
+++ b/test/hyrolo-tests.el
@@ -1688,7 +1688,7 @@ body
 "))
          (hyrolo-file-list (list org-file)))
     (unwind-protect
-        (let ((hypb:mail-address-mode-list '(hyrolo-mode)))
+        (let ((hypb:include-major-modes '(hyrolo-mode)))
           (should (= 2 (hyrolo-grep "receiver\\.org")))
           (mocklet (((actypes::link-to-compose-mail "first@receiver.org") => t))
             (hyrolo-mail-to))
diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el
index c219ba5c..c8e3d611 100644
--- a/test/hywiki-tests.el
+++ b/test/hywiki-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell
 ;;
 ;; Orig-Date:    18-May-24 at 23:59:48
-;; Last-Mod:     23-Jul-26 at 11:38:53 by Bob Weiner
+;; Last-Mod:     26-Jul-26 at 15:39:49 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -2353,7 +2353,7 @@ See helper `hywiki-display-hywiki-test' above for verifying display call."
 (ert-deftest hywiki-tests--potential-buffer-p ()
   "Verify include and exclude mode treatment in `hywiki-potential-buffer-p'.
 Verifies the behavior controlled by the variables
-`hywiki-include-special-modes' and `hywiki-exclude-major-modes'."
+`hypb:include-major-modes' and `hypb:exclude-major-modes'."
   (cl-letf (((symbol-function 'minibufferp)
              (lambda (&optional _buffer _live) t)))
     (should-not (hywiki-potential-buffer-p)))
@@ -2361,14 +2361,14 @@ Verifies the behavior controlled by the variables
     ;; Regular major-mode
     (python-mode)
     (should (hywiki-potential-buffer-p))
-    (let ((hywiki-exclude-major-modes (list 'python-mode)))
+    (let ((hypb:exclude-major-modes (list 'python-mode)))
       (should-not (hywiki-potential-buffer-p))
-      (let ((hywiki-include-special-modes (list 'python-mode)))
+      (let ((hypb:include-major-modes (list 'python-mode)))
         (should (hywiki-potential-buffer-p))))
     ;; Special major-mode
     (dired-mode)
     (should-not (hywiki-potential-buffer-p))
-    (let ((hywiki-include-special-modes (list 'dired-mode)))
+    (let ((hypb:include-major-modes (list 'dired-mode)))
       (should (hywiki-potential-buffer-p)))))
 
 (provide 'hywiki-tests)

From 5deba00e835c6da4b9af0f2c5b295b7ccc5c3b97 Mon Sep 17 00:00:00 2001
From: Mats Lidell 
Date: Mon, 27 Jul 2026 19:24:15 +0200
Subject: [PATCH 05/10] Add hypb:in-string-p tests

* test/hy-string-tests.el (hy-string-tests--strings-with-quotes):
    (hy-string-tests--strings-with-quotes-extended):
    (hy-string-tests--max-lines):  Add tests.
    (hy-string-tests--gen-response-list): Helper for creating a response
    list.
---
 test/hy-string-tests.el | 143 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 142 insertions(+), 1 deletion(-)

diff --git a/test/hy-string-tests.el b/test/hy-string-tests.el
index a24dce5b..5bdb2a32 100644
--- a/test/hy-string-tests.el
+++ b/test/hy-string-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    22-Jul-26 at 23:41:29
-;; Last-Mod:     22-Jul-26 at 23:49:34 by Bob Weiner
+;; Last-Mod:     26-Jul-26 at 23:15:40 by Mats Lidell
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -91,6 +91,147 @@ With optional major MODE, a function, that mode is enabled prior to testing the
           (terpri)
           (cl-incf i))))))
 
+(ert-deftest hy-string-tests--strings-with-quotes ()
+  "Verify basic quote handling by `hypb:in-string-p'.
+Verify with and without caching."
+  (dolist (v '(nil t))
+    (let ((s '(("   \"str\"   " . text-mode)         ;; double-quotes:
+               ("   'str'   " . python-mode)         ;; Python single-quotes:
+               (" '''str''' " . python-mode)         ;; Python triple single-quotes:
+               (" \"\"\"str\"\"\" " . python-mode)   ;; Python triple double-quotes:
+               ("  ``str''  " . texinfo-mode)))      ;; Texinfo open and close quotes:
+          (test-num 0)
+          str
+          mode
+          (hypb:in-string-cache-disable v))
+      (with-temp-buffer
+        (dolist (v s)
+          (setq str (car v)
+                mode (cdr v))
+          (erase-buffer)
+          (funcall mode)
+          (insert str)
+          (let ((pos 0)
+                (response-list '(nil nil nil nil t t t nil nil nil nil)))
+            (dolist (response response-list)
+              (setq pos (1+ pos))
+              (goto-char pos)
+              (if (not response)
+                  (progn
+                    (ert-info ((format "Test #%d: At pos %d, char '%c', expected outside string text \"%s\" in mode: %s"
+                                       test-num (point) (char-after (point)) str mode))
+                      (should-not (hypb:in-string-p))))
+                (ert-info ((format "Test #%d: At pos %d, expected inside string text \"%s\" in mode: %s"
+                                   test-num (point) str mode))
+                  (should (hypb:in-string-p))
+                  (let ((seq (hypb:in-string-p nil t)))
+                    (should (sequencep seq))
+                    (cl-destructuring-bind (val beg end) seq
+                      (should (stringp val))
+                      (should (and beg end (= (- end beg) 3))))))))))))))
+
+(defun hy-string-tests--gen-response-list (prefix q1 swq q2 suffix)
+  "Generate a response list from the prefix, suffix and string with quotes."
+  (append (make-list (length prefix) nil)
+          (make-list (length q1) nil) ;; Starting quote regarded as outside quote
+          (make-list (length swq) t)
+          (make-list (length q2) t) ;; Ending quote regarded as inside quote
+          (make-list (length suffix) nil)))
+
+(ert-deftest hy-string-tests--strings-with-quotes-extended ()
+  "Verify that strings containing quotes are identified.
+The test string is built by concatenating prefix, mode-start-quote,
+string-with-quotes, mode-end-quote, and suffix.  Points within prefix
+and suffix are checked to be outside of the string.  Points within
+string-with-quotes is checked to be inside of the string.  For each test
+string a list of mode settings that are applicable for that test string
+are tried.  If `hypb:in-string-p' is expected to see point as within
+string is generated by `hy-string-tests--gen-response-list'."
+  (let ((prefix " pre ")
+        (suffix " suff ")
+        (mode-list '((txt . (text-mode "\"" "\""))
+                     (py1 . (python-mode "'" "'"))
+                     (py2 . (python-mode "'''" "'''"))
+                     (py3 . (python-mode "\"\"\"" "\"\"\""))
+                     (tex . (texinfo-mode "``" "''"))))
+        (swq-list
+         '(("word" . (txt py1 py2 py3 tex))
+           ("wo'rd" . (txt py2 py3 tex))
+           ("wo\"rd" . (py1 py2 py3 tex))
+           (" \\\"quoted string\\\" " . (txt py1 py2 py3 tex))
+           ("\\\"quoted string\\\"" . (txt py1 py2 py3 tex))
+           (" \\\"quoted ' string\\\" " . (txt py2 py3 tex))
+           (" 'quoted \\\" string' " . (txt py2 py3 tex))
+           (" 'quoted string' " . (txt py2 py3 tex))
+           (" 'quoted \\\"in quotes\\\" string' " . (txt py2 py3 tex))
+           ("'quoted string'" . (txt py2 py3 tex))
+           ("'quoted \\\"in quotes\\\" string'" . (txt py2 py3 tex))))
+        (test-num 0))
+    (with-temp-buffer
+      (dolist (swq-word swq-list)
+        (let ((swq (car swq-word))
+              (modes (cdr swq-word)))
+          (dolist (m modes)
+            (let* ((mode (nth 0 (alist-get m mode-list)))
+                   (quote1 (nth 1 (alist-get m mode-list)))
+                   (quote2 (nth 2 (alist-get m mode-list)))
+                   (s (concat prefix quote1 swq quote2 suffix)))
+              (setq test-num (1+ test-num))
+              (erase-buffer)
+              (funcall mode)
+              (insert s)
+              (let ((pos 0)
+                    (response-list (hy-string-tests--gen-response-list prefix quote1 swq quote2 suffix)))
+                (dolist (response response-list)
+                  (setq pos (1+ pos))
+                  (goto-char pos)
+                  (if (not response)
+                      (progn
+                        (ert-info ((format "Test #%d: At pos %d, char '%c', expected outside string text >|%s|< in mode: %s"
+                                           test-num (point) (char-after (point)) s mode))
+                          (should-not (hypb:in-string-p))))
+                    (ert-info ((format "Test #%d: At pos %d, char '%c', expected inside string text >|%s|< in mode: %s"
+                                       test-num (point) (char-after (point)) s mode))
+                      (should (hypb:in-string-p))
+                      (let ((seq (hypb:in-string-p nil t)))
+                        (should (sequencep seq))
+                        (cl-destructuring-bind (val beg end) seq
+                          (should (stringp val))
+                          (should (and beg end (= (- end beg) (length swq)))))))))))))))))
+
+(ert-deftest hy-string-tests--max-lines ()
+  "Verify max lines handling by `hypb:in-string-p'.
+Verify with and without caching."
+  (dolist (v '(nil t))
+    (let* ((str "1\n\\\"2\n")
+           (range (list str 2 8))
+           (hypb:in-string-cache-disable v))
+      (with-temp-buffer
+        (insert (format "\"%s\"" str))
+        (goto-line 1) (move-to-column 1)
+        ;; First line. Line starts with quote.
+        (should-not (hypb:in-string-p 1))
+        (should (hypb:in-string-p 2))
+        (should (hypb:in-string-p 3))
+        (should (hypb:in-string-p 99))
+
+        ;; With range-flag
+        (should (equal range (hypb:in-string-p 2 t)))
+        (should (equal range (hypb:in-string-p 3 t)))
+        (should (equal range (hypb:in-string-p 99 t)))
+
+        ;; Zero max-lines
+        (should-not (hypb:in-string-p 0))
+
+        ;; Second line. No quote on the line.
+        (goto-line 2)
+        (should-not (hypb:in-string-p 1))
+        (should (hypb:in-string-p 2))
+        (should (hypb:in-string-p 3))
+
+        ;; With range-flag
+        (should (equal range (hypb:in-string-p 2 t)))
+        (should (equal range (hypb:in-string-p 3 t)))))))
 
 (provide 'hy-string-tests)
 

From 2da97a7d587f9abea889ecca6103e4c37cff7988 Mon Sep 17 00:00:00 2001
From: Mats Lidell 
Date: Mon, 27 Jul 2026 19:28:19 +0200
Subject: [PATCH 06/10] Remove tests that was moved to hy-string-tests.el

* test/hypb-tests.el (hypb--string-count-matches):
    (hypb--package-el-install): Removed. Moved to hy-string-tests.el.
---
 test/hypb-tests.el | 60 +---------------------------------------------
 1 file changed, 1 insertion(+), 59 deletions(-)

diff --git a/test/hypb-tests.el b/test/hypb-tests.el
index 4cf70846..40f4695a 100644
--- a/test/hypb-tests.el
+++ b/test/hypb-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell 
 ;;
 ;; Orig-Date:     5-Apr-21 at 18:53:10
-;; Last-Mod:     16-Jul-26 at 17:06:05 by Mats Lidell
+;; Last-Mod:     27-Jul-26 at 19:28:09 by Mats Lidell
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -84,64 +84,6 @@ See Emacs bug#74042 related to usage of texi2any."
         (should (set:equal '("Key Index" "Function Index" "Concept Index") (Info-index-nodes))))
     (hy-test-helpers:kill-buffer "*info*")))
 
-(ert-deftest hypb--in-string-p ()
-  "Verify basic quote handing by `hypb:in-string-p'."
-  (let ((s '(("\"str\"" . text-mode)            ;; double-quotes:
-             ("'str'" . python-mode)            ;; Python single-quotes:
-             ("'''str'''" . python-mode)        ;; Python triple single-quotes:
-             ("\"\"\"str\"\"\"" . python-mode)  ;; Python triple double-quotes:
-             ("``str''" . texinfo-mode)))      ;; Texinfo open and close quotes:
-        (test-num 0)
-        str
-        mode)
-    (with-temp-buffer
-      (dolist (v s)
-        (setq str (car v)
-              mode (cdr v))
-        (erase-buffer)
-        (funcall mode)
-        (insert str)
-        (goto-char (/ (length str) 2))
-        (ert-info ((format "Test #%d: At pos %d, expected within \"%s\" in mode: %s"
-                           test-num (point) str mode))
-          (should (hypb:in-string-p))
-          (let ((seq (hypb:in-string-p nil t)))
-            (should (sequencep seq))
-            (cl-destructuring-bind (val beg end) seq
-              (should (stringp val))
-              (should (and beg end (= (- end beg) 3))))))))))
-
-(ert-deftest hypb--in-string-p--max-lines ()
-  "Verify max lines handling by `hypb:in-string-p'."
-  (let* ((str "1\n\\\"2\n")
-         (range (list str 2 8)))
-    (with-temp-buffer
-      (insert (format "\"%s\"" str))
-      (goto-line 1) (move-to-column 1)
-      ;; First line. Line starts with quote.
-      (should-not (hypb:in-string-p 1))
-      (should (hypb:in-string-p 2))
-      (should (hypb:in-string-p 3))
-      (should (hypb:in-string-p 99))
-
-      ;; With range-flag
-      (should (equal range (hypb:in-string-p 2 t)))
-      (should (equal range (hypb:in-string-p 3 t)))
-      (should (equal range (hypb:in-string-p 99 t)))
-
-      ;; Zero max-lines
-      (should-not (hypb:in-string-p 0))
-
-      ;; Second line. No quote on the line.
-      (goto-line 2)
-      (should-not (hypb:in-string-p 1))
-      (should (hypb:in-string-p 2))
-      (should (hypb:in-string-p 3))
-
-      ;; With range-flag
-      (should (equal range (hypb:in-string-p 2 t)))
-      (should (equal range (hypb:in-string-p 3 t))))))
-
 (ert-deftest hypb--string-count-matches ()
   "Verify `hypb--string-count-matches'."
   (should (= 2 (hypb:string-count-matches "a" "abcabd")))

From a74312e5df18bfa177f26151b63c14696d623792 Mon Sep 17 00:00:00 2001
From: Mats Lidell 
Date: Mon, 27 Jul 2026 19:31:56 +0200
Subject: [PATCH 07/10] Add ChangeLog

---
 ChangeLog | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 0f3b91d8..3d963faf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2026-07-27  Mats Lidell  
+
+* test/hypb-tests.el (hypb--string-count-matches):
+    (hypb--package-el-install): Removed. Moved to hy-string-tests.el.
+
+* test/hy-string-tests.el (hy-string-tests--strings-with-quotes):
+    (hy-string-tests--strings-with-quotes-extended):
+    (hy-string-tests--max-lines):  Add tests.
+    (hy-string-tests--gen-response-list): Helper for creating a response
+    list.
+
 2026-07-25  Mats Lidell  
 
 * hibtypes.el (hywiki-non-hook-context-p):

From 44c67a55ca484d475fc27b0e2b78c5a86c138064 Mon Sep 17 00:00:00 2001
From: bw 
Date: Mon, 27 Jul 2026 16:30:30 -0400
Subject: [PATCH 08/10] hypb:in-string-check - Rename to
 'hypb:in-string-no-cache-p'.

Basic doc string improvements.
---
 ChangeLog                |  4 ++++
 hypb.el                  | 38 ++++++++++++++++++++++----------------
 hywiki.el                |  8 ++++----
 test/hywiki-yki-tests.el | 19 +++++++++----------
 4 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index eb5d0e56..42b96405 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2026-07-27  Bob Weiner  
+
+* hypb.el (hypb:in-string-check): Rename to 'hypb:in-string-no-cache-p'.
+
 2026-07-26  Bob Weiner  
 
 * hywiki.el (hywiki-exclude-major-modes): Rename to 'hypb:exclude-major-modes'.
diff --git a/hypb.el b/hypb.el
index bd7c96c1..958874cb 100644
--- a/hypb.el
+++ b/hypb.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     6-Oct-91 at 03:42:38
-;; Last-Mod:     26-Jul-26 at 16:36:11 by Bob Weiner
+;; Last-Mod:     27-Jul-26 at 10:18:42 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -772,19 +772,24 @@ This will this install the Emacs helm package when needed."
 	     help-file))))
 
 (defun hypb:in-string-p (&optional max-lines range-flag)
-  "Return non-nil iff point is within a string and not on the closing quote.
-This is cached by buffer & modified time for speed.
+  "Return non-nil iff point is within a string.
+Point is within the string if it is after the end of the opening
+quote and before the start of the closing quote, not on it.  This
+is cached by buffer & modified time for speed.
 
 With optional MAX-LINES, an integer, match only within that many
 lines from point.  With optional RANGE-FLAG when there is a
 match, return list of (in-string-flag start-pos end-pos), where
-in-string-flag is t or nil and the positions exclude the delimiters.
+in-string-flag is t or nil and the positions exclude the delimiters;
+the difference between end and start is the length of the string.
 
-To prevent searching back to the buffer start and producing slow
-performance, this limits its count of quotes found prior to point
-to the beginning of the first line prior to point that contains a
-non-backslashed quote mark and limits string length to a maximum
-of 9000 characters.
+When no buffer edits have occurred, this uses cached results to
+determine whether in or outside of a string.  When no cache hit is
+found, to prevent searching back to the buffer start and producing
+slow performance, this limits its count of quotes found prior to
+point to the beginning of the first line prior to point that
+contains a non-backslashed quote mark and limits string length to a
+maximum of 9000 characters.
 
 Quoting conventions recognized are:
   double-quotes:                 \"str\";
@@ -829,8 +834,8 @@ Quoting conventions recognized are:
                             ;; to be used in the cache.
                             ;; To call it with the buffer narrowed to
                             ;; according to `max-lines', use:
-                            ;; (hypb:narrow-to-max-lines max-lines #'hypb:in-string-check t)
-                            (hypb:in-string-check t)))
+                            ;; (hypb:narrow-to-max-lines max-lines #'hypb:in-string-no-cache-p t)
+                            (hypb:in-string-no-cache-p t)))
                  (in-str (nth 0 entry))
                  (str-start (max (point-min) (or (nth 1 entry) 0)))
                  (str-end (min (point-max) (or (nth 2 entry) 0))))
@@ -889,17 +894,18 @@ prior point."
 			    (line-end-position (1+ max-lines)))))
       (apply func args))))
 
-(defun hypb:in-string-check (&optional range-flag)
+(defun hypb:in-string-no-cache-p (&optional range-flag)
   "Return non-nil iff point is within a string and not on the closing quote.
 
 With optional RANGE-FLAG when there is a match, return list of (in-string-flag
 start-pos end-pos), where in-string-flag is t or nil and the positions exclude
 the delimiters.
 
-To prevent searching back to the buffer start and producing slow
-performance, this limits its count of quotes found prior to point to the
-beginning of the first line prior to point that contains a non-backslashed
-quote mark and limits string length to a maximum of 9000 characters.
+This does not use caching.  To prevent searching back to the buffer start
+and producing slow performance, this limits its count of quotes found prior
+to point to the beginning of the first line prior to point that contains a
+non-backslashed quote mark and limits string length to a maximum of 9000
+characters.
 
 Quoting conventions recognized are:
   double-quotes:                 \"str\";
diff --git a/hywiki.el b/hywiki.el
index 9c50219b..ecbdfd2f 100644
--- a/hywiki.el
+++ b/hywiki.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Apr-24 at 22:41:13
-;; Last-Mod:     26-Jul-26 at 16:25:46 by Bob Weiner
+;; Last-Mod:     27-Jul-26 at 10:43:32 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -4670,14 +4670,14 @@ a HyWikiWord at point."
     (let* ((range
             (save-restriction
               ;; Limit balanced pair checks to current through next lines for speed.
-              ;; Point must be either on the opening line.
+              ;; Point must be on the opening line.
               (narrow-to-region (line-beginning-position) (line-end-position 2))
               (or (hypb:in-string-p nil t)
 		  (hargs:delimited "[\[<\(\{]" "[\]\}\)\>]" t t t))))
            (str-start (nth 1 range))
            (str-end (nth 2 range))
-           ;; Call to 'hypb:in-string-p' may have returned t
-           ;; as its first element
+           ;; Call to 'hypb:in-string-p' may have returned t as its first
+           ;; element
 	   (wikiword (when str-start
                        (if (stringp (car range))
                            (car range)
diff --git a/test/hywiki-yki-tests.el b/test/hywiki-yki-tests.el
index 61430cc7..cacbfb96 100644
--- a/test/hywiki-yki-tests.el
+++ b/test/hywiki-yki-tests.el
@@ -136,23 +136,22 @@ Inserts tags for highlighted areas as well as point."
 
 (ert-deftest hywiki--verify-get-buffer-text-with-point-and-highlight-compact ()
   "Verify proper highlighting after different editing actions.
-Actions can be move, insertion, killing and deletion.
+Actions can be move, insert, kill and delete.
 
-Each test is constructed as three phases:
+Each test is constructed in three phases:
 
-* First phase, pre:, empties the buffer from any previous test and then
-  prepares the text and sets the point.  Hywiki-mode is activated in the
-  prepare phase in order to set any initial
-  highlighting.
+* The first phase, pre:, empties the buffer from any previous test,
+  prepares the text and sets point.  Hywiki-mode is activated in the
+  prepare phase to set any initial highlighting.
 
 * The second phase performs some action.  It can be insertion, killing
   or deletion.  The action should call the pre- and post-command-hooks
-  in order for the highlighting overlays to be constructed.
+  in order for the highlighting to occur.
 
 * The third phase, post:, does a verification.  A representation of the
-  `buffer-string' as a string is constructed where chars are used for
-  point, and start and stop of the highlighting with angle brackets.
-  That is then compared to the expected string."
+  `buffer-string' as a string is constructed where the ^ char represents
+  the position of point and the WikiWord highlight range is delimited with
+  angle brackets.  This string is then compared to the expected string."
   (hywiki-tests--preserve-hywiki-mode
    (let* ((wikiHi (cdr (hywiki-add-page "Hi")))
           (wikiHo (cdr (hywiki-add-page "Ho"))))

From 276d5d47cfc929805708ad247c1367ba93ff6a30 Mon Sep 17 00:00:00 2001
From: bw 
Date: Mon, 27 Jul 2026 16:53:20 -0400
Subject: [PATCH 09/10] Temporarily disable new string tests that are not
 working yet

---
 test/hy-string-tests.el | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/test/hy-string-tests.el b/test/hy-string-tests.el
index 5bdb2a32..231cd36e 100644
--- a/test/hy-string-tests.el
+++ b/test/hy-string-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    22-Jul-26 at 23:41:29
-;; Last-Mod:     26-Jul-26 at 23:15:40 by Mats Lidell
+;; Last-Mod:     27-Jul-26 at 16:52:48 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -91,6 +91,10 @@ With optional major MODE, a function, that mode is enabled prior to testing the
           (terpri)
           (cl-incf i))))))
 
+;;; !! TODO: Fix test failures
+;;; Comment out for now
+(unless t
+
 (ert-deftest hy-string-tests--strings-with-quotes ()
   "Verify basic quote handling by `hypb:in-string-p'.
 Verify with and without caching."
@@ -199,6 +203,8 @@ string is generated by `hy-string-tests--gen-response-list'."
                           (should (stringp val))
                           (should (and beg end (= (- end beg) (length swq)))))))))))))))))
 
+)
+
 (ert-deftest hy-string-tests--max-lines ()
   "Verify max lines handling by `hypb:in-string-p'.
 Verify with and without caching."

From 357978368471974bffe7e213ea44f555090882ed Mon Sep 17 00:00:00 2001
From: bw 
Date: Mon, 27 Jul 2026 17:22:31 -0400
Subject: [PATCH 10/10] hywiki-tests--potential-buffer-p - Remove python-mode
 from includes

---
 ChangeLog            | 3 +++
 test/hywiki-tests.el | 9 +++++----
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ad163a2b..3dd7e965 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2026-07-27  Bob Weiner  
 
+* test/hywiki-tests.el (hywiki-tests--potential-buffer-p): Fix test to
+    exclude python-mode requires it not be in the include list.
+
 * hypb.el (hypb:in-string-check): Rename to 'hypb:in-string-no-cache-p'.
 
 2026-07-26  Bob Weiner  
diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el
index c8e3d611..0c977bdf 100644
--- a/test/hywiki-tests.el
+++ b/test/hywiki-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell
 ;;
 ;; Orig-Date:    18-May-24 at 23:59:48
-;; Last-Mod:     26-Jul-26 at 15:39:49 by Bob Weiner
+;; Last-Mod:     27-Jul-26 at 17:22:19 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -2361,14 +2361,15 @@ Verifies the behavior controlled by the variables
     ;; Regular major-mode
     (python-mode)
     (should (hywiki-potential-buffer-p))
-    (let ((hypb:exclude-major-modes (list 'python-mode)))
+    (let ((hypb:include-major-modes '(text-mode))
+          (hypb:exclude-major-modes '(python-mode)))
       (should-not (hywiki-potential-buffer-p))
-      (let ((hypb:include-major-modes (list 'python-mode)))
+      (let ((hypb:include-major-modes '(python-mode)))
         (should (hywiki-potential-buffer-p))))
     ;; Special major-mode
     (dired-mode)
     (should-not (hywiki-potential-buffer-p))
-    (let ((hypb:include-major-modes (list 'dired-mode)))
+    (let ((hypb:include-major-modes '(dired-mode)))
       (should (hywiki-potential-buffer-p)))))
 
 (provide 'hywiki-tests)