branch: externals/hyperbole
commit bccc18d08b5ff90b0f6b8e132e9e15a1578e4bc8
Author: bw <r...@gnu.org>
Commit: bw <r...@gnu.org>

    Latest rsw updates; hywiki hooks and hywiki-word-at rewritten
---
 ChangeLog            |  85 +++++++
 HY-ABOUT             |   2 +-
 Makefile             |   6 +-
 README.md            |   2 +-
 README.toc.md        |  19 +-
 hargs.el             |  12 +-
 hibtypes.el          |  17 +-
 hproperty.el         |   9 +-
 hsys-org.el          |  44 +++-
 hsys-xref.el         |   6 +-
 hui-select.el        |   4 +-
 hypb.el              |   8 +-
 hyperbole.el         |   4 +-
 hywiki.el            | 649 ++++++++++++++++++++++++++++-----------------------
 man/hyperbole.texi   |  30 +--
 test/hywiki-tests.el |  72 +++---
 test/kcell-tests.el  |   4 +-
 17 files changed, 607 insertions(+), 366 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2c0c59facf..12fb2a0713 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,88 @@
+2025-03-16  Bob Weiner  <r...@gnu.org>
+
+* HY-ABOUT:
+  MELPA-RECIPE.el:
+  README.md:
+  man/hyperbole.texi:
+  hyperbole-pkg.el ("hyperbole"): Update requirement to Emacs version 28 from
+    27.2 since Markdown mode now requires this.
+
+2025-03-14  Bob Weiner  <r...@gnu.org>
+
+* hypb.el (hypb:in-string-p): Made return the start position of the string
+
+* hywiki.el (hywiki--page-name): Rename to 'hywiki--word-only'.
+            (hywiki--word-pre-command): Add for use in command hooks.
+            (hywiki-debuttonize-non-character-commands,
+             hywiki-buttonize-character-commands,
+             hywiki-buttonize-non-character-commands): Rewrite all of these
+    to capture the first HyWikiWord and then only dehighlight in post hooks
+    if the HyWikiWords has changed.
+
+2025-03-13  Bob Weiner  <r...@gnu.org>
+
+* hywiki.el (hywiki-word-at): Clarify :range return value in doc string.
+
+2025-03-08  Bob Weiner  <r...@gnu.org>
+
+* hywiki.el (hywiki-word-at): Fix so hy:WikiWord is recognized without any
+    delimiters.
+  hsys-org.el (hsys-org-link-at-p): Fix to handle Org links without square or
+    angle brackets, e.g. file:WikiWord.org.
+              (hsys-org-thing-at-p): Add to test if point is on a specific org
+    construct type, e.g. a link.
+              (hsys-org-link-at-p): Remove 'with-suppressed-warnings' since
+    inner call to 'hsys-org-thing-at-p' is now run only when in org mode.
+
+* test/hywiki-tests.el (hywiki-tests--convert-words-to-org-link): Fix expected
+value to be [[WikiWord]] not [[file:WikiWord.org][WikiWord]].
+
+2025-03-07  Bob Weiner  <r...@gnu.org>
+
+* test/hywiki-tests.el (hywiki-tests--wikiword-identified-with-delimiters):
+    Fix to show which wikiword item fails.
+
+* hywiki.el (hywiki-maybe-highlight-page-name): Fix to eliminate narrowing
+    of region that hides any balanced delimiters around a HyWikiWord.  Also
+    generalize HyWikiWord range finding using updated 'hywiki-word-at'.
+            (hywiki-word-at): Fix to allow whitespace between delimiters and
+    between #section words when delimited.  Also, if not on a wikiword and
+    'range-flag' is non-nil, return '(nil nil nil).
+
+2025-03-06  Bob Weiner  <r...@gnu.org>
+
+* hywiki.el (hywiki-maybe-highlight-between-page-names): Allow for whitespace
+    after opening delimiter.
+
+2025-03-02  Bob Weiner  <r...@gnu.org>
+
+* test/hywiki-tests.el (hywiki-tests--convert-words-to-org-link): Fix expected
+    link match strings.
+
+* hsys-xref.el (hsys-xref-identifier-at-point): Fix to return nil if xref 
returns
+    a pathname as an identifier.  This fixes a problem with the Action Key
+    triggering the wrong action; it should recognize it as a pathname.
+
+* test/hywiki-tests.el (hywiki-tests--add-org-roam-node): Mock variable,
+    `cl-struct-org-roam-node-tags' needed when org-roam package is not 
installed.
+
+2025-02-27  Bob Weiner  <r...@gnu.org>
+
+* hywiki.el (hywiki--maybe-de/highlight-sexp): Fix to narrow to region of
+    current HyWikiWord range before calling 'func'.
+            (hywiki--maybe-de/highlight-sexp): Add optional 'sexp-start' and
+    'sexp-end' args when known; range should include delimiters.
+            (hywiki-buttonize-character-commands,
+             hywiki-buttonize-non-character-commands): Pass 
'hywiki--buttonize-start'
+    and 'hywiki--buttonize-end' positions to 'hywiki--maybe-de/highlight-sexp'
+    when known rather than recomputing.
+
+* hproperty.el (hproperty:but-move): Add and use in "hywiki.el".
+
+* hywiki.el (hywiki-get-delimited-range): Rename to 
'hywiki-at-range-delimiter'.
+            (hywiki-referent-exists-p): Fix return value doc when given :range
+    arg.  Fix to send word string rather than tuple to 'hywiki-get-referent'.
+
 2025-02-25  Bob Weiner  <r...@gnu.org>
 
 * hywiki.el (hywiki-word-with-optional-spaces-suffix-exact-regexp): Remove
diff --git a/HY-ABOUT b/HY-ABOUT
index da0954216c..9d43f05daa 100644
--- a/HY-ABOUT
+++ b/HY-ABOUT
@@ -11,7 +11,7 @@
 GNU Hyperbole (pronounced Ga-new Hi-per-bo-lee), or just Hyperbole, is
 an efficient and programmable hypertextual information management
 system implemented as a GNU Emacs package.  It works well on GNU Emacs
-27.2 or above.  (See also: "HY-WHY.kotl" for Hyperbole uses).
+28 or above.  (See also: "HY-WHY.kotl" for Hyperbole uses).
 
 Hyperbole includes easy-to-use, powerful hypertextual buttons without
 the need to learn a markup language; a hierarchical, record-based
diff --git a/Makefile b/Makefile
index 33ea6de4dd..15e2d16bef 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 # Author:       Bob Weiner
 #
 # Orig-Date:    15-Jun-94 at 03:42:38
-# Last-Mod:     30-Jan-25 at 09:30:52 by Mats Lidell
+# Last-Mod:     16-Mar-25 at 10:20:44 by Bob Weiner
 #
 # Copyright (C) 1994-2023  Free Software Foundation, Inc.
 # See the file HY-COPY for license information.
@@ -81,7 +81,7 @@
 #
 #               To interactively run a docker version of Emacs with Hyperbole:
 #                   make docker-run              - default to running master
-#                   make docker-run version=27.2 - run Emacs V27.2
+#                   make docker-run version=28.2 - run Emacs V28.2
 #
 #               To build and test a dockerized version of Emacs with Hyperbole:
 #                   make docker                  - defaults: version=master 
targets='clean bin test'
@@ -181,7 +181,7 @@ HYPB_WEB_REPO_LOCATION = ../hyweb/hyperbole/
 HYPB_WEB_REPO_LOCATION_DEVEL = $(HYPB_WEB_REPO_LOCATION)devel/
 
 # CI/CD Emacs versions for local docker based tests
-DOCKER_VERSIONS=27.2 28.2 29.4 master
+DOCKER_VERSIONS=28.2 29.4 30.1 master
 
 ##########################################################################
 #                     NO CHANGES REQUIRED BELOW HERE.                    #
diff --git a/README.md b/README.md
index bf039a4d66..c91f9c8fe3 100644
--- a/README.md
+++ b/README.md
@@ -146,7 +146,7 @@ keyboard and mouse-based control of information display 
within multiple
 windows.  It also provides point-and-click access to World-Wide Web URLs,
 Info manuals, ftp archives, etc.
 
-Hyperbole works well on GNU Emacs 27.2 or above.  It is designed and written
+Hyperbole works well on GNU Emacs 28 or above.  It is designed and written
 by Bob Weiner.  It is maintained by him and Mats Lidell.  Its main
 distribution site is: <https://www.gnu.org/software/hyperbole/>.  If any
 term in here is new or unfamiliar to you, you can look it up in the
diff --git a/README.toc.md b/README.toc.md
index 9fb84e7230..c91f9c8fe3 100644
--- a/README.toc.md
+++ b/README.toc.md
@@ -2,12 +2,23 @@
 
 [We work on Hyperbole as a gift to the Emacs community and request you
  send us a thank you or a testimonial describing your usage if you like
- Hyperbole (mailto:r...@gnu.org)].
+ Hyperbole to [r...@gnu.org](mailto:r...@gnu.org)].
 
 [TOC]
 
 ![Hyperbole screenshot of the Koutliner, DEMO file and 
HyRolo](man/im/hyperbole-cv.png)
 
+## Reference Manual
+
+Hyperbole has many features you can explore interactively or by reading 
sections of
+the reference manual:
+
+   - [Browse Hyperbole Web Manual](man/hyperbole.html)
+
+   - [In Emacs, Browse Hyperbole Info Manual](man/hyperbole.info)
+
+   - [Display or Print PDF Manual](man/hyperbole.pdf)
+
 ## Videos
 
 If you prefer video introductions, visit the videos linked to below;
@@ -135,7 +146,7 @@ keyboard and mouse-based control of information display 
within multiple
 windows.  It also provides point-and-click access to World-Wide Web URLs,
 Info manuals, ftp archives, etc.
 
-Hyperbole works well on GNU Emacs 27.2 or above.  It is designed and written
+Hyperbole works well on GNU Emacs 28 or above.  It is designed and written
 by Bob Weiner.  It is maintained by him and Mats Lidell.  Its main
 distribution site is: <https://www.gnu.org/software/hyperbole/>.  If any
 term in here is new or unfamiliar to you, you can look it up in the
@@ -228,9 +239,9 @@ not a simple introduction.  It is included in the "man/" 
subdirectory
 of the Hyperbole package directory in four forms:
 
 [hyperbole.info](man/hyperbole.info)   - online Info browser version  
-[hyperbole.html](man/hyperbole.html)   - web HTML version  
+[hyperbole.html](man/hyperbole.html)   - web version  
 [hyperbole.pdf](man/hyperbole.pdf)     - printable version  
-[hyperbole.texi](man/hyperbole.texi)   - source form  
+[hyperbole.texi](man/hyperbole.texi)   - source version  
 
 The Hyperbole package installation places the Info version of this manual
 where needed and adds an entry for Hyperbole into the Info directory under
diff --git a/hargs.el b/hargs.el
index 7e21020fc2..d22f3da1fc 100644
--- a/hargs.el
+++ b/hargs.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    31-Oct-91 at 23:17:35
-;; Last-Mod:     25-Feb-25 at 02:16:13 by Bob Weiner
+;; Last-Mod:     27-Feb-25 at 21:21:40 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -525,8 +525,14 @@ following sexpression is returned.  Otherwise, the 
innermost sexpression
 that point is within is returned or nil if none."
   (let ((not-quoted
         '(condition-case ()
-             (not (and (eq (char-syntax (char-after (- (point) 2))) ?\\)
-                       (not (eq (char-syntax (char-after (- (point) 3))) 
?\\))))
+             (not (and (= (if (char-after (- (point) 2))
+                              (char-syntax (char-after (- (point) 2)))
+                            0)
+                          ?\\)
+                       (not (= (if (char-after (- (point) 3))
+                                   (char-syntax (char-after (- (point) 3)))
+                                 0)
+                               ?\\))))
            (error t))))
     (save-excursion
       (ignore-errors
diff --git a/hibtypes.el b/hibtypes.el
index 91ba677533..25b424ddee 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:     29-Jan-25 at 10:07:49 by Mats Lidell
+;; Last-Mod:      2-Mar-25 at 12:05:51 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1591,10 +1591,19 @@ action type, function symbol to call or test to 
execute, i.e.
     ;;     at the end of the buffer
     ;;     or is followed by a space, punctuation or grouping character.
     (when (and lbl-key (or (null (char-before start-pos))
-                           (memq (char-syntax (char-before start-pos)) '(?\  
?\> ?\( ?\))))
-              (not (memq (char-syntax (char-after (1+ start-pos))) '(?\  ?\>)))
+                           (memq (if (char-before start-pos)
+                                    (char-syntax (char-before start-pos))
+                                  0)
+                                '(?\  ?\> ?\( ?\))))
+              (not (memq (if (char-after (1+ start-pos))
+                             (char-syntax (char-after (1+ start-pos)))
+                           0)
+                         '(?\  ?\>)))
               (or (null (char-after end-pos))
-                   (memq (char-syntax (char-after end-pos)) '(?\  ?\> ?. ?\( 
?\)))
+                   (memq (if (char-after end-pos)
+                            (char-syntax (char-after end-pos))
+                          0)
+                        '(?\  ?\> ?. ?\( ?\)))
                    ;; Some of these characters may have symbol-constituent 
syntax
                    ;; rather than punctuation, so check them individually.
                    (memq (char-after end-pos) '(?. ?, ?\; ?: ?! ?\' ?\"))))
diff --git a/hproperty.el b/hproperty.el
index ca27419f7a..c7fcc9e364 100644
--- a/hproperty.el
+++ b/hproperty.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Aug-92
-;; Last-Mod:     18-Jan-25 at 20:53:20 by Bob Weiner
+;; Last-Mod:     27-Feb-25 at 22:50:13 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -274,6 +274,13 @@ If optional PROPERTY and VALUE are given, return only the 
first button
 with that PROPERTY and VALUE."
   (car (hproperty:but-get-first-in-region pos (1+ pos) property value)))
 
+(defun hproperty:but-move (hproperty-but start end &optional buffer)
+  "Set the endpoints of HPROPERTY-BUT to START and END in optional BUFFER.
+If BUFFER is nil and HPROPERTY-BUT has no buffer, put it in the current buffer;
+otherwise, if BUFFER is omitted, leave HPROPERTY-BUT in the same
+buffer it presently inhabits."
+  (move-overlay hproperty-but start end buffer))
+
 (defun hproperty:but-start (hproperty-but)
   "Return the end position of an HPROPERTY-BUT.
 See `hproperty:but-get'."
