branch: externals/hyperbole
commit c32b73d2c34c61cdbe59411cbba418bf375dd2f4
Author: bw <[email protected]>
Commit: bw <[email protected]>

    hywiki.el - Fix reference completion on # section characters
    
    hbut:modify-syntax Treat # as a symbol constituent to support
      'company-mode' completion in for 'hbut:syntax-table' and
      'help-mode-syntax-table'.
    
    README.md: Add "The Emacs Hyperbole" great article by Mike Hostetler.
---
 ChangeLog               | 22 ++++++++++++++++++
 README.md               | 60 +++++++++++++++++++++++++------------------------
 hbut.el                 |  5 ++++-
 hywiki.el               | 48 +++++++++++++++++++++++++++++----------
 test/hywconfig-tests.el |  4 ++--
 5 files changed, 95 insertions(+), 44 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 87d7754632..b3956c3323 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
+2026-02-26  Bob Weiner  <[email protected]>
+
+* hywiki.el (hywiki-word-strip-suffix): Fix to strip any leading or trailing #
+    and whitespace chars.
+    (hywiki-format-grep-to-reference): Don't add double quotes so when used
+    with completions, don't fail because the double quote is not included in
+    the matched prefix.
+    (hywiki-insert-link): Add double-quotes if link contains a space.
+    (hywiki-completion-exit-function): Add.
+    (hywiki-word-add-completion-at-point): Add call to above function in
+    completion exit hooks that support normal completion, company and corfu.
+    (hywiki-maybe-at-wikiword-beginning): Change when non-nil return value to
+    be the preceding char or if at bol, then 0.
+
+2026-02-25  Bob Weiner  <[email protected]>
+
+* hbut.el (hbut:modify-syntax): Treat # as a symbol constituent to support
+    'company-mode' completion in for 'hbut:syntax-table' and
+    'help-mode-syntax-table'.
+
 2026-02-22  Bob Weiner  <[email protected]>
 
+* README.md: Add "The Emacs Hyperbole" great article by Mike Hostetler.
+
 * hywiki.el (hywiki-format-reference): Rename to 
'hywiki-format-grep-to-reference';
     remove autoload.
             (hywiki-format-reference-to-grep): Add.
