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

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

[elpa] externals/hyperbole ef9c00eaa8 1/5: Snapshot of still in progress


From: ELPA Syncer
Subject: [elpa] externals/hyperbole ef9c00eaa8 1/5: Snapshot of still in progress ibut updates; see Todo list
Date: Sun, 18 Jun 2023 03:58:39 -0400 (EDT)

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

    Snapshot of still in progress ibut updates; see Todo list
    
    Mostly have to finish ibut:operate whose calling convention has changed.
---
 ChangeLog          |  110 +++++
 TAGS               | 1234 ++++++++++++++++++++++++++--------------------------
 hact.el            |    6 +-
 hactypes.el        |   25 +-
 hargs.el           |   73 +++-
 hbdata.el          |   65 +--
 hbut.el            |  716 ++++++++++++++++++------------
 hibtypes.el        |   48 +-
 hmouse-tag.el      |   36 +-
 hpath.el           |    4 +-
 hui-mouse.el       |   31 +-
 hui.el             |   50 ++-
 hyrolo.el          |    8 +-
 kotl/klink.el      |    6 +-
 kotl/kotl-mode.el  |   11 +-
 kotl/kview.el      |   13 +-
 man/hkey-help.txt  |    2 +-
 man/hyperbole.texi |  123 ++++--
 man/version.texi   |    4 +-
 test/hbut-tests.el |  147 ++++++-
 20 files changed, 1604 insertions(+), 1108 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 56193ac6d5..ee705cebb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,113 @@
