emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/hyperbole 5d94882558 9/9: Merge pull request #360 from


From: ELPA Syncer
Subject: [elpa] externals/hyperbole 5d94882558 9/9: Merge pull request #360 from rswgnu/rsw
Date: Sat, 8 Jul 2023 18:57:59 -0400 (EDT)

branch: externals/hyperbole
commit 5d9488255895dbff1b2abc821106210ed14632c7
Merge: ac6e50e3ec 7bbd133144
Author: Robert Weiner <rsw@gnu.org>
Commit: GitHub <noreply@github.com>

    Merge pull request #360 from rswgnu/rsw
    
    Latest updates from rsw branch
---
 ChangeLog              | 116 +++++++++++++++++++++++
 DEMO                   |  23 +++--
 hact.el                |  36 ++++---
 hactypes.el            |   6 +-
 hargs.el               | 147 ++++++++++++++++++++++-------
 hbut.el                | 206 ++++++++++++++++++++++------------------
 hib-social.el          |  25 ++---
 hibtypes.el            |  17 ++--
 hload-path.el          |   6 +-
 hmouse-drv.el          |  28 +++---
 hmouse-sh.el           |  17 +++-
 hpath.el               |   8 +-
 hui-menu.el            |   5 +-
 hui-mini.el            |   3 +-
 hui-mouse.el           |  24 ++---
 hui.el                 | 251 +++++++++++++++++++++++++++++++------------------
 hypb.el                |   4 +-
 hyperbole.el           |   9 +-
 man/hkey-help.txt      |   3 +-
 man/hyperbole.texi     |  94 +++++++++++++-----
 man/version.texi       |   4 +-
 test/demo-tests.el     |   6 +-
 test/hactypes-tests.el |   6 +-
 test/hbut-tests.el     | 140 +++++++++++++++++++++++++--
 24 files changed, 834 insertions(+), 350 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d1f7eecebb..a230e0e6e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,104 @@
