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

    hui.el - Add more context types to hui:kill/copy cmds when no region
    
    (hui:selectable-thing-priority-list): Add this defcustom; if nil, disables
      both delimited and non-delimited regional thing selection in 
`hyperbole-mode'
      when no region is active.
    
    hpath.el (hpath:url-at-p, hpath:url-p, hpath:www-at-p, hpath:www-p): Clarify
      in doc string whether leading protocol string is necessary for 
recognition.
    
    hmouse-drv.el (hkey-throw): Change so selects the window thrown to.  Use new
      'hkey-throw-and-stay' for old behavior.
---
 ChangeLog          |  54 +++++++++++
 hact.el            |   9 +-
 hbut.el            |   4 +-
 hmouse-drv.el      |  38 +++++++-
 hpath.el           |  11 ++-
 hui-select.el      | 125 ++++++++++++++------------
 hui-window.el      |  10 +--
 hui.el             | 260 ++++++++++++++++++++++++++++++++++++-----------------
 hypb.el            |   9 +-
 hyperbole.el       |  10 +--
 kotl/kotl-mode.el  |  71 +++++++--------
 kotl/kview.el      |   8 +-
 man/hyperbole.texi |  10 +--
 test/hui-tests.el  | 109 +++++++++++-----------
 14 files changed, 462 insertions(+), 266 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 777d78ab8d..d4741b3b6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2025-06-20  Bob Weiner  <r...@gnu.org>
+
+* kotl/kotl-mode.el (kotl-mode:kill-region):
+  hui.el (hui:copy-to-register, hui:kill-ring-save): Test that a mark is set
+    in the buffer before calling 'indicate-copied-region' or it will error.
+
+* kotl/kotl-mode.el (kotl-mode:kill-region): Add 'kill-ring-save' to
+    'kill-commands'.
+
+* test/hui-tests.el (hui--kill-highlighted-region): Update to only error when
+    on whitespace.
+
+* hypb.el (hypb:in-string-p): Fix bug where point was on the end delimiter and
+    the search forward for it skips over it because it requires a non-backslash
+    character ahead of it.  Update doc to note that this returns nil if point
+    is on the closing quote(s).
+
+* hmouse-drv.el (hkey-throw): Change so selects the window thrown to.  Use new
+    'hkey-throw-and-stay' for old behavior.
+
+* hui-select.el (hui-select-get-region-boundaries): Set syntax-table so <> and 
{}
+    work as balanced pairs.
+                (hui-select-string-p):  Rewrite to use string start and end 
values
+    returned by (hypb:in-string-p nil t) and to use 'hargs:delimited' to 
simplify
+    the implementation.
+  hui.el (hui:delimited-selectable-thing): Replace call of 
'hui-select-get-thing'
+    with (hui-select-delimited-thing-call #'hui-select-thing) so does not 
select
+    multiple lines due to sexpressions when point is at the start of:
+      <a...@abc.com>
+      "www.google.com".
+
+* hpath.el (hpath:url-at-p, hpath:url-p, hpath:www-at-p, hpath:www-p): Clarify
+    in doc string whether leading protocol string is necessary for recognition.
+
+* hui.el (hui:kill-region): Rename to 'hui:kill-region-internal' for 
consistency.
+         (hui-copy-to-register): Rename to 'hui:copy-to-register'.
+         (hui-kill-region): Rename to 'hui:kill-region'.
+         (hui-kill-ring-save): Rename to 'hui:kill-ring-save'.
+         (hui:selectable-thing-priority-list): Add this defcustom; if nil, 
disables
+    both delimited and non-delimited regional thing selection in 
'hyperbole-mode'
+    when no region is active.
+        (hui:non-delimited-selectable-symbol-and-bounds): Add and select
+    a customizable set of non-delimitable symbols using {M-w} and {C-w}.
+         (hui:copy-to-register, hui:kill-region, hui:kill-ring-save): Call 
above
+    added function.
+         (hui:delimited-selectable-thing-and-bounds): Add <thing-type> to 
beginning
+    of list returned to match 'hui:non-delimited-selectable-symbol-and-bounds'.
+         (hui:selectable-thing-and-bounds): Add to call both delimited and 
non-delim
+    thing-and-bounds functions and to include any delimiters.
+
+2025-06-19  Bob Weiner  <r...@gnu.org>
+
+* hui-window.el (hmouse-dired-readin-hook): Fix where to find associated doc.
+
 2025-06-16  Bob Weiner  <r...@gnu.org>
 
 * test/hyrolo-tests.el 
(hyrolo-tests--forward-same-level-all-file-types-level1):
diff --git a/hact.el b/hact.el
index 1bcd8106cc..f456b53ed6 100644
--- a/hact.el
+++ b/hact.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    18-Sep-91 at 02:57:09
-;; Last-Mod:     19-Apr-25 at 19:03:44 by Bob Weiner
+;; Last-Mod:     19-Jun-25 at 10:24:53 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -393,10 +393,9 @@ Autoloads action function if need be to get the parameter 
list."
 (defun hact (&rest args)
   "Perform action formed from rest of ARGS and return the result.
 The value of `hrule:action' determines what effect this has.  The
-default for `hrule:action' is `actype:act' which returns the
-result of the action unless it is nil, in which case t is
-returned instead, to ensure that implicit button types register
-the performance of the action.
+default for `hrule:action' is `actype:act' which returns the result of
+the action unless it is nil, in which case t is returned instead, to
+ensure that implicit button types register the performance of the action.
 
 Alternatively act as a no-op when testing implicit button type contexts.
 First arg may be a symbol or symbol name for either an action type or a
diff --git a/hbut.el b/hbut.el
index d7258ea3c6..ab85b9c9be 100644
--- a/hbut.el
+++ b/hbut.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    18-Sep-91 at 02:57:09
-;; Last-Mod:     26-Apr-25 at 10:12:23 by Bob Weiner
+;; Last-Mod:     20-Jun-25 at 16:39:53 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1632,7 +1632,7 @@ Modify `hbut:syntax-table' and `help-mode-syntax-table' 
to include <> and {}.
 Modify `text-mode-syntax-table' and `fundamental-mode's syntax table
 to include {} only.  For use with implicit button activations."
   ;; Treat angle brackets and braces as opening and closing delimiters
