Skip to content

Commit e96444b

Browse files
authored
Merge pull request #907 from rswgnu/rsw
hui:link-possible-types - Fix ilink creation to HyWiki and Org bufs
2 parents 38b7605 + 198336d commit e96444b

14 files changed

Lines changed: 635 additions & 366 deletions

ChangeLog

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,103 @@
1+
2026-03-17 Bob Weiner <rsw@gnu.org>
2+
3+
* hibtypes.el (pathname): Add a clause to handle "#section" links by
4+
themselves as some change had broken this capability.
5+
6+
* test/hibtypes-tests.el (ibtypes:org-id-test): Fix by adding missing
7+
'Org' in front of 'ID' in the string match.
8+
9+
* hpath.el (hpath:validate): Fix path and suffix handling edge cases.
10+
11+
2026-03-16 Bob Weiner <rsw@gnu.org>
12+
13+
* hibtypes.el (action): Ensure if action name is bound only as a variable
14+
that there are no arguments within the angle brackets. If there are,
15+
then it is not an action button.
16+
17+
* test/hywiki-tests.el (hywiki-tests--save-referent-org-id): Fix to mock
18+
'org-id-get' instead of 'org-id-get-create' and add call to
19+
`hywiki-get-referent' to ensure referent is created and read back properly.
20+
21+
* hywiki.el (hywiki-get-page-file): The page file may have previously been
22+
resolved and sent as input here. If it exists, simply use it.
23+
24+
* hpath.el (hpath:is-p): Remove 'file-exists-p' call because 'hpath:normalize'
25+
handles that while accounting for path #suffixes which the 'file-exists-p'
26+
call mistakenly nullifies.
27+
(hpath:validate): Fix that 'suffix' was set to the whole path string
28+
when 'suffix-start' was null. Now it is set properly to nil.
29+
Also fix so if a file named "myfile#name", validate accepts it without
30+
treating the #name as a suffic/section to be stripped.
31+
32+
2026-03-15 Bob Weiner <rsw@gnu.org>
33+
34+
* test/demo-tests.el (fast-demo-display-kotl-starting-from-cell,
35+
demo-implicit-button-hash-link-test)
36+
demo-implicit-button-line-and-column-rtest):
37+
Update these to remove 'hy-test-helpers:kill-buffer' since 'with-temp-buffer'
38+
cleans it up. This eliminates a null buffer error.
39+
40+
* hpath.el (hpath:normalize): Handle directory paths and avoid reading in the
41+
file to handle it.
42+
(hpath:validate): Fix to strip #suffix before validation and add
43+
it back on return.
44+
* hibtypes.el (hywiki-existing-word): Simplify pathname check without calling
45+
other ibtypes.
46+
47+
* hpath.el (hpath:suffixes): Remove ".org" as it triggers pathname ibtype when
48+
it shouldn't and overrides `hywiki-existing-word'.
49+
50+
* hywiki.el (hywiki-add-org-id): Remove (hmouse-choose-link-and-referent-windows)
51+
as this is not what inserts a link but just creates the wikiword referent.
52+
(hywiki-word-regexp): Add optional .org suffix so "WikiWord.org#section"
53+
works.
54+
55+
* hywiki.el (hywiki-referent-menu): Change from inserting a string link
56+
to an Org link that includes the associated Org heading title. Change
57+
format from "ID: uuid" to [[id:uuid][title]].
58+
(hywiki-add-org-id):
59+
test/hywiki-tests.el (hywiki-tests--add-org-id):
60+
(hywiki-tests--save-referent-org-id):
61+
(hywiki-tests--add-org-id): Add reading back the org-id
62+
referent.
63+
(hywiki-tests--save-referent-org-id): Delete this test;
64+
covered better by 'hywiki-tests--add-org-id'.
65+
hui.el (hui:link-possible-types): Update id handling in all of these.
66+
67+
* hywiki.el (hywiki-get-page-file, hywiki-get-existing-page-file): Add
68+
second function and check that 'file-stem-name' does not contain
69+
a directory, so it is not returned with the wrong dir attached.
70+
hpath.el (hpath:at-p, hpath:find-line):
71+
hibtypes.el (pathname-line-and-column, hib-link-to-file-line): Call
72+
the new fuction in these four functions.
73+
74+
* hywiki.el (hywiki-org-get-heading-match-regexp,
75+
hywiki--org-set-heading-regexp): Make whitespace before
76+
optional components optional and allow for tabs.
77+
78+
* hywiki.el (hywiki-referent-menu): Change all "ID: " to "id:" to match
79+
how Org works with the id: link type prefix when specifying ids.
80+
81+
* hpath.el (hpath:find, hpath:expand): Fix to properly expand HyWiki
82+
page references.
83+
84+
* test/hywiki-tests.el (hywiki-tests--save-referent-global-button-use-menu):
85+
Rewrite to not use mocking. Fixes this to work with latest
86+
'hpath:find' as well.
87+
88+
* hbut.el (ibut:insert-text): Ensure line and col nums are prefixed with :L
89+
and :C.
90+
* hywiki.el (hywiki-org-get-heading-match-regexp): Handle both HyWiki dir
91+
custom todo keywords when in a page and Org standard todo keywords, otherwise.
92+
* hibtypes.el (pathname-line-and-column, hib-link-to-file-line): Expand HyWiki
93+
page name using 'hywiki-get-page-file' before try to expand in current
94+
directory
95+
(pathname-line-and-column, hib-link-to-file-line): Call
96+
'hywiki-get-page-file' only if 'label' has no directory attached. This fixes
97+
a problem where ".org" is attached improperly to the filename.
98+
* hpath.el (hpath:at-p, hpath:find-line): Handle pathname expansion of HyWiki
99+
page names.
100+
1101
2026-03-15 Mats Lidell <matsl@gnu.org>
2102

