branch: externals/hyperbole
commit 7a86ea33e246c66a9e5fdcd98a219d2ec9bb87e9
Author: Bob Weiner <r...@gnu.org>
Commit: Bob Weiner <r...@gnu.org>

    Add ibut:create and allow Assist Key :help for Elisp functions
---
 ChangeLog   |  13 ++++++
 hact.el     |   8 ++--
 hbut.el     | 129 +++++++++++++++++++++++++++++++++++++-----------------------
 hibtypes.el |  55 +++++++++++++++++---------
 4 files changed, 134 insertions(+), 71 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b68deaa062..21b4c9bfe5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,8 @@
     to return search expression rather than doing the search.  Use
     with Assist Key.
 
+* hibtypes.el (action): Call ibut:create to ensure button attributes
+    are set properly.
 * test/demo-tests.el (fast-demo-key-series-shell-pushd-hyperb-dir,
                       fast-demo-key-series-shell-grep,
                       fast-demo-key-series-shell-apropos):
@@ -66,6 +68,11 @@
     (hypb:function-symbol-replace, hypb:map-sublists)
     (hypb:constant-vector-symbol-replace): Delete functions.
 
+* hbut.el (ibut:create): Add, extracted from 'ibut:at-p'; define
+    with cl-defun so can optionally use non-positional colon-prefixed
+    keyword args to specify specific args.
+
+* hmouse-drv.el (hkey-help): Set 'assist-flag' so matches Assist Key
 2022-07-12  Mats Lidell  <ma...@gnu.org>
 
 * test/hpath-tests.el (hpath:auto-variable-alist-load-path-test): Simplify
@@ -74,6 +81,12 @@
 * test/hui-tests.el (hui-gbut-edit-link-to-file-button): Remove test file
     after test case is completed.
 
+2022-07-11  Bob Weiner  <r...@gnu.org>
+
+* hibtypes.el (action:help): Allow for action button assist key :help
+    functions, even if the action button type is not a Hyperbole type,
+    i.e. a regular function.
+
 2022-07-11  Mats Lidell  <ma...@gnu.org>
 
 * test/hy-test-helpers.el (hy-test-helpers:should-last-message): Use
diff --git a/hact.el b/hact.el
index edc16f2798..131bf9c22f 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:     30-May-22 at 13:55:46 by Bob Weiner
+;; Last-Mod:     17-Jul-22 at 12:58:33 by Bob Weiner
 ;;
 ;; Copyright (C) 1991-2021  Free Software Foundation, Inc.
 ;; See the "HY-COPY" file for license information.
@@ -264,8 +264,10 @@ When optional SYM is given, returns the name for that 
symbol only, if any."
 ;;; ------------------------------------------------------------------------
 
 (defun   htype:symbol (type type-category)
-  "Return possibly new Hyperbole type symbol composed from TYPE and 
TYPE-CATEGORY (both symbols)."
-  (intern (concat (symbol-name type-category) "::" (symbol-name type))))
+  "Return possibly new Hyperbole type symbol composed from TYPE and 
TYPE-CATEGORY (both symbols).
+TYPE-CATEGORY must be one of `actypes' or `ibtypes'; if not, return nil."
+  (when (memq type-category '(actypes ibtypes))
+    (intern (concat (symbol-name type-category) "::" (symbol-name type)))))
 
 ;;; ========================================================================
 ;;; action class
diff --git a/hbut.el b/hbut.el
index 10fe130fc0..2f8568b60c 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:     15-Jul-22 at 22:07:35 by Mats Lidell
+;; Last-Mod:     17-Jul-22 at 16:26:56 by Bob Weiner
 ;;
 ;; Copyright (C) 1991-2022  Free Software Foundation, Inc.
 ;; See the "HY-COPY" file for license information.
@@ -17,8 +17,8 @@
 ;;; Other required Elisp libraries
 ;;; ************************************************************************
 
-(eval-and-compile (mapc #'require '(elisp-mode help-mode hversion hmoccur
-                                               hbmap htz hbdata hact view)))
+(eval-and-compile (mapc #'require '(cl-lib elisp-mode help-mode hversion
+                                   hmoccur hbmap htz hbdata hact view)))
 
 ;;; ************************************************************************
 ;;; Public declarations
@@ -1519,52 +1519,11 @@ excluding delimiters, not just one."
                    ;; should need that.
                    (goto-char (min (+ 2 (match-end 0)) (point-max)))
                  (goto-char opoint))))