+2023-06-11  Bob Weiner  <rsw@gnu.org>
+
+* man/hyperbole.texi (Smart Mouse Drags between Windows): Update appendix doc
+    to latest behavior.
+
+* hbut.el (ibut:operate): Drop 'name' arg and get it from 'hbut:current attrs.
+          (ibut:program):
+  hui.el (hui:ibut-create, hui:ibut-link-create): Change calls to 
'ibut:operate'.
+
+* test/hbut-tests.el (hbut-tests-ibut-insert-annot-bib): Allow for 0 or more
+    whitespace at end of buffer.
+
+* hbdata.el (hbdata:instance-next): Improve doc.
+            (hbdata:ibut-instance): Fix inverted logic when orig-name-key
+    is given.
+
+* hbut.el (ibut:label-instances-regexp, ebut:label-instances-regexp,
+           hbut:label-instances-regexp): Add to search for hbut label
+    matches of all numbered instances.
+          (ibut:label-key-match): Call 'ibut:label-instances-regexp'.
+
+2023-06-10  Bob Weiner  <rsw@gnu.org>
+
+* hbut.el (ibut:create): Invoke 'ibut:set-name-and-label-key-p' prior to
+    finding ibtype when 'but-sym' is not given.
+  man/hyperbole.texi (Programmatic Implicit Button Types): Note that above
+    call automatically sets up to flash delimited implicit buttons when
+    activated.
+          (ibut:edit): Embed this whole function into 'ibut:operate'.
+         (ebut:map): Use defaults for start and end delims.
+          (ibut:label-map): Remove unused delim args and use two optional args.
+
+* kotl/klink.el (klink:act): Document.
+                (klink): Remove 'ibut:set-label' as replaced with global
+    invocation of 'ibut:set-name-and-label-key-p'.
+
+* hbdata.el (hbdata:ibut-instance-last): Remove unused 2nd and 3rd params.
+
+* hui-mouse.el (hkey-alist): Save found smart-lisp identifier to 'hkey-value'
+    for use in 'smart-lisp-find-tag' call.
+  hmouse-tag.el (smart-lisp-at-change-log-tag-p): Fix to return identifier.
+                (smart-lisp): Optimize to send any previously found tag
+    stored in 'hkey-value' to 'smart-lisp-find-tag' call.
+                (smart-lisp-at-known-identifier-p): Caches and return any
+    identifier found.
+
+* man/hyperbole.texi (Smart Key - Identifier Menu Mode):
+  hui-mouse.el (smart-imenu-item-at-p): Move to after programming mode
+    handlers so don't have to test for any such modes here and so it does
+    not override their behaviors.
+
+* hmouse-tag.el (smart-lisp-find-tag): Widen buffer, goto tag location
+    and return t only when 'hpath:display-buffer' returns non-nil.
+
+* hbut.el (ibut:operate): Improve doc.
+
+2023-05-29  Bob Weiner  <rsw@gnu.org>
+
+* hact.el (hact): Set 'hbut:current 'actype property from first arg.
+
+* hbut.el (ibut:operate): Improve create/modify error message.
+          (ibut:at-p): Change so when given name-key-only arg, returns name
+    field as a key, not the text field, lbl-key.  If no name, return nil.
+
+* hactypes.el (link-to-ibut):
+  hui.el (hui:ibut-create, hui:ibut-link-create, hui:gibut-create):
+  hbut.el (ibut:program, ibut:operate, ibut:to, ibut:to-text): Start
+    replacing args named 'label' and 'lbl-key' which represent an ibut
+name with 'name' and 'name-key'.
+          (ibut:to): Change to use 'hbut:current attr 'name' instead of
+    'lbl-key'.
+
+* hbut.el (ibut:program): Fix/generalize error handling.
+          (ibut:create): Fix doc string to reflect return of button
+  instance num string or t for first instance or nil for failure, rather
+  than returning the button symbol.  See 'hbdata:ibut-instance' for details.
+
+* hibtypes.el (action, annot-bib): Call 'ibut:set-name-and-label-key-p)'
+    instead of 'ibut:label-p' so can tell name from label text.
+
+* hbut.el (ibut:operate): Make 2nd arg optional when creating new buttons.
+
+2023-05-28  Bob Weiner  <rsw@gnu.org>
+
+* hbut.el (ibut:operate): Fix to set ibut name property from 'new-lbl-key'.
+          (ibut:create): Fix logic to match doc when but-sym is not given;
+    then prefer args given over any ibut at point (hbut:current); add new
+    internal 'but-sym-flag' to achieve this.
+          (ibut:label-p): Fix doc to indicate can be used to find either
+    the optional name or the text of an implicit button.
+          (ibut:at-p): If in a prog mode and outside of a comment, don't
+    look for button at all, just return nil.  Also, greatly simplify
+    with most functionality left in the 'ibut:create' call.
+          (ibut:set-name-and-label-key-p): Add; extracted from prior
+    'ibut:at-p'.  Use in 'ibut:create'.
+  hargs.el (hargs:delimited): Update to include delims when testing with
+    'exclude-regexp' flag but return the string without delimiters.  This
+    allows ignoring matches to <[str]> when just looking for [str].
+    Also, Add optional arg at end, as-key; when non-nil return string as
+    a Hyperbole label key (no spaces).  Use in 'ibut:label-p'.
+
+* kotl/kview.el (kview:char-invisible-p, kview:char-visible-p): Simplify by
+    using 'get-char-property' which handles text properties and overlays.
+
+* kotl/kotl-mode.el (kotl-mode:pre-self-insert-command): Remove this test
+    since know we are in kotl-mode now that this is added as a mode-specific
+    pre-command hook: (eq major-mode 'kotl-mode).  Also, comment this test
+    out since call should not be on the stack since this is a pre-command
+    hook: (not (hyperb:stack-frame '(kcell-view:to-label-end))).
+
 2023-05-27  Bob Weiner  <rsw@gnu.org>
 
 * kotl/kotl-mode.el (kotl-mode:setup-keymap): Create this function instead
diff --git a/TAGS b/TAGS
index f474fd8be0..13067f5074 100644
--- a/TAGS
+++ b/TAGS
@@ -36,22 +36,22 @@ hact.el,1868
 (defun action:params 327,13457
 (defun action:param-list 348,14242
 (defun hact 359,14669
-(defun    actype:act 367,15057
-(defalias 'actype:elisp-symbol actype:elisp-symbol400,16576
-(defun    actype:def-symbol 402,16629
-(defun    actype:eval 412,16987
-(defun    actype:action 433,17828
-(defun    actype:action-body 450,18339
-(defmacro defact 462,18810
-(def-edebug-spec defact475,19409
-(def-edebug-spec lambda-list480,19553
-(defalias 'actype:create actype:create485,19674
-(defun    actype:delete 487,19710
-(defun    actype:doc 492,19891
-(defun    actype:identity 522,20926
-(defun    actype:interact 527,21108
-(defun    actype:params 535,21480
-(defun    actype:param-list 539,21616
+(defun    actype:act 369,15162
+(defalias 'actype:elisp-symbol actype:elisp-symbol402,16681
+(defun    actype:def-symbol 404,16734
+(defun    actype:eval 414,17092
+(defun    actype:action 435,17933
+(defun    actype:action-body 452,18451
+(defmacro defact 464,18922
+(def-edebug-spec defact477,19521
+(def-edebug-spec lambda-list482,19665
+(defalias 'actype:create actype:create487,19786
+(defun    actype:delete 489,19822
+(defun    actype:doc 494,20003
+(defun    actype:identity 524,21038
+(defun    actype:interact 529,21220
+(defun    actype:params 537,21592
+(defun    actype:param-list 541,21728
 
 hactypes.el,1275
 (defact annot-bib 35,1258
@@ -79,45 +79,45 @@ hactypes.el,1275
 (defact link-to-Info-index-item 469,18495
 (defact link-to-Info-node 484,19252
 (defact link-to-ibut 499,19978
-(defact link-to-kcell 547,21993
-(defact link-to-mail 567,22694
-(defact link-to-org-id 591,23861
-(defact link-to-org-id-marker 600,24174
-(defact link-to-regexp-match 610,24552
-(defact link-to-rfc 637,25623
-(defact link-to-string-match 644,25891
-(defact link-to-texinfo-node 653,26344
-(defact link-to-web-search 678,27397
-(defact man-show 686,27778
-(defact rfc-toc 694,28088
-(defact text-toc 721,29255
-
-hargs.el,961
+(defact link-to-kcell 548,22065
+(defact link-to-mail 568,22766
+(defact link-to-org-id 592,23933
+(defact link-to-org-id-marker 601,24246
+(defact link-to-regexp-match 611,24624
+(defact link-to-rfc 638,25695
+(defact link-to-string-match 645,25963
+(defact link-to-texinfo-node 654,26416
+(defact link-to-web-search 679,27469
+(defact man-show 687,27850
+(defact rfc-toc 695,28160
+(defact text-toc 722,29327
+
+hargs.el,963
 (defvar hargs:defaults 41,1440
 (defvar hargs:reading-type 44,1547
 (defalias 'hargs:find-tag-default hargs:find-tag-default54,1975
 (defun hargs:action-get 56,2031
 (defun hargs:buffer-substring 68,2569
 (defun hargs:delimited 78,3122
-(defun hargs:get 165,6818
-(defmacro hargs:make-iform-vector 202,8391
-(defun hargs:prompt 223,9304
-(defun hargs:select-event-window 232,9619
-(defun hargs:set-string-to-complete 242,10060
-(defun hargs:unset-string-to-complete 250,10416
-(defun hargs:sexpression-p 254,10551
-(defun hargs:actype-get 282,11734
-(defun hargs:at-p 289,12039
-(defun hargs:completion 409,16673
-(defun hargs:iform-read 481,19137
-(defun hargs:read 556,22079
-(defun hargs:read-buffer-name 597,23709
-(defun hargs:read-match 602,23896
-(defun hargs:select-p 635,25260
-(defvar hargs:reading-symbol 674,26794
-(defconst hargs:iform-vector677,26869
-(defconst hargs:iform-extensions-vector783,30389
-(defvar hargs:string-to-complete 842,32727
+(defun hargs:get 190,7777
+(defmacro hargs:make-iform-vector 227,9350
+(defun hargs:prompt 248,10263
+(defun hargs:select-event-window 257,10578
+(defun hargs:set-string-to-complete 267,11019
+(defun hargs:unset-string-to-complete 275,11375
+(defun hargs:sexpression-p 279,11510
+(defun hargs:actype-get 307,12693
+(defun hargs:at-p 314,12998
+(defun hargs:completion 434,17632
+(defun hargs:iform-read 506,20096
+(defun hargs:read 581,23038
+(defun hargs:read-buffer-name 622,24668
+(defun hargs:read-match 627,24855
+(defun hargs:select-p 660,26219
+(defvar hargs:reading-symbol 699,27753
+(defconst hargs:iform-vector702,27828
+(defconst hargs:iform-extensions-vector808,31348
+(defvar hargs:string-to-complete 867,33686
 
 hbdata.el,874
 (defun hbdata:action 75,3130
@@ -138,13 +138,13 @@ hbdata.el,874
 (defun hbdata:ebut-instance-last 267,10523
 (defun hbdata:get-entry 278,10925
 (defun hbdata:ibut-instance 287,11310
-(defun hbdata:ibut-instance-last 314,12447
-(defun hbdata:instance-next 325,12909
-(defun hbdata:to-entry 337,13284
-(defun hbdata:apply-entry 360,14246
-(defun hbdata:to-entry-buf 427,16432
-(defun hbdata:to-hbdata-buffer 474,18262
-(defun hbdata:write 498,19286
+(defun hbdata:ibut-instance-last 317,12465
+(defun hbdata:instance-next 328,12927
+(defun hbdata:to-entry 340,13302
+(defun hbdata:apply-entry 363,14264
+(defun hbdata:to-entry-buf 430,16450
+(defun hbdata:to-hbdata-buffer 477,18280
+(defun hbdata:write 501,19304
 
 hbmap.el,259
 (defvar hbmap:filename 22,642
@@ -156,7 +156,7 @@ hbmap.el,259
 (defvar hbmap:dir-user112,4112
 (defvar hbmap:dir-filename120,4405
 
-hbut.el,5492
+hbut.el,5547
 (defvar   ebut:hattr-save 43,1422
 (defun    ebut:act 47,1539
 (defun    ebut:alist 58,1941
@@ -169,138 +169,139 @@ hbut.el,5492
 (defun    ebut:key 193,7180
 (defun    ebut:key-of-label-p 200,7418
 (defalias 'ebut:to-key-src ebut:to-key-src205,7624
-(defalias 'ebut:key-src-set-buffer ebut:key-src-set-buffer206,7681
-(defalias 'ebut:key-src-fmt ebut:key-src-fmt207,7743
-(defalias 'ebut:key-to-label ebut:key-to-label208,7798
-(defun    ebut:label-p 210,7855
-(defalias 'ebut:label-regexp ebut:label-regexp273,10428
-(defalias 'ebut:label-to-key ebut:label-to-key275,10479
-(defun    ebut:list 277,10530
-(defalias 'map-ebut map-ebut299,11372
-(defun    ebut:map 301,11405
-(defun    ebut:next-occurrence 311,11920
-(defun    ebut:operate 326,12599
-(defun    ebut:program 435,16797
-(defun    ebut:search 466,18248
-(defun    ebut:to 545,20912
-(defun    ebut:delimit 579,22264
-(defun    ebut:match-regexp 606,23332
-(defconst ebut:label-start 617,23772
-(defconst ebut:label-end 619,23873
-(defconst hbut:instance-sep 621,23972
-(defun    gbut:act 628,24312
-(defun    gbut:delete 643,24927
-(defun    gbut:ebut-program 648,25150
-(defun    gbut:file 668,26041
-(defun    gbut:get 672,26199
-(defun    gbut:help 684,26613
-(defun    gbut:label-list 695,27035
-(defun    gbut:label-p 699,27154
-(defun    gbut:to 714,27969
-(defun    gbut:key-list 732,28626
-(defun    gbut:ebut-key-list 736,28752
-(defun    gbut:ibut-key-list 750,29213
-(defun    hattr:attributes 763,29722
-(defun    hattr:clear 773,30027
-(defun    hattr:copy 784,30403
-(defun hattr:emacs-button-attributes 795,30793
-(defun hattr:emacs-button-is-p 808,31283
-(defun    hattr:get 815,31569
-(defun    hattr:list 819,31703
-(defun    hattr:memq 827,31980
-(defun    hattr:report 839,32411
-(defun    hattr:save 867,33437
-(defun    hattr:set 885,34289
-(defalias 'hattr:summarize hattr:summarize889,34468
-(defvar   hattr:filename891,34512
-(defconst hbut:max-len 901,34945
-(defsubst hbut:max-len 908,35186
-(defun    hbut:act 912,35336
-(defun    hbut:action 975,38039
-(defun    hbut:at-p 985,38347
-(defun    hbut:comment 998,38747
-(defvar   hbut:fill-prefix-regexps1031,39974
-(defun    hbut:fill-prefix-remove 1055,40822
-(defun    hbut:delete 1065,41214
-(defun    hbut:funcall 1080,41847
-(defun    hbut:get 1107,42979
-(defun    hbut:get-key-src 1118,43507
-(defun    hbut:is-p 1176,45794
-(defun    hbut:key 1181,45953
-(defun    hbut:to-key-src 1188,46173
-(defun    hbut:key-src-fmt 1195,46492
-(defun    hbut:key-src-set-buffer 1211,47142
-(defun    hbut:key-to-label 1233,47841
-(defun    hbut:label 1254,48525
-(defun    hbut:label-list 1270,49139
-(defun    hbut:label-p 1274,49293
-(defun    hbut:label-regexp 1287,50068
-(defun    hbut:label-to-key 1321,51295
-(defun    hbut:map 1334,51885
-(defvar   hbut:syntax-table 1390,54072
-(defun    hbut:modify-syntax 1396,54342
-(defun    hbut:outside-comment-p 1411,54969
-(defun    hbut:rename 1419,55329
-(defun    hbut:report 1430,55735
-(defun    hbut:source 1489,57669
-(defalias 'hbut:summarize hbut:summarize1504,58242
-(defun    hbut:to 1506,58283
-(defvar   hbut:current 1513,58611
-(defconst hbut:source-prefix 1516,58716
-(defun    hbut:key-list 1523,59047
-(defun    hbut:ebut-key-list 1527,59212
-(defun    hbut:ibut-key-list 1542,59737
-(defun    ibut:act 1556,60280
-(defun    ibut:alist 1567,60686
-(defun    ibut:at-p 1573,60915
-(defun    ibut:at-type-p 1617,62754
-(cl-defun ibut:create 1633,63478
-(def-edebug-spec cl-defun1758,67787
-(def-edebug-spec lambda-key-list1763,67934
-(defun    ibut:delete 1769,68106
-(defun    ibut:delimit 1796,69112
-(defun    ibut:edit 1823,70181
-(defun    ibut:get 1834,70655
-(defun    ibut:is-p 1856,71472
-(defun    ibut:label-map 1864,71765
-(defun    ibut:label-key-match 1879,72554
-(defun    ibut:label-p 1889,72934
-(defun    ibut:label-regexp 1907,73924
-(defun    ibut:label-set 1913,74215
-(defun    ibut:label-sort-keys 1935,75246
-(defun    ibut:list 1954,75876
-(defun    ibut:key 1976,76727
-(defalias 'ibut:to-key-src ibut:to-key-src1983,76965
-(defalias 'ibut:key-to-label ibut:key-to-label1984,77012
-(defalias 'ibut:label-to-key ibut:label-to-key1985,77061
-(defalias 'map-ibut map-ibut1986,77110
-(defun    ibut:map 1988,77151
-(defun    ibut:next-occurrence 1999,77644
-(defun    ibut:operate 2014,78389
-(defun    ibut:insert-text 2136,82879
-(defun    ibut:previous-occurrence 2185,85074
-(defun    ibut:program 2200,85805
-(defun    ibut:rename 2231,87256
-(defalias 'ibut:summarize ibut:summarize2251,88191
-(defun    ibut:to 2253,88232
-(defun    ibut:at-to-name-p 2301,89892
-(defun    ibut:to-name 2325,90690
-(defun    ibut:to-text 2359,92029
-(defconst ibut:label-start 2410,94098
-(defconst ibut:label-end 2412,94199
-(defvar   ibut:label-separator 2415,94299
-(defvar   ibut:label-separator-regexp 2423,94616
-(defmacro defib 2430,94955
-(def-edebug-spec defib2467,96640
-(def-edebug-spec lambda-list2472,96780
-(defalias 'ibtype:create ibtype:create2477,96898
-(defun ibtype:activate-link 2479,96933
-(defmacro defil 2491,97382
-(defmacro defal 2588,101720
-(defalias 'ibtype:create-action-link-type 
ibtype:create-action-link-type2644,103889
-(defalias 'ibtype:create-regexp-link-type 
ibtype:create-regexp-link-type2645,103940
-(defun    ibtype:def-symbol 2647,103992
-(defun    ibtype:delete 2657,104349
+(defalias 'ebut:key-src-set-buffer ebut:key-src-set-buffer206,7678
+(defalias 'ebut:key-src-fmt ebut:key-src-fmt207,7740
+(defalias 'ebut:key-to-label ebut:key-to-label208,7795
+(defun    ebut:label-p 210,7852
+(defalias 'ebut:label-regexp ebut:label-regexp273,10425
+(defalias 'ebut:label-to-key ebut:label-to-key275,10476
+(defun    ebut:list 277,10527
+(defalias 'map-ebut map-ebut299,11369
+(defun    ebut:map 301,11402
+(defun    ebut:next-occurrence 311,11917
+(defun    ebut:operate 326,12596
+(defun    ebut:program 435,16794
+(defun    ebut:search 466,18245
+(defun    ebut:to 545,20909
+(defun    ebut:delimit 579,22261
+(defun    ebut:match-regexp 606,23329
+(defconst ebut:label-start 617,23769
+(defconst ebut:label-end 619,23870
+(defconst hbut:instance-sep 621,23969
+(defun    gbut:act 628,24309
+(defun    gbut:delete 643,24924
+(defun    gbut:ebut-program 648,25147
+(defun    gbut:file 668,26038
+(defun    gbut:get 672,26196
+(defun    gbut:help 684,26610
+(defun    gbut:label-list 695,27032
+(defun    gbut:label-p 699,27151
+(defun    gbut:to 714,27966
+(defun    gbut:key-list 732,28623
+(defun    gbut:ebut-key-list 736,28749
+(defun    gbut:ibut-key-list 750,29210
+(defun    hattr:attributes 763,29719
+(defun    hattr:clear 773,30024
+(defun    hattr:copy 784,30400
+(defun hattr:emacs-button-attributes 795,30790
+(defun hattr:emacs-button-is-p 808,31280
+(defun    hattr:get 815,31566
+(defun    hattr:list 819,31700
+(defun    hattr:memq 827,31977
+(defun    hattr:report 839,32408
+(defun    hattr:save 867,33434
+(defun    hattr:set 885,34286
+(defalias 'hattr:summarize hattr:summarize889,34465
+(defvar   hattr:filename891,34509
+(defconst hbut:max-len 901,34942
+(defsubst hbut:max-len 908,35183
+(defun    hbut:act 912,35333
+(defun    hbut:action 975,38036
+(defun    hbut:at-p 985,38344
+(defun    hbut:comment 998,38744
+(defvar   hbut:fill-prefix-regexps1031,39971
+(defun    hbut:fill-prefix-remove 1055,40819
+(defun    hbut:delete 1065,41211
+(defun    hbut:funcall 1080,41844
+(defun    hbut:get 1107,42976
+(defun    hbut:get-key-src 1118,43504
+(defun    hbut:is-p 1176,45791
+(defun    hbut:key 1181,45950
+(defun    hbut:to-key-src 1188,46170
+(defun    hbut:key-src-fmt 1195,46489
+(defun    hbut:key-src-set-buffer 1211,47139
+(defun    hbut:key-to-label 1233,47838
+(defun    hbut:label 1254,48522
+(defun    hbut:label-list 1270,49136
+(defun    hbut:label-p 1274,49290
+(defun    hbut:label-regexp 1287,50065
+(defun    hbut:label-to-key 1321,51292
+(defun    hbut:map 1334,51882
+(defvar   hbut:syntax-table 1390,54069
+(defun    hbut:modify-syntax 1396,54339
+(defun    hbut:outside-comment-p 1411,54966
+(defun    hbut:rename 1419,55326
+(defun    hbut:report 1430,55732
+(defun    hbut:source 1489,57666
+(defalias 'hbut:summarize hbut:summarize1504,58239
+(defun    hbut:to 1506,58280
+(defvar   hbut:current 1513,58608
+(defconst hbut:source-prefix 1516,58713
+(defun    hbut:key-list 1523,59044
+(defun    hbut:ebut-key-list 1527,59209
+(defun    hbut:ibut-key-list 1542,59734
+(defun    ibut:act 1556,60277
+(defun    ibut:alist 1567,60683
+(defun    ibut:at-p 1573,60912
+(defun    ibut:at-type-p 1592,61759
+(defun  ibut:set-name-and-label-key-p 1608,62483
+(cl-defun ibut:create 1672,64803
+(def-edebug-spec cl-defun1841,70541
+(def-edebug-spec lambda-key-list1846,70688
+(defun    ibut:delete 1852,70860
+(defun    ibut:delimit 1879,71866
+(defun    ibut:edit 1906,72935
+(defun    ibut:get 1918,73428
+(defun    ibut:is-p 1940,74245
+(defun    ibut:label-map 1948,74538
+(defun    ibut:label-key-match 1963,75327
+(defun    ibut:label-p 1973,75707
+(defun    ibut:label-regexp 2009,77388
+(defun    ibut:label-set 2015,77679
+(defun    ibut:label-sort-keys 2037,78710
+(defun    ibut:list 2056,79340
+(defun    ibut:key 2078,80191
+(defalias 'ibut:to-key-src ibut:to-key-src2085,80429
+(defalias 'ibut:key-to-label ibut:key-to-label2086,80476
+(defalias 'ibut:label-to-key ibut:label-to-key2087,80525
+(defalias 'map-ibut map-ibut2088,80574
+(defun    ibut:map 2090,80615
+(defun    ibut:next-occurrence 2101,81108
+(defun    ibut:operate 2116,81853
+(defun    ibut:insert-text 2244,86635
+(defun    ibut:previous-occurrence 2294,88866
+(defun    ibut:program 2309,89597
+(defun    ibut:rename 2339,90971
+(defalias 'ibut:summarize ibut:summarize2359,91906
+(defun    ibut:to 2361,91947
+(defun    ibut:at-to-name-p 2411,93674
+(defun    ibut:to-name 2435,94472
+(defun    ibut:to-text 2469,95811
+(defconst ibut:label-start 2520,97895
+(defconst ibut:label-end 2522,97996
+(defvar   ibut:label-separator 2525,98096
+(defvar   ibut:label-separator-regexp 2533,98413
+(defmacro defib 2540,98752
+(def-edebug-spec defib2577,100437
+(def-edebug-spec lambda-list2582,100577
+(defalias 'ibtype:create ibtype:create2587,100695
+(defun ibtype:activate-link 2589,100730
+(defmacro defil 2601,101179
+(defmacro defal 2698,105517
+(defalias 'ibtype:create-action-link-type 
ibtype:create-action-link-type2754,107686
+(defalias 'ibtype:create-regexp-link-type 
ibtype:create-regexp-link-type2755,107737
+(defun    ibtype:def-symbol 2757,107789
+(defun    ibtype:delete 2767,108146
 
 hgnus.el,110
 (defun Gnus-init 54,1683
@@ -413,47 +414,47 @@ hibtypes.el,1664
 (defib mail-address 323,14699
 (defib org-link-outside-org-mode 363,16585
 (defib annot-bib 382,17479
-(defun markdown-follow-link-p 405,18575
-(defun markdown-follow-inline-link-p 426,19240
-(defib markdown-internal-link 453,20524
-(defib rfc-toc 483,22068
-(defib id-cflow 508,23138
-(defib ctags 555,25192
-(defib etags 581,26594
-(defib cscope 618,28499
-(defib text-toc 645,29651
-(defib dir-summary 677,31233
-(defib rfc 713,32803
-(defib man-apropos 745,34215
-(defun hlink 770,35274
-(defun parse-label-and-file 790,36261
-(defconst elink:start 812,37166
-(defconst elink:end 814,37271
-(defib elink 817,37369
-(defconst glink:start 827,37770
-(defconst glink:end 829,37873
-(defib glink 832,37969
-(defconst ilink:start 841,38259
-(defconst ilink:end 843,38364
-(defib ilink 846,38462
-(defib pathname-line-and-column 861,39118
-(defib ipython-stack-frame 889,40711
-(defib ripgrep-msg 931,42873
-(defib grep-msg 977,45014
-(defun hib-python-traceback 1045,48862
-(defib debugger-source 1056,49474
-(defib elisp-compiler-msg 1142,53515
-(defib patch-msg 1244,58586
-(defib texinfo-ref 1271,59790
-(defib gnus-push-button 1356,64318
-(defib Info-node 1368,64860
-(defib hyp-address 1401,66549
-(defib hyp-source 1420,67563
-(defconst action:start 1447,68682
-(defconst action:end 1450,68791
-(defib action 1459,69141
-(defun action:help 1557,73748
-(defib completion 1584,74840
+(defun markdown-follow-link-p 404,18525
+(defun markdown-follow-inline-link-p 425,19190
+(defib markdown-internal-link 452,20474
+(defib rfc-toc 482,22018
+(defib id-cflow 507,23088
+(defib ctags 554,25142
+(defib etags 580,26544
+(defib cscope 617,28449
+(defib text-toc 644,29601
+(defib dir-summary 676,31183
+(defib rfc 712,32753
+(defib man-apropos 744,34165
+(defun hlink 769,35224
+(defun parse-label-and-file 789,36211
+(defconst elink:start 811,37116
+(defconst elink:end 813,37221
+(defib elink 816,37319
+(defconst glink:start 826,37720
+(defconst glink:end 828,37823
+(defib glink 831,37919
+(defconst ilink:start 840,38209
+(defconst ilink:end 842,38314
+(defib ilink 845,38412
+(defib pathname-line-and-column 860,39068
+(defib ipython-stack-frame 888,40661
+(defib ripgrep-msg 930,42823
+(defib grep-msg 976,44964
+(defun hib-python-traceback 1044,48812
+(defib debugger-source 1055,49424
+(defib elisp-compiler-msg 1141,53465
+(defib patch-msg 1243,58536
+(defib texinfo-ref 1270,59740
+(defib gnus-push-button 1355,64268
+(defib Info-node 1367,64810
+(defib hyp-address 1400,66499
+(defib hyp-source 1419,67513
+(defconst action:start 1446,68632
+(defconst action:end 1449,68741
+(defib action 1458,69091
+(defun action:help 1557,73575
+(defib completion 1584,74667
 
 hinit.el,145
 (defvar   hyperb:user-email 22,623
@@ -850,51 +851,51 @@ hpath.el,5601
 (defun hpath:file-line-and-column 1313,59154
 (defun hpath:find-noselect 1331,60031
 (defun hpath:find 1340,60380
-(defun hpath:to-markup-anchor 1505,67368
-(defun hpath:find-executable 1569,70107
-(defun hpath:find-line 1584,70611
-(defun hpath:find-other-frame 1604,71381
-(defun hpath:find-other-window 1619,71859
-(defun hpath:get-external-display-alist 1629,72354
-(defun hpath:is-p 1648,73343
-(defun hpath:push-tag-mark 1749,78156
-(defun hpath:relative-arguments 1763,78668
-(defun hpath:relative-to 1773,79098
-(defun hpath:rfc 1805,80386
-(defun hpath:start-end 1810,80559
-(defun hpath:return-one-value 1839,81763
-(defun hpath:substitute-value 1877,83444
-(defun hpath:substitute-var 1921,85099
-(defun hpath:symlink-referent 1959,86565
-(defun hpath:symlink-expand 1974,87160
-(defun hpath:to-line 2009,88799
-(defun hpath:trim 2018,89086
-(defun hpath:normalize 2027,89424
-(defun hpath:validate 2035,89810
-(defun hpath:find-file-urls-p 2058,90717
-(defun hpath:handle-urls 2064,90976
-(defalias 
'hyperb:substitute-in-file-namehyperb:substitute-in-file-name2081,91718
-(defun substitute-in-file-name 2084,91809
-(defun hpath:enable-find-file-urls 2097,92451
-(defun hpath:disable-find-file-urls 2128,93581
-(defun hpath:find-file-urls-mode 2157,94616
-(defun hpath:url-at-p 2169,95103
-(defun hpath:url-p 2180,95594
-(defun hpath:www-at-p 2191,95989
-(defun hpath:www-p 2207,96686
-(defun hpath:command-string 2215,97009
-(defun hpath:display-where-function 2224,97416
-(defun hpath:remote-available-p 2234,97886
-(defun hpath:remote-default-user 2253,98733
-(defun hpath:delete-trailer 2267,99189
-(defun hpath:exists-p 2275,99473
-(defun hpath:find-file-mailcap 2306,100470
-(defun hpath:find-program 2322,100986
-(defun hpath:match 2343,101857
-(defun hpath:get-single-string-variable-value 2357,102457
-(defun hpath:substitute-dir 2387,103551
-(defun hpath:substitute-match-value 2453,106634
-(defun hpath:substitute-var-name 2515,108850
+(defun hpath:to-markup-anchor 1505,67365
+(defun hpath:find-executable 1569,70104
+(defun hpath:find-line 1584,70608
+(defun hpath:find-other-frame 1604,71378
+(defun hpath:find-other-window 1619,71856
+(defun hpath:get-external-display-alist 1629,72351
+(defun hpath:is-p 1648,73340
+(defun hpath:push-tag-mark 1749,78153
+(defun hpath:relative-arguments 1763,78665
+(defun hpath:relative-to 1773,79095
+(defun hpath:rfc 1805,80383
+(defun hpath:start-end 1810,80556
+(defun hpath:return-one-value 1839,81760
+(defun hpath:substitute-value 1877,83441
+(defun hpath:substitute-var 1921,85096
+(defun hpath:symlink-referent 1959,86562
+(defun hpath:symlink-expand 1974,87157
+(defun hpath:to-line 2009,88796
+(defun hpath:trim 2018,89083
+(defun hpath:normalize 2027,89421
+(defun hpath:validate 2035,89807
+(defun hpath:find-file-urls-p 2058,90714
+(defun hpath:handle-urls 2064,90973
+(defalias 
'hyperb:substitute-in-file-namehyperb:substitute-in-file-name2081,91715
+(defun substitute-in-file-name 2084,91806
+(defun hpath:enable-find-file-urls 2097,92448
+(defun hpath:disable-find-file-urls 2128,93578
+(defun hpath:find-file-urls-mode 2157,94613
+(defun hpath:url-at-p 2169,95100
+(defun hpath:url-p 2180,95591
+(defun hpath:www-at-p 2191,95986
+(defun hpath:www-p 2207,96683
+(defun hpath:command-string 2215,97006
+(defun hpath:display-where-function 2224,97413
+(defun hpath:remote-available-p 2234,97883
+(defun hpath:remote-default-user 2253,98730
+(defun hpath:delete-trailer 2267,99186
+(defun hpath:exists-p 2275,99470
+(defun hpath:find-file-mailcap 2306,100467
+(defun hpath:find-program 2322,100983
+(defun hpath:match 2343,101854
+(defun hpath:get-single-string-variable-value 2357,102454
+(defun hpath:substitute-dir 2387,103548
+(defun hpath:substitute-match-value 2453,106631
+(defun hpath:substitute-var-name 2515,108847
 
 hrmail.el,723
 (defun Rmail-init 47,1512
@@ -1512,48 +1513,48 @@ hui.el,2327
 (defun hui:gbut-edit 564,22760
 (defun hui:gbut-rename 653,26201
 (defun hui:gibut-create 665,26664
-(defun hui:hbut-act 693,27704
-(defun hui:hbut-buf 701,28077
-(defun hui:hbut-current-act 726,28839
-(defun hui:hbut-delete 736,29213
-(defun hui:hbut-help 776,30986
-(defun hui:hbut-label 817,32472
-(defun hui:hbut-label-default 828,32969
-(defun hui:hbut-rename 843,33704
-(defun hui:hbut-report 853,34060
-(defalias 'hui:hbut-summarize hui:hbut-summarize864,34412
-(defun hui:ibut-act 866,34462
-(defun hui:ibut-create 881,35028
-(defun hui:ibut-edit 914,36404
-(defun hui:ibut-label-create 984,39081
-(defun hui:ibut-rename 1022,40956
-(defun hui:link 1056,42113
-(defun hui:ebut-link-directly 1060,42273
-(defun hui:ibut-link-directly 1131,45108
-(defun hui:action 1209,48256
-(defun hui:actype 1262,49989
-(defun hui:buf-writable-err 1281,50982
-(defvar hui:ignore-buffers-regexp 1301,51845
-(defun hui:ebut-delete-op 1304,52015
-(defun hui:ebut-message 1335,53268
-(defun hui:ebut-unmark 1346,53672
-(defun hui:file-find 1406,56135
-(defun hui:hbut-operate 1413,56405
-(defun hui:hbut-term-highlight 1438,57520
-(defun hui:hbut-term-unhighlight 1452,57922
-(defun hui:help-ebut-highlight 1461,58208
-(defun hui:htype-delete 1467,58456
-(defun hui:htype-help 1478,58863
-(defun hui:htype-help-current-window 1529,60631
-(defun hui:ibut-delete-op 1536,60996
-(defun hui:ibut-message 1560,62099
-(defun hui:key-dir 1571,62503
-(defun hui:key-src 1580,62851
-(defun hui:ebut-link-create 1589,63222
-(defun hui:ibut-link-create 1612,64421
-(defun hui:link-possible-types 1635,65620
-(defun hui:list-remove-text-properties 1768,70988
-(defvar hui:ebut-label-prev 1778,71378
+(defun hui:hbut-act 693,27715
+(defun hui:hbut-buf 701,28088
+(defun hui:hbut-current-act 726,28850
+(defun hui:hbut-delete 736,29224
+(defun hui:hbut-help 776,30997
+(defun hui:hbut-label 817,32483
+(defun hui:hbut-label-default 828,32980
+(defun hui:hbut-rename 843,33715
+(defun hui:hbut-report 853,34071
+(defalias 'hui:hbut-summarize hui:hbut-summarize864,34423
+(defun hui:ibut-act 866,34473
+(defun hui:ibut-create 881,35039
+(defun hui:ibut-edit 914,36421
+(defun hui:ibut-label-create 984,39098
+(defun hui:ibut-rename 1022,40973
+(defun hui:link 1056,42130
+(defun hui:ebut-link-directly 1060,42290
+(defun hui:ibut-link-directly 1131,45125
+(defun hui:action 1211,48339
+(defun hui:actype 1264,50072
+(defun hui:buf-writable-err 1283,51065
+(defvar hui:ignore-buffers-regexp 1303,51928
+(defun hui:ebut-delete-op 1306,52098
+(defun hui:ebut-message 1337,53351
+(defun hui:ebut-unmark 1348,53755
+(defun hui:file-find 1408,56218
+(defun hui:hbut-operate 1415,56488
+(defun hui:hbut-term-highlight 1440,57601
+(defun hui:hbut-term-unhighlight 1454,58003
+(defun hui:help-ebut-highlight 1463,58289
+(defun hui:htype-delete 1469,58537
+(defun hui:htype-help 1480,58944
+(defun hui:htype-help-current-window 1531,60712
+(defun hui:ibut-delete-op 1538,61077
+(defun hui:ibut-message 1562,62180
+(defun hui:key-dir 1573,62584
+(defun hui:key-src 1582,62932
+(defun hui:ebut-link-create 1591,63303
+(defun hui:ibut-link-create 1614,64502
+(defun hui:link-possible-types 1637,65699
+(defun hui:list-remove-text-properties 1770,71067
+(defvar hui:ebut-label-prev 1780,71457
 
 hvar.el,272
 (defvar var::append-list 34,1095
@@ -2112,190 +2113,190 @@ kotl/kotl-mode.el,9397
 (defvar yank-window-start 76,2909
 (defvar yank-undo-function 77,2940
 (defun kotl-mode 93,3588
-(defun kotl-mode:example 214,8413
-(defalias 
'kotl-mode:backward-delete-char-untabifykotl-mode:backward-delete-char-untabify270,10829
-(defalias 
'kotl-mode:backward-delete-charkotl-mode:backward-delete-char272,10915
-(defalias 
'kotl-mode:delete-forward-charkotl-mode:delete-forward-char274,10992
-(defalias 'kotl-mode:left-char kotl-mode:left-char276,11059
-(defalias 'kotl-mode:right-char kotl-mode:right-char277,11116
-(defun kotl-mode:backward-kill-word 279,11174
-(defun kotl-mode:backward-or-forward-delete-char 295,11694
-(defun kotl-mode:center-line 303,12109
-(defun kotl-mode:center-paragraph 326,12957
-(defun kotl-mode:copy-kcell-reference-to-register 348,13756
-(defun kotl-mode:copy-absolute-kcell-link-to-kill-ring 363,14410
-(defun kotl-mode:copy-relative-kcell-link-to-kill-ring 370,14693
-(defun kotl-mode:copy-absolute-kcell-link-to-register 376,14930
-(defun kotl-mode:copy-relative-kcell-link-to-register 383,15260
-(defun kotl-mode:copy-region-as-kill 390,15580
-(defun kotl-mode:copy-to-register 395,15763
-(defun kotl-mode:delete-backward-char 408,16227
-(defun kotl-mode:delete-blank-lines 422,16744
-(defun kotl-mode:delete-char 445,17610
-(defun kotl-mode:delete-horizontal-space 509,19854
-(defun kotl-mode:delete-indentation 520,20154
-(defun kotl-mode:skip-filling-p 545,21046
-(defun kotl-mode:fill-cell 560,21527
-(defun kotl-mode:fill-paragraph 616,23807
-(defun kotl-mode:fill-tree 649,25211
-(defun kotl-mode:just-one-space 657,25611
-(defun kotl-mode:kill-line 666,25898
-(defalias 'kotl-mode:kill-visual-line kotl-mode:kill-visual-line699,27023
-(defun kotl-mode:kill-whole-line 701,27084
-(defun kotl-mode:kill-region 707,27247
-(defun kotl-mode:kill-or-copy-region 763,29591
-(defalias 'kotl-mode:completion-kill-region 
kotl-mode:completion-kill-region798,30769
-(defalias 'kotl-mode:kill-ring-save kotl-mode:kill-ring-save801,30856
-(defun kotl-mode:kill-sentence 803,30925
-(defun kotl-mode:kill-word 819,31427
-(defun kotl-mode:newline 835,31911
-(defalias 'kotl-mode:electric-indent-just-newline 
kotl-mode:electric-indent-just-newline855,32465
-(defalias 'kotl-mode:electric-newline-and-maybe-indent 
kotl-mode:electric-newline-and-maybe-indent856,32535
-(defalias 'kotl-mode:newline-and-indent kotl-mode:newline-and-indent857,32610
-(defalias 'kotl-mode:reindent-then-newline-and-indent 
kotl-mode:reindent-then-newline-and-indent858,32670
-(defun kotl-mode:open-line 860,32745
-(defun kotl-mode:quoted-insert 879,33330
-(defun kotl-mode:set-fill-prefix 918,34943
-(defun kotl-mode:tab-command 924,35170
-(defun kotl-mode:toggle-indent-tabs-mode 939,35789
-(defun kotl-mode:toggle-tab-flag 948,36196
-(defun kotl-mode:transpose-chars 959,36735
-(defun kotl-mode:transpose-lines 972,37424
-(defun kotl-mode:transpose-paragraphs 1021,39335
-(defun kotl-mode:transpose-sentences 1026,39537
-(defun kotl-mode:transpose-words 1031,39728
-(defun kotl-mode:untab-command 1039,40139
-(defun kotl-mode:zap-to-char 1056,40838
-(defun kotl-mode:append-cell 1067,41300
-(defun kotl-mode:clipboard-yank 1092,42345
-(defun kotl-mode:copy-after 1098,42532
-(defun kotl-mode:copy-before 1123,43503
-(defun kotl-mode:move-after 1148,44529
-(defun kotl-mode:move-before 1245,48485
-(defun kotl-mode:yank 1339,52422
-(defun kotl-mode:yank-pop 1374,53917
-(defalias 'kotl-mode:scroll-down-command 
kotl-mode:scroll-down-command1420,55840
-(defalias 'kotl-mode:scroll-up-command kotl-mode:scroll-up-command1421,55905
-(defun kotl-mode:back-to-indentation 1423,55968
-(defun kotl-mode:backward-cell 1430,56203
-(defun kotl-mode:backward-char 1451,56993
-(defun kotl-mode:backward-paragraph 1473,57666
-(defalias 'kotl-mode:backward-para kotl-mode:backward-para1487,58148
-(defun kotl-mode:backward-sentence 1489,58215
-(defun kotl-mode:backward-word 1518,59250
-(defun kotl-mode:beginning-of-buffer 1537,59768
-(defun kotl-mode:beginning-of-cell 1548,60122
-(defun kotl-mode:beginning-of-line 1561,60577
-(defalias 'kotl-mode:beginning-of-visual-line 
kotl-mode:beginning-of-visual-line1576,61141
-(defalias 'kotl-mode:move-beginning-of-line 
kotl-mode:move-beginning-of-line1577,61217
-(defun kotl-mode:beginning-of-tree 1579,61292
-(defun kotl-mode:down-level 1592,61834
-(defun kotl-mode:end-of-buffer 1612,62472
-(defun kotl-mode:end-of-cell 1624,62837
-(defun kotl-mode:to-end-of-line 1640,63500
-(defalias 'kotl-mode:end-of-line kotl-mode:end-of-line1655,64069
-(defalias 'kotl-mode:end-of-visual-line 
kotl-mode:end-of-visual-line1656,64129
-(defalias 'kotl-mode:move-end-of-line kotl-mode:move-end-of-line1657,64196
-(defun kotl-mode:end-of-tree 1659,64262
-(defun kotl-mode:first-sibling 1682,65252
-(defun kotl-mode:forward-cell 1694,65784
-(defun kotl-mode:forward-char 1709,66372
-(defun kotl-mode:forward-paragraph 1727,66916
-(defalias 'kotl-mode:forward-para kotl-mode:forward-para1750,67739
-(defun kotl-mode:forward-sentence 1752,67804
-(defun kotl-mode:forward-word 1780,68776
-(defun kotl-mode:goto-cell 1803,69525
-(defun kotl-mode:head-cell 1843,71147
-(defun kotl-mode:last-sibling 1854,71521
-(defun kotl-mode:mark-paragraph 1866,72053
-(defun kotl-mode:mark-whole-buffer 1876,72372
-(defun kotl-mode:next-cell 1884,72625
-(defun kotl-mode:next-line 1898,73090
-(defun kotl-mode:next-tree 1923,73972
-(defun kotl-mode:previous-line 1935,74486
-(defun kotl-mode:previous-cell 1959,75349
-(defun kotl-mode:scroll-down 1980,76045
-(defun kotl-mode:scroll-up 1989,76362
-(defun kotl-mode:tail-cell 1998,76669
-(defun kotl-mode:up-level 2010,77062
-(defun kotl-mode:bobp 2036,78014
-(defun kotl-mode:bocp 2043,78234
-(defun kotl-mode:bolp 2056,78668
-(defun kotl-mode:buffer-empty-p 2061,78817
-(defun kotl-mode:eobp 2067,79004
-(defun kotl-mode:eocp 2072,79162
-(defun kotl-mode:eolp 2083,79473
-(defun kotl-mode:first-cell-p 2094,79888
-(defalias 'kotl-mode:first-line-p kotl-mode:first-line-p2098,80030
-(defun kotl-mode:last-cell-p 2100,80080
-(defun kotl-mode:last-line-p 2104,80216
-(defun kotl-mode:action-key 2115,80563
-(defun kotl-mode:assist-key 2157,82459
-(defun kotl-mode:add-child 2198,84344
-(defun kotl-mode:add-parent 2203,84492
-(defun kotl-mode:add-cell 2208,84644
-(defun kotl-mode:demote-tree 2291,87858
-(defun kotl-mode:exchange-cells 2353,90038
-(defun kotl-mode:kill-contents 2431,92883
-(defun kotl-mode:kill-tree 2439,93131
-(defun kotl-mode:move-tree-backward 2467,94143
-(defun kotl-mode:move-tree-forward 2476,94507
-(defun kotl-mode:promote-tree 2500,95465
-(defun kotl-mode:remove-cell-attribute 2544,96969
-(defun kotl-mode:set-cell-attribute 2589,98643
-(defun kotl-mode:set-or-remove-cell-attribute 2647,100910
-(defun kotl-mode:split-cell 2669,101923
-(defun kotl-mode:transpose-cells 2700,103122
-(defun kotl-mode:copy-region-to-buffer 2754,105218
-(defun kotl-mode:copy-tree-to-buffer 2777,106209
-(defun kotl-mode:copy-tree-or-region-to-buffer 2807,107547
-(defun kotl-mode:mail-tree 2820,108050
-(defun kotl-mode:collapse-tree 2847,108992
-(defun kotl-mode:expand-tree 2859,109475
-(defun kotl-mode:toggle-tree-expansion 2873,110022
-(defun kotl-mode:overview 2886,110470
-(defun kotl-mode:show-all 2896,110756
-(defun kotl-mode:top-cells 2910,111246
-(defun kotl-mode:hide-sublevels 2925,111734
-(defun kotl-mode:hide-subtree 2936,112244
-(defun kotl-mode:show-subtree 2953,112876
-(defun kotl-mode:hide-tree 2959,113081
-(defun kotl-mode:show-tree 2979,113808
-(defun kotl-mode:cell-attributes 2984,113961
-(defun kotl-mode:cell-help 2999,114538
-(defun kotl-mode:get-cell-attribute 3053,116582
-(defun kotl-mode:org-delete-backward-char 3080,117684
-(defun kotl-mode:org-delete-char 3090,118185
-(defun kotl-mode:org-force-self-insert 3100,118664
-(defun kotl-mode:org-self-insert-command 3106,118844
-(defun kotl-mode:orgtbl-ctrl-c-ctrl-c 3114,119192
-(defun kotl-mode:orgtbl-create-or-convert-from-region 3122,119470
-(defun kotl-mode:orgtbl-self-insert-command 3130,119823
-(defun kotl-mode:self-insert-command 3139,120176
-(defun kotl-mode:add-indent-to-region 3157,121097
-(defun kotl-mode:delete-line 3169,121603
-(defun kotl-mode:exchange-point-and-mark 3183,122091
-(defun kotl-mode:indent-line 3189,122369
-(defun kotl-mode:indent-region 3203,122859
-(defun kotl-mode:is-p 3208,122987
-(defun kotl-mode:shrink-region 3215,123227
-(defun kotl-mode:valid-region-p 3234,124103
-(defun kotl-mode:maybe-shrink-region-p 3244,124497
-(defun kotl-mode:tree-end 3269,125483
-(defun kotl-mode:tree-start 3288,126230
-(defun kotl-mode:line-move 3293,126419
-(defun kotl-mode:pre-self-insert-command 3312,127092
-(defun kotl-mode:print-attributes 3324,127694
-(defun kotl-mode:isearch-open-invisible 3343,128443
-(defun kotl-mode:reveal-toggle-invisible 3346,128587
-(defun kotl-mode:set-temp-goal-column 3387,130292
-(defun kotl-mode:to-visible-position 3398,130694
-(defun kotl-mode:to-valid-position 3411,131275
-(defun kotl-mode:transpose-lines-internal 3428,131977
-(defun kotl-mode:update-buffer 3451,132752
-(defun kotl-mode:maintain-region-highlight 3462,133075
-(defun kotl-mode:setup-keymap 3467,133232
-(defun delete-selection-pre-hook 3680,142578
+(defun kotl-mode:example 215,8460
+(defalias 
'kotl-mode:backward-delete-char-untabifykotl-mode:backward-delete-char-untabify271,10876
+(defalias 
'kotl-mode:backward-delete-charkotl-mode:backward-delete-char273,10962
+(defalias 
'kotl-mode:delete-forward-charkotl-mode:delete-forward-char275,11039
+(defalias 'kotl-mode:left-char kotl-mode:left-char277,11106
+(defalias 'kotl-mode:right-char kotl-mode:right-char278,11163
+(defun kotl-mode:backward-kill-word 280,11221
+(defun kotl-mode:backward-or-forward-delete-char 296,11741
+(defun kotl-mode:center-line 304,12156
+(defun kotl-mode:center-paragraph 327,13004
+(defun kotl-mode:copy-kcell-reference-to-register 349,13803
+(defun kotl-mode:copy-absolute-kcell-link-to-kill-ring 364,14457
+(defun kotl-mode:copy-relative-kcell-link-to-kill-ring 371,14740
+(defun kotl-mode:copy-absolute-kcell-link-to-register 377,14977
+(defun kotl-mode:copy-relative-kcell-link-to-register 384,15307
+(defun kotl-mode:copy-region-as-kill 391,15627
+(defun kotl-mode:copy-to-register 396,15810
+(defun kotl-mode:delete-backward-char 409,16274
+(defun kotl-mode:delete-blank-lines 423,16791
+(defun kotl-mode:delete-char 446,17657
+(defun kotl-mode:delete-horizontal-space 510,19901
+(defun kotl-mode:delete-indentation 521,20201
+(defun kotl-mode:skip-filling-p 546,21093
+(defun kotl-mode:fill-cell 561,21574
+(defun kotl-mode:fill-paragraph 617,23854
+(defun kotl-mode:fill-tree 650,25258
+(defun kotl-mode:just-one-space 658,25658
+(defun kotl-mode:kill-line 667,25945
+(defalias 'kotl-mode:kill-visual-line kotl-mode:kill-visual-line700,27070
+(defun kotl-mode:kill-whole-line 702,27131
+(defun kotl-mode:kill-region 708,27294
+(defun kotl-mode:kill-or-copy-region 764,29638
+(defalias 'kotl-mode:completion-kill-region 
kotl-mode:completion-kill-region799,30816
+(defalias 'kotl-mode:kill-ring-save kotl-mode:kill-ring-save802,30903
+(defun kotl-mode:kill-sentence 804,30972
+(defun kotl-mode:kill-word 820,31474
+(defun kotl-mode:newline 836,31958
+(defalias 'kotl-mode:electric-indent-just-newline 
kotl-mode:electric-indent-just-newline856,32512
+(defalias 'kotl-mode:electric-newline-and-maybe-indent 
kotl-mode:electric-newline-and-maybe-indent857,32582
+(defalias 'kotl-mode:newline-and-indent kotl-mode:newline-and-indent858,32657
+(defalias 'kotl-mode:reindent-then-newline-and-indent 
kotl-mode:reindent-then-newline-and-indent859,32717
+(defun kotl-mode:open-line 861,32792
+(defun kotl-mode:quoted-insert 880,33377
+(defun kotl-mode:set-fill-prefix 919,34990
+(defun kotl-mode:tab-command 925,35217
+(defun kotl-mode:toggle-indent-tabs-mode 940,35836
+(defun kotl-mode:toggle-tab-flag 949,36243
+(defun kotl-mode:transpose-chars 960,36782
+(defun kotl-mode:transpose-lines 973,37471
+(defun kotl-mode:transpose-paragraphs 1022,39382
+(defun kotl-mode:transpose-sentences 1027,39584
+(defun kotl-mode:transpose-words 1032,39775
+(defun kotl-mode:untab-command 1040,40186
+(defun kotl-mode:zap-to-char 1057,40885
+(defun kotl-mode:append-cell 1068,41347
+(defun kotl-mode:clipboard-yank 1093,42392
+(defun kotl-mode:copy-after 1099,42579
+(defun kotl-mode:copy-before 1124,43550
+(defun kotl-mode:move-after 1149,44576
+(defun kotl-mode:move-before 1246,48532
+(defun kotl-mode:yank 1340,52469
+(defun kotl-mode:yank-pop 1375,53964
+(defalias 'kotl-mode:scroll-down-command 
kotl-mode:scroll-down-command1421,55887
+(defalias 'kotl-mode:scroll-up-command kotl-mode:scroll-up-command1422,55952
+(defun kotl-mode:back-to-indentation 1424,56015
+(defun kotl-mode:backward-cell 1431,56250
+(defun kotl-mode:backward-char 1452,57040
+(defun kotl-mode:backward-paragraph 1474,57713
+(defalias 'kotl-mode:backward-para kotl-mode:backward-para1488,58195
+(defun kotl-mode:backward-sentence 1490,58262
+(defun kotl-mode:backward-word 1519,59297
+(defun kotl-mode:beginning-of-buffer 1538,59815
+(defun kotl-mode:beginning-of-cell 1549,60169
+(defun kotl-mode:beginning-of-line 1562,60624
+(defalias 'kotl-mode:beginning-of-visual-line 
kotl-mode:beginning-of-visual-line1577,61188
+(defalias 'kotl-mode:move-beginning-of-line 
kotl-mode:move-beginning-of-line1578,61264
+(defun kotl-mode:beginning-of-tree 1580,61339
+(defun kotl-mode:down-level 1593,61881
+(defun kotl-mode:end-of-buffer 1613,62519
+(defun kotl-mode:end-of-cell 1625,62884
+(defun kotl-mode:to-end-of-line 1641,63547
+(defalias 'kotl-mode:end-of-line kotl-mode:end-of-line1656,64116
+(defalias 'kotl-mode:end-of-visual-line 
kotl-mode:end-of-visual-line1657,64176
+(defalias 'kotl-mode:move-end-of-line kotl-mode:move-end-of-line1658,64243
+(defun kotl-mode:end-of-tree 1660,64309
+(defun kotl-mode:first-sibling 1683,65299
+(defun kotl-mode:forward-cell 1695,65831
+(defun kotl-mode:forward-char 1710,66419
+(defun kotl-mode:forward-paragraph 1728,66961
+(defalias 'kotl-mode:forward-para kotl-mode:forward-para1751,67784
+(defun kotl-mode:forward-sentence 1753,67849
+(defun kotl-mode:forward-word 1781,68821
+(defun kotl-mode:goto-cell 1804,69570
+(defun kotl-mode:head-cell 1844,71192
+(defun kotl-mode:last-sibling 1855,71566
+(defun kotl-mode:mark-paragraph 1867,72098
+(defun kotl-mode:mark-whole-buffer 1877,72417
+(defun kotl-mode:next-cell 1885,72670
+(defun kotl-mode:next-line 1899,73135
+(defun kotl-mode:next-tree 1924,74017
+(defun kotl-mode:previous-line 1936,74531
+(defun kotl-mode:previous-cell 1960,75394
+(defun kotl-mode:scroll-down 1981,76090
+(defun kotl-mode:scroll-up 1990,76407
+(defun kotl-mode:tail-cell 1999,76714
+(defun kotl-mode:up-level 2011,77107
+(defun kotl-mode:bobp 2037,78059
+(defun kotl-mode:bocp 2044,78279
+(defun kotl-mode:bolp 2057,78713
+(defun kotl-mode:buffer-empty-p 2062,78862
+(defun kotl-mode:eobp 2068,79049
+(defun kotl-mode:eocp 2073,79207
+(defun kotl-mode:eolp 2084,79520
+(defun kotl-mode:first-cell-p 2095,79935
+(defalias 'kotl-mode:first-line-p kotl-mode:first-line-p2099,80077
+(defun kotl-mode:last-cell-p 2101,80127
+(defun kotl-mode:last-line-p 2105,80263
+(defun kotl-mode:action-key 2116,80610
+(defun kotl-mode:assist-key 2158,82506
+(defun kotl-mode:add-child 2199,84391
+(defun kotl-mode:add-parent 2204,84539
+(defun kotl-mode:add-cell 2209,84691
+(defun kotl-mode:demote-tree 2292,87905
+(defun kotl-mode:exchange-cells 2354,90085
+(defun kotl-mode:kill-contents 2432,92930
+(defun kotl-mode:kill-tree 2440,93178
+(defun kotl-mode:move-tree-backward 2468,94190
+(defun kotl-mode:move-tree-forward 2477,94554
+(defun kotl-mode:promote-tree 2501,95512
+(defun kotl-mode:remove-cell-attribute 2545,97016
+(defun kotl-mode:set-cell-attribute 2590,98690
+(defun kotl-mode:set-or-remove-cell-attribute 2648,100957
+(defun kotl-mode:split-cell 2670,101970
+(defun kotl-mode:transpose-cells 2701,103169
+(defun kotl-mode:copy-region-to-buffer 2755,105265
+(defun kotl-mode:copy-tree-to-buffer 2778,106256
+(defun kotl-mode:copy-tree-or-region-to-buffer 2808,107594
+(defun kotl-mode:mail-tree 2821,108097
+(defun kotl-mode:collapse-tree 2848,109039
+(defun kotl-mode:expand-tree 2860,109522
+(defun kotl-mode:toggle-tree-expansion 2874,110069
+(defun kotl-mode:overview 2887,110517
+(defun kotl-mode:show-all 2897,110803
+(defun kotl-mode:top-cells 2911,111293
+(defun kotl-mode:hide-sublevels 2926,111781
+(defun kotl-mode:hide-subtree 2937,112291
+(defun kotl-mode:show-subtree 2954,112923
+(defun kotl-mode:hide-tree 2960,113128
+(defun kotl-mode:show-tree 2980,113855
+(defun kotl-mode:cell-attributes 2985,114008
+(defun kotl-mode:cell-help 3000,114585
+(defun kotl-mode:get-cell-attribute 3054,116629
+(defun kotl-mode:org-delete-backward-char 3081,117731
+(defun kotl-mode:org-delete-char 3091,118232
+(defun kotl-mode:org-force-self-insert 3101,118711
+(defun kotl-mode:org-self-insert-command 3107,118891
+(defun kotl-mode:orgtbl-ctrl-c-ctrl-c 3115,119239
+(defun kotl-mode:orgtbl-create-or-convert-from-region 3123,119517
+(defun kotl-mode:orgtbl-self-insert-command 3131,119870
+(defun kotl-mode:self-insert-command 3140,120223
+(defun kotl-mode:add-indent-to-region 3158,121144
+(defun kotl-mode:delete-line 3170,121650
+(defun kotl-mode:exchange-point-and-mark 3184,122138
+(defun kotl-mode:indent-line 3190,122416
+(defun kotl-mode:indent-region 3204,122906
+(defun kotl-mode:is-p 3209,123034
+(defun kotl-mode:shrink-region 3216,123274
+(defun kotl-mode:valid-region-p 3235,124150
+(defun kotl-mode:maybe-shrink-region-p 3245,124544
+(defun kotl-mode:tree-end 3270,125530
+(defun kotl-mode:tree-start 3289,126277
+(defun kotl-mode:line-move 3294,126466
+(defun kotl-mode:pre-self-insert-command 3313,127139
+(defun kotl-mode:print-attributes 3328,127755
+(defun kotl-mode:isearch-open-invisible 3347,128504
+(defun kotl-mode:reveal-toggle-invisible 3350,128648
+(defun kotl-mode:set-temp-goal-column 3391,130353
+(defun kotl-mode:to-visible-position 3402,130755
+(defun kotl-mode:to-valid-position 3415,131336
+(defun kotl-mode:transpose-lines-internal 3432,132038
+(defun kotl-mode:update-buffer 3455,132813
+(defun kotl-mode:maintain-region-highlight 3466,133136
+(defun kotl-mode:setup-keymap 3471,133293
+(defun delete-selection-pre-hook 3684,142639
 
 kotl/kotl-orgtbl.el,275
 (defvar kotl-mode-overriding-orgtbl-mode-map 60,2554
@@ -2341,102 +2342,102 @@ kotl/kproperty.el,602
 (defun kproperty:replace-separator 105,4120
 (defun kproperty:set 118,4711
 
-kotl/kview.el,3725
-(define-obsolete-variable-alias 'label-sep-len label-sep-len25,737
-(defvar kview-label-sep-len 26,814
-(defcustom kview:default-blank-lines 35,1127
-(defvar kview:default-levels-to-show 42,1369
-(defvar kview:default-lines-to-show 45,1488
-(defcustom kview:default-label-min-width 48,1608
-(defcustom kview:default-label-separator 55,1911
-(defconst kview:outline-regexp 61,2103
-(defcustom kview:default-label-type 64,2283
-(defcustom kview:default-level-indent 78,2864
-(defun kcell-view:backward 93,3370
-(defun kcell-view:cell 121,4343
-(defun kcell-view:cell-from-ref 125,4481
-(defun kcell-view:child 140,5180
-(defun kcell-view:child-p 160,6019
-(defun kcell-view:collapse 170,6409
-(defun kcell-view:collapsed-p 179,6821
-(defun kcell-view:hide 192,7411
-(defun kcell-view:invisible-p 198,7685
-(defun kcell-view:contents 214,8361
-(defun kcell-view:create 234,9108
-(defun kcell-view:end 291,11307
-(defun kcell-view:end-contents 300,11573
-(defun kcell-view:expand 310,11871
-(defun kcell-view:forward 316,12136
-(defun kcell-view:get-attr 344,13141
-(defun kcell-view:idstamp-integer 357,13615
-(defun kcell-view:idstamp 363,13839
-(defun kcell-view:indent 369,14072
-(defun kcell-view:label 379,14488
-(defun kcell-view:level 392,14944
-(defun kcell-view:line 403,15505
-(defun kcell-view:lines-visible 412,15850
-(defun kcell-view:next 422,16305
-(defun kcell-view:next-invisible-p 430,16612
-(defun kcell-view:operate 435,16870
-(defun kcell-view:parent 443,17199
-(defun kcell-view:previous 465,18085
-(defun kcell-view:plist 473,18408
-(defun kcell-view:plist-point 477,18557
-(defun kcell-view:to-label-end 482,18756
-(defun kcell-view:absolute-reference 504,19763
-(defun kcell-view:reference 515,20270
-(defun kcell-view:remove-attr 527,20894
-(defun kcell-view:set-attr 542,21510
-(defun kcell-view:set-cell 558,22187
-(defun kcell-view:sibling-p 565,22425
-(defun kcell-view:start 573,22716
-(defun kcell-view:to-visible-label-end 579,22967
-(defun kcell-view:visible-label 594,23617
-(defun kview:add-cell 607,24053
-(defun kview:beginning-of-actual-line 620,24706
-(defun kview:buffer 625,24889
-(defun kview:char-invisible-p 631,25063
-(defun kview:char-visible-p 640,25385
-(defun kview:create 648,25691
-(defun kview:delete-region 705,27967
-(defun kview:end-of-actual-line 709,28101
-(defun kview:fill-region 714,28272
-(defun kview:first-invisible-point 739,29215
-(defun kview:first-visible-point 755,29941
-(defun kview:get-cells-status 768,30497
-(defun kview:goto-cell-id 789,31403
-(defun kview:id-counter 801,31822
-(defun kview:id-increment 805,31987
-(defun kview:idstamp-to-label 811,32207
-(defun kview:insert-contents 817,32419
-(defun kview:is-p 864,34053
-(defun kview:kotl 869,34158
-(defun kview:label 874,34313
-(defun kview:label-function 879,34535
-(defun kview:label-min-width 886,34902
-(defun kview:label-separator 892,35144
-(defun kview:label-separator-length 898,35386
-(defun kview:label-type 903,35611
-(defun kview:level-indent 909,35833
-(defun kview:map-branch 915,36067
-(defun kview:map-cells 947,37493
-(defun kview:map-region 960,37949
-(defun kview:map-siblings 1000,39499
-(defun kview:map-expanded-tree 1029,40685
-(defun kview:map-tree 1087,43100
-(defun kview:move 1125,44792
-(defun kview:previous-visible-point 1197,47226
-(defun kview:set-buffer 1213,47927
-(defun kview:set-cells-status 1222,48222
-(defun kview:set-label-type 1250,49523
-(defun kview:top-cell 1282,50668
-(defun kview:valid-position-p 1287,50841
-(defun kview:get-attr 1312,51860
-(defun kcell-view:next-kcell 1316,51992
-(defun kcell-view:previous-kcell 1329,52602
-(defun kview:set-attr 1348,53529
-(defun kview:set-functions 1359,53851
-(defun kview:set-label-separator 1366,54257
+kotl/kview.el,3724
+(define-obsolete-variable-alias 'label-sep-len label-sep-len25,736
+(defvar kview-label-sep-len 26,813
+(defcustom kview:default-blank-lines 35,1126
+(defvar kview:default-levels-to-show 42,1368
+(defvar kview:default-lines-to-show 45,1487
+(defcustom kview:default-label-min-width 48,1607
+(defcustom kview:default-label-separator 55,1910
+(defconst kview:outline-regexp 61,2102
+(defcustom kview:default-label-type 64,2282
+(defcustom kview:default-level-indent 78,2863
+(defun kcell-view:backward 93,3369
+(defun kcell-view:cell 121,4342
+(defun kcell-view:cell-from-ref 125,4480
+(defun kcell-view:child 140,5179
+(defun kcell-view:child-p 160,6018
+(defun kcell-view:collapse 170,6408
+(defun kcell-view:collapsed-p 179,6820
+(defun kcell-view:hide 192,7410
+(defun kcell-view:invisible-p 198,7684
+(defun kcell-view:contents 214,8360
+(defun kcell-view:create 234,9107
+(defun kcell-view:end 291,11306
+(defun kcell-view:end-contents 300,11572
+(defun kcell-view:expand 310,11870
+(defun kcell-view:forward 316,12135
+(defun kcell-view:get-attr 344,13140
+(defun kcell-view:idstamp-integer 357,13614
+(defun kcell-view:idstamp 363,13838
+(defun kcell-view:indent 369,14071
+(defun kcell-view:label 379,14487
+(defun kcell-view:level 392,14943
+(defun kcell-view:line 403,15504
+(defun kcell-view:lines-visible 412,15849
+(defun kcell-view:next 422,16304
+(defun kcell-view:next-invisible-p 430,16611
+(defun kcell-view:operate 435,16869
+(defun kcell-view:parent 443,17198
+(defun kcell-view:previous 465,18084
+(defun kcell-view:plist 473,18407
+(defun kcell-view:plist-point 477,18556
+(defun kcell-view:to-label-end 482,18755
+(defun kcell-view:absolute-reference 504,19762
+(defun kcell-view:reference 515,20269
+(defun kcell-view:remove-attr 527,20893
+(defun kcell-view:set-attr 542,21509
+(defun kcell-view:set-cell 558,22186
+(defun kcell-view:sibling-p 565,22424
+(defun kcell-view:start 573,22715
+(defun kcell-view:to-visible-label-end 579,22966
+(defun kcell-view:visible-label 594,23616
+(defun kview:add-cell 607,24052
+(defun kview:beginning-of-actual-line 620,24705
+(defun kview:buffer 625,24888
+(defun kview:char-invisible-p 631,25062
+(defun kview:char-visible-p 637,25261
+(defun kview:create 641,25427
+(defun kview:delete-region 698,27703
+(defun kview:end-of-actual-line 702,27837
+(defun kview:fill-region 707,28008
+(defun kview:first-invisible-point 732,28951
+(defun kview:first-visible-point 748,29677
+(defun kview:get-cells-status 761,30233
+(defun kview:goto-cell-id 782,31139
+(defun kview:id-counter 794,31558
+(defun kview:id-increment 798,31723
+(defun kview:idstamp-to-label 804,31943
+(defun kview:insert-contents 810,32155
+(defun kview:is-p 857,33789
+(defun kview:kotl 862,33894
+(defun kview:label 867,34049
+(defun kview:label-function 872,34271
+(defun kview:label-min-width 879,34638
+(defun kview:label-separator 885,34880
+(defun kview:label-separator-length 891,35122
+(defun kview:label-type 896,35347
+(defun kview:level-indent 902,35569
+(defun kview:map-branch 908,35803
+(defun kview:map-cells 940,37229
+(defun kview:map-region 953,37685
+(defun kview:map-siblings 993,39235
+(defun kview:map-expanded-tree 1022,40421
+(defun kview:map-tree 1080,42836
+(defun kview:move 1118,44528
+(defun kview:previous-visible-point 1190,46962
+(defun kview:set-buffer 1206,47663
+(defun kview:set-cells-status 1215,47958
+(defun kview:set-label-type 1243,49259
+(defun kview:top-cell 1275,50404
+(defun kview:valid-position-p 1280,50577
+(defun kview:get-attr 1305,51596
+(defun kcell-view:next-kcell 1309,51728
+(defun kcell-view:previous-kcell 1322,52338
+(defun kview:set-attr 1341,53265
+(defun kview:set-functions 1352,53587
+(defun kview:set-label-separator 1359,53993
 
 kotl/kvspec.el,700
 (defvar kvspec:current 65,2524
@@ -2516,22 +2517,29 @@ test/hargs-tests.el,122
 (ert-deftest hargs-get-verify-extension-characters 25,551
 (ert-deftest hargs-get-verify-extension-characters-+K 44,1393
 
-test/hbut-tests.el,903
-(defun hbut-tests:should-match-tmp-folder 27,553
-(ert-deftest ebut-program-link-to-directory 33,851
-(ert-deftest ebut-program-link-to-directory-2 46,1447
-(ert-deftest ebut-program-shell-cmd 56,1953
-(ert-deftest ebut-delete-removes-ebut-and-returns-button-data 66,2375
-(ert-deftest gbut-program-calls-ebut-program 79,2823
-(ert-deftest gbut-program-link-to-directory 90,3339
-(ert-deftest gbut-program-eval-elisp 106,4150
-(ert-deftest gbut-program-link-to-file 119,4756
-(ert-deftest gbut-program-link-to-file-line 132,5384
-(ert-deftest gbut-program-link-to-file-line-and-column 145,6033
-(ert-deftest hypb:program-create-ebut-in-buffer 158,6720
-(ert-deftest hypb:program-create-ebut-in-buffer-with-same-label 166,7105
-(ert-deftest hypb:program-create-link-to-file-line-and-column-but-in-file 
174,7495
-(ert-deftest 
hypb--ebut-at-p-should-not-insert-hbdata-section-in-non-file-buffers 184,8040
+test/hbut-tests.el,1328
+(defun hbut-tests:should-match-tmp-folder 28,602
+(ert-deftest ebut-program-link-to-directory 34,873
+(ert-deftest ebut-program-link-to-directory-2 47,1469
+(ert-deftest ebut-program-shell-cmd 57,1975
+(ert-deftest ebut-delete-removes-ebut-and-returns-button-data 67,2397
+(ert-deftest gbut-program-calls-ebut-program 80,2845
+(ert-deftest gbut-program-link-to-directory 91,3361
+(ert-deftest gbut-program-eval-elisp 107,4172
+(ert-deftest gbut-program-link-to-file 120,4778
+(ert-deftest gbut-program-link-to-file-line 133,5406
+(ert-deftest gbut-program-link-to-file-line-and-column 146,6055
+(ert-deftest hypb:program-create-ebut-in-buffer 159,6742
+(ert-deftest hypb:program-create-ebut-in-buffer-with-same-label 167,7127
+(ert-deftest hypb:program-create-link-to-file-line-and-column-but-in-file 
175,7517
+(ert-deftest 
hypb--ebut-at-p-should-not-insert-hbdata-section-in-non-file-buffers 185,8062
+(ert-deftest hbut-tests-ibut-program-link-to-directory 194,8407
+(ert-deftest hbut-tests-ibut-program-link-to-file 200,8655
+(ert-deftest hbut-tests-ibut-insert-text-link-to-dir 211,9072
+(ert-deftest hbut-tests-ibut-insert-annot-bib 223,9525
+(ert-deftest hbut-tests-ibut-insert-kbd-key 244,10211
+(ert-deftest hbut-tests-ibut-insert-text-temp-buffer 255,10570
+(ert-deftest hbut-tests-ibut-insert-text-temp-file 292,12503
 
 test/hib-kbd-tests.el,96
 (ert-deftest kbd-key-hy-about-test 28,705
diff --git a/hact.el b/hact.el
index b1910c1b66..39e468c62d 100644
--- a/hact.el
+++ b/hact.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    18-Sep-91 at 02:57:09
-;; Last-Mod:     30-Apr-23 at 14:40:46 by Bob Weiner
+;; Last-Mod:     29-May-23 at 21:50:42 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -362,6 +362,8 @@ The value of `hrule:action' determines what effect this has.
 Alternatively act as a no-op when testing implicit button type contexts.
 First arg may be a symbol or symbol name for either an action type or a
 function.  Runs `action-act-hook' before performing action."
+  ;; (message "hact args: %S" args)
+  (hattr:set 'hbut:current 'actype (actype:elisp-symbol (car args)))
   (apply hrule:action args))
 
 (defun    actype:act (actype &rest args)
@@ -431,7 +433,7 @@ performing ACTION."
          (hhist:add hist-elt))))))
 
 (defun    actype:action (actype)
-  "Return action part of ACTYPE.
+  "Return action part (body) of ACTYPE.
 ACTYPE is a bound function symbol, symbol name or function body.
 ACTYPE may be a Hyperbole actype or Emacs Lisp function."
   (let (actname
diff --git a/hactypes.el b/hactypes.el
index a622feb99e..1101ba186f 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:     21-May-23 at 03:15:30 by Bob Weiner
+;; Last-Mod:     10-Jun-23 at 21:13:02 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -496,8 +496,9 @@ available.  Filename may be given without the .info suffix."
       (id-info string)
     (hypb:error "(link-to-Info-node): Invalid Info node: `%s'" string)))
 
-(defact link-to-ibut (key &optional but-src point)
-  "Perform implicit button action specified by KEY, optional BUT-SRC and POINT.
+(defact link-to-ibut (name-key &optional but-src point)
+  "Perform implicit button action specified by NAME-KEY, optional BUT-SRC and 
POINT.
+NAME-KEY must be a normalized key for an ibut <[name]>.
 BUT-SRC defaults to the current buffer's file or if there is no
 attached file, then to its buffer name.  POINT defaults to the
 current point.
@@ -505,10 +506,10 @@ current point.
 When the button with this action type is created, point must be
 on the implicit button to which to link."
   (interactive
-   (let ((ibut-key (ibut:at-p t)))
-     (cond (ibut-key
-           (list ibut-key (or buffer-file-name (buffer-name)) (point)))
-          ;; TODO: If default is null below and are creating, rather than 
editing
+   (let ((ibut-name-key (ibut:at-p t)))
+     (cond (ibut-name-key
+           (list ibut-name-key (or buffer-file-name (buffer-name)) (point)))
+          ;; !! TODO: If default is null below and are creating, rather than 
editing
           ;; the link, it would be better to throw an error than create
           ;; an invalid link, but it is difficult to tell which operation
           ;; is in progress, so ignore this for now.  -- RSW, 01-25-2020
@@ -518,7 +519,7 @@ on the implicit button to which to link."
            hargs:defaults)
           (t
            (hypb:error "(link-to-ibut): Point must be on an implicit button to 
create a link-to-ibut")))))
-  (when (null key)
+  (when (null name-key)
     (hypb:error "(link-to-ibut): Point must be on an implicit button to create 
a link-to-ibut"))
   (let (but
        normalized-file)
@@ -534,12 +535,12 @@ on the implicit button to which to link."
       (hmail:msg-narrow))
     (when (integerp point)
       (goto-char (min point (point-max))))
-    (setq but (ibut:to key))
+    (setq but (ibut:to name-key))
     (cond (but
           (hbut:act but))
-         (key
-          (hypb:error "(link-to-ibut): No implicit button `%s' found in `%s'"
-                      (ibut:key-to-label key)
+         (name-key
+          (hypb:error "(link-to-ibut): No implicit button named `%s' found in 
`%s'"
+                      (ibut:key-to-label name-key)
                       (or but-src (buffer-name))))
          (t
           (hypb:error "(link-to-ibut): Link reference is null/empty")))))
diff --git a/hargs.el b/hargs.el
index a5aa9c111f..21bfe0de53 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:     14-May-23 at 01:52:22 by Bob Weiner
+;; Last-Mod:     29-May-23 at 02:22:19 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -77,39 +77,46 @@ Convert NUL characters to colons for use with grep lines."
 
 (defun hargs:delimited (start-delim end-delim
                        &optional start-regexp-flag end-regexp-flag
-                       list-positions-flag exclude-regexp)
+                       list-positions-flag exclude-regexp as-key)
   "Return a delimited string that point is within the first line of, or nil.
-The string is normalized and reduced to a single line.
-START-DELIM and END-DELIM are strings that specify the argument
-delimiters.  With optional START-REGEXP-FLAG non-nil, START-DELIM is
-treated as a regular expression.  END-REGEXP-FLAG is similar.
-With optional LIST-POSITIONS-FLAG, return list of (string-matched
-start-pos end-pos).  With optional EXCLUDE-REGEXP, any matched
-string is ignored if it matches this regexp."
+The string matched may be up to two lines long.  The delimiters
+are removed, the string is normalized and reduced to a single
+line.  START-DELIM and END-DELIM are strings that specify the
+argument delimiters.  With optional START-REGEXP-FLAG non-nil,
+START-DELIM is treated as a regular expression.  END-REGEXP-FLAG
+is similar.  With optional LIST-POSITIONS-FLAG, return list
+of (string-matched start-pos end-pos).  Optional
+EXCLUDE-REGEXP is compared against the match string with its delimiters
+included; any string that matches this regexp is ignored."
   (let* ((opoint (point))
-        (line-begin (line-beginning-position))
         ;; This initial limit if the forward search limit for start delimiters
         (limit (if start-regexp-flag opoint
                  (+ opoint (1- (length start-delim)))))
-        (forward-search-func (if start-regexp-flag 're-search-forward
-                               'search-forward))
-        (reverse-search-func (if end-regexp-flag 're-search-backward
-                               'search-backward))
+        (start-search-func (if start-regexp-flag 're-search-forward 
'search-forward))
+        (end-search-func   (if end-regexp-flag   're-search-forward 
'search-forward))
         (count 0)
         first
         start
-        end)
+        end
+        end-pos
+        start-with-delim
+        end-with-delim)
     (if (string-equal start-delim end-delim)
        (save-excursion
          (beginning-of-line)
-         (while (and (setq start (funcall forward-search-func start-delim 
limit t))
+         (while (and (setq end-pos (funcall start-search-func start-delim 
limit t))
+                     (setq start-with-delim (match-beginning 0))
+                     ;; Prevent infinite loop where regexp match does not
+                     ;; move end-pos forward, e.g. match to bol.
+                     (not (eq first end-pos))
+                     (setq start end-pos)
                      (setq count (1+ count))
                      (< (point) opoint)
                      ;; This is not to find the real end delimiter but to find
                      ;; end delimiters that precede the current argument and 
are
                      ;; therefore false matches, hence the search is limited to
                      ;; prior to the original point.
-                     (funcall forward-search-func end-delim opoint t)
+                     (funcall end-search-func end-delim opoint t)
                      (setq count (1+ count)))
            (setq first (or first start)
                  start nil))
@@ -128,17 +135,26 @@ string is ignored if it matches this regexp."
       ;; Start and end delims are different, so don't have to worry
       ;; about whether in or outside two of the same delimiters and
       ;; can match much more simply.
+      ;; Use forward rather than reverse search here to perform greedy
+      ;; searches when optional matches within a regexp.
       (save-excursion
-       (setq start (when (funcall reverse-search-func start-delim line-begin t)
-                     (match-end 0)))))
+       (beginning-of-line)
+       (while (and (setq end-pos (funcall start-search-func start-delim limit 
t))
+                   ;; Prevent infinite loop where regexp match does not
+                   ;; move end-pos forward, e.g. match to bol.
+                   (not (eq start end-pos)))
+         (setq start-with-delim (match-beginning 0)
+               start (match-end 0)))))
 
     (when start
       (save-excursion
        (forward-line 2)
        (setq limit (point))
        (goto-char opoint)
-       (and (funcall forward-search-func end-delim limit t)
-            (setq end (match-beginning 0))
+       (and (funcall end-search-func end-delim limit t)
+            (setq end (match-beginning 0)
+                  end-with-delim (match-end 0))
+
             ;; Ignore any preceding backslash, e.g. when a double-quoted
             ;; string is embedded within a doc string, except when
             ;; the string starts with 2 backslashes or an MSWindows
@@ -153,9 +169,18 @@ string is ignored if it matches this regexp."
               t)
             (< start end)
             (>= end opoint)
-            (let ((string (hargs:buffer-substring start end)))
-              (unless (and (stringp exclude-regexp) (string-match 
exclude-regexp string) )
-                (setq string (replace-regexp-in-string "[\n\r\f]\\s-*" " " 
string nil t))
+            (let ((string (hargs:buffer-substring start end))
+                  (string-with-delims (when (stringp exclude-regexp)
+                                        (hargs:buffer-substring 
start-with-delim
+                                                                
end-with-delim))))
+              (unless (and string-with-delims
+                           (string-match exclude-regexp string-with-delims))
+                ;; Normalize the string
+                (setq string
+                      (if as-key
+                          (hbut:label-to-key string)
+                        (replace-regexp-in-string "[\n\r\f]\\s-*"
+                                                  " " string nil t)))
                 (unless hyperb:microsoft-os-p
                   (setq string (hpath:mswindows-to-posix string)))
                 (if list-positions-flag
diff --git a/hbdata.el b/hbdata.el
index fbbce7b86b..963691816f 100644
--- a/hbdata.el
+++ b/hbdata.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     2-Apr-91
-;; Last-Mod:     17-May-23 at 02:31:18 by Bob Weiner
+;; Last-Mod:     11-Jun-23 at 09:59:24 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -265,7 +265,7 @@ entry, otherwise modify existing one.  Nil BUT-SYM means use
          (cons hbdata lbl-instance))))))
 
 (defun hbdata:ebut-instance-last (lbl-key key-src &optional directory)
-  "Return highest instance number for repeated explicit button label.
+  "Return highest instance number for explicit button label.
 1 if not repeated, nil if no instance.
 Utilize arguments LBL-KEY, KEY-SRC and optional DIRECTORY."
   (hbdata:apply-entry
@@ -284,37 +284,34 @@ 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
+(defun hbdata:ibut-instance (&optional orig-name-key but-sym)
+  "Return ibutton instance number string from optional ORIG-NAME-KEY and 
BUT-SYM.
+ORIG-NAME-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)))))))
+        (name-key (ibut:label-to-key (hattr:get b 'name)))
+        (key (or orig-name-key name-key))
+        (new-key (if orig-name-key name-key key))
+        (lbl-instance))
+    (or (when key
+         (if orig-name-key
+             (let ((inst-num (hbdata:ibut-instance-last new-key)))
+               (setq lbl-instance (when inst-num
+                                    (hbdata:instance-next
+                                     (concat new-key hbut:instance-sep
+                                             (int-to-string inst-num))))))
+           (when (setq lbl-instance (hbdata:ibut-instance-last new-key))
+             (setq lbl-instance (concat hbut:instance-sep
+                                        (int-to-string (1+ lbl-instance))))))
          lbl-instance)
        t)))
 
-(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 argument LBL-KEY."
-  (let ((key (car (ibut:label-sort-keys (ibut:label-key-match lbl-key)))))
+(defun hbdata:ibut-instance-last (name-key)
+  "Return highest instance number for implicit button NAME-KEY in current 
buffer.
+1 if not repeated, nil if no instance."
+  (let ((key (car (ibut:label-sort-keys (ibut:label-key-match name-key)))))
     (cond ((null key) nil)
          ((string-match (concat (regexp-quote hbut:instance-sep)
                                 "\\([0-9]+\\)\\'")
@@ -322,16 +319,20 @@ label or t when first instance."
           (string-to-number (match-string 1 key)))
          (t 1))))
 
-(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
+(defun hbdata:instance-next (name-key)
+  "Return string for the next higher button instance number after NAME-KEY's.
+Return nil if NAME-KEY is nil.
+
+This does not search any buffer for other instances; it uses the
+NAME-KEY string literally, so it must include any instance number
+to increment."
+  (and name-key
        (if (string-match
-           (concat (regexp-quote hbut:instance-sep) "[0-9]+$") lbl-key)
+           (concat (regexp-quote hbut:instance-sep) "[0-9]+$") name-key)
           (concat hbut:instance-sep
                   (int-to-string
                    (1+ (string-to-number
-                        (substring lbl-key (1+ (match-beginning 0)))))))
+                        (substring name-key (1+ (match-beginning 0)))))))
         ":2")))
 
 (defun hbdata:to-entry (but-key key-src &optional directory instance)
diff --git a/hbut.el b/hbut.el
index 8a5b031198..5ab00eaaad 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:     22-May-23 at 23:06:54 by Bob Weiner
+;; Last-Mod:     11-Jun-23 at 13:42:14 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -202,7 +202,7 @@ Return nil if no matching button is found."
   (and (stringp key) (stringp label)
        (equal key (downcase (ebut:label-to-key label)))))
 
-(defalias 'ebut:to-key-src            #'hbut:to-key-src)
+(defalias 'ebut:to-key-src         #'hbut:to-key-src)
 (defalias 'ebut:key-src-set-buffer #'hbut:key-src-set-buffer)
 (defalias 'ebut:key-src-fmt        #'hbut:key-src-fmt)
 (defalias 'ebut:key-to-label       #'hbut:key-to-label)
@@ -270,7 +270,8 @@ to two lines."
                      (list lbl-key but-start but-end)))
                   (t (if as-label (ebut:key-to-label lbl-key) lbl-key))))))))
 
-(defalias 'ebut:label-regexp #'hbut:label-regexp)
+(defalias 'ebut:label-regexp           #'hbut:label-regexp)
+(defalias 'ebut:label-instances-regexp #'hbut:label-instances-regexp)
 
 (defalias 'ebut:label-to-key #'hbut:label-to-key)
 
@@ -306,7 +307,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:label-start ebut:label-end regexp-match 
include-delims))
+  (hbut:map but-func nil nil 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.
@@ -1258,15 +1259,6 @@ 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)))
@@ -1285,7 +1277,38 @@ label search to two lines."
       (ibut:label-p as-label start-delim end-delim pos-flag two-lines-flag)))
 
 (defun    hbut:label-regexp (lbl-key &optional no-delim start-delim end-delim)
-  "Unnormalize LBL-KEY.  Return regular expr matching delimited button label.
+  "Unnormalize LBL-KEY.  Return regexp 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: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:label-start)) sep0
+                                          "\\(")))
+          (case-fold-search))
+      (while (< pos len)
+       (setq c (aref lbl-key pos)
+             regexp (concat regexp
+                            (if (eq c ?_)
+                                (if (or (= (1+ pos) len)
+                                        (not (eq (aref lbl-key (1+ pos)) ?_)))
+                                    sep
+                                  (setq pos (1+ pos))
+                                  "_")
+                              (regexp-quote (char-to-string c))))
+             pos (1+ pos)))
+      (if no-delim
+         regexp
+       (setq regexp (concat regexp
+                            "\\)" sep0 (regexp-quote (or end-delim 
ebut:label-end))))))))
+
+(defun    hbut:label-instances-regexp (lbl-key &optional no-delim start-delim 
end-delim)
+  "Unnormalize LBL-KEY.
+Return regexp matching all instances of 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:label-start' and `ebut:label-end'."
@@ -1312,10 +1335,10 @@ label; these default to `ebut:label-start' and 
`ebut:label-end'."
       (if no-delim
          regexp
        (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]+\\)?"))
+                             (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)
@@ -1354,8 +1377,8 @@ include delimiters when INCLUDE-DELIMS is non-nil)."
   (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)))
+        (end-char (unless match-to-start-delim
+                    (substring end-delim -1)))
         (result)
         (ignore)
         (regexp-to-match
@@ -1364,7 +1387,7 @@ include delimiters when INCLUDE-DELIMS is non-nil)."
                ((stringp regexp-match)
                 regexp-match)
                (t (concat (regexp-quote start-delim)
-                          "\\([^" end-sym "\"][^" end-sym "]*\\)"
+                          "\\([^" end-char "\"][^" end-char "]*\\)"
                           (regexp-quote end-delim)))))
         start end delim-start lbl)
     (save-excursion
@@ -1375,7 +1398,8 @@ include delimiters when INCLUDE-DELIMS is non-nil)."
              end (match-end include-delims)
              lbl (match-string-no-properties 1)
              delim-start (match-beginning 0)
-             ;; If within a programming language buffer, ignore matches 
outside comments.
+             ;; If within a programming language buffer, ignore matches
+             ;; outside comments.
              ignore (hbut:outside-comment-p))
        (save-excursion
          (goto-char delim-start)
@@ -1570,53 +1594,28 @@ Each element is a list of just an implicit button 
label.  For use
 as a completion table."
   (mapcar #'list (ibut:list file)))
 
-(defun    ibut:at-p (&optional key-only)
+(defun    ibut:at-p (&optional name-key-only)
   "Return symbol for implicit button at point, else nil.
-Point may be on the implicit button text or its optional
-preceding label.  With optional KEY-ONLY, return the label key
-for button only.
+Point may be on the implicit button text or its optional preceding
+name.  With optional NAME-KEY-ONLY, return only the label key of the
+button.
 
-Any labeled implicit button must contain at least two characters,
+Any named implicit button must contain at least two characters,
 excluding delimiters, not just one."
   ;; Since the Smart Keys handle end-of-line 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
-  (unless (eolp)
-    (let* ((opoint (point))
-          (name-start-end (ibut:label-p t nil nil t t))
-          (name       (nth 0 name-start-end))
-          (name-end   (nth 2 name-start-end))
-          (lbl-key (or (ibut:label-to-key name)
-                       (ibut:label-p nil "\"" "\"" nil t)
-                       (ibut:label-p nil "<" ">" nil t)
-                       (ibut:label-p nil "{" "}" nil t))))
-      (unwind-protect
-         (progn
-           (when (not (hbut:outside-comment-p))
-             ;; Skip past any optional name and separators
-             (when name-start-end
-               (goto-char name-end)
-               (if (looking-at ibut:label-separator-regexp)
-                   ;; Move past up to 2 possible characters of ibut
-                   ;; delimiters; this prevents recognizing labeled,
-                   ;; delimited ibuts of a single character since no one
-                   ;; should need that.
-                   (goto-char (min (+ 2 (match-end 0)) (point-max)))
-                 (goto-char opoint))))
-           (if key-only
-               lbl-key
-             ;; Check for an implicit button at current point, record its
-             ;; attributes and return a button symbol for it.  This call
-             ;; 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.
-             (when (ibut:create :name name :lbl-key lbl-key)
-               'hbut:current)))
-       (goto-char opoint)))))
+  (unless (or (eolp) (hbut:outside-comment-p))
+    ;; Check for an implicit button at current point, record its
+    ;; attributes in memory and return a button symbol for it.
+    (when (ibut:create)
+      (if name-key-only
+         (ibut:label-to-key (hattr:get 'hbut:current 'name))
+       'hbut:current))))
 
 (defun    ibut:at-type-p (ibut-type-symbol)
   "Return non-nil if point is on a button of type IBUT-TYPE-SYMBOL.
-Point must be on the button itself and not its label, if any.
+Point must be on the button itself and not its name, if any.
 
 The return value is a list of the type's action type symbol and
 associated arguments from the button."
@@ -1630,50 +1629,139 @@ associated arguments from the button."
              (hrule:action 'actype:identity))
          (funcall ibut-type-symbol))))))
 
+(defun  ibut:set-name-and-label-key-p (&optional start-delim end-delim)
+  "Set hbut:current name, lbl-key, lbl-start and lbl-end ibut attributes.
+Point may be on the implicit button text or its optional preceding
+name.  Return t if on an implicit button or nil otherwise.
+
+Optional START-DELIM and END-DELIM may be given to find the button text
+\(not name); without these, try a series of matching delimiters.
+
+Any implicit button name must contain at least two characters,
+excluding delimiters, not just one."
+  (let* ((opoint (point))
+        (name-start-end (ibut:label-p t nil nil t t))
+        (name       (nth 0 name-start-end))
+        (name-end   (nth 2 name-start-end))
+        lbl-start-end
+        lbl-start
+        lbl-end
+        lbl-key)
+    (unwind-protect
+       (progn
+         ;; Skip past any optional name and separators
+         (when name-end
+           (goto-char name-end)
+           (if (looking-at ibut:label-separator-regexp)
+               ;; Move past up to 2 possible characters of ibut
+               ;; delimiters; this prevents recognizing named,
+               ;; delimited ibuts of a single character since no one
+               ;; should need that.
+               (goto-char (min (+ 2 (match-end 0)) (point-max)))
+             (goto-char opoint)))
+
+         (setq lbl-start-end (if (and start-delim end-delim)
+                                 (ibut:label-p nil start-delim end-delim t t)
+                               (or (ibut:label-p nil "\"" "\"" t t)
+                                   (ibut:label-p nil "<" ">" t t)
+                                   (ibut:label-p nil "{" "}" t t)
+                                   (ibut:label-p nil "[" "]" t t)))
+               lbl-key (nth 0 lbl-start-end)
+               lbl-start (nth 1 lbl-start-end)
+               lbl-end (nth 2 lbl-start-end))
+         (when lbl-end
+           (hattr:set 'hbut:current 'lbl-key lbl-key)
+           (hattr:set 'hbut:current 'lbl-start lbl-start)
+           (hattr:set 'hbut:current 'lbl-end lbl-end))
+
+         (when (and lbl-start (not name-end))
+           ;; Point is within ibut text, not its name, so search
+           ;; backward for any name on the same line.
+           (goto-char lbl-start)
+           (when (looking-back ibut:label-separator-regexp
+                               (line-beginning-position) t)
+             ;; Move to within delimiters of name
+             (goto-char (max (- (match-beginning 0) 3) (point-min)))
+             (setq name-start-end (ibut:label-p t nil nil t t)
+                   name           (nth 0 name-start-end)
+                   name-end       (nth 2 name-start-end))))
+
+         (when (and lbl-end name-end)
+           (hattr:set 'hbut:current 'name name))
+
+         (when lbl-end
+           t))
+      (goto-char opoint))))
+
 (cl-defun ibut:create (&optional &key but-sym name lbl-key lbl-start lbl-end
                                 loc dir categ actype args action)
   "Create an in-memory representation of an implicit button.
-Return symbol hbut:current with attributes from arguments given.
+
+If successful, return button instance num string or t for first
+instance; otherwise, return nil.  See `hbdata:ibut-instance' for
+details.
+
 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.
+return nil if no implicit button is found at point.
 
-  ;; `lbl-key' attribute will be set from `but-sym' if any, the button `name' 
if any;
-  ;; and, otherwise, from its text.
+Store new button attributes in the symbol, 'hbut:current."
+  ;; :args is ignored unless :categ or :action is also given.
+
+  ;; `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 `but-sym' if any; and,
   ;; otherwise, the start and end of the ibut text, excluding
   ;; delimiters, not of its name.
 
-  (let* ((types (htype:category 'ibtypes))
+  (let* ((but-sym-flag (not (null but-sym)))
+        (types (htype:category 'ibtypes))
         ;; Global var used in (hact) function, don't delete.
         (hrule:action #'actype:identity)
         (ibpoint (point-marker))
         (itype)
-        (is-type categ))
-
+        (is-type categ)
+        (name-and-lbl-key-flag)
+        (text-start)
+        (text-end)
+        (ibtype-point))
     (unwind-protect
        (progn
          (unless but-sym
            (hattr:clear 'hbut:current)
+           (setq name-and-lbl-key-flag (ibut:set-name-and-label-key-p))
+           (when but-sym-flag
+             (setq name-and-lbl-key-flag nil))
            ;; 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)))
-                 (setq is-type itype)
-                 ;; Any implicit button type check should leave point
-                 ;; unchanged.  Trigger an error if not.
-                 (unless (equal (point-marker) ibpoint)
-                   (hypb:error "(Hyperbole): `%s' at-p test improperly moved 
point from %s to %s"
-                               is-type ibpoint (point-marker))))
-               (setq types (cdr types))))
+             (unwind-protect
+                 (progn (setq text-start (or (hattr:get 'hbut:current 
'lbl-start)
+                                             (point))
+                              text-end (or (hattr:get 'hbut:current 'lbl-end)
+                                           (point)))
+                        (unless (and (<= text-start (point))
+                                     (>= text-end (point)))
+                          ;; Move to text of ibut before trying to activate it
+                          ;; (may be on name)
+                          (goto-char text-start))
+                        (setq ibtype-point (point))
+                        (while (and (not is-type) types)
+                          (setq itype (car types))
+                          (when (and itype (setq args (funcall itype)))
+                            (setq is-type itype)
+                            ;; Any implicit button type check should leave 
point
+                            ;; unchanged.  Trigger an error if not.
+                            (unless (equal (point) ibtype-point)
+                              (hypb:error "(Hyperbole): `%s' at-p test 
improperly moved point from %s to %s"
+                                          is-type ibpoint (point-marker))))
+                          (setq types (cdr types))))
+               (goto-char ibpoint)))
            (set-marker ibpoint nil))
 
          (when (or is-type but-sym)
@@ -1681,77 +1769,108 @@ return nil if no implicit button is found at point."
              (setq but-sym 'hbut:current))
            (let ((current-categ     (hattr:get but-sym 'categ))
                  (current-name      (hattr:get but-sym 'name))
-                 ;; (current-lbl-key   (hattr:get but-sym 'lbl-key))
+                 (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-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-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)))
+             (cond ((and but-sym-flag current-name)
+                    (setq name current-name))
+                   ((or name name-and-lbl-key-flag))
+                   (current-name
+                    (setq name current-name)))
+             (when name
+               (hattr:set 'hbut:current 'name name))
+
+             (cond ((and but-sym-flag current-lbl-key)
+                    (setq lbl-key current-lbl-key))
+                   ((or lbl-key name-and-lbl-key-flag))
+                   (current-lbl-key
+                    (setq lbl-key current-lbl-key)))
              (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
-                        (or is-type current-categ 'implicit))
-
-             (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)))
+             (cond ((and but-sym-flag current-lbl-start)
+                    (setq lbl-start current-lbl-start))
+                   ((or lbl-start name-and-lbl-key-flag))
+                   (current-lbl-start
+                    (setq lbl-start current-lbl-start)))
+             (when lbl-start
+               (hattr:set 'hbut:current 'lbl-start lbl-start))
+
+             (cond ((and but-sym-flag current-lbl-end)
+                    (setq lbl-end current-lbl-end))
+                   ((or lbl-end name-and-lbl-key-flag))
+                   (current-lbl-end
+                    (setq lbl-end current-lbl-end)))
+             (when lbl-end
+               (hattr:set 'hbut:current 'lbl-end lbl-end))
+
+             (cond ((and but-sym-flag current-loc)
+                    (setq loc current-loc))
+                   ((or loc (setq loc (save-excursion
+                                        (hbut:to-key-src 'full)))))
+                   (current-loc
+                    (setq loc current-loc)))
+             (when loc
+               (hattr:set 'hbut:current 'loc loc))
+
+             (cond ((and but-sym-flag current-dir)
+                    (setq dir current-dir))
+                   ((or dir (setq dir (hui:key-dir (current-buffer)))))
+                   (current-dir
+                    (setq dir current-dir)))
+             (when dir
+               (hattr:set 'hbut:current 'dir dir))
+
+             (cond ((and but-sym-flag current-action)
+                    (setq action current-action))
+                   (action)
+                   (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))))))
+               (hattr:set 'hbut:current 'action action))
+
+             (cond ((and but-sym-flag current-categ)
+                    (setq categ current-categ))
+                   (categ)
+                   (t
+                    (setq categ (or is-type current-categ 'implicit))))
+             (when categ
+               (hattr:set 'hbut:current 'categ categ))
+
+             (if (not categ)
+                 (setq args nil)
+               (unless action
+                 (cond ((and but-sym-flag current-args)
+                        (setq args current-args))
+                       (args)
+                       (current-args
+                        (setq args current-args))))
+               (setq args (copy-sequence args))
+               (when (eq (car args) #'hact)
+                 (setq args (cdr args))))
+
+             (cond ((and but-sym-flag current-actype)
+                    (setq actype current-actype))
+                   (actype)
+                   (current-actype
+                    (setq actype current-actype)))
+             (unless actype
+               (setq actype (or
+                             ;; Hyperbole action type
+                             (symtable:actype-p (car args))
+                             ;; Regular Emacs Lisp function symbol
+                             (car args))))
+             (hattr:set 'hbut:current 'actype actype)
+
+             (when args
+               (hattr:set 'hbut:current 'args (if actype (cdr args) args))))
+
            (hbdata:ibut-instance)))
       (set-marker ibpoint nil))))
 
@@ -1820,17 +1939,6 @@ Insert INSTANCE-FLAG after END, before ending delimiter."
     (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.
@@ -1861,48 +1969,63 @@ Return nil if no matching button is found."
           (or (eq categ 'implicit)
               (string-match "\\`ibtypes::" (symbol-name categ)))))))
 
-(defun    ibut:label-map (but-func &optional _start-delim _end-delim
-                                  _regexp-match _include-delims)
-  "Apply BUT-FUNC to buttons delimited by optional START-DELIM and END-DELIM.
-START-DELIM defaults to ibut:label-start; END-DELIM defaults to ibut:label-end.
+(defun    ibut:label-map (but-func &optional regexp-match include-delims)
+  "Apply BUT-FUNC to buttons delimited by `ibut:label-start' and 
`ibut:label-end'.
 If REGEXP-MATCH is non-nil, only buttons which match this argument are
 considered.
 
 Map over portion of buffer visible under any current restriction.
-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).
-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))
+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))
 
-(defun    ibut:label-key-match (lbl-key)
-  "Return a list of implicit button label keys fully matching LBL-KEY.
+(defun    ibut:label-key-match (name-key)
+  "Return a list of implicit button label keys fully matching NAME-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))
-         (ibut:label-regexp lbl-key))))
+         (ibut:label-instances-regexp name-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.
-This is the normalized key form of an optional label that may
-precede an implicit button.  Use `ibut:at-p' instead to test if
-point is on either the implicit button text itself or the label.
-Assume point is within the first line of any button label.
 
-All following arguments are optional.  If AS-LABEL is non-nil,
-label is returned rather than the key derived from the label.
-START-DELIM and END-DELIM are strings that override default
-button label delimiters.  With POS-FLAG non-nil, return list of
-label-or-key, but-label-start-position, but-label-end-position.
-Positions include delimiters.  With TWO-LINES-FLAG non-nil,
-constrain label search to two lines."
+This is the normalized key form of an optional name that may precede an
+implicit button (when the start and end delimiters are not given as
+arguments).  If delimiters are given as arguments, return the key form
+of the implicit button text at point between those delimiters.
+
+Use `ibut:at-p' instead to test if point is on either the
+implicit button text itself or the label. Assume point is within the
+first line of any button label.
+
+All following arguments are optional.  If AS-LABEL is non-nil, label is
+returned rather than the key derived from the label.  START-DELIM and
+END-DELIM are strings that override default button label delimiters.
+With POS-FLAG non-nil, return list of label-or-key,
+but-label-start-position, but-label-end-position.  Positions include
+delimiters.  With TWO-LINES-FLAG non-nil, constrain label search to two
+lines."
+  (unless start-delim
+    (setq start-delim ibut:label-start))
+  (unless end-delim
+    (setq end-delim ibut:label-end))
+
   (with-syntax-table hbut:syntax-table
-    (ebut:label-p as-label (or start-delim ibut:label-start)
-                 (or end-delim ibut:label-end) pos-flag two-lines-flag)))
+    (if (or (string-prefix-p "<" start-delim)
+           (string-suffix-p ">" end-delim))
+       (ebut:label-p as-label start-delim end-delim
+                     pos-flag two-lines-flag)
+      ;; When delims do not end with <>, then filter out matches
+      ;; that are surrounded by angle brackets, e.g. [str] should
+      ;; not match to occurrences of <[str]>.
+      (hargs:delimited (concat "<?" (regexp-quote start-delim))
+                      (concat (regexp-quote end-delim) ">?")
+                      t t pos-flag "\\`<.*>\\'" (not as-label)))))
 
 (defun    ibut:label-regexp (lbl-key &optional no-delim)
   "Unnormalize ibutton LBL-KEY.
@@ -1910,6 +2033,12 @@ Return regular expression matching delimited button 
label.
 Optional NO-DELIM leaves off delimiters, leading and trailing space."
   (hbut:label-regexp lbl-key no-delim ibut:label-start ibut:label-end))
 
+(defun    ibut:label-instances-regexp (lbl-key &optional no-delim)
+  "Unnormalize ibutton LBL-KEY.
+Return regular expression matching all instances of delimited button label.
+Optional NO-DELIM leaves off delimiters, leading and trailing space."
+  (hbut:label-instances-regexp lbl-key no-delim ibut:label-start 
ibut:label-end))
+
 (defun    ibut:label-set (label &optional start end)
   "Set current implicit button attributes.
 Get attributes from LABEL and optional START, END positions.
@@ -1919,8 +2048,8 @@ activated or queried for its attributes.  If LABEL is a 
list, it
 is assumed to contain all arguments.
 
 For legacy reasons, the label here is actually the text of the
-implicit button matched contextually and never the optional delimited
-name/label preceding the text."
+implicit button matched contextually and never the optional <[name]>
+preceding the text."
   (cond ((stringp label)
         (hattr:set 'hbut:current 'lbl-key (hbut:label-to-key label))
         (when start (hattr:set    'hbut:current 'lbl-start start))
@@ -1991,9 +2120,10 @@ positions at which the button label delimiter begins and 
ends."
 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)."
+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))
 
 (defun    ibut:next-occurrence (lbl-key &optional buffer)
@@ -2011,37 +2141,80 @@ 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 active region text 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)
+(defun    ibut:operate (&optional new-name)
+  "Insert/modify an ibutton based on `hbut:current' in current buffer.
+If optional NEW-NAME is non-nil, modify an existing ibutton with 'name'
+attribute in `hbut:current'.
+
+If NAME is nil, use the active region text as the button name, if any;
+if no such region, then create an unnamed implicit button.
+
+Return instance string appended to name to form a per-buffer unique
+name; nil if name is already unique or no name.  Signal an error when no
+such button is found in the current buffer.
+
+Summary of operations based on inputs:
+|-------+----------+--------+------------------------------------------------|
+| name  | new-name | region | operation                                      |
+|-------+----------+--------+------------------------------------------------|
+| nil   | nil      | nil    | create: unnamed ibut                           |
+| aname | nil      | nil    | create/update: aname named ibut                |
+| aname | nil      | region | create/update: aname named ibut (skip region)  |
+| nil   | nil      | region | create/update: region named ibut               |
+| aname | newname  | nil    | mod: rename aname to newname                   |
+| aname | newname  | region | mod: rename aname to newname (skip region)     |
+| nil   | newname  | nil    | mod: add newname to lbl-key ibut               |
+| nil   | newname  | region | mod: add newname to lbl-key ibut (skip region) |
+|-------+----------+--------+------------------------------------------------|"
+  ;; !! TODO: Code does not yet fully match what is in docstring table
+  (let* ((lbl-key (hattr:get 'hbut:current 'lbl-key))
+        (actype (hattr:get 'hbut:current 'actype))
+        (name (hattr:get 'hbut:current 'name))
+        (name-regexp (ibut:label-regexp (ibut:label-to-key name)))
+        (modify new-name)
+        (region-flag (hmouse-use-region-p))
+        ;; (new-name-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)
+    (unless (and (stringp lbl-key) (not (string-empty-p lbl-key)))
+      (hypb:error "(ibut:operate): hbut:current ibut lbl-key (%s) must be 
non-nil"
+                 lbl-key))
+    (unless actype
+      (hypb:error "(ibut:operate): hbut:current ibut actype (%s) must be 
non-nil"
+                 actype))
+    (when (and new-name (or (not (stringp new-name)) (string-empty-p 
new-name)))
+      (hypb:error "(ibut:operate): 'new-name' value must be a non-empty 
string, not: '%s'"
+                 new-name))
+
+    (unless new-name
+      (setq new-name name))
+    ;; (setq new-name-key (ibut:label-to-key new-name))
+    ;; (hattr:set 'hbut:current 'lbl-key new-name-key)
+    (when (stringp new-name)
+      (hattr:set 'hbut:current 'name new-name))
     (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))))
+      (if (progn
+           (if modify
+               (progn
+                 (setq instance-flag
+                       (hbdata:ibut-instance-last (ibut:label-to-key 
new-name)))
+                 (run-hooks 'ibut-edit-hook))
+             (setq instance-flag
+                   (hbdata:ibut-instance-last (ibut:label-to-key name)))
+             (run-hooks 'ibut-create-hook))
+           (when (null instance-flag)
+             (setq instance-flag t))
+           instance-flag)
+         (when (hmail:editor-p)
+           (hmail:msg-narrow))
+       (hypb:error "(ibut:operate): Failed to %s button %s%s%s in buffer %s"
+                   (if modify "modify" "create")
+                   ibut:label-start name ibut:label-end
+                   (buffer-name))))
     (cond (modify
-           ;; Rename all occurrences of button - those with same label
+           ;; Rename all occurrences of button - those with same name
            (let* ((but-key-and-pos (ibut:label-p nil nil nil 'pos))
                   (at-but (equal (car but-key-and-pos)
-                                 (ibut:label-to-key new-label))))
+                                 (ibut:label-to-key new-name))))
              (when at-but
                (ibut:delimit (nth 1 but-key-and-pos)
                              (nth 2 but-key-and-pos)
@@ -2051,26 +2224,26 @@ button is found in the current buffer."
                        (delete-region start end)
                        (ibut:delimit
                         (point)
-                        (progn (insert new-label) (point))
+                        (progn (insert new-name) (point))
                         instance-flag))
-                     lbl-regexp 'include-delims))
+                     name-regexp 'include-delims))
                    (at-but)
-                   ((hypb:error "(ibut:operate): No button matching: %s" 
curr-label)))))
+                   ((hypb:error "(ibut:operate): No button matching: %s" 
name)))))
 
          (instance-flag
-          ;; Above flag is 't when only one instance of the label
+          ;; Above flag is 't when only one instance of the name
           ;;
-          ;; Add a new button recording its start and end positions
+          ;; Add a new implicit button in the buffer, recording its
+          ;; start and end positions
           (let (start end mark prev-point buf-lbl)
-            (cond ((not (and curr-label new-label))
-                   ;; No label/name to insert, just insert ibutton
-                   ;; text below
+            (cond ((not (and name new-name))
+                   ;; No name to insert, just insert ibutton text below
                    )
-                  ((not curr-label)
+                  ((not name)
                    (setq start (point))
-                   (insert new-label)
+                   (insert new-name)
                    (setq end (point)))
-                  ((and (hmouse-use-region-p)
+                  ((and region-flag
                         (if (hyperb:stack-frame
                              '(hui:ebut-create hui:ebut-edit 
hui:ebut-edit-region
                                                hui:ebut-link-create 
hui:gbut-create
@@ -2082,7 +2255,7 @@ button is found in the current buffer."
                                          start (region-beginning)
                                          end (region-end)
                                          buf-lbl 
(buffer-substring-no-properties start end))
-                                   (equal buf-lbl curr-label))
+                                   (equal buf-lbl name))
                           ;; Utilize any action-key-depress-prev-point
                           (setq mark (marker-position (mark-marker)))
                           (setq prev-point (and action-key-depress-prev-point
@@ -2094,14 +2267,14 @@ button is found in the current buffer."
                                         prev-point
                                       (region-end))
                                 buf-lbl (buffer-substring-no-properties start 
end))
-                          (equal buf-lbl curr-label)))
+                          (equal buf-lbl name)))
                    nil)
                   ((progn (when start (goto-char start))
-                          (looking-at (regexp-quote curr-label)))
+                          (looking-at (regexp-quote name)))
                    (setq start (point)
                          end (match-end 0)))
                   (t (setq start (point))
-                     (insert curr-label)
+                     (insert name)
                      (setq end (point))))
             (when (and start end)
               (ibut:delimit start end instance-flag))
@@ -2113,13 +2286,14 @@ button is found in the current buffer."
              "(ibut:operate): Operation failed.  Check button attribute 
permissions: %s"
              hattr:filename)))
 
-    ;; Append any instance-flag string to the button label
+    ;; Append any instance-flag string to the button name
     (when (stringp instance-flag)
-      (setq new-label (concat new-label instance-flag))
-      (hattr:set 'hbut:current 'lbl-key (ibut:label-to-key new-label)))
+      (setq new-name (concat new-name instance-flag))
+      ;; (hattr:set 'hbut:current 'lbl-key (ibut:label-to-key new-name))
+      (hattr:set 'hbut:current 'name new-name))
 
     ;; Position point
-    (let ((new-key (ibut:label-to-key new-label)))
+    (let ((new-key (ibut:label-to-key new-name)))
       (cond ((equal (ibut:label-p) new-key)
             ;; In case right before the start of the desired
             ;; button's delimiters.
@@ -2137,7 +2311,8 @@ button is found in the current buffer."
   "Space, delimit and insert the activatable text of IBUT."
   (when (not (string-empty-p (or (hattr:get ibut 'name) "")))
     (insert ibut:label-separator))
-  (let* ((actype (actype:elisp-symbol (hattr:get ibut 'actype)))
+  (let* ((actype (actype:elisp-symbol (or (hattr:get ibut 'actype)
+                                         (hattr:get ibut 'categ))))
         (args   (hattr:get ibut 'args))
         (arg1   (nth 0 args))
         (arg2   (nth 1 args))
@@ -2197,14 +2372,14 @@ 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)
+(defun    ibut:program (name 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
+Create button from NAME, ACTYPE (action type), and optional actype ARGS.
+Insert NAME text at point surrounded by <[ ]> delimiters, adding any
+necessary instance number of the button after the NAME.  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.
+the button NAME which is automatically provided as the first argument.
 
 For interactive creation, use `hui:ibut-create' instead."
   (save-excursion
@@ -2214,19 +2389,18 @@ For interactive creation, use `hui:ibut-create' 
instead."
       (condition-case err
          (progn
            (hattr:clear 'hbut:current)
+           (hattr:set 'hbut:current 'name name)
            (hattr:set 'hbut:current 'categ 'implicit)
            (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)))
+             (error (format "actype arg must be a bound symbol (not a string): 
%S" actype)))
            (hattr:set 'hbut:current 'args args)
-           (ibut:operate label nil))
+           (ibut:operate))
        (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)))))))
+              (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.
@@ -2250,21 +2424,21 @@ current."
 
 (defalias 'ibut:summarize 'hbut:report)
 
-(defun    ibut:to (lbl-key)
-  "Find the nearest implicit button with LBL-KEY (a label or label key).
+(defun    ibut:to (name-key)
+  "Find the nearest implicit button with NAME-KEY (a name or name key).
 Find within the visible portion of the current buffer.
-Leave point inside the button text or its optional label, if it has one.
+Leave point inside the button text or its optional name, if it has one.
 Return the symbol for the button, else nil."
-  (unless lbl-key
-    (setq lbl-key (ibut:label-p nil nil nil nil t)))
-  (hbut:funcall (lambda (lbl-key _buffer _key-src)
-                 (when lbl-key
-                   ;; Handle a label given rather than a label key
-                   (when (string-match-p "\\s-" lbl-key)
-                     (setq lbl-key (ibut:label-to-key lbl-key)))
-                   (let ((regexp (hbut:label-regexp lbl-key t))
+  (unless name-key
+    (setq name-key (ibut:label-p nil nil nil nil t)))
+  (hbut:funcall (lambda (name-key _buffer _key-src)
+                 (when name-key
+                   ;; Handle a name given rather than a name key
+                   (when (string-match-p "\\s-" name-key)
+                     (setq name-key (ibut:label-to-key name-key)))
+                   (let ((regexp (hbut:label-regexp name-key t))
                          (start (point))
-                         at-lbl-key
+                         at-name-key
                          ibut
                          pos
                          found)
@@ -2282,20 +2456,22 @@ Return the symbol for the button, else nil."
                                found (save-excursion
                                        (goto-char (1- (point)))
                                        (setq ibut (ibut:at-p)
-                                             at-lbl-key (hattr:get ibut 
'lbl-key))
-                                       (equal at-lbl-key lbl-key))))
+                                             at-name-key (ibut:label-to-key
+                                                          (hattr:get ibut 
'name)))
+                                       (equal at-name-key name-key))))
                        (unless found
                          (goto-char start))
                        ;; re-search backward
                        (while (and (not found) (re-search-backward regexp nil 
t))
                          (setq pos (match-beginning 0)
                                ibut (ibut:at-p)
-                               at-lbl-key (hattr:get ibut 'lbl-key)
-                               found (equal at-lbl-key lbl-key))))
+                               at-name-key (ibut:label-to-key
+                                            (hattr:get ibut 'name))
+                               found (equal at-name-key name-key))))
                      (when found
                        (goto-char pos)
                        ibut))))
-               lbl-key
+               name-key
                (current-buffer)))
 
 (defun    ibut:at-to-name-p (&optional ibut)
@@ -2356,38 +2532,38 @@ Return the symbol for the button if found, else nil."
    lbl-key
    (current-buffer)))
 
-(defun    ibut:to-text (lbl-key)
-  "Move to the text of the nearest implicit button matching LBL-KEY.
-Find the nearest implicit button with LBL-KEY (a label or label
-key) within the visible portion of the current buffer and move to
-within its button text.  This will find an implicit button if
-point is within its name or text or if LBL-KEY is a name/name-key
-of an existing implicit button.  It will not find other unnamed
+(defun    ibut:to-text (name-key)
+  "Move to the text of the nearest implicit button matching NAME-KEY.
+Find the nearest implicit button with NAME-KEY (a name or name key)
+within the visible portion of the current buffer and move to within
+its button text.  This will find an implicit button if point is
+within its name or text or if NAME-KEY is a name/name-key of an
+existing implicit button.  It will not find other unnamed
 implicit buttons.
 
 Return the symbol for the button if found, else nil."
-  (unless lbl-key
-    (setq lbl-key (ibut:label-p nil nil nil nil t)))
-  (when lbl-key
+  (unless name-key
+    (setq name-key (ibut:label-p nil nil nil nil t)))
+  (when name-key
     (hbut:funcall
-     (lambda (lbl-key _buffer _key-src)
+     (lambda (name-key _buffer _key-src)
        (let* ((name-start-end (ibut:label-p t nil nil t t))
              (name-end (nth 2 name-start-end))
              (at-name (car name-start-end))
-             (at-lbl-key (ibut:label-p nil "\"" "\"" nil t))
+             (at-name-key (ibut:label-p nil "\"" "\"" nil t))
              (opoint (point))
              move-flag
              start
              ibut)
         ;; Do not move point if it is already in the text of an
-        ;; implicit button matching LBL-KEY.  If on the name of
+        ;; implicit button matching NAME-KEY.  If on the name of
         ;; the same button, move into the text of the button.
-        (cond ((and lbl-key (equal at-lbl-key lbl-key))
+        (cond ((and name-key (equal at-name-key name-key))
                (setq ibut 'hbut:current))
-              ((and at-name (equal (ibut:label-to-key at-name) lbl-key))
+              ((and at-name (equal (ibut:label-to-key at-name) name-key))
                (setq ibut 'hbut:current
                      move-flag t))
-              ((and lbl-key (setq ibut (ibut:to lbl-key)))
+              ((and name-key (setq ibut (ibut:to name-key)))
                (setq move-flag t)))
         (when (and move-flag ibut (not (hbut:outside-comment-p)))
           ;; Skip past any optional name and separators
@@ -2403,7 +2579,7 @@ Return the symbol for the button if found, else nil."
                   (goto-char (min (+ 2 (match-end 0)) (point-max)))
                 (goto-char opoint)))))
         ibut))
-     lbl-key
+     name-key
      (current-buffer))))
 
 ;;; ------------------------------------------------------------------------
diff --git a/hibtypes.el b/hibtypes.el
index d576427aef..aba38268c0 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:     20-May-23 at 16:10:20 by Bob Weiner
+;; Last-Mod:     10-Jun-23 at 20:47:06 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -391,12 +391,10 @@ must have an attached file."
          (not (or (eq chr ?\ ) (eq chr ?*))))
        (not (or (derived-mode-p 'prog-mode)
                 (apply #'derived-mode-p '(c-mode objc-mode c++-mode java-mode 
markdown-mode org-mode))))
-       (let* ((ref-and-pos (hbut:label-p t "[" "]" t))
-              (ref (car ref-and-pos)))
+       (let ((ref (hattr:get 'hbut:current 'lbl-key)))
          (and ref (eq ?w (char-syntax (aref ref 0)))
               (not (string-match "[#@]" ref))
-              (progn (ibut:label-set ref-and-pos)
-                     (hact 'annot-bib ref))))))
+              (hact 'annot-bib ref)))))
 
 ;;; ========================================================================
 ;;; Displays in-file Markdown link referents.
@@ -1467,12 +1465,12 @@ There may not be any <> characters within the 
expression.  The
 first identifier in the expression must be an Elisp variable,
 action type or a function symbol to call, i.e. '<'actype-or-elisp-symbol
 arg1 ... argN '>'.  For example, <mail nil \"user@somewhere.org\">."
-  (let* ((hbut:max-len 0)
-         (label-key-start-end (ibut:label-p nil action:start action:end t))
-         (lbl-key (nth 0 label-key-start-end))
-         (start-pos (nth 1 label-key-start-end))
-         (end-pos (nth 2 label-key-start-end))
-         actype actype-sym action args lbl var-flag)
+  (let ((hbut:max-len 0)
+       (lbl-key (hattr:get 'hbut:current 'lbl-key))
+       (start-pos (hattr:get 'hbut:current 'lbl-start))
+       (end-pos  (hattr:get 'hbut:current 'lbl-end))
+        actype actype-sym action args lbl var-flag)
+
     ;; Continue only if start-delim is either:
     ;;     at the beginning of the buffer
     ;;     or preceded by a space character or a grouping character
@@ -1483,8 +1481,8 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
     ;;     or is followed by a space, punctuation or grouping character.
     (when (and lbl-key (or (null (char-before start-pos))
                            (memq (char-syntax (char-before start-pos)) '(?\  
?\> ?\( ?\))))
-               (not (memq (char-syntax (char-after (1+ start-pos))) '(?\  
?\>)))
-               (or (null (char-after end-pos))
+              (not (memq (char-syntax (char-after (1+ start-pos))) '(?\  ?\>)))
+              (or (null (char-after end-pos))
                    (memq (char-syntax (char-after end-pos)) '(?\  ?\> ?. ?\( 
?\)))
                    ;; Some of these characters may have symbol-constituent 
syntax
                    ;; rather than punctuation, so check them individually.
@@ -1494,7 +1492,7 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
       ;; bound as a function symbol
       (when (string-match "\\`\\$" lbl)
         (setq var-flag t
-              lbl (substring lbl 1)))
+             lbl (substring lbl 1)))
       (setq actype (if (string-match-p " " lbl) (car (split-string lbl)) lbl)
             actype-sym (intern-soft (concat "actypes::" actype))
            ;; Must ignore that (boundp nil) would be t here.
@@ -1502,7 +1500,7 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
                            (or (fboundp actype-sym) (boundp actype-sym)
                                (special-form-p actype-sym))
                            actype-sym)
-                       (and (setq actype-sym (intern-soft actype))
+                      (and (setq actype-sym (intern-soft actype))
                            (or (fboundp actype-sym) (boundp actype-sym)
                                (special-form-p actype-sym))
                            actype-sym)))
@@ -1515,7 +1513,7 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
                                              (combine-and-quote-strings
                                               (split-string lbl) "\" \""))))
         (setq action (read (concat "(" lbl ")"))
-              args (cdr action))
+             args (cdr action))
        ;; Ensure action uses an fboundp symbol if executing a
        ;; Hyperbole actype.
        (when (and (car action) (symbolp (car action)))
@@ -1524,22 +1522,22 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
                      (car action))))
        (unless assist-flag
           (cond ((and (symbolp actype) (fboundp actype)
-                      (string-match "-p\\'" (symbol-name actype)))
+                     (string-match "-p\\'" (symbol-name actype)))
                 ;; Is a function with a boolean result
                 (setq args `(',args)
                       action `(display-boolean ',action)
-                       actype #'display-boolean))
+                      actype #'display-boolean))
                ((and (null args) (symbolp actype) (boundp actype)
-                      (or var-flag (not (fboundp actype))))
+                     (or var-flag (not (fboundp actype))))
                 ;; Is a variable, display its value as the action
                 (setq args `(',args)
-                       action `(display-variable ',actype)
-                       actype #'display-variable))
+                      action `(display-variable ',actype)
+                      actype #'display-variable))
                (t
                 ;; All other expressions, display the action result in the 
minibuffer
                 (setq args `(',args)
-                       action `(display-value ',action)
-                       actype #'display-value))))
+                      action `(display-value ',action)
+                      actype #'display-value))))
 
        ;; Create implicit button object and store in symbol hbut:current.
        (ibut:create :lbl-key lbl-key :lbl-start start-pos :lbl-end end-pos
@@ -1547,11 +1545,11 @@ arg1 ... argN '>'.  For example, <mail nil 
\"user@somewhere.org\">."
 
         ;; Necessary so can return a null value, which actype:act cannot.
         (let ((hrule:action
-               (if (eq hrule:action #'actype:identity)
+              (if (eq hrule:action #'actype:identity)
                    #'actype:identity
                  #'actype:eval)))
           (if (eq hrule:action #'actype:identity)
-              `(hact ,actype ,@args)
+             `(hact ,actype ,@args)
             `(hact ,actype ,@(mapcar #'eval args))))))))
 
 (defun action:help (hbut)
diff --git a/hmouse-tag.el b/hmouse-tag.el
index c1142905fe..264c478dcd 100644
--- a/hmouse-tag.el
+++ b/hmouse-tag.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    24-Aug-91
-;; Last-Mod:     14-May-23 at 01:29:38 by Bob Weiner
+;; Last-Mod:     10-Jun-23 at 18:00:52 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -381,7 +381,7 @@ If:
   nil)
 
 (defun smart-emacs-lisp-mode-p ()
-  "Return t if in a mode which uses Emacs Lisp symbols."
+  "Return non-nil if in a mode which uses Emacs Lisp symbols."
   ;; Beyond Lisp files, Emacs Lisp symbols appear frequently in Byte-Compiled
   ;; buffers, debugger buffers, program ChangeLog buffers, Help buffers,
   ;; *Warnings*, *Flymake log* and *Flymake diagnostics... buffers.
@@ -662,7 +662,7 @@ Use `hpath:display-buffer' to show definition or 
documentation."
                                  "Show doc for" "Find")))
         current-prefix-arg))
   (unless (stringp tag)
-    (setq tag (smart-lisp-at-tag-p t)))
+    (setq tag (or hkey-value (smart-lisp-at-tag-p t))))
   (let* ((elisp-flag (smart-emacs-lisp-mode-p))
         (tag-sym (intern-soft tag)))
     (cond ((and show-doc elisp-flag)
@@ -675,8 +675,9 @@ Use `hpath:display-buffer' to show definition or 
documentation."
                 (t nil)))
          ((and elisp-flag (fboundp 'find-function-noselect)
                (let ((result (smart-lisp-bound-symbol-def tag-sym)))
-                 (when (cdr result)
-                   (hpath:display-buffer (car result))
+                 (when (and (cdr result)
+                            (hpath:display-buffer (car result)))
+                   (widen)
                    (goto-char (cdr result))
                    t))))
          ;; If elisp-flag is true, then make xref use tags tables to
@@ -701,7 +702,7 @@ Use `hpath:display-buffer' to show definition or 
documentation."
 
 (defun smart-lisp-at-definition-p ()
   "Return non-nil if point is on the first line of a non-alias Lisp definition.
-  Apply only to non-help buffers and return nil in others."
+Apply only to non-help buffers and return nil in others."
     (unless (derived-mode-p 'help-mode)
       (save-excursion
        (beginning-of-line)
@@ -726,7 +727,8 @@ Return matching Elisp tag name that point is within, else 
nil."
   (when (derived-mode-p 'change-log-mode)
     (let ((identifier (smart-lisp-at-tag-p)))
       (and identifier (intern-soft identifier)
-          (string-match "[^-]-[^-]" identifier)))))
+          (string-match "[^-]-[^-]" identifier)
+          identifier))))
 
 (defun smart-lisp-htype-tag (tag)
   "Given TAG at point, if a Hyperbole type, return the full symbol name, else 
TAG."
@@ -1133,7 +1135,7 @@ This indicates that TAG is serving as a hyperlink button."
   tag)
 
 (defun smart-lisp-at-known-identifier-p ()
-  "Return non-nil if point is within a known Lisp identifier.
+  "Return identifier if point is within a known Lisp identifier, else nil.
 The Lisp identifier is either listed in a tags table or is a
 known Emacs Lisp identifier."
   (interactive)
@@ -1149,17 +1151,21 @@ known Emacs Lisp identifier."
                 (goto-char opoint)
                 (when lib
                   (ignore-errors (and (find-library-name lib) t)))))
-    (let* ((tag (smart-lisp-at-tag-p t))
+    ;; Cache tag value
+    (setq hkey-value (smart-lisp-at-tag-p t))
+    (let* ((tag hkey-value)
           (tag-sym (intern-soft tag)))
-      (cond ((if (fboundp 'find-function-noselect)
-                (let ((result (smart-lisp-bound-symbol-def tag-sym)))
-                  (if (cdr result) t))))
+      (cond ((when (and (fboundp 'find-function-noselect) tag-sym)
+              (let ((result (smart-lisp-bound-symbol-def tag-sym)))
+                (when (cdr result)
+                  tag))))
            ;; This part only works properly for Emacs Lisp, so is 
conditionalized.
-           (tag (smart-tags-find-p tag))))))
+           (and tag (smart-tags-find-p tag) tag)))))
 
 (defun smart-lisp-bound-symbol-def (tag-sym)
-  "Return the file where TAG-SYM is defined which may be a .elc file.
-TAG-SYM may be a function, variable or face."
+  "Return a pair (buffer . point) where TAG-SYM is defined, else nil.
+The buffer may be attached to a .elc file.  TAG-SYM may be a function,
+variable or face."
   (save-excursion
     ;; Bound Emacs Lisp function, variable and face definition display.
     (ignore-errors (or (find-function-noselect tag-sym)
diff --git a/hpath.el b/hpath.el
index 90ee4fcfa0..f47901582c 100644
--- a/hpath.el
+++ b/hpath.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     1-Nov-91 at 00:44:23
-;; Last-Mod:     20-May-23 at 23:20:22 by Bob Weiner
+;; Last-Mod:     28-May-23 at 16:53:34 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1411,7 +1411,7 @@ but locational suffixes within the file are utilized."
              path (if (match-end 1)
                       (substring path 0 (match-end 1))
                     (or buffer-file-name "")))
-       ;; 'anchor' may improproperly include trailing punctuation;
+       ;; 'anchor' may improperly include trailing punctuation;
        ;; remove it if so.
        (when (string-match "\\s.+\\'" anchor)
          (setq anchor (substring anchor 0 (match-beginning 0))))))
diff --git a/hui-mouse.el b/hui-mouse.el
index d371bb321e..09f53a6cb7 100644
--- a/hui-mouse.el
+++ b/hui-mouse.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    04-Feb-89
-;; Last-Mod:     21-May-23 at 12:06:23 by Bob Weiner
+;; Last-Mod:     10-Jun-23 at 18:38:57 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -393,11 +393,6 @@ Its default value is `smart-scroll-down'.  To disable it, 
set it to
          (setq hkey-value (smart-python-at-tag-p)))
      . ((smart-python hkey-value) . (smart-python hkey-value 'next-tag)))
     ;;
-    ;; Imenu listing in GNU Emacs
-    ((smart-imenu-item-at-p)
-     . ((smart-imenu-display-item-where (car hkey-value) (cdr hkey-value)) .
-       (imenu-choose-buffer-index)))
-    ;;
     ((and (eq major-mode 'c-mode)
          buffer-file-name (smart-c-at-tag-p))
      . ((smart-c) . (smart-c nil 'next-tag)))
@@ -412,11 +407,16 @@ Its default value is `smart-scroll-down'.  To disable it, 
set it to
          buffer-file-name (smart-asm-at-tag-p))
      . ((smart-asm) . (smart-asm nil 'next-tag)))
     ;;
-    ((or (and (smart-lisp-mode-p)
-             (or (smart-lisp-at-load-expression-p)
-                 (smart-lisp-at-tag-p)))
-        ;; Tightly limit Lisp matches in change-log-mode.
-        (smart-lisp-at-change-log-tag-p))
+    ((setq hkey-value nil
+          hkey-value
+          (or (when (smart-lisp-mode-p)
+                (or (setq hkey-value (smart-lisp-at-load-expression-p))
+                    (smart-lisp-at-tag-p)))
+              ;; Tightly limit Lisp matches in change-log-mode but
+              ;; only call this if hkey-value is true since
+              ;; otherwise, already know there is no tag at point.
+              (when hkey-value
+                (smart-lisp-at-change-log-tag-p))))
      . ((smart-lisp) . (smart-lisp 'show-doc)))
     ;;
     ;;
@@ -438,6 +438,11 @@ Its default value is `smart-scroll-down'.  To disable it, 
set it to
          (smart-objc-at-tag-p))
      . ((smart-objc) . (smart-objc nil 'next-tag)))
     ;;
+    ;; Imenu listing in GNU Emacs
+    ((smart-imenu-item-at-p)
+     . ((smart-imenu-display-item-where (car hkey-value) (cdr hkey-value)) .
+       (imenu-choose-buffer-index)))
+    ;;
     ((and (memq major-mode '(fortran-mode f90-mode))
          buffer-file-name (smart-fortran-at-tag-p))
      . ((smart-fortran) . (smart-fortran nil 'next-tag)))
@@ -1398,10 +1403,6 @@ Does nothing unless imenu has been loaded and an index 
has been
 created for the current buffer.  When return value is non-nil, also
 sets `hkey-value' to (identifier . identifier-definition-buffer-position)."
   (and (featurep 'imenu) imenu--index-alist
-       ;; Ignore non-alias identifiers on the first line of a Lisp def.
-       (not (and (smart-lisp-mode-p) (smart-lisp-at-definition-p)))
-       ;; Ignore Lisp loading expressions
-       (not (smart-lisp-at-load-expression-p))
        (setq hkey-value (smart-imenu-item-p hkey-value variable-flag))
        (setq hkey-value (cons (hargs:find-tag-default) hkey-value))
        (cdr hkey-value)))
diff --git a/hui.el b/hui.el
index 9c815bb79a..e4b2c19c47 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:     20-May-23 at 17:31:58 by Bob Weiner
+;; Last-Mod:     11-Jun-23 at 12:04:31 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -662,17 +662,17 @@ When in the global button buffer, the default is the 
button at point."
                                          nil t nil 'gbut)))))
   (hbut:rename (gbut:to label)))
 
-(defun hui:gibut-create (lbl text)
-  "Create a Hyperbole global implicit button with LBL and button TEXT.
+(defun hui:gibut-create (name text)
+  "Create a Hyperbole global implicit button with NAME and button TEXT at 
point.
 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): ")
+  (interactive "sCreate global implicit button named: \nsButton text (with any 
delimiters): ")
   (let (but-buf
        opoint
         delimited-label)
     (save-excursion
-      (setq delimited-label (concat ibut:label-start lbl ibut:label-end)
+      (setq delimited-label (concat ibut:label-start name ibut:label-end)
            but-buf (hpath:find-noselect (gbut:file)))
       (hui:buf-writable-err but-buf "gibut-create")
       ;; This prevents movement of point which might be useful to user.
@@ -688,7 +688,7 @@ Use `hui:gbut-create' to create a global explicit button."
          ;; Create button object from ibut at point
          (ibut:create))
        (save-buffer))
-      (message "`%s' global implicit button created." lbl))))
+      (message "`%s' global implicit button created." name))))
 
 (defun hui:hbut-act (&optional but)
   "Execute action for optional Hyperbole button symbol BUT in current buffer.
@@ -863,20 +863,20 @@ See `hbut:report'."
 
 (defalias 'hui:hbut-summarize #'hui:hbut-report)
 
-(defun hui:ibut-act (&optional but)
-  "Activate optional labeled implicit button symbol BUT in current buffer.
+(defun hui:ibut-act (&optional ibut)
+  "Activate optional labeled implicit button symbol IBUT in current buffer.
 Default is any implicit button at point."
   (interactive
-   (let ((but (ibut:at-p)) (lst))
+   (let ((ibut (ibut:at-p)) (lst))
      (list
-      (cond (but)
+      (cond (ibut)
            ((setq lst (ibut:alist))
             (ibut:get (ibut:label-to-key
                        (hargs:read-match "Activate labeled implicit button: " 
lst nil t
                                          (ibut:label-p 'as-label) 'ibut))))
            (t
             (hypb:error "(ibut-act): No labeled implicit buttons in 
buffer."))))))
-  (hui:hbut-operate #'ibut:act "Activate labeled implicit button: " but))
+  (hui:hbut-operate #'ibut:act "Activate labeled implicit button: " ibut))
 
 (defun hui:ibut-create (&optional start end)
   "Interactively create an implicit Hyperbole button at point.
@@ -888,17 +888,17 @@ 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)
+    (let ((default-name) name 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 default-name (hui:hbut-label-default start end (not 
(called-interactively-p 'interactive)))
+             name (hui:hbut-label default-name "ibut-create"))
+       (unless (equal name default-name)
+         (setq default-name nil))
 
        (setq but-buf (current-buffer))
        (hui:buf-writable-err but-buf "ibut-create")
 
-       (hattr:set 'hbut:current 'name lbl)
+       (hattr:set 'hbut:current 'name name)
        (hattr:set 'hbut:current 'categ 'implicit)
        (hattr:set 'hbut:current 'loc (hui:key-src but-buf))
        (hattr:set 'hbut:current 'dir (hui:key-dir but-buf))
@@ -907,7 +907,7 @@ For programmatic creation, use `ibut:program' instead."
        (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)
+       (ibut:operate)
        (when (called-interactively-p 'interactive)
          (hui:ibut-message nil))))))
 
@@ -1130,6 +1130,8 @@ from those instead.  See also documentation for
 
 (defun hui:ibut-link-directly (&optional depress-window release-window)
   "Create a link ibutton at Action Key depress point, linked to release point.
+If ibutton exists at point, replace it with the new link button.
+
 With optional DEPRESS-WINDOW and RELEASE-WINDOW, use the points
 from those instead.  See also documentation for
 `hui:link-possible-types'."
@@ -1429,7 +1431,7 @@ for with completion of all labeled buttons within the 
current buffer."
         (hui:but-flash)
         (apply hrule:action
                operation
-               (list but)))
+               `(',but)))
        ((and but (symbolp but))
         (hypb:error "(hbut-operate): Symbol, %s, has invalid Hyperbole button 
attributes:\n  %S" but (hattr:list but)))
        (t
@@ -1609,11 +1611,11 @@ arguments."
   (let ((label (hbut:key-to-label lbl-key)))
     (ebut:operate label (when edit-flag label))))
 
-(defun hui:ibut-link-create (edit-flag but-window lbl-key but-loc but-dir 
type-and-args)
+(defun hui:ibut-link-create (edit-flag but-window name-key but-loc but-dir 
type-and-args)
   "Create or edit a new Hyperbole implicit link button.
 If EDIT-FLAG is non-nil, edit button at point in BUT-WINDOW,
-otherwise, prompt for button label and create a button.
-LBL-KEY is internal form of button label.  BUT-LOC is the file or buffer
+otherwise, prompt for button name and create a button.
+NAME-KEY is internal form of button name.  BUT-LOC is the file or buffer
 in which to create button.  BUT-DIR is the directory of BUT-LOC.
 TYPE-AND-ARGS is the action type for the button followed by any
 arguments it requires.  Any text properties are removed from string
@@ -1629,8 +1631,8 @@ arguments."
   (unless (and but-loc (or (equal (buffer-name) but-loc)
                           (eq (current-buffer) but-loc)))
     (hbut:key-src-set-buffer but-loc))
-  (let ((label (hbut:key-to-label lbl-key)))
-    (ibut:operate label (when edit-flag label))))
+  (let ((name (hbut:key-to-label name-key)))
+    (ibut:operate (when edit-flag name))))
 
 (defun hui:link-possible-types ()
   "Return list of possible link action types during editing of a Hyperbole 
button.
diff --git a/hyrolo.el b/hyrolo.el
index fae0fa3986..ae9f978f37 100644
--- a/hyrolo.el
+++ b/hyrolo.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     7-Jun-89 at 22:08:29
-;; Last-Mod:     23-Apr-23 at 22:20:14 by Mats Lidell
+;; Last-Mod:     10-Jun-23 at 21:17:16 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -732,12 +732,12 @@ Return t if entry is killed, nil otherwise."
 (defun hyrolo-mail-to ()
   "Start composing mail addressed to the first e-mail address at or after 
point."
   (interactive)
-  (let ((opoint (point)) button)
+  (let ((opoint (point)) ibut)
     (skip-chars-backward "^ \t\n\r<>")
     (if (and (re-search-forward mail-address-regexp nil t)
             (goto-char (match-beginning 1))
-            (setq button (ibut:at-p)))
-       (hui:hbut-act button)
+            (setq ibut (ibut:at-p)))
+       (hui:hbut-act ibut)
       (goto-char opoint)
       (beep)
       (message "(hyrolo-mail-to): Invalid buffer or no e-mail address 
found"))))
diff --git a/kotl/klink.el b/kotl/klink.el
index 8ca1161d22..06445fa6e1 100644
--- a/kotl/klink.el
+++ b/kotl/klink.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    15-Nov-93 at 12:15:16
-;; Last-Mod:     20-May-23 at 16:52:28 by Bob Weiner
+;; Last-Mod:     10-Jun-23 at 20:48:59 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -221,7 +221,6 @@ same directory."
 ;;; Hyperbole type definitions
 ;;; ************************************************************************
 
-
 (defib klink ()
   "Follow a link delimited by <> to a koutline cell.
 See documentation for the `link-to-kotl' function for valid klink formats."
@@ -229,7 +228,6 @@ See documentation for the `link-to-kotl' function for valid 
klink formats."
         (link (car link-and-pos))
         (start-pos (nth 1 link-and-pos)))
     (when link
-      (ibut:label-set link-and-pos)
       (hact 'klink:act link start-pos))))
 
 (defact link-to-kotl (link)
@@ -269,6 +267,8 @@ See documentation for `kcell:ref-to-id' for valid cell-ref 
formats."
 ;;; ************************************************************************
 
 (defun klink:act (link start-pos)
+  "Jump to klink LINK's referent.
+Update relative part of klink if referent has moved."
   (let ((obuf (current-buffer)))
     ;; Perform klink's action which is to jump to link referent.
     (prog1 (hact 'link-to-kotl link)
diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el
index 89cd6d46f4..78136c079d 100644
--- a/kotl/kotl-mode.el
+++ b/kotl/kotl-mode.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    6/30/93
-;; Last-Mod:     27-May-23 at 23:53:04 by Bob Weiner
+;; Last-Mod:     28-May-23 at 10:19:56 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -130,8 +130,9 @@ It provides the following keys:
   (setq-local fill-paragraph-function #'kfill:fill-paragraph)
   ;;
   ;; Prevent insertion of characters outside of editable bounds,
-  ;; e.g. after the mouse sets point to a non-editable position
-  (add-hook 'pre-command-hook #'kotl-mode:pre-self-insert-command)
+  ;; e.g. after the mouse sets point to a non-editable position.  Add hook
+  ;; only in this major mode.
+  (add-hook 'pre-command-hook #'kotl-mode:pre-self-insert-command nil t)
   ;;
   ;; Ensure that outline structure data is saved when save-buffer is called
   ;; from save-some-buffers, {C-x s}.
@@ -3318,10 +3319,10 @@ Mouse may have moved point outside of an editable area.
                              kotl-mode:self-insert-command
                              orgtbl-self-insert-command
                              self-insert-command))
-        (eq major-mode 'kotl-mode)
         (not (kview:valid-position-p))
         ;; Prevent repeatedly moving point to valid position when moving trees
-        (not (hyperb:stack-frame '(kcell-view:to-label-end))))
+        ;; (not (hyperb:stack-frame '(kcell-view:to-label-end)))
+        )
     (kotl-mode:to-valid-position)))
 
 (defun kotl-mode:print-attributes (_kview)
diff --git a/kotl/kview.el b/kotl/kview.el
index b510192257..3f843eabaf 100644
--- a/kotl/kview.el
+++ b/kotl/kview.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    6/30/93
-;; Last-Mod:      5-Feb-23 at 22:36:46 by Mats Lidell
+;; Last-Mod:     28-May-23 at 10:38:17 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -630,20 +630,13 @@ level."
 ;;;###autoload
 (defun kview:char-invisible-p (&optional pos)
   "Return t if the character after point is invisible/hidden, else nil."
-  (or pos (setq pos (point)))
-  (when (or (kproperty:get pos 'invisible)
-           (delq nil (mapcar (lambda (o) (overlay-get o 'invisible))
-                             (overlays-at (or pos (point))))))
+  (when (get-char-property (or pos (point)) 'invisible)
     t))
 
 ;;;###autoload
 (defun kview:char-visible-p (&optional pos)
   "Return t if the character after point is visible, else nil."
-  (unless pos
-    (setq pos (point)))
-  (and (not (kproperty:get pos 'invisible))
-       (not (delq nil (mapcar (lambda (o) (overlay-get o 'invisible))
-                             (overlays-at (or pos (point))))))))
+  (not (get-char-property (or pos (point)) 'invisible)))
 
 (defun kview:create (buffer-name
                         &optional id-counter top-cell-attributes
diff --git a/man/hkey-help.txt b/man/hkey-help.txt
index ab5cbe3b36..f32ae91bed 100644
--- a/man/hkey-help.txt
+++ b/man/hkey-help.txt
@@ -85,13 +85,13 @@ Hyperbole Key Press/Click in Special Modes
   Emacs Regression Test Def     Evals and runs test        Edebugs and runs 
test
   Thing Begin or End            Marks thing region         Marks & kills thing 
region
   Page Directory Listing        Jumps to page              <- same
-  Imenu Programming Identifier  Jumps to in-buffer def     Prompts for id to 
jump to
   C,C++,Objective-C,Java Modes  Jumps to id/include def    Jumps to next def
   Assembly Language Mode        Jumps to id/include def    Jumps to next def
   Java Cross-reference Tag      Jumps to identifier def    Jumps to next def
   JavaScript and Python Modes   Jumps to identifier def    Jumps to next def
   Any Known Lisp or ChangeLog   Jumps to identifier def    Referent Doc
   Fortran Mode                  Jumps to identifier def    Jumps to next def
+  Imenu Programming Identifier  Jumps to in-buffer def     Prompts for id to 
jump to
   Emacs Lisp Compiler Error     Jumps to def with error    <- same
   Emacs Regression Test (ERT)   Jumps to def with error    <- same
   Other Compiler Error          Jumps to src error line    <- same
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index d6da04808b..852edf3ead 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:     23-May-23 at 00:35:49 by Bob Weiner
+@c Last-Mod:     11-Jun-23 at 13:21:00 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 May 23, 2023.
+Printed June 11, 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
-May 23, 2023
+June 11, 2023
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -476,7 +476,6 @@ Smart Keyboard Keys
 * Smart Key - Bookmark Mode::
 * Smart Key - Pages Directory Mode::
 * Smart Key - Python Source Code::
-* Smart Key - Identifier Menu Mode ::
 * Smart Key - C Source Code::
 * Smart Key - C++ Source Code::
 * Smart Key - Assembly Source Code::
@@ -485,6 +484,7 @@ Smart Keyboard Keys
 * Smart Key - JavaScript Source Code::
 * Smart Key - Objective-C Source Code::
 * Smart Key - Fortran Source Code::
+* Smart Key - Identifier Menu Mode ::
 * Smart Key - Occurrence Matches::
 * Smart Key - Calendar Mode::
 * Smart Key - Man Page Apropos::
@@ -2666,15 +2666,6 @@ as the reference.  References must be delimited by 
square brackets, must
 begin with a word constituent character, and must not be in buffers
 whose names begin with a ` ' or `*' character.
 
-@c Handled instead by @pxref{Smart Key - Identifier Menu Mode}.
-@c @findex ibtypes imenu-item
-@c @vindex file, imenu.el
-@c @cindex identifier menu
-@c @cindex imenu
-@c @item imenu-item
-@c Display the in-buffer definition of an identifier that point is within or 
after, else nil.
-@c This triggers only when imenu has already been used to generate an 
in-buffer item index.
-
 @findex ibtypes mail-address
 @cindex e-mail address
 @cindex rolo address
@@ -6925,14 +6916,12 @@ type.
 @cindex ibtype, return val
 @cindex ibtype, actype
 The body of an implicit button type is a predicate which determines
-whether or not point is within an implicit button of the type.  If not,
-the predicate returns @samp{nil}.  If so, it may optionally setup to
-flash the button and then to perform one or more actions.  A call of the
-form: @code{(ibut:label-set label start-pos end-pos)} is used to setup
-the button flashing, if desired.  This is then typically immediately
-followed by an action invocation of the form:
-@code{(hact 'actype &rest actype-arguments)} where @code{actype} is a
-Hyperbole action type symbol or an Emacs Lisp function name or lambda;
+whether or not point is within an implicit button of the type.  If
+not, the predicate returns @samp{nil}.  If the type is delimited,
+Hyperbole automatically sets up to flash the button when activated.
+Action invocations have the form: @code{(hact 'actype &rest
+actype-arguments)} where @code{actype} is a Hyperbole action type
+symbol or an Emacs Lisp function name or lambda;
 @code{actype-arguments} are the arguments fed to the action invocation
 when an implicit button of the type is activated.
 
@@ -9426,6 +9415,46 @@ If an active (highlighted) region exists within the 
editor:
 @end group
 @end format
 
+@format
+@group
+Otherwise, if dragged from inside one window to another:
+  ACTION AND ASSIST KEYS
+     (1) If depress was on a buffer name in Buffer-menu/ibuffer mode or on
+         a file/directory in dired mode, displays the item in window of 
release.
+         If the drag start position is within a button, displays the button
+         referent in window of release.
+         See @code{hmouse-drag-item-mode-forms} for how to allow for draggable
+         items in other modes.
+     (2) Otherwise, creates a new link button at the drag start location,
+         linked to the drag end location.  Action Key creates an explicit 
button;
+         Assist Key creates an implicit button.
+
+         In Hyperbole versions prior to 9, Assist Key drags between windows 
would
+         swap buffers.  In version 9 and above, start or end the between window
+         drag on a modeline to get this same behavior.
+@end group
+@end format
+
+@node Smart Mouse Drags within a Window, Smart Mouse Drags outside a Window, 
Smart Mouse Drags between Windows, Smart Mouse Keys
+@subsection Smart Mouse Drags between Windows
+
+@cindex active region
+@cindex copy and yank
+@cindex kill and yank
+@cindex yanking
+@cindex pasting a region
+@format
+@group
+If an active (highlighted) region exists within the editor:
+  ACTION KEY
+     Copies and yanks (pastes) the region to the release point in a
+     different window.
+  ASSIST KEY
+     Kills (cuts) and yanks (pastes) the region to the release point
+     in a different window.
+@end group
+@end format
+
 @format
 @group
 Otherwise, if dragged from inside one window to another:
@@ -9564,7 +9593,6 @@ If dragged from an Emacs window to outside of Emacs:
 * Smart Key - Bookmark Mode::
 * Smart Key - Pages Directory Mode::
 * Smart Key - Python Source Code::
-* Smart Key - Identifier Menu Mode ::
 * Smart Key - C Source Code::
 * Smart Key - C++ Source Code::
 * Smart Key - Assembly Source Code::
@@ -9573,6 +9601,7 @@ If dragged from an Emacs window to outside of Emacs:
 * Smart Key - JavaScript Source Code::
 * Smart Key - Objective-C Source Code::
 * Smart Key - Fortran Source Code::
+* Smart Key - Identifier Menu Mode ::
 * Smart Key - Occurrence Matches::
 * Smart Key - Calendar Mode::
 * Smart Key - Man Page Apropos::
@@ -10172,7 +10201,7 @@ When pressed on a pages-directory-mode entry line:
 @end group
 @end format
 
-@node Smart Key - Python Source Code, Smart Key - Identifier Menu Mode , Smart 
Key - Pages Directory Mode, Smart Keyboard Keys
+@node Smart Key - Python Source Code, Smart Key - C Source Code, Smart Key - 
Pages Directory Mode, Smart Keyboard Keys
 @subsection Smart Key - Python Source Code
 @format
 @group
@@ -10201,29 +10230,8 @@ When pressed within a Python source code file (without 
the OO-Browser):
 @end group
 @end format
 
-@node Smart Key - Identifier Menu Mode , Smart Key - C Source Code, Smart Key 
- Python Source Code, Smart Keyboard Keys
-@subsection Smart Key - Identifier Menu Mode 
-
-@format
-@group
-This works only for identifiers defined within the same source file in
-which they are referenced.  It requires either Emacs' imenu library
-and it requires that an index of identifiers has been built for the
-current buffer.  Other handlers handle identifier references and
-definitions across multiple files.
-
-@noindent
-When pressed on an identifier name after an identifier index has been 
generated:
-  ACTION KEY
-     Jumps to the source definition within the current buffer of the 
identifier at point.
-  ASSIST KEY
-     Prompts with completion for an identifier defined within the buffer and 
then jumps
-     to the its source definition.
-@end group
-@end format
-
 @page
-@node Smart Key - C Source Code, Smart Key - C++ Source Code, Smart Key - 
Identifier Menu Mode , Smart Keyboard Keys
+@node Smart Key - C Source Code, Smart Key - C++ Source Code, Smart Key - 
Python Source Code, Smart Keyboard Keys
 @subsection Smart Key - C Source Code
 
 @vindex smart-c-cpp-include-path
@@ -10455,7 +10463,7 @@ OO-Browser):
 @end group
 @end format
 
-@node Smart Key - Fortran Source Code, Smart Key - Occurrence Matches, Smart 
Key - Objective-C Source Code, Smart Keyboard Keys
+@node Smart Key - Fortran Source Code, Smart Key - Identifier Menu Mode , 
Smart Key - Objective-C Source Code, Smart Keyboard Keys
 @subsection Smart Key - Fortran Source Code
 
 @format
@@ -10469,7 +10477,28 @@ When pressed within a Fortran source code file:
 @end group
 @end format
 
-@node Smart Key - Occurrence Matches, Smart Key - Calendar Mode, Smart Key - 
Fortran Source Code, Smart Keyboard Keys
+@node Smart Key - Identifier Menu Mode , Smart Key - Occurrence Matches, Smart 
Key - Fortran Source Code, Smart Keyboard Keys
+@subsection Smart Key - Identifier Menu Mode 
+
+@format
+@group
+This works only for identifiers defined within the same source file in
+which they are referenced.  It requires either Emacs' imenu library
+and it requires that an index of identifiers has been built for the
+current buffer.  Other handlers handle identifier references and
+definitions across multiple files.
+
+@noindent
+When pressed on an identifier name after an identifier index has been 
generated:
+  ACTION KEY
+     Jumps to the source definition within the current buffer of the 
identifier at point.
+  ASSIST KEY
+     Prompts with completion for an identifier defined within the buffer and 
then jumps
+     to the its source definition.
+@end group
+@end format
+
+@node Smart Key - Occurrence Matches, Smart Key - Calendar Mode, Smart Key - 
Identifier Menu Mode , Smart Keyboard Keys
 @subsection Smart Key - Occurrence Matches
 
 @format
diff --git a/man/version.texi b/man/version.texi
index c47df44a0a..83a9274080 100644
--- a/man/version.texi
+++ b/man/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED May, 2023
-@set UPDATED-MONTH May 2023
+@set UPDATED June, 2023
+@set UPDATED-MONTH June 2023
 @set EDITION 8.0.1pre
 @set VERSION 8.0.1pre
diff --git a/test/hbut-tests.el b/test/hbut-tests.el
index c8900de5f5..4a36f097dc 100644
--- a/test/hbut-tests.el
+++ b/test/hbut-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <matsl@gnu.org>
 ;;
 ;; Orig-Date:    30-may-21 at 09:33:00
-;; Last-Mod:     30-Apr-23 at 11:04:33 by Mats Lidell
+;; Last-Mod:     11-Jun-23 at 11:29:30 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -23,9 +23,10 @@
 (require 'hactypes)
 (require 'hpath)
 (require 'el-mock)
+(require 'hy-test-helpers "test/hy-test-helpers")
 
 (defun hbut-tests:should-match-tmp-folder (tmp)
-  "Check that TMP matches either a list of a single element of \"/tmp\" or 
\"private/tmp\".
+  "Check that TMP matches either of \"/tmp\" or \"private/tmp\".
 Needed since hyperbole expands all links to absolute paths and
 /tmp can be a symbolic link."
   (should (member tmp '(("/tmp") ("./tmp") ("/private/tmp")))))
@@ -190,6 +191,148 @@ Needed since hyperbole expands all links to absolute 
paths and
       (should-not (ebut:at-p))
       (should (string= button (buffer-string))))))
 
+(ert-deftest hbut-tests-ibut-program-link-to-directory ()
+  "Programmatically create ibut link-to-directory."
+  (with-temp-buffer
+    (ibut:program "label" 'link-to-directory "/tmp")
+    (should (string= "<[label]> - \"/tmp\"" (buffer-string)))))
+
+(ert-deftest hbut-tests-ibut-program-link-to-file ()
+  "Programatically create ibut link to file."
+  (let ((test-file (make-temp-file "ibut" nil ".txt")))
+    (unwind-protect
+        (with-temp-buffer
+          (ibut:program "label" 'link-to-file test-file)
+          (should (string=
+                   (concat "<[label]> - \"" test-file "\"")
+                   (buffer-string))))
+      (delete-file test-file))))
+
+(ert-deftest hbut-tests-ibut-insert-text-link-to-dir ()
+  "Insert link to dir."
+  (with-temp-buffer
+    (ibut:program "label" 'link-to-directory "/tmp")
+    (should (string= "<[label]> - \"/tmp\"" (buffer-string)))
+    (goto-char 3)
+    (let ((but (ibut:at-p)))
+      (with-temp-buffer
+        (ibut:insert-text but)
+       ;; Allow for /tmp being a link to /private/tmp on Macos
+        (should (string-match "\"\\(/private\\)?/tmp\"" (buffer-string)))))))
+
+(ert-deftest hbut-tests-ibut-insert-annot-bib ()
+  "Insert ibut to annot-bib, which must be attached to a file."
+  (let ((annot-bib-file (make-temp-file "annot-bib" nil ".txt"))
+       annot-bib-buf
+       but)
+    (unwind-protect
+        (progn
+         ;; Test with name
+          (setq annot-bib-buf (find-file annot-bib-file))
+         (ibut:program "label" 'annot-bib "arg")
+         (save-buffer)
+         (should (string-match (concat (regexp-quote "<[label]> - [arg]")
+                                       "\\s-*")
+                               (buffer-string)))
+         ;; Test without name
+         (erase-buffer)
+         (ibut:program nil 'annot-bib "arg")
+         (save-buffer)
+         (should (string-match (concat (regexp-quote "[arg]")
+                                       "\\s-*")
+                               (buffer-string))))
+      (kill-buffer annot-bib-buf)
+      (hy-test-helpers:kill-buffer annot-bib-file))))
+
+(ert-deftest hbut-tests-ibut-insert-kbd-key ()
+  "Insert ibut to kbd-key."
+  (with-temp-buffer
+    (ibut:program "label" 'kbd-key "{ C-h h }")
+    (should (string= "<[label]> - { C-h h }" (buffer-string)))
+    (goto-char 3)
+    (let ((but (ibut:at-p)))
+      (with-temp-buffer
+        (ibut:insert-text but)
+        (should (string= "" (buffer-string)))))))
+
+(ert-deftest hbut-tests-ibut-insert-text-temp-buffer ()
+  "Insert ibut text using an ibut in a temp buffer as source."
+  (dolist (bd
+           ;; Test data is in the format:
+           ;;  - action-type implicit-button-text resulting-button-text
+           ;; The third parameter is optional and if missing the
+           ;; implicit-button-text is used as the result as
+           ;; well. i.e. Works when the input string is preserved.
+           '(
+             ('actypes::kbd-key "{C-h h}")
+             ; ('actypes::annotate-bib "[FSF 12]") ;; Requires a file!?
+             ; ('actypes::exec-shell-cmd "!/bin/bash") ;; Not identified as an 
ibut
+             ; ('actypes::exec-window-cmd "&/bin/bash") ;; Not identified as 
an ibut
+             ('actypes::link-to-gbut "<glink:arg1>")
+             ('actypes::link-to-ebut "<elink:arg1>")
+             ('actypes::link-to-ebut "<elink:arg1:arg2>" "<elink:arg1: arg2>")
+             ('actypes::link-to-ibut "<ilink:arg1>")
+             ('actypes::link-to-ibut "<ilink:arg1:arg2>" "<ilink:arg1: arg2>")
+             ('actypes::link-to-kcell "<@ 3b=06>" "<nil \"@ 3b=06\" 13>")
+
+             ;; Verified manually. Produces nil when run by ert!?
+             ; ('actypes::link-to-kcell "<EXAMPLE.kotl, 4=012>" "<nil 
EXAMPLE.kotl, 4=012 13>")
+
+             ; ('actypes::link-to-org-id "id:arg1") ;; Can links to org id be 
created using text only?
+             ('actypes::link-to-rfc "rfc123")
+             ; ('actypes::man-show "rm(1)      - remove")
+             ('actypes::link-to-file-line "/etc/passwd:10" 
"\"/etc/passwd:10\"")
+             ('actypes::link-to-file "/etc/passwd" "\"/etc/passwd\"")))
+    (with-temp-buffer
+      (insert (format "<[label]> - %s" (cadr bd)))
+      (goto-char 3)
+      (let ((but (ibut:at-p))
+            (match (or (caddr bd) (cadr bd))))
+        (with-temp-buffer
+          (ibut:insert-text but)
+          (should (string= match (buffer-string))))))))
+
+(ert-deftest hbut-tests-ibut-insert-text-temp-file ()
+  "Insert ibut text using an ibut in a temp file as source."
+  (dolist (bd
+           ;; Test data is in the format:
+           ;;  - action-type implicit-button-text resulting-button-text
+           ;; The third parameter is optional and if missing the
+           ;; implicit-button-text is used as the result as
+           ;; well. i.e. Work when the input string is preserved.
+           '(
+             ('actypes::kbd-key "{C-h h}")
+             ('actypes::annotate-bib "[FSF 12]") ;; Requires a file!
+             ; ('actypes::exec-shell-cmd "!/bin/bash") ;; Not identified as an 
ibut
+             ; ('actypes::exec-window-cmd "&/bin/bash") ;; Not identified as 
an ibut
+             ('actypes::link-to-gbut "<glink:arg1>")
+             ('actypes::link-to-ebut "<elink:arg1>")
+             ('actypes::link-to-ebut "<elink:arg1:arg2>" "<elink:arg1: arg2>")
+             ('actypes::link-to-ibut "<ilink:arg1>")
+             ('actypes::link-to-ibut "<ilink:arg1:arg2>" "<ilink:arg1: arg2>")
+             ('actypes::link-to-kcell "<@ 3b=06>" "<nil \"@ 3b=06\" 13>")
+
+             ;; Verified manually. Produces nil when run by ert!?
+             ; ('actypes::link-to-kcell "<EXAMPLE.kotl, 4=012>" "<nil 
EXAMPLE.kotl, 4=012 13>")
+
+             ; ('actypes::link-to-org-id "id:arg1") ;; Can links to org id be 
created using text only?
+             ('actypes::link-to-rfc "rfc123")
+             ; ('actypes::man-show "rm(1)      - remove")
+             ('actypes::link-to-file-line "/etc/passwd:10" 
"\"/etc/passwd:10\"")
+             ('actypes::link-to-file "/etc/passwd" "\"/etc/passwd\"")))
+    (let ((file (make-temp-file "hypb" nil ".txt"
+                                (format "<[label]> - %s" (cadr bd)))))
+      (unwind-protect
+          (progn
+            (find-file file)
+            (goto-char 3)
+            (let ((but (ibut:at-p))
+                  (match (or (caddr bd) (cadr bd))))
+              (with-temp-buffer
+                (ibut:insert-text but)
+                (should (string= match (buffer-string))))))
+        (delete-file file)))))
+
 ;; This file can't be byte-compiled without the `el-mock' package (because of
 ;; the use of the `with-mock' macro), which is not a dependency of Hyperbole.
 ;;  Local Variables:



reply via email to

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