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

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

[elpa] externals/hyperbole a74747a330 4/4: Add interactive creation of n


From: ELPA Syncer
Subject: [elpa] externals/hyperbole a74747a330 4/4: Add interactive creation of named implicit buttons via Ibut/Create
Date: Fri, 31 Mar 2023 03:58:30 -0400 (EDT)

branch: externals/hyperbole
commit a74747a3301a288bda146ad0eb861a9b9ce60fb2
Author: Bob Weiner <rsw@gnu.org>
Commit: Bob Weiner <rsw@gnu.org>

    Add interactive creation of named implicit buttons via Ibut/Create
---
 ChangeLog                |  61 +++++
 TAGS                     | 673 +++++++++++++++++++++++-----------------------
 hactypes.el              |   4 +-
 hargs.el                 |   8 +-
 hbdata.el                |  76 ++++--
 hbut.el                  | 675 +++++++++++++++++++++++++++++++++--------------
 hibtypes.el              |   4 +-
 hui-em-but.el            |  24 +-
 hui-menu.el              |   3 +-
 hui-mini.el              |   4 +-
 hui.el                   | 111 +++++---
 hypb.el                  |   6 +-
 man/hyperbole.html       | 115 ++++++--
 man/hyperbole.info       | Bin 595607 -> 597861 bytes
 man/hyperbole.pdf        | Bin 1348264 -> 1350501 bytes
 man/hyperbole.texi       |  67 +++--
 test/hmouse-drv-tests.el |   2 +-
 test/hui-tests.el        |   6 +-
 18 files changed, 1185 insertions(+), 654 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0b078a1dcd..035381d6c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,64 @@
+2023-03-29  Bob Weiner  <rsw@gnu.org>
+
+* man/hyperbole.texi (Implicit Buttons): Add paragraph on the use of Ibut/
+    menu.
+
+* hui.el (hui:ebut-create, hui:ibut-create): Remove prompting for button
+    buffer and always use current buffer.
+
+* hui-menu.el (infodock-hyperbole-menu): Add item Implicit-Button/Create.
+  hui-mini.el (hui:menus): Add minibuffer item Ibut/Create.
+
+2023-03-28  Bob Weiner  <rsw@gnu.org>
+
+* hbut.el (def-edebug-spec cl-defun): Add to make 'cl-defun' edebuggable.
+
+2023-03-27  Bob Weiner  <rsw@gnu.org>
+
+* hbut.el (ibut:label-separator): Change from " " to " - " for better
+    separation visibility.
+          (ibut:insert-text): Add.
+  hypb.el (hypb:format-args): Add and use in 'ibut:insert-text'.
+
+2023-03-26  Bob Weiner  <rsw@gnu.org>
+
+* hbdata.el (hbdata:ibut-instance-last): Add.
+            (hbdata:ibut-instance): Add.
+  hbut.el (ibut:create): Improve doc and add but-sym arg which can supply
+    all other arguments in its properties.
+          (hbut:map): Rewrite handling of 'regexp-match' arg so it always
+    applies to the button label and not its text, to accomodate named
+    implicit button filtering.
+          (hbut:label-regexp): Ensure label is wrapped as grouping 1 and
+    an optional instance number is matched.
+          (ibut:map): Utilize 'start-delim' and 'end-delim' when non-nil.
+         (hbut:map): Remove properties from 'lbl' as not needed.
+         (ibut:label-key-match): Add to return filtered list of ibut labels.
+          (ibut:label-sort-instances): Add to sort label key instance numbers.
+
+2023-03-16  Bob Weiner  <rsw@gnu.org>
+
+* hbdata.el (hbdata:build): Rename to hbdata:ebut-build and call in
+    hbdata:write.
+           (hbdata:instance-last): Rename to hbdata:ebut-instance-last.
+
+* hbut.el (hbut:label-list): Use in ibut:edit.
+  hui-em-but.el (ibut-face, hproperty:ibut-face): Add and use in
+    ibut:delimit.
+
+* hbut.el (ebut:instance-sep): Rename to 'hbut:instance-sep'.
+
+* hui.el (hui:ibut-create):
+  hbut.el (ibut:create, ibut:delimit, ibut:edit, ibut:operate): Add
+    interactive, labeled implicit button creation.
+
+* ebut:start, ebut:end: Rename to ebut:label-start and ebut:label-end.
+
+2023-03-15  Bob Weiner  <rsw@gnu.org>
+
+* hui.el (hui:ebut-buf): Rename to 'hui:hbut-buf' since not ebut-specific.
+        (hui:ebut-create, hui:ibut-create): Update call to above function.
+
 2023-03-13  Bob Weiner  <rsw@gnu.org>
 
 * test/hui-tests.el (require 'hibtypes 'klink): Force defib loads so