-
-           ;; Check for an implicit button at current point, record its
-           ;; attributes and return a button symbol for it.
-           (let ((types (htype:category 'ibtypes))
-                 ;; Global var used in (hact) function, don't delete.
-                 (hrule:action 'actype:identity)
-                 (ibpoint (point-marker))
-                 (itype)
-                 (args)
-                 (is-type))
-             (unless key-only
-               (hattr:clear 'hbut:current))
-             (while (and (not is-type) types)
-               (setq itype (car types))
-               (when (and itype (setq args (funcall itype)))
-                 (setq is-type itype)
-                 ;; Any implicit button type check should leave point
-                 ;; unchanged.  Trigger an error if not.
-                 (unless (equal (point-marker) ibpoint)
-                   (hypb:error "(Hyperbole): `ibtypes::%s' implicit button 
type test failed to restore point to %s" is-type ibpoint)))
-               (setq types (cdr types)))
-             (set-marker ibpoint nil)
-             (when is-type
-               (when name
-                 (hattr:set 'hbut:current 'name name))
-               (hattr:set 'hbut:current 'categ is-type)
-               (when lbl-key
-                 (hattr:set 'hbut:current 'lbl-key lbl-key))
-               (if key-only
-                   (hattr:get 'hbut:current 'lbl-key)
-                 (hattr:set 'hbut:current 'loc (save-excursion
-                                                 (hbut:key-src 'full)))
-                 (or (hattr:get 'hbut:current 'args)
-                     (not (listp args))
-                     (progn
-                       (setq args (copy-sequence args))
-                       (when (eq (car args) #'hact)
-                         (setq args (cdr args)))
-                       (hattr:set 'hbut:current 'actype
-                                  (or
-                                   ;; Hyperbole action type
-                                   (symtable:actype-p (car args))
-                                   ;; Regular Emacs Lisp function symbol
-                                   (car args)))
-                       (hattr:set 'hbut:current 'args (cdr args))))
-                 'hbut:current))))
+           (if key-only
+               lbl-key
+             ;; Check for an implicit button at current point, record its
+             ;; attributes and return a button symbol for it.
+             (ibut:create)))
        (goto-char opoint)))))
 
 (defun    ibut:at-type-p (ibut-type-symbol)
@@ -1583,6 +1542,78 @@ associated arguments from the button."
              (hrule:action 'actype:identity))
          (funcall ibut-type-symbol))))))
 
+(cl-defun ibut:create (&optional &key name lbl-key lbl-start lbl-end
+                                loc categ actype args action)
+  "Return `hbut:current' symbol with attributes of implicit button at point.
+Return nil if no implicit button at point."
+  ;; :args is ignored unless :categ is also given.
+
+  ;; Since the Smart Keys handle end-of-line and end-of-buffer
+  ;; separately from whether point is within an implicit button,
+  ;; always report not within one when point is at the end of a line.
+  ;; -- RSW, 02-16-2020 and 07-17-2022
+  (unless (or (eolp) (eobp))
+    (let* ((types (htype:category 'ibtypes))
+          ;; Global var used in (hact) function, don't delete.
+          (hrule:action 'actype:identity)
+          (name-start-end (ibut:label-p t nil nil t t))
+          (ibpoint (point-marker))
+          (itype)
+          (is-type categ))
+
+      (unless name
+       (setq name (nth 0 name-start-end)))
+      (unless lbl-key
+       (setq lbl-key (or (ibut:label-to-key name)
+                         (ibut:label-p nil "\"" "\"" nil))))
+      (unless lbl-start
+       (setq lbl-start (nth 1 name-start-end)))
+      (unless lbl-end
+       (setq lbl-end (nth 2 name-start-end)))
+
+      (hattr:clear 'hbut:current)
+      (unless is-type
+       (while (and (not is-type) types)
+         (setq itype (car types))
+         (when (and itype (setq args (funcall itype)))
+           (setq is-type itype)
+           ;; Any implicit button type check should leave point
+           ;; unchanged.  Trigger an error if not.
+           (unless (equal (point-marker) ibpoint)
+             (hypb:error "(Hyperbole): `ibtypes::%s' implicit button type test 
failed to restore point to %s" is-type ibpoint)))
+         (setq types (cdr types))))
+
+      (set-marker ibpoint nil)
+      (when is-type
+       (when name
+         (hattr:set 'hbut:current 'name name))
+       (when lbl-start
+         (hattr:set 'hbut:current 'lbl-start lbl-start))
+       (when lbl-end
+         (hattr:set 'hbut:current 'lbl-end lbl-end))
+       (hattr:set 'hbut:current 'categ is-type)
+       (when lbl-key
+         (hattr:set 'hbut:current 'lbl-key lbl-key))
+       (hattr:set 'hbut:current 'loc (or loc (save-excursion
+                                               (hbut:key-src 'full))))
+       (when action
+         (hattr:set 'hbut:current 'action action))
+       (or args
+           (hattr:get 'hbut:current 'args)
+           (not (listp args))
+           (progn
+             (setq args (copy-sequence args))
+             (when (eq (car args) #'hact)
+               (setq args (cdr args)))
+             (hattr:set 'hbut:current 'actype
+                        (or
+                         ;; Hyperbole action type
+                         (symtable:actype-p (car args))
+                         ;; Regular Emacs Lisp function symbol
+                         (car args)))
+             (hattr:set 'hbut:current 'args (cdr args))))
+       'hbut:current))))
+
 (defun    ibut:delete (&optional but-sym)
   "Delete Hyperbole implicit button based on optional BUT-SYM.
 Default is `hbut:current'.
diff --git a/hibtypes.el b/hibtypes.el
index cee63a9786..a366ab30c2 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:     14-Jun-22 at 20:06:40 by Mats Lidell
+;; Last-Mod:     17-Jul-22 at 23:19:27 by Bob Weiner
 ;;
 ;; Copyright (C) 1991-2022 Free Software Foundation, Inc.
 ;; See the "HY-COPY" file for license information.
@@ -1357,7 +1357,7 @@ action type or a function symbol to call, i.e. 
'<'actype-or-elisp-symbol
 arg1 ... argN '>'.  For example, <mail nil \"u...@somewhere.org\">."
   (let* ((hbut:max-len 0)
          (label-key-start-end (ibut:label-p nil action:start action:end t))
-         (ibut-key (nth 0 label-key-start-end))
+         (lbl-key (nth 0 label-key-start-end))
          (start-pos (nth 1 label-key-start-end))
          (end-pos (nth 2 label-key-start-end))
          actype actype-sym action args lbl var-flag)
@@ -1369,7 +1369,7 @@ arg1 ... argN '>'.  For example, <mail nil 
\"u...@somewhere.org\">."
     ;;   and end-delim is either:
     ;;     at the end of the buffer
     ;;     or is followed by a space, punctuation or grouping character.
-    (when (and ibut-key (or (null (char-before start-pos))
+    (when (and lbl-key (or (null (char-before start-pos))
                             (memq (char-syntax (char-before start-pos)) '(?\  
?\> ?\( ?\))))
                (not (memq (char-syntax (char-after (1+ start-pos))) '(?\  
?\>)))
                (or (null (char-after end-pos))
@@ -1377,7 +1377,7 @@ arg1 ... argN '>'.  For example, <mail nil 
\"u...@somewhere.org\">."
                    ;; Some of these characters may have symbol-constituent 
syntax
                    ;; rather than punctuation, so check them individually.
                    (memq (char-after end-pos) '(?. ?, ?\; ?: ?! ?\' ?\"))))
-      (setq lbl (ibut:key-to-label ibut-key))
+      (setq lbl (ibut:key-to-label lbl-key))
       ;; Handle $ preceding var name in cases where same name is
       ;; bound as a function symbol
       (when (string-match "\\`\\$" lbl)
@@ -1395,21 +1395,33 @@ arg1 ... argN '>'.  For example, <mail nil 
\"u...@somewhere.org\">."
                                (special-form-p actype-sym))
                            actype-sym)))
       (when actype
-        (ibut:label-set lbl start-pos end-pos)
         (setq action (read (concat "(" lbl ")"))
               args (cdr action))
-        (cond ((and (symbolp actype) (fboundp actype)
-                    (string-match "-p\\'" (symbol-name actype)))
-               ;; Is a function with a boolean result
-               (setq args `(',action)
-                    action `(display-boolean ',action)
-                     actype #'display-boolean))
-              ((and (null args) (symbolp actype) (boundp actype)
-                    (or var-flag (not (fboundp actype))))
-               ;; Is a variable, display its value as the action
-               (setq args `(',actype)
-                     action `(display-variable ',actype)
-                     actype #'display-variable)))
+       (unless assist-flag
+          (cond ((and (symbolp actype) (fboundp actype)
+                      (string-match "-p\\'" (symbol-name actype)))
+                ;; Is a function with a boolean result
+                (setq args `(',action)
+                      action `(display-boolean ',action)
+                       actype #'display-boolean))
+               ((and (null args) (symbolp actype) (boundp actype)
+                      (or var-flag (not (fboundp actype))))
+                ;; Is a variable, display its value as the action
+                (setq args `(',actype)
+                       action `(display-variable ',actype)
+                       actype #'display-variable))
+               ((and (symbolp actype) (fboundp actype)
+                      (string-match "\\b\\(get\\|value\\)" (symbol-name 
actype)))
+                ;; For 'get' and 'value' functions, display the action
+                ;; result in the minibuffer
+                (setq args `(',action)
+                       action `(display-value ',action)
+                       actype #'display-value))))
+
+       ;; Create implicit button structure
+       (ibut:create :lbl-key lbl-key :lbl-start start-pos :lbl-end end-pos
+                    :categ 'ibtypes::action :actype actype :args args :action 
action)
+
         ;; Necessary so can return a null value, which actype:act cannot.
         (let ((hrule:action
                (if (eq hrule:action #'actype:identity)
@@ -1429,10 +1441,15 @@ If a boolean function or variable, display its value."
   (when (hbut:is-p hbut)
     (let* ((label (hbut:key-to-label (hattr:get hbut 'lbl-key)))
           (actype (hattr:get hbut 'actype))
-          (args (hattr:get hbut 'args)))
+          (args (hattr:get hbut 'args))
+          (type-help-func))
       (setq actype (or (htype:def-symbol actype) actype))
       (if hbut
-         (progn (hbut:report hbut)
+         (progn (setq type-help-func (intern-soft (concat (symbol-name actype) 
":help")))
+                (if (functionp type-help-func)
+                    (funcall type-help-func hbut)
+                  (let ((total (hbut:report hbut)))
+                    (when total (hui:help-ebut-highlight))))
                 (when (memq actype '(display-boolean display-variable))
                   (apply #'actype:eval actype args)))
        (error "(action:help): No action button labeled: %s" label)))))

Reply via email to