diff --git a/hsys-org.el b/hsys-org.el
index a66d35b3c9..72ca860e15 100644
--- a/hsys-org.el
+++ b/hsys-org.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     2-Jul-16 at 14:54:14
-;; Last-Mod:      5-Jan-25 at 12:06:01 by Bob Weiner
+;; Last-Mod:      9-Mar-25 at 10:47:48 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -497,19 +497,16 @@ Match to all todos if `keyword' is nil or the empty 
string."
       (looking-at org-babel-src-block-regexp))))
 
 (defun hsys-org-link-at-p ()
-  "Return non-nil iff point is on a square-bracketed Org mode link.
+  "Return non-nil iff point is on an Org mode link.
 Ignore [[hy:HyWiki]] buttons and return nil (handle these as
 implicit buttons).  Assume caller has already checked that the
 current buffer is in `org-mode' or is looking for an Org link in
 another buffer type."
   (unless (or (smart-eolp) (smart-eobp))
-    (with-suppressed-warnings nil
-      (let ((in-org-link (org-in-regexp org-link-bracket-re nil t)))
-       (when in-org-link
-         (save-match-data
-           ;; If this Org link matches a potential HyWiki word, ignore it.
-           (unless (and (fboundp 'hywiki-word-at) (hywiki-word-at))
-             in-org-link)))))))
+    (when (eq 'link (plist-get (hsys-org-thing-at-p) :type))
+      (save-match-data
+       ;; If this Org link matches a potential HyWiki word, ignore it.
+       (not (and (fboundp 'hywiki-word-at) (hywiki-word-at)))))))
 
 ;; Assume caller has already checked that the current buffer is in org-mode.
 (defun hsys-org-heading-at-p (&optional _)
@@ -525,6 +522,35 @@ Assume caller has already checked that the current buffer 
is in
 `org-mode'."
   (hsys-org-face-at-p 'org-target))
 
+;; Derived from `org-open-at-point' in "org.el".
+(defun hsys-org-thing-at-p ()
+  "Return a plist of properties for Org thing at point or nil if none.
+The plist form is: (:type <type> :value <value> :context <context>).
+The thing can be a link, citation, timestamp, footnote, src-block or
+tags.
+
+On top of syntactically correct links, this function also works
+on links and timestamps in comments, node properties, and
+keywords if point is on something looking like a timestamp or a
+link."
+  (when (derived-mode-p 'org-mode)
+    (org-load-modules-maybe)
+    ;; Org's regex matching can fail in non-thing contexts; return nil then
+    (let* ((context
+           ;; Only consider supported types, even if they are not the
+           ;; closest one.
+           (org-element-lineage
+            (org-element-context)
+            '(citation citation-reference clock comment comment-block
+                       footnote-definition footnote-reference headline
+                       inline-src-block inlinetask keyword link node-property
+                       planning src-block timestamp)
+            t))
+          (type (org-element-type context))
+          (value (org-element-property :value context)))
+      (when type
+       (list :type type :value value :context context)))))
+
 (defun hsys-org-todo-at-p ()
   "Return non-nil iff point is on an Org mode todo keyword.
 Assume caller has already checked that the current buffer is in `org-mode'."
diff --git a/hsys-xref.el b/hsys-xref.el
index d633699af1..798f598119 100644
--- a/hsys-xref.el
+++ b/hsys-xref.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    24-Aug-91
-;; Last-Mod:     14-Apr-24 at 19:03:32 by Bob Weiner
+;; Last-Mod:      2-Mar-25 at 18:11:45 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -49,7 +49,9 @@
   (car (hsys-xref-definitions identifier)))
 
 (defun hsys-xref-identifier-at-point ()
-  (xref-backend-identifier-at-point (xref-find-backend)))
+  ;; Return nil if xref returns a pathname as an identifier
+  (unless (hpath:at-p nil t)
+    (xref-backend-identifier-at-point (xref-find-backend))))
 
 (defun hsys-xref-item-buffer (item)
   "Return the buffer in which xref ITEM is defined."
diff --git a/hui-select.el b/hui-select.el
index 7eded1718d..44e734f071 100644
--- a/hui-select.el
+++ b/hui-select.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    19-Oct-96 at 02:25:27
-;; Last-Mod:     25-Feb-25 at 02:24:41 by Bob Weiner
+;; Last-Mod:     27-Feb-25 at 21:24:19 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -915,7 +915,7 @@ end sexp delimiters, ignore it, and return nil."
                          (when (region-active-p) (deactivate-mark))
                          (mark-sexp) t)))
     (ignore-errors
-      (let ((syn-after (char-syntax (char-after)))
+      (let ((syn-after (if (char-after) (char-syntax (char-after)) 0))
            syn-before)
        (cond ((eq syn-after ?\()
               (funcall mark-sexp-func))
diff --git a/hypb.el b/hypb.el
index 90fd98bbc6..afa75dc6ac 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:     29-Jan-25 at 20:27:07 by Mats Lidell
+;; Last-Mod:     15-Mar-25 at 09:06:58 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -666,7 +666,11 @@ This will this install the Emacs helm package when needed."
 (defun hypb:in-string-p ()
   "Return non-nil iff point is in a double quoted string."
   (syntax-ppss-flush-cache (line-beginning-position))
-  (nth 3 (syntax-ppss)))
+  (let ((sexp-state-list (syntax-ppss)))
+    ;; if in a string
+    (when (nth 3 sexp-state-list)
+      ;; return start of str position (opening quote)
+      (nth 8 sexp-state-list))))
 
 (defun hypb:indirect-function (obj)
   "Return the function at the end of OBJ's function chain.
diff --git a/hyperbole.el b/hyperbole.el
index 6db1ed9c7e..30c4871bc1 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -9,12 +9,12 @@
 ;; Maintainer:   Robert Weiner <r...@gnu.org>
 ;; Maintainers:  Robert Weiner <r...@gnu.org>, Mats Lidell <ma...@gnu.org>
 ;; Created:      06-Oct-92 at 11:52:51
-;; Last-Mod:      2-Feb-25 at 07:27:43 by Bob Weiner
+;; Last-Mod:     16-Mar-25 at 10:11:31 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
 ;; Package:      hyperbole
-;; Package-Requires: ((emacs "27.2"))
+;; Package-Requires: ((emacs "28"))
 ;; URL:          http://www.gnu.org/software/hyperbole
 
 ;; See the "HY-COPY" file for license information.
diff --git a/hywiki.el b/hywiki.el
index c542d31475..ee206ae029 100644
--- a/hywiki.el
+++ b/hywiki.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Acpr-24 at 22:41:13
-;; Last-Mod:     25-Feb-25 at 02:39:08 by Bob Weiner
+;; Last-Mod:     16-Mar-25 at 10:05:36 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -236,7 +236,8 @@ Each element is of the form: (wikiword . (referent-type . 
referent-value)).")
 (defvar hywiki--end nil)
 (defvar hywiki--flag nil)
 (defvar hywiki--highlighting-done-flag t)
-(defvar hywiki--page-name nil)
+(defvar hywiki--word-pre-command nil)
+(defvar hywiki--word-only nil)
 (defvar hywiki--range nil)
 (defvar hywiki--save-case-fold-search nil)
 (defvar hywiki--save-org-link-type-required nil)
@@ -356,7 +357,7 @@ Presently, there are no key bindings; this is for future 
use.")
   "HyWiki string prefix type for Org links.  Excludes trailing colon.")
 
 (defvar hywiki-org-link-type-required t
-  "When non-nil, HyWiki Org links must start with `hywiki-org-link-type'.
+  "When non-nil, HyWiki Org links must start with `hywiki-org-link-type':.
 Otherwise, this prefix is not needed and HyWiki word Org links
 override standard Org link lookups.  See \"(org)Internal Links\".")
 
@@ -465,7 +466,7 @@ Do not use a start or end line/string anchor in this 
regexp.")
 
 (defconst hywiki-word-section-regexp
   "\\(#[^][# \t\n\r\f]+\\)"
-  "Regexp that matches a HyWiki word #section extension.
+  "Regexp that matches a non-delimited HyWiki word #section extension.
 After the first # character, this may contain any non-square-bracket,
 non-# and non-whitespace characters.")
 
@@ -556,22 +557,31 @@ Non-nil is the default."
   "Turn any HyWikiWords between point into highlighted Hyperbole buttons.
 Triggered by `post-self-insert-hook' for self-inserting characters.
 Highlight after inserting any non-word character."
+  ;; If `hywiki--flag' is set non-nil below, then
+  ;; `hywiki-buttonize-non-character-commands' on `post-command-hook'
+  ;; does nothing.
   (unless (setq hywiki--flag (hywiki-non-hook-context-p))
     (setq hywiki--range nil)
     (save-excursion
       (cond ((marker-position hywiki--buttonize-start)
-            (goto-char (1- hywiki--buttonize-start)))
-           ((setq hywiki--range (hywiki-word-at :range))
-            (cl-destructuring-bind (_ start end)
-                hywiki--range
-              (set-marker hywiki--buttonize-start start)
-              (set-marker hywiki--buttonize-end end))
-            (goto-char (1- hywiki--buttonize-start))))
-      (if (marker-position hywiki--buttonize-start)
-         (hywiki--maybe-de/highlight-sexp #'hywiki-maybe-highlight-page-names 
1)
-       (hywiki-maybe-highlight-between-page-names)))
-    (set-marker hywiki--buttonize-start nil)
-    (set-marker hywiki--buttonize-end nil)))
+            ;; Point was before or after a WikiWord delimiter
+            (goto-char hywiki--buttonize-start)
+            (skip-chars-backward "-" (line-beginning-position))
+            (goto-char (1- (point))))
+             ((setq hywiki--range (hywiki-word-at :range))
+              (cl-destructuring-bind (_ start end)
+                  hywiki--range
+                (if (and start end)
+                    (progn
+                      ;; On a non-delimited HyWikiWord
+                      (set-marker hywiki--buttonize-start start)
+                      (set-marker hywiki--buttonize-end end)
+                      (goto-char start)
+                      (skip-chars-backward "-" (line-beginning-position))
+                      t)
+                  (setq hywiki--range nil)))))
+
+      (hywiki--rehighlight-at-point))))
 
 (defun hywiki-buttonize-non-character-commands ()
   "Highlight any HyWikiWord before or after point as a Hyperbole button.
@@ -582,74 +592,73 @@ deletion commands and those in 
`hywiki-non-character-commands'."
              (and (symbolp this-command)
                   (string-match-p 
"^\\(org-\\)?\\(delete-\\|kill-\\)\\|\\(-delete\\|-kill\\)\\(-\\|$\\)" 
(symbol-name this-command))))
       (setq hywiki--range nil)
+
       (save-excursion
        (cond ((marker-position hywiki--buttonize-start)
-              (goto-char hywiki--buttonize-start))
+              ;; Point was before or after a WikiWord delimiter
+              (goto-char (1+ hywiki--buttonize-start)))
              ((setq hywiki--range (hywiki-word-at :range))
               (cl-destructuring-bind (_ start end)
                   hywiki--range
-                (set-marker hywiki--buttonize-start start)
-                (set-marker hywiki--buttonize-end end))
-              (goto-char hywiki--buttonize-start)))
-       (if (marker-position hywiki--buttonize-start)
-           (hywiki--maybe-de/highlight-sexp 
#'hywiki-maybe-highlight-page-names 1)
-         (hywiki-maybe-highlight-between-page-names)))
-      (set-marker hywiki--buttonize-start nil)
-      (set-marker hywiki--buttonize-end nil))))
-
-
-      ;; (when (and (marker-position hywiki--buttonize-start)
-      ;;                (marker-position hywiki--buttonize-end))
-
-      ;;       ;; When these markers are set, it means the command just
-      ;;       ;; edited a char within a delimited range that now needs any
-      ;;       ;; HyWikiWords inside to be re-highlighted.
-      ;;       (save-excursion
-      ;;         (goto-char hywiki--buttonize-start)
-      ;;         ;; (message "%s" (point))
-      ;;         (let ((opening-char (char-after))
-      ;;               closing-char)
-      ;;           (when (memq opening-char '(?\( ?\"))
-      ;;             (delete-char 1))
-      ;;           (hywiki-maybe-highlight-between-page-names)
-      ;;           (when (memq opening-char '(?\( ?\"))
-      ;;             (insert-before-markers opening-char))
-
-      ;;           (setq closing-char (char-before))
-      ;;           (when (memq closing-char '(?\) ?\"))
-      ;;             ;; (delete-char -1)
-      ;;             ;; (insert " ")
-      ;;             )
-      ;;           ;; (goto-char hywiki--buttonize-start)
-      ;;           (when (memq closing-char '(?\) ?\"))
-      ;;             ;; (goto-char (+ 2 hywiki--buttonize-end))
-      ;;             ;; (delete-char -1)
-      ;;             ;; (insert-before-markers closing-char)
-      ;;             ))))
-      ;; (hywiki-maybe-highlight-between-page-names))))
+                (if (and start end)
+                    (progn
+                      ;; On a non-delimited HyWikiWord
+                      (set-marker hywiki--buttonize-start start)
+                      (set-marker hywiki--buttonize-end end)
+                      (goto-char start)
+                      (skip-chars-backward "-" (line-beginning-position))
+                      t)
+                  (setq hywiki--range nil)))))
+
+       (hywiki--rehighlight-at-point)))))
+
+(defun hywiki--rehighlight-at-point ()
+  ;; Dehighlight any existing word only if the editing command
+  ;; has changed the word-only part of the WikiWord reference
+  (when (and hywiki--word-pre-command hywiki--range
+            (not (equal hywiki--word-pre-command
+                        (hywiki-get-singular-wikiword (car hywiki--range)))))
+    ;; Dehighlight if point is on or between a HyWikiWord
+    (hywiki-maybe-dehighlight-between-page-names))
+
+  ;; Highlight wikiwords around point as needed
+  (cond (hywiki--range
+        (hywiki-maybe-highlight-on-page-name))
+       ((and (marker-position hywiki--buttonize-start)
+             (marker-position hywiki--buttonize-end))
+        (hywiki--maybe-de/highlight-sexp
+         #'hywiki-maybe-highlight-page-names 1
+         hywiki--buttonize-start hywiki--buttonize-end))
+       (t (hywiki-maybe-highlight-between-page-names)))
+
+  (set-marker hywiki--buttonize-start nil)
+  (set-marker hywiki--buttonize-end nil))
 
 (defun hywiki-debuttonize-non-character-commands ()
-  "Dehighlight any HyWikiWord before or after point.
+  "Store any HyWikiWord before or after point for later comparison.
 Triggered by `pre-command-hook' for non-character-commands, including
 deletion commands and those in `hywiki-non-character-commands'."
+  (setq hywiki--word-pre-command nil)
   (when (and (markerp hywiki--buttonize-start) (markerp hywiki--buttonize-end))
     (set-marker hywiki--buttonize-start nil)
     (set-marker hywiki--buttonize-end nil))
   (unless (hywiki-non-hook-context-p)
+    ;; Record the WikiWord from any WikiWord ref that point is on
+    (setq hywiki--word-pre-command (hywiki-get-singular-wikiword 
(hywiki-word-at)))
     (when (or (memq this-command hywiki-non-character-commands)
              (and (symbolp this-command)
                   (string-match-p 
"^\\(org-\\)?\\(delete-\\|kill-\\)\\|\\(-delete\\|-kill\\)\\(-\\|$\\)" 
(symbol-name this-command))))
-      (cl-destructuring-bind (start end)
-         ;; Get delimited region only if before or after delimiters,
-         ;; else return (nil nil).
-         (hywiki-get-delimited-range) ;; includes delimiters
-       ;; Use these to store any range of a delimited HyWikiWord#section
-       (set-marker hywiki--buttonize-start start)
-       (set-marker hywiki--buttonize-end end)
-       ;; Enable dehighlighting in HyWiki pages
-       (unless (and start end)
-         ;; Dehighlight any page name at point
-         (hywiki-maybe-dehighlight-between-page-names)))))
+      ;; Test if at delimiters surrounding a WikiWord and if so,
+      ;; record those for use by post hooks.
+      (save-excursion
+       (cl-destructuring-bind (start end)
+           ;; Get delimited region only if before or after delimiters,
+           ;; else return (nil nil).
+           (hywiki-at-range-delimiter) ;; includes delimiters
+         ;; Use these to store any range of a delimited HyWikiWord#section
+         (set-marker hywiki--buttonize-start start)
+         (set-marker hywiki--buttonize-end end)
+         start))))
   (setq hywiki--flag nil))
 
 (defun hywiki-buttonize-word (func start end face)
@@ -1451,14 +1460,8 @@ Use when publishing a HyWiki file to another format, 
e.g. html.
 
 For example, the link:
   \"WikiWord#Multi-Word Section\"
-or
-  \"[[hy:WikiWord#Multi-Word Section]]\"
 is converted to:
-  \"[[file:<hywiki-directory>/WikiWord.org::Multi-Word 
Section][WikiWord#Multi-Word Section]]\".
-
-If the reference is in a file within the `hywiki-directory', it
-simplifies to:
-  \"[[file:WikiWord.org::Multi-Word Section][WikiWord#Multi-Word Section]]\".
+  \"[[hy:WikiWord#Multi-Word Section]]\".
 
 If the reference is within the WikiWord page to which it refers, it
 simplifies to:
@@ -1660,8 +1663,8 @@ positions of each HyWikiWord and its optional #section."
            (overlays-in (point-min) (point-max)))))
   nil)
 