diff --git a/TAGS b/TAGS
index 2e76df5305..7319b74ed8 100644
--- a/TAGS
+++ b/TAGS
@@ -80,17 +80,17 @@ hactypes.el,1275
 (defact link-to-Info-node 484,19252
 (defact link-to-ibut 499,19978
 (defact link-to-kcell 549,22004
-(defact link-to-mail 569,22704
-(defact link-to-org-id 593,23871
-(defact link-to-org-id-marker 602,24184
-(defact link-to-regexp-match 612,24562
-(defact link-to-rfc 639,25633
-(defact link-to-string-match 646,25901
-(defact link-to-texinfo-node 655,26354
-(defact link-to-web-search 680,27407
-(defact man-show 688,27788
-(defact rfc-toc 696,28098
-(defact text-toc 723,29265
+(defact link-to-mail 569,22705
+(defact link-to-org-id 593,23872
+(defact link-to-org-id-marker 602,24185
+(defact link-to-regexp-match 612,24563
+(defact link-to-rfc 639,25634
+(defact link-to-string-match 646,25902
+(defact link-to-texinfo-node 655,26355
+(defact link-to-web-search 680,27408
+(defact man-show 688,27789
+(defact rfc-toc 696,28099
+(defact text-toc 723,29266
 
 hargs.el,961
 (defvar hargs:defaults 41,1440
@@ -108,18 +108,18 @@ hargs.el,961
 (defun hargs:sexpression-p 254,10551
 (defun hargs:actype-get 283,11756
 (defun hargs:at-p 290,12061
-(defun hargs:completion 412,16759
-(defun hargs:iform-read 484,19223
-(defun hargs:read 559,22165
-(defun hargs:read-buffer-name 600,23795
-(defun hargs:read-match 605,23982
-(defun hargs:select-p 638,25346
-(defvar hargs:reading-symbol 677,26859
-(defconst hargs:iform-vector680,26934
-(defconst hargs:iform-extensions-vector786,30454
-(defvar hargs:string-to-complete 845,32792
-
-hbdata.el,778
+(defun hargs:completion 410,16695
+(defun hargs:iform-read 482,19159
+(defun hargs:read 557,22101
+(defun hargs:read-buffer-name 598,23731
+(defun hargs:read-match 603,23918
+(defun hargs:select-p 636,25282
+(defvar hargs:reading-symbol 675,26795
+(defconst hargs:iform-vector678,26870
+(defconst hargs:iform-extensions-vector784,30390
+(defvar hargs:string-to-complete 843,32728
+
+hbdata.el,872
 (defun hbdata:action 66,2778
 (defun hbdata:actype 70,2894
 (defun hbdata:args 84,3427
@@ -132,17 +132,19 @@ hbdata.el,778
 (defun hbdata:mod-time 114,4314
 (defun hbdata:referent 119,4484
 (defun hbdata:search 123,4575
-(defun hbdata:build 150,5646
-(defun hbdata:get-entry 224,8879
-(defun hbdata:instance-next 233,9264
-(defun hbdata:instance-last 245,9639
-(defun hbdata:delete-entry 256,10027
-(defun hbdata:delete-entry-at-point 287,11173
-(defun hbdata:to-entry 290,11273
-(defun hbdata:apply-entry 313,12235
-(defun hbdata:to-hbdata-buffer 380,14421
-(defun hbdata:to-entry-buf 405,15446
-(defun hbdata:write 451,17255
+(defun hbdata:ebut-build 150,5646
+(defun hbdata:get-entry 224,8896
+(defun hbdata:ibut-instance 233,9281
+(defun hbdata:instance-next 260,10418
+(defun hbdata:ebut-instance-last 272,10793
+(defun hbdata:delete-entry 283,11195
+(defun hbdata:delete-entry-at-point 314,12341
+(defun hbdata:ibut-instance-last 317,12441
+(defun hbdata:to-entry 329,12933
+(defun hbdata:apply-entry 352,13895
+(defun hbdata:to-hbdata-buffer 419,16081
+(defun hbdata:to-entry-buf 443,17105
+(defun hbdata:write 489,18914
 
 hbmap.el,259
 (defvar hbmap:filename 22,642
@@ -154,140 +156,149 @@ hbmap.el,259
 (defvar hbmap:dir-user112,4112
 (defvar hbmap:dir-filename120,4405
 
-hbut.el,5042
+hbut.el,5401
 (defvar   ebut:hattr-save 41,1374
 (defun    ebut:act 45,1491
 (defun    ebut:alist 56,1893
 (defun    ebut:at-p 62,2114
 (defun    ebut:create 69,2421
-(defun    ebut:delete 91,3409
-(defun    ebut:edit 104,3868
-(defun    ebut:get 117,4375
-(defun    ebut:is-p 186,6898
-(defun    ebut:key 191,7086
-(defun    ebut:key-of-label-p 198,7324
-(defalias 'ebut:to-key-src ebut:to-key-src203,7530
-(defalias 'ebut:key-src-set-buffer ebut:key-src-set-buffer204,7587
-(defalias 'ebut:key-src-fmt ebut:key-src-fmt205,7649
-(defalias 'ebut:key-to-label ebut:key-to-label206,7704
-(defun    ebut:label-p 208,7761
-(defalias 'ebut:label-regexp ebut:label-regexp275,10368
-(defalias 'ebut:label-to-key ebut:label-to-key277,10419
-(defun    ebut:list 279,10470
-(defalias 'map-ebut map-ebut299,11303
-(defun    ebut:map 301,11336
-(defun    ebut:next-occurrence 311,11839
-(defun    ebut:operate 326,12512
-(defun    ebut:program 435,16624
-(defun    ebut:search 465,18027
-(defun    ebut:to 544,20691
-(defun    ebut:delimit 577,22024
-(defun    ebut:match-regexp 604,23059
-(defconst ebut:start 615,23481
-(defconst ebut:end 617,23576
-(defconst ebut:instance-sep 619,23669
-(defun    gbut:act 626,24009
-(defun    gbut:delete 641,24624
-(defun    gbut:ebut-program 646,24847
-(defun    gbut:file 666,25738
-(defun    gbut:get 670,25896
-(defun    gbut:help 682,26310
-(defun    gbut:label-list 693,26732
-(defun    gbut:label-p 697,26851
-(defun    gbut:to 712,27666
-(defun    gbut:key-list 730,28323
-(defun    gbut:ebut-key-list 734,28449
-(defun    gbut:ibut-key-list 748,28899
-(defun    hattr:attributes 761,29410
-(defun    hattr:clear 771,29715
-(defun    hattr:copy 782,30091
-(defun    hattr:get 793,30481
-(defun    hattr:list 797,30615
-(defun    hattr:memq 804,30887
-(defun    hattr:report 816,31318
-(defun    hattr:save 844,32344
-(defun    hattr:set 862,33196
-(defalias 'hattr:summarize hattr:summarize866,33375
-(defvar   hattr:filename868,33419
-(defconst hbut:max-len 878,33852
-(defsubst hbut:max-len 885,34093
-(defun    hbut:act 889,34243
-(defun    hbut:action 952,36937
-(defun    hbut:at-p 964,37398
-(defun    hbut:comment 977,37798
-(defvar   hbut:fill-prefix-regexps1012,38952
-(defun    hbut:fill-prefix-remove 1036,39800
-(defun    hbut:delete 1046,40192
-(defun    hbut:funcall 1061,40825
-(defun    hbut:get 1087,41888
-(defun    hbut:get-key-src 1098,42416
-(defun    hbut:is-p 1156,44703
-(defun    hbut:key 1161,44862
-(defun    hbut:to-key-src 1168,45082
-(defun    hbut:key-src-fmt 1175,45401
-(defun    hbut:key-src-set-buffer 1191,46051
-(defun    hbut:key-to-label 1212,46698
-(defun    hbut:label 1233,47382
-(defun    hbut:label-p 1240,47628
-(defun    hbut:label-regexp 1253,48403
-(defun    hbut:label-to-key 1281,49386
-(defun    hbut:map 1294,49976
-(defvar   hbut:syntax-table 1340,51791
-(defun    hbut:modify-syntax 1346,52061
-(defun    hbut:outside-comment-p 1361,52688
-(defun    hbut:rename 1369,53047
-(defun    hbut:report 1380,53453
-(defun    hbut:source 1439,55375
-(defalias 'hbut:summarize hbut:summarize1454,55948
-(defun    hbut:to 1456,55989
-(defvar   hbut:current 1463,56317
-(defconst hbut:source-prefix 1466,56422
-(defun    hbut:label-list 1471,56675
-(defun    hbut:key-list 1477,56892
-(defun    hbut:ebut-key-list 1481,57057
-(defun    hbut:ibut-key-list 1496,57566
-(defun    ibut:act 1510,58109
-(defun    ibut:alist 1521,58515
-(defun    ibut:at-p 1527,58744
-(defun    ibut:at-type-p 1570,60560
-(cl-defun ibut:create 1586,61284
-(defun    ibut:delete 1703,65168
-(defun    ibut:get 1730,66164
-(defun    ibut:is-p 1752,66981
-(defun    ibut:label-map 1758,67236
-(defun    ibut:rename 1773,68025
-(defun    ibut:label-p 1794,69036
-(defun    ibut:label-regexp 1812,70026
-(defun    ibut:label-set 1818,70317
-(defun    ibut:list 1840,71348
-(defun    ibut:key 1860,72192
-(defalias 'ibut:to-key-src ibut:to-key-src1867,72430
-(defalias 'ibut:key-to-label ibut:key-to-label1868,72477
-(defalias 'ibut:label-to-key ibut:label-to-key1869,72526
-(defalias 'map-ibut map-ibut1870,72575
-(defun    ibut:map 1872,72616
-(defun    ibut:next-occurrence 1883,73140
-(defun    ibut:previous-occurrence 1898,73885
-(defalias 'ibut:summarize ibut:summarize1913,74616
-(defun    ibut:to 1915,74657
-(defun    ibut:at-to-name-p 1962,76298
-(defun    ibut:to-name 1986,77096
-(defun    ibut:to-text 2019,78415
-(defconst ibut:label-start 2069,80462
-(defconst ibut:label-end 2071,80563
-(defvar   ibut:label-separator 2074,80663
-(defvar   ibut:label-separator-regexp 2081,80969
-(defmacro defib 2088,81308
-(def-edebug-spec defib2125,82993
-(def-edebug-spec lambda-list2130,83133
-(defalias 'ibtype:create ibtype:create2135,83251
-(defun ibtype:activate-link 2137,83286
-(defmacro defil 2149,83735
-(defmacro defal 2246,88073
-(defalias 'ibtype:create-action-link-type 
ibtype:create-action-link-type2302,90242
-(defalias 'ibtype:create-regexp-link-type 
ibtype:create-regexp-link-type2303,90293
-(defun    ibtype:def-symbol 2305,90345
-(defun    ibtype:delete 2315,90702
+(defun    ebut:delete 91,3422
+(defun    ebut:edit 104,3890
+(defun    ebut:get 117,4397
+(defun    ebut:is-p 186,6920
+(defun    ebut:key 191,7108
+(defun    ebut:key-of-label-p 198,7346
+(defalias 'ebut:to-key-src ebut:to-key-src203,7552
+(defalias 'ebut:key-src-set-buffer ebut:key-src-set-buffer204,7609
+(defalias 'ebut:key-src-fmt ebut:key-src-fmt205,7671
+(defalias 'ebut:key-to-label ebut:key-to-label206,7726
+(defun    ebut:label-p 208,7783
+(defalias 'ebut:label-regexp ebut:label-regexp275,10402
+(defalias 'ebut:label-to-key ebut:label-to-key277,10453
+(defun    ebut:list 279,10504
+(defalias 'map-ebut map-ebut301,11346
+(defun    ebut:map 303,11379
+(defun    ebut:next-occurrence 313,11894
+(defun    ebut:operate 328,12573
+(defun    ebut:program 436,16609
+(defun    ebut:search 466,18012
+(defun    ebut:to 545,20676
+(defun    ebut:delimit 578,22009
+(defun    ebut:match-regexp 605,23077
+(defconst ebut:label-start 616,23517
+(defconst ebut:label-end 618,23618
+(defconst hbut:instance-sep 620,23717
+(defun    gbut:act 627,24057
+(defun    gbut:delete 642,24672
+(defun    gbut:ebut-program 647,24895
+(defun    gbut:file 667,25786
+(defun    gbut:get 671,25944
+(defun    gbut:help 683,26358
+(defun    gbut:label-list 694,26780
+(defun    gbut:label-p 698,26899
+(defun    gbut:to 713,27714
+(defun    gbut:key-list 731,28371
+(defun    gbut:ebut-key-list 735,28497
+(defun    gbut:ibut-key-list 749,28947
+(defun    hattr:attributes 762,29456
+(defun    hattr:clear 772,29761
+(defun    hattr:copy 783,30137
+(defun    hattr:get 794,30527
+(defun    hattr:list 798,30661
+(defun    hattr:memq 805,30933
+(defun    hattr:report 817,31364
+(defun    hattr:save 845,32390
+(defun    hattr:set 863,33242
+(defalias 'hattr:summarize hattr:summarize867,33421
+(defvar   hattr:filename869,33465
+(defconst hbut:max-len 879,33898
+(defsubst hbut:max-len 886,34139
+(defun    hbut:act 890,34289
+(defun    hbut:action 953,36992
+(defun    hbut:at-p 965,37453
+(defun    hbut:comment 978,37853
+(defvar   hbut:fill-prefix-regexps1013,39007
+(defun    hbut:fill-prefix-remove 1037,39855
+(defun    hbut:delete 1047,40247
+(defun    hbut:funcall 1062,40880
+(defun    hbut:get 1088,41943
+(defun    hbut:get-key-src 1099,42471
+(defun    hbut:is-p 1157,44758
+(defun    hbut:key 1162,44917
+(defun    hbut:to-key-src 1169,45137
+(defun    hbut:key-src-fmt 1176,45456
+(defun    hbut:key-src-set-buffer 1192,46106
+(defun    hbut:key-to-label 1213,46753
+(defun    hbut:label 1234,47437
+(defun    hbut:label-list 1250,48051
+(defun    hbut:label-p 1254,48205
+(defun    hbut:label-regexp 1267,48980
+(defun    hbut:label-to-key 1301,50198
+(defun    hbut:map 1314,50788
+(defvar   hbut:syntax-table 1370,52975
+(defun    hbut:modify-syntax 1376,53245
+(defun    hbut:outside-comment-p 1391,53872
+(defun    hbut:rename 1399,54231
+(defun    hbut:report 1410,54637
+(defun    hbut:source 1469,56571
+(defalias 'hbut:summarize hbut:summarize1484,57144
+(defun    hbut:to 1486,57185
+(defvar   hbut:current 1493,57513
+(defconst hbut:source-prefix 1496,57618
+(defun    hbut:key-list 1503,57949
+(defun    hbut:ebut-key-list 1507,58114
+(defun    hbut:ibut-key-list 1522,58623
+(defun    ibut:act 1536,59166
+(defun    ibut:alist 1547,59572
+(defun    ibut:at-p 1553,59801
+(defun    ibut:at-type-p 1597,61640
+(cl-defun ibut:create 1613,62364
+(def-edebug-spec cl-defun1737,66643
+(def-edebug-spec lambda-key-list1742,66790
+(defun    ibut:delete 1748,66962
+(defun    ibut:delimit 1775,67968
+(defun    ibut:edit 1802,69037
+(defun    ibut:get 1813,69511
+(defun    ibut:is-p 1835,70328
+(defun    ibut:label-map 1841,70583
+(defun    ibut:label-key-match 1856,71372
+(defun    ibut:label-p 1866,71760
+(defun    ibut:label-regexp 1884,72750
+(defun    ibut:label-set 1890,73041
+(defun    ibut:label-sort-keys 1912,74072
+(defun    ibut:list 1931,74702
+(defun    ibut:key 1953,75553
+(defalias 'ibut:to-key-src ibut:to-key-src1960,75791
+(defalias 'ibut:key-to-label ibut:key-to-label1961,75838
+(defalias 'ibut:label-to-key ibut:label-to-key1962,75887
+(defalias 'map-ibut map-ibut1963,75936
+(defun    ibut:map 1965,75977
+(defun    ibut:next-occurrence 1983,76656
+(defun    ibut:operate 1998,77401
+(defun    ibut:insert-text 2110,81604
+(defun    ibut:previous-occurrence 2139,83041
+(defun    ibut:program 2154,83772
+(defun    ibut:rename 2184,85175
+(defalias 'ibut:summarize ibut:summarize2205,86186
+(defun    ibut:to 2207,86227
+(defun    ibut:at-to-name-p 2254,87868
+(defun    ibut:to-name 2278,88666
+(defun    ibut:to-text 2311,89985
+(defconst ibut:label-start 2361,92032
+(defconst ibut:label-end 2363,92133
+(defvar   ibut:label-separator 2366,92233
+(defvar   ibut:label-separator-regexp 2374,92550
+(defmacro defib 2381,92889
+(def-edebug-spec defib2418,94574
+(def-edebug-spec lambda-list2423,94714
+(defalias 'ibtype:create ibtype:create2428,94832
+(defun ibtype:activate-link 2430,94867
+(defmacro defil 2442,95316
+(defmacro defal 2539,99654
+(defalias 'ibtype:create-action-link-type 
ibtype:create-action-link-type2595,101823
+(defalias 'ibtype:create-regexp-link-type 
ibtype:create-regexp-link-type2596,101874
+(defun    ibtype:def-symbol 2598,101926
+(defun    ibtype:delete 2608,102283
 
 hgnus.el,110
 (defun Gnus-init 54,1683
@@ -439,8 +450,8 @@ hibtypes.el,1664
 (defconst action:start 1444,68467
 (defconst action:end 1447,68576
 (defib action 1456,68926
-(defun action:help 1554,73503
-(defib completion 1581,74595
+(defun action:help 1554,73534
+(defib completion 1581,74626
 
 hinit.el,145
 (defvar   hyperb:user-email 22,623
@@ -1196,49 +1207,49 @@ hui-menu.el,638
 (defun hyperbole-menubar-menu 283,10988
 (defun hyperbole-popup-menu 306,12009
 (defun infodock-hyperbole-menu 313,12277
-(defvar hui-menu-max-list-length 475,18516
-(defvar hui-menu-order-explicit-buttons 478,18631
+(defvar hui-menu-max-list-length 476,18552
+(defvar hui-menu-order-explicit-buttons 479,18667
 
 hui-mini.el,1412
-(defvar hui:menu-exit-hyperbole 30,930
-(defvar hui:menu-select 33,1082
-(defvar hui:menu-quit 35,1193
-(defvar hui:menu-abort 37,1314
-(defvar hui:menu-top 39,1402
-(defvar hui:menu-keys 42,1503
-(defvar hui:menu-p 46,1667
-(defvar hui:menus 49,1749
-(defun hyperbole 60,2199
-(defun hyperbole-demo 91,3429
-(defun hyperbole-set-key 98,3665
-(defun hui:menu-hyperbole-prefix 141,5594
-(defun hui:menu-act 145,5779
-(defun hui:get-keys 192,7597
-(defun hui:menu-get-keys 204,7963
-(defun hui:menu-backward-item 232,9051
-(defun hui:menu-doc 256,9931
-(defun hui:menu-exit-hyperbole 274,10831
-(defun hui:menu-enter 280,11006
-(defalias 'hui:menu-quit hui:menu-quit296,11561
-(defalias 'hui:menu-abort hui:menu-abort297,11606
-(defalias 'hui:menu-top hui:menu-top298,11651
-(defalias 'hui:menu-select hui:menu-select299,11696
-(defun hui:menu-forward-item 301,11742
-(defun hui:menu-help 325,12616
-(defun hui:menu-item-key 351,13596
-(defun hui:menu-item-keys 366,14156
-(defun hui:menu-choose 373,14477
-(defun hui:menu-to-personal-section 442,17233
-(defun hui:bottom-window 456,17897
-(defun hui:menu-item 466,18226
-(defun hui:menu-line 509,20234
-(defun hui:menu-multi-line 524,20869
-(defun hui:menu-web-search 550,21737
-(defun hui-search-web 571,22354
-(defvar hui:menu-mode-map 593,23213
-(defun hyperbole-minibuffer-menu 621,24652
-(defcustom hui:menu-to906,41020
-(defcustom hui:doc-a-z945,42523
+(defvar hui:menu-exit-hyperbole 30,929
+(defvar hui:menu-select 33,1081
+(defvar hui:menu-quit 35,1192
+(defvar hui:menu-abort 37,1313
+(defvar hui:menu-top 39,1401
+(defvar hui:menu-keys 42,1502
+(defvar hui:menu-p 46,1666
+(defvar hui:menus 49,1748
+(defun hyperbole 60,2198
+(defun hyperbole-demo 91,3428
+(defun hyperbole-set-key 98,3664
+(defun hui:menu-hyperbole-prefix 141,5593
+(defun hui:menu-act 145,5778
+(defun hui:get-keys 192,7596
+(defun hui:menu-get-keys 204,7962
+(defun hui:menu-backward-item 232,9050
+(defun hui:menu-doc 256,9930
+(defun hui:menu-exit-hyperbole 274,10830
+(defun hui:menu-enter 280,11005
+(defalias 'hui:menu-quit hui:menu-quit296,11560
+(defalias 'hui:menu-abort hui:menu-abort297,11605
+(defalias 'hui:menu-top hui:menu-top298,11650
+(defalias 'hui:menu-select hui:menu-select299,11695
+(defun hui:menu-forward-item 301,11741
+(defun hui:menu-help 325,12615
+(defun hui:menu-item-key 351,13595
+(defun hui:menu-item-keys 366,14155
+(defun hui:menu-choose 373,14476
+(defun hui:menu-to-personal-section 442,17232
+(defun hui:bottom-window 456,17896
+(defun hui:menu-item 466,18225
+(defun hui:menu-line 509,20233
+(defun hui:menu-multi-line 524,20868
+(defun hui:menu-web-search 550,21736
+(defun hui-search-web 571,22353
+(defvar hui:menu-mode-map 593,23212
+(defun hyperbole-minibuffer-menu 621,24651
+(defcustom hui:menu-to908,41115
+(defcustom hui:doc-a-z947,42618
 
 hui-mouse.el,3073
 (defvar hmouse-set-point-command 58,2118
@@ -1469,7 +1480,7 @@ hui-window.el,3322
 (defun hmouse-x-coord 1239,55178
 (defun hmouse-y-coord 1263,55975
 
-hui.el,2199
+hui.el,2235
 (defcustom hui:hbut-delete-confirm-flag 39,1219
 (defcustom hui:ebut-prompt-for-action 44,1382
 (defun hui-copy-to-register 55,1804
@@ -1480,55 +1491,56 @@ hui.el,2199
 (defun hui:delimited-selectable-thing-and-bounds 244,9693
 (defun hui:ebut-act 267,10737
 (defun hui:ebut-create 282,11261
-(defun hui:ebut-delete 314,12605
-(defun hui:ebut-edit-region 339,13733
-(defun hui:ebut-edit 359,14631
-(defun hui:ebut-rename 408,16430
-(defun hui:ebut-search 467,18811
-(defun hui:gbut-create 501,20235
-(defun hui:gbut-delete 543,21948
-(defun hui:gbut-edit 558,22598
-(defun hui:gbut-rename 647,26039
-(defun hui:gibut-create 659,26502
-(defun hui:hbut-act 685,27431
-(defun hui:hbut-current-act 693,27804
-(defun hui:hbut-delete 703,28178
-(defun hui:hbut-help 743,29939
-(defun hui:hbut-label 784,31425
-(defun hui:hbut-label-default 795,31922
-(defun hui:hbut-rename 810,32657
-(defun hui:hbut-report 820,33013
-(defalias 'hui:hbut-summarize hui:hbut-summarize831,33365
-(defun hui:ibut-act 833,33415
-(defun hui:ibut-edit 848,33981
-(defun hui:ibut-label-create 918,36658
-(defun hui:ibut-rename 956,38533
-(defun hui:link 990,39690
-(defun hui:link-directly 994,39850
-(defun hui:action 1061,42450
-(defun hui:actype 1114,44183
-(defun hui:buf-writable-err 1133,45176
-(defvar hui:ignore-buffers-regexp 1153,46039
-(defun hui:ebut-buf 1156,46209
-(defun hui:ebut-delete-op 1181,46971
-(defun hui:ebut-message 1212,48224
-(defun hui:ebut-unmark 1223,48616
-(defun hui:file-find 1283,51057
-(defun hui:hbut-operate 1290,51327
-(defun hui:hbut-term-highlight 1315,52442
-(defun hui:hbut-term-unhighlight 1329,52844
-(defun hui:help-ebut-highlight 1338,53130
-(defun hui:htype-delete 1344,53378
-(defun hui:htype-help 1355,53785
-(defun hui:htype-help-current-window 1406,55553
-(defun hui:ibut-delete-op 1413,55918
-(defun hui:ibut-message 1437,57021
-(defun hui:key-dir 1448,57425
-(defun hui:key-src 1457,57773
-(defun hui:link-create 1466,58144
-(defun hui:link-possible-types 1483,59022
-(defun hui:list-remove-text-properties 1614,64320
-(defvar hui:ebut-label-prev 1624,64710
+(defun hui:ebut-delete 314,12573
+(defun hui:ebut-edit-region 339,13713
+(defun hui:ebut-edit 359,14611
+(defun hui:ebut-rename 408,16410
+(defun hui:ebut-search 467,18791
+(defun hui:gbut-create 501,20227
+(defun hui:gbut-delete 543,21940
+(defun hui:gbut-edit 558,22590
+(defun hui:gbut-rename 647,26031
+(defun hui:gibut-create 659,26494
+(defun hui:hbut-act 687,27534
+(defun hui:hbut-buf 695,27907
+(defun hui:hbut-current-act 720,28669
+(defun hui:hbut-delete 730,29043
+(defun hui:hbut-help 770,30816
+(defun hui:hbut-label 811,32302
+(defun hui:hbut-label-default 822,32799
+(defun hui:hbut-rename 837,33534
+(defun hui:hbut-report 847,33890
+(defalias 'hui:hbut-summarize hui:hbut-summarize858,34242
+(defun hui:ibut-act 860,34292
+(defun hui:ibut-create 875,34858
+(defun hui:ibut-edit 906,36153
+(defun hui:ibut-label-create 976,38830
+(defun hui:ibut-rename 1014,40705
+(defun hui:link 1048,41862
+(defun hui:link-directly 1052,42022
+(defun hui:action 1119,44622
+(defun hui:actype 1172,46355
+(defun hui:buf-writable-err 1191,47348
+(defvar hui:ignore-buffers-regexp 1211,48211
+(defun hui:ebut-delete-op 1214,48381
+(defun hui:ebut-message 1245,49634
+(defun hui:ebut-unmark 1256,50038
+(defun hui:file-find 1316,52503
+(defun hui:hbut-operate 1323,52773
+(defun hui:hbut-term-highlight 1348,53888
+(defun hui:hbut-term-unhighlight 1362,54290
+(defun hui:help-ebut-highlight 1371,54576
+(defun hui:htype-delete 1377,54824
+(defun hui:htype-help 1388,55231
+(defun hui:htype-help-current-window 1439,56999
+(defun hui:ibut-delete-op 1446,57364
+(defun hui:ibut-message 1470,58467
+(defun hui:key-dir 1481,58871
+(defun hui:key-src 1490,59219
+(defun hui:link-create 1499,59590
+(defun hui:link-possible-types 1516,60468
+(defun hui:list-remove-text-properties 1647,65766
+(defvar hui:ebut-label-prev 1657,66156
 
 hvar.el,272
 (defvar var::append-list 34,1095
@@ -1581,7 +1593,7 @@ hvm.el,874
 (defun vm-force-mode-line-update 525,19036
 (defvar Vm-msg-start-regexp 539,19592
 
-hypb.el,2530
+hypb.el,2566
 (defconst hypb:help-buf-prefix 28,889
 (defcustom hypb:rgrep-command32,1035
 (defun hypb:activate-interaction-log-mode 81,2925
@@ -1604,48 +1616,49 @@ hypb.el,2530
 (define-derived-mode hypb:fgrep-git-log-mode 462,19348
 (defun hypb:file-major-mode 468,19695
 (defun hypb:filter-directories 478,20087
-(defun hypb:format-quote 493,20748
-(defun hypb:get-completion 507,21222
-(defun hypb:get-raw-syntax-descriptor 530,22262
-(defun hypb:glob-to-regexp 535,22481
-(defun hypb:goto-marker 546,22939
-(defun hypb:grep-git-log 564,23580
-(defun hypb:help-buf-name 571,23955
-(defun hypb:helm-apropos 580,24326
-(defun hypb:helm-info 589,24670
-(defun hypb:hkey-help-file 597,24989
-(defun hypb:indirect-function 611,25542
-(defun hypb:insert-region 625,26094
-(defun hypb:locate 642,26865
-(defun hypb:map-plist 674,28248
-(defun hypb:map-vector 680,28467
-(defun hypb:mark-object 693,28953
-(defun hypb:maximize-window-height 703,29342
-(defun hypb:object-p 716,29823
-(defun hypb:readable-directories 723,30073
-(defun hypb:require-package 733,30509
-(defun hypb:remove-lines 746,31103
-(defun hypb:return-process-output 752,31333
-(defun hypb:rgrep 771,32040
-(defun hypb:save-lines 808,33753
-(defmacro hypb:save-selected-window-and-input-focus 814,33981
-(defun hypb:select-window-frame 821,34310
-(defun hypb:set-raw-syntax-descriptor 828,34626
-(defun hypb:straight-package-plist 842,35227
-(defun hypb:string-count-matches 852,35751
-(defun hypb:supercite-p 880,36759
-(defun hypb:toggle-isearch-invisible 894,37210
-(defun hypb:uuid 914,38134
-(defun hypb:user-name 938,38723
-(defun hypb:window-list 944,38948
-(defvar hypb:home-page 955,39520
-(defvar hypb:hyperbole-banner-keymap958,39624
-(defun hypb:display-file-with-logo 967,39940
-(defun hypb:browse-home-page 989,40936
-(defun hypb:insert-hyperbole-banner 999,41261
-(defun hypb:locate-pathnames 1030,42679
-(defun hypb:oct-to-int 1037,42913
-(define-button-type 'hyperbole-banner)hyperbole-banner1054,43501
+(defun hypb:format-args 493,20748
+(defun hypb:format-quote 497,20930
+(defun hypb:get-completion 511,21404
+(defun hypb:get-raw-syntax-descriptor 534,22444
+(defun hypb:glob-to-regexp 539,22663
+(defun hypb:goto-marker 550,23121
+(defun hypb:grep-git-log 568,23762
+(defun hypb:help-buf-name 575,24137
+(defun hypb:helm-apropos 584,24508
+(defun hypb:helm-info 593,24852
+(defun hypb:hkey-help-file 601,25171
+(defun hypb:indirect-function 615,25724
+(defun hypb:insert-region 629,26276
+(defun hypb:locate 646,27047
+(defun hypb:map-plist 678,28430
+(defun hypb:map-vector 684,28649
+(defun hypb:mark-object 697,29135
+(defun hypb:maximize-window-height 707,29524
+(defun hypb:object-p 720,30005
+(defun hypb:readable-directories 727,30255
+(defun hypb:require-package 737,30691
+(defun hypb:remove-lines 750,31285
+(defun hypb:return-process-output 756,31515
+(defun hypb:rgrep 775,32222
+(defun hypb:save-lines 812,33935
+(defmacro hypb:save-selected-window-and-input-focus 818,34163
+(defun hypb:select-window-frame 825,34492
+(defun hypb:set-raw-syntax-descriptor 832,34808
+(defun hypb:straight-package-plist 846,35409
+(defun hypb:string-count-matches 856,35933
+(defun hypb:supercite-p 884,36941
+(defun hypb:toggle-isearch-invisible 898,37392
+(defun hypb:uuid 918,38316
+(defun hypb:user-name 942,38905
+(defun hypb:window-list 948,39130
+(defvar hypb:home-page 959,39702
+(defvar hypb:hyperbole-banner-keymap962,39806
+(defun hypb:display-file-with-logo 971,40122
+(defun hypb:browse-home-page 993,41118
+(defun hypb:insert-hyperbole-banner 1003,41443
+(defun hypb:locate-pathnames 1034,42861
+(defun hypb:oct-to-int 1041,43095
+(define-button-type 'hyperbole-banner)hyperbole-banner1058,43683
 
 hyperbole.el,821
 (defconst hyperbole-loading 81,3564
@@ -1876,36 +1889,38 @@ hypb-maintenance.el,150
 (defconst hypb:hy-news-footer37,928
 (defun hypb:web-repo-update 45,1016
 
-hui-em-but.el,1154
-(defcustom hproperty:but-highlight-flag 40,1129
-(defcustom hproperty:but-emphasize-flag 45,1299
-(defcustom hproperty:but-flash-time 50,1474
-(defcustom hproperty:but-flash-time-seconds 56,1768
-(defface hbut-flash61,1893
-(defcustom hproperty:flash-face 76,2403
-(defcustom hproperty:highlight-face 82,2580
-(defface hbut-face88,2741
-(defcustom hproperty:but-face 96,3031
-(defface hbut-item-face102,3196
-(defcustom hproperty:item-face 117,3721
-(defun hproperty:but-add 132,4236
-(defun hproperty:but-clear 140,4653
-(defun hproperty:but-create 151,5010
-(defun hproperty:but-create-all 165,5661
-(defun hproperty:but-create-on-yank 177,6274
-(defun hproperty:but-delete 184,6514
-(defun hproperty:but-get 192,6813
-(defsubst hproperty:list-cycle 201,7067
-(defconst hproperty:color-list210,7448
-(defvar hproperty:color-ptr 214,7541
-(defconst hproperty:good-colors217,7645
-(defun hproperty:cycle-but-color 232,8263
-(defun hproperty:but-p 244,8697
-(defun hproperty:set-but-face 250,8948
-(defun hproperty:but-flash 254,9073
-(defun hproperty:select-item 275,9835
-(defun hproperty:select-line 286,10244
-(defvar hproperty:item-button 298,10746
+hui-em-but.el,1224
+(defcustom hproperty:but-highlight-flag 40,1128
+(defcustom hproperty:but-emphasize-flag 45,1298
+(defcustom hproperty:but-flash-time 50,1473
+(defcustom hproperty:but-flash-time-seconds 56,1767
+(defface hbut-flash61,1892
+(defcustom hproperty:flash-face 76,2402
+(defcustom hproperty:highlight-face 82,2579
+(defface hbut-face88,2740
+(defcustom hproperty:but-face 96,3039
+(defface hbut-item-face102,3207
+(defcustom hproperty:item-face 117,3737
+(defface ibut-face123,3913
+(defcustom hproperty:ibut-face 131,4214
+(defun hproperty:but-add 146,4727
+(defun hproperty:but-clear 154,5144
+(defun hproperty:but-create 165,5501
+(defun hproperty:but-create-all 179,6152
+(defun hproperty:but-create-on-yank 191,6765
+(defun hproperty:but-delete 198,7005
+(defun hproperty:but-get 206,7304
+(defsubst hproperty:list-cycle 215,7558
+(defconst hproperty:color-list224,7939
+(defvar hproperty:color-ptr 228,8032
+(defconst hproperty:good-colors231,8136
+(defun hproperty:cycle-but-color 246,8754
+(defun hproperty:but-p 258,9188
+(defun hproperty:set-but-face 264,9439
+(defun hproperty:but-flash 268,9564
+(defun hproperty:select-item 289,10326
+(defun hproperty:select-line 300,10735
+(defvar hproperty:item-button 312,11237
 
 hui-register.el,214
 (cl-defstruct hui-register-but31,784
diff --git a/hactypes.el b/hactypes.el
index 546b188126..903de92b5d 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:     11-Mar-23 at 13:04:56 by Bob Weiner
+;; Last-Mod:     29-Mar-23 at 18:14:35 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -561,7 +561,7 @@ If CELL-REF is nil, show the first cell in the view."
             (kotl-mode:goto-cell cell-ref)
           (kotl-mode:beginning-of-buffer))
         (recenter 0))
-       ((and (stringp cell-ref) (> (length cell-ref) 0)
+       ((and (stringp cell-ref) (> (length cell-ref) 0)
              (eq ?| (aref cell-ref 0)))
         ;; Activate view spec in current window.
         (kotl-mode:goto-cell cell-ref))))
diff --git a/hargs.el b/hargs.el
index ac253b6a16..5f9d59138b 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:     26-Feb-23 at 10:31:04 by Bob Weiner
+;; Last-Mod:     16-Mar-23 at 21:41:09 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -363,12 +363,10 @@ Handles all of the interactive argument types that 
`hargs:iform-read' does."
        ((eq hargs:reading-type 'string)
         (or (hargs:delimited "\"" "\"") (hargs:delimited "'" "'")
             (hargs:delimited "`" "'")))
-       ((or (eq hargs:reading-type 'actype)
-            (eq hargs:reading-type 'actypes))
+       ((memq hargs:reading-type '(actype actypes))
         (let ((name (hargs:find-tag-default)))
           (car (set:member name (htype:names 'actypes)))))
-       ((or (eq hargs:reading-type 'ibtype)
-            (eq hargs:reading-type 'ibtypes))
+       ((memq hargs:reading-type '(ibtype ibtypes))
         (let ((name (hargs:find-tag-default)))
           (car (set:member name (htype:names 'ibtypes)))))
        ((eq hargs:reading-type 'sexpression) (hargs:sexpression-p))
diff --git a/hbdata.el b/hbdata.el
index 943a2872fa..a1362b235a 100644
--- a/hbdata.el
+++ b/hbdata.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     2-Apr-91
-;; Last-Mod:     29-Jan-23 at 02:34:21 by Bob Weiner
+;; Last-Mod:     29-Mar-23 at 21:04:06 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -147,11 +147,11 @@ Search is case-insensitive.  Return list with elements:
 ;;; Button data operators
 ;;; ------------------------------------------------------------------------
 
-(defun hbdata:build (&optional mod-lbl-key but-sym)
+(defun hbdata:ebut-build (&optional mod-lbl-key but-sym)
   "Construct button data from optional MOD-LBL-KEY and BUT-SYM.
 Modify BUT-SYM attributes.  MOD-LBL-KEY nil means create a new
 entry, otherwise modify existing one.  Nil BUT-SYM means use
-`hbut:current'  If successful, return a cons of
+`hbut:current'.  If successful, return a cons of
  (button-data . button-instance-str), else nil."
   (let* ((b (hattr:copy (or but-sym 'hbut:current) 'but))
         (l (hattr:get b 'loc))
@@ -174,19 +174,19 @@ entry, otherwise modify existing one.  Nil BUT-SYM means 
use
                    mod-time    (htz:date-sortable-gmt)
                    entry       (cons new-key (cdr entry)))
              (hbdata:delete-entry-at-point)
-             (when (setq lbl-instance (hbdata:instance-last new-key loc dir))
-               (setq lbl-instance (concat ebut:instance-sep
+             (when (setq lbl-instance (hbdata:ebut-instance-last new-key loc 
dir))
+               (setq lbl-instance (concat hbut:instance-sep
                                           (int-to-string (1+ lbl-instance))))
                ;; This expression is needed to ensure that the highest
                ;; numbered instance of a label appears before
-               ;; other instances, so 'hbdata:instance-last' will work.
+               ;; other instances, so 'hbdata:ebut-instance-last' will work.
                (when (hbdata:to-entry-buf loc dir)
                  (forward-line 1))))
-         (let ((inst-num (hbdata:instance-last new-key loc dir)))
-           (setq lbl-instance (if inst-num
-                                  (hbdata:instance-next
-                                   (concat new-key ebut:instance-sep
-                                           (int-to-string inst-num))))))))
+         (let ((inst-num (hbdata:ebut-instance-last new-key loc dir)))
+           (setq lbl-instance (when inst-num
+                                (hbdata:instance-next
+                                 (concat new-key hbut:instance-sep
+                                         (int-to-string inst-num))))))))
       (when (or entry (not mod-lbl-key))
        (hattr:set b 'lbl-key (concat new-key lbl-instance))
        (hattr:set b 'loc loc)
@@ -230,20 +230,47 @@ class `hbdata' to operate on the entry."
    (lambda () (read (current-buffer)))
    lbl-key key-src directory))
 
+(defun hbdata:ibut-instance (&optional orig-lbl-key but-sym)
+  "Return ibutton instance number string from optional ORIG-LBL-KEY and 
BUT-SYM.
+ORIG-LBL-KEY nil means create a new ibutton; otherwise modify an
+existing one.  BUT-SYM nil means use `hbut:current'.  If
+successful, return a button instance string to append to button
+label or t when first instance."
+  (let* ((b (hattr:copy (or but-sym 'hbut:current) 'but))
+        (l (hattr:get b 'loc))
+        (key (or orig-lbl-key (hattr:get b 'lbl-key)))
+        (new-key (if orig-lbl-key (hattr:get b 'lbl-key) key))
+        (lbl-instance)
+        loc dir)
+    (or (when l
+         (setq loc (if (bufferp l) l (file-name-nondirectory l))
+               dir (if (bufferp l) nil (file-name-directory l)))
+         (if orig-lbl-key
+             (when (setq lbl-instance (hbdata:ibut-instance-last new-key loc 
dir))
+               (setq lbl-instance (concat hbut:instance-sep
+                                          (int-to-string (1+ lbl-instance)))))
+           (let ((inst-num (hbdata:ibut-instance-last new-key loc dir)))
+             (setq lbl-instance (when inst-num
+                                  (hbdata:instance-next
+                                   (concat new-key hbut:instance-sep
+                                           (int-to-string inst-num)))))))
+         lbl-instance)
+       t)))
+
 (defun hbdata:instance-next (lbl-key)
   "Return string for button instance number following LBL-KEY's.
 Nil if LBL-KEY is nil."
   (and lbl-key
        (if (string-match
-           (concat (regexp-quote ebut:instance-sep) "[0-9]+$") lbl-key)
-          (concat ebut:instance-sep
+           (concat (regexp-quote hbut:instance-sep) "[0-9]+$") lbl-key)
+          (concat hbut:instance-sep
                   (int-to-string
                    (1+ (string-to-number
                         (substring lbl-key (1+ (match-beginning 0)))))))
         ":2")))
 
-(defun hbdata:instance-last (lbl-key key-src &optional directory)
-  "Return highest instance number for repeated button label.
+(defun hbdata:ebut-instance-last (lbl-key key-src &optional directory)
+  "Return highest instance number for repeated explicit button label.
 1 if not repeated, nil if no instance.
 Utilize arguments LBL-KEY, KEY-SRC and optional DIRECTORY."
   (hbdata:apply-entry
@@ -287,6 +314,18 @@ If the hbdata buffer is blank/empty, kill it and remove 
the associated file."
 (defun hbdata:delete-entry-at-point ()
   (delete-region (point) (progn (forward-line 1) (point))))
 
+(defun hbdata:ibut-instance-last (lbl-key key-src &optional directory)
+  "Return highest instance number for repeated implicit button label.
+1 if not repeated, nil if no instance.
+Utilize arguments LBL-KEY, KEY-SRC and optional DIRECTORY."
+  (let ((key (car (ibut:label-sort-keys (ibut:label-key-match lbl-key)))))
+    (cond ((null key) nil)
+         ((string-match (concat (regexp-quote hbut:instance-sep)
+                                "\\([0-9]+\\)\\'")
+                        key)
+          (string-to-number (match-string 1 key)))
+         (t 1))))
+
 (defun hbdata:to-entry (but-key key-src &optional directory instance)
   "Return button data entry indexed by BUT-KEY, KEY-SRC, optional DIRECTORY.
 Return nil if entry is not found.  Leave point at start of entry when
@@ -317,7 +356,7 @@ Hbdata is given by LBL-KEY, KEY-SRC and optional DIRECTORY.
 With optional CREATE-FLAG, if no such line exists, insert a new file entry at
 the beginning of the hbdata file (which is created if necessary).
 INSTANCE-FLAG non-nil means search for any button instance matching LBL-KEY and
-call FUNC with point right after any `ebut:instance-sep' in match.
+call FUNC with point right after any `hbut:instance-sep' in match.
 Return value of evaluation when a matching entry is found or nil."
   (let (found
        rtn
@@ -367,7 +406,7 @@ Return value of evaluation when a matching entry is found 
or nil."
              (if (if instance-flag
                      (re-search-forward
                       (concat "\n(\"" qkey "["
-                              ebut:instance-sep "\"]") end t)
+                              hbut:instance-sep "\"]") end t)
                    (search-forward (concat "\n(\"" lbl-key "\"") end t))
                  (progn
                    (unless instance-flag
@@ -401,7 +440,6 @@ one and return buffer, otherwise return nil."
        (hbmap:dir-add (file-name-directory file)))
       buf)))
 
-
 (defun hbdata:to-entry-buf (key-src &optional directory create)
   "Move point to end of line in but data buffer matching KEY-SRC.
 Use hbdata file in KEY-SRC's directory, or optional DIRECTORY or if nil, use
@@ -454,7 +492,7 @@ ORIG-LBL-KEY nil means create a new entry, otherwise modify 
existing one.
 BUT-SYM nil means use `hbut:current'.  If successful, return
 a button instance string to append to button label or t when first instance.
 On failure, return nil."
-  (let ((cons (hbdata:build orig-lbl-key but-sym))
+  (let ((cons (hbdata:ebut-build orig-lbl-key but-sym))
        entry lbl-instance)
     (unless (or (and buffer-file-name (not (file-writable-p buffer-file-name)))
                (null cons))
diff --git a/hbut.el b/hbut.el
index c38dd5fec1..7d8a3dc986 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:     11-Mar-23 at 17:16:43 by Bob Weiner
+;; Last-Mod:     29-Mar-23 at 22:25:14 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -68,7 +68,7 @@ button delimiters."
 
 (defun    ebut:create (&optional but-sym)
   "Create Hyperbole explicit button based on optional BUT-SYM.
-Default is `hbut:current'.
+Default is the symbol hbut:current.
 Button should hold the following attributes (see `hattr:set'):
    lbl-key (normalized button label string),
    loc     (filename or buffer where button is located),
@@ -79,7 +79,7 @@ Button should hold the following attributes (see `hattr:set'):
             argument of the button lbl-key, args may be nil).
 
 If successful, return any instance number to append to button label
-except when instance number would be 1, then return t.  On failure,
+except when instance number would be \"1\", then return t.  On failure,
 return nil.
 
 If successful, leave point in button data buffer, so caller should use
@@ -90,7 +90,7 @@ If successful, leave point in button data buffer, so caller 
should use
 
 (defun    ebut:delete (&optional but-sym)
   "Delete Hyperbole explicit button based on optional BUT-SYM.
-Default is `hbut:current'.
+Default is the symbol hbut:current.
 Return entry deleted (a list of attribute values) or nil."
   (unless but-sym
     (setq but-sym (ebut:at-p)))
@@ -102,7 +102,7 @@ Return entry deleted (a list of attribute values) or nil."
       entry)))
 
 (defun    ebut:edit (&optional lbl-key but-sym)
-  "Edit existing Hyperbole button from optional LBL-KEY and BUT-SYM.
+  "Edit explicit Hyperbole button from optional LBL-KEY and BUT-SYM.
 Defaults are the key for any button label at point and `hbut:current'.
 If successful, return button's instance number, except when instance
 number is 1, then return t.  On failure, as when button does not exist,
@@ -221,8 +221,8 @@ to two lines."
        (quoted "\\(^\\|[^\\{$]\\)")
        (hbut:max-len hbut:max-len)
        npoint start lbl-key end but-start but-end start-regexp end-regexp)
-    (unless start-delim (setq start-delim ebut:start))
-    (unless end-delim (setq end-delim ebut:end))
+    (unless start-delim (setq start-delim ebut:label-start))
+    (unless end-delim (setq end-delim ebut:label-end))
     (setq npoint (+ opoint (length start-delim))
          start-regexp (regexp-quote start-delim)
          end-regexp (regexp-quote end-delim))
@@ -282,7 +282,9 @@ Remove duplicate labels if optional LOC-P is omitted.  With 
LOC-P, return
 list of elements (label start end) where start and end are the buffer
 positions at which the button delimiter begins and ends."
   (interactive)
-  (setq file (if file (and (file-exists-p file) (find-file-noselect file))
+  (setq file (if file
+                (when (file-exists-p file)
+                  (find-file-noselect file))
               (current-buffer)))
   (when file
     (set-buffer file)
@@ -306,7 +308,7 @@ considered.
 BUT-FUNC must take precisely three arguments: the button label, the
 start position of the delimited button label and its end position (positions
 include delimiters when INCLUDE-DELIMS is non-nil)."
-  (hbut:map but-func ebut:start ebut:end regexp-match include-delims))
+  (hbut:map but-func ebut:label-start ebut:label-end regexp-match 
include-delims))
 
 (defun    ebut:next-occurrence (lbl-key &optional buffer)
   "Move point to next occurrence of button with LBL-KEY in optional BUFFER.
@@ -321,12 +323,10 @@ move to the first occurrence of the button."
          (error "(ebut:next-occurrence): Invalid buffer arg: %s" buffer)
        (switch-to-buffer buffer)))
   (if (re-search-forward (ebut:label-regexp lbl-key) nil t)
-      (goto-char (+ (match-beginning 0) (length ebut:start)))))
+      (goto-char (+ (match-beginning 0) (length ebut:label-start)))))
 
 (defun    ebut:operate (curr-label new-label)
-  "Operate on and modify properties of an explicit button given by CURR-LABEL.
-When NEW-LABEL is non-nil, this is substituted for CURR-LABEL and the
-associated button is modified.  Otherwise, a new button is created.
+  "Create an in-buffer ebutton named CURR-LABEL.  Modify if NEW-LABEL is given.
 
 If CURR-LABEL is nil, the text in the active region is used as the
 button label, if any, otherwise, an error is signaled.
@@ -376,7 +376,8 @@ button is found in the current buffer."
                   ((and (hmouse-use-region-p)
                         (if (hyperb:stack-frame
                              '(hui:ebut-create hui:ebut-edit 
hui:ebut-edit-region hui:gbut-create
-                                                       hui:gbut-edit 
hui:link-create ebut:program))
+                                                       hui:gbut-edit 
hui:link-create ebut:program
+                                               hui:ibut-create hui:ibut-edit 
ibut:program))
                             ;; Ignore action-key-depress-prev-point
                             (progn (setq mark (marker-position (mark-marker))
                                          start (region-beginning)
@@ -420,12 +421,12 @@ button is found in the current buffer."
       (cond ((equal (ebut:label-p) new-key)
             ;; In case right before the start of the desired
             ;; button's delimiters.
-            (forward-char 2) (search-backward ebut:start nil t)
+            (forward-char 2) (search-backward ebut:label-start nil t)
             (goto-char (match-end 0)))
            ((let ((regexp (ebut:label-regexp new-key)))
               (or (re-search-forward  regexp nil t)
                   (re-search-backward regexp nil t)))
-            (goto-char (+ (match-beginning 0) (length ebut:start))))))
+            (goto-char (+ (match-beginning 0) (length ebut:label-start))))))
 
     ;; instance-flag might be 't which we don't want to return.
     (when (stringp instance-flag) instance-flag)))
@@ -459,8 +460,8 @@ For interactive creation, use `hui:ebut-create' instead."
            (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): %s" err)))))))
+                  (error (format "(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)
   "Write explicit button lines matching STRING to OUT-BUF.
@@ -575,12 +576,12 @@ else nil."
 
 ;;; ------------------------------------------------------------------------
 (defun    ebut:delimit (start end instance-flag)
-  "Delimit button label spanning region START to END in current buffer.
+  "Delimit explicit button label spanning region START to END in current 
buffer.
 If button is already delimited or delimit fails, return nil, else t.
 Insert INSTANCE-FLAG after END, before ending delimiter."
   (goto-char start)
-  (when (looking-at (regexp-quote ebut:start))
-    (forward-char (length ebut:start)))
+  (when (looking-at (regexp-quote ebut:label-start))
+    (forward-char (length ebut:label-start)))
   (unless (ebut:label-p)
     (setq start (move-marker (make-marker) start)
          end (move-marker (make-marker) end))
@@ -588,9 +589,9 @@ Insert INSTANCE-FLAG after END, before ending delimiter."
     ;; instance-flag may be 't to indicate don't add an instance number
     (unless (stringp instance-flag)
       (setq instance-flag ""))
-    (insert ebut:start)
+    (insert ebut:label-start)
     (goto-char end)
-    (insert instance-flag ebut:end)
+    (insert instance-flag ebut:label-end)
     ;; Insert any comment delimiter before the start marker.
     (set-marker-insertion-type start t)
     (hbut:comment start end)
@@ -604,19 +605,19 @@ Insert INSTANCE-FLAG after END, before ending delimiter."
 (defun    ebut:match-regexp (match-keys match-part)
   "Return regexp to match to all explicit button keys from MATCH-KEYS."
   (setq match-part (if match-part
-                      (concat "[^" (substring ebut:end -1) "]*")
+                      (concat "[^" (substring ebut:label-end -1) "]*")
                     "[ \t\n\r]*"))
   (concat
-   (regexp-quote ebut:start) match-part
+   (regexp-quote ebut:label-start) match-part
    "\\(" (mapconcat (lambda (key) (ebut:label-regexp key 'no-delim))
                    match-keys "\\|")
-   "\\)" match-part (regexp-quote ebut:end)))
+   "\\)" match-part (regexp-quote ebut:label-end)))
 
-(defconst ebut:start "<("
+(defconst ebut:label-start "<("
   "String matching the start of a Hyperbole explicit hyper-button.")
-(defconst ebut:end   ")>"
+(defconst ebut:label-end   ")>"
   "String matching the end of a Hyperbole explicit hyper-button.")
-(defconst ebut:instance-sep ":"
+(defconst hbut:instance-sep ":"
   "String of one character, separates an ebut label from its instance num.")
 
 ;;; ========================================================================
@@ -752,7 +753,7 @@ Return the symbol for the button when found, else nil."
       (with-current-buffer (find-file-noselect (gbut:file))
        (save-restriction
          (widen)
-         (ibut:label-map #'(lambda (label _start _end) (ibut:label-to-key 
label))))))))
+         (ibut:label-map (lambda (label _start _end) (ibut:label-to-key 
label))))))))
 
 ;;; ========================================================================
 ;;; hattr class
@@ -888,7 +889,7 @@ Use the function, (hbut:max-len), to read the proper 
value.")
 
 (defun    hbut:act (&optional hbut)
   "Perform action for optional explicit or implicit Hyperbole button symbol 
HBUT.
-Default is `hbut:current'."
+Default is the symbol hbut:current."
   (interactive (list (hbut:get (hargs:read-match "Activate labeled Hyperbole 
button: "
                                                 (nconc (ebut:alist) 
(ibut:alist))
                                                 nil t nil 'hbut))))
@@ -1237,6 +1238,19 @@ If LBL-KEY is not a string or is just punctuation, 
return nil."
     (error "(hbut:label): Argument is not a Hyperbole button symbol, `%s'"
           hbut)))
 
+;; (defun hbut:label-list ()
+;;   "Return the list of Hyperbole button labels/names in the current buffer."
+;;   (save-excursion
+;;     (save-restriction
+;;       (widen)
+;;       (nconc
+;;        (hbut:map (lambda (label _start _end) label) ebut:label-start 
ebut:label-end)
+;;        (hbut:map (lambda (label _start _end) label) ibut:label-start 
ibut:label-end)))))
+
+(defun    hbut:label-list ()
+  "Return the list of Hyperbole button labels/names in the current buffer."
+  (mapcar #'hbut:key-to-label (hbut:key-list)))
+
 (defun    hbut:label-p (&optional as-label start-delim end-delim pos-flag 
two-lines-flag)
   "Return key for the Hyperbole button label that point is within, else nil.
 Assume point is within the first line of any button label.  All
@@ -1254,14 +1268,15 @@ label search to two lines."
   "Unnormalize LBL-KEY.  Return regular expr matching delimited button label.
 Optional NO-DELIM leaves off delimiters and leading and trailing space.
 Optional START-DELIM and END-DELIM are added around the returned
-label; these default to `ebut:start' and `ebut:end'."
+label; these default to `ebut:label-start' and `ebut:label-end'."
   (when lbl-key
    (let* ((pos 0)
           (len (length lbl-key))
           (c)
           (sep0 "[ \t\n\r]*")
           (sep "[ \t\n\r]+")
-          (regexp (if no-delim "" (concat (regexp-quote (or start-delim 
ebut:start)) sep0)))
+          (regexp (if no-delim "" (concat (regexp-quote (or start-delim 
ebut:label-start)) sep0
+                                          "\\(")))
           (case-fold-search))
       (while (< pos len)
        (setq c (aref lbl-key pos)
@@ -1276,7 +1291,12 @@ label; these default to `ebut:start' and `ebut:end'."
              pos (1+ pos)))
       (if no-delim
          regexp
-       (setq regexp (concat regexp sep0 (regexp-quote (or end-delim 
ebut:end))))))))
+       (setq regexp (concat regexp
+                            (if (string-match (format "%s[0-9]+\\'" 
(regexp-quote hbut:instance-sep))
+                                              lbl-key)
+                                ""
+                              (concat "\\(" (regexp-quote hbut:instance-sep) 
"[0-9]+\\)?"))
+                            "\\)" sep0 (regexp-quote (or end-delim 
ebut:label-end))))))))
 
 (defun    hbut:label-to-key (label)
   "Normalize LABEL for use as a Hyperbole button key and return key.
@@ -1296,46 +1316,56 @@ whitespace sequences with `_'."
   "Apply BUT-FUNC to a set of hbuttons in the visible part of the current 
buffer.
 The set of buttons are those whose labels are delimited by
 optional START-DELIM and END-DELIM and that match any optional
-REGEXP-MATCH.
+REGEXP-MATCH (may be a partial match but must include delimiters).
 
-START-DELIM defaults to ebut:start; END-DELIM defaults to ebut:end.
-If END-DELIM is a symbol, e.g. t, then treat START-DELIM as a regular
-expression which matches an entire button string.
+START-DELIM defaults to ebut:label-start; END-DELIM defaults to
+ebut:label-end.  If END-DELIM is a symbol, e.g. t, then treat
+START-DELIM as a regular expression which matches an entire
+button string including instance numbers and
+delimiters (REGEXP-MATCH is ignored in such cases).
+
+Any regexp given must have grouping 1 match the label.
 
 BUT-FUNC must take precisely three arguments: the button label, the
 start position of the delimited button label and its end position (positions
 include delimiters when INCLUDE-DELIMS is non-nil)."
-  (or start-delim (setq start-delim ebut:start))
-  (or end-delim (setq end-delim ebut:end))
-  (let* ((regexp (symbolp end-delim))
-        (end-sym (or regexp (substring end-delim -1)))
-        (rtn)
+  (unless start-delim
+    (setq start-delim ebut:label-start))
+  (unless end-delim
+    (setq end-delim ebut:label-end))
+  (let* ((match-to-start-delim (when end-delim (symbolp end-delim)))
+        (end-sym (unless match-to-start-delim
+                   (substring end-delim -1)))
+        (result)
         (ignore)
-        start end but lbl)
+        (regexp-to-match
+         (cond (match-to-start-delim
+                start-delim)
+               ((stringp regexp-match)
+                regexp-match)
+               (t (concat (regexp-quote start-delim)
+                          "\\([^" end-sym "\"][^" end-sym "]*\\)"
+                          (regexp-quote end-delim)))))
+        start end delim-start lbl)
     (save-excursion
       (goto-char (point-min))
       (setq include-delims (if include-delims 0 1))
-      (while (re-search-forward
-             (if regexp start-delim
-               (concat (regexp-quote start-delim)
-                       "\\([^" end-sym "\"][^" end-sym "]*\\)"
-                       (regexp-quote end-delim)))
-             nil t)
+      (while (re-search-forward regexp-to-match nil t)
        (setq start (match-beginning include-delims)
              end (match-end include-delims)
-             but (match-string 0)
-             lbl (match-string 1)
+             lbl (match-string-no-properties 1)
+             delim-start (match-beginning 0)
              ;; If within a programming language buffer, ignore matches 
outside comments.
              ignore (hbut:outside-comment-p))
        (save-excursion
-         (goto-char start)
+         (goto-char delim-start)
          ;; Ignore matches with quoted delimiters.
-         (or ignore (setq ignore (memq (preceding-char) '(?\\ ?\{)))))
-       (cond (ignore (setq ignore nil))
-             ((or (not regexp-match)
-                  (string-match regexp-match but))
-              (setq rtn (cons (funcall but-func lbl start end) rtn))))))
-    (nreverse rtn)))
+         (unless ignore
+           (setq ignore (memq (preceding-char) '(?\\ ?\{)))))
+       (if ignore
+           (setq ignore nil)
+         (setq result (cons (funcall but-func lbl start end) result)))))
+    (nreverse result)))
 
 (defvar   hbut:syntax-table (copy-syntax-table emacs-lisp-mode-syntax-table)
   "Modified Elisp syntax table for use with Action and Key Series buttons.
@@ -1424,7 +1454,7 @@ Return number of buttons reported on or nil if none."
                       attribs (hattr:list but))
             (princ (if (ibut:is-p but)
                        lbl
-                     (concat ebut:start lbl ebut:end)))
+                     (concat ebut:label-start lbl ebut:label-end)))
             (terpri)
             (let ((doc (actype:doc but (= 1 (length lbl-lst)))))
               (when doc
@@ -1468,10 +1498,6 @@ button label.  Return the symbol for the button, else 
nil."
 This expression should be followed immediately by a file-name indicating the
 source file for the buttons in the menu, if any.")
 
-(defun    hbut:label-list ()
-  "Return list of current buffer's Hyperbole button labels."
-  (mapcar #'hbut:key-to-label (hbut:key-list)))
-
 ;;; ------------------------------------------------------------------------
 
 (defun    hbut:key-list ()
@@ -1564,7 +1590,8 @@ excluding delimiters, not just one."
              ;; typically writes the text start and end attributes saved as
              ;; `lbl-start' and `lbl-end' after finding the ibut type at point.
              ;; So do not pass these attributes in to this call.
-             (ibut:create :name name :lbl-key lbl-key)))
+             (when (ibut:create :name name :lbl-key lbl-key)
+               'hbut:current)))
        (goto-char opoint)))))
 
 (defun    ibut:at-type-p (ibut-type-symbol)
@@ -1583,34 +1610,40 @@ 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
+(cl-defun ibut:create (&optional &key but-sym name lbl-key lbl-start lbl-end
                                 loc dir categ actype args action)
-  "Return `hbut:current' symbol with attributes of implicit button at point.
-Return nil if no implicit button at point."
+  "Create an in-memory representation of an implicit button.
+Return symbol hbut:current with attributes from arguments given.
+If BUT-SYM is given, take buttons arguments from its property
+list.  Otherwise, button arguments can be given individually or
+if CATEG and following arguments are not given, create the button
+object from the implicit button at point, if any; in which case,
+return nil if no implicit button is found at point."
   ;; :args is ignored unless :categ is also given.
 
-  ;; `lbl-key' attribute will be set from the button name, if any;
-  ;; otherwise, from its text.
+  ;; `lbl-key' attribute will be set from `but-sym' if any, the button `name' 
if any;
+  ;; and, otherwise, from its text.
 
-  ;; `lbl-start' and `lbl-end' will be set from the start and end of the
-  ;; ibut text, excluding delimiters, not of its name.
+  ;; `lbl-start' and `lbl-end' will be set from `but-sym' if any; and,
+  ;; otherwise, the start and end of the ibut text, excluding
+  ;; delimiters, not of its name.
 
-  ;; 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)
-          (ibpoint (point-marker))
-          (itype)
-          (is-type categ))
+  (let* ((types (htype:category 'ibtypes))
+        ;; Global var used in (hact) function, don't delete.
+        (hrule:action #'actype:identity)
+        (ibpoint (point-marker))
+        (itype)
+        (is-type categ))
 
-      (unwind-protect
-         (progn
+    (unwind-protect
+       (progn
+         (unless but-sym
            (hattr:clear 'hbut:current)
-           (unless is-type
+           ;; 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 is-type (eolp) (eobp))
              (while (and (not is-type) types)
                (setq itype (car types))
                (when (and itype (setq args (funcall itype)))
@@ -1621,88 +1654,100 @@ Return nil if no implicit button at point."
                    (hypb:error "(Hyperbole): `%s' at-p test improperly moved 
point from %s to %s"
                                is-type ibpoint (point-marker))))
                (setq types (cdr types))))
-
-           (set-marker ibpoint nil)
-
-           (when is-type
-             (let ((current-name      (hattr:get 'hbut:current 'name))
-                   ;; (current-lbl-key   (hattr:get 'hbut:current 'lbl-key))
-                   (current-lbl-start (hattr:get 'hbut:current 'lbl-start))
-                   (current-lbl-end   (hattr:get 'hbut:current 'lbl-end))
-                   ;; (current-categ     (hattr:get 'hbut:current 'categ))
-                   (current-loc       (hattr:get 'hbut:current 'loc))
-                   (current-dir       (hattr:get 'hbut:current 'dir))
-                   (current-action    (hattr:get 'hbut:current 'action))
-                   ;; (current-actype    (hattr:get 'hbut:current 'actype))
-                   (current-args      (hattr:get 'hbut:current 'args)))
-
-               (if current-name
-                   (setq name current-name)
-                 (unless name
-                   (setq name (ibut:label-p t nil nil nil t)))
-                 (when name
-                   (hattr:set 'hbut:current 'name name)))
-
-               ;; Need to ignore current-lbl-key and use name if any
-               (setq lbl-key (or (ibut:label-to-key name)
-                                 lbl-key
-                                 (ibut:label-p nil "\"" "\"" nil t)))
-               (when lbl-key
-                 (hattr:set 'hbut:current 'lbl-key lbl-key))
-
-               (if current-lbl-start
-                   (setq lbl-start current-lbl-start)
-                 (when lbl-start
-                   (hattr:set 'hbut:current 'lbl-start lbl-start)))
-
-               (if current-lbl-end
-                   (setq lbl-end current-lbl-end)
-                 (when lbl-end
-                   (hattr:set 'hbut:current 'lbl-end lbl-end)))
-
-               (hattr:set 'hbut:current 'categ is-type)
-
-               (if current-loc
-                   (setq loc current-loc)
-                 (unless loc
-                   (setq loc (save-excursion (hbut:to-key-src 'full))))
-                 (when loc
-                   (hattr:set 'hbut:current 'loc loc)))
-
-               (if current-dir
-                   (setq dir current-dir)
-                 (unless dir
-                   (setq dir (hui:key-dir (current-buffer))))
-                 (when dir
-                   (hattr:set 'hbut:current 'dir dir)))
-
-               (if current-action
-                   (setq action current-action)
-                 (when action
-                   (hattr:set 'hbut:current 'action action)))
+           (set-marker ibpoint nil))
+
+         (when (or is-type but-sym)
+           (unless but-sym
+             (setq but-sym 'hbut:current))
+           (let ((current-name      (hattr:get but-sym 'name))
+                 ;; (current-lbl-key   (hattr:get but-sym 'lbl-key))
+                 (current-lbl-start (hattr:get but-sym 'lbl-start))
+                 (current-lbl-end   (hattr:get but-sym 'lbl-end))
+                 ;; (current-categ     (hattr:get but-sym 'categ))
+                 (current-loc       (hattr:get but-sym 'loc))
+                 (current-dir       (hattr:get but-sym 'dir))
+                 (current-action    (hattr:get but-sym 'action))
+                 ;; (current-actype    (hattr:get but-sym 'actype))
+                 (current-args      (hattr:get but-sym 'args)))
+
+             (if current-name
+                 (setq name current-name)
+               (unless name
+                 (setq name (ibut:label-p t nil nil nil t)))
+               (when name
+                 (hattr:set 'hbut:current 'name name)))
+
+             ;; Need to ignore current-lbl-key and use name if any
+             (setq lbl-key (or (when name (ibut:label-to-key name))
+                               lbl-key
+                               (ibut:label-p nil "\"" "\"" nil t)))
+             (when lbl-key
+               (hattr:set 'hbut:current 'lbl-key lbl-key))
+
+             (if current-lbl-start
+                 (setq lbl-start current-lbl-start)
+               (when lbl-start
+                 (hattr:set 'hbut:current 'lbl-start lbl-start)))
+
+             (if current-lbl-end
+                 (setq lbl-end current-lbl-end)
+               (when lbl-end
+                 (hattr:set 'hbut:current 'lbl-end lbl-end)))
+
+             (hattr:set 'hbut:current 'categ is-type)
+
+             (if current-loc
+                 (setq loc current-loc)
+               (unless loc
+                 (setq loc (save-excursion (hbut:to-key-src 'full))))
+               (when loc
+                 (hattr:set 'hbut:current 'loc loc)))
+
+             (if current-dir
+                 (setq dir current-dir)
+               (unless dir
+                 (setq dir (hui:key-dir (current-buffer))))
+               (when dir
+                 (hattr:set 'hbut:current 'dir dir)))
+
+             (if current-action
+                 (setq action current-action)
                (when action
-                 (unless args (setq args action)))
-
-               (or 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
-                                 actype
-                                 ;; Hyperbole action type
-                                 (symtable:actype-p (car args))
-                                 ;; Regular Emacs Lisp function symbol
-                                 (car args)))
-                     (hattr:set 'hbut:current 'args (if actype args (cdr 
args))))))
-             'hbut:current))
-       (set-marker ibpoint nil)))))
+                 (hattr:set 'hbut:current 'action action)))
+             (when action
+               (unless args (setq args action)))
+
+             (or 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
+                               actype
+                               ;; Hyperbole action type
+                               (symtable:actype-p (car args))
+                               ;; Regular Emacs Lisp function symbol
+                               (car args)))
+                   (hattr:set 'hbut:current 'args (if actype args (cdr 
args))))))
+           (hbdata:ibut-instance)))
+      (set-marker ibpoint nil))))
+
+(def-edebug-spec cl-defun
+ (&define name lambda-key-list
+          [&optional stringp]   ; Match the doc string, if present.
+          def-body))
+
+(def-edebug-spec lambda-key-list
+ (([&rest arg]
+   [&optional ["&optional" "&key" arg &rest arg]]
+   [&optional ["&optional" arg &rest arg]]
+   &optional ["&rest" arg])))
 
 (defun    ibut:delete (&optional but-sym)
   "Delete Hyperbole implicit button based on optional BUT-SYM.
-Default is `hbut:current'.
+Default is the symbol hbut:current'.
 Return symbol for button deleted or nil."
   (unless but-sym
     (setq but-sym 'hbut:current))
@@ -1727,6 +1772,44 @@ Return symbol for button deleted or nil."
                (run-hooks 'ibut-delete-hook)))))
        but-sym))))
 
+(defun    ibut:delimit (start end instance-flag)
+  "Delimit implicit button label spanning region START to END in current 
buffer.
+If button is already delimited or delimit fails, return nil, else t.
+Insert INSTANCE-FLAG after END, before ending delimiter."
+  (goto-char start)
+  (when (looking-at (regexp-quote ibut:label-start))
+    (forward-char (length ibut:label-start)))
+  (unless (ibut:label-p)
+    (setq start (move-marker (make-marker) start)
+         end (move-marker (make-marker) end))
+    (set-marker-insertion-type end t)
+    ;; instance-flag may be 't to indicate don't add an instance number
+    (unless (stringp instance-flag)
+      (setq instance-flag ""))
+    (insert ibut:label-start)
+    (goto-char end)
+    (insert instance-flag ibut:label-end)
+    ;; Insert any comment delimiter before the start marker.
+    (set-marker-insertion-type start t)
+    (hbut:comment start end)
+    (when (fboundp 'hproperty:but-add)
+      (hproperty:but-add start end hproperty:ibut-face))
+    (goto-char end)
+    (move-marker start nil)
+    (move-marker end nil)
+    t))
+
+(defun    ibut:edit (&optional lbl-key but-sym)
+  "Edit implicit Hyperbole button from optional LBL-KEY and BUT-SYM.
+Defaults are the key for any button label at point and `hbut:current'.
+If successful, return button's instance number, except when instance
+number is 1, then return t.  On failure, as when button does not exist,
+return nil."
+  (save-excursion
+    (let ((lbl-instance (hbdata:write lbl-key but-sym)))
+      (run-hooks 'ibut-edit-hook)
+      lbl-instance)))
+
 (defun    ibut:get (&optional lbl-key buffer key-src)
   "Return implicit Hyperbole button symbol given by LBL-KEY and BUFFER.
 KEY-SRC is given when retrieving global buttons and is the full source 
pathname.
@@ -1770,26 +1853,15 @@ If END-DELIM is a symbol, e.g. t, then treat 
START-DELIM as a regular
 expression which matches an entire button string."
   (hbut:map but-func ibut:label-start ibut:label-end))
 
-(defun    ibut:rename (old-lbl new-lbl)
-  "Change an implicit button name in the current buffer from OLD-LBL to 
NEW-LBL.
-Return t if the label is changed, else nil.
-
-Signal an error when no such button is found in the current buffer.
-
-Leave point at the start of the button label which may be elsewhere
-than the current point; callers should use `save-excursion` to retain
-current."
-  ;; !! Need to handle adding instances to labels, similar to ebut:operate.
-  (cond ((or (not (stringp new-lbl)) (< (length new-lbl) 1))
-        (error "(ibut:rename): Invalid 'new-lbl' argument: \"%s\"" new-lbl))
-       ((or (not (stringp old-lbl)) (< (length old-lbl) 1))
-        (error "(ibut:rename): Invalid 'old-lbl' argument: \"%s\"" old-lbl))
-       ((ibut:to old-lbl)
-         (unless (string-equal old-lbl new-lbl)
-          (delete-region (point) (search-forward ibut:label-end nil t))
-          (save-excursion (insert new-lbl ibut:label-end))
-           t))
-       (t (error "(ibut:rename): Button '%s' not found in visible portion of 
buffer." old-lbl))))
+(defun    ibut:label-key-match (lbl-key)
+  "Return a list of implicit button label keys fully matching LBL-KEY.
+There may be multiple results if there are numbered instances
+with the same label.  Names are returned in the order they are
+first encountered."
+  (apply #'set:create
+        (ibut:map
+         (lambda (lbl _start _end) (ibut:label-to-key lbl))
+         nil nil (ibut:label-regexp lbl-key))))
 
 (defun    ibut:label-p (&optional as-label start-delim end-delim pos-flag 
two-lines-flag)
   "Return key for the implicit button label that point is within, else nil.
@@ -1837,13 +1909,34 @@ name/label preceding the text."
        (t (error "(ibut:label-set): Invalid label arg: `%s'" label)))
   label)
 
+(defun    ibut:label-sort-keys (lbl-keys)
+  "Return a sorted list of ibutton LBL-KEYS with highest instance number 
first."
+  (sort (delq nil lbl-keys) (lambda (key1 key2)
+                             (setq key1
+                                   (cond ((null key1) 0)
+                                         ((string-match (concat (regexp-quote 
hbut:instance-sep)
+                                                                
"\\([0-9]+\\)\\'")
+                                                        key1)
+                                          (string-to-number (match-string 1 
key1)))
+                                         (t 1))
+                                   key2
+                                   (cond ((null key2) 0)
+                                         ((string-match (concat (regexp-quote 
hbut:instance-sep)
+                                                                
"\\([0-9]+\\)\\'")
+                                                        key2)
+                                          (string-to-number (match-string 1 
key2)))
+                                         (t 1)))
+                             (> key1 key2))))
+
 (defun    ibut:list (&optional file loc-p)
-  "Return list of labels of labeled ibuts in FILE or the current buffer.
+  "Return list of labels of named ibuts in FILE or the current buffer.
 Remove duplicate labels if optional LOC-P is omitted.  With LOC-P, return
 list of elements (label start end) where start and end are the buffer
 positions at which the button label delimiter begins and ends."
   (interactive)
-  (setq file (if file (and (file-exists-p file) (find-file-noselect file))
+  (setq file (if file
+                (when (file-exists-p file)
+                  (find-file-noselect file))
               (current-buffer)))
   (when file
     (set-buffer file)
@@ -1869,16 +1962,23 @@ positions at which the button label delimiter begins 
and ends."
 (defalias 'ibut:label-to-key 'hbut:label-to-key)
 (defalias 'map-ibut          'ibut:map)
 
-(defun    ibut:map (but-func &optional _start-delim _end-delim
+(defun    ibut:map (but-func &optional start-delim end-delim
                             regexp-match include-delims)
   "Apply BUT-FUNC to the visible, named implicit buttons.
+
+Optional START-DELIM and END-DELIM override the default `ibut:label-start'
+and `ibut:label-end' delimiters.
+
 If REGEXP-MATCH is non-nil, only buttons which match this argument
 are considered.
 
 BUT-FUNC must take precisely three arguments: the button label, the
 start position of the delimited button label and its end position (positions
 include delimiters when INCLUDE-DELIMS is non-nil)."
-  (hbut:map but-func ibut:label-start ibut:label-end regexp-match 
include-delims))
+  (hbut:map but-func
+           (or start-delim ibut:label-start)
+           (or end-delim ibut:label-end)
+           regexp-match include-delims))
 
 (defun    ibut:next-occurrence (lbl-key &optional buffer)
   "Move point to next occurrence of an implicit button with LBL-KEY.
@@ -1895,6 +1995,147 @@ move to the first occurrence of the button."
            (re-search-forward (ibut:label-regexp lbl-key t) nil t))
     (goto-char (+ (match-beginning 0) (length ibut:label-start)))))
 
+(defun    ibut:operate (curr-label new-label)
+  "Create an in-buffer ibutton named CURR-LABEL.  Modify if NEW-LABEL is given.
+
+If CURR-LABEL is nil, the text in the active region is used as the
+button label, if any, otherwise, an error is signaled.
+
+Return instance string appended to label to form a per-buffer unique
+label; nil if label is already unique.  Signal an error when no such
+button is found in the current buffer."
+  (let* ((lbl-key (ibut:label-to-key curr-label))
+        (lbl-regexp (ibut:label-regexp lbl-key))
+        (modify new-label)
+        (new-lbl-key)
+        (instance-flag))
+    (unless new-label
+      (setq new-label curr-label))
+    (setq new-lbl-key (ibut:label-to-key new-label))
+    (hattr:set 'hbut:current 'lbl-key new-lbl-key)
+    (save-excursion
+      (when (setq instance-flag
+                 (if modify
+                     (ibut:edit lbl-key)
+                   ;; Create implicit button structure
+                   (ibut:create :but-sym 'hbut:current)))
+       (when (hmail:editor-p)
+         (hmail:msg-narrow))))
+    (cond (modify
+           ;; Rename all occurrences of button - those with same label
+           (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-label))))
+             (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-label) (point))
+                        instance-flag))
+                     lbl-regexp 'include-delims))
+                   (at-but)
+                   ((hypb:error "(ibut:operate): No button matching: %s" 
curr-label)))))
+
+         (instance-flag
+          ;; Add a new button recording its start and end positions
+          (let (start end mark prev-point buf-lbl)
+            (cond ((not curr-label)
+                   (setq start (point))
+                   (insert new-label)
+                   (setq end (point)))
+                  ((and (hmouse-use-region-p)
+                        (if (hyperb:stack-frame
+                             '(hui:ebut-create hui:ebut-edit 
hui:ebut-edit-region hui:gbut-create
+                                                       hui:gbut-edit 
hui:link-create ebut:program
+                                               hui:ibut-create hui:ibut-edit 
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 curr-label))
+                          ;; 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))
+                                          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 curr-label)))
+                   nil)
+                  ((progn (when start (goto-char start))
+                          (looking-at (regexp-quote curr-label)))
+                   (setq start (point)
+                         end (match-end 0)))
+                  (t (setq start (point))
+                     (insert curr-label)
+                     (setq end (point))))
+            (ibut:delimit start end instance-flag)
+            (ibut:insert-text 'hbut:current)
+            (goto-char start)))
+
+         (t (hypb:error
+             "(ibut:operate): Operation failed.  Check button attribute 
permissions: %s"
+             hattr:filename)))
+
+    ;; Append any instance-flag string to the button label
+    (when (stringp instance-flag)
+      (setq new-label (concat new-label instance-flag))
+      (hattr:set 'hbut:current 'lbl-key (ibut:label-to-key new-label)))
+
+    ;; Position point
+    (let ((new-key (ibut:label-to-key new-label)))
+      (cond ((equal (ibut:label-p) new-key)
+            ;; In case right before the start of the desired
+            ;; button's delimiters.
+            (forward-char 2) (search-backward ibut:label-start nil t)
+            (goto-char (match-end 0)))
+           ((let ((regexp (ibut:label-regexp new-key)))
+              (or (re-search-forward  regexp nil t)
+                  (re-search-backward regexp nil t)))
+            (goto-char (+ (match-beginning 0) (length ibut:label-start))))))
+
+    ;; instance-flag might be 't which we don't want to return.
+    (when (stringp instance-flag) instance-flag)))
+
+(defun    ibut:insert-text (ibut)
+  "Space, delimit and insert the activatable text of IBUT."
+  (insert ibut:label-separator)
+  (let ((actype (hattr:get ibut 'actype))
+       (args   (hattr:get ibut 'args)))
+    (pcase actype
+      ('kbd-key (insert "{" (car args) "}" ))
+      ((or 'link-to-directory 'link-to-file
+          'link-to-Info-node 'link-to-Info-index-item)
+       (insert "\"" (car args) "\""))
+      ('link-to-file-line (insert (apply #'format "\"%s:%d\"" args)))
+      ('link-to-file-line-and-column (insert (apply #'format "\"%s:%d:%d\"" 
args)))
+      ('annot-bib (insert "[" (car args) "]"))
+      ('exec-shell-cmd (insert "\"!" (car args) "\""))
+      ('exec-window-cmd (insert "\"&" (car args) "\""))
+      ('link-to-ebut (progn (insert "<elink:" (car args))
+                           (when (cadr args) (insert ": " (cadr args)))))
+      ('link-to-ibut (progn (insert "<ilink:" (car args))
+                           (when (cadr args) (insert ": " (cadr args)))))
+      ('link-to-gbut (insert "<elink:" (car args)))
+      ('link-to-kcell (progn (insert "<") (when (car args) (insert (car args)))
+                            (when (cadr args) (insert ", " (cadr args)))))
+      ('link-to-org-id (insert (format "\"id:%s\"" (car args))))
+      ('link-to-rfc (insert (format "rfc%d" (car args))))
+      ('man-show (insert (car args)))
+      ;; Generic action button type                                            
      
+      (_ (insert (format "<%s%s%s>" actype (if args " " "")
+                        (if args (hypb:format-args args) "")))))))
+
 (defun    ibut:previous-occurrence (lbl-key &optional buffer)
   "Move point to previous occurrence of an implicit button with LBL-KEY.
 Optional BUFFER defaults to current buffer.  It may be a buffer name.
@@ -1910,6 +2151,57 @@ the whole buffer."
            (re-search-backward (ibut:label-regexp lbl-key t) nil t))
     (goto-char (+ (match-beginning 0) (length ibut:label-start)))))
 
+(defun    ibut:program (label actype &rest args)
+  "Programmatically create an implicit Hyperbole button at point.
+Create button from LABEL, ACTYPE (action type), and optional actype ARGS.
+Insert LABEL text at point surrounded by <[ ]> delimiters, adding any
+necessary instance number of the button after the LABEL.  ACTYPE may
+be a Hyperbole action type name (from defact) or an Emacs Lisp
+function, followed by a list of arguments for the actype, aside from
+the button LABEL which is automatically provided as the first argument.
+
+For interactive creation, use `hui:ibut-create' instead."
+  (save-excursion
+     (let ((but-buf (current-buffer))
+          (actype-sym (actype:action actype)))
+      (hui:buf-writable-err but-buf "ibut-create")
+      (condition-case err
+         (progn
+           (hattr:clear 'hbut:current)
+           (hattr:set 'hbut:current 'loc (hui:key-src but-buf))
+           (hattr:set 'hbut:current 'dir (hui:key-dir but-buf))
+            (if (or (and actype-sym (fboundp actype-sym))
+                   (functionp actype))
+               (hattr:set 'hbut:current 'actype actype)
+             (error (format "(%s)" actype)))
+           (hattr:set 'hbut:current 'args args)
+           (ibut:operate label nil))
+       (error (hattr:clear 'hbut:current)
+              (if (and (listp (cdr err)) (= (length (cdr err)) 1))
+                  (error (format "(ibut:program): actype arg must be a bound 
symbol (not a string): %S" actype))
+                (error "(ibut:program): %S" err)))))))
+
+(defun    ibut:rename (old-lbl new-lbl)
+  "Change an implicit button name in the current buffer from OLD-LBL to 
NEW-LBL.
+Return t if the label is changed, else nil.
+
+Signal an error when no such button is found in the current buffer.
+
+Leave point at the start of the button label which may be elsewhere
+than the current point; callers should use `save-excursion` to retain
+current."
+  ;; !! Need to handle adding instances to labels, similar to ebut:operate.
+  (cond ((or (not (stringp new-lbl)) (< (length new-lbl) 1))
+        (error "(ibut:rename): Invalid 'new-lbl' argument: \"%s\"" new-lbl))
+       ((or (not (stringp old-lbl)) (< (length old-lbl) 1))
+        (error "(ibut:rename): Invalid 'old-lbl' argument: \"%s\"" old-lbl))
+       ((ibut:to old-lbl)
+         (unless (string-equal old-lbl new-lbl)
+          (delete-region (point) (search-forward ibut:label-end nil t))
+          (save-excursion (insert new-lbl ibut:label-end))
+           t))
+       (t (error "(ibut:rename): Button '%s' not found in visible portion of 
buffer." old-lbl))))
+
 (defalias 'ibut:summarize 'hbut:report)
 
 (defun    ibut:to (lbl-key)
@@ -2071,10 +2363,11 @@ Return the symbol for the button if found, else nil."
 (defconst ibut:label-end   "]>"
   "String matching the end of a Hyperbole implicit button label.")
 
-(defvar   ibut:label-separator " "
-  "String inserted immediately after a newly created implicit button name.
+(defvar   ibut:label-separator " - "
+  "Default separator string inserted between implicit button name and its text.
+
 This separates it from the implicit button text.  See also
-`ibut:label-separator-regexp' for all valid characters that may
+`ibut:label-separator-regexp' for all valid characters that may be
 manually inserted to separate an implicit button label from its
 text.")
 
diff --git a/hibtypes.el b/hibtypes.el
index ac58483837..e82929f660 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:     12-Mar-23 at 21:41:30 by Bob Weiner
+;; Last-Mod:     27-Mar-23 at 23:35:16 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1538,7 +1538,7 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
                        action `(display-value ',action)
                        actype #'display-value))))
 
-       ;; Create implicit button structure
+       ;; 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)
 
diff --git a/hui-em-but.el b/hui-em-but.el
index 7fb94e1eff..d05570bafb 100644
--- a/hui-em-but.el
+++ b/hui-em-but.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Aug-92
-;; Last-Mod:      7-Oct-22 at 00:17:10 by Mats Lidell
+;; Last-Mod:     16-Mar-23 at 22:25:03 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -90,11 +90,11 @@
     (((background dark)) (:background "red" :foreground "black"))
     (((min-colors 88)) (:foreground "salmon4"))
     (t (:background "red")))
-  "Face for hyperbole buttons."
+  "Face for explicit Hyperbole buttons."
   :group 'hyperbole-buttons)
 
 (defcustom hproperty:but-face 'hbut-face
-  "Hyperbole face for hyper-buttons."
+  "Hyperbole face for explicit buttons."
   :type 'face
   :initialize #'custom-initialize-default
   :group 'hyperbole-buttons)
@@ -111,11 +111,25 @@
     (((class color) (min-colors 8))
      :background "yellow" :foreground "black")
     (t :inverse-video t))
-  "Face for hyperbole buttons."
+  "Face for Hyperbole list buttons."
   :group 'hyperbole-buttons)
 
 (defcustom hproperty:item-face 'hbut-item-face
-  "Hyperbole face for hyper-buttons."
+  "Hyperbole face for list hyper-buttons."
+  :type 'face
+  :initialize #'custom-initialize-default
+  :group 'hyperbole-buttons)
+
+(defface ibut-face
+  '((((min-colors 88) (background dark)) (:foreground "salmon2"))
+    (((background dark)) (:background "red2" :foreground "black"))
+    (((min-colors 88)) (:foreground "salmon3"))
+    (t (:background "red2")))
+  "Face for implicit Hyperbole buttons."
+  :group 'hyperbole-buttons)
+
+(defcustom hproperty:ibut-face 'ibut-face
+  "Hyperbole face for implicit buttons."
   :type 'face
   :initialize #'custom-initialize-default
   :group 'hyperbole-buttons)
diff --git a/hui-menu.el b/hui-menu.el
index 4bd38e94b6..19dca91b6e 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:      6-Nov-22 at 12:23:29 by Bob Weiner
+;; Last-Mod:     29-Mar-23 at 22:05:18 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -415,6 +415,7 @@ REBUILD-FLAG is non-nil, in which case the menu is rebuilt."
                   ["Manual"   (id-info "(hyperbole)Implicit Buttons") t]
                   "----"
                   ["Activate" hui:ibut-act t]
+                  ["Create"   hui:ibut-create t]
                   ["Delete-Type" (hui:htype-delete 'ibtypes) t]
                   ["Edit"   hui:ibut-edit t]
                   ["Help"   hui:hbut-help t]
diff --git a/hui-mini.el b/hui-mini.el
index 42223858c4..e736ade908 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:     29-Jan-23 at 17:17:22 by Mats Lidell
+;; Last-Mod:     29-Mar-23 at 22:03:59 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -790,6 +790,8 @@ The menu is a menu of commands from MENU-ALIST."
         (("IButton>")
          ("Act"            hui:ibut-act
            "Activates implicit button at point or prompts for labeled implicit 
button to activate.")
+         ("Create"         hui:ibut-create
+           "Labels and creates an implicit button of any type.")
          ("DeleteIButType" (hui:htype-delete 'ibtypes)
           "Deletes specified button type.")
          ("Edit"           hui:ibut-edit "Edits/modifies named implicit button 
attributes.")
diff --git a/hui.el b/hui.el
index 9e8e935da4..34cfe16bcb 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:     12-Mar-23 at 20:46:57 by Bob Weiner
+;; Last-Mod:     29-Mar-23 at 22:13:40 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -296,7 +296,7 @@ For programmatic creation, use `ebut:program' instead."
        (unless (equal lbl default-lbl)
          (setq default-lbl nil))
 
-       (setq but-buf (if default-lbl (current-buffer) (hui:ebut-buf)))
+       (setq but-buf (current-buffer))
        (hui:buf-writable-err but-buf "ebut-create")
 
        (hattr:set 'hbut:current 'loc (hui:key-src but-buf))
@@ -329,8 +329,8 @@ Signal an error if point is not within a button."
   (let ((interactive (called-interactively-p 'interactive)))
     (if (and hui:hbut-delete-confirm-flag interactive)
        (if (y-or-n-p (format "Delete button %s%s%s? "
-                             ebut:start
-                             (hbut:key-to-label but-key) ebut:end))
+                             ebut:label-start
+                             (hbut:key-to-label but-key) ebut:label-end))
            (hui:ebut-delete-op interactive but-key key-src)
          (message "")
          nil)
@@ -489,7 +489,7 @@ a menu to find any of the occurrences."
          (if (fboundp 'hproperty:but-create)
              (hproperty:but-create nil nil (regexp-quote
                                             (if match-part string
-                                              (concat ebut:start string 
ebut:end)))))
+                                              (concat ebut:label-start string 
ebut:label-end)))))
          (goto-char (point-min))
          (pop-to-buffer out-buf)
          (if (called-interactively-p 'interactive) (message "%d match%s." total
@@ -658,6 +658,7 @@ When in the global button buffer, the default is the button 
at point."
 
 (defun hui:gibut-create (lbl text)
   "Create a Hyperbole global implicit button with LBL and button TEXT.
+Button is stored as the properties of the symbol, 'hbut:current.
 
 Use `hui:gbut-create' to create a global explicit button."
   (interactive "sCreate global implicit button labeled: \nsButton text (with 
any delimiters): ")
@@ -678,6 +679,7 @@ Use `hui:gbut-create' to create a global explicit button."
         (insert delimited-label ": " text "\n")
        (save-excursion
          (goto-char (+ opoint (length ibut:label-start)))
+         ;; Create button object from ibut at point
          (ibut:create))
        (save-buffer))
       (message "`%s' global implicit button created." lbl))))
@@ -690,6 +692,31 @@ The default is the current button."
                                                 nil t nil 'hbut))))
   (hui:hbut-operate #'hbut:act "Activate Hyperbole button: " but))
 
+(defun hui:hbut-buf (&optional prompt)
+  "Prompt for and return a buffer in which to place a button."
+  (let ((buf-name))
+    (while
+       (progn
+         (setq buf-name
+               (hargs:read-match
+                (or prompt "Button's buffer: ")
+                (delq nil
+                      (mapcar
+                       ;; Filter only buffer whose names start with a
+                       ;; space, are read-only or are known not to be
+                       ;; editable, since buttons can be
+                       ;; in buffers without attached files now.
+                       (lambda (buf)
+                         (let ((b (buffer-name buf)))
+                           (unless (or (string-match-p 
hui:ignore-buffers-regexp b)
+                                       (buffer-local-value 'buffer-read-only 
buf))
+                             (cons b nil))))
+                       (buffer-list)))
+                nil t (buffer-name) 'buffer))
+         (or (null buf-name) (equal buf-name "")))
+      (beep))
+    (get-buffer buf-name)))
+
 (defun hui:hbut-current-act ()
   "Activate Hyperbole button at point or signal an error if there is none."
   (interactive)
@@ -725,7 +752,7 @@ Signal an error if point is not within a button."
        (cond ((ebut:to but-key)
               (if (and hui:hbut-delete-confirm-flag interactive)
                   (if (y-or-n-p (format "Delete button %s%s%s? "
-                                        ebut:start label ebut:end))
+                                        ebut:label-start label ebut:label-end))
                       (hui:ebut-delete-op interactive but-key key-src)
                     (message "")
                     nil)
@@ -845,6 +872,37 @@ Default is any implicit button at point."
             (hypb:error "(ibut-act): No labeled implicit buttons in 
buffer."))))))
   (hui:hbut-operate #'ibut:act "Activate labeled implicit button: " but))
 
+(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
+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-lbl) lbl but-buf actype)
+      (save-excursion
+       (setq default-lbl (hui:hbut-label-default start end (not 
(called-interactively-p 'interactive)))
+             lbl (hui:hbut-label default-lbl "ibut-create"))
+       (unless (equal lbl default-lbl)
+         (setq default-lbl nil))
+
+       (setq but-buf (current-buffer))
+       (hui:buf-writable-err but-buf "ibut-create")
+
+       (hattr:set 'hbut:current 'loc (hui:key-src but-buf))
+       (hattr:set 'hbut:current 'dir (hui:key-dir but-buf))
+       (setq actype (hui:actype))
+       (hattr:set 'hbut:current 'actype actype)
+       (hattr:set 'hbut:current 'args (hargs:actype-get actype))
+       (hattr:set 'hbut:current 'action nil)
+       ;; Adds instance number to in-buffer label if necessary
+       (ibut:operate lbl nil)
+       (when (called-interactively-p 'interactive)
+         (hui:ibut-message nil))))))
+
 (defun hui:ibut-edit (lbl-key)
   "Edit a named implicit Hyperbole button given by LBL-KEY.
 Signal an error when no such button is found in the current buffer."
@@ -1153,31 +1211,6 @@ Trigger an error if DEFAULT-ACTYPE is invalid."
 (defvar hui:ignore-buffers-regexp "\\`\\( \\|BLANK\\'\\|\\*Pp 
\\|TAGS\\|*quelpa\\)"
   "When prompting for a buffer name, ignore any buffers whose names match to 
this.")
 
-(defun hui:ebut-buf (&optional prompt)
-  "Prompt for and return a buffer in which to place a button."
-  (let ((buf-name))
-    (while
-       (progn
-         (setq buf-name
-               (hargs:read-match
-                (or prompt "Button's buffer: ")
-                (delq nil
-                      (mapcar
-                       ;; Filter only buffer whose names start with a
-                       ;; space, are read-only or are known not to be
-                       ;; editable, since buttons can be
-                       ;; in buffers without attached files now.
-                       (lambda (buf)
-                         (let ((b (buffer-name buf)))
-                           (unless (or (string-match-p 
hui:ignore-buffers-regexp b)
-                                       (buffer-local-value 'buffer-read-only 
buf))
-                             (cons b nil))))
-                       (buffer-list)))
-                nil t (buffer-name) 'buffer))
-         (or (null buf-name) (equal buf-name "")))
-      (beep))
-    (get-buffer buf-name)))
-
 (defun hui:ebut-delete-op (interactive but-key key-src)
   "INTERACTIVEly or not, delete explicit button given by BUT-KEY in KEY-SRC.
 KEY-SRC may be a buffer or a pathname; when nil, the current
@@ -1214,9 +1247,9 @@ from the button that point is within."
        (args (hattr:get 'hbut:current 'args)))
     (setq actype (actype:def-symbol actype))
     (message "%s%s%s %s %S"
-            ebut:start
+            ebut:label-start
             (hbut:key-to-label (hattr:get 'hbut:current 'lbl-key))
-            ebut:end
+            ebut:label-end
             (if but-edit-flag "now executes" "executes")
             (cons actype args))))
 
@@ -1233,7 +1266,7 @@ With a prefix argument, also delete the button text 
between the delimiters."
                        end-delim-pos (match-end 0))
                  (when (fboundp 'hproperty:but-delete)
                    (hproperty:but-delete start-delim-pos))
-                 (goto-char (- (point) (length ebut:end)))
+                 (goto-char (- (point) (length ebut:label-end)))
                  (skip-chars-backward " \t\n\r")
                  (setq text-end (point))
                  ;; Limit instance number removal to single digit 2-9
@@ -1241,12 +1274,12 @@ With a prefix argument, also delete the button text 
between the delimiters."
                  ;; number that is part of the text and  should not
                  ;; be removed.
                  (skip-chars-backward "2-9")
-                 (skip-chars-backward ebut:instance-sep)
-                 (when (looking-at (concat (regexp-quote ebut:instance-sep)
+                 (skip-chars-backward hbut:instance-sep)
+                 (when (looking-at (concat (regexp-quote hbut:instance-sep)
                                            "[2-9]"
-                                           (regexp-quote ebut:end)))
+                                           (regexp-quote ebut:label-end)))
                    (setq text-end (point)))
-                 (when (search-backward ebut:start (- (point) (hbut:max-len)) 
t)
+                 (when (search-backward ebut:label-start (- (point) 
(hbut:max-len)) t)
                    (if current-prefix-arg
                        ;; Remove button text, delimiters and preceding space, 
if any.
                        (delete-region (max (point-min)
@@ -1261,7 +1294,7 @@ With a prefix argument, also delete the button text 
between the delimiters."
                      (delete-region (match-beginning 0) (match-end 0))))))))
     (if (called-interactively-p 'interactive)
        (save-excursion
-         (when (search-forward ebut:end nil t) (funcall form)))
+         (when (search-forward ebut:label-end nil t) (funcall form)))
       ;; Non-interactive invocation.
       (let (cur-flag)
        (if (and (or (null key-src) (eq key-src buffer-file-name))
diff --git a/hypb.el b/hypb.el
index 248a12a4c2..f52b2f1eff 100644
--- a/hypb.el
+++ b/hypb.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     6-Oct-91 at 03:42:38
-;; Last-Mod:     27-Feb-23 at 18:11:15 by Bob Weiner
+;; Last-Mod:     28-Mar-23 at 00:02:25 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -490,6 +490,10 @@ Return a flattened list of all matching files."
                    (apply #'nconc (mapcar (lambda (dir) 
(directory-files-recursively dir file-regexp))
                                           dirs)))))
 
+(defun hypb:format-args (args)
+  "Return a space-separated string of quoted ARGS without surrounding 
parentheses."
+  (if args (mapconcat (lambda (a) (format "%S" a)) args " ") ""))
+
 (defun hypb:format-quote (arg)
   "Replace all single % with %% in any string ARG.
 This is so that a call to `format' or `message' ignores them.
diff --git a/man/hyperbole.html b/man/hyperbole.html
index 4cb809a515..25580c653a 100644
--- a/man/hyperbole.html
+++ b/man/hyperbole.html
@@ -107,7 +107,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</P>
 
 <PRE>
 Edition 8.0.1pre
-Printed March 7, 2023.
+Printed March 29, 2023.
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -1942,23 +1942,27 @@ Next: <a href="#Button-Files" accesskey="n" 
rel="next">Button Files</a>, Previou
 <a class="index-entry-id" id="index-button_002c-implicit-1"></a>
 <a class="index-entry-id" id="index-implicit-button-1"></a>
 <a class="index-entry-id" id="index-link_002dto_002dfile"></a>
-<p><em class="dfn">Implicit buttons</em> are virtual buttons recognized within 
the natural
-structure of a document.  For example, a web URL button that displays its link
-or an email address button that starts a mail message to the associated
-address.  Implicit buttons are identified by implicit button type contextual
-pattern matchers that identify appropriate textual patterns at point.
+<p>Hyperbole can recognize and activate <em class="dfn">implicit buttons</em> 
within
+documents that require no special markup, e.g. pathnames or URLs, and
+many other types.  For example, an Action Key press on a web URL will
+display its link in a browser, regardless of the format of the
+document.  Similarly, an Action Key press on an email address starts
+composing mail to that address.
 </p>
 <a class="index-entry-id" id="index-implicit-button-type"></a>
-<p>An <em class="dfn">implicit button type</em> utilizes Emacs Lisp to 
identify a pattern or
-state that when matched triggers an <em class="emph">action</em> associated 
with the implicit
-button type.  The action is specified by either a Hyperbole action type
-(see <a class="pxref" href="#Action-Types">Action Types</a>) or an Emacs Lisp 
command.  Implicit button types may use
-the same action types that explicit buttons use.  As an example, the pathname
-implicit button type matches to any existing local filename or directory name
-and its action type, <code class="code">link-to-file</code>, displays the 
associated file or
-directory, typically in another window.  An explicit button could do the same
-thing but has to be created manually, rather than recognized as part of the
-buffer text.
+<p>Implicit buttons are identified by implicit button type contextual
+pattern matchers that identify appropriate textual patterns at point.
+An <em class="dfn">implicit button type</em> utilizes Emacs Lisp to identify a
+pattern or state that when matched triggers an <em class="emph">action</em>
+associated with the implicit button type.  The action is specified by
+either a Hyperbole action type (see <a class="pxref" 
href="#Action-Types">Action Types</a>) or an Emacs Lisp
+command.  Implicit button types may use the same action types that
+explicit buttons use.  As an example, the pathname implicit button
+type matches to any existing local filename or directory name and its
+action type, <code class="code">link-to-file</code>, displays the associated 
file or
+directory, typically in another window.  An explicit button could do
+the same thing but has to be created manually, rather than recognized
+as part of the buffer text.
 </p>
 <a class="index-entry-id" id="index-file_002c-hibtypes_002eel"></a>
 <a class="index-entry-id" id="index-context"></a>
@@ -1993,18 +1997,29 @@ button with a label of &rsquo;My Emacs Files&rsquo;:
 <pre class="example-preformatted">&lt;[My Emacs Files]&gt;: 
&quot;~/.emacs.d&quot;
 </pre></div>
 
+<p>The label is delimited by &lsquo;<samp class="samp">&lt;[</samp>&rsquo; and 
&lsquo;<samp class="samp">]&gt;</samp>&rsquo; and can be followed
+by any number of :, - or = separator characters, including none.
+</p>
+<a class="index-entry-id" id="index-C_002dh-h-i"></a>
+<a class="index-entry-id" id="index-menu_002c-Ibut"></a>
+<a class="index-entry-id" id="index-menu_002c-Implicit_002dButton"></a>
+<a class="index-entry-id" id="index-C_002dh-h-i-a-1"></a>
+<a class="index-entry-id" id="index-C_002dh-h-i-c"></a>
 <a class="index-entry-id" id="index-C_002dh-h-i-e"></a>
 <a class="index-entry-id" id="index-C_002dh-h-i-l"></a>
-<p>The label is delimited by &lsquo;<samp class="samp">&lt;[</samp>&rsquo; and 
&lsquo;<samp class="samp">]&gt;</samp>&rsquo; and can be followed
-by any number of :, - or = separator characters, including none.  You
-can activate the button either from its label or its text.  With point
-on the text of an implicit button, <kbd class="kbd">{C-h h i l}</kbd> will 
label it.  Or
-you may simply type the label and delimiters manually.  You can also
-simply edit any implicit button manually but for a little more help in
-editing named implicit buttons, use <kbd class="kbd">{C-h h i e}</kbd> which 
prompts
-you to rename the button and to change its text (the button itself).
+<p>Implicit buttons are managed with the Hyperbole Ibut/ menu accessed
+with <kbd class="kbd">{C-h h i}</kbd>.  The Create item, <kbd class="kbd">{C-h 
h i c}</kbd>, prompts for
+an implicit button label, an action type, and the action&rsquo;s associated
+arguments, such as a file to which to link.  It then creates the
+button at point.  To activate the button with point on its label or
+button text, use the Act menu item, <kbd class="kbd">{C-h h i a}</kbd> or 
press the
+Action Key.  You can use <kbd class="kbd">{C-h h i e}</kbd> to edit an 
implicit button
+(or simply edit it manually).  If you want to add a label to an
+existing implicit button without one, use <kbd class="kbd">{C-h h i l}</kbd> 
to label
+it.
 </p>
 
+
 <ul class="mini-toc">
 <li><a href="#Implicit-Button-Types" accesskey="1">Implicit Button 
Types</a></li>
 <li><a href="#Action-Buttons" accesskey="2">Action Buttons</a></li>
@@ -3382,6 +3397,7 @@ upon the referent context in which the Action Key is 
released.
 <div class="example">
 <pre class="example-preformatted">Referent Context         Link Type
 ----------------------------------------------------
+Org Roam or Org Id       link-to-org-id
 Global Button            link-to-gbut
 Explicit Button          link-to-ebut
 Implicit Button          link-to-ibut
@@ -3982,8 +3998,8 @@ includes an activation menu item for each global button.
 <dt><strong class="strong">Hist</strong></dt>
 <dd><p>Return to previous positions in the button traversal history.
 </p>
-<a class="index-entry-id" id="index-menu_002c-Implicit_002dButton"></a>
-<a class="index-entry-id" id="index-menu_002c-Ibut"></a>
+<a class="index-entry-id" id="index-menu_002c-Implicit_002dButton-1"></a>
+<a class="index-entry-id" id="index-menu_002c-Ibut-1"></a>
 </dd>
 <dt><strong class="strong">Ibut/</strong></dt>
 <dd><p>All implicit button commands.
@@ -7519,6 +7535,13 @@ See <a data-manual="emacs" 
href="https://www.gnu.org/software/emacs/manual/html_
 if any emacs-related terms are unfamiliar to you.
 </p>
 <dl class="table">
+<dt><b class="b">Ace Window</b></dt>
+<dd><p>Emacs extension package that labels windows with letters and allows
+quick selection or other operations on a specific window.  Hyperbole
+extends this with a number of additional commands like throw a buffer
+to a window or replace a windows&rsquo;s contents.  See <a class="xref" 
href="#Keyboard-Drags">Keyboard Drags</a>.
+</p>
+</dd>
 <dt><b class="b">Action</b></dt>
 <dd><p>An executable behavior associated with a Hyperbole button.  <em 
class="dfn">Links</em>
 are a specific class of actions which display existing entities, such as
@@ -7673,6 +7696,15 @@ level deeper than the parent.
 used to provide an interface to an internal or external Hyperbole
 abstraction.
 </p>
+<a class="index-entry-id" id="index-consult-package"></a>
+<a class="index-entry-id" id="index-consult_002dorg_002droam-package"></a>
+</dd>
+<dt><b class="b">Consult</b></dt>
+<dd><p>An Emacs extension package that provides asynchronous search and narrow
+wrappers around common search commands like grep, ripgrep, find and locate.
+Hyperbole optionally utilizes this to search the HyRolo.  Use the
+<code class="code">consult-org-roam</code> package to search Org Roam notes 
similarly.
+</p>
 </dd>
 <dt><b class="b">Context</b></dt>
 <dd><p>A programmatic or positional state recognized by Hyperbole.
@@ -7960,6 +7992,23 @@ Keys that utilize the OO-Browser&rsquo;s capabilities 
both when it is displayed
 on screen and when editing code.
 </p>
 </dd>
+<dt><b class="b">Org Mode</b></dt>
+<dd><p>A built-in Emacs mode for outlining, note taking and scientific
+publishing.  Hyperbole simplifies access to a number of its features
+and integrates its own hypermedia capabilities with those of Org mode.
+Hyperbole can display the referent of any Org Id.
+See <a class="xref" href="#Smart-Key-_002d-Org-Mode">Smart Key - Org Mode</a>.
+</p>
+<a class="index-entry-id" id="index-org_002droam-package"></a>
+</dd>
+<dt><b class="b">Org Roam</b></dt>
+<dd><p>An Emacs extension package that inserts ids into Org mode files and
+indexes them within a Sqlite database for rapid note taking and lookup
+by title.  Hyperbole can display the referent of any Org Roam Id and
+provides full-text searching of Org Roam nodes utilzing the interactive
+grep commands from the Consult extension package.
+</p>
+</dd>
 <dt><b class="b">Outline</b></dt>
 <dd><p>See <b class="b">Koutline</b>.
 </p>
@@ -10318,7 +10367,7 @@ Next: <a href="#Smart-Key-_002d-Ivy" accesskey="n" 
rel="next">Smart Key - Ivy</a
 <a class="index-entry-id" 
id="index-org_002dlink_002doutside_002dorg_002dmode"></a>
 <p>Org links may be used outside of Org mode buffers.  Such links are
 handled by the separate implicit button type, <code 
class="code">org-link-outside-org-mode</code>.
-Org and Org Roam IDs may be activated as hyperbuttons outside of Org mode 
buffers.
+Org Roam and Org IDs may be activated as hyperbuttons outside of Org mode 
buffers.
 They are handled by the separate implicit button type, <code 
class="code">org-id</code>.
 </p>
 <hr>
@@ -12458,7 +12507,10 @@ Next: <a href="#Function" accesskey="n" 
rel="next">Function, Variable and File I
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-f-w-1"><code>C-h h f 
w</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Default-Hyperbole-Bindings">Default Hyperbole Bindings</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-g"><code>C-h h g</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Global-Buttons">Global 
Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-h"><code>C-h h h</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Default-Hyperbole-Bindings">Default 
Hyperbole Bindings</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-i"><code>C-h h i</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-i-a"><code>C-h h i a</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-i-a-1"><code>C-h h i 
a</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Implicit-Buttons">Implicit Buttons</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-i-c"><code>C-h h i c</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-i-e"><code>C-h h i e</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-i-l"><code>C-h h i l</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-C_002dh-h-k-e"><code>C-h h k e</code></a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Koutliner">Koutliner</a></td></tr>
@@ -13736,6 +13788,8 @@ Previous: <a href="#Function" accesskey="p" 
rel="prev">Function, Variable and Fi
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-completion-4">completion</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Smart-Key-_002d-Helm-Mode">Smart Key 
- Helm Mode</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-completion_002c-Ivy">completion, Ivy</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Smart-Key-_002d-Ivy">Smart Key - 
Ivy</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-configuration">configuration</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a 
href="#Customization">Customization</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-consult-package">consult package</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Glossary">Glossary</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-consult_002dorg_002droam-package">consult-org-roam 
package</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Glossary">Glossary</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-contacts_002c-Google">contacts, Google</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#HyRolo-Settings">HyRolo 
Settings</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-context">context</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-context_002dsensitive-help">context-sensitive 
help</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Smart-Key-Operations">Smart Key Operations</a></td></tr>
@@ -14282,8 +14336,10 @@ Previous: <a href="#Function" accesskey="p" 
rel="prev">Function, Variable and Fi
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Global_002dButton">menu, 
Global-Button</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Global-Buttons">Global Buttons</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Global_002dButton-1">menu, 
Global-Button</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Menus">Menus</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-HyRolo">menu, HyRolo</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#HyRolo-Menu">HyRolo 
Menu</a></td></tr>
-<tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Ibut">menu, Ibut</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Menus">Menus</a></td></tr>
-<tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Implicit_002dButton">menu, 
Implicit-Button</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Menus">Menus</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Ibut">menu, Ibut</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Buttons">Implicit 
Buttons</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Ibut-1">menu, Ibut</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Menus">Menus</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Implicit_002dButton">menu, 
Implicit-Button</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Implicit-Buttons">Implicit Buttons</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Implicit_002dButton-1">menu, 
Implicit-Button</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Menus">Menus</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-KeyBindings">menu, 
KeyBindings</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Menus">Menus</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Kotl">menu, Kotl</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Menus">Menus</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-menu_002c-Koutline">menu, Koutline</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Menus">Menus</a></td></tr>
@@ -14378,6 +14434,7 @@ Previous: <a href="#Function" accesskey="p" 
rel="prev">Function, Variable and Fi
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-Org-tables">Org tables</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Promoting-and-Demoting">Promoting 
and Demoting</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-org_002dmode">org-mode</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Implicit-Button-Types">Implicit 
Button Types</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-Org_002dmode">Org-mode</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Questions-and-Answers">Questions and 
Answers</a></td></tr>
+<tr><td></td><td class="printindex-index-entry"><a 
href="#index-org_002droam-package">org-roam package</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#Glossary">Glossary</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-other-frame">other frame</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#HyControl">HyControl</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-other-window">other window</a>:</td><td>&nbsp;</td><td 
class="printindex-index-section"><a href="#HyControl">HyControl</a></td></tr>
 <tr><td></td><td class="printindex-index-entry"><a 
href="#index-outline-file-suffix">outline file 
suffix</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a 
href="#Creating-Outlines">Creating Outlines</a></td></tr>
diff --git a/man/hyperbole.info b/man/hyperbole.info
index 6915603960..9f23c46eef 100644
Binary files a/man/hyperbole.info and b/man/hyperbole.info differ
diff --git a/man/hyperbole.pdf b/man/hyperbole.pdf
index cf06c30190..598dbf2ede 100644
Binary files a/man/hyperbole.pdf and b/man/hyperbole.pdf differ
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index 3cb03bcc8b..5acfe1ab96 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:     12-Mar-23 at 20:46:34 by Bob Weiner
+@c Last-Mod:     29-Mar-23 at 23:11:38 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 March 7, 2023.
+Printed March 29, 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
-March 7, 2023
+March 29, 2023
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -2035,23 +2035,27 @@ Manual}, for details on bookmarks.
 @cindex button, implicit
 @cindex implicit button
 @findex link-to-file
-@dfn{Implicit buttons} are virtual buttons recognized within the natural
-structure of a document.  For example, a web URL button that displays its link
-or an email address button that starts a mail message to the associated
-address.  Implicit buttons are identified by implicit button type contextual
-pattern matchers that identify appropriate textual patterns at point.
+Hyperbole can recognize and activate @dfn{implicit buttons} within
+documents that require no special markup, e.g. pathnames or URLs, and
+many other types.  For example, an Action Key press on a web URL will
+display its link in a browser, regardless of the format of the
+document.  Similarly, an Action Key press on an email address starts
+composing mail to that address.
 
 @cindex implicit button type
-An @dfn{implicit button type} utilizes Emacs Lisp to identify a pattern or
-state that when matched triggers an @emph{action} associated with the implicit
-button type.  The action is specified by either a Hyperbole action type
-(@pxref{Action Types}) or an Emacs Lisp command.  Implicit button types may use
-the same action types that explicit buttons use.  As an example, the pathname
-implicit button type matches to any existing local filename or directory name
-and its action type, @code{link-to-file}, displays the associated file or
-directory, typically in another window.  An explicit button could do the same
-thing but has to be created manually, rather than recognized as part of the
-buffer text.
+Implicit buttons are identified by implicit button type contextual
+pattern matchers that identify appropriate textual patterns at point.
+An @dfn{implicit button type} utilizes Emacs Lisp to identify a
+pattern or state that when matched triggers an @emph{action}
+associated with the implicit button type.  The action is specified by
+either a Hyperbole action type (@pxref{Action Types}) or an Emacs Lisp
+command.  Implicit button types may use the same action types that
+explicit buttons use.  As an example, the pathname implicit button
+type matches to any existing local filename or directory name and its
+action type, @code{link-to-file}, displays the associated file or
+directory, typically in another window.  An explicit button could do
+the same thing but has to be created manually, rather than recognized
+as part of the buffer text.
 
 @vindex file, hibtypes.el
 @cindex context
@@ -2087,16 +2091,27 @@ button with a label of 'My Emacs Files':
 <[My Emacs Files]>: "~/.emacs.d"
 @end example
 
+The label is delimited by @samp{<[} and @samp{]>} and can be followed
+by any number of :, - or = separator characters, including none.
+
+@kindex C-h h i
+@cindex menu, Ibut
+@cindex menu, Implicit-Button
+@kindex C-h h i a
+@kindex C-h h i c
 @kindex C-h h i e
 @kindex C-h h i l
-The label is delimited by @samp{<[} and @samp{]>} and can be followed
-by any number of :, - or = separator characters, including none.  You
-can activate the button either from its label or its text.  With point
-on the text of an implicit button, @bkbd{C-h h i l} will label it.  Or
-you may simply type the label and delimiters manually.  You can also
-simply edit any implicit button manually but for a little more help in
-editing named implicit buttons, use @bkbd{C-h h i e} which prompts
-you to rename the button and to change its text (the button itself).
+Implicit buttons are managed with the Hyperbole Ibut/ menu accessed
+with @bkbd{C-h h i}.  The Create item, @bkbd{C-h h i c}, prompts for
+an implicit button label, an action type, and the action's associated
+arguments, such as a file to which to link.  It then creates the
+button at point.  To activate the button with point on its label or
+button text, use the Act menu item, @bkbd{C-h h i a} or press the
+Action Key.  You can use @bkbd{C-h h i e} to edit an implicit button
+(or simply edit it manually).  If you want to add a label to an
+existing implicit button without one, use @bkbd{C-h h i l} to label
+it.
+
 
 @menu
 * Implicit Button Types::
diff --git a/test/hmouse-drv-tests.el b/test/hmouse-drv-tests.el
index 2aa345302e..1a814f4c77 100644
--- a/test/hmouse-drv-tests.el
+++ b/test/hmouse-drv-tests.el
@@ -179,7 +179,7 @@
     (goto-char 3)
     (with-simulated-input "TMP RET"
       (hui:ibut-label-create)
-      (should (string= "<[TMP]> \"/tmp\"\n" (buffer-string))))))
+      (should (string= "<[TMP]> - \"/tmp\"\n" (buffer-string))))))
 
 (ert-deftest hbut-ib-create-label-fails-if-label-exists ()
   "Creation of a label for an implicit button fails if a label exists."
diff --git a/test/hui-tests.el b/test/hui-tests.el
index 283eebfca4..1d9e6b379e 100644
--- a/test/hui-tests.el
+++ b/test/hui-tests.el
@@ -91,7 +91,7 @@
     (goto-char 3)
     (with-simulated-input "TMP RET"
       (hui:ibut-label-create)
-      (should (string= "<[TMP]> \"/tmp\"\n" (buffer-string))))))
+      (should (string= "<[TMP]> - \"/tmp\"\n" (buffer-string))))))
 
 (ert-deftest hui-ibut-label-create-fails-if-label-exists ()
   "Creation of a label for an implicit button fails if a label exists."
@@ -123,7 +123,7 @@
   (let ((file (make-temp-file "hypb_" nil ".txt")))
     (unwind-protect
         (find-file file)
-        (with-simulated-input "label RET RET www-url RET www.hypb.org RET"
+        (with-simulated-input "label RET www-url RET www.hypb.org RET"
           (hui:ebut-create)
           (hy-test-helpers-verify-hattr-at-p :actype 'actypes::www-url :args 
'("www.hypb.org") :loc file :lbl-key "label"))
       (delete-file file))))
@@ -134,7 +134,7 @@ Ensure modifying the button but keeping the label does not 
create a double label
   (let ((file (make-temp-file "hypb_" nil ".txt")))
     (unwind-protect
         (find-file file)
-        (with-simulated-input "label RET RET www-url RET www.hypb.org RET"
+        (with-simulated-input "label RET www-url RET www.hypb.org RET"
           (hui:ebut-create)
           (hy-test-helpers-verify-hattr-at-p :actype 'actypes::www-url :args 
'("www.hypb.org") :loc file :lbl-key "label"))
         (with-simulated-input "RET RET RET RET"



reply via email to

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