-  ;; for ease  of matching.
+  ;; for ease of matching.
   (mapc (lambda (syntax-table)
          (modify-syntax-entry ?\< "(>" syntax-table)
          (modify-syntax-entry ?\> ")<" syntax-table)
diff --git a/hmouse-drv.el b/hmouse-drv.el
index 9349967698..1bdba28299 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    04-Feb-90
-;; Last-Mod:     10-May-25 at 00:19:45 by Mats Lidell
+;; Last-Mod:     20-Jun-25 at 15:22:16 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -627,6 +627,40 @@ Throw one of:
  - a displayable item at point or
  - the current buffer.
 With optional prefix arg THROW-REGION-FLAG, throw the current region
+even if not active.  After the throw, the RELEASE-WINDOW becomes the
+selected window."
+  (interactive (list (ace-window nil) current-prefix-arg))
+  (let ((depress-frame (selected-frame))
+       (display-delay (if (boundp 'temp-display-delay)
+                          temp-display-delay
+                        0.5)))
+    ;; Throw either the region or the item at point and keep selected-window
+    (let ((action-key-depress-window (selected-window))
+         (action-key-release-window release-window)
+         (action-key-depress-args))
+      (unless (hkey-insert-region action-key-depress-window release-window 
throw-region-flag display-delay)
+       (if (cadr (assq major-mode hmouse-drag-item-mode-forms))
+           (hmouse-item-to-window)
+         (set-window-buffer release-window (current-buffer))))
+      (unless (eq depress-frame (window-frame release-window))
+       ;; Force redisplay or item buffer won't be displayed here.
+       (redisplay t)
+       ;; Show the frame thrown to before it is covered when
+       ;; input-focus is returned to the depress-frame.
+       (raise-frame (window-frame release-window))
+       (select-frame-set-input-focus (window-frame release-window))
+       ;; Don't use sit-for here because it can be interrupted early.
+       (sleep-for display-delay))
+      (select-window release-window))))
+
+;;;###autoload
+(defun hkey-throw-and-stay (release-window &optional throw-region-flag)
+  "Throw a thing to display in RELEASE-WINDOW.
+Throw one of:
+ - the active (highlighted) region,
+ - a displayable item at point or
+ - the current buffer.
+With optional prefix arg THROW-REGION-FLAG, throw the current region
 even if not active.
 The selected window does not change."
   (interactive (list (ace-window nil) current-prefix-arg))
@@ -798,7 +832,7 @@ Leave the end window selected."
 Throw either a displayable item at start window's point or its current
 buffer to the end window.  The selected window does not change."
   (interactive)
-  (hmouse-choose-windows #'hkey-throw))
+  (hmouse-choose-windows #'hkey-throw-and-stay))
 
 (defun hmouse-choose-link-and-referent-windows ()
   "Select and return a list of (link-button-window referent-window)."
diff --git a/hpath.el b/hpath.el
index b05aa1dde3..0bb15bbfee 100644
--- a/hpath.el
+++ b/hpath.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     1-Nov-91 at 00:44:23
-;; Last-Mod:     15-Jun-25 at 12:03:03 by Bob Weiner
+;; Last-Mod:     20-Jun-25 at 09:41:06 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -2399,7 +2399,7 @@ off otherwise."
             #'hpath:disable-find-file-urls)))
 
 (defun hpath:url-at-p ()
-  "Return an url that point immediately precedes or nil.
+  "Return a url with an initial protocol that point immediately precedes or 
nil.
 Url is a world-wide-web universal resource locator.
 See the documentation for `hpath:url-regexp' for `match-string' groupings."
   (if (or (looking-at hpath:url-regexp) (looking-at hpath:url-regexp2)
@@ -2410,8 +2410,9 @@ See the documentation for `hpath:url-regexp' for 
`match-string' groupings."
        (buffer-substring-no-properties (match-beginning hpath:url-grpn) 
(point)))))
 
 (defun hpath:url-p (obj)
-  "Return t if OBJ is an url, else nil.
+  "Return t if OBJ is a url, else nil.
 Url is a world-wide-web universal resource locator.
+The url may lack a leading protocol; it will be inferred.
 See the documentation for `hpath:url-regexp' for match groupings to
 use with `string-match'."
   (and (stringp obj)
@@ -2422,6 +2423,7 @@ use with `string-match'."
 
 (defun hpath:www-at-p (&optional include-start-and-end-p)
   "Return a world-wide-web link reference that point is within or nil.
+The url may lack a leading protocol; it will be inferred.
 With optional INCLUDE-START-AND-END-P non-nil, returns list of:
   (link-string begin-position end-position)."
   (save-excursion
@@ -2437,7 +2439,8 @@ With optional INCLUDE-START-AND-END-P non-nil, returns 
list of:
                 (point))))))
 
 (defun hpath:www-p (path)
-  "Return PATH iff PATH is a world-wide-web link reference, else nil."
+  "Return PATH iff PATH is a world-wide-web link reference, else nil.
+The PATH may lack a leading protocol; it will be inferred."
   (and (stringp path) (hpath:url-p path) path))
 
 ;;; ************************************************************************
diff --git a/hui-select.el b/hui-select.el
index 13f678acfe..e241f48897 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:     14-Apr-25 at 15:53:22 by Mats Lidell
+;; Last-Mod:     21-Jun-25 at 13:29:32 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -541,9 +541,13 @@ Also, add language-specific syntax setups to aid in thing 
selection."
 
 (defun hui-select-get-region-boundaries ()
   "Return the (START . END) boundaries of region for `hui-select-thing'."
-  (or (hui-select-boundaries (point))
-      (when (eq hui-select-previous 'punctuation)
-       (hui-select-word (point)))))
+  (with-syntax-table
+      (if (memq major-mode hui-select-ignore-quoted-sexp-modes)
+         (syntax-table)
+       hui-select-syntax-table)
+    (or (hui-select-boundaries (point))
+       (when (eq hui-select-previous 'punctuation)
+         (hui-select-word (point))))))
 
 ;;;###autoload
 (defun hui-select-get-thing ()
@@ -1040,63 +1044,66 @@ Return the updated cons cell."
     hui-select-region))
 
 (defun hui-select-string-p (&optional start-delim end-delim)
-  "Return (start . end) of a string.
-Works when on a delim or on the first line with point in the
-string or directly before it.  Positions include delimiters.
-String is delimited by double quotes unless optional START-DELIM
-and END-DELIM (strings) are given.  Returns nil if not within a
-string."
+  "Return (start . end) positions of a string, including delimiters.
+This works when point is immediately before the opening or closing
+delimiter or within the text of the string.  The string is delimited
+by double quotes, unless optional START-DELIM and END-DELIM (strings)
+are given.  Return nil if not at a string."
   (unless start-delim (setq start-delim "\""))
   (unless end-delim (setq end-delim "\""))
+  (let (string-start-end)
   (with-syntax-table hbut:syntax-table
-    (or (and (equal start-delim "\"") (equal end-delim "\"")
-            (ignore-errors
-              (cond ((and (= (or (char-after) 0) ?\")
-                          (/= (or (char-before) 0) ?\\))
-                     (if (hypb:in-string-p)
-                         (hui-select-set-region (1+ (point))
-                                                (scan-sexps (1+ (point)) -1))
-                       (hui-select-set-region (point) (scan-sexps (point) 1))))
-                    ((and (= (or (char-before) 0) ?\")
-                          (/= (or (char-before (1- (point))) 0) ?\\))
-                     (if (hypb:in-string-p)
-                         (hui-select-set-region (1- (point)) (scan-sexps (1- 
(point)) 1))
-                       (hui-select-set-region (point) (scan-sexps (point) 
-1)))))))
-       (let ((opoint (point))
-             (count 0)
-             bol start delim-regexp start-regexp end-regexp)
-         ;; Special case for the empty string.
-         (if (looking-at (concat (regexp-quote start-delim)
-                                 (regexp-quote end-delim)))
-             (hui-select-set-region (point) (match-end 0))
-           (setq start-regexp (concat "\\(^\\|[^\\]\\)\\("
-                                      (regexp-quote start-delim) "\\)")
-                 end-regexp   (concat "[^\\]\\(" (regexp-quote end-delim) 
"\\)")
-                 delim-regexp (concat start-regexp "\\|" end-regexp))
-           (save-excursion
-             (beginning-of-line)
-             (setq bol (point))
-             (while (re-search-forward delim-regexp opoint t)
-               (setq count (1+ count))
-               ;; This is so we don't miss the closing delimiter of an empty
-               ;; string.
-               (if (and (= (point) (1+ bol))
-                        (looking-at (regexp-quote end-delim)))
-                   (setq count (1+ count))
-                 (unless (bobp)
-                   (backward-char 1))))
-             (goto-char opoint)
-             ;; If found an even # of starting and ending delimiters before
-             ;; opoint, then opoint is at the start of a string, where we want 
it.
-             (if (zerop (mod count 2))
-                 (unless (bobp)
-                   (backward-char 1))
-               (re-search-backward start-regexp nil t))
-             ;; Point is now before the start of the string.
-             (when (re-search-forward start-regexp nil t)
-               (setq start (match-beginning 2))
-               (when (re-search-forward end-regexp nil t)
-                 (hui-select-set-region start (point))))))))))
+    (or
+     ;; On or before double quote delimiters
+     (and (equal start-delim "\"") (equal end-delim "\"")
+         (cond ((and (= (or (char-after) 0) ?\")
+                     (/= (or (char-before) 0) ?\\))
+                (if (setq string-start-end (hypb:in-string-p nil t))
+                    ;; Add double quote delimiters to the region returned
+                    (hui-select-set-region (1- (nth 1 string-start-end))
+                                           (1+ (nth 2 string-start-end)))
+                  ;; May be on the closing double quote of a string in
+                  ;; which case this first scan-sexps will fail but
+                  ;; the second will succeed.
+                  (when (setq string-start-end
+                              (or (ignore-errors (hui-select-set-region 
(point) (scan-sexps (point) 1)))
+                                  (ignore-errors (hui-select-set-region
+                                                  (scan-sexps (1+ (point)) -1)
+                                                  (1+ (point))))))
+                    (hui-select-set-region
+                     (min (car string-start-end) (cdr string-start-end))
+                     (max (car string-start-end) (cdr string-start-end))))))
+               ((and (= (or (char-before) 0) ?\")
+                     (/= (or (char-before (1- (point))) 0) ?\\))
+                (if (setq string-start-end (hypb:in-string-p nil t))
+                    ;; Add double quote delimiters to the region returned
+                    (hui-select-set-region (1- (nth 1 string-start-end))
+                                           (1+ (nth 2 string-start-end)))
+                  ;; Either there are no matching string delimiters
+                  ;; (only an open delimiter) or (point) is immediately
+                  ;; after the end of the string in which case the
+                  ;; following scan-sexps will succeed.
+                  (when (setq string-start-end
+                              (ignore-errors (hui-select-set-region (point) 
(scan-sexps (point) -1))))
+                    (hui-select-set-region
+                     (min (car string-start-end) (cdr string-start-end))
+                     (max (car string-start-end) (cdr string-start-end))))))))
+
+     ;; Non-double quote delimiters
+     (let ((opoint (point))
+          (count 0)
+          bol start delim-regexp start-regexp end-regexp)
+       (save-excursion
+        (when (looking-at (regexp-quote start-delim))
+          (goto-char (match-end 0)))
+        (when (setq string-start-end
+                    (hargs:delimited start-delim end-delim nil nil t))
+          ;; Include delimiters
+          (hui-select-set-region (- (nth 1 string-start-end)
+                                    (length start-delim))
+                                 (+ (nth 2 string-start-end)
+                                    (length end-delim))))))))))
+
 ;;;
 ;;; Code selections
 ;;;
@@ -1445,7 +1452,7 @@ The region includes sexpressions before and after POS"
                 (hui-select-set-region (point) end))))))
 
 (defun hui-select-string (pos)
-  "Return (start . end) of string at POS or nil.  Pos include delimiters.
+  "Return (start . end) of string including delimiters at POS, or nil.
 Delimiters may be single, double or open and close quotes."
   (setq hui-select-previous 'string)
   (save-excursion
diff --git a/hui-window.el b/hui-window.el
index 71bd190756..abf08a955f 100644
--- a/hui-window.el
+++ b/hui-window.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Sep-92
-;; Last-Mod:     11-Nov-24 at 00:20:41 by Bob Weiner
+;; Last-Mod:     19-Jun-25 at 11:44:26 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -387,18 +387,18 @@ part of InfoDock and not a part of Hyperbole)."
 
 (defun hmouse-dired-readin-hook ()
   "Remove local `hpath:display-where' setting whenever re-read a Dired 
directory.
-See `hmouse-dired-item-dragged' for use."
+See the `hmouse-dired-display-here-mode' function for use."
   (hmouse-dired-display-here-mode 0))
 
 (define-minor-mode hmouse-dired-display-here-mode
   "Display item here on key press after Dired item drag.
 Once a Dired buffer item has been dragged, make next Action Key
-press on an item display it in the same Dired window.
+press on an item display it in the current Dired window.
 
 By default an Action Key press on a Dired item displays it in another
 window.   But once a Dired item is dragged to another window, the next
-Action Key press should display it in the Dired window so that the
-behavior matches that of Buffer Menu and allows for setting what is
+Action Key press should display it in the current Dired window so that
+the behavior matches that of Buffer Menu and allows for setting what is
 displayed in all windows on screen, including the Dired window.
 
 If the directory is re-read into the Dired buffer with {g}, then Action
diff --git a/hui.el b/hui.el
index e1af82cca2..0f7c23e33e 100644
--- a/hui.el
+++ b/hui.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    19-Sep-91 at 21:42:03
-;; Last-Mod:     20-Apr-25 at 15:15:12 by Bob Weiner
+;; Last-Mod:     21-Jun-25 at 13:26:46 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -19,6 +19,7 @@
 ;;; Other required Elisp libraries
 ;;; ************************************************************************
 
+(require 'cl-macs)  ;; For `cl-do*'
 (require 'hversion)
 (require 'hargs)
 ;; Avoid any potential library name conflict by giving the load directory.
@@ -49,16 +50,26 @@
 ;;; Public variables
 ;;; ************************************************************************
 
-(defcustom hui:hbut-delete-confirm-flag t
-  "*Non-nil means prompt before interactively deleting explicit buttons."
+(defcustom hui:ebut-prompt-for-action nil
+  "*Non-nil prompts for a button-specific action on explicit button creation."
   :type 'boolean
   :group 'hyperbole-buttons)
 
-(defcustom hui:ebut-prompt-for-action nil
-  "*Non-nil prompts for a button-specific action on explicit button creation."
+(defcustom hui:hbut-delete-confirm-flag t
+  "*Non-nil means prompt before interactively deleting explicit buttons."
   :type 'boolean
   :group 'hyperbole-buttons)
 
+(defcustom hui:selectable-thing-priority-list '(uuid email filename symbol 
word)
+   "List of priority ordered symbols recognized by `thing-at-point'.
+Either a 'url matches or the first match from this list is used when
+`hui:non-delimited-selectable-thing-and-bounds' is called during region
+copy and kills.  Set this list to nil to disable both delimited and
+non-delimited thing recognition in copy and kill commands when
+`hyperbole-mode' is enabled."
+  :type '(list symbol)
+  :group 'hyperbole)
+
 ;;; ************************************************************************
 ;;; Private variables
 ;;; ************************************************************************
@@ -76,7 +87,7 @@ At other times, value must be nil.")
 
 ;; Derived from copy-to-register of "register.el"
 ;;;###autoload
-(defun hui-copy-to-register (register start end &optional delete-flag 
region-flag)
+(defun hui:copy-to-register (register start end &optional delete-flag 
region-flag)
   "Copy region or thing into REGISTER.  With prefix arg, delete as well.
 Called from program, takes five args: REGISTER, START, END, DELETE-FLAG,
 and REGION-FLAG.  START and END are buffer positions indicating what to copy.
@@ -109,10 +120,11 @@ point; see `hui:delimited-selectable-thing'."
                        ((and (called-interactively-p 'interactive)
                             transient-mark-mode
                             (not (use-region-p))
-                            (prog1 (setq thing-and-bounds 
(hui:delimited-selectable-thing-and-bounds)
-                                         start (nth 1 thing-and-bounds)
-                                         end   (nth 2 thing-and-bounds)
-                                         thing (nth 0 thing-and-bounds))
+                            (prog1 (setq thing-and-bounds
+                                         (hui:selectable-thing-and-bounds)
+                                         thing (nth 1 thing-and-bounds)
+                                         start (nth 2 thing-and-bounds)
+                                         end   (nth 3 thing-and-bounds))
                               (when (and delete-flag start end)
                                 (delete-region start end))))
                        thing)
@@ -126,16 +138,17 @@ point; see `hui:delimited-selectable-thing'."
       (setq deactivate-mark t)
       (cond (delete-flag)
            ((called-interactively-p 'interactive)
-            (if thing
-                (message "Saved selectable thing: %s" thing)
-              (indicate-copied-region)))))))
+            (cond (thing
+                   (message "Saved selectable thing: %s" thing))
+                  ((mark t)
+                   (indicate-copied-region))))))))
 
 ;; In "hyperbole.el", use this to override the {C-w} command from
 ;; either "completion.el" or "simple.el" when hyperbole-mode is active
 ;; to allow killing kcell references, active regions and delimited
 ;; areas (like sexpressions).
 ;;;###autoload
-(defun hui-kill-region (beg end &optional region interactive-flag)
+(defun hui:kill-region (beg end &optional region interactive-flag)
   "Kill (\"cut\") between point and mark.
 The text is deleted but saved in the kill ring.
 The command \\[yank] can retrieve it from there.
@@ -153,37 +166,34 @@ Patched to remove the most recent completion."
   ;; calling `kill-append'.
   (interactive (list (when mark-active (mark))
                     (when mark-active (point))
-                    'region (prefix-numeric-value current-prefix-arg)))
-  (cond ((and transient-mark-mode
-              (or (use-region-p)
-                 (not interactive-flag)))
-        (unless (and beg end)
-          (setq beg (region-beginning)
-                end (region-end))))
-       ((and transient-mark-mode
-             (let* ((major-mode 'fundamental-mode)
-                    ;; Setting the major mode prevents hui-select from
-                    ;; suppressing use of `hui-select-syntax-table'
-                    ;; if in one of `hui-select-ignore-quoted-sexp-modes'.
-                    (sel-func (hui-select-at-delimited-thing-p))
-                    beg-end)
-               (when sel-func
-                 (setq beg-end (funcall sel-func (point))
-                       beg (car beg-end)
-                       end (cdr beg-end)
-                       region nil)
-                 t))))
-       (interactive-flag (setq beg (mark)
-                               end (point))))
+                    'region t))
+  (when transient-mark-mode
+    (cond ((or (use-region-p)
+              (not interactive-flag))
+          (unless (and beg end)
+            (setq beg (region-beginning)
+                  end (region-end))))
+         ;; Setting the major mode prevents hui-select from
+         ;; suppressing use of `hui-select-syntax-table'
+         ;; if in one of `hui-select-ignore-quoted-sexp-modes'.
+         ((let* ((major-mode 'fundamental-mode)
+                 thing-and-bounds)
+            (when (setq thing-and-bounds (hui:selectable-thing-and-bounds))
+              (setq beg (nth 2 thing-and-bounds)
+                    end (nth 3 thing-and-bounds)
+                    region nil)
+              t)))))
 
   ;; If there is no mark, this call should trigger an error
-  (hui:kill-region beg end region))
+  (if (and (null beg) (null end) (eq (mark t) (point)))
+      (hui:kill-region-internal (mark t) (point) region)
+    (hui:kill-region-internal beg end region)))
 
 ;; In "hyperbole.el", use this to override the {M-w} command from
 ;; "simple.el" when hyperbole-mode is active to allow copying kcell
 ;; references, active regions and delimited areas (like sexpressions).
 ;;;###autoload
-(defun hui-kill-ring-save (beg end &optional region)
+(defun hui:kill-ring-save (beg end &optional region)
   "Save the active region as if killed, but don't kill it.
 In Transient Mark mode, deactivate the mark.
 If `interprogram-cut-function' is non-nil, also save the text for a window
@@ -225,22 +235,29 @@ visual feedback indicating the extent of the region being 
copied."
                  end (point)))
          (hui:validate-region beg end region)
          (copy-region-as-kill beg end region))
-      (setq thing (hui:delimited-selectable-thing))
-      (if (stringp thing)
-         (progn (kill-new thing)
-                (setq deactivate-mark t))
-       (when (and (called-interactively-p 'interactive)
-                  (or (null beg) (null end)))
-         (setq beg (mark)
-               end (point)))
-       (hui:validate-region beg end region)
-       (copy-region-as-kill beg end region)))
+      (if (derived-mode-p 'kotl-mode)
+         (kotl-mode:copy-region-as-kill beg end)
+       ;; Setting the major mode prevents hui-select from
+       ;; suppressing use of `hui-select-syntax-table'
+       ;; if in one of `hui-select-ignore-quoted-sexp-modes'.
+       (let ((major-mode 'fundamental-mode))
+         (setq thing (nth 1 (hui:selectable-thing-and-bounds))))
+       (if (stringp thing)
+           (progn (kill-new thing)
+                  (setq deactivate-mark t))
+         (when (and (called-interactively-p 'interactive)
+                    (or (null beg) (null end)))
+           (setq beg (mark)
+                 end (point)))
+         (hui:validate-region beg end region)
+         (copy-region-as-kill beg end region))))
     ;; This use of `called-interactively-p' is correct because the
     ;; code it controls just gives the user visual feedback.
     (when (called-interactively-p 'interactive)
-      (if thing
-         (message "Saved selectable thing: %s" thing)
-       (indicate-copied-region)))))
+      (cond (thing
+            (message "Saved selectable thing: %s" thing))
+           ((mark t)
+            (indicate-copied-region))))))
 
 ;;; ************************************************************************
 ;;; Public functions
@@ -307,6 +324,7 @@ binding."
 
 (defun hui:delimited-selectable-thing ()
   "Return any delimited selectable thing at point as a string or nil if none.
+Return nil if `hui:selectable-thing-priority-list' is nil.
 
 With point:
   in a Koutline klink, copy the klink;
@@ -315,41 +333,115 @@ With point:
   on a Hyperbole button, copy the text of the button excluding delimiters;
   at the start of a paired delimiter,
     copy the text including the delimiters."
-  (cond ((klink:absolute (klink:at-p)))
-       ((derived-mode-p 'kotl-mode)
-        (kcell-view:absolute-reference))
-       ((and (not (hyperb:stack-frame '(hui-kill-ring-save hbut:at-p ibut:at-p 
ebut:at-p)))
-             (let* ((hbut (hbut:at-p))
-                    (start (when hbut (hattr:get hbut 'lbl-start)))
-                    (end (when hbut (hattr:get hbut 'lbl-end))))
-               (and start end
-                    (buffer-substring-no-properties start end)))))
-       ((hui-select-at-delimited-thing-p)
-        (hui-select-get-thing))))
+  (when hui:selectable-thing-priority-list
+    (cond ((klink:absolute (klink:at-p)))
+         ((derived-mode-p 'kotl-mode)
+          (kcell-view:absolute-reference))
+         ((and (not (hyperb:stack-frame '(hui:kill-ring-save hbut:at-p 
ibut:at-p ebut:at-p)))
+               (let* ((hbut (hbut:at-p))
+                      (start (when hbut (hattr:get hbut 'lbl-start)))
+                      (end (when hbut (hattr:get hbut 'lbl-end))))
+                 (and start end
+                      (buffer-substring-no-properties start end)))))
+         ((hui-select-at-delimited-thing-p)
+          (hui-select-get-thing)))))
 
 (defun hui:delimited-selectable-thing-and-bounds ()
   "Return a list of any delimited selectable thing at point.
-The list is (<thing-string> <thing-start> <thing-end>)
-or nil if none.  Start and end may be nil if the thing
-was generated rather than extracted from a region."
-  (let (thing-and-bounds thing start end)
-    (cond ((setq thing-and-bounds (klink:at-p))
-          (when thing-and-bounds
-            (setcar thing-and-bounds (klink:absolute thing-and-bounds))
-            thing-and-bounds))
-         ((derived-mode-p 'kotl-mode)
-          (list (kcell-view:absolute-reference)))
-         ((and (not (hyperb:stack-frame '(hui-kill-ring-save hbut:at-p 
ibut:at-p ebut:at-p)))
-               (setq thing (hbut:at-p)
-                     start (when thing (hattr:get thing 'lbl-start))
-                     end (when thing (hattr:get thing 'lbl-end))))
-          (and start end
-               (list (buffer-substring-no-properties start end) start end)))
-         ((hui-select-at-delimited-thing-p)
-          (when (setq thing-and-bounds (hui-select-get-region-boundaries))
-            (list (buffer-substring-no-properties (car thing-and-bounds) (cdr 
thing-and-bounds))
-                  (car thing-and-bounds)
-                  (cdr thing-and-bounds)))))))
+The list returned is (<thing-type> <thing-string> <thing-start> <thing-end>)
+or nil if none or if `hui:selectable-thing-priority-list' is nil.
+Start and end may be nil if the thing was generated rather than
+extracted from a region."
+  (when (and hui:selectable-thing-priority-list
+            (not (looking-at "[ \t\n\r\f]")))
+    (let (thing-and-bounds thing start end)
+      (cond ((setq thing-and-bounds (klink:at-p))
+            (when thing-and-bounds
+              (setcar thing-and-bounds (klink:absolute thing-and-bounds))
+              (cons 'klink thing-and-bounds)))
+           ((hui-select-at-delimited-thing-p)
+            (when (setq thing-and-bounds (hui-select-get-region-boundaries))
+              (list hui-select-previous
+                    (buffer-substring-no-properties
+                     (car thing-and-bounds) (cdr thing-and-bounds))
+                    (car thing-and-bounds)
+                    (cdr thing-and-bounds))))
+           ((and (not (hyperb:stack-frame '(hui:kill-ring-save hbut:at-p 
ibut:at-p ebut:at-p)))
+                 (setq thing (hbut:at-p)
+                       start (when thing (hattr:get thing 'lbl-start))
+                       end (when thing (hattr:get thing 'lbl-end))))
+            (and start end
+                 (list (hattr:get thing 'categ)
+                       (buffer-substring-no-properties start end) start 
end)))))))
+
+(defun hui:non-delimited-selectable-thing-and-bounds ()
+  "Return a list of properties for any non-delimited thing at point.
+The list returned is (<thing-type> <thing-string> <thing-start> <thing-end>)
+or nil if none.
+
+The prioritized types of things tested is 'url plus the list of types
+in `hui:selectable-thing-priority-list' if that variable is non-nil."
+  (when (and hui:selectable-thing-priority-list
+            (not (looking-at "[ \t\n\r\f]")))
+    (with-syntax-table
+       (if (memq major-mode hui-select-ignore-quoted-sexp-modes)
+           (syntax-table)
+         hui-select-syntax-table)
+      (let* ((types hui:selectable-thing-priority-list)
+            thing-and-bounds type thing start-end start end)
+       ;; Can't use thing-at-point here since it won't recognize URLs
+       ;; without a protocol prefix, e.g. www.google.com.
+       (when types
+         (setq thing-and-bounds (hpath:www-at-p t)))
+       (if thing-and-bounds
+           (cons 'url thing-and-bounds)
+         (while (and types (not thing))
+           (setq type (car types)
+                 types (cdr types)
+                 thing (thing-at-point type t))
+           (when thing
+             (cond ((eq type 'filename)
+                    (unless (file-exists-p thing)
+                      (setq thing nil)))
+                   ((eq type 'email)
+                    (unless (string-match "@.+\\." thing)
+                      (setq thing nil)))))
+           (when thing
+             (setq start-end (bounds-of-thing-at-point type)
+                   start (car start-end)
+                   end   (cdr start-end))))
+         (when thing (list type thing start end)))))))
+
+(defun hui:selectable-thing-and-bounds ()
+  "Return a list of any selectable thing at point.
+The list returned is (<thing-type> <thing-string> <thing-start> <thing-end>)
+or nil if none or if `hui:selectable-thing-priority-list' is nil.
+Start and end may be nil if the thing was generated rather than
+extracted from a region."
+  (let* (thing-and-bounds type thing start end)
+    (when (setq thing-and-bounds
+               (or (hui:delimited-selectable-thing-and-bounds)
+                   (hui:non-delimited-selectable-thing-and-bounds)))
+      (setq type (nth 0 thing-and-bounds)
+           thing (nth 1 thing-and-bounds)
+           start (nth 2 thing-and-bounds)
+           end (nth 3 thing-and-bounds))
+      (unless
+         ;; Already enclosed in delimiters
+         (or (and (= (char-syntax (char-after start)) ?\()
+                  (= (char-syntax (char-before end)) ?\)))
+             (and (= (char-syntax (char-after start)) ?\")
+                  (= (char-syntax (char-before end)) ?\")))
+           ;; Surrounded by delimiters to add to the thing
+       (when (or (and (= (if (char-before start) (char-syntax (char-before 
start)) 0) ?\()
+                      (= (if (char-after end) (char-syntax (char-after end)) 
0) ?\)))
+                 (and (= (if (char-before start) (char-syntax (char-before 
start)) 0) ?\")
+                      (= (if (char-after end) (char-syntax (char-after end)) 
0) ?\")))
+         ;; Include delimiters in return value
+         (setq start (1- start)
+               end (1+ end)
+               thing (buffer-substring-no-properties start end)))))
+       (when thing (list type thing start end))))
 
 (defun hui:ebut-act (&optional but)
   "Activate optional explicit button symbol BUT in current buffer.
@@ -1881,7 +1973,7 @@ string arguments."
          (ibut:operate))
       (ibut:operate))))
 
-(defun hui:kill-region (beg end &optional region)
+(defun hui:kill-region-internal (beg end &optional region)
   "Invoke context-sensitive kill-region command over BEG and END.
 Third optional arg, REGION, when non-nil is sent to any call of
 `kill-region' and used to invoke the `region-extract-function'
diff --git a/hypb.el b/hypb.el
index 3f0749f4de..9e151e82f1 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:     27-May-25 at 22:00:10 by Bob Weiner
+;; Last-Mod:     20-Jun-25 at 17:53:08 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -681,7 +681,7 @@ 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.
+  "Return non-nil iff point is within a string and not on the closing quote.
 
 With optional MAX-LINES, an integer, match only within that many
 lines from point.  With optional RANGE-FLAG, return list
@@ -760,6 +760,11 @@ Quoting conventions recognized are:
                                  (format "[\\]\\(%s\\)"
                                          (regexp-quote open-match-string))
                                  start (point))))
+                    ;; Move back one char in case point is on a
+                    ;; closing delimiter char to ensure it is not
+                    ;; backslash quoted and so the right delimiter is matched.
+                    (unless (= (1- (point)) (line-beginning-position))
+                      (goto-char (1- (point))))
                     (re-search-forward close-regexp nil t)
                     (if range-flag
                         (progn
diff --git a/hyperbole.el b/hyperbole.el
index cad1f61861..753ead4c58 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -9,7 +9,7 @@
 ;; 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:     16-Mar-25 at 10:11:31 by Bob Weiner
+;; Last-Mod:     20-Jun-25 at 00:21:49 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
@@ -310,17 +310,17 @@ of the commands."
     ;; "simple.el" when hyperbole-mode is active to allow killing
     ;; kcell references, active regions and delimited areas (like
     ;; sexpressions).
-    (hkey-set-key [remap completion-kill-region] #'hui-kill-region)
-    (hkey-set-key [remap kill-region]            #'hui-kill-region)
+    (hkey-set-key [remap completion-kill-region] #'hui:kill-region)
+    (hkey-set-key [remap kill-region]            #'hui:kill-region)
     ;;
     ;; Override the {M-w} command from "simple.el" when hyperbole-mode
     ;; is active to allow copying delimited things, kcell references
     ;; or regions to the kill ring.
-    (hkey-set-key [remap kill-ring-save]         #'hui-kill-ring-save)
+    (hkey-set-key [remap kill-ring-save]         #'hui:kill-ring-save)
     ;;
     ;; Override the {C-x r s} command from "register.el" when hyperbole-mode 
is active
     ;; to allow copying delimited things, kcell references or regions to a 
register.
-    (hkey-set-key "\C-xrs" #'hui-copy-to-register)
+    (hkey-set-key "\C-xrs" #'hui:copy-to-register)
     ;;
     ;; Bind {C-c @} to create a user-specified sized grid of windows
     ;; displaying different buffers.
diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el
index 337c8f0471..d938dc22be 100644
--- a/kotl/kotl-mode.el
+++ b/kotl/kotl-mode.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    6/30/93
-;; Last-Mod:     18-Jun-25 at 00:36:26 by Mats Lidell
+;; Last-Mod:     20-Jun-25 at 20:08:20 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -740,17 +740,17 @@ With optional prefix argument TOP-P non-nil, refill all 
cells in the outline."
   (let ((kill-whole-line t))
     (kotl-mode:kill-line arg)))
 
-(defun kotl-mode:kill-region (start end &optional copy-p)
+(defun kotl-mode:kill-region (start end &optional copy-flag)
   "Kill region between START and END within a single kcell.
-With optional COPY-P equal to t, copy region to kill ring but does not
-kill it.  With COPY-P any other non-nil value, return region as a
+With optional COPY-FLAG equal to t, copy region to kill ring but does not
+kill it.  With COPY-FLAG any other non-nil value, return region as a
 string without affecting kill ring.
 
 If called interactively, `transient-mark-mode' is non-nil, and
 there is no active region, copy any delimited selectable thing at
 point; see `hui:delimited-selectable-thing'.
 
-If the buffer is read-only and COPY-P is nil, the region will not be deleted
+If the buffer is read-only and COPY-FLAG is nil, the region will not be deleted
 but it will be copied to the kill ring and then an error will be signaled.
 
 If a completion is active, this aborts the completion only."
@@ -758,13 +758,13 @@ If a completion is active, this aborts the completion 
only."
    (progn (barf-if-buffer-read-only)
          (list (when mark-active (region-beginning))
                (when mark-active (region-end)))))
-  (let ((read-only (and (not copy-p) buffer-read-only))
-       (kill-commands '(kill-region kotl-mode:completion-kill-region
+  (let ((read-only (and (not copy-flag) buffer-read-only))
+       (kill-commands '(kill-region kill-ring-save 
kotl-mode:completion-kill-region
                          kotl-mode:kill-region kotl-mode:copy-region-as-kill))
        thing-and-bounds
        thing)
     (when read-only
-      (setq copy-p t))
+      (setq copy-flag t))
     (prog1 (cond
            ((eq last-command 'complete)
             (delete-region (point) cmpl-last-insert-location)
@@ -774,14 +774,14 @@ If a completion is active, this aborts the completion 
only."
            ((and (memq this-command kill-commands)
                  transient-mark-mode
                  (not (use-region-p))
-                 (setq thing-and-bounds 
(hui:delimited-selectable-thing-and-bounds)
-                       start (nth 1 thing-and-bounds)
-                       end   (nth 2 thing-and-bounds)
-                       thing (nth 0 thing-and-bounds)))
-            (if (and copy-p (not (eq copy-p t)))
+                 (setq thing-and-bounds (hui:selectable-thing-and-bounds)
+                       thing (nth 1 thing-and-bounds)
+                       start (nth 2 thing-and-bounds)
+                       end   (nth 3 thing-and-bounds)))
+            (if (and copy-flag (not (eq copy-flag t)))
                 ;; Return thing as a string
                 thing
-              (kotl-mode:kill-or-copy-region start end copy-p thing)))
+              (kotl-mode:kill-or-copy-region start end copy-flag thing)))
            ;; If no thing to process, copy region whether active or not
            ((and (number-or-marker-p start)
                  (number-or-marker-p end)
@@ -789,14 +789,15 @@ If a completion is active, this aborts the completion 
only."
                      (kcell-view:cell end)))
             (save-excursion
               (goto-char start)
-              (kotl-mode:kill-or-copy-region start end copy-p)))
+              (kotl-mode:kill-or-copy-region start end copy-flag)))
            (t (error "(kotl-mode:kill-region): Bad region or not within a 
single Koutline cell")))
-      (when (and copy-p (memq this-command kill-commands))
-       (if thing
-           (message "Saved selectable thing: %s" thing)
-         (indicate-copied-region))))))
+      (when (and copy-flag (memq this-command kill-commands))
+       (cond (thing
+              (message "Saved selectable thing: %s" thing))
+             ((mark t)
+              (indicate-copied-region)))))))
 
-(defun kotl-mode:kill-or-copy-region (start end copy-p &optional kill-str)
+(defun kotl-mode:kill-or-copy-region (start end copy-flag &optional kill-str)
   (when (and start end)
     (let ((indent (kcell-view:indent))
          subst-str)
@@ -808,7 +809,7 @@ If a completion is active, this aborts the completion only."
            kill-str
            (replace-regexp-in-string
             subst-str "\\1" (buffer-substring start end)))
-      (unless copy-p
+      (unless copy-flag
        ;; If last char of region is a newline, then delete indent in
        ;; following line.
        (delete-region
@@ -816,7 +817,7 @@ If a completion is active, this aborts the completion only."
                                '(?\n ?\r))
                          indent
                        0))))))
-  (cond ((and copy-p (not (eq copy-p t)))
+  (cond ((and copy-flag (not (eq copy-flag t)))
         ;; Return killed region as a string.
         kill-str)
        ((not (and start end))
@@ -826,7 +827,7 @@ If a completion is active, this aborts the completion only."
             (kill-new kill-str))
           (setq this-command 'kill-region)
           (setq deactivate-mark t)
-          (when (and (not copy-p) buffer-read-only)
+          (when (and (not copy-flag) buffer-read-only)
             (barf-if-buffer-read-only))
           nil)))
 
@@ -1182,11 +1183,11 @@ Leave point at the start of the root cell of the new 
tree."
    kotl-kview))
 
 (defun kotl-mode:move-after (from-cell-ref to-cell-ref child-p
-                            &optional copy-p fill-p)
+                            &optional copy-flag fill-p)
   "Move tree rooted at FROM-CELL-REF to follow tree rooted at TO-CELL-REF.
 If prefix arg CHILD-P is non-nil, make FROM-CELL-REF the first child of
 TO-CELL-REF, otherwise make it the sibling following TO-CELL-REF.
-With optional COPY-P, copies tree rather than moving it.
+With optional COPY-FLAG, copies tree rather than moving it.
 
 Leave point at original location but return the tree's new start point."
   (interactive
@@ -1199,7 +1200,7 @@ Leave point at original location but return the tree's 
new start point."
                (if current-prefix-arg "child" "sibling")))
          (list label label))
       (list current-prefix-arg))))
-  (if (and (not copy-p) (equal from-cell-ref to-cell-ref))
+  (if (and (not copy-flag) (equal from-cell-ref to-cell-ref))
       (error "(kotl-mode:move-after): Can't move tree after itself"))
   (let* ((lbl-sep-len (kview:label-separator-length kotl-kview))
         (move-to-point (set-marker
@@ -1219,7 +1220,7 @@ Leave point at original location but return the tree's 
new start point."
     ;;
     ;; We can't move a tree to a point within itself, so if that is the case
     ;; and this is not a copy operation, signal an error.
-    (when (and (not copy-p) (>= move-to-point start) (<= move-to-point end))
+    (when (and (not copy-flag) (>= move-to-point start) (<= move-to-point end))
       (error "(kotl-mode:move-after): Can't move tree <%s> to within itself"
             from-label))
     ;;
@@ -1248,7 +1249,7 @@ Leave point at original location but return the tree's 
new start point."
     ;;
     ;; Insert tree-to-move at new location
     ;;
-    (kview:move start end (point) from-indent to-indent copy-p
+    (kview:move start end (point) from-indent to-indent copy-flag
                (or fill-p kotl-mode:refill-flag))
     ;;
     ;; Ensure that point is within editable region of cell with to-label.
@@ -1258,7 +1259,7 @@ Leave point at original location but return the tree's 
new start point."
     ;; Update current cell and new siblings' labels within view.
     (klabel-type:update-labels to-label)
     ;;
-    (unless copy-p
+    (unless copy-flag
       ;;
       ;; Move to sibling of tree-to-move within view and update labels within
       ;; view of tree-to-move's original siblings.
@@ -1279,11 +1280,11 @@ Leave point at original location but return the tree's 
new start point."
     new-tree-start))
 
 (defun kotl-mode:move-before (from-cell-ref to-cell-ref parent-p
-                             &optional copy-p fill-p)
+                             &optional copy-flag fill-p)
   "Move tree rooted at FROM-CELL-REF to precede tree rooted at TO-CELL-REF.
 If prefix arg PARENT-P is non-nil, make FROM-CELL-REF the first child of
 TO-CELL-REF's parent, otherwise make it the preceding sibling of TO-CELL-REF.
-With optional COPY-P, copies tree rather than moving it.
+With optional COPY-FLAG, copies tree rather than moving it.
 
 Leave point at original location but return the tree's new start point."
   (interactive
@@ -1296,7 +1297,7 @@ Leave point at original location but return the tree's 
new start point."
                       "preceding sibling")))
          (list label label))
       (list current-prefix-arg))))
-  (when (and (not copy-p) (equal from-cell-ref to-cell-ref))
+  (when (and (not copy-flag) (equal from-cell-ref to-cell-ref))
     (error "(kotl-mode:move-before): Can't move tree before itself"))
   (let* ((lbl-sep-len (kview:label-separator-length kotl-kview))
         (move-to-point (set-marker
@@ -1315,7 +1316,7 @@ Leave point at original location but return the tree's 
new start point."
     ;;
     ;; We can't move a tree to a point within itself, so if that is the case
     ;; and this is not a copy operation, signal an error.
-    (when (and (not copy-p) (>= move-to-point start) (<= move-to-point end))
+    (when (and (not copy-flag) (>= move-to-point start) (<= move-to-point end))
       (error "(kotl-mode:move-before): Can't move tree <%s> to within itself"
             from-label))
     ;;
@@ -1342,7 +1343,7 @@ Leave point at original location but return the tree's 
new start point."
     ;;
     ;; Insert tree-to-move at new location
     ;;
-    (kview:move start end (point) from-indent to-indent copy-p
+    (kview:move start end (point) from-indent to-indent copy-flag
                (or fill-p kotl-mode:refill-flag))
     ;;
     ;; Ensure that point is within editable region of root of tree just moved.
@@ -1352,7 +1353,7 @@ Leave point at original location but return the tree's 
new start point."
     ;; Update current cell and new siblings' labels within view.
     (klabel-type:update-labels to-label)
     ;;
-    (unless copy-p
+    (unless copy-flag
       ;;
       ;; Move to sibling of tree-to-move within view and update labels within
       ;; view of tree-to-move's original siblings.
diff --git a/kotl/kview.el b/kotl/kview.el
index 5bd9fdf72a..c4a960fe7f 100644
--- a/kotl/kview.el
+++ b/kotl/kview.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    6/30/93
-;; Last-Mod:     29-Jan-25 at 19:07:24 by Mats Lidell
+;; Last-Mod:     20-Jun-25 at 00:40:40 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1169,10 +1169,10 @@ See also `kview:map-region', `kview:map-branch' and 
`kview:map-siblings'."
          (nreverse results)))))
 
 (defun kview:move (from-start from-end to-start from-indent to-indent
-                  &optional copy-p fill-p)
+                  &optional copy-flag fill-p)
   "Move tree between FROM-START and FROM-END to TO-START.
 Also change indentation from FROM-INDENT to TO-INDENT.
-Copy tree if optional COPY-P is non-nil.  Refill cells if optional
+Copy tree if optional COPY-FLAG is non-nil.  Refill cells if optional
 FILL-P is non-nil.  Leave point at TO-START."
   (let ((region (buffer-substring from-start from-end))
        (new-start (set-marker (make-marker) to-start))
@@ -1181,7 +1181,7 @@ FILL-P is non-nil.  Leave point at TO-START."
 
     ;;
     ;; Move or copy tree region to new location.
-    (or copy-p (delete-region from-start from-end))
+    (or copy-flag (delete-region from-start from-end))
     (goto-char new-start)
     (insert region)
     (setq new-end (point))
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index 323271e8c3..9c05daa6e7 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:     15-Jun-25 at 22:44:41 by Bob Weiner
+@c Last-Mod:     20-Jun-25 at 00:10:17 by Bob Weiner
 
 @c %**start of header (This is for running Texinfo on a region.)
 @setfilename hyperbole.info
@@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</P>
 
 <PRE>
 Edition 9.0.2pre
-Printed June 15, 2025.
+Printed June 20, 2025.
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -9439,12 +9439,12 @@ binding.  @xref{Smart Key Thing Selection}, for more 
information.
 
 @cindex key binding, M-w
 @vindex mark-even-if-inactive
-@findex hui-kill-ring-save
+@findex hui:kill-ring-save
 @kitem M-w
 @cindex copying things to kill ring
 Delimited Thing, Koutline Cell Reference or Region Copy: While Hyperbole is
 active, it sets @code{mark-even-if-inactive} to @code{nil} and overrides
-@bkbd{M-w} with its own command, @code{hui-kill-ring-save}, which copies the
+@bkbd{M-w} with its own command, @code{hui:kill-ring-save}, which copies the
 region only when it is active/highlighted.  When there is no active region,
 @bkbd{M-w} does one of the following:
 
@@ -9461,7 +9461,7 @@ region only when it is active/highlighted.  When there is 
no active region,
 Delimited Thing, Koutline Cell Reference or Region Save to Register: This
 does the same thing as @bkbd{M-w} except it copies to an Emacs register
 given by a letter or number rather than the kill ring.  While Hyperbole is 
active,
-it overrides @bkbd{C-x r s} with its own command, @code{hui-copy-to-register}.
+it overrides @bkbd{C-x r s} with its own command, @code{hui:copy-to-register}.
 which copies the region only when it is active/highlighted.
 @end table
 
diff --git a/test/hui-tests.el b/test/hui-tests.el
index 7a8a68bf5a..1e93d10134 100644
--- a/test/hui-tests.el
+++ b/test/hui-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <ma...@gnu.org>
 ;;
 ;; Orig-Date:    30-Jan-21 at 12:00:00
-;; Last-Mod:     25-Apr-25 at 19:50:39 by Mats Lidell
+;; Last-Mod:     20-Jun-25 at 19:37:43 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -410,7 +410,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (kotl-mode:beginning-of-cell)
 
           (forward-char 1)
-          (call-interactively #'hui-kill-ring-save)
+          (call-interactively #'hui:kill-ring-save)
 
           (kotl-mode:add-cell)
           (yank)
@@ -432,7 +432,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (kotl-mode:beginning-of-cell)
 
           (forward-char 1)
-          (call-interactively #'hui-kill-ring-save)
+          (call-interactively #'hui:kill-ring-save)
 
           (find-file other-file)
           (yank)
@@ -455,7 +455,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (kotl-mode:beginning-of-cell)
 
           (forward-char 1)
-          (call-interactively #'hui-kill-ring-save)
+          (call-interactively #'hui:kill-ring-save)
 
           (find-file other-file)
           (yank)
@@ -479,7 +479,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (kotl-mode:beginning-of-cell)
 
           (forward-char 1)
-          (call-interactively #'hui-kill-ring-save)
+          (call-interactively #'hui:kill-ring-save)
 
           (find-file other-file)
           (yank)
@@ -505,7 +505,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (forward-char 1)
           (with-mock
             (mock (register-read-with-preview  "Copy to register: ") => ?a)
-            (call-interactively #'hui-copy-to-register))
+            (call-interactively #'hui:copy-to-register))
 
           (kotl-mode:add-cell)
           (insert-register ?a)
@@ -530,7 +530,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (forward-char 1)
           (with-mock
             (mock (register-read-with-preview  "Copy to register: ") => ?a)
-            (call-interactively #'hui-copy-to-register))
+            (call-interactively #'hui:copy-to-register))
 
           (find-file other-file)
           (insert-register ?a)
@@ -555,7 +555,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (forward-char 1)
           (with-mock
             (mock (register-read-with-preview  "Copy to register: ") => ?a)
-            (call-interactively #'hui-copy-to-register))
+            (call-interactively #'hui:copy-to-register))
 
           (find-file other-file)
           (insert-register ?a)
@@ -581,7 +581,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (forward-char 1)
           (with-mock
             (mock (register-read-with-preview  "Copy to register: ") => ?a)
-            (call-interactively #'hui-copy-to-register))
+            (call-interactively #'hui:copy-to-register))
 
           (find-file other-file)
           (insert-register ?a)
@@ -605,7 +605,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (kotl-mode:newline 1)
           (insert "b")
           (setq last-command #'ignore)
-          (hui-kill-ring-save (region-beginning) (region-end))
+          (hui:kill-ring-save (region-beginning) (region-end))
           (should (string= (current-kill 0 t) "a\nb")))
       (hy-delete-file-and-buffer kotl-file))))
 
@@ -619,7 +619,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
           (insert "a")
           (kotl-mode:add-cell)
           (insert "b")
-          (should-error (hui-kill-ring-save (region-beginning) (region-end)) 
:type 'error))
+          (should-error (hui:kill-ring-save (region-beginning) (region-end)) 
:type 'error))
       (hy-delete-file-and-buffer kotl-file))))
 
 (ert-deftest hui--ibut-create-interactive ()
@@ -764,7 +764,7 @@ With point on label suggest that ibut for rename."
   (with-temp-buffer
     (ebut:program "label" 'link-to-directory "/tmp")
     (end-of-line)
-    (hui-kill-ring-save (point-min) (point))
+    (hui:kill-ring-save (point-min) (point))
     (yank)
     (goto-char (point-min))
     (should (looking-at-p "<(label)><(label)>"))
@@ -1174,7 +1174,7 @@ With point on label suggest that ibut for rename."
       (hy-delete-file-and-buffer global-but-file))))
 
 (ert-deftest hui--kill-highlighted-region-default-settings ()
-  "Verify `hui-kill-region'.
+  "Verify `hui:kill-region'.
 The Emacs default settings are used, i.e. both `transient-mark-mode' and
 `mark-even-if-inactive' are enabled."
   (with-temp-buffer
@@ -1185,17 +1185,14 @@ The Emacs default settings are used, i.e. both 
`transient-mark-mode' and
       (set-mark nil)
 
       ;; No mark set
-      (condition-case err
-          (call-interactively #'hui-kill-region)
-        (error
-         (progn
-           (should (memq (car err) (list 'error 'user-error)))
-           (should (string-match "The mark is not set now, so there is no 
region" (cadr err))))))
+      (call-interactively #'hui:kill-region)
+      (should (string= "{def}ghi" (buffer-string)))
 
       (set-mark (point))
+      (activate-mark)
       (goto-char 4)
-      (call-interactively #'hui-kill-region)
-      (should (string= "{def}ghi" (buffer-string)))
+      (call-interactively #'hui:kill-region)
+      (should (string= "f}ghi" (buffer-string)))
 
       (erase-buffer)
       (insert "abc{def}hig")
@@ -1203,7 +1200,7 @@ The Emacs default settings are used, i.e. both 
`transient-mark-mode' and
       (set-mark (point))
       (goto-char 4)
       (deactivate-mark)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "abchig" (buffer-string)))
 
       (erase-buffer)
@@ -1212,7 +1209,7 @@ The Emacs default settings are used, i.e. both 
`transient-mark-mode' and
       (set-mark (point))
       (goto-char 4)
       (activate-mark)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "{def}igh" (buffer-string)))
 
       (erase-buffer)
@@ -1221,8 +1218,8 @@ The Emacs default settings are used, i.e. both 
`transient-mark-mode' and
       (set-mark (point))
       (goto-char 5)
       (deactivate-mark)
-      (call-interactively #'hui-kill-region)
-      (should (string= "def}ghi" (buffer-string)))
+      (call-interactively #'hui:kill-region)
+      (should (string= "bcaghi" (buffer-string)))
 
       ;; Not interactive
       (erase-buffer)
@@ -1231,7 +1228,7 @@ The Emacs default settings are used, i.e. both 
`transient-mark-mode' and
       (set-mark (point))
       (goto-char 4)
       (activate-mark)
-      (hui-kill-region (mark t) (point))
+      (hui:kill-region (mark t) (point))
       (should (string= "{efd}ghi" (buffer-string)))
 
       ;; Pick up region if beg or end is not set.
@@ -1241,27 +1238,28 @@ The Emacs default settings are used, i.e. both 
`transient-mark-mode' and
       (set-mark (point))
       (goto-char 4)
       (deactivate-mark)
-      (hui-kill-region nil nil)
+      (hui:kill-region nil nil)
       (should (string= "{def}ghi" (buffer-string))))))
 
 
 (ert-deftest hui--kill-highlighted-region ()
-  "Verify `hui-kill-region'.
+  "Verify `hui:kill-region'.
 `transient-mark-mode' is enabled and `mark-even-if-inactive' is
 disabled."
   (with-temp-buffer
     (let ((transient-mark-mode t)
          (mark-even-if-inactive nil))
-      (insert "abc{def}ghi")
+      (insert " abc{def}ghi")
       (goto-char 1)
       (set-mark nil)
 
-      ;; No mark set
-      (should-error (call-interactively #'hui-kill-region) :type 'error)
+      ;; No mark set and on whitespace
+      (should-error (call-interactively #'hui:kill-region) :type 'error)
 
+      (delete-char 1)
       (set-mark (point))
       (goto-char 4)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "{def}ghi" (buffer-string)))
 
       (erase-buffer)
@@ -1270,7 +1268,7 @@ disabled."
       (set-mark (point))
       (goto-char 4)
       (deactivate-mark)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "abchig" (buffer-string)))
 
       (erase-buffer)
@@ -1279,7 +1277,7 @@ disabled."
       (set-mark (point))
       (goto-char 4)
       (activate-mark)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "{def}igh" (buffer-string)))
 
       (erase-buffer)
@@ -1288,7 +1286,8 @@ disabled."
       (set-mark (point))
       (goto-char 5)
       (deactivate-mark)
-      (should-error (call-interactively #'hui-kill-region) :type 'error)
+      (call-interactively #'hui:kill-region)
+      (should (string= "bcaghi" (buffer-string)))
 
       ;; Not interactive
       (erase-buffer)
@@ -1297,7 +1296,7 @@ disabled."
       (set-mark (point))
       (goto-char 4)
       (activate-mark)
-      (hui-kill-region (mark t) (point))
+      (hui:kill-region (mark t) (point))
       (should (string= "{efd}ghi" (buffer-string)))
 
       (erase-buffer)
@@ -1306,10 +1305,11 @@ disabled."
       (set-mark (point))
       (goto-char 4)
       (deactivate-mark)
-      (should-error (hui-kill-region nil (point)) :type 'error))))
+      (call-interactively #'hui:kill-region)
+      (should (string= "bacghi" (buffer-string))))))
 
 (ert-deftest hui--kill-non-highlighted-region ()
-  "Verify `hui-kill-region'.
+  "Verify `hui:kill-region'.
 `transient-mark-mode' is disabled and `mark-even-if-inactive' is
 enabled."
   (with-temp-buffer
@@ -1321,11 +1321,11 @@ enabled."
       (set-mark nil)
 
       ;; No mark set
-      (should-error (call-interactively #'hui-kill-region) :type 'error)
+      (should-error (call-interactively #'hui:kill-region) :type 'error)
 
       (set-mark (point))
       (goto-char 4)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "{def}ghi" (buffer-string)))
 
       (erase-buffer)
@@ -1333,7 +1333,7 @@ enabled."
       (goto-char 1)
       (set-mark (point))
       (goto-char 4)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "{def}hig" (buffer-string)))
 
       (erase-buffer)
@@ -1341,7 +1341,7 @@ enabled."
       (goto-char 1)
       (set-mark (point))
       (goto-char 5)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "def}igh" (buffer-string)))
 
       ;; Not interactive
@@ -1351,7 +1351,7 @@ enabled."
       (goto-char 1)
       (set-mark (point))
       (goto-char 4)
-      (hui-kill-region (mark t) (point))
+      (hui:kill-region (mark t) (point))
       (should (string= "{def}gih" (buffer-string)))
 
       (erase-buffer)
@@ -1359,17 +1359,17 @@ enabled."
       (goto-char 1)
       (set-mark nil)
       (goto-char 4)
-      (should-error (hui-kill-region nil (point)) :type 'error)
+      (should-error (hui:kill-region nil (point)) :type 'error)
 
       (erase-buffer)
       (insert "bca{def}hig")
       (goto-char 1)
       (set-mark (point))
       (goto-char 5)
-      (hui-kill-region (mark t) (point))
+      (hui:kill-region (mark t) (point))
       (should (string= "def}hig" (buffer-string)))
 
-      (hui-kill-region (mark t) (point))
+      (hui:kill-region (mark t) (point))
       (should (string= "def}hig" (buffer-string))))))
 
 (ert-deftest hui--kill-empty-region-twice ()
@@ -1382,15 +1382,16 @@ Mimics the test case of setting a mark and hitting 
`C-w' twice."
       (insert "foo bar")
       (goto-char 4)
       (set-mark (point))
-      (call-interactively #'hui-kill-region)
+      (activate-mark)
+      (call-interactively #'hui:kill-region)
       ;; Prepare second call to be setup as kill-region would leave
       ;; the state when calling it using C-w.
       (setq mark-active nil)
       (setq last-command #'kill-region)
-      (call-interactively #'hui-kill-region))))
+      (call-interactively #'hui:kill-region))))
 
 (ert-deftest hui--kill-region-multiple-kill ()
-  "Verify `hui-kill-region' saves to the yank ring on multiple kills.
+  "Verify `hui:kill-region' saves to the yank ring on multiple kills.
 See test case `kill-whole-line-after-other-kill' and others in
 simple-tests.el for prior art of forcing values on `last-command'."
   ;; Two regions
@@ -1401,12 +1402,12 @@ simple-tests.el for prior art of forcing values on 
`last-command'."
       (goto-char 2)
       (set-mark (point))
       (goto-char 4)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (goto-char 2)
       (set-mark (point))
       (goto-char 4)
       (setq last-command #'kill-region)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "16" (buffer-string)))
       (should (string= "2345" (car kill-ring)))))
 
@@ -1425,7 +1426,7 @@ line 1
       (set-mark (point))
       (goto-char 4)
       (setq last-command #'kill-region)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "14" (buffer-string)))
       (should (string= "line 1\n23" (car kill-ring)))))
 
@@ -1439,9 +1440,9 @@ line 1
       (goto-char 4)
       (deactivate-mark)
       (setq last-command #'ignore)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (setq last-command #'kill-region)
-      (call-interactively #'hui-kill-region)
+      (call-interactively #'hui:kill-region)
       (should (string= "abcjkl" (buffer-string)))
       (should (string= "{def}{ghi}" (car kill-ring))))))
 

Reply via email to