diff --git a/README.md b/README.md
index 2124a69922..e7385f4c6c 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ otherwise, skip to the next section.
    - [Quick Introduction](https://youtu.be/K1MNUctggwI)
 
    - [Top 10 ways Hyperbole amps up 
Emacs](https://emacsconf.org/2023/talks/hyperamp/)
-  
+
    - [Introduction to Buttons](https://youtu.be/zoEht66N2PI)
 
    - [Linking Personal Info with Implicit 
Buttons](https://emacsconf.org/2022/talks/buttons/)
@@ -44,19 +44,21 @@ otherwise, skip to the next section.
    - [HyRolo, fast contact/hierarchical record 
viewer](https://youtu.be/xdJGFdgKPFY)
 
    - [Using Koutline for stream of thought 
journaling](https://emacsconf.org/2023/talks/koutline/)
-  
+
    - [Build a Zettelkasten with 
HyRolo](https://emacsconf.org/2022/talks/rolodex/)
 
    - [HyControl, fast Emacs frame and window 
manager](https://youtu.be/M3-aMh1ccJk)
 
    - [Writing test cases for GNU 
Hyperbole](https://emacsconf.org/2023/talks/test/)
-  
+
    - [Find/Web Search](https://youtu.be/8lMlJed0-OM)
 
    - [Linking personal info with implicit 
buttons](https://youtu.be/TQ_fG7b1iHI)
 
 ## Articles
 
+   - [The Emacs Hyperbole](https://mike.hostetlerhome.com/emacs-hyperbole)
+
    - [HyWiki: My Favorite Part of 
Hyperbole](https://kirankp.com/blog/gnu-hyperbole/)
 
    - [Hyperbole VisionQuest Part 
1](https://github.com/termitereform/JunkPile/blob/master/HyperboleNotes.org)
@@ -191,7 +193,7 @@ start moving further, faster.
 Once you have Emacs set up at your site, GNU Hyperbole may be
 installed by using the Emacs Package Manager.  If you are not
 familiar with it, see the Packages section of the GNU Emacs Manual,
-[Emacs 
Packages](https://www.gnu.org/software/emacs/manual/html_node/emacs/Packages.html).
 
+[Emacs 
Packages](https://www.gnu.org/software/emacs/manual/html_node/emacs/Packages.html).
 
 If you have Hyperbole 5.10 or higher already installed and simply want to
 upgrade it, invoke the Emacs Package Manager with {M-x list-packages RET},
@@ -267,10 +269,10 @@ Hyperbole also includes the Hyperbole Manual, a full 
reference manual,
 not a simple introduction.  It is included in the "man/" subdirectory
 of the Hyperbole package directory in four forms:
 
-[hyperbole.info](man/hyperbole.info)   - online Info browser version  
-[hyperbole.html](man/hyperbole.html)   - web version  
-[hyperbole.pdf](man/hyperbole.pdf)     - printable version  
-[hyperbole.texi](man/hyperbole.texi)   - source version  
+[hyperbole.info](man/hyperbole.info)   - online Info browser version
+[hyperbole.html](man/hyperbole.html)   - web version
+[hyperbole.pdf](man/hyperbole.pdf)     - printable version
+[hyperbole.texi](man/hyperbole.texi)   - source version
 
 The Hyperbole package installation places the Info version of this manual
 where needed and adds an entry for Hyperbole into the Info directory under
@@ -323,7 +325,7 @@ Hyperbole consists of six parts:
        automatically recognized within text that perform actions,
        e.g. bug#24568 displays the bug status information for that bug
        number.
-       
+
        These actions may be links or arbitrary Lisp expressions.  So
        for example, you could create your own button type of
        Wikipedia searches that jumped to the named Wikipedia page
@@ -403,7 +405,7 @@ to a file or executing a shell command.
 There are three categories of Hyperbole buttons:
 
    1.  *Explicit Buttons*
-          created by Hyperbole, accessible from within a single document; 
+          created by Hyperbole, accessible from within a single document;
 
    2.  *Global Buttons*
           created by Hyperbole, accessible anywhere within a user's
@@ -457,7 +459,7 @@ Some of Hyperbole's most important features include:
 
 Typical Hyperbole applications include:
 
- - *Personal Information Management*  
+ - *Personal Information Management*
    Overlapping link paths provide a variety of views into an
    information space.  A single key press activates buttons
    regardless of their types, making navigation easy.
@@ -465,7 +467,7 @@ Typical Hyperbole applications include:
    A search facility locates buttons in context and permits quick
    selection.
 
- - *Documentation Browsing*  
+ - *Documentation Browsing*
    Embedding cross-references in a favorite documentation format.
 
    Addition of a point-and-click interface to existing documentation.
@@ -474,18 +476,18 @@ Typical Hyperbole applications include:
    of an identifier from its use within code or its reference within
    documentation.
 
- - *Brainstorming*  
+ - *Brainstorming*
    Capture of ideas and then quick reorganization with the Hyperbole
    Koutliner.  Link to related ideas, eliminating the need to copy
    and paste information into a single place.
 
- - *Help/Training Systems*  
+ - *Help/Training Systems*
    Creation of tutorials with embedded buttons that show students how
    things work while explaining the concepts, e.g. an introduction
    to UNIX commands.  This technique can be much more effective than
    descriptions alone.
 
- - *Archive Managers*  
+ - *Archive Managers*
    Supplementation of programs that manage archives from incoming
    information stream, having them add topic-based buttons that
    link to the archive holdings.  Users can then search and create
@@ -547,19 +549,19 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
   well-thought out, poised engineering.  It may be from the 90s, but it
   feels like a breath of fresh air to me.
 
-                        -- de_sonnaz on reddit  
+                        -- de_sonnaz on reddit
 
 
   \*\*\* MAN I love Hyperbole!!!  Wow! \*\*\*
 
-                        -- Ken Olstad  
+                        -- Ken Olstad
                            Cheyenne Software, Inc.
 
 -------
 
   I *love* koutlines.
 
-                        -- Bob Glickstein  
+                        -- Bob Glickstein
                            Z-Code Software Corporation
 
 -------
@@ -580,7 +582,7 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
   but due to the ease of installation and the quality of the documentation,
   digging into it is actually fun.
 
-                        -- Aditya Siram  
+                        -- Aditya Siram
 
 -------
 
@@ -616,7 +618,7 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
   useful set of power tools.  If Emacs is your preferred productivity
   environment, it's definitely worth getting familiar with it.
 
-                        -- Chris Nuzum  
+                        -- Chris Nuzum
                            Co-founder, Traction Softwarea, Inc.
 
 -------
@@ -633,7 +635,7 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
   perfect, but adequate), so I can put any aspect of development on
   our internal web for others to see.
 
-                        -- Farzin Guilak  
+                        -- Farzin Guilak
                            Protocol Systems, Inc., Engineer
 
 -------
@@ -656,7 +658,7 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
    4. The Hyperbole Koutliner, which I find a very useful tool.  I've
       implemented Emacspeak extensions to support it.
 
-                        -- TV Raman  
+                        -- TV Raman
                            Google Inc.
 
 -------
@@ -679,7 +681,7 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
   that do various little things, and I index saved mail messages by putting
   explicit link-to-mail buttons in an outline file.
 
-                        -- Ken Olstad  
+                        -- Ken Olstad
                            Cheyenne Software, Inc.
 
 -------
@@ -711,12 +713,12 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
 
   * Organizing and viewing online documentation: using Hyperbole along with
     Hyper-man and Info makes it truly easy to look up online documentation.
-      
+
   * Other desktop organization tasks: including links to various mail
     folders, saved newsgroup conversation threads, online note-taker,
     emacs-command invocations, etc.
 
-                        -- Dadong Wan  
+                        -- Dadong Wan
                            University of Hawaii
 
 -------
@@ -729,15 +731,15 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
   in it is a very powerful capability.  Using ange-ftp mode, one can make
   file references "across the world" as easily as normal file references.
 
-                        -- Mark Eichin  
+                        -- Mark Eichin
                            Cygnus Support
 -------
 
    I just wanted to say how much I enjoy using the Hyperbole Koutliner.
    It is a great way to quickly construct very readable technical documents
-   that I can pass around to others.   Thanks for the great work.  
+   that I can pass around to others.   Thanks for the great work.
 
-                        -- Jeff Fried  
+                        -- Jeff Fried
                            Informix
 
 -------
@@ -745,7 +747,7 @@ default context-sensitive Hyperbole key bindings (Smart 
Keys).
    The Hyperbole system provides a nice interface to exploring corners of
    Unix that I didn't know existed before.
 
-                        -- Craig Smith  
+                        -- Craig Smith
 
 
 ## Why was Hyperbole developed?
diff --git a/hbut.el b/hbut.el
index 850fe36b08..006ecb76a9 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:     18-Feb-26 at 23:49:33 by Bob Weiner
+;; Last-Mod:     25-Feb-26 at 22:31:30 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1638,6 +1638,9 @@ to include {} only.  For use with implicit button 
activations."
   ;; Treat angle brackets and braces as opening and closing delimiters
   ;; for ease of matching.
   (mapc (lambda (syntax-table)
+          ;; Treat # as a symbol constituent to support company-mode 
completion.
+          (modify-syntax-entry ?# "_" syntax-table)
+          ;; Treat angle brackets as opening and closing delimiters for ease 
of matching.
          (modify-syntax-entry ?\< "(>" syntax-table)
          (modify-syntax-entry ?\> ")<" syntax-table)
          ;; Treat braces as opening and closing delimiters for ease of 
matching.
diff --git a/hywiki.el b/hywiki.el
index 0bb4f7a90c..f72be27b03 100644
--- a/hywiki.el
+++ b/hywiki.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Apr-24 at 22:41:13
-;; Last-Mod:     22-Feb-26 at 23:14:29 by Bob Weiner
+;; Last-Mod:     26-Feb-26 at 23:16:36 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1490,12 +1490,13 @@ Each candidate is an alist with keys: file, line, text, 
and display."
                             (not (hywiki-non-hook-context-p))
                             (hywiki-word-at t t)))
          (ref (nth 0 ref-start-end))
+         (partial-page-name (hywiki-get-singular-wikiword ref))
          (start (nth 1 ref-start-end))
          (end (nth 2 ref-start-end)))
     (when start
       (let* ((default-directory hywiki-directory)
              (cmd (format "grep -nEH -r '^[ \t]*\\*+ +' ./*%s*%s"
-                          ref
+                          partial-page-name
                           hywiki-file-suffix))
              (output (shell-command-to-string cmd))
              (lines (split-string output "\n" t))
@@ -1507,6 +1508,16 @@ Each candidate is an alist with keys: file, line, text, 
and display."
         (when candidate-alist
           (list start end candidate-alist
                 :exclusive 'no
+                ;; For company, allow any non-delim chars in prefix
+                ;; :company-prefix-length t
+                ;; :company-prefix-dirty t
+                ;; Returning the prefix as (string . t) tells Company:
+                ;; 'This is the prefix, and yes, it is currently valid 
(dirty).'
+                ;; :company-prefix-snapshot (cons ref t)
+
+                ;; This prevents the minibuffer/Corfu/Company from
+                ;; re-parsing the # as a 'function quote' trigger.
+                :company-kind (lambda (_) 'keyword)
                 :annotation-function (lambda (_) " [HyWiki]")))))))
 
 (defun hywiki-create-referent-and-display (wikiword &optional prompt-flag)
@@ -1768,7 +1779,10 @@ simplifies to:
              (hywiki--referent-reference-to-org-link reference referent 
description))))))
 
 (defun hywiki-maybe-at-wikiword-beginning ()
-  "Return non-nil if previous character is one preceding a HyWikiWord.
+  "Return non-nil if at bol or previous character is one preceding a 
HyWikiWord.
+When non-nil, the value returned is 0 for bol and the preceding character,
+otherwise.
+
 Do not test whether or not a page exists for the HyWikiWord.
 Use `hywiki-get-referent' to determine whether a HyWiki page exists."
   ;; Ignore wikiwords preceded by any non-whitespace character, except
@@ -1776,7 +1790,7 @@ Use `hywiki-get-referent' to determine whether a HyWiki 
page exists."
   (when (or (bolp)
            (string-match (regexp-quote (char-to-string (char-before)))
                          "\[\(\{\<\"'`\t\n\r\f "))
-    t))
+    (or (char-before) 0)))
 
 (defun hywiki-directory-edit ()
   "Edit HyWiki pages in current `hywiki-directory'.
@@ -2069,6 +2083,8 @@ Add double quotes if the section contains any whitespace 
after trimming."
   (interactive "*P")
   (let ((ref (if arg (hywiki-word-read) (hywiki-page-read-reference))))
     (when ref
+      (when (string-match-p "\\s-" ref)
+       (setq ref (concat "\"" ref ""\")))
       (insert ref)
       (skip-chars-backward "\"")
       (goto-char (1- (point)))
@@ -2076,7 +2092,6 @@ Add double quotes if the section contains any whitespace 
after trimming."
 
 (defun hywiki-format-grep-to-reference (page-and-headline)
   "Return a HyWikiWord#section reference from PAGE-AND-HEADLINE.
-Call `hywiki-consult-page-and-headline' to generate PAGE-AND-HEADLINE.
 Add double quotes if the section contains any whitespace after trimming.
 
 Return t if PAGE-AND-HEADLINE is a valid string, else nil.  If the page name
@@ -2089,11 +2104,7 @@ therein is invalid, trigger an error."
           (setq line (string-trim line))
           ;; Drop '* ' prefix
           (setq line (hsys-org-format-heading line t t t t))
-          (format (if (string-match-p "\\s-" line)
-                     "\"%s#%s\""
-                   "%s#%s")
-                 page
-                 line))
+          (format "%s#%s" page line))
       (message "(hwiki-format-grep-to-reference): Parse error on: %s"
                page-and-headline)
       nil)))
@@ -3308,6 +3319,7 @@ variables."
   "Return PAGE-NAME with any optional #section:Lnum:Cnum stripped off.
 If an empty string or not a string, return nil."
   (when (and (stringp page-name) (not (string-empty-p page-name)))
+    (setq page-name (string-trim page-name "[# \t\n\r]+" "[# \t\n\r]+"))
     (if (and (string-match hywiki-word-with-optional-suffix-exact-regexp 
page-name)
             (or (match-beginning 2) (match-beginning 4)))
        ;; Remove any #section:Lnum:Cnum suffix in PAGE-NAME.
@@ -3957,11 +3969,23 @@ occurs with one of these hooks, the problematic hook is 
removed."
   (hywiki-get-referent-hasht)
   (hywiki-maybe-directory-updated))
 
+(defun hywiki-completion-exit-function ()
+  "Function called when HyWiki reference completion ends."
+  (hywiki-maybe-highlight-reference))
+
 (defun hywiki-word-add-completion-at-point ()
   "Add HyWiki refs in-buffer completion to `completion-at-point-functions'.
 Completion requires typing at least the two first characters of the
-completion or no completion candidates are returned."
-  (add-hook 'completion-at-point-functions #'hywiki-completion-at-point -90 t))
+completion or no completion candidates are returned.
+If using `company-mode', you must use the `company-capf' backend for HyWiki
+completion to work properly."
+  (add-hook 'completion-at-point-functions #'hywiki-completion-at-point -90 t)
+  (if (featurep 'company-mode)
+      (progn (add-hook 'company-completion-finished-hook
+                       #'hywiki-completion-exit-function)
+             (add-hook 'company-completion-cancelled-hook
+                       #'hywiki-completion-exit-function))
+    (advice-add 'completion--insert :after #'hywiki-completion-exit-function)))
 
 (defun hywiki-word-remove-completion-at-point ()
   "Remove HyWiki refs in-buffer completion from 
`completion-at-point-functions'."
diff --git a/test/hywconfig-tests.el b/test/hywconfig-tests.el
index 82144e5fd1..4b6c02913b 100644
--- a/test/hywconfig-tests.el
+++ b/test/hywconfig-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <[email protected]>
 ;;
 ;; Orig-Date:    30-Jan-21 at 12:00:00
-;; Last-Mod:     23-Dec-23 at 01:21:53 by Bob Weiner
+;; Last-Mod:     22-Feb-26 at 23:34:03 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -29,7 +29,7 @@
   "Remove names from frame parameters."
   (set-frame-parameter nil 'named-hywconfigs nil))
 
-(ert-deftest hywconfig--inital-ring-is-empty ()
+(ert-deftest hywconfig--initial-ring-is-empty ()
   "Verify an initial ring is empty."
   (hywconfig-tests--remove-ring)
   (should (hywconfig-ring-empty-p)))

Reply via email to