+2023-07-08  Bob Weiner  <rsw@gnu.org>
+
+* test/demo-tests.el 
(demo-implicit-button-action-button-boolean-function-call-test):
+    Rename to 'demo-implicit-button-action-button-display-boolean-test' so can
+    find when search for use of 'display-boolean'.
+
+* hactypes.el (display-boolean): Improve clarity of output message.
+  test/hactypes-tests.el (display-boolean-true-test, 
display-boolean-false-test):
+    Update to new output message format.
+
+* hpath.el (hpath:absolute-arguments): Fix to process only string arguments.
+
+* hibtypes.el (action): Fix 'args' not being set right after add display-* 
actypes.
+    Stop storing unneeded ibutton 'action attribute.
+
+* hact.el (actype:action): Fix doc to say may return actype's fboundp symbol.
+    Use 'actype:action-body' if always need the body of the function.
+          (symtable:actype-p): Fix to return Elisp function symbols as well
+    since 'actype:elisp-symbol' is an alias to this defsubst.
+          (symtable:hyperbole-actype-p): Add to exclude Elisp function symbols.
+          (actype:act): Use above new function.
+
+* DEMO (Completion Selection):
+  man/hkey-help.txt:
+  man/hyperbole.texi (Smart Key Argument Selection): Update to new minibuffer
+    argument handling including Vertico support.
+
+2023-07-05  Bob Weiner  <rsw@gnu.org>
+
+* hpath.el (hpath:markdown-section-pattern, hpath:outline-section-pattern): Fix
+    to allow for opening pair chars after matching anchor (previously had to 
be a
+    :punct: character only).
+
+2023-07-04  Bob Weiner  <rsw@gnu.org>
+
+* hyperbole.el (hyperb:init): Activate 'vertico-mouse-mode' when
+    'vertico-mode' is used so that the Action Key properly selects completions
+    from the candidate list.  Since Vertico displays completions automatically,
+    must initialize this before Vertico is invoked so cannot wait until a Smart
+    Mouse Key is first pressed.
+  hargs.el (hargs:select-p):
+           (hargs:at-p): When 'hargs:reading-type' is nil, rather than a
+    string, return a list of (completion-so-far exact-completion-match),
+    for consumption by 'hargs:select-p'.  Add feature to kill to end of
+    minibuffer line and refresh completions when not inserting a fully
+    matching completion (works for regular and vertico completions if
+    'vertico-mouse-mode' has been enabled prior to using).
+
+* hmouse-sh.el (hmouse-posn-set-point): Avoid setting point to a read-only
+    location when vertico-mode is active.
+
+2023-07-03  Bob Weiner  <rsw@gnu.org>
+
+* hmouse-drv.el (hkey-help): Remove ref to XEmacs 'help-selects-help-window'.
+
+* hargs.el (hargs:select-p): Add vertico and ivy completion support.
+           (hargs:at-p): Add vertico support.
+  hui-mouse.el (hkey-alist): Remove ivy support; move above.
+
+* hact.el (actype:act): Fix error when 'args' are null.
+
+* hbut.el (hbut:action): Fix error when 'atype' is not a symbol.
+
+* hmouse-sh.el (hmouse-drag-region): Disable Hyperbole-specific functionality
+    when hyperbole-mode is nil.
+
+2023-07-02  Bob Weiner  <rsw@gnu.org>
+
+* hui.el (hui:ibut-create):
+  hbut.el (ibut:program): Prevent from creating a new ibut within a named
+    or labeled Hyperbole button.
+
+* hui.el (hui:ibut-create): Call (hattr:clear 'hbut:current) before creating
+    in-memory button.
+
+* hib-social.el (hibtypes-social-default-service): Pluralize defgroup name to
+    'hyperbole-buttons' to match other files.  Remove duplicate unneeded
+    :group from each defcustom.
+
+2023-07-01  Bob Weiner  <rsw@gnu.org>
+
+* hui.el (hui:link-possible-types): If in a .texi but not within a node, don't
+    raise error, just use a link-to-file-line instead.
+
+* hui-menu.el (infodock-hyperbole-menu):
+  hui-mini.el (hui:menus): Add Link item calling 'hui:gbut-link-directly'.
+  man/hyperbole.texi (Global Buttons): Add doc for new Gbut/Link item.
+  hui.el (hui:gbut-link-directly): Add to create named global link buttons 
based on
+    current windows.
+         (hui:gbut-create): Update to prompt for ibut name when called 
interactively.
+    Also, prompt if 'lbl' arg is nil and prompt for ibut text when called with 
a
+    prefix argument, 'ibut-flag'.  Also check that start and end buffers are 
the same
+    when creating an ibut.
+         (hui:ebut-edit, hui:gbut-edit, hui:hbut-label): Fix to not allow 
blank labels.
+         (hui:ebut-link-directly, hui:ibut-link-directly): In body, clear 
Smart Key
+    variables if not called interactively (since interactive clause also 
clears these
+    variables).  Also, if a button already exists at point, return t else nil. 
 This
+    lets the caller know what type of create/edit msg to display.  If not 
editing
+    an existing button, when prompting for a name or label, use any active and
+    highlighted region as the name or label.
+
 2023-07-01  Mats Lidell  <matsl@gnu.org>
 
 * hui.el:
@@ -16,6 +117,15 @@
     Monnier. Thanks Stefan.
     Align header fields consistently with other files.
 
+2023-06-30  Bob Weiner  <rsw@gnu.org>
+
+* hmouse-drv.el (hkey-window-link): Move action/assist-key-clear-varriables
+    calls into hui:*but-link-directly calls so happens every time they are
+    called.
+
+* man/hyperbole.texi (Glossary): Fix to note gbut:file is a function, not
+    a variable.
+
 2023-06-29  Mats Lidell  <matsl@gnu.org>
 
 * hyrolo.el: Remove redundant `:group` args.  Remove obsolete `*` in
@@ -24,6 +134,12 @@
 * hbut.el (defib): Remove redundant indent property. Change by Stefan
     Monnier.
 
+2023-06-27  Bob Weiner  <rsw@gnu.org>
+
+* test/hbut-tests.el (hbut-tests:should-match-tmp-folder): Change to use
+    a regexp 'string-match-p' to a string input rather than a 'member' test
+    to a list of lists.
+
 2023-06-25  Bob Weiner  <rsw@gnu.org>
 * hbut.el (ibut:to-name, ibut:at-p, ibut:to-text): Remove test call to
     'hbut:outside-comment-p' since ibuts don't have to be within programming
diff --git a/DEMO b/DEMO
index 5c6191fd2f..d09fa39973 100644
--- a/DEMO
+++ b/DEMO
@@ -1060,12 +1060,23 @@ Try that one by pressing between the square brackets.
 
 ** Completion Selection
 
-Often when Emacs or Hyperbole prompts for an argument in the minibuffer, a
-list of possible argument completions is available by pressing {?}.  A single
-Action Key press on any of these completions inserts it into the minibuffer
-for your inspection.  A second press on the same completion causes it to be
-used as the argument value and any succeeding argument prompt is then
-displayed.  Test this technique with a {C-x C-f} (find-file) and then a {?}.
+Often when Emacs or Hyperbole prompts for an argument in the
+minibuffer, a list of possible argument completions is available by
+pressing {?} or automatically displayed.  A single Action Key press on
+any of these completions inserts it into the minibuffer for your
+inspection.  A second press on the same completion uses it as the
+argument value and moves on to any next minibuffer argument prompt.
+Test this technique with a {C-x C-f} (find-file) and then a {?}.
+
+Within the minibuffer itself, the Smart Keys are also
+context-sensitive.  A press of the Action Key at the end of the
+argument line tries to accept the argument and when successful, exits
+the minibuffer.  A press of the Assist Key at the end of the argument
+line displays matching completions for times when they are not
+automatically displayed or need updating.  A press of the Action or
+Assist Key on part of the argument, deletes from point to the end of
+the line, expanding the set of available completions and redisplaying
+them.
 
 ** Hyperbole Source Buttons
 
diff --git a/hact.el b/hact.el
index 3d215beaf0..3fc3bfaff8 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:     29-May-23 at 21:50:42 by Bob Weiner
+;; Last-Mod:      8-Jul-23 at 13:19:37 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -115,9 +115,19 @@ with the `ibtypes::' prefix and one without.  The value 
for both
 keys is the Elisp symbol for the type, which includes the prefix.")
 
 (defsubst symtable:actype-p (symbol-or-name)
-  "Return SYMBOL-OR-NAME if it is a Hyperbole action type, else nil."
+  "Return SYMBOL-OR-NAME if a Hyperbole action type or Elisp function, else 
nil."
   (when (or (symbolp symbol-or-name) (stringp symbol-or-name))
-    (symtable:get symbol-or-name symtable:actypes)))
+    (or (symtable:get symbol-or-name symtable:actypes)
+       (and (stringp symbol-or-name) (fboundp (intern-soft symbol-or-name))
+            (intern-soft symbol-or-name))
+       (and (functionp symbol-or-name) symbol-or-name))))
+
+(defsubst symtable:hyperbole-actype-p (symbol-or-name)
+  "Return SYMBOL-OR-NAME if a Hyperbole action type, else nil.
+This excludes Emacs Lisp functions which may be used as action types.
+Use `actype:elisp-symbol' to include these."
+  (when (or (symbolp symbol-or-name) (stringp symbol-or-name))
+    (or (symtable:get symbol-or-name symtable:actypes))))
 
 (defsubst symtable:ibtype-p (symbol-or-name)
   "Return SYMBOL-OR-NAME if it is a Hyperbole implicit button type, else nil."
@@ -384,7 +394,7 @@ performing ACTION."
       ;; being used as a path.  So do this only if actype is a defact
       ;; and not a defun to limit any potential impact. RSW - 9/22/2017
       (and (symbolp action)
-          (symtable:actype-p action)
+          (symtable:hyperbole-actype-p action)
           (setq args (hpath:absolute-arguments actype args)))
       (let ((hist-elt (hhist:element)))
        (run-hooks 'action-act-hook)
@@ -413,6 +423,9 @@ is returned."
 
 (defun    actype:eval (actype &rest args)
   "Perform action formed from ACTYPE and rest of ARGS and return value.
+This differs from `actype:act' in that it can return nil and does not
+expand relative pathname ARGS.
+
 ACTYPE may be a string containing a Lisp expression from which ACTYPE
 and ARGS are extracted.  ACTYPE may be a symbol or symbol name for
 either an action type or a function.  Run `action-act-hook' before
@@ -424,18 +437,19 @@ performing ACTION."
       (let ((hist-elt (hhist:element)))
        (run-hooks 'action-act-hook)
        (prog1 (if (or (symbolp action) (listp action)
-                      (byte-code-function-p action)
-                      (subrp action)
-                      (and (stringp action) (not (integerp action))
-                           (setq action (key-binding action))))
+                         (byte-code-function-p action)
+                         (subrp action)
+                         (and (stringp action) (not (integerp action))
+                              (setq action (key-binding action))))
                   (apply action args)
                 (eval action))
          (hhist:add hist-elt))))))
 
 (defun    actype:action (actype)
-  "Return action part (body) of ACTYPE.
-ACTYPE is a bound function symbol, symbol name or function body.
-ACTYPE may be a Hyperbole actype or Emacs Lisp function."
+  "If ACTYPE is a bound function symbol, return it.
+Otherwise, return its body.  ACTYPE must be a bound function
+symbol, symbol name or function body.  ACTYPE may be a Hyperbole
+actype or Emacs Lisp function."
   (let (actname
        action)
     (cond ((stringp actype)
diff --git a/hactypes.el b/hactypes.el
index 981af765a9..02e7539db3 100644
--- a/hactypes.el
+++ b/hactypes.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    23-Sep-91 at 20:34:36
-;; Last-Mod:      1-Jul-23 at 23:06:38 by Mats Lidell
+;; Last-Mod:      8-Jul-23 at 16:02:44 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -67,8 +67,8 @@ inserted, delete the completions window."
 Return any non-nil value or t."
   (interactive "xDisplay bool expr value: ")
   (let ((result (eval bool-expr t)))
-    (message "Boolean result (%s) = %S; Expr: %S"
-            (if result "True" "False") result bool-expr)
+    (message "Result = %S; Boolean value = %s; Expr = %S"
+            result (if result "True" "False") bool-expr)
     (or result t)))
 
 (defact display-value (value)
diff --git a/hargs.el b/hargs.el
index 4cee338726..ca1ab5a866 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:     17-Jun-23 at 13:05:33 by Bob Weiner
+;; Last-Mod:      5-Jul-23 at 00:45:15 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -328,7 +328,47 @@ default values.
 Caller should have checked whether an argument is presently being read
 and has set `hargs:reading-type' to an appropriate argument type.
 Handles all of the interactive argument types that `hargs:iform-read' does."
-  (cond ((and (eq hargs:reading-type 'kcell)
+  (cond ;; vertico-mode
+       ((and (null hargs:reading-type)
+             (bound-and-true-p vertico-mode)
+             ;; Ensure vertico is prompting for an argument
+             (vertico--command-p nil (current-buffer))
+             (active-minibuffer-window))
+        (if (and action-key-release-args
+                 (fboundp #'vertico-mouse--index)
+                 (eq (posn-window (event-end action-key-release-args))
+                     (active-minibuffer-window)))
+            (with-selected-window (active-minibuffer-window)
+              (let ((index (vertico-mouse--index action-key-release-args))
+                    mini)
+                (if index
+                    (save-excursion
+                      (vertico--goto index)
+                      (vertico--update t)
+                      (vertico--candidate))
+                  ;; Assume event occurred within the
+                  ;; minibufer-contents and return just the contents
+                  ;; before point so that those after are deleted and
+                  ;; more completions are shown.
+                  (setq mini (minibuffer-contents-no-properties))
+                  ;; The minibuffer may have some read-only contents
+                  ;; at the beginning, e.g. M-x, not included in the 'mini'
+                  ;; string, so we have to offset the max index into
+                  ;; the string in such cases and protect against
+                  ;; when point is set into this read-only area with
+                  ;; the 'max' call below.
+                  (list (substring mini 0 (max (- (point) (point-max)) (- 
(length mini)))) nil))))
+          (list (vertico--candidate) t)))
+       ((and (null hargs:reading-type)
+             action-key-release-args
+             (eq (posn-window (event-end action-key-release-args))
+                 (active-minibuffer-window)))
+        ;; Event occurred within the minibufer-contents and return
+        ;; just the contents before point so that those after are
+        ;; deleted and more completions are shown.
+        (setq mini (minibuffer-contents-no-properties))
+        (list (substring mini 0 (max (- (point) (point-max)) (- (length 
mini)))) nil))
+       ((and (eq hargs:reading-type 'kcell)
              (eq major-mode 'kotl-mode)
              (not (looking-at "^$")))
         (kcell-view:label))
@@ -360,7 +400,9 @@ Handles all of the interactive argument types that 
`hargs:iform-read' does."
                         (following-char))))
                    ;; At the end of the menu
                    (t 0)))))
-       ((hargs:completion t))
+       ((let ((completion (hargs:completion t)))
+          (when completion
+            (list completion t))))
        ((eq hargs:reading-type 'ebut) (ebut:label-p 'as-label))
        ((eq hargs:reading-type 'ibut) (ibut:label-p 'as-label))
        ((eq hargs:reading-type 'gbut)
@@ -495,7 +537,9 @@ Insert in minibuffer if active or in other window if 
minibuffer is inactive."
                              entry))))
                (or no-insert
                    (when entry
-                     (erase-buffer)
+                     (if (eq insert-window (minibuffer-window))
+                         (delete-minibuffer-contents)
+                       (erase-buffer))
                      (insert entry))))
               ;; In buffer, non-minibuffer completion.
               ;; Only insert entry if last buffer line does
@@ -558,7 +602,7 @@ See also documentation for `interactive'."
                  (while (cond
                          ((eq (aref iform i) ?*))
                          ((eq (aref iform i) ?@)
-                          (hargs:select-event-window)
+                          (hargs:selectevent-window)
                           t)
                          ((eq (aref iform i) ?^)
                           (handle-shift-selection))
@@ -663,8 +707,9 @@ of value to be read."
                  (beep))))
            result)
        (setq hargs:reading-type prev-reading-p)
-       (select-window owind)
-       (switch-to-buffer obuf)))))
+       (when (window-live-p owind)
+         (select-window owind)
+         (switch-to-buffer obuf))))))
 
 (defun hargs:select-p (&optional value assist-bool)
   "Return optional VALUE or value selected at point if any, else nil.
@@ -673,33 +718,69 @@ the current minibuffer argument, otherwise, the 
minibuffer is erased
 and value is inserted there.
 Optional ASSIST-BOOL non-nil triggers display of Hyperbole menu item
 help when appropriate."
-    (when (and (> (minibuffer-depth) 0) (or value (setq value (hargs:at-p))))
-      (let ((owind (selected-window)) (back-to)
-           (str-value (and value (format "%s" value)))
-           ;; This command requires recursive minibuffers.
-           (enable-recursive-minibuffers t))
-       (unwind-protect
-           (progn
-             (select-window (minibuffer-window))
-             (set-buffer (window-buffer (minibuffer-window)))
+  (when (and (> (minibuffer-depth) 0) (or value (setq value (hargs:at-p))))
+    (let ((owind (selected-window)) (back-to)
+         ;; This command requires recursive minibuffers.
+         (enable-recursive-minibuffers t))
+      (when (stringp value)
+       (setq value (list value nil)))
+      (unwind-protect
+         (cl-destructuring-bind (str-value exact-completion-flag) value
+           (setq str-value (and str-value (format "%s" str-value)))
+           (select-window (minibuffer-window))
+           (set-buffer (window-buffer (minibuffer-window)))
+           (cond
+            ;;
+            ;; Selecting a Hyperbole minibuffer menu item
+            ((eq hargs:reading-type 'hmenu)
+             (when assist-bool
+               (setq hargs:reading-type 'hmenu-help))
+             (hui:menu-enter str-value))
+            ;;
+            ;; Exit minibuffer and use its existing value as the desired 
parameter.
+            ((string-equal str-value (minibuffer-contents))
+             (goto-char (point-max))
+             (cond
+              ;; vertico-mode
+              ((and (bound-and-true-p vertico-mode)
+                    ;; Ensure vertico is prompting for an argument
+                    (vertico--command-p nil (current-buffer)))
+               (vertico-exit))
+              ;; ivy-mode
+              ((bound-and-true-p ivy-mode)
+               (if assist-bool
+                   (ivy-dispatching-done)
+                 (ivy-done)))
+              ;; standard minibuffer completion
+              (t (exit-minibuffer))))
+            ;;
+            ;; Clear minibuffer and insert value.
+            (t
+             (delete-minibuffer-contents)
+             (goto-char (point-max))
              (cond
-              ;;
-              ;; Selecting a Hyperbole minibuffer menu item
-              ((eq hargs:reading-type 'hmenu)
-               (when assist-bool
-                 (setq hargs:reading-type 'hmenu-help))
-               (hui:menu-enter str-value))
-              ;;
-              ;; Enter existing value into the minibuffer as the desired 
parameter.
-              ((string-equal str-value (minibuffer-contents))
-               (exit-minibuffer))
-              ;;
-              ;; Clear minibuffer and insert value.
-              (t (delete-minibuffer-contents)
-                 (insert str-value)
-                 (setq back-to t)))
-             value)
-         (when back-to (select-window owind))))))
+              ;; ivy-mode
+              ((bound-and-true-p ivy-mode)
+               (if assist-bool
+                   (ivy-dispatching-done)
+                 (ivy-done)))
+              ;; standard minibuffer completion
+              ;; vertico-mode
+              ((and (bound-and-true-p vertico-mode)
+                    ;; Ensure vertico is prompting for an argument
+                    (vertico--command-p nil (current-buffer)))
+                (if str-value
+                   (insert str-value)
+                 (vertico-insert))
+               (vertico--update t))
+              (t
+               (insert str-value)
+               (unless exact-completion-flag
+                 (minibuffer-completion-help))
+               (setq back-to t)))
+             value)))
+       (when (and back-to (window-live-p owind))
+         (select-window owind))))))
 
 ;;; ************************************************************************
 ;;; Private variables
diff --git a/hbut.el b/hbut.el
index 10a168a7bd..10606694ec 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:     30-Jun-23 at 22:39:57 by Mats Lidell
+;; Last-Mod:      8-Jul-23 at 16:02:16 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -219,7 +219,7 @@ Return nil if no matching button is found."
 (defalias 'ebut:key-src-fmt        #'hbut:key-src-fmt)
 (defalias 'ebut:key-to-label       #'hbut:key-to-label)
 
-(defvar hbut:max-len)
+(defvar   hbut:max-len)
 
 (defun    ebut:label-p (&optional as-label start-delim end-delim pos-flag 
two-lines-flag)
   "Return key for the explicit button label that point is within, else nil.
@@ -470,12 +470,12 @@ For interactive creation, use `hui:ebut-create' instead."
             (if (or (and actype-sym (fboundp actype-sym))
                    (functionp actype))
                (hattr:set 'hbut:current 'actype actype)
-             (error (format "(%s)" actype)))
+             (error "(%s)" actype))
            (hattr:set 'hbut:current 'args args)
            (ebut:operate label nil))
        (error (hattr:clear 'hbut:current)
               (if (and (listp (cdr err)) (= (length (cdr err)) 1))
-                  (error (format "(ebut:program): actype arg must be a bound 
symbol (not a string): %S" actype))
+                  (error "(ebut:program): actype arg must be a bound symbol 
(not a string): %S" actype)
                 (error "(ebut:program): %S" err)))))))
 
 (defun    ebut:search (string out-buf &optional match-part)
@@ -807,7 +807,7 @@ Return TO-HBUT."
   (setplist to-hbut (copy-sequence (symbol-plist from-hbut)))
   to-hbut)
 
-(defun hattr:emacs-button-attributes (button)
+(defun    hattr:emacs-button-attributes (button)
   "Return a property list of an Emacs BUTTON."
   (if (markerp button)
       ;; If on a text property button, button-at will
@@ -820,7 +820,7 @@ Return TO-HBUT."
       (when category
        (symbol-plist category)))))
 
-(defun hattr:emacs-button-is-p (button)
+(defun    hattr:emacs-button-is-p (button)
   "If BUTTON is a valid Emacs button, return its category, else return nil."
   (let* ((type (when (or (overlayp button) (markerp button))
                 (button-get button 'type)))
@@ -982,7 +982,8 @@ Default is the symbol hbut:current."
        action)
     (setq action (car (hattr:get hbut 'action))
          atype  (hattr:get hbut 'actype))
-    (if (= (length (symbol-name atype)) 2)
+    (if (and (symbolp atype)
+            (= (length (symbol-name atype)) 2))
        atype
       (or action (actype:action atype)))))
 
@@ -2171,7 +2172,7 @@ move to the first occurrence of the button."
 
 (defun    ibut:operate (&optional new-name edit-flag)
   "Insert/modify an ibutton based on `hbut:current' in current buffer.
-Optional non-nil NEW-NAME is name to give button.  With optional
+Optional non-nil NEW-NAME is new name to give button.  With optional
 EDIT-FLAG non-nil, modify an existing in-buffer ibutton rather
 than creating a new one.
 
@@ -2182,20 +2183,28 @@ Return instance string appended to name to form a 
per-buffer unique
 name; nil if name is already unique or no name.  Signal an error when no
 such button is found in the current buffer.
 
-Summary of operations based on inputs:
-|-------+----------+--------+------------------------------------------------|
-| name  | new-name | region | operation                                      |
-|-------+----------+--------+------------------------------------------------|
-| nil   | nil      | nil    | create: unnamed ibut                           |
-| aname | nil      | nil    | create/update: aname named ibut                |
-| aname | nil      | region | create/update: aname named ibut (skip region)  |
-| nil   | nil      | region | create/update: region named ibut               |
-| aname | newname  | nil    | mod: rename aname to newname                   |
-| aname | newname  | region | mod: rename aname to newname (skip region)     |
-| nil   | newname  | nil    | mod: add newname to lbl-key ibut at point      |
-| nil   | newname  | region | mod: add newname to lbl-key ibut (skip region) |
-|-------+----------+--------+------------------------------------------------|"
-  ;; !! TODO: Code does not yet fully match what is in docstring table
+Summary of operations based on inputs (name arg comes from \\='hbut:current 
attrs):
+|----+------+----------+--------+------+-----------------------------------------------|
+|  # | name | new-name | region | edit | operation                             
        |
+|----+------+----------+--------+------+-----------------------------------------------|
+|  1 | nil  | nil      | nil    | nil  | create: unnamed ibut from 
hbut:current attrs  |
+|  2 | nil  | new-name | nil    | nil  | create: new-name named ibut           
        |
+|  3 | name | nil      | nil    | nil  | create: aname named ibut              
        |
+|  4 | name | new-name | nil    | nil  | ERROR: create can't have name and 
new-name    |
+|  5 | name | new-name | region | nil  | ERROR: create can't have name and 
new-name    |
+|  6 | name | nil      | region | nil  | create: aname named ibut (skip 
region)        |
+|  7 | nil  | nil      | region | nil  | create: region named ibut             
        |
+|  8 | nil  | new-name | region | nil  | create: new-name named ibut (skip 
region)     |
+|----+------+----------+--------+------+-----------------------------------------------|
+|  9 | nil  | nil      | nil    | t    | mod: unnamed ibut from hbut:current 
attrs     |
+| 10 | nil  | new-name | nil    | t    | mod: add new-name to lbl-key ibut at 
point    |
+| 11 | name | nil      | nil    | t    | mod: aname named ibut from 
hbut:current attrs |
+| 12 | name | new-name | nil    | t    | mod: rename aname to new-name         
        |
+| 13 | name | new-name | region | t    | ERROR: Can't use region to mod 
existing ibut  |
+| 14 | name | nil      | region | t    | ERROR: Can't use region to mod 
existing ibut  |
+| 15 | nil  | nil      | region | t    | ERROR: Can't use region to mod 
existing ibut  |
+| 16 | nil  | new-name | region | t    | ERROR: Can't use region to mod 
existing ibut  |
+|----+------+----------+--------+------+-----------------------------------------------|"
   (let* ((actype (hattr:get 'hbut:current 'actype))
         (name (hattr:get 'hbut:current 'name))
         (name-regexp (ibut:label-regexp (ibut:label-to-key name)))
@@ -2207,6 +2216,10 @@ Summary of operations based on inputs:
     (when (and new-name (or (not (stringp new-name)) (string-empty-p 
new-name)))
       (hypb:error "(ibut:operate): 'new-name' value must be a non-empty 
string, not: '%s'"
                  new-name))
+    (when (and name new-name (not edit-flag))
+      (hypb:error "(ibut:operate): 'edit-flag' must be t to rename a button 
(hbut:current name and new-name both given)"))
+    (when (and region-flag edit-flag)
+      (hypb:error "(ibut:operate): 'edit-flag' must be nil when region is 
highlighted to use region as new button name"))
 
     (unless new-name
       (setq new-name name))
@@ -2214,14 +2227,8 @@ Summary of operations based on inputs:
       (hattr:set 'hbut:current 'name new-name))
     (save-excursion
       (if (progn
-           (if edit-flag
-               (progn
-                 (setq instance-flag
-                       (hbdata:ibut-instance-last (ibut:label-to-key 
new-name)))
-                 (run-hooks 'ibut-edit-hook))
-             (setq instance-flag
-                   (hbdata:ibut-instance-last (ibut:label-to-key name)))
-             (run-hooks 'ibut-create-hook))
+           (setq instance-flag (hbdata:ibut-instance-last (ibut:label-to-key
+                                                           (if edit-flag 
new-name name))))
            (when (null instance-flag)
              (setq instance-flag t))
            instance-flag)
@@ -2231,43 +2238,47 @@ Summary of operations based on inputs:
                    (if edit-flag "modify" "create")
                    ibut:label-start name ibut:label-end
                    (buffer-name))))
-    (cond (edit-flag
-          (if name
-              ;; Rename all occurrences of button - those with same name
-              (let* ((but-key-and-pos (ibut:label-p nil nil nil 'pos))
-                     (at-but (equal (car but-key-and-pos)
-                                    (ibut:label-to-key new-name))))
-                (when at-but
-                  (ibut:delimit (nth 1 but-key-and-pos)
-                                (nth 2 but-key-and-pos)
+    (let (start end mark prev-point)
+      (cond (edit-flag
+            (cond (name
+                   ;; Rename all occurrences of button - those with same name
+                   (let* ((but-key-and-pos (ibut:label-p nil nil nil 'pos))
+                          (at-but (equal (car but-key-and-pos)
+                                         (ibut:label-to-key new-name))))
+                     (when at-but
+                       (ibut:delimit (nth 1 but-key-and-pos)
+                                     (nth 2 but-key-and-pos)
+                                     instance-flag))
+                     (cond ((ibut:map
+                             (lambda (_lbl start end)
+                               (delete-region start end)
+                               (ibut:delimit
+                                (point)
+                                (progn (insert new-name) (point))
                                 instance-flag))
-                (cond ((ibut:map
-                        (lambda (_lbl start end)
-                          (delete-region start end)
-                          (ibut:delimit
-                           (point)
-                           (progn (insert new-name) (point))
-                           instance-flag))
-                        name-regexp 'include-delims))
-                      (at-but)
-                      ((hypb:error "(ibut:operate): No button matching: %s" 
name))))
-            ;; Add new-name to nameless button at point
-            (goto-char (or (hattr:get 'hbut:current 'lbl-start) (point)))
-            (ibut:delimit (point)
-                          (progn (insert new-name) (point))
-                          instance-flag)))
-
-         (instance-flag
-          ;; Above flag is 't when there is exactly one existing
-          ;; instance of the button name
-          ;;
-          ;; Add a new implicit button in the buffer, recording its
-          ;; start and end positions; new-name is always nil here
-          (let (start end mark prev-point buf-lbl)
+                             name-regexp 'include-delims))
+                           (at-but)
+                           ((hypb:error "(ibut:operate): No button matching: 
%s" name)))))
+                  (new-name
+                   ;; Add new-name to nameless button at point
+                   (goto-char (or (hattr:get 'hbut:current 'lbl-start) 
(point)))
+                   (ibut:delimit (point)
+                                 (progn (insert new-name) (point))
+                                 instance-flag))))
+
+           (instance-flag
+            ;; Above flag is 't when there is exactly one existing
+            ;; instance of the button name
+            ;;
+            ;; Add a new implicit button in the buffer, recording its
+            ;; start and end positions; new-name is always nil here
             (cond ((not (or name region-flag))
                    ;; No name to insert, just insert ibutton text below
                    )
                   ((and region-flag
+                        ;; ignore region when name or new-name are set
+                        (not (or name new-name))
+                        ;; new-name is always nil here
                         (if (hyperb:stack-frame
                              '(hui:ebut-create hui:ebut-edit 
hui:ebut-edit-region
                                                hui:ebut-link-create 
hui:gbut-create
@@ -2275,43 +2286,45 @@ Summary of operations based on inputs:
                                                hui:ibut-create hui:ibut-edit
                                                hui:ibut-link-create 
ibut:program))
                             ;; Ignore action-key-depress-prev-point
-                            (progn (setq mark (marker-position (mark-marker))
-                                         start (region-beginning)
-                                         end (region-end)
-                                         buf-lbl 
(buffer-substring-no-properties start end))
-                                   (equal buf-lbl name))
+                            (setq start (region-beginning)
+                                  end (region-end)
+                                  name (buffer-substring-no-properties start 
end))
                           ;; Utilize any action-key-depress-prev-point
-                          (setq mark (marker-position (mark-marker)))
-                          (setq prev-point (and action-key-depress-prev-point
-                                                (marker-position 
action-key-depress-prev-point)))
-                          (setq start (if (and prev-point mark (<= prev-point 
mark))
+                          (setq mark (marker-position (mark-marker))
+                                prev-point (and action-key-depress-prev-point
+                                                (marker-position 
action-key-depress-prev-point))
+                                start (if (and prev-point mark (<= prev-point 
mark))
                                           prev-point
                                         (region-beginning))
                                 end (if (and prev-point mark (> prev-point 
mark))
                                         prev-point
                                       (region-end))
-                                buf-lbl (buffer-substring-no-properties start 
end))
-                          (equal buf-lbl name)))
+                                name (buffer-substring-no-properties start 
end))))
                    nil)
                   ((progn (when start (goto-char start))
-                          (when name  (looking-at (regexp-quote name))))
+                          (or (when name  (looking-at (regexp-quote name)))
+                              (when new-name  (looking-at (regexp-quote 
new-name)))))
                    (setq start (point)
                          end (match-end 0)))
                   (name
                    (setq start (point))
                    (insert name)
-                   (setq end (point))))
-
-            (when (and start end)
-              (ibut:delimit start end instance-flag))
-            (ibut:insert-text 'hbut:current)
-            (if start
-                (goto-char start)
-              (goto-char (max (- (point) 2) (point-min))))))
-
-         (t (hypb:error
-             "(ibut:operate): Operation failed.  Check button attribute 
permissions: %s"
-             hattr:filename)))
+                   (setq end (point)))
+                  (new-name
+                   (setq start (point))
+                   (insert new-name)
+                   (setq end (point)))))
+           (t (hypb:error
+               "(ibut:operate): Operation failed.  Check button attribute 
permissions: %s"
+               hattr:filename)))
+
+      (unless edit-flag
+       (when (and start end)
+         (ibut:delimit start end instance-flag))
+       (ibut:insert-text 'hbut:current)
+       (if start
+           (goto-char start)
+         (goto-char (max (- (point) 2) (point-min))))))
 
     ;; Append any instance-flag string to the button name
     (when (stringp instance-flag)
@@ -2342,6 +2355,8 @@ Summary of operations based on inputs:
        (hypb:error "(ibut:operate): hbut:current ibut lbl-key '%s' must be 
non-nil"
                    lbl-key)))
 
+    (run-hooks (if edit-flag 'ibut-edit-hook 'ibut-create-hook))
+
     ;; instance-flag might be 't which we don't want to return.
     (when (stringp instance-flag) instance-flag)))
 
@@ -2357,8 +2372,7 @@ Summary of operations based on inputs:
         (args   (hattr:get ibut 'args))
         (arg1   (nth 0 args))
         (arg2   (nth 1 args))
-        (arg3   (nth 2 args))
-        (arg4   (nth 3 args)))
+        (arg3   (nth 2 args)))
     (pcase actype
       ('actypes::kbd-key
        (cond ((and (stringp arg1) (string-match "\\s-*{.+}\\s-*" arg1))
@@ -2450,10 +2464,20 @@ function, followed by a list of arguments for the 
actype, aside from
 the button NAME which is automatically provided as the first argument.
 
 For interactive creation, use `hui:ibut-create' instead."
+  ;; Throw an error if on a named or delimited Hyperbole button since
+  ;; cannot create another button within such contexts.
+  (when (hbut:at-p)
+    (let ((name (hattr:get 'hbut:current 'name))
+         (lbl (hbut:key-to-label (hattr:get 'hbut:current 'lbl-key)))
+         (lbl-start (hattr:get 'hbut:current 'lbl-start))
+         (lbl-end (hattr:get 'hbut:current 'lbl-end)))
+      (when (or name lbl (and lbl-start lbl-end))
+       (error "(ibut:program): Cannot nest an ibut within the existing button: 
%s"
+              (or name lbl (buffer-substring-no-properties lbl-start 
lbl-end))))))
   (save-excursion
     (let ((but-buf (current-buffer))
          (actype-sym (actype:action actype)))
-      (hui:buf-writable-err but-buf "ibut-create")
+      (hui:buf-writable-err but-buf "ibut:program")
       (hattr:clear 'hbut:current)
       (hattr:set 'hbut:current 'name name)
       (hattr:set 'hbut:current 'categ 'implicit)
@@ -2462,7 +2486,7 @@ For interactive creation, use `hui:ibut-create' instead."
       (if (or (and actype-sym (fboundp actype-sym))
              (functionp actype))
          (hattr:set 'hbut:current 'actype actype)
-       (error (format "actype arg must be a bound symbol (not a string): %S" 
actype)))
+       (error "actype arg must be a bound symbol (not a string): %S" actype))
       (hattr:set 'hbut:current 'args args)
       (condition-case err
          (ibut:operate)
@@ -2715,7 +2739,7 @@ type for ibtype is presently undefined."
 
 (defalias 'ibtype:create #'defib)
 
-(defun ibtype:activate-link (referent)
+(defun    ibtype:activate-link (referent)
   "Activate an implicit link REFERENT, either a key series, a url or a path."
   (when referent
     (let ((key-series (kbd-key:is-p referent)))
diff --git a/hib-social.el b/hib-social.el
index 74c4bb1fd9..55d38d3531 100644
--- a/hib-social.el
+++ b/hib-social.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    20-Jul-16 at 22:41:34
-;; Last-Mod:     28-May-23 at 10:06:20 by Mats Lidell
+;; Last-Mod:      2-Jul-23 at 04:19:57 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -189,42 +189,35 @@
                (const "gitlab")
                (const "instagram")
                (const "twitter"))
-  :group 'hyperbole-button)
+  :group 'hyperbole-buttons)
 
 (defcustom hibtypes-social-display-function #'browse-url
   "Function of one arg, url, to display when activating a social media 
reference."
-  :type 'function
-  :group 'hyperbole-button)
+  :type 'function)
 
 (defcustom hibtypes-git-default-project nil
   "Default project name to associate with any local git commit link."
-  :type 'string
-  :group 'hyperbole-button)
+  :type 'string)
 
 (defcustom hibtypes-git-use-magit-flag nil
   "Non-nil means use `magit' rather than `dired' for a git directory button."
-  :type 'boolean
-  :group 'hyperbole-button)
+  :type 'boolean)
 
 (defcustom hibtypes-github-default-project nil
   "Default project name to associate with any Github commit link."
-  :type 'string
-  :group 'hyperbole-button)
+  :type 'string)
 
 (defcustom hibtypes-github-default-user nil
   "Default user name to associate with any Github commit link."
-  :type 'string
-  :group 'hyperbole-button)
+  :type 'string)
 
 (defcustom hibtypes-gitlab-default-project nil
   "Default project name to associate with any Github commit link."
-  :type 'string
-  :group 'hyperbole-button)
+  :type 'string)
 
 (defcustom hibtypes-gitlab-default-user nil
   "Default user name to associate with any Github commit link."
-  :type 'string
-  :group 'hyperbole-button)
+  :type 'string)
 
 ;;; ************************************************************************
 ;;; Public declarations
diff --git a/hibtypes.el b/hibtypes.el
index 2f9814b458..629a02b23f 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:     25-Jun-23 at 23:04:09 by Bob Weiner
+;; Last-Mod:      8-Jul-23 at 14:02:33 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1537,24 +1537,21 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
           (cond ((and (symbolp actype) (fboundp actype)
                      (string-match "-p\\'" (symbol-name actype)))
                 ;; Is a function with a boolean result
-                (setq args `(',args)
-                      action `(display-boolean ',action)
-                      actype #'display-boolean))
+                (setq actype #'display-boolean
+                      args `(',action)))
                ((and (null args) (symbolp actype) (boundp actype)
                      (or var-flag (not (fboundp actype))))
                 ;; Is a variable, display its value as the action
-                (setq args `(',args)
-                      action `(display-variable ',actype)
+                (setq args `(',actype)
                       actype #'display-variable))
                (t
                 ;; All other expressions, display the action result in the 
minibuffer
-                (setq args `(',args)
-                      action `(display-value ',action)
-                      actype #'display-value))))
+                (setq actype #'display-value
+                      args `(',action)))))
 
        ;; Create implicit button object and store in symbol hbut:current.
        (ibut:create :lbl-key lbl-key :lbl-start start-pos :lbl-end end-pos
-                    :categ 'ibtypes::action :actype actype :args args :action 
action)
+                    :categ 'ibtypes::action :actype actype :args args)
 
         ;; Necessary so can return a null value, which actype:act cannot.
         (let ((hrule:action
diff --git a/hload-path.el b/hload-path.el
index 34ad0f8115..002cc244a4 100644
--- a/hload-path.el
+++ b/hload-path.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    29-Jun-16 at 14:39:33
-;; Last-Mod:     25-Jun-23 at 09:58:19 by Bob Weiner
+;; Last-Mod:      2-Jul-23 at 12:25:01 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -25,14 +25,12 @@
 ;;; Public variables
 ;;; ************************************************************************
 
-
 (defvar hyperb:microsoft-os-p
   (memq system-type '(ms-windows windows-nt ms-dos win32))
   "Non-nil iff Hyperbole is running under a Microsoft OS but not for WSL.
 WSL is Windows Subsystem for Linux.
 Use `hyperb:wsl-os-p' to test if running under WSL.")
 
-
 (defvar hyperb:wsl-os-p
   (and (eq system-type 'gnu/linux) (executable-find "wsl.exe") t)
   "T iff Hyperbole is running under Microsoft Windows Subsystem for Linux 
(WSL).")
@@ -173,7 +171,7 @@ This is used only when running from git source and not a 
package release."
     (with-current-buffer (find-file-noselect al-file)
       (hload-path--make-directory-autoloads "." al-file)))
   (unless (hyperb:autoloads-exist-p)
-    (error (format "Hyperbole failed to generate autoload files; try running 
'make src' in a shell in %s" hyperb:dir))))
+    (error "Hyperbole failed to generate autoload files; try running 'make 
src' in a shell in %s" hyperb:dir)))
 
 (defun hyperb:maybe-load-autoloads ()
   "Load Hyperbole autoload files that have not already been loaded."
diff --git a/hmouse-drv.el b/hmouse-drv.el
index 4ae38d346f..5d5cef6258 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    04-Feb-90
-;; Last-Mod:     19-Jun-23 at 15:56:40 by Bob Weiner
+;; Last-Mod:      4-Jul-23 at 15:36:51 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -635,11 +635,6 @@ With a prefix argument, create an unnamed implicit button 
instead."
   (let ((start-window (selected-window)))
     (unwind-protect
        (progn
-         ;; Clear Smart Key variables so `hui:*but-link-directly' does not
-         ;; improperly reference values left over from a prior drag or
-         ;; click.  This command does not utilize the Smart Keys.
-         (action-key-clear-variables)
-         (assist-key-clear-variables)
          (funcall (if current-prefix-arg
                       #'hui:ibut-link-directly
                     #'hui:ebut-link-directly)
@@ -787,8 +782,9 @@ buffer to the end window.  The selected window does not 
change."
             ;; Fall through to error below
             )
            (t
-            ;; Either this frame has more than two windows or other frames 
exist
-            ;; that together have more than one window; choose which to use.
+            ;; Either this frame has more than two windows or other
+            ;; frames exist that together have more than one window;
+            ;; choose which to use as the referent window.
             (setq referent-window
                   (if (fboundp #'aw-select) ;; ace-window selection
                       (let ((aw-scope 'global))
@@ -1072,12 +1068,10 @@ documentation is found."
                                  (select-window (previous-window))
                                  (display-buffer buf 'other-win))
                              (display-buffer buf 'other-win))
-                           (if (or (and (boundp 'help-window-select)
-                                        help-window-select)
-                                   (and (boundp 'help-selects-help-window)
-                                        help-selects-help-window))
-                               (select-window (get-buffer-window buf))
-                             (select-window owind)))))
+                           (select-window
+                            (if (bound-and-true-p help-window-select)
+                                (get-buffer-window buf)
+                              owind)))))
                       (temp-buffer-show-function temp-buffer-show-hook))
                  (with-output-to-temp-buffer
                      (hypb:help-buf-name
@@ -1376,9 +1370,9 @@ and it was inactive, return its window, else nil."
   (let ((window (posn-window (event-start event))))
     (when (framep window)
       (setq window (frame-selected-window window)))
-    (and (window-minibuffer-p window)
-        (not (minibuffer-window-active-p window))
-        window)))
+    (and window
+        (window-minibuffer-p window)
+        (not (minibuffer-window-active-p window)))))
 
 ;; Based on code from subr.el.
 (defun hmouse-vertical-line-spacing (frame)
diff --git a/hmouse-sh.el b/hmouse-sh.el
index 5c81a82f4e..f14b9b09d3 100644
--- a/hmouse-sh.el
+++ b/hmouse-sh.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     3-Sep-91 at 21:40:58
-;; Last-Mod:     16-Oct-22 at 19:32:50 by Mats Lidell
+;; Last-Mod:      4-Jul-23 at 12:26:37 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -401,13 +401,19 @@ Select the corresponding window as well."
     (unless (windowp (posn-window position))
       (error "Position not in text area of window"))
     (select-window (posn-window position)))
-  (when (numberp (posn-point position))
-    (goto-char (posn-point position))))
+  (let ((pos-point (posn-point position)))
+    ;; Need all these checks for vertico-mode
+    (when (and (numberp pos-point)
+              (>= pos-point (point-min))
+              (<= pos-point (point-max)))
+      (goto-char pos-point))))
 
 ;; Based on mouse-drag-region from Emacs mouse.el.
 (defun hmouse-drag-region (start-event)
   "Set the region to the text that the mouse is dragged over.
-If not the start of a region drag-and-drop, then depress the Action Key.
+If not the start of a region drag-and-drop, and hyperbole-mode is
+enabled, then depress the Action Key.
+
 Highlight the drag area as you move the mouse.
 This must be bound to a button-down mouse event.
 In Transient Mark mode, the highlighting remains as long as the mark
@@ -423,7 +429,8 @@ is dragged over to."
       (mouse-drag-and-drop-region start-event)
     ;; Give temporary modes such as isearch a chance to turn off.
     (run-hooks 'mouse-leave-buffer-hook)
-    (action-key-depress start-event)
+    (when hyperbole-mode
+      (action-key-depress start-event))
     (mouse-drag-track start-event)))
 
 ;; Based on a function from Emacs mouse.el.
diff --git a/hpath.el b/hpath.el
index 47cd61f2e7..c50a9bc074 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:     30-Jun-23 at 22:38:18 by Mats Lidell
+;; Last-Mod:      8-Jul-23 at 16:01:35 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -660,14 +660,14 @@ Contains a %s for replacement of a specific anchor id.")
   "Regexp matching a Markdown anchor id definition.
 Contains a %s for replacement of a specific anchor id.")
 
-(defconst hpath:markdown-section-pattern "^[ \t]*\\(#+\\|\\*+\\)[ \t]+%s\\([ 
\t[:punct:]]*\\)$"
+(defconst hpath:markdown-section-pattern "^[ \t]*\\(#+\\|\\*+\\)[ 
\t]+%s\\([\[<\({ \t[:punct:]]*\\)$"
   "Regexp matching a Markdown section header.
 Contains a %s for replacement of a specific section name.")
 
 (defconst hpath:markdown-suffix-regexp "\\.[mM][dD]"
   "Regexp that matches to a Markdown file suffix.")
 
-(defconst hpath:outline-section-pattern "^\\*+[ \t]+%s[ 
\t]*\\([:punct:]+\\|$\\)"
+(defconst hpath:outline-section-pattern "^\\*+[ \t]+%s[ 
\t]*\\([\[<\({[:punct:]]+\\|$\\)"
   "Bol-anchored, no leading spaces regexp matching an Emacs outline section 
header.
 Contains a %s for replacement of a specific section name.")
 
@@ -716,7 +716,7 @@ Uses optional DEFAULT-DIRS (a list of dirs or a single dir) 
or
                 (make-list (max 0 (- (length arg-list) (length param-list)))
                            (last param-list))))
     (cl-mapcar (lambda (param arg)
-                (if (and arg
+                (if (and (stringp param)
                          (or (string-match-p "file" param)
                              (string-match-p "dir" param)
                              (string-match-p "path" param)))
diff --git a/hui-menu.el b/hui-menu.el
index 4e2151c879..fab739f65b 100644
--- a/hui-menu.el
+++ b/hui-menu.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    28-Oct-94 at 10:59:44
-;; Last-Mod:     19-Jun-23 at 13:28:35 by Bob Weiner
+;; Last-Mod:      2-Jul-23 at 04:01:16 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -416,6 +416,7 @@ REBUILD-FLAG is non-nil, in which case the menu is rebuilt."
                   ["Delete" hui:gbut-delete t]
                   ["Edit"   hui:gbut-edit t]
                   ["Help"   gbut:help t]
+                  ["Link"   hui:gbut-link-directly t]
                    ["Rename" hui:gbut-rename t])
                 '("Implicit-Button"
                   ["Manual"   (id-info "(hyperbole)Implicit Buttons") t]
@@ -426,7 +427,7 @@ REBUILD-FLAG is non-nil, in which case the menu is rebuilt."
                   ["Edit"   hui:ibut-edit t]
                   ["Help"   hui:hbut-help t]
                   ["Link"   hui:ibut-link-directly t]
-                  ["Name"  hui:ibut-label-create t]
+                  ["Name"   hui:ibut-label-create t]
                   ["Rename" hui:ibut-rename t]
                   ["Types"  (hui:htype-help 'ibtypes 'no-sort) t])
                 '("Koutliner"
diff --git a/hui-mini.el b/hui-mini.el
index 3c6b716ac5..2b06bbba25 100644
--- a/hui-mini.el
+++ b/hui-mini.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    15-Oct-91 at 20:13:17
-;; Last-Mod:     19-Jun-23 at 13:26:26 by Bob Weiner
+;; Last-Mod:      1-Jul-23 at 10:57:39 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -812,6 +812,7 @@ The menu is a menu of commands from MENU-ALIST."
          ("Help"   gbut:help       "Report on a global button by name.")
          ("Info"   (id-info        "(hyperbole)Global Buttons")
           "Display manual section on global buttons.")
+         ("Link"   hui:gbut-link-directly "Add a named global button link to 
point in other/another window.")
          ("Rename" hui:gbut-rename "Rename a global button.")))
        '(ibut .
         (("IButton>")
diff --git a/hui-mouse.el b/hui-mouse.el
index cf7aad628d..bfbb56740f 100644
--- a/hui-mouse.el
+++ b/hui-mouse.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    04-Feb-89
-;; Last-Mod:     25-Jun-23 at 16:36:39 by Mats Lidell
+;; Last-Mod:      4-Jul-23 at 19:51:04 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -208,10 +208,6 @@ Its default value is `smart-scroll-down'.  To disable it, 
set it to
            (smart-org)))
      . ((smart-org) . (smart-org)))
     ;;
-    ;; Ivy minibuffer completion mode
-    ((and (boundp 'ivy-mode) ivy-mode (minibuffer-window-active-p 
(selected-window)))
-     . ((ivy-done) . (ivy-dispatching-done)))
-    ;;
     ;; Treemacs hierarchical file manager
     ((eq major-mode 'treemacs-mode)
      . ((smart-treemacs) . (smart-treemacs)))
@@ -225,10 +221,15 @@ Its default value is `smart-scroll-down'.  To disable it, 
set it to
      . ((smart-push-button nil (mouse-event-p last-command-event))
        . (smart-push-button-help nil (mouse-event-p last-command-event))))
     ;;
-    ;; If click in the minibuffer and reading an argument,
-    ;; accept argument or give completion help.
-    ((and (> (minibuffer-depth) 0)
+    ;; If click in the minibuffer and reading an argument (aside from
+    ;; with vertico or ivy), accept argument or give completion help.
+    ((and hargs:reading-type
+         (> (minibuffer-depth) 0)
          (eq (selected-window) (minibuffer-window))
+         (not (bound-and-true-p ivy-mode))
+         (not (and (bound-and-true-p vertico-mode)
+                   ;; Ensure vertico is prompting for an argument
+                   (vertico--command-p nil (current-buffer))))
          (not (eq hargs:reading-type 'hmenu))
          (not (smart-helm-alive-p)))
      . ((funcall (key-binding (kbd "RET"))) . (smart-completion-help)))
@@ -236,8 +237,7 @@ Its default value is `smart-scroll-down'.  To disable it, 
set it to
     ;; If reading a Hyperbole menu item or a Hyperbole completion-based
     ;; argument, allow selection of an item at point.
     ((and (> (minibuffer-depth) 0) (setq hkey-value (hargs:at-p)))
-     . ((hargs:select-p hkey-value)
-       . (hargs:select-p hkey-value 'assist)))
+     . ((hargs:select-p hkey-value) . (hargs:select-p hkey-value 'assist)))
     ;;
     ;; If reading a Hyperbole menu item and nothing is selected, just return.
     ;; Or if in a helm session with point in the minibuffer, quit the
@@ -574,8 +574,8 @@ smart keyboard keys.")
 
 (defun smart-completion-help ()
   "Offer completion help for current minibuffer argument, if any."
-  (if (where-is-internal 'minibuffer-completion-help (current-local-map))
-      (minibuffer-completion-help)))
+  (when (where-is-internal 'minibuffer-completion-help (current-local-map))
+    (minibuffer-completion-help)))
 
 ;;; ************************************************************************
 ;;; smart-buffer-menu functions
diff --git a/hui.el b/hui.el
index cf2244135d..9f33680846 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:     30-Jun-23 at 22:50:57 by Mats Lidell
+;; Last-Mod:      8-Jul-23 at 16:04:59 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -389,9 +389,10 @@ Signal an error when no such button is found in the 
current buffer."
              (hargs:read
               "Change button label to: "
               (lambda (lbl)
-                (and (not (string-equal lbl "")) (<= (length lbl) 
(hbut:max-len))))
+                (and (not (string-match-p "\\`\\s-*\\'" lbl))
+                     (<= (length lbl) (hbut:max-len))))
               lbl
-              (format "(ebut-edit): Enter a string of at most %s chars."
+              (format "(ebut-edit): Enter a non-blank string of at most %s 
chars."
                       (hbut:max-len))
               'string))
 
@@ -505,16 +506,22 @@ a menu to find any of the occurrences."
        total))))
 
 (defun hui:gbut-create (lbl ibut-flag)
-  "Create a Hyperbole global explicit button with LBL.
-
-With prefix arg IBUT-FLAG non-nil, create a global implicit button instead.
-See `hui:gibut-create' for details."
-  (interactive (list (unless current-prefix-arg
-                       (read-string "Create global explicit button labeled: "))
-                     current-prefix-arg))
-  (if ibut-flag
-      (call-interactively #'hui:gibut-create)
-    (hypb:assert-same-start-and-end-buffer
+  "Create a Hyperbole global button with LBL.
+By default, create an explicit button.
+
+With prefix arg IBUT-FLAG non-nil, create a global implicit
+button with LBL as its name instead.  See `hui:gibut-create' for
+details."
+  (interactive (list nil current-prefix-arg))
+  (unless lbl
+    (setq lbl (hui:hbut-label nil "gbut-create"
+                             (if current-prefix-arg
+                                 "Create global implicit button named: "
+                               "Create global explicit button labeled: "))))
+  (hypb:assert-same-start-and-end-buffer
+    (if ibut-flag
+       (hui:gibut-create lbl (hui:hbut-label nil "gbut-create"
+                                             "Implicit button text (with any 
delimiters): "))
       (let (actype
             but-buf
             src-dir)
@@ -548,10 +555,10 @@ See `hui:gibut-create' for details."
 
 (defun hui:gbut-delete (but-key)
   "Delete global Hyperbole button given by BUT-KEY.
-Return t if button is deleted, nil if user chooses not to delete or signal
-an error otherwise.  If called interactively, prompt user whether to delete
-and derive BUT-KEY from the button that point is within.
-Signal an error if point is not within a button."
+         Return t if button is deleted, nil if user chooses not to delete or 
signal
+         an error otherwise.  If called interactively, prompt user whether to 
delete
+         and derive BUT-KEY from the button that point is within.
+         Signal an error if point is not within a button."
   (interactive (list (save-excursion
                       (hui:buf-writable-err
                        (find-file-noselect (gbut:file)) "gbut-delete")
@@ -563,9 +570,9 @@ Signal an error if point is not within a button."
 
 (defun hui:gbut-edit (lbl-key)
   "Edit a global Hyperbole button given by LBL-KEY.
-The button may be explicit or a labeled implicit button.
-When called interactively, save the global button buffer after the
-modification   Signal an error when no such button is found."
+         The button may be explicit or a labeled implicit button.
+         When called interactively, save the global button buffer after the
+         modification   Signal an error when no such button is found."
   (interactive (list (save-excursion
                       (hui:buf-writable-err
                        (find-file-noselect (gbut:file)) "gbut-edit")
@@ -597,9 +604,10 @@ modification   Signal an error when no such button is 
found."
              (hargs:read
               "Change global button label to: "
               (lambda (lbl)
-                (and (not (string-equal lbl "")) (<= (length lbl) 
(hbut:max-len))))
+                (and (not (string-match-p "\\`\\s-*\\'" lbl))
+                     (<= (length lbl) (hbut:max-len))))
               lbl
-              (format "(gbut-edit): Enter a string of at most %s chars."
+              (format "(gbut-edit): Enter a non-blank string of at most %s 
chars."
                       (hbut:max-len))
               'string))
 
@@ -650,9 +658,40 @@ modification   Signal an error when no such button is 
found."
                           new-lbl
                           ibut:label-end))))))))))
 
+(defun hui:gbut-link-directly (&optional arg)
+  "Prompt for a new global link button name and add it.
+Open a blank line at the end of the global/personal button file
+and insert a new global button.  By default, add an explicit
+button.  With optional prefix ARG non-nil, insert a named
+implicit button.  See also documentation for
+`hui:link-possible-types'."
+  (interactive "P")
+  (save-window-excursion
+    (when (or (= (count-windows) 1)
+             (= (hypb:count-visible-windows) 1))
+      (split-window-vertically))
+    (find-file (gbut:file))
+    (hui:buf-writable-err (current-buffer) "gbut-link-directly")
+    (multiple-value-bind (link-but-window referent-window)
+       (hmouse-choose-link-and-referent-windows)
+      (goto-char (point-max))
+      (beginning-of-line)
+      (unless (looking-at-p "[ \t]*$")
+       (end-of-line)
+       (newline))
+      (let ((standard-output (current-buffer))
+           edit-flag)
+       (if arg
+           (progn (setq edit-flag (hui:ibut-link-directly link-but-window 
referent-window t))
+                  (when (called-interactively-p 'interactive)
+                    (hui:ibut-message edit-flag)))
+         (setq edit-flag (hui:ebut-link-directly link-but-window 
referent-window))
+         (when (called-interactively-p 'interactive)
+           (hui:ebut-message edit-flag)))))))
+
 (defun hui:gbut-rename (label)
   "Interactively rename a Hyperbole global button with LABEL.
-When in the global button buffer, the default is the button at point."
+         When in the global button buffer, the default is the button at point."
   (interactive (list (save-excursion
                       (hui:buf-writable-err
                        (find-file-noselect (gbut:file)) "gbut-rename")
@@ -692,7 +731,7 @@ Use `hui:gbut-create' to create a global explicit button."
 
 (defun hui:hbut-act (&optional but)
   "Execute action for optional Hyperbole button symbol BUT in current buffer.
-The default is the current button."
+         The default is the current button."
   (interactive (list (hbut:get (hargs:read-match "Activate labeled Hyperbole 
button: "
                                                 (nconc (ebut:alist) 
(ibut:alist))
                                                 nil t nil 'hbut))))
@@ -730,7 +769,7 @@ The default is the current button."
     (cond ((null but)
           (hypb:error "(hbut-act): No current button to activate"))
          ((not (hbut:is-p but))
-          (hypb:error "(hbut-act): Button is invalid; it has no attributes"))
+          (hypb:error "(hbut-act): Button is invalid ; it has no attributes"))
          (t (hui:but-flash) (hbut:act but)))))
 
 (defun hui:hbut-delete (&optional but-key key-src)
@@ -819,9 +858,10 @@ BUT defaults to the button whose label point is within."
 Optional PROMPT string replaces the standard prompt of `Button label: '."
   (hargs:read (if (stringp prompt) prompt "Button label: ")
              (lambda (lbl)
-               (and (not (string-equal lbl "")) (<= (length lbl) 
(hbut:max-len))))
+               (and (not (string-match-p "\\`\\s-*\\'" lbl))
+                    (<= (length lbl) (hbut:max-len))))
              default-label
-             (format "(%s): Enter a string of at most %s chars."
+             (format "(%s): Enter a non-blank string of at most %s chars."
                      func-name (hbut:max-len))
              'string))
 
@@ -880,24 +920,36 @@ Default is any implicit button at point."
 
 (defun hui:ibut-create (&optional start end)
   "Interactively create an implicit Hyperbole button at point.
-Use any label between optional START and END (when interactive,
-active) region points.  Indicate button creation by delimiting
+Use any label between optional START and END points (when interactive,
+any active region).  Indicate button creation by delimiting
 and adding any necessary instance number to the button label.
 
 For programmatic creation, use `ibut:program' instead."
   (interactive (list (when (use-region-p) (region-beginning))
                     (when (use-region-p) (region-end))))
   (hypb:assert-same-start-and-end-buffer
-    (let ((default-name) name but-buf actype)
+    (let (default-name name but-buf actype)
+      (setq but-buf (current-buffer))
+      (hui:buf-writable-err but-buf "ibut-create")
+      (hattr:clear 'hbut:current)
+
+      ;; Throw an error if on a named or delimited Hyperbole button since
+      ;; cannot create another button within such contexts.
+      (when (hbut:at-p)
+       (let ((name (hattr:get 'hbut:current 'name))
+             (lbl (hbut:key-to-label (hattr:get 'hbut:current 'lbl-key)))
+             (lbl-start (hattr:get 'hbut:current 'lbl-start))
+             (lbl-end (hattr:get 'hbut:current 'lbl-end)))
+         (when (or name lbl (and lbl-start lbl-end))
+           (error "(ibut-create): Cannot nest an ibut within the existing 
button: '%s'"
+                  (or name lbl (buffer-substring-no-properties lbl-start 
lbl-end))))))
+
       (save-excursion
        (setq default-name (hui:hbut-label-default start end (not 
(called-interactively-p 'interactive)))
              name (hui:hbut-label default-name "ibut-create"))
        (unless (equal name default-name)
          (setq default-name nil))
 
-       (setq but-buf (current-buffer))
-       (hui:buf-writable-err but-buf "ibut-create")
-
        (hattr:set 'hbut:current 'name name)
        (hattr:set 'hbut:current 'categ 'implicit)
        (hattr:set 'hbut:current 'loc (hui:key-src but-buf))
@@ -1055,6 +1107,9 @@ Signal an error when no such button is found in the 
current buffer."
 
 (defun hui:ebut-link-directly (&optional depress-window release-window)
   "Create a link ebutton at Action Key depress point, linked to release point.
+If an explicit button already exists at point, replace it with the new
+link button and return t; otherwise, return nil.
+
 With optional DEPRESS-WINDOW and RELEASE-WINDOW, use the points
 from those instead.  See also documentation for
 `hui:link-possible-types'."
@@ -1066,7 +1121,12 @@ from those instead.  See also documentation for
                 (assist-key-clear-variables)
                 (hmouse-choose-link-and-referent-windows)))
 
-  (let (but-name edit-flag link-types num-types type-and-args lbl-key but-loc 
but-dir)
+  (unless (called-interactively-p 'any)
+    ;; Clear smart key variables so this does not improperly reference
+    ;; values left over from a prior drag or click.
+    (action-key-clear-variables)
+    (assist-key-clear-variables))
+  (let (but-lbl edit-flag link-types num-types type-and-args lbl-key but-loc 
but-dir)
     (multiple-value-bind (link-but-window referent-window)
        (if (and depress-window release-window)
            (list depress-window release-window)
@@ -1080,30 +1140,31 @@ from those instead.  See also documentation for
                 (not (eq (current-buffer) action-key-depress-buffer))
                 (buffer-live-p action-key-depress-buffer))
        (switch-to-buffer action-key-depress-buffer))
-      (hui:buf-writable-err (current-buffer) "link-directly")
+      (hui:buf-writable-err (current-buffer) "ebut-link-directly")
       (if (ebut:at-p)
          (setq edit-flag t
                but-loc (hattr:get 'hbut:current 'loc)
                but-dir (hattr:get 'hbut:current 'dir)
                lbl-key (hattr:get 'hbut:current 'lbl-key))
        (setq but-loc (hui:key-src (current-buffer))
-             but-dir (hui:key-dir (current-buffer))
-             but-name (hui:hbut-label
-                       (cond ((hmouse-prior-active-region)
-                              hkey-region)
-                             ((use-region-p)
-                              (hui:hbut-label-default
-                               (region-beginning) (region-end))))
-                       "link-directly"
-                       "Create button named: ")
-             lbl-key (hbut:label-to-key but-name)))
+             but-dir (hui:key-dir (current-buffer)))
+       (unless lbl-key
+         (setq but-lbl (hui:hbut-label
+                        (cond ((hmouse-prior-active-region)
+                               hkey-region)
+                              ((use-region-p)
+                               (hui:hbut-label-default
+                                (region-beginning) (region-end))))
+                        "ebut-link-directly"
+                        "Create button named: ")
+               lbl-key (hbut:label-to-key but-lbl))))
       (select-window referent-window)
       (setq link-types (hui:link-possible-types)
            num-types (length link-types))
 
       ;; num-types is the number of possible link types to choose among
       (cond ((= num-types 0)
-            (error "(link-directly): No possible link type to create"))
+            (error "(ebut-link-directly): No possible link type to create"))
            ((= num-types 1)
             (setq type-and-args (hui:list-remove-text-properties (car 
link-types)))
             (hui:ebut-link-create edit-flag link-but-window lbl-key but-loc 
but-dir type-and-args))
@@ -1134,11 +1195,13 @@ from those instead.  See also documentation for
       (with-selected-window referent-window
        (hmouse-pulse-line))
       (when (called-interactively-p 'interactive)
-       (hui:ebut-message edit-flag)))))
+       (hui:ebut-message edit-flag))
+      edit-flag)))
 
 (defun hui:ibut-link-directly (&optional depress-window release-window 
name-arg-flag)
   "Create a link ibutton at Assist Key depress point, linked to release point.
-If ibutton exists at point, replace it with the new link button.
+If an ibutton already exists at point, replace it with the new
+link button and return t; otherwise, return nil.
 
 With optional DEPRESS-WINDOW and RELEASE-WINDOW, use the points
 from those instead.  See also documentation for
@@ -1159,6 +1222,11 @@ drag from a window to another window's modeline."
                 (append (hmouse-choose-link-and-referent-windows)
                         current-prefix-arg)))
 
+  (unless (called-interactively-p 'any)
+    ;; Clear smart key variables so this does not improperly reference
+    ;; values left over from a prior drag or click.
+    (action-key-clear-variables)
+    (assist-key-clear-variables))
   (let (but-name edit-flag link-types num-types type-and-args name-key but-loc 
but-dir)
     ;; edit-flag when set non-nil means are editing an existing ibut at point
     (multiple-value-bind (link-but-window referent-window)
@@ -1174,35 +1242,31 @@ drag from a window to another window's modeline."
                 (not (eq (current-buffer) assist-key-depress-buffer))
                 (buffer-live-p assist-key-depress-buffer))
        (switch-to-buffer assist-key-depress-buffer))
-      (hui:buf-writable-err (current-buffer) "link-directly")
+      (hui:buf-writable-err (current-buffer) "ibut-link-directly")
       (if (ibut:at-p)
          (setq edit-flag t
                but-loc (hattr:get 'hbut:current 'loc)
                but-dir (hattr:get 'hbut:current 'dir)
                name-key (ibut:label-to-key (hattr:get 'hbut:current 'name)))
        (setq but-loc (hui:key-src (current-buffer))
-             but-dir (hui:key-dir (current-buffer))
-             ;; Don't prompt to name implicit button
-             ;; but-name (hui:hbut-label
-             ;;              (cond ((hmouse-prior-active-region)
-             ;;                     hkey-region)
-             ;;                    ((use-region-p)
-             ;;                     (hui:hbut-label-default
-             ;;                      (region-beginning) (region-end))))
-             ;;              "link-directly"
-             ;;              "Create button named: ")
-             ;; name-key (hbut:label-to-key but-name)
-             ))
-      (when name-arg-flag
-       (setq name-key (ibut:label-to-key (hui:hbut-label nil 
"hui:ibut-link-directly"
-                                                         "Name for implicit 
button: "))))
+             but-dir (hui:key-dir (current-buffer))))
+      (when (and name-arg-flag (not name-key))
+       (setq but-name (hui:hbut-label
+                       (cond ((hmouse-prior-active-region)
+                              hkey-region)
+                             ((use-region-p)
+                              (hui:hbut-label-default
+                               (region-beginning) (region-end))))
+                       "ibut-link-directly"
+                       "Name for implicit button: ")
+             name-key (hbut:label-to-key but-name)))
       (select-window referent-window)
       (setq link-types (hui:link-possible-types)
            num-types (length link-types))
 
       ;; num-types is the number of possible link types to choose among
       (cond ((= num-types 0)
-            (error "(link-directly): No possible link type to create"))
+            (error "(ibut-link-directly): No possible link type to create"))
            ((= num-types 1)
             (setq type-and-args (hui:list-remove-text-properties (car 
link-types)))
             (hui:ibut-link-create edit-flag link-but-window name-key but-loc 
but-dir type-and-args))
@@ -1232,7 +1296,8 @@ drag from a window to another window's modeline."
       (with-selected-window referent-window
        (hmouse-pulse-line))
       (when (called-interactively-p 'interactive)
-       (hui:ibut-message edit-flag)))))
+       (hui:ibut-message edit-flag))
+      edit-flag)))
 
 
 ;;; ************************************************************************
@@ -1248,10 +1313,8 @@ drag from a window to another window's modeline."
              (params-str (and params (concat " " (prin1-to-string params)))))
         (while (progn
                  (while (and (setq act-str
-                                   (hargs:read
-                                    (or prompt (concat "Action" params-str
-                                                       ": ")) nil nil
-                                    nil 'string))
+                                   (hargs:read (or prompt (concat "Action" 
params-str ": "))
+                                               nil nil nil 'string))
                              (not (string-equal act-str ""))
                              (condition-case ()
                                  (progn (setq act (read act-str)) nil)
@@ -1271,7 +1334,7 @@ drag from a window to another window's modeline."
                                     (and (string-match
                                           (concat "[\( \t\n\r,']"
                                                   (regexp-quote param)
-                                                  "[\(\) \t\n\r\"]")
+                                                  "[() \t\n\r\"]")
                                           act-str)
                                          t))
                                   params-no-keywords)))))
@@ -1653,6 +1716,9 @@ which to create button.  BUT-DIR is the directory of 
BUT-LOC.
 TYPE-AND-ARGS is the action type for the button followed by any
 arguments it requires.  Any text properties are removed from
 string arguments."
+  ;; Don't set 'name attribute here since this may be a rename where
+  ;; we need to use the existing name attribute before renaming to
+  ;; label version of `name-key'.
   (hattr:set 'hbut:current 'categ 'implicit)
   (hattr:set 'hbut:current 'loc but-loc)
   (hattr:set 'hbut:current 'dir but-dir)
@@ -1729,28 +1795,27 @@ Buffer without File      link-to-buffer-tmp"
                               ((and (require 'bookmark)
                                     (derived-mode-p 'bookmark-bmenu-mode)
                                     (list 'link-to-bookmark 
(bookmark-bmenu-bookmark))))
-                              ((cond ((derived-mode-p 'Info-mode)
-                                      (if (and Info-current-node
-                                               (member Info-current-node
-                                                       (Info-index-nodes 
Info-current-file))
-                                               (Info-menu-item-at-p))
-                                          (let ((hargs:reading-type 
'Info-index-item))
-                                            (list 'link-to-Info-index-item 
(hargs:at-p)))
-                                        (let ((hargs:reading-type 'Info-node))
-                                          (list 'link-to-Info-node 
(hargs:at-p)))))
-                                     ((derived-mode-p #'texinfo-mode)
-                                      (let (node)
-                                        (save-excursion
-                                          (beginning-of-line)
-                                          (when (and (not (looking-at "@node 
"))
-                                                     (not (re-search-backward 
"^@node " nil t)))
-                                            (hypb:error 
"(hui:link-possible-types): Not within a texinfo node"))
-                                          (require 'texnfo-upd)
-                                          (setq node (texinfo-copy-node-name)))
-                                        (list 'link-to-texinfo-node 
buffer-file-name node)))
-                                     ((hmail:reader-p)
-                                      (list 'link-to-mail
-                                            (list (rmail:msg-id-get) 
buffer-file-name)))))
+                              ((let (node)
+                                 (cond ((derived-mode-p 'Info-mode)
+                                        (if (and Info-current-node
+                                                 (member Info-current-node
+                                                         (Info-index-nodes 
Info-current-file))
+                                                 (Info-menu-item-at-p))
+                                            (let ((hargs:reading-type 
'Info-index-item))
+                                              (list 'link-to-Info-index-item 
(hargs:at-p)))
+                                          (let ((hargs:reading-type 
'Info-node))
+                                            (list 'link-to-Info-node 
(hargs:at-p)))))
+                                       ((and (derived-mode-p #'texinfo-mode)
+                                             (save-excursion
+                                               (beginning-of-line)
+                                               (or (looking-at "@node ")
+                                                   (re-search-backward "^@node 
" nil t))))
+                                        (require 'texnfo-upd)
+                                        (setq node (texinfo-copy-node-name))
+                                        (list 'link-to-texinfo-node 
buffer-file-name node))
+                                       ((hmail:reader-p)
+                                        (list 'link-to-mail
+                                              (list (rmail:msg-id-get) 
buffer-file-name))))))
                               (t (cond
                                   ((let ((hargs:reading-type 'directory))
                                      (setq val (hargs:at-p t)))
diff --git a/hypb.el b/hypb.el
index b1050e7eda..e617a0b0c3 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:     25-Jun-23 at 10:11:57 by Mats Lidell
+;; Last-Mod:      1-Jul-23 at 10:15:54 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -167,7 +167,7 @@ Raise and reuse any existing single window frame displaying 
ilog."
   (ilog-show-in-other-frame))
 
 (defmacro hypb:assert-same-start-and-end-buffer (&rest body)
-  "Assert that buffers name does not change during execution of BODY.
+  "Assert that current buffer does not change following execution of BODY.
 Trigger an error with traceback if the buffer is not live or its
 name differs at the start and end of BODY."
   (declare (indent 0) (debug t))
diff --git a/hyperbole.el b/hyperbole.el
index 7cdb137436..34a65d6143 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -7,7 +7,7 @@
 ;; Author:       Bob Weiner
 ;; Maintainer:   Bob Weiner <rsw@gnu.org>, Mats Lidell <matsl@gnu.org>
 ;; Created:      06-Oct-92 at 11:52:51
-;; Last-Mod:      1-Jul-23 at 23:42:43 by Mats Lidell
+;; Last-Mod:      8-Jul-23 at 16:00:21 by Bob Weiner
 ;; Released:     03-Dec-22
 ;; Version:      8.0.1pre
 ;; Keywords:     comm, convenience, files, frames, hypermedia, languages, 
mail, matching, mouse, multimedia, outlines, tools, wp
@@ -196,6 +196,7 @@ Assist Key will do."
 `hkey-initialize' must have already been called or the list will be empty."
   hyperbole-mode-map)
 
+;; Use `hkey-set-key' instead.
 (make-obsolete 'hkey-global-set-key 'hkey-set-key "8.0.0")
 (defun hkey-global-set-key (key command &optional _no-add)
   "Define a Hyperbole KEY bound to COMMAND.  Optional third arg, NO-ADD is 
ignored."
@@ -481,6 +482,12 @@ frame, those functions by default still return the prior 
frame."
                                'buttons
                              t)))
   ;;
+  ;; When vertico-mode is used, vertico-mouse-mode is needed for the
+  ;; Action Key to properly select completions from the candidate list.
+  (if (bound-and-true-p vertico-mode)
+      (vertico-mouse-mode 1)
+    (add-hook 'vertico-mode-hook (lambda () (vertico-mouse-mode 1))))
+  ;;
   ;; Hyperbole initialization is complete.
   (message "Initializing Hyperbole...done"))
 
diff --git a/man/hkey-help.txt b/man/hkey-help.txt
index f32ae91bed..bac0b5aef9 100644
--- a/man/hkey-help.txt
+++ b/man/hkey-help.txt
@@ -8,7 +8,8 @@ Hyperbole
   Reading argument
     1st press at an arg value   Copies value to minibuffer <- same
     2nd press at an arg value   Uses value as argument     <- same
-    In minibuffer               Accepts minibuffer arg     Completion help
+    In minibuffer at eol        Accepts minibuffer arg     List completions
+    In minibuffer before eol    Deletes rest of arg        Deletes rest of arg
   On an implicit button/path    Activates button           Button help
   Within a koutline cell        Collapses and expands      Shows tree props
   Left of a koutline cell       Creates a klink            Moves a tree
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index ef5b30b5b8..2ffa6fbe3a 100644
--- a/man/hyperbole.texi
+++ b/man/hyperbole.texi
@@ -7,7 +7,7 @@
 @c Author:       Bob Weiner
 @c
 @c Orig-Date:     6-Nov-91 at 11:18:03
-@c Last-Mod:     22-Jun-23 at 17:39:17 by Bob Weiner
+@c Last-Mod:      8-Jul-23 at 10:31:40 by Bob Weiner
 
 @c %**start of header (This is for running Texinfo on a region.)
 @setfilename hyperbole.info
@@ -156,7 +156,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</P>
 
 <PRE>
 Edition 8.0.1pre
-Printed June 22, 2023.
+Printed July 8, 2023.
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -198,7 +198,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 @example
 Edition 8.0.1pre
-June 22, 2023
+July 8, 2023
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -1223,24 +1223,45 @@ Hyperbole user interface has an extensive core of 
argument types that
 it recognizes.  Whenever Hyperbole is prompting you for an argument,
 it knows the type that it needs and provides some error checking to
 help you get it right.  More importantly, it allows you to press the
-Action Key within an entity that you want to use as an argument and it
-will grab the appropriate thing and show it to you at the input prompt
-within the minibuffer.  If you press (click with a mouse) the Action
-Key on the same thing again, it accepts the entity as the argument
-and moves on.  Thus, a double click registers a desired argument.
-Double-quoted strings, pathnames, mail messages, Info nodes, dired
-listings, buffers, numbers, completion items and so forth are all
-recognized at appropriate times.  All of the argument types mentioned
-in the documentation for the Emacs Lisp @code{interactive} function
-are recognized.  Experiment a little and you will quickly get used to
-this direct selection technique.
+Action Key within an entity that you want to use as an argument.
+Hyperbole will copy the appropriate thing to the minibuffer as the
+argument.  If you press (click with a mouse) the Action Key on the
+same thing again, e.g. within a list of possible completions,
+Hyperbole exits the minibuffer and uses the current argument.  Thus, a
+double click registers a desired argument.  Double-quoted strings,
+pathnames, mail messages, Info nodes, dired listings, buffers,
+numbers, completion items and so forth are all recognized at
+appropriate times.  All of the argument types mentioned in the
+documentation for the Emacs Lisp @code{interactive} function are
+recognized.  Experiment a little and you will quickly get used to this
+direct selection technique.
 
 @cindex completion
-Wherever possible, standard Emacs completion is offered, as described in
-@ref{Completion,,,emacs,the GNU Emacs Manual}.  Remember to use @bkbd{?}
-to see what your possibilities for an argument are.  Once you have a
-list of possible completions on screen, press the Action Key twice on
-any item to enter it as the argument.
+@cindex Vertico completion
+Wherever possible, standard Emacs completion is offered, as described
+in @ref{Completion,,,emacs,the GNU Emacs Manual}.  Remember to use
+@bkbd{?}  to see what your possibilities for an argument are if
+completions are not automatically shown to you.  Once you have a list
+of possible completions on screen, press the Action Key twice on any
+item to enter it as the argument.  If you are using the Vertico
+completion library with completions displayed in the minibuffer,
+selection of completions works the same as if they were displayed in a
+separate buffer as in standard Emacs.
+
+@cindex minibuffer completion
+@cindex minibuffer arguments
+@cindex Smart Keys in minibuffer
+@cindex Action Key in minibuffer
+@cindex Assist Key in minibuffer
+Within the minibuffer itself, the Smart Keys are also
+context-sensitive.  A press of the Action Key at the end of the
+argument line tries to accept the argument and when successful, exits
+the minibuffer.  A press of the Assist Key at the end of the argument
+line displays matching completions for times when they are not
+automatically displayed or need updating.  A press of the Action or
+Assist Key on part of the argument, deletes from point to the end of
+the line, expanding the set of available completions and redisplaying
+them.
 
 @node Smart Key Debugging, Smart Key Thing Selection, Smart Key Argument 
Selection, Smart Keys
 @section   Smart Key Debugging
@@ -2001,7 +2022,7 @@ asking for help on a button.
 Sometimes it is useful to activate buttons without regard to the
 information with which you are working.  In such instances, you use
 @dfn{global buttons}, which are buttons that may be activated or
-otherwise operated upon by typing their labels/names when they are
+otherwise operated upon by typing their names/labels when they are
 prompted for, rather than selecting the buttons within a buffer.  In
 contrast, activation of explicit buttons depends upon the information on
 your screen since they are accessible only from within their particular
@@ -2026,6 +2047,30 @@ you for its action type and associated arguments.  
@bkbd{C-h h g e} to
 edit an existing global button.  To remove a button, use the Delete menu
 item, @bkbd{C-h h g d}; @pxref{Deletion}.
 
+@cindex global link creation
+@cindex creating global links
+@cindex menu item, Gbut/Link
+@kindex C-h h g l
+To create a global button that links to point in one of your Emacs
+windows, use the Link menu item, @bkbd{C-h h g l}.
+
+By default this will create a global explicit link button.  Give it a
+prefix argument to create a global implicit link button.
+
+With a single window visible on-screen or a single window within your
+current frame, this will prompt you for a button name or label
+(temporarily showing you your global/personal button file) and then
+will insert a button that links to the current point within that window.
+
+If you have exactly two Emacs windows in your current frame or exactly
+two windows visible across two Emacs frames, then the link referent will
+be to the point in the other, non-selected window.
+
+With more than two windows on screen, Hyperbole will prompt you to choose
+the referent window and its associated point to which to link.  If the
+Ace Window package is installed and active, this will be used to choose
+the window; otherwise, you will be prompted to select it by mouse.
+
 Global buttons are actually explicit buttons stored at the end of your
 personal button file, @pxref{Button Files}.  You can always go into that
 file and activate, edit or annotate these buttons with comments.
@@ -7405,16 +7450,17 @@ frame is visible at a time as each frame generally 
fills the whole
 terminal display, providing a virtual screen capability.  Emacs
 windows exist within a frame.
 
-@vindex gbut:file
+@findex gbut:file
 @item Global Button
 A Hyperbole button which is accessed by name rather than direct
 selection.  Global buttons are useful when one wants quick access to
 actions such as jumping to common file locations or for performing
 sequences of operations.  One need not locate them since they are
 always available by name, with full completion offered.  All global
-buttons are stored in the file given by the variable @code{gbut:file}
-and may be activated with the Action Key when editing this file.  By
-default, this is the same as the user's personal button file.
+buttons are stored in the file returned by the function call,
+@code{(gbut:file)}, and may be activated with the Action Key when
+editing this file.  By default, this is the same as the user's
+personal button file.
 
 @item Glink
 @itemx link-to-gbut
diff --git a/man/version.texi b/man/version.texi
index 83a9274080..b2e483a613 100644
--- a/man/version.texi
+++ b/man/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED June, 2023
-@set UPDATED-MONTH June 2023
+@set UPDATED July, 2023
+@set UPDATED-MONTH July 2023
 @set EDITION 8.0.1pre
 @set VERSION 8.0.1pre
diff --git a/test/demo-tests.el b/test/demo-tests.el
index 1431c44c1d..7278704098 100644
--- a/test/demo-tests.el
+++ b/test/demo-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <matsl@gnu.org>
 ;;
 ;; Orig-Date:    30-Jan-21 at 12:00:00
-;; Last-Mod:     22-Jun-23 at 20:35:55 by Mats Lidell
+;; Last-Mod:      8-Jul-23 at 14:16:51 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -231,12 +231,12 @@
                   (string-match-p "hactypes\\.el"  hactypes-buf)
                   (string-match-p "hibtypes\\.el"  hibtypes-buf))))))
 
-(ert-deftest demo-implicit-button-action-button-boolean-function-call-test ()
+(ert-deftest demo-implicit-button-action-button-display-boolean-test ()
   (with-temp-buffer
     (insert "<string-empty-p \"False\">")
     (goto-char 2)
     (action-key)
-    (hy-test-helpers:should-last-message "Boolean result (False) = nil")))
+    (hy-test-helpers:should-last-message "Result = nil; Boolean value = 
False")))
 
 (ert-deftest demo-implicit-button-action-button-variable-display-test ()
   (with-temp-buffer
diff --git a/test/hactypes-tests.el b/test/hactypes-tests.el
index e23980e11c..39a1ea098d 100644
--- a/test/hactypes-tests.el
+++ b/test/hactypes-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <matsl@gnu.org>
 ;;
 ;; Orig-Date:    30-Jan-21 at 12:00:00
-;; Last-Mod:      6-Feb-22 at 00:56:35 by Bob Weiner
+;; Last-Mod:      8-Jul-23 at 14:11:49 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -26,11 +26,11 @@
 
 (ert-deftest display-boolean-true-test ()
   (should (actypes::display-boolean t))
-  (hy-test-helpers:should-last-message "Boolean result (True) = t"))
+  (hy-test-helpers:should-last-message "Result = t; Boolean value = True"))
 
 (ert-deftest display-boolean-false-test ()
   (should (actypes::display-boolean nil))
-    (hy-test-helpers:should-last-message "Boolean result (False) = nil"))
+    (hy-test-helpers:should-last-message "Result = nil; Boolean value = 
False"))
 
 (provide 'hactypes-tests)
 ;;; hactypes-tests.el ends here
diff --git a/test/hbut-tests.el b/test/hbut-tests.el
index 0d3875a2fa..8f95038b07 100644
--- a/test/hbut-tests.el
+++ b/test/hbut-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <matsl@gnu.org>
 ;;
 ;; Orig-Date:    30-may-21 at 09:33:00
-;; Last-Mod:     17-Jun-23 at 23:02:50 by Bob Weiner
+;; Last-Mod:      5-Jul-23 at 00:29:02 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -26,10 +26,10 @@
 (require 'hy-test-helpers "test/hy-test-helpers")
 
 (defun hbut-tests:should-match-tmp-folder (tmp)
-  "Check that TMP matches either of \"/tmp\" or \"private/tmp\".
+  "Check that TMP matches either of \"/tmp\" or \"/private/tmp\".
 Needed since hyperbole expands all links to absolute paths and
 /tmp can be a symbolic link."
-  (should (member tmp '(("/tmp") ("./tmp") ("/private/tmp")))))
+  (should (and (stringp tmp) (string-match-p 
"\\`\"?\\(/\\|./\\|/private/\\)tmp\"?\\'" tmp) t)))
 
 (ert-deftest ebut-program-link-to-directory ()
   "Programatically create ebut with link-to-directory."
@@ -39,7 +39,7 @@ Needed since hyperbole expands all links to absolute paths and
           (find-file file)
           (ebut:program "label" 'link-to-directory "/tmp")
           (should (eq (hattr:get (hbut:at-p) 'actype) 
'actypes::link-to-directory))
-          (hbut-tests:should-match-tmp-folder (hattr:get (hbut:at-p) 'args))
+          (hbut-tests:should-match-tmp-folder (car (hattr:get (hbut:at-p) 
'args)))
           (should (equal (hattr:get (hbut:at-p) 'loc) file))
           (should (equal (hattr:get (hbut:at-p) 'lbl-key) "label")))
       (hy-delete-file-and-buffer file))))
@@ -99,7 +99,7 @@ Needed since hyperbole expands all links to absolute paths and
             (gbut:ebut-program "global" 'link-to-directory "/tmp"))
          (with-current-buffer test-buffer
             (should (eq (hattr:get (hbut:at-p) 'actype) 
'actypes::link-to-directory))
-            (hbut-tests:should-match-tmp-folder (hattr:get (hbut:at-p) 'args))
+            (hbut-tests:should-match-tmp-folder (car (hattr:get (hbut:at-p) 
'args)))
             (should (equal (hattr:get (hbut:at-p) 'loc) test-file))
             (should (equal (hattr:get (hbut:at-p) 'lbl-key) "global"))))
       (hy-delete-file-and-buffer test-file))))
@@ -161,7 +161,7 @@ Needed since hyperbole expands all links to absolute paths 
and
   (with-temp-buffer
     (ebut:program "label" 'link-to-directory "/tmp")
     (should (eq (hattr:get (hbut:at-p) 'actype) 'actypes::link-to-directory))
-    (hbut-tests:should-match-tmp-folder (hattr:get (hbut:at-p) 'args))
+    (hbut-tests:should-match-tmp-folder (car (hattr:get (hbut:at-p) 'args)))
     (should (equal (hattr:get (hbut:at-p) 'lbl-key) "label"))))
 
 (ert-deftest hypb:program-create-ebut-in-buffer-with-same-label ()
@@ -337,6 +337,134 @@ Needed since hyperbole expands all links to absolute 
paths and
     `(dolist (bd ,hbut-tests-actypes-list)
        (with-temp-file "hypb.txt" ,@body))))
 
+;; ibut:operate tests
+
+(ert-deftest hbut-tests--ibut-operate--none ()
+  "Create unnamed ibut.
+  
|------+----------+--------+-----------+-----------------------------------------------|
+  | name | new-name | region | edit-flag | operation                           
          |
+  
|------+----------+--------+-----------+-----------------------------------------------|
+  | nil  | nil      | nil    | nil       | create: unnamed ibut from 
hbut:current attrs  |
+  
|------+----------+--------+-----------+-----------------------------------------------|"
+  (with-temp-buffer
+    (insert "/tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (hbut-tests:should-match-tmp-folder (buffer-substring-no-properties 
(point-min) (point-max)))
+    (erase-buffer)
+    (should-not (ibut:operate))
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (hbut-tests:should-match-tmp-folder (buffer-substring-no-properties 
(point-min) (point-max)))))
+
+(ert-deftest hbut-tests--ibut-operate--aname ()
+  "Create aname ibut."
+  (with-temp-buffer
+    (insert "<[aname]> - /tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (hbut-tests:should-match-tmp-folder (buffer-substring-no-properties 
(point-min) (point-max)))
+    (erase-buffer)
+    (
+     (hattr:set 'hbut:current 'name "aname")
+     (hattr:set 'hbut:current 'name "")
+    (should-not (ibut:operate))
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (should (string= "<[aname]> - /tmp<[aname]> - \"/tmp\""
+                    (buffer-substring-no-properties (point-min) 
(point-max)))))))
+
+(ert-deftest hbut-tests--ibut-operate--aname-region-skip-region ()
+  "Create aname ibut and ignore region."
+  (with-temp-buffer
+    (insert "<[aname]> - /tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (end-of-buffer)
+    (insert "\n")
+    (set-mark (point))
+    (insert "abcd")
+    (should (region-active-p))
+    (should-not (ibut:operate))
+    ;; Inserted just before region which is kept
+    (should (string= "<[aname]> - /tmp\n<[aname]> - \"/tmp\"abcd"
+                    (buffer-substring-no-properties (point-min) 
(point-max))))))
+
+(ert-deftest hbut-tests--ibut-operate--region ()
+  "Create ibut with aname, ignore region."
+  (with-temp-buffer
+    (insert "/tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (end-of-buffer)
+    (insert "\n")
+    (set-mark (point))
+    (insert "name")
+    (should (region-active-p))
+    (should-not (ibut:operate))
+    (should (string= "/tmp\n<[name]>\"/tmp\""
+                    (buffer-substring-no-properties (point-min) 
(point-max))))))
+
+(ert-deftest hbut-tests--ibut-operate--modify-named ()
+  "Add new-name to named ibut."
+  (with-temp-buffer
+    (insert "<[name]> /tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (should-not (ibut:operate "new-name" t))
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (should (string= "<[new-name]> /tmp"
+                    (buffer-substring-no-properties (point-min) 
(point-max))))))
+
+(ert-deftest hbut-tests--ibut-operate--modify-named-skip-region ()
+  "Add new-name to named ibut and ignore region."
+  (with-temp-buffer
+    (insert "<[name]> /tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (set-mark (point-max))
+    (should (region-active-p))
+    (should-not (ibut:operate "new-name" t))
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (should (string= "<[new-name]> /tmp"
+                    (buffer-substring-no-properties (point-min) 
(point-max))))))
+
+(ert-deftest hbut-tests--ibut-operate--add-new-name ()
+  "Add new-name to unnamed ibut."
+  (with-temp-buffer
+    (insert "/tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    (should-not (ibut:operate "new-name" t))
+    ;; Missing delimiter -- Not identified as a ibut after name is inserted
+    ;; (should (hbut:at-p))
+    ;; (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    ;; delimiter
+    (should (string= "<[new-name]>/tmp"
+                    (buffer-substring-no-properties (point-min) 
(point-max))))))
+
+(ert-deftest hbut-tests--ibut-operate--add-new-name-skip-region ()
+  "Add new-name to unnamed ibut, skip active region."
+  (with-temp-buffer
+    (insert "/tmp")
+    (goto-char 2)
+    (should (hbut:at-p))
+    (set-mark (point-max))
+    (should (region-active-p))
+    (should-not (ibut:operate "new-name" t))
+    ;; Missing delimiter -- Not identified as a ibut after name is inserted
+    ;; (should (hbut:at-p))
+    ;; (should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
+    ;; Missing delimiter
+    (should (string= "<[new-name]>/tmp"
+                    ))))
+
 ;; This file can't be byte-compiled without the `el-mock' package (because of
 ;; the use of the `with-mock' macro), which is not a dependency of Hyperbole.
 ;;  Local Variables:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]