-(defun hywiki-get-delimited-range ()
-  "Before or after a balanced delimiter, return the delimited range list.
+(defun hywiki-at-range-delimiter ()
+  "Immediately before or after a balanced delimiter, return the delimited 
range.
 If no such range, return \\='(nil nil).
 This includes the delimiters: (), {}, <>, [] and \"\" (double quotes)."
   (save-excursion
@@ -1867,11 +1870,28 @@ Return t if no errors and a pair was found, else nil."
        (when result t)))))
 
 (defun hywiki-maybe-dehighlight-between-page-names ()
-  "Dehighlight any non-Org link HyWiki page#section names between point.
+  "Dehighlight any non-Org link HyWiki page#section between point.
 If in a programming mode, must be within a comment.  Use
 `hywiki-word-face' to dehighlight."
-  (hywiki-maybe-dehighlight-off-page-name)
-  (hywiki-maybe-dehighlight-on-page-name))
+  (cond ((hproperty:char-property-range (point) 'face hywiki-word-face)
+        ;; This is called in pre-command-hook before any chars are
+        ;; deleted, so have to dehighlight it though it still temporarily
+        ;; may be a valid HyWikiWord.
+        (hywiki-maybe-dehighlight-on-page-name))
+       ((cl-destructuring-bind (start end)
+           (hywiki-at-range-delimiter)
+         (when (and start end)
+           (save-excursion
+             (goto-char (1+ start))
+             (and (hproperty:char-property-range (point) 'face 
hywiki-word-face)
+                  (equal (hywiki-referent-exists-p :range)
+                         '(nil nil nil))
+                  ;; non-existing wikiword
+                  (hywiki-maybe-dehighlight-on-page-name)))
+           t)))
+       ((looking-at "[ \t\n\r\f]")
+        (hywiki-maybe-dehighlight-off-page-name)
+        (hywiki-maybe-dehighlight-on-page-name))))
 
 (defun hywiki-maybe-dehighlight-off-page-name ()
   "Dehighlight any non-Org link HyWiki page#section at or one char before 
point.
@@ -1882,7 +1902,7 @@ in a programming mode, must be within a comment."
   (hywiki-maybe-dehighlight-page-name
    ;; Flag on-page-name if on a whitespace character
    (or (= (point) (point-max))
-       (eq (char-syntax (char-after)) ? ))))
+       (= (if (char-after) (char-syntax (char-after)) 0) ? ))))
 
 (defun hywiki-maybe-dehighlight-on-page-name ()
   "Dehighlight any non-Org link HyWiki page#section at or one char before 
point.
@@ -1893,7 +1913,7 @@ be within a comment."
   (hywiki-maybe-dehighlight-page-name
    ;; Flag on-page-name if not on a whitespace character
    (and (/= (point) (point-max))
-       (/= (char-syntax (char-after)) ? ))))
+       (/= (if (char-after) (char-syntax (char-after)) 0) ? ))))
 
 ;;;###autoload
 (defun hywiki-maybe-dehighlight-page-name (&optional on-page-name)
@@ -1947,10 +1967,10 @@ If in a programming mode, must be within a comment.  Use
            (if (and (hywiki-maybe-at-wikiword-beginning)
                     (looking-at hywiki--word-and-buttonize-character-regexp)
                     (progn
-                      (setq hywiki--page-name (match-string-no-properties 2)
+                      (setq hywiki--word-only (match-string-no-properties 2)
                             hywiki--start (match-beginning 1)
                             hywiki--end   (match-end 1))
-                      (hywiki-get-referent hywiki--page-name)))
+                      (hywiki-get-referent hywiki--word-only)))
                (when (setq hywiki--buts (hproperty:but-get-all-in-region
                                          hywiki--start hywiki--end
                                          'face hywiki-word-face))
@@ -1964,11 +1984,11 @@ If in a programming mode, must be within a comment.  Use
 
 ;;;###autoload
 (defun hywiki-maybe-highlight-page-name (&optional on-page-name)
-  "Highlight any non-Org link HyWiki page#section at or one char before point.
+  "Highlight any non-Org link HyWikiWord#section at or one char before point.
 With optional ON-PAGE-NAME non-nil, assume point is within the page or
-section name.  Otherwise, if `pre-command-hook' has set
+section name.  Otherwise, if a HyWiki per-character hook has set
 `hywiki--buttonize-start' `hywiki--buttonize-end' global variables,
-use these as the region in which to highlight.
+use these as the region to highlight.
 
 If in a programming mode, must be within a comment.  Use
 `hywiki-word-face' to highlight.  Do not highlight references to
@@ -1977,7 +1997,7 @@ the current page unless they have sections attached."
   (when (and (hywiki-active-in-current-buffer-p)
             (if (and (derived-mode-p 'prog-mode)
                      (not (apply #'derived-mode-p 
hywiki-highlight-all-in-prog-modes)))
-                ;; Non-nil if match is inside a comment
+                ;; Non-nil if match is inside a comment or string
                 (or (nth 4 (syntax-ppss)) (hypb:in-string-p))
               t)
             ;;  (or on-page-name
@@ -1988,78 +2008,77 @@ the current page unless they have sections attached."
       (setq hywiki--highlighting-done-flag nil)
       (with-syntax-table hbut:syntax-table
        (save-excursion
-         (save-restriction
-           (when (and (marker-position hywiki--buttonize-start)
-                      (marker-position hywiki--buttonize-end))
-             (narrow-to-region hywiki--buttonize-start hywiki--buttonize-end)
-             (goto-char hywiki--buttonize-start))
+         (when (and (marker-position hywiki--buttonize-start)
+                    (marker-position hywiki--buttonize-end))
+           (goto-char hywiki--buttonize-start))
 
-           (unless on-page-name
-             ;; after page name
-             (skip-syntax-backward ">-"))
+         (unless on-page-name
+           ;; after page name
+           (skip-syntax-backward ">-"))
 
-           (unless (or hywiki--highlighting-done-flag
-                       (hywiki-maybe-highlight-balanced-pairs))
+         (unless (or hywiki--highlighting-done-flag
+                     (hywiki-maybe-highlight-balanced-pairs))
 
-             (unless on-page-name
-               ;; May be a closing delimiter that we have to skip past
-               (skip-chars-backward (regexp-quote 
(hywiki-get-buttonize-characters))))
-             ;; Skip past HyWikiWord or section
+           (unless on-page-name
+             ;; May be a HyWikiWord ending character to skip past
+             (skip-chars-backward (hywiki-get-buttonize-characters)
+                                  (line-beginning-position)))
+           ;; Skip past HyWikiWord or section
+           (skip-syntax-backward "^-$()<>._\"\'")
+           (skip-chars-backward "-_*#:[:alnum:]")
+
+           (setq hywiki--save-case-fold-search case-fold-search
+                 case-fold-search nil
+                 hywiki--save-org-link-type-required 
hywiki-org-link-type-required
+                 hywiki-org-link-type-required t
+                 hywiki--start nil
+                 hywiki--end   nil)
+
+           (if (and (cl-destructuring-bind (word start end)
+                        (hywiki-word-at :range)
+                      (setq hywiki--word-only word
+                            hywiki--start start
+                            hywiki--end end))
+                    hywiki--start
+                    (hywiki-get-referent hywiki--word-only)
+                    (goto-char hywiki--start))
+               (progn
+                 (setq hywiki--current-page (hywiki-get-buffer-page-name))
+                 ;; Don't highlight current-page matches unless they
+                 ;; include a #section.
+                 (unless (string-equal hywiki--current-page
+                                       (buffer-substring-no-properties
+                                        hywiki--start hywiki--end))
+                   (if (setq hywiki--buts (hproperty:but-get-all-in-region
+                                           hywiki--start hywiki--end
+                                           'face hywiki-word-face))
+                       (if (> (length hywiki--buts) 1)
+                           (progn (hproperty:but-clear-all-in-list 
hywiki--buts)
+                                  (hywiki-maybe-highlight-page-names
+                                   hywiki--start hywiki--end))
+                         ;; There is only one existing button
+                         (setq hywiki--buts (car hywiki--buts)
+                               hywiki--but-start (hproperty:but-start 
hywiki--buts)
+                               hywiki--but-end   (hproperty:but-end 
hywiki--buts))
+                         (unless (and (= hywiki--start hywiki--but-start)
+                                      (= hywiki--end hywiki--but-end))
+                           (hproperty:but-delete hywiki--buts)
+                           (hywiki-maybe-highlight-page-names
+                            hywiki--start hywiki--end)))
+                     (hywiki-maybe-highlight-page-names
+                      hywiki--start hywiki--end))))
+             ;; Remove any potential earlier highlighting since the
+             ;; previous word may have changed.
              (skip-syntax-backward "^-$()<>._\"\'")
-             (skip-chars-backward "-_*#:[:alnum:]")
-
-             (setq hywiki--save-case-fold-search case-fold-search
-                   case-fold-search nil
-                   hywiki--save-org-link-type-required 
hywiki-org-link-type-required
-                   hywiki-org-link-type-required t
-                   hywiki--start nil
-                   hywiki--end   nil)
-
-             (if (and (hywiki-maybe-at-wikiword-beginning)
-                      (looking-at hywiki--word-and-buttonize-character-regexp)
-                      (progn
-                        (setq hywiki--page-name (match-string-no-properties 2)
-                              hywiki--start (match-beginning 1)
-                              ;; This excludes optional char after the 
page#section
-                              hywiki--end   (match-end 1))
-                        (hywiki-get-referent hywiki--page-name)))
-                 (progn
-                   (setq hywiki--current-page (hywiki-get-buffer-page-name))
-                   ;; Don't highlight current-page matches unless they
-                   ;; include a #section.
-                   (unless (string-equal hywiki--current-page
-                                         (buffer-substring-no-properties
-                                          hywiki--start hywiki--end))
-                     (if (setq hywiki--buts (hproperty:but-get-all-in-region
-                                             hywiki--start hywiki--end
-                                             'face hywiki-word-face))
-                         (if (> (length hywiki--buts) 1)
-                             (progn (hproperty:but-clear-all-in-list 
hywiki--buts)
-                                    (hywiki-maybe-highlight-page-names
-                                     hywiki--start hywiki--end))
-                           ;; There is only one existing button
-                           (setq hywiki--buts (car hywiki--buts)
-                                 hywiki--but-start (hproperty:but-start 
hywiki--buts)
-                                 hywiki--but-end   (hproperty:but-end 
hywiki--buts))
-                           (unless (and (= hywiki--start hywiki--but-start)
-                                        (= hywiki--end hywiki--but-end))
-                             (hproperty:but-delete hywiki--buts)
-                             (hywiki-maybe-highlight-page-names
-                              hywiki--start hywiki--end)))
-                       (hywiki-maybe-highlight-page-names
-                        hywiki--start hywiki--end))))
-               ;; Remove any potential earlier highlighting since the
-               ;; previous word may have changed.
-               (skip-syntax-backward "^-$()<>._\"\'")
-               (if (setq hywiki--buts (hproperty:but-get-all-in-region
+             (when (setq hywiki--buts (hproperty:but-get-all-in-region
                                        (point) (1+ (point)) 'face 
hywiki-word-face))
-                   (if (> (length hywiki--buts) 1)
-                       (hproperty:but-clear-all-in-list hywiki--buts)
-                     ;; There is only one existing button
-                     (setq hywiki--buts (car hywiki--buts)
-                           hywiki--but-start (hproperty:but-start hywiki--buts)
-                           hywiki--but-end   (hproperty:but-end hywiki--buts))
-                     (hproperty:but-delete hywiki--buts))))))))))
+               (if (> (length hywiki--buts) 1)
+                   (hproperty:but-clear-all-in-list hywiki--buts)
+                 ;; There is only one existing button
+                 (setq hywiki--buts (car hywiki--buts)
+                       hywiki--but-start (hproperty:but-start hywiki--buts)
+                       hywiki--but-end   (hproperty:but-end hywiki--buts))
+                 (hproperty:but-delete hywiki--buts)))))))))
 
 (defun hywiki-maybe-highlight-between-page-names ()
   "Highlight any non-Org link HyWiki page#section names between point.
@@ -2067,8 +2086,31 @@ the current page unless they have sections attached."
 If in a programming mode, must be within a comment.  Use
 `hywiki-word-face' to highlight.  Do not highlight references to
 the current page unless they have sections attached."
-  (hywiki-maybe-highlight-off-page-name)
-  (hywiki-maybe-highlight-on-page-name))
+  (cond ((hproperty:char-property-range (point) 'face hywiki-word-face))
+       ((cl-destructuring-bind (word start end)
+            (hywiki-word-at :range)
+          (when (and start end)
+            (save-excursion
+              (goto-char start)
+              (when (hywiki-referent-exists-p word)
+                ;; existing wikiword
+                (hywiki-maybe-highlight-on-page-name)))
+            t)))
+       ((cl-destructuring-bind (start end)
+            (hywiki-at-range-delimiter)
+          (when (and start end)
+            (save-excursion
+              (goto-char (1+ start))
+              (skip-syntax-forward "-" (line-end-position))
+              (unless (equal (hywiki-referent-exists-p :range)
+                             '(nil nil nil))
+                ;; existing wikiword
+                (hywiki-maybe-highlight-on-page-name)))
+            t)))
+       ((looking-at "[ \t\n\r\f]")
+        (hywiki-maybe-highlight-off-page-name)
+        (hywiki-maybe-highlight-on-page-name))
+       (t (hywiki-maybe-highlight-on-page-name))))
 
 (defun hywiki-maybe-highlight-off-page-name ()
   "Highlight any non-Org link HyWiki page#section at or one char before point.
@@ -2097,7 +2139,7 @@ the current page unless they have sections attached."
   (hywiki-maybe-highlight-page-name
    ;; flag on-page-name if not on a whitespace character
    (and (/= (point) (point-max))
-       (/= (char-syntax (char-after)) ? ))))
+       (/= (if (char-after) (char-syntax (char-after)) 0) ? ))))
 
 (defun hywiki-maybe-dehighlight-org-element-backward ()
   "Dehighlight HyWikiWords within a closing double/single square/angle 
bracket."
@@ -2156,8 +2198,8 @@ interactively), limit dehighlighting to the region."
       'face hywiki-word-face))
     (unless (or region-start region-end)
       (setq hywiki-buffer-highlighted-state 'd))))
-
-;;;###autoload
+;
+;;###autoload
 (defun hywiki-maybe-highlight-page-names (&optional region-start region-end 
skip-lookups-update-flag)
   "Highlight each non-Org link HyWiki page#section in a buffer/region.
 With optional REGION-START and REGION-END positions or markers (active
@@ -2199,9 +2241,12 @@ value of `hywiki-word-highlight-flag' is changed."
                           (narrow-to-region region-start region-end)))
                      ((and region-start region-end)
                       (narrow-to-region region-start region-end)))
-               ;; Enable dehighlighting in HyWiki pages
-               (let ((hywiki-word-highlight-flag))
-                 (hywiki-maybe-dehighlight-page-names))
+               ;; Enable dehighlighting in HyWiki pages only when
+               ;; whole buffer is being processed; this prevents an
+               ;; error when called from `hywiki-maybe-highlight-sexp'.
+               (unless (and region-start region-end)
+                 (let ((hywiki-word-highlight-flag))
+                   (hywiki-maybe-dehighlight-page-names)))
                (dolist (hywiki-words-regexp hywiki--any-wikiword-regexp-list)
                  (goto-char (point-min))
                  (let ((highlight-in-comments-and-strings-only
@@ -2426,7 +2471,7 @@ regexps of wikiwords, if the hash table is out-of-date."
 (defun hywiki-get-singular-wikiword (wikiword)
   "Return the singular version of the given WIKIWORD with any suffix removed.
 If `hywiki-allow-plurals-flag' is nil, return unchanged WIKIWORD name
-with andy suffix removed."
+with any suffix removed."
   (setq wikiword (hywiki-word-strip-suffix wikiword))
   (if (or (not hywiki-allow-plurals-flag)
          (not (stringp wikiword)))
@@ -2512,7 +2557,10 @@ save and potentially set `hywiki--directory-mod-time' and
   (or (file-writable-p save-file)
       (error "(hywiki-cache-save): Non-writable Environment file, \"%s\"" 
save-file))
   (let ((buf (get-file-buffer save-file)))
-    (and buf (kill-buffer buf)))
+    (when buf
+      (if (buffer-modified-p buf)
+         (error "(hywiki-cache-save): Attempt to kill modified Environment 
file failed to save, \"%s\"" save-file)
+       (kill-buffer buf))))
   (let ((dir (or (file-name-directory save-file)
                 default-directory)))
     (or (file-writable-p dir)
@@ -2538,8 +2586,9 @@ save and potentially set `hywiki--directory-mod-time' and
        (princ ")\n")
 
        (save-buffer)
-       (set-buffer-modified-p nil)
-       (kill-buffer standard-output)))))
+       (if (buffer-modified-p)
+           (error "(hywiki-cache-save): Attempt to kill modified Environment 
file failed to save, \"%s\"" save-file)
+         (kill-buffer standard-output))))))
 
 (defun hywiki-make-referent-hasht ()
   "Rebuld referent hasht from list of HyWiki page files and non-page entries."
@@ -2766,35 +2815,35 @@ Customize this directory with:
     (advice-remove #'org-export-get-reference 
#'hywiki--org-export-get-reference)))
 
 (defun hywiki-referent-exists-p (&optional word start end)
-  "Return an optional HyWiki WORD or word at point, if has an existing 
referent.
+  "Return the HyWikiWord at point or optional HyWiki WORD, if has a referent.
 If no such referent exists, return nil.
 
 Word may be of form:
  1. HyWikiWord#section with an optional #section.
  2. If WORD is the symbol, :range, and there is a HyWikiWord at point
     with an existing referent, return the tuple of values: (word
-    word-start word-end) instead of the word.
+    word-start word-end) instead of the word; otherwise, return the tuple
+    '(nil nil nil).
 
 When using the word at point, a call to `hywiki-active-in-current-buffer-p'
-at point must return non-nil or this function will return nil." 
-  (setq hywiki--page-name word)
+at point must return non-nil or this function will return nil."
+  (setq hywiki--word-only word)
   (when (stringp word)
     (setq word (hywiki-strip-org-link word)))
   (if (or (stringp word)
          (setq word (hywiki-word-at word)))
-      (unless (hywiki-get-referent word)
+      (unless (hywiki-get-referent (if (stringp word) word (nth 0 word)))
        (setq word nil))
     (setq word nil))
   (when (and (listp word) (= (length word) 3))
     (setq start (nth 1 word)
          end   (nth 2 word)
+         ;; `word' must be set last so list version can be referenced
+         ;; first above
          word  (nth 0 word)))
-  (if (eq hywiki--page-name :range)
-      (if (and word (setq hywiki--range
-                         (hproperty:char-property-range
-                          (point) 'face hywiki-word-face)))
-         (list word (or start (car hywiki--range)) (or end (cdr 
hywiki--range)))
-       (list word start end))
+  (if (eq hywiki--word-only :range)
+      (or (hywiki-word-at :range)
+         (list word start end))
     word))
 
 (defun hywiki-strip-org-link (link-str)
@@ -2868,116 +2917,140 @@ Action Key press; with a prefix ARG, emulate an 
Assist Key press."
 
 (defun hywiki-word-at (&optional range-flag)
   "Return potential HyWikiWord and optional #section:Lnum:Cnum at point or nil.
-Point should be on the HyWikiWord itself.
+If the HyWikiWord is delimited, Point must be within the delimiters.
 
 With optional RANGE-FLAG, return a list of (HyWikiWord start-position
-end-position); the positions are for only the HyWikiWord itself.
+end-position); the positions include the entire
+HyWikiWord#section:Lnum:Cnum string but exclude any delimiters.
 
 This does not test whether a referent exists for the HyWiki word; call
 `hywiki-referent-exists-p' without an argument for that.
 
 A call to `hywiki-active-in-current-buffer-p' at point must return non-nil
 or this will return nil."
-  (when (hywiki-active-in-current-buffer-p)
-    (if (setq hywiki--range
-             (hproperty:char-property-range (point) 'face hywiki-word-face))
-       (let ((wikiword (buffer-substring-no-properties (car hywiki--range) 
(cdr hywiki--range))))
-         (when (string-match hywiki-word-with-optional-suffix-exact-regexp 
wikiword)
-           (if range-flag
-               (list wikiword (car hywiki--range) (cdr hywiki--range))
-             wikiword)))
-      (save-excursion
-       ;; Don't use `cl-destructuring-bind' here since the `hargs:delimited' 
call
-       ;; can return nil rather than the 3 arg list that would be required
-       (let* ((wikiword-start-end
-               (let ((start-regexp (concat "\\[\\[\\(" hywiki-org-link-type 
":\\)?")))
-                 (save-excursion
-                   (skip-chars-backward (concat hywiki-org-link-type ":["))
-                   (when (looking-at start-regexp)
-                     (goto-char (match-end 0)))
-                   (hargs:delimited (concat "\\[\\[\\(" hywiki-org-link-type 
":\\)?")
-                                    "\\(\\]\\[\\|\\]\\]\\)" t t t))))
-              (wikiword (nth 0 wikiword-start-end))
-              (start    (nth 1 wikiword-start-end))
-              (end      (nth 2 wikiword-start-end)))
-         (when (cond (wikiword
-                      ;; Handle an Org link [[HyWikiWord]] [[hy:HyWikiWord]]
-                      ;; or [[HyWikiWord#section][Description Text]].
-                      ;; Get the HyWikiWord link reference, ignoring any
-                      ;; description given in the link
-                      ;; Don't use next line so don't have to load all of Org
-                      ;; mode just to check for HyWikiWords; however, disables
-                      ;; support for Org mode aliases.
-                      ;; (setq wikiword (org-link-expand-abbrev 
(org-link-unescape (string-trim wikiword))))
-                      (setq wikiword (hywiki-strip-org-link wikiword))
-                      (when (and wikiword end)
-                        ;; Update start and end to newly stripped
-                        ;; string positions
-                        (save-excursion
-                          (save-restriction
-                            (narrow-to-region start end)
-                            (goto-char (point-min))
-                            (when (search-forward wikiword nil t)
-                              (setq start (match-beginning 0)
-                                    end   (match-end 0))))))
-                      (hywiki-word-is-p wikiword))
-
-                     ;; Handle when pre-command-hook has dehighlighted a
-                     ;; delimited HyWikiWord reference with multiple
-                     ;; words in its section, e.g. (WikiWord#one two
-                     ;; three).  That is, allow for spaces in the
-                     ;; section.
-                     ((with-syntax-table hywiki--org-mode-syntax-table
-                        (unless (or (= (if (char-after) (char-syntax 
(char-after)) 0) ?\()
-                                    (= (if (char-before) (char-syntax 
(char-before)) 0) ?\)))
+  (if (hywiki-active-in-current-buffer-p)
+      ;; (if (setq hywiki--range
+      ;;               (hproperty:char-property-range (point) 'face 
hywiki-word-face))
+      ;;         (let ((wikiword (buffer-substring-no-properties (car 
hywiki--range) (cdr hywiki--range))))
+      ;;           (if (string-match 
hywiki-word-with-optional-suffix-exact-regexp wikiword)
+      ;;               (if range-flag
+      ;;                   (list wikiword (car hywiki--range) (cdr 
hywiki--range))
+      ;;                 wikiword)
+      ;;             (when range-flag
+      ;;               '(nil nil nil))))
+       (save-excursion
+         ;; Don't use `cl-destructuring-bind' here since the `hargs:delimited' 
call
+         ;; can return nil rather than the 3 arg list that would be required
+         (let* ((wikiword-start-end
+                 (let ((start-regexp (concat "\\[\\[\\(" hywiki-org-link-type 
":\\)?")))
+                   (save-excursion
+                     (skip-chars-backward (concat hywiki-org-link-type ":["))
+                     (when (looking-at start-regexp)
+                       (goto-char (match-end 0)))
+                     (hargs:delimited (concat "\\[\\[\\(" hywiki-org-link-type 
":\\)?")
+                                      "\\(\\]\\[\\|\\]\\]\\)" t t t))))
+                (wikiword (nth 0 wikiword-start-end))
+                (start    (nth 1 wikiword-start-end))
+                (end      (nth 2 wikiword-start-end)))
+           (with-syntax-table hywiki--org-mode-syntax-table
+             (if (cond (wikiword
+                        ;; Handle an Org link [[HyWikiWord]] [[hy:HyWikiWord]]
+                        ;; or [[HyWikiWord#section][Description Text]].
+                        ;; Get the HyWikiWord link reference, ignoring any
+                        ;; description given in the link
+                        ;; Don't use next line so don't have to load all of Org
+                        ;; mode just to check for HyWikiWords; however, 
disables
+                        ;; support for Org mode aliases.
+                        ;; (setq wikiword (org-link-expand-abbrev 
(org-link-unescape (string-trim wikiword))))
+                        (setq wikiword (hywiki-strip-org-link wikiword))
+                        (when (and wikiword end)
+                          ;; Update start and end to newly stripped
+                          ;; string positions
                           (save-excursion
-                            (condition-case ()
-                                (backward-up-list)
-                              (error nil))
-                            (when (= (if (char-after) (char-syntax 
(char-after)) 0) ?\()
-                              (goto-char (1+ (point)))
-                              (when (looking-at (concat hywiki-word-regexp 
"\\(#[^][()<>{}\"\n\r\f]+\\)?"
-                                                        
hywiki-word-line-and-column-numbers-regexp "?"))
+                            (save-restriction
+                              (narrow-to-region start end)
+                              (goto-char (point-min))
+                              (when (search-forward wikiword nil t)
                                 (setq start (match-beginning 0)
-                                      end   (match-end 0)
-                                      ;; No following char
-                                      wikiword (string-trim
-                                                
(buffer-substring-no-properties start end)))))))))
-
-                     ;; Handle a non-delimited HyWikiWord with optional
-                     ;; #section:Lnum:Cnum; if it is an Org link, it may
-                     ;; optionally have a hy: link-type prefix.  Ignore
-                     ;; wikiwords preceded by any non-whitespace
-                     ;; character, except any of these: "([\"'`'"
-                     (t (let ((case-fold-search nil))
-                          (progn
-                            ;; May be a closing delimiter that we have to skip 
past
-                            (skip-chars-backward (regexp-quote 
(hywiki-get-buttonize-characters)))
-                            ;; Skip past HyWikiWord or section
-                            (skip-syntax-backward "^-$()<>._\"\'")
-                            (skip-chars-backward "-_*#:[:alnum:]"))
-                          (when (hywiki-maybe-at-wikiword-beginning)
-                            (cond ((looking-at 
hywiki--word-and-buttonize-character-regexp)
-                                   (setq start (match-beginning 1)
-                                         end (match-end 1)
-                                         wikiword (string-trim
-                                                   
(buffer-substring-no-properties start end))))
-                                  ((and (looking-at 
hywiki-word-with-optional-suffix-regexp)
-                                        ;; Can't be followed by a # character
-                                        (/= (or (char-after (match-end 0)) 0)
-                                            ?#))
-                                   (setq start (match-beginning 0)
-                                         end   (match-end 0)
-                                         ;; No following char
-                                         wikiword (string-trim
-                                                   
(buffer-substring-no-properties start end)))))))))
-           (if range-flag
-               (list wikiword start end)
-             wikiword)))))))
+                                      end   (match-end 0))))))
+                        (hywiki-word-is-p wikiword))
+
+                       ;; Handle a delimited HyWikiWord reference
+                       ;; with multiple words in its section,
+                       ;; e.g. (MyWikiWord WikiWord#one two three).
+                       ;; That is, allow for spaces in the section
+                       ;; and possible multiple WikiWords within the
+                       ;; delimiters.
+                       ((let ((case-fold-search nil)
+                              (bol (line-beginning-position))
+                              opoint)
+                          ;; May be a HyWikiWord ending character to skip past
+                          (skip-chars-backward 
(hywiki-get-buttonize-characters) bol)
+                          (setq opoint (point))
+                          ;; Skip past HyWikiWord or section
+                          (skip-syntax-backward "^$()<>._\"\'" bol)
+                          (unless (= (or (char-before) 0) ?#)
+                            (goto-char opoint)
+                            (skip-syntax-backward "^-$()<>._\"\'" bol))
+                          (skip-chars-backward "-_*#:[:alnum:]" bol)
+                          (skip-syntax-backward "-" bol)
+                          (when (and (cl-find (char-before) "\[\(\{\<\"")
+                                     (progn
+                                       (skip-syntax-forward "-")
+                                       (hywiki-maybe-at-wikiword-beginning))
+                                     (looking-at (concat hywiki-word-regexp 
"\\(#[^][#()<>{}\"\n\r\f]+\\)?"
+                                                         
hywiki-word-line-and-column-numbers-regexp "?"))
+                                     (progn (goto-char (match-end 0))
+                                            (skip-chars-forward "-")))
+                            (setq start (match-beginning 0)
+                                  end   (match-end 0)
+                                  ;; No following char
+                                  wikiword (string-trim
+                                            (buffer-substring-no-properties 
start end))))))
+
+                       ;; Handle a non-delimited HyWikiWord with optional
+                       ;; #section:Lnum:Cnum; if it is an Org link, it may
+                       ;; optionally have a hy: link-type prefix.  Ignore
+                       ;; wikiwords preceded by any non-whitespace
+                       ;; character, except any of these: "([\"'`'"
+                       (t (let ((case-fold-search nil))
+                            (skip-syntax-forward "-")
+                            (when (hywiki-maybe-at-wikiword-beginning)
+                              (when (looking-at (concat hywiki-org-link-type 
":"))
+                                (goto-char (match-end 0)))
+                              (cond ((looking-at 
hywiki--word-and-buttonize-character-regexp)
+                                     (setq start (match-beginning 1)
+                                           end (match-end 1)
+                                           wikiword (string-trim
+                                                     
(buffer-substring-no-properties start end))))
+                                    ((and (looking-at 
hywiki-word-with-optional-suffix-regexp)
+                                          ;; Can't be followed by a # character
+                                          (/= (or (char-after (match-end 0)) 0)
+                                              ?#))
+                                     (setq start (match-beginning 0)
+                                           end   (match-end 0)
+                                           ;; No following char
+                                           wikiword (string-trim
+                                                     
(buffer-substring-no-properties start end)))))))))
+                 (if range-flag
+                     (list wikiword start end)
+                   wikiword)
+               (when range-flag
+                 '(nil nil nil))))))
+       ;; )
+    (when range-flag
+      '(nil nil nil))))
 
 (defun hywiki-word-at-point ()
   "Return singular HyWikiWord at point with its suffix stripped or nil.
-Point should be on the HyWikiWord itself."
+Point should be on the HyWikiWord itself.  Suffix is anything after
+the # symbol.
+
+This does not test whether a referent exists for the HyWiki word; call
+`hywiki-referent-exists-p' without an argument for that.
+
+A call to `hywiki-active-in-current-buffer-p' at point must return non-nil
+or this will return nil."
   (hywiki-get-singular-wikiword (hywiki-word-strip-suffix (hywiki-word-at))))
 
 ;;;###autoload
@@ -3220,19 +3293,21 @@ delimited grouping."
       ;; single delimiters - highlight
       (funcall func 1))))
 
-(defun hywiki--maybe-de/highlight-sexp (func direction-number)
-  "De/highlight HyWikiWord with FUNC on a single square/angle bracket.
+(defun hywiki--maybe-de/highlight-sexp (func direction-number &optional 
sexp-start sexp-end)
+  "De/highlight HyWikiWord with FUNC on a single paired delimiter char.
 DIRECTION-NUMBER is 1 for forward scanning and -1 for backward scanning."
-  (let* ((sexp-start (point))
-        (sexp-end (scan-sexps sexp-start direction-number)))
-    (when (and sexp-start sexp-end)
-      (cl-destructuring-bind (start end)
-         ;; Point may be at end of sexp, so start and end may
-         ;; need to be reversed.
-         (list (min sexp-start sexp-end) (max sexp-start sexp-end))
-       ;; Increment sexp-start so regexp matching excludes the
-       ;; delimiter and starts with the HyWikiWord.  But include any
-       ;; trailing delimiter or regexp matching will not work.
+  (setq sexp-start (or sexp-start (point))
+       sexp-end (or sexp-end (scan-sexps sexp-start direction-number)))
+  (when (and sexp-start sexp-end)
+    (cl-destructuring-bind (start end)
+       ;; Point may be at end of sexp, so start and end may
+       ;; need to be reversed.
+       (list (min sexp-start sexp-end) (max sexp-start sexp-end))
+      ;; Increment sexp-start so regexp matching excludes the
+      ;; delimiter and starts with the HyWikiWord.  But include any
+      ;; trailing delimiter or regexp matching will not work.
+      (save-restriction
+       (narrow-to-region (1+ start) end)
        (prog1 (funcall func (1+ start) end)
          (setq hywiki--highlighting-done-flag nil))))))
 
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index e66da842f1..438331af61 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:     19-Jan-25 at 18:06:31 by Bob Weiner
+@c Last-Mod:     16-Mar-25 at 10:23:12 by Bob Weiner
 
 @c %**start of header (This is for running Texinfo on a region.)
 @setfilename hyperbole.info
@@ -30,8 +30,8 @@
 @set txicodequoteundirected
 @set txicodequotebacktick
 
-@set UPDATED January, 2025
-@set UPDATED-MONTH January 2025
+@set UPDATED March, 2025
+@set UPDATED-MONTH March 2025
 @set EDITION 9.0.2pre
 @set VERSION 9.0.2pre
 
@@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</P>
 
 <PRE>
 Edition 9.0.2pre
-Printed January 19, 2025.
+Printed March 16, 2025.
 
   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
-January 19, 2025
+March 16, 2025
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -538,8 +538,8 @@ Smart Keyboard Keys
 @chapter Introduction
 
 This edition of the GNU Hyperbole Manual is for use with any version
-9.0.2pre or greater of GNU Hyperbole.  Hyperbole runs atop GNU Emacs 27.2
-or higher.  It will trigger an error if your Emacs is older.
+9.0.2pre or greater of GNU Hyperbole.  Hyperbole runs atop GNU Emacs
+28 or higher.  It will trigger an error if your Emacs is older.
 
 This chapter summarizes the structure of the rest of the manual,
 describes Hyperbole, lists some of its potential applications, and
@@ -8628,8 +8628,8 @@ the GNU Emacs Manual}).
 @group
 ;; Below are the lines to add:
 
-(when (< emacs-major-version 27)
-  (error "Hyperbole requires Emacs 27 or above, not %d"
+(when (< emacs-major-version 28)
+  (error "Hyperbole requires Emacs 28 or above, not %d"
          emacs-major-version))
 (require 'package)
 (unless (package-installed-p 'hyperbole)
@@ -8677,8 +8677,8 @@ the GNU Emacs Manual}).
 @group
 ;; Below are the lines to add:
 
-(when (< emacs-major-version 27)
-  (error "Hyperbole requires Emacs 27 or above, not %d"
+(when (< emacs-major-version 28)
+  (error "Hyperbole requires Emacs 28 or above, not %d"
          emacs-major-version))
 (require 'package)
 (add-to-list 'package-archives
@@ -8724,8 +8724,8 @@ the GNU Emacs Manual}).
 @group
 ;; Use this in your Emacs init file to install Straight
 (progn
-  (when (< emacs-major-version 27)
-    (error "Hyperbole requires Emacs 27 or above, not %d"
+  (when (< emacs-major-version 28)
+    (error "Hyperbole requires Emacs 28 or above, not %d"
            emacs-major-version))
   (defvar bootstrap-version)
   (setq package-enable-at-startup nil)
@@ -8785,8 +8785,8 @@ lines to your personal Emacs initialization file, 
@file{~/.emacs}:
 @lisp
 @group
 (unless (and (featurep 'hyperbole) hyperbole-mode)
-  (when (< emacs-major-version 27)
-    (error "Hyperbole requires Emacs 27 or above, not %d"
+  (when (< emacs-major-version 28)
+    (error "Hyperbole requires Emacs 28 or above, not %d"
            emacs-major-version))
   (push "<directory-ending-with-hyperbole-where-you-unpacked>"
         load-path)
diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el
index e406e55a75..0984235223 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:     24-Feb-25 at 00:46:05 by Bob Weiner
+;; Last-Mod:     14-Mar-25 at 17:35:00 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -203,14 +203,16 @@ line 2
           ;; Matches a WikiWord
           (dolist (v '("WikiWord" "[WikiWord]" "[[WikiWord]]" "{WikiWord}" 
"(WikiWord)"
                        "<WikiWord>" "<<WikiWord>>" "{[[WikiWord]]}" 
"([[WikiWord]])"
-                       "[WikiWord AnotherWord]"
+                       "[WikiWord AnotherWord WikiWord WikiWord]"
                        ))
             (with-temp-buffer
               (org-mode)
               (insert v)
              (newline nil t)
               (goto-char 6)
-              (should (string= "WikiWord" (hywiki-word-at)))))
+              (if (string= "WikiWord" (hywiki-word-at))
+                 (should t)
+               (should-not v))))
 
           ;; Does not match as a WikiWord
           (dolist (v '("WikiWord#"))
@@ -219,7 +221,9 @@ line 2
               (insert v)
              (newline nil t)
               (goto-char 6)
-              (should-not (string= "WikiWord" (hywiki-word-at)))))
+             (if (string= "WikiWord" (hywiki-word-at))
+                 (should-not v)
+               (should t))))
 
           ;; Identifies as org link (Note: Not checked if target
           ;; exists.) AND matches WikiWord
@@ -231,7 +235,9 @@ line 2
               (goto-char 6)
               (font-lock-ensure)
               (should (hsys-org-face-at-p 'org-link))
-              (should (string= "WikiWord" (hywiki-word-at)))))
+             (if (string= "WikiWord" (hywiki-word-at))
+                 (should t)
+               (should-not v))))
 
           ;; Identifies as org link (Note: Not checked if target
           ;; exists.) AND DOES NOT match WikiWord
@@ -243,7 +249,9 @@ line 2
               (goto-char 6)
               (font-lock-ensure)
               (should (hsys-org-face-at-p 'org-link))
-              (should-not (string= "WikiWord" (hywiki-word-at))))))
+              (if (string= "WikiWord" (hywiki-word-at))
+                 (should-not v)
+               (should t)))))
       (hywiki-mode 0)
       (hy-delete-dir-and-buffer hywiki-directory))))
 
@@ -503,6 +511,7 @@ Both mod-time and checksum must be changed for a test to 
return true."
   (declare (indent 0) (debug t))
   `(progn
      (progn ,@body)
+     (setq this-command 'org-return)
      (funcall 'hywiki-debuttonize-non-character-commands)
      (funcall 'hywiki-buttonize-character-commands)
      (funcall 'hywiki-buttonize-non-character-commands)))
@@ -561,17 +570,20 @@ Both mod-time and checksum must be changed for a test to 
return true."
           (hywiki-tests--remove-hywiki-hooks)
           (with-temp-buffer
             (hywiki-mode 1)
-            (with-hywiki-buttonize-and-insert-hooks (insert "Wikiord "))
-            (goto-char 5)
+            (with-hywiki-buttonize-and-insert-hooks
+             (insert "Wikiord ")
+              (goto-char 5))
             (should (looking-at-p "ord"))
             (should-not (hproperty:but-get (point) 'face hywiki-word-face))
 
-            (with-hywiki-buttonize-and-insert-hooks (insert "W"))
-            (goto-char 5)
+            (with-hywiki-buttonize-and-insert-hooks
+             (insert "W")
+              (goto-char 5))
             (should (looking-at-p "Word"))
             (should (hproperty:but-get (point) 'face hywiki-word-face))
 
-            (with-hywiki-buttonize-and-insert-hooks (delete-char 1))
+            (with-hywiki-buttonize-and-insert-hooks
+             (delete-char 1))
             (should (looking-at-p "ord"))
             (should-not (hproperty:but-get (point) 'face hywiki-word-face))))
       (hywiki-tests--add-hywiki-hooks)
@@ -581,32 +593,35 @@ Both mod-time and checksum must be changed for a test to 
return true."
 
 (ert-deftest 
hywiki-tests--verify-face-property-when-editing-wikiword-first-char ()
   "Verify face property changes when WikiWord is edited in the first char 
position."
-  (let* ((hywiki-directory (make-temp-file "hywiki" t))
-         (wikipage (cdr (hywiki-add-page "WikiWord"))))
-    (skip-unless (not noninteractive))
-    (unwind-protect
-        (progn
-          (hywiki-tests--remove-hywiki-hooks)
-          (with-temp-buffer
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (let* ((hywiki-directory (make-temp-file "hywiki" t))
+           (wikipage (cdr (hywiki-add-page "WikiWord"))))
+      (unwind-protect
+          (progn
+            (hywiki-tests--remove-hywiki-hooks)
             (hywiki-mode 1)
             (with-hywiki-buttonize-and-insert-hooks (insert "WikiWord "))
             (goto-char 1)
             (should (looking-at-p "Wiki"))
             (should (hproperty:but-get (point) 'face hywiki-word-face))
 
-           (delete-char 1)
-           (hywiki-maybe-dehighlight-page-name t)
+            (with-hywiki-buttonize-and-insert-hooks
+             (delete-char 1))
             (should (looking-at-p "iki"))
             (should-not (hproperty:but-get (point) 'face hywiki-word-face))
 
-            (with-hywiki-buttonize-and-insert-hooks (insert "W"))
-            (goto-char 1)
+            (with-hywiki-buttonize-and-insert-hooks
+             (insert "W")
+              (goto-char 1))
             (should (looking-at-p "Wiki"))
-            (should (hproperty:but-get (point) 'face hywiki-word-face))))
-      (hywiki-tests--add-hywiki-hooks)
-      (hywiki-mode 0)
-      (hy-delete-files-and-buffers (list wikipage))
-      (hy-delete-dir-and-buffer hywiki-directory))))
+            (should (hproperty:but-get (point) 'face hywiki-word-face)))
+       ;; !! FIXME: Uncomment these lines.
+       ;; (hywiki-tests--add-hywiki-hooks)
+       ;; (hywiki-mode 0)
+       ;; (hy-delete-files-and-buffers (list wikipage))
+       ;; (hy-delete-dir-and-buffer hywiki-directory)
+       ))))
 
 (ert-deftest hywiki-tests--convert-words-to-org-link ()
   "Verify `hywiki-convert-words-to-org-links' converts WikiWords to org links."
@@ -894,7 +909,8 @@ Note special meaning of `hywiki-allow-plurals-flag'."
   (let* ((hywiki-directory (make-temp-file "hywiki" t))
         (wikiword (hy-make-random-wikiword)))
     (unwind-protect
-        (mocklet (((hypb:require-package 'org-roam) => t)
+        (mocklet ((cl-struct-org-roam-node-tags => nil)
+                 ((hypb:require-package 'org-roam) => t)
                  ((org-roam-node-read) => "node")
                  (org-roam-node-title => "node-title"))
          (hywiki-add-org-roam-node wikiword)
diff --git a/test/kcell-tests.el b/test/kcell-tests.el
index 5d4ddeba58..9fed2b5f6c 100644
--- a/test/kcell-tests.el
+++ b/test/kcell-tests.el
@@ -7,14 +7,14 @@
 ;; e-mail:       ma...@gnu.org
 ;;
 ;; orig-date:    16-Feb-22 at 23:28:49
-;; last-mod:     23-Aug-24 at 13:27:11 by Bob Weiner
+;; last-mod:     16-Mar-25 at 10:15:23 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
 ;; Copyright (C) 2021-2024  Free Software Foundation, Inc.
 ;; Licensed under the GNU General Public License, version 3.
 ;;
-;; This file is not part of Emacs.  It requires Emacs 27.2 or above.
+;; This file is not part of Emacs.  It requires Emacs 28 or above.
 ;; This file is part of Hyperbole.
 ;;
 ;;; Commentary:

Reply via email to