3103
* test/hyrolo-tests.el: Prefix all tests with hyrolo-tests. Use
@@ -22,6 +122,41 @@
22122

23123
2026-03-14 Bob Weiner <rsw@gnu.org>
24124

125+
* hpath.el (hpath:call): (file-exists-p "") returns t, so fix to check for empty
126+
string before calling that.
127+
hibtypes.el (hpath:is-p): Unless 'non-exist' arg is sent or path is a remote file,
128+
return path only if it exists.
129+
130+
* hui.el (require 'hsys-org): Add.
131+
hibtypes.el (require 'hsys-org): Add.
132+
hsys-org.el (hsys-org-uuid-is-p): Add and use in "hibtypes.el" and "hui.el".
133+
134+
* hui.el (hui:link-possible-types): For Org/Org-Roam ids, send 2nd arg
135+
of current heading string to 'link-to-org-id' call.
136+
(hui:link-possible-types): If in a HyWiki page but not on a heading line,
137+
use a 'link-to-wikiword' with the page name and line number.
138+
hactypes.el (link-to-org-id): Add optional heading 'title' arg for use in
139+
'hbut:insert-text' where ibut links are created.
140+
141+
* hbut.el (ibut:insert-text): For 'actypes::link-to-org-id', change from
142+
a double-quoted link to a double square bracketed Org link. This allows
143+
including the title from the Org heading linked to which is stored in
144+
the current Hyperbole button attribute, 'lbl-key'.
145+
146+
* hui.el (hui:link-possible-types): For HyWiki links, wrap a call of
147+
'hpath:org-normalize-title' around 'hywiki-org-format-heading' to ensure
148+
everything but the title is removed.
149+
150+
* hsys-org.el (hsys-org-link-at-p): Don't shrink label region down to just
151+
the description part of the Org link, leave it as the entire space inside
152+
the Org open and close brackets. Remove this code:
153+
(when (string-match "\\]\\[" label)
154+
(setq start (match-end 0)))
155+
This makes link activation work better.
156+
157+
* hibtypes.el (org-id, org-id:help): Fix to remove "id:" prefix so
158+
that uuid check predicates succeed properly.
159+
25160
* Makefile (HYPB_BIN_WARN): Fix preceding commentary on example use.
26161
(test-all TERM=xterm-256color): Add #(LET_VARIABLES).
27162

hact.el

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
;; Author: Bob Weiner
44
;;
55
;; Orig-Date: 18-Sep-91 at 02:57:09
6-
;; Last-Mod: 30-Dec-25 at 14:42:06 by Mats Lidell
6+
;; Last-Mod: 16-Mar-26 at 22:11:38 by Bob Weiner
77
;;
88
;; SPDX-License-Identifier: GPL-3.0-or-later
99
;;
@@ -391,7 +391,7 @@ Autoloads action function if need be to get the parameter list."
391391
;;; ========================================================================
392392

393393
(defun hact (&rest args)
394-
"Perform action formed from rest of ARGS and return the result.
394+
"Perform action function formed from rest of ARGS and return the result.
395395
The value of `hrule:action' determines what effect this has. The
396396
default for `hrule:action' is `actype:act' which returns the result of
397397
the action unless it is nil, in which case t is returned instead, to

hactypes.el

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
;; Author: Bob Weiner
44
;;
55
;; Orig-Date: 23-Sep-91 at 20:34:36
6-
;; Last-Mod: 28-Sep-25 at 23:27:18 by Mats Lidell
6+
;; Last-Mod: 15-Mar-26 at 14:44:00 by Bob Weiner
77
;;
88
;; SPDX-License-Identifier: GPL-3.0-or-later
99
;;
@@ -639,8 +639,9 @@ information on how to specify a mail reader to use."
639639
(hypb:error "(link-to-mail): No msg `%s' in file \"%s\""
640640
mail-msg-id mail-file)))))
641641

642-
(defact link-to-org-id (id)
643-
"Display the Org entry, if any, for ID."
642+
(defact link-to-org-id (id &optional title)
643+
"Display the Org entry, if any, for ID with optional TITLE.
644+
ID is a uuid without any 'id:' prefix."
644645
(when (stringp id)
645646
(let* ((inhibit-message t) ;; Inhibit org-id-find status msgs
646647
(m (or (and (featurep 'org-roam) (org-roam-id-find id 'marker))

hbut.el

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
;; Author: Bob Weiner
44
;;
55
;; Orig-Date: 18-Sep-91 at 02:57:09
6-
;; Last-Mod: 28-Feb-26 at 16:33:40 by Bob Weiner
6+
;; Last-Mod: 15-Mar-26 at 22:16:44 by Bob Weiner
77
;;
88
;; SPDX-License-Identifier: GPL-3.0-or-later
99
;;
@@ -586,9 +586,7 @@ For interactive creation, use `hui:ebut-create' instead."
586586
(hattr:set 'hbut:current 'args args)
587587
(ebut:operate label nil))
588588
(error (hattr:clear 'hbut:current)
589-
(if (and (listp (cdr err)) (= (length (cdr err)) 1))
590-
(error "(ebut:program): actype arg must be a bound symbol (not a string): %S" actype)
591-
(error "(ebut:program): %S" err)))))))
589+
(error "(ebut:program): %S" err))))))
592590

593591
(defun ebut:search (string out-buf &optional match-part)
594592
"Write explicit button lines matching STRING to OUT-BUF.
@@ -2723,7 +2721,12 @@ Summary of operations based on inputs (name arg from \\='hbut:current attrs):
27232721
(if (string-prefix-p "<" arg1)
27242722
(insert arg1)
27252723
(insert "<" arg1 ">"))))
2726-
('actypes::link-to-org-id (insert (format "\"id:%s\"" arg1)))
2724+
;; Insert an Org-style link here so can include the Org title linked
2725+
;; to for clarity.
2726+
('actypes::link-to-org-id
2727+
(insert (if arg2
2728+
(format "[[id:%s][%s]]" arg1 arg2)
2729+
(format "[[id:%s]]" arg1))))
27272730
('actypes::link-to-rfc (insert (format "rfc%d" arg1)))
27282731
('actypes::link-to-wikiword (insert (if (and (stringp arg1)
27292732
(string-match-p "\\s-" arg1))
@@ -2732,13 +2735,13 @@ Summary of operations based on inputs (name arg from \\='hbut:current attrs):
27322735
arg1)))
27332736
('man (insert arg1))
27342737
('actypes::man-show (insert arg1))
2735-
('actypes::link-to-file-line (insert (format "\"%s:%d\""
2738+
('actypes::link-to-file-line (insert (format "\"%s:L%d\""
27362739
(hpath:shorten arg1) arg2)))
27372740
('actypes::link-to-file-line-and-column
27382741
(insert
27392742
(if (eq arg3 0)
2740-
(format "\"%s:%d\"" (hpath:shorten arg1) arg2)
2741-
(format "\"%s:%d:%d\"" (hpath:shorten arg1) arg2 arg3))))
2743+
(format "\"%s:L%d\"" (hpath:shorten arg1) arg2)
2744+
(format "\"%s:L%d:C%d\"" (hpath:shorten arg1) arg2 arg3))))
27422745
('actypes::link-to-file
27432746
;; arg2 when given is a buffer position
27442747
(insert "\""

hibtypes.el

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
;; Author: Bob Weiner
44
;;
55
;; Orig-Date: 19-Sep-91 at 20:45:31
6-
;; Last-Mod: 14-Mar-26 at 03:16:36 by Bob Weiner
6+
;; Last-Mod: 17-Mar-26 at 19:48:06 by Bob Weiner
77
;;
88
;; SPDX-License-Identifier: GPL-3.0-or-later
99
;;
@@ -37,10 +37,11 @@
3737
;;; Other required Elisp libraries
3838
;;; ************************************************************************
3939

40-
(require 'cl-lib) ;; for cl-count
40+
(require 'cl-lib) ;; for cl-count and cl-find
4141
(require 'find-func) ;; used by grep-msg ibtype
4242
(eval-when-compile (require 'hversion))
4343
(require 'hactypes)
44+
(require 'hsys-org)
4445
(require 'hypb)
4546
(require 'org-macs) ;; for org-uuid-regexp
4647
(require 'subr-x) ;; for string-trim
@@ -175,17 +176,19 @@ only to prevent false matches."
175176
(start (when bounds (car bounds)))
176177
(end (when bounds (cdr bounds)))
177178
m)
179+
;; Remove any "ID:" or "id:" prefix
180+
(when (and id (string-prefix-p "id:" id t))
181+
(setq id (substring id 3)
182+
start (+ start 3)))
178183
;; Ignore ID definitions or when not on a possible ID
179-
(when (and id (if (fboundp 'org-uuidgen-p)
180-
(org-uuidgen-p id)
181-
(string-match org-uuid-regexp (downcase id))))
184+
(when (hsys-org-uuid-is-p id)
182185
(when (and start end)
183186
(ibut:label-set id start end))
184187
(if (and (not assist-flag)
185188
(save-excursion (beginning-of-line)
186189
(re-search-forward ":\\(CUSTOM_\\)?ID:[ \t]+"
187190
(line-end-position) t)))
188-
(hact 'message "On ID definition; use {C-u M-RET} to copy a link to an ID.")
191+
(hact 'message "On Org ID definition; use {C-u M-RET} to copy a link to an ID.")
189192
(when (let ((inhibit-message t) ;; Inhibit org-id-find status msgs
190193
(obuf (current-buffer))
191194
(omode major-mode))
@@ -208,6 +211,9 @@ If the referenced location is found, return non-nil."
208211
(let ((id (thing-at-point 'symbol t)) ;; Could be a uuid or some other form of id
209212
m
210213
mpos)
214+
;; Remove any "ID:" or "id:" prefix
215+
(when (and id (string-prefix-p "id:" id t))
216+
(setq id (substring id 3)))
211217
;; Ignore ID definitions or when not on a possible ID
212218
(when (and id
213219
(let ((inhibit-message t)) ;; Inhibit org-id-find status msgs
@@ -350,7 +356,10 @@ display options."
350356
;; Match PATH-related Environment and Lisp variable names and
351357
;; Emacs Lisp and Info files without any directory component.
352358
(when (setq path orig-path)
353-
(cond ((and (string-match hpath:path-variable-regexp path)
359+
(cond ((string-match "\\`#[^#]+" path)
360+
(apply #'ibut:label-set path (hpath:start-end path))
361+
(hact 'link-to-file path))
362+
((and (string-match hpath:path-variable-regexp path)
354363
(setq path (match-string-no-properties 1 path))
355364
(hpath:is-path-variable-p path))
356365
(setq path (if (or assist-flag (hyperb:stack-frame '(hkey-help)))
@@ -490,7 +499,6 @@ handle any links they recognize first."
490499
;; Prevent infinite recursion, e.g. if called via
491500
;; `org-metareturn-hook' from `org-meta-return' invocation.
492501
(not (hyperb:stack-frame '(ibtypes::debugger-source org-meta-return))))
493-
(require 'hsys-org)
494502
(declare-function hsys-org-link-at-p "hsys-org" ())
495503
(declare-function hsys-org-set-ibut-label "hsys-org" (start-end))
496504
(let ((start-end (hsys-org-link-at-p)))
@@ -985,9 +993,10 @@ See `hpath:find' function documentation for special file display options."
985993
(col-num (when (match-end 4)
986994
(string-to-number (match-string-no-properties 5 path-line-and-col))))
987995
(label (match-string-no-properties 1 path-line-and-col))
988-
;; Next variable must come last as it can overwrite the match-data
989-
(file (hpath:expand label)))
990-
(when (setq file (hpath:is-p file))
996+
;; Next variable should come last as it can overwrite the match-data
997+
file)
998+
(when (setq file (or (hpath:is-p (hpath:expand label))
999+
(hywiki-get-existing-page-file label)))
9911000
(ibut:label-set label start (+ start (length label)))
9921001
(if col-num
9931002
(hact 'link-to-file-line-and-column file line-num col-num)
@@ -1017,8 +1026,9 @@ LINE-NUM may be an integer or string."
10171026
(and (or (null (setq ext (file-name-extension file)))
10181027
(member (concat "." ext) (get-load-suffixes)))
10191028
(ignore-errors (find-library-name file)))
1020-
(expand-file-name file))))
1021-
(when (file-exists-p file)
1029+
(hpath:is-p (expand-file-name file))
1030+
(hywiki-get-existing-page-file file))))
1031+
(when (file-exists-p (hpath:normalize file))
10221032
(actypes::link-to-file-line file line-num))))
10231033

10241034
(defib ipython-stack-frame ()
@@ -1624,7 +1634,7 @@ action type, function symbol to call or test to execute, i.e.
16241634
(let ((hbut:max-len 0)
16251635
(name (hattr:get 'hbut:current 'name))
16261636
(testing-flag (when (bound-and-true-p ert--running-tests) t))
1627-
actype actype-sym action args lbl var-flag)
1637+
actname actype actype-sym action args is-var lbl sep var-flag)
16281638

16291639
;; Continue only if there if there is one of:
16301640
;; 1. `ert--running-tests' is non-nil
@@ -1640,23 +1650,26 @@ action type, function symbol to call or test to execute, i.e.
16401650
(when (string-match "\\`\\$" lbl)
16411651
(setq var-flag t
16421652
lbl (substring lbl 1)))
1643-
(setq actype (if (string-match-p " " lbl) (car (split-string lbl)) lbl)
1644-
actype-sym (or (actype:elisp-symbol actype) (intern-soft actype))
1653+
(setq actname (if (setq sep (cl-position ?\ lbl)) (substring lbl 0 sep) lbl)
1654+
actype-sym (or (actype:elisp-symbol actname) (intern-soft actname))
16451655
;; Must ignore that (boundp nil) would be t here.
16461656
actype (and actype-sym
1647-
(or (fboundp actype-sym) (boundp actype-sym)
1657+
(or (fboundp actype-sym)
1658+
(setq is-var (boundp actype-sym))
16481659
(special-form-p actype-sym)
16491660
(ert-test-boundp actype-sym))
16501661
actype-sym))
1651-
(when actype
1662+
(when (and actype (or (null is-var)
1663+
;; is a variable so can't have arguments
1664+
(equal actname lbl)))
16521665
;; For <hynote> buttons, need to double quote each argument so
16531666
;; 'read' does not change the idstamp 02 to 2.
16541667
(when (and (memq actype '(hy hynote))
16551668
(string-match-p " " lbl))
16561669
(setq lbl (replace-regexp-in-string "\"\\(.*\\)\\'" "\\1\""
16571670
(combine-and-quote-strings
16581671
(split-string lbl) "\" \""))))
1659-
(setq action (read (concat "(" lbl ")"))
1672+
(setq action (ignore-errors (read (concat "(" lbl ")")))
16601673
args (cdr action))
16611674
;; Ensure action uses an fboundp symbol if executing a
16621675
;; Hyperbole actype.
@@ -1762,8 +1775,7 @@ not yet existing HyWikiWords."
17621775
(cl-destructuring-bind (wikiword start end)
17631776
(hywiki-referent-exists-p :range)
17641777
(when wikiword
1765-
(unless (or (ibtypes::pathname-line-and-column)
1766-
(ibtypes::pathname))
1778+
(unless (file-exists-p (hywiki-word-from-reference wikiword))
17671779
(if (and start end)
17681780
(ibut:label-set wikiword start end)
17691781
(ibut:label-set wikiword))

0 commit comments

Comments
 (0)