branch: externals/hyperbole
commit 8a8367189c10598d81b57908887aa5925e0cfc38
Merge: d4aaee59fe 0c019d9b8f
Author: Robert Weiner <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #550 from rswgnu/rsw
hynote.el - Add initial HyNote link support for Org and Org Roam
---
ChangeLog | 47 ++++++++++++---
MANIFEST | 11 ++--
Makefile | 10 +--
hbut.el | 11 +++-
hibtypes.el | 8 ++-
hmouse-drv.el | 10 ++-
hui-em-but.el => hproperty.el | 80 ++++++++++++++++++++++--
hsettings.el | 8 +--
hsys-org.el | 44 +++++---------
hynote.el | 137 ++++++++++++++++++++++++++++++++++++++++++
hypb.el | 6 ++
hywiki.el | 55 +++--------------
test/hsys-org-tests.el | 5 +-
test/hui-tests.el | 6 +-
14 files changed, 319 insertions(+), 119 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c8f6c08d40..77a0d444e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,42 @@
+2024-06-29 Bob Weiner <[email protected]>
+
+* test/hui-tests.el (hui-ebut-create-link-to-info-index-using-completion):
+ When finished, kill all *info*<#> buffers.
+
+* hui-em-but.el: Rename to "hproperty.el".
+
+* hui-em-but.el (hproperty:char-property-start, hproperty:char-property-end,
+ hproperty:char-property-range, hproperty:overlay-range)
+ hproperty:char-property-contains-p):
+ Add char-property and overlay utility functions and use in "hsys-org.el"
+ and "hsys-org-tests.el"; adds compatibility with Org mode 9.7 and earlier.
+
+2024-06-25 Bob Weiner <[email protected]>
+
+* hibtypes.el (hynote): Add for Org and Org Roam links by name.
+ MANIFEST (hynote.el): Add.
+ Makefile (EL_COMPILE): Add hynote.el.
+
+* hynote.el (hynote-directory-list, hynote-find-file-stem): Add.
+
+* hbut.el (ibut:create): Add debugging to show the type name if an ibtype
+ evaluation fails.
+ hmouse-drv.el (hkey-execute, hkey-help): Change 'eval' to 'hypb:eval-debug'
+ to show a backtrace whenever an error occurs.
+
2024-06-23 Bob Weiner <[email protected]>
-* Makefile: (dockerized-run): Add to intweractively run dockerized versions
- of Emacs with Hyperbole. Update Commentary to summarize dockerized
+* hynote.el (hynote-get-files, hynote-get-file-stem-list, hynote-find-file,
+ hynote-file-stem-start-end-at):
+ Add these functions to find non-HyWikiWord files in `hywiki-directory' when
+ referenced by stem name, e.g. Action key on Non-Wiki-Word displays
+ Non-Wiki-Word.org.
+ (hynote-file): Add ibtype to display non-HyWikiWord files in
+ hywiki-directory'.
+
+
+* Makefile: (docker-run): Add to intweractively run docker versions
+ of Emacs with Hyperbole. Update Commentary to summarize docker
targets that build, byte-compile and run Hyperbole.
2024-06-22 Mats Lidell <[email protected]>
@@ -12,7 +47,7 @@
* Makefile (dockerized-update): Target to update (pull) the Emacs docker
image.
- (dockerized): Copy source to docker so not local workspace is affected
+ (dockererized): Copy source to docker so not local workspace is affected
when running targets in the docker environment.
2024-06-22 Bob Weiner <[email protected]>
@@ -31,12 +66,6 @@
* hywiki.el (hywiki-word-at): Fix to use
'hywiki-word-with-optional-section-regexp'
instead of 'hywiki-word-regexp' so handles sections properly.
(hywiki-word-highlight-flag): Improve documentation.
- (hywiki-get-files, hywiki-get-file-stem-list, hywiki-find-file):
- Add these functions to find non-HyWikiWord files in `hywiki-directory' when
- referenced by stem name, e.g. Action key on Non-Wiki-Word displays
- Non-Wiki-Word.org.
- (hywiki-file): Add ibtype to display non-HyWikiWord files in
- hywiki-directory'.
(hywiki-get-page-file): Allow name to include 'hywiki-file-suffix'
for non-HyWikiWord files. Also, rename to 'hywiki-get-file'.
diff --git a/MANIFEST b/MANIFEST
index f2ded012f9..99d3a9ed0c 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -36,10 +36,8 @@ hmouse-key.el - Setup Smart Key mouse bindings
hmouse-mod.el - Action Key acts as CONTROL modifier and Assist Key as
META modifier (Unused)
hmouse-sh.el - System-dependent Smart Mouse Key bindings
hmouse-tag.el - Smart Key support of programming language tags location
-hycontrol.el - Interactive sizing, moving, replicating and deleting of
windows and frames
-hyrolo-menu.el - Pulldown and popup menus of HyRolo commands
+hproperty.el - GNU Emacs button highlighting and flashing support
hui-dired-sidebar.el - Smart Key support for dired sidebar
-hui-em-but.el - GNU Emacs button highlighting and flashing support
hui-jmenu.el - Popup menus for jumping to and managing buffers,
frames, and windows
hui-menu.el - Menubar menu of GNU Hyperbole commands
hui-mini.el - Single line command menus for GNU Hyperbole
@@ -48,6 +46,8 @@ hui-select.el - Select delimited or larger and larger
syntax-driven regio
hui-treemacs.el - GNU Hyperbole Smart Key support for the Treemacs file
manager package
hui-window.el - Smart Mouse Key window and modeline depress/release
actions
hui.el - GNU Hyperbole button and hyperlink user interface
+hycontrol.el - Interactive sizing, moving, replicating and deleting of
windows and frames
+hyrolo-menu.el - Pulldown and popup menus of HyRolo commands
* --- APPLICATION PROGRAMMING INTERFACE ---
hact.el - GNU Hyperbole button action handling
@@ -78,9 +78,10 @@ hyrolo.el - Hierarchical, multi-file, easy-to-use
record management s
hyrolo.py - Output file header and matching entries from HyRolo
files via the command-line
hyrolo-logic.el - Logic functions for GNU Hyperbole Rolo files
-* --- HYPERBOLE WIKI ---
-hywiki.el - Hyperbole's auto-wikiword note-taking system
+* --- HYPERBOLE NOTES AND WIKI ---
hasht.el - Create hash tables from lists and operate on them.
+hynote.el - Link to Org and Org Roam notes by name
+hywiki.el - Hyperbole's auto-wikiword note-taking system
* --- USENET NEWS SUPPORT ---
hgnus.el - GNU Hyperbole buttons in news reader/poster: GNUS
diff --git a/Makefile b/Makefile
index 7cc0b848a1..fc840442c6 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
# Author: Bob Weiner
#
# Orig-Date: 15-Jun-94 at 03:42:38
-# Last-Mod: 23-Jun-24 at 00:16:22 by Bob Weiner
+# Last-Mod: 29-Jun-24 at 18:59:38 by Bob Weiner
#
# Copyright (C) 1994-2023 Free Software Foundation, Inc.
# See the file HY-COPY for license information.
@@ -195,12 +195,12 @@ EL_COMPILE = hact.el hactypes.el hargs.el hbdata.el
hbmap.el hbut.el \
hib-social.el hibtypes.el \
hinit.el hload-path.el hmail.el hmh.el hmoccur.el hmouse-info.el \
hmouse-drv.el hmouse-key.el hmouse-mod.el hmouse-sh.el
hmouse-tag.el \
- hpath.el hrmail.el hsettings.el hsmail.el hsys-flymake.el
hsys-org.el \
- hsys-org-roam.el hsys-www.el hsys-xref.el hsys-youtube.el htz.el \
+ hpath.el hproperty.el hrmail.el hsettings.el hsmail.el
hsys-flymake.el \
+ hsys-org.el hsys-org-roam.el hsys-www.el hsys-xref.el
hsys-youtube.el htz.el \
hycontrol.el hui-jmenu.el hui-menu.el hui-mini.el hui-mouse.el
hui-select.el \
- hui-treemacs.el hui-window.el hui.el hvar.el hversion.el hypb.el
hyperbole.el \
+ hui-treemacs.el hui-window.el hui.el hvar.el hversion.el hynote.el
hypb.el hyperbole.el \
hyrolo-demo.el hyrolo-logic.el hyrolo-menu.el hyrolo.el
hywconfig.el hywiki.el \
- hasht.el set.el hypb-ert.el hui-dired-sidebar.el
hypb-maintenance.el hui-em-but.el \
+ hasht.el set.el hypb-ert.el hui-dired-sidebar.el
hypb-maintenance.el \
hui-register.el
EL_SRC = $(EL_COMPILE)
diff --git a/hbut.el b/hbut.el
index 501d92a11d..958db847ee 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: 23-Jun-24 at 00:11:37 by Mats Lidell
+;; Last-Mod: 25-Jun-24 at 01:03:43 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1957,7 +1957,14 @@ If a new button is created, store its attributes in the
symbol,
(setq ibtype-point (point))
(while (and (not is-type) types)
(setq itype (car types))
- (when (and itype (setq args (funcall itype)))
+ (when (condition-case ()
+ (and itype (setq args (funcall itype)))
+ ;; Purposely trigger another error
+ ;; here by sending a symbol
+ ;; argument to the message call
+ ;; below so can see the value of
+ ;; itype whose funcall failed above.
+ (error (message itype)))
(setq is-type itype)
;; Any implicit button type check should leave
point
;; unchanged. Trigger an error if not.
diff --git a/hibtypes.el b/hibtypes.el
index ed2156f614..c4b11e4467 100644
--- a/hibtypes.el
+++ b/hibtypes.el
@@ -91,7 +91,13 @@
;; ibtype priorities.
;;; ========================================================================
-;;; Creates and display personal wiki pages with auto-wikiword links
+;;; Displays Org and Org Roam files and sections by name link
+;;; ========================================================================
+
+(load "hynote")
+
+;;; ========================================================================
+;;; Creates and displays personal wiki pages and sections with auto-wikiword
links
;;; ========================================================================
(load "hywiki")
diff --git a/hmouse-drv.el b/hmouse-drv.el
index 59b2b43f4a..c748fced8b 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 04-Feb-90
-;; Last-Mod: 8-Mar-24 at 11:06:21 by Mats Lidell
+;; Last-Mod: 25-Jun-24 at 02:13:58 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1029,7 +1029,7 @@ predicate is found."
(while (and (null pred-value) (setq hkey-form (car hkey-forms)))
(if (setq hkey-action (if assisting (cddr hkey-form) (cadr hkey-form))
pred (car hkey-form)
- pred-value (eval pred))
+ pred-value (hypb:eval-debug pred))
(progn
;; Any Smart Key predicate should leave point unchanged.
;; Trigger an error if not.
@@ -1041,9 +1041,7 @@ predicate is found."
(when hkey-debug
(hkey-debug pred pred-value hkey-action))
(if hkey-debug
- (let ((debug-on-error t)
- (debug-on-quit t))
- (eval hkey-action))
+ (hypb:eval-debug hkey-action)
(eval hkey-action)))
(setq hkey-forms (cdr hkey-forms))))
pred-value))
@@ -1062,7 +1060,7 @@ documentation is found."
(assist-flag assisting)
hkey-form pred-value call calls cmd-sym doc)
(while (and (null pred-value) (setq hkey-form (car hkey-forms)))
- (or (setq pred-value (eval (car hkey-form)))
+ (or (setq pred-value (hypb:eval-debug (car hkey-form)))
(setq hkey-forms (cdr hkey-forms))))
(if pred-value
(setq call (if assisting (cdr (cdr hkey-form))
diff --git a/hui-em-but.el b/hproperty.el
similarity index 80%
rename from hui-em-but.el
rename to hproperty.el
index 7bce522728..2a34918c23 100644
--- a/hui-em-but.el
+++ b/hproperty.el
@@ -1,9 +1,9 @@
-;;; hui-em-but.el --- GNU Emacs button highlighting and flashing support -*-
lexical-binding: t; -*-
+;;; hproperty.el --- GNU Emacs button highlighting and flashing support -*-
lexical-binding: t; -*-
;;
;; Author: Bob Weiner
;;
;; Orig-Date: 21-Aug-92
-;; Last-Mod: 26-May-24 at 17:24:25 by Bob Weiner
+;; Last-Mod: 29-Jun-24 at 18:57:42 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -261,6 +261,78 @@ See `hproperty:but-get'."
(add-to-list 'yank-handled-properties '(hproperty:but-face .
hproperty:but-create-on-yank))
+;;; char-property and overlay utility functions
+
+(defun hproperty:char-property-contains-p (pos property value)
+ "At POS if PROPERTY contains VALUE (a symbol), return VALUE, else nil."
+ (let ((val (get-char-property pos property)))
+ (when (or (eq val value)
+ ;; `val' may be a list of property values
+ (and (listp val) (memq value val)))
+ value)))
+
+(defun hproperty:char-property-start (pos property value)
+ "From POS, return the start of text PROPERTY with VALUE overlapping POS.
+Otherwise, return nil. Value must be a symbol."
+ (when-let ((val (hproperty:char-property-contains-p pos property value))
+ (prev pos))
+ ;; Can't use `previous-single-char-property-change' below
+ ;; because it checks for any change in the property value, not
+ ;; just if the property contains the value desired.
+ (while (and (setq prev (1- prev))
+ (>= prev (point-min))
+ (hproperty:char-property-contains-p prev property value)))
+ (max (1+ prev) (point-min))))
+
+(defun hproperty:char-property-end (pos property value)
+ "From POS, return the end of text PROPERTY with VALUE overlapping POS.
+Otherwise, return nil. Value must be a symbol."
+ (when-let ((val (hproperty:char-property-contains-p pos property value))
+ (next pos))
+ ;; Can't use `next-single-char-property-change' below
+ ;; because it checks for any change in the property value, not
+ ;; just if the property contains the value desired.
+ (while (and (setq next (1+ next))
+ (<= next (point-max))
+ (hproperty:char-property-contains-p next property value)))
+ (min next (point-max))))
+
+(defun hproperty:char-property-range (pos property &optional value)
+ "Return a char-property range (start . end) at POS where PROPERTY = VALUE.
+Return nil if no such range. If POS is nil, use point.
+VALUE is optional; if omitted, use the first char-property at POS with
PROPERTY."
+ (unless pos (setq pos (point)))
+ (let ((start pos)
+ (end pos)
+ val)
+ (when (or (null value)
+ (eq value (setq val (hproperty:char-property-contains-p pos
property value))))
+ (setq start (hproperty:char-property-start pos property val)
+ end (hproperty:char-property-end pos property val)))
+ (unless (or (null start) (null end) (= start end))
+ (cons start end))))
+
+(defun hproperty:overlay-range (pos property &optional value)
+ "Return the first overlay range (start . end) at POS where PROPERTY = VALUE.
+Return nil if no such overlay range. If POS is nil, use point.
+VALUE is optional; if omitted, use the first overlay at POS with PROPERTY.
+
+Use `hproperty:char-property-range' for the same capability but for
+both text-properties and overlays."
+ (unless pos (setq pos (point)))
+ (let ((start pos)
+ (end pos)
+ val)
+ (catch 'end
+ (dolist (overlay (overlays-at pos t))
+ (when (and (setq val (overlay-get overlay property))
+ (or (null value) (eq val value)))
+ (setq start (overlay-start overlay)
+ end (overlay-end overlay))
+ (throw 'end nil))))
+ (unless (= start end)
+ (cons start end))))
+
;;; ************************************************************************
;;; Private functions
;;; ************************************************************************
@@ -375,6 +447,6 @@ hproperty:color-ptr."
"Button used to highlight an item in a listing buffer.")
(make-variable-buffer-local 'hproperty:item-button)
-(provide 'hui-em-but)
+(provide 'hproperty)
-;;; hui-em-but.el ends here
+;;; hproperty.el ends here
diff --git a/hsettings.el b/hsettings.el
index 7e1994fdaa..cac10afe16 100644
--- a/hsettings.el
+++ b/hsettings.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 15-Apr-91 at 00:48:49
-;; Last-Mod: 13-Apr-24 at 11:22:31 by Bob Weiner
+;; Last-Mod: 29-Jun-24 at 18:57:18 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -38,8 +38,8 @@
(defvar helm-allow-mouse)
(defvar htz:local) ; "htz.el"
-(declare-function hproperty:but-create "hui-em-but")
-(declare-function hproperty:but-flash "hui-em-but")
+(declare-function hproperty:but-create "hproperty")
+(declare-function hproperty:but-flash "hproperty")
(declare-function hyperbole-minibuffer-menu "hui-mini")
(declare-function hyperbole-menubar-menu "hui-menu")
@@ -298,7 +298,7 @@ then runs the search."
"Button flash No-op.")
(cond ((not noninteractive)
- (require 'hui-em-but)
+ (require 'hproperty)
;; Highlight explicit buttons whenever a file is read in.
(add-hook 'find-file-hook #'hproperty:but-create t)
(defalias 'hui:but-flash #'hproperty:but-flash)))
diff --git a/hsys-org.el b/hsys-org.el
index 11dbde4471..259aa93760 100644
--- a/hsys-org.el
+++ b/hsys-org.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 2-Jul-16 at 14:54:14
-;; Last-Mod: 22-Jun-24 at 23:43:08 by Mats Lidell
+;; Last-Mod: 29-Jun-24 at 18:55:30 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -31,7 +31,7 @@
;;; ************************************************************************
(eval-when-compile (require 'hmouse-drv))
-(require 'hbut)
+(require 'hproperty) ;; requires 'hbut
(require 'org)
(require 'org-element)
(require 'org-fold nil t)
@@ -368,21 +368,6 @@ Match to all todos if `keyword' is nil or the empty
string."
(org-occur (concat "^" org-outline-regexp " *" (regexp-quote
keyword)))
keyword))
-(defun hsys-org-region-with-text-property-value (pos property)
- "Return region around POS that shares its text PROPERTY value, else nil.
-Return the (start . end) buffer positions of the region."
- (when (null pos) (setq pos (point)))
- (let ((property-value (get-text-property pos property))
- (start-point pos))
- (when property-value
- ;; Can't use previous-single-property-change here because it
- ;; ignores characters that lack the property, i.e. have nil values.
- (if (bobp)
- (setq start-point (point-min))
- (while (equal (get-text-property (1- start-point) property)
property-value)
- (setq start-point (1- start-point))))
- (cons start-point (next-single-property-change start-point property)))))
-
(defun hsys-org-agenda-item-at-p ()
"Return non-nil if point is on an Org Agenda view item line, else nil."
(and (apply #'derived-mode-p '(org-agenda-mode))
@@ -453,7 +438,7 @@ Assume caller has already checked that the current buffer
is in `org-mode'."
Link region is (start . end) and includes delimiters, else nil."
(and (hsys-org-face-at-p 'org-link)
(equal (get-text-property (point) 'help-echo) "Radio target link")
- (hsys-org-region-with-text-property-value (point) 'face)))
+ (hproperty:char-property-range (point) 'face 'org-link)))
(defun hsys-org-radio-target-def-at-p ()
"Return target region iff point is on a <<<radio target>>> definition.
@@ -461,18 +446,19 @@ Target region is (start . end) and includes any
delimiters, else nil."
(when (hsys-org-target-at-p)
(save-excursion
(unless (looking-at org-radio-target-regexp)
- (goto-char (or (previous-single-property-change (point) 'face)
(point-min))))
+ (goto-char (or (hproperty:char-property-start (point) 'face 'org-target)
+ (point-min))))
(when (looking-at "<<<")
(goto-char (match-end 0)))
(and (hsys-org-face-at-p 'org-target)
- (hsys-org-region-with-text-property-value (point) 'face)))))
+ (hproperty:char-property-range (point) 'face 'org-target)))))
(defun hsys-org-radio-target-at-p ()
"Return region iff point is on a <<<radio target>>> or a link to one.
The region is (start . end) and includes any delimiters, else nil."
(and (or (hsys-org-radio-target-def-at-p)
(hsys-org-radio-target-link-at-p))
- (hsys-org-region-with-text-property-value (point) 'face)))
+ (hproperty:char-property-range (point) 'face 'org-target)))
(defun hsys-org-internal-target-link-at-p ()
"Return link text region iff point is on an Org mode internal target link.
@@ -480,7 +466,7 @@ Link region is (start . end) and includes delimiters, else
nil."
(and (hsys-org-face-at-p 'org-link)
(not (equal (get-text-property (point) 'help-echo) "Radio target link"))
(hsys-org-link-at-p)
- (hsys-org-region-with-text-property-value (point) 'face)))
+ (hproperty:char-property-range (point) 'face 'org-link)))
(defun hsys-org-internal-target-def-at-p ()
"Return target region iff point is on <<internal target>> definition.
@@ -488,26 +474,24 @@ Target region is (start . end) and includes any
delimiters, else nil."
(when (hsys-org-target-at-p)
(save-excursion
(unless (looking-at org-target-regexp)
- (goto-char (or (previous-single-property-change (point) 'face)
(point-min))))
+ (goto-char (or (hproperty:char-property-start (point) 'face 'org-target)
+ (point-min))))
(when (looking-at "<<")
(goto-char (match-end 0)))
(and (hsys-org-face-at-p 'org-target)
- (hsys-org-region-with-text-property-value (point) 'face)))))
+ (hproperty:char-property-range (point) 'face 'org-target)))))
(defun hsys-org-internal-target-at-p ()
- "Return region iff point is on an <<internal target>> or a link to one.
+ "Return target region iff point is on an <<internal target>> or a link to
one.
The region is (start . end) and includes any delimiters, else nil."
(and (or (hsys-org-internal-target-def-at-p)
(hsys-org-internal-target-link-at-p))
- (hsys-org-region-with-text-property-value (point) 'face)))
+ (hproperty:char-property-range (point) 'face 'org-target)))
(defun hsys-org-face-at-p (org-face-type)
"Return ORG-FACE-TYPE iff point is on a character with that face, else nil.
ORG-FACE-TYPE must be a symbol, not a symbol name."
- (let ((face-prop (get-text-property (point) 'face)))
- (when (or (eq face-prop org-face-type)
- (and (listp face-prop) (memq org-face-type face-prop)))
- org-face-type)))
+ (hproperty:char-property-contains-p (point) 'face org-face-type))
;; Adapted from Org code
(defun hsys-org-search-internal-link-p (target)
diff --git a/hynote.el b/hynote.el
new file mode 100644
index 0000000000..8f16206fd5
--- /dev/null
+++ b/hynote.el
@@ -0,0 +1,137 @@
+;;; hynote.el --- Link to Org and Org Roam notes by name -*-
lexical-binding: t; -*-
+;;
+;; Author: Bob Weiner
+;;
+;; Orig-Date: 23-Jun-24 at 12:50:37
+;; Last-Mod: 25-Jun-24 at 02:39:05 by Bob Weiner
+;;
+;; SPDX-License-Identifier: GPL-3.0-or-later
+;;
+;; Copyright (C) 2024 Free Software Foundation, Inc.
+;; See the "HY-COPY" file for license information.
+;;
+;; This file is part of GNU Hyperbole.
+
+;;; Commentary:
+;;
+;; This is Hyperbole's note taking system, HyNote. It utilizes the
+;; Org mode or the Koutliner file format plus UUIds and HyRolo for note
lookups.
+;;
+;; See all the autoloaded functions herein for interactive commands.
+;; See the Info manual entry "(hyperbole)HyNote" for usage information.
+
+;;; Code:
+;;; ************************************************************************
+;;; Other required Elisp libraries
+;;; ************************************************************************
+
+(require 'hyrolo)
+(require 'hywiki)
+
+;;; ************************************************************************
+;;; Public Implicit Button and Action Types
+;;; ************************************************************************
+
+(defun hynote-file-stem-start-end-at ()
+ "Return (file-stem start end) if on a `hynote-directory-list' file stem.
+Otherwise, return (nil nil nil)."
+ (or (hpath:delimited-possible-path nil t)
+ (list nil nil nil)))
+
+(defib hynote-file ()
+ "When on a HyNote file name stem, display the file and its optional section.
+This type is active only in buffers where `hywiki-active-in-current-buffer-p'
+is true. This may require that (hywiki-mode) has been enabled."
+ (when (hywiki-active-in-current-buffer-p)
+ (cl-destructuring-bind (file-stem-name start end)
+ (hynote-file-stem-start-end-at)
+ (when file-stem-name
+ (let ((file (hynote-get-file file-stem-name))
+ section)
+ (when (and file (file-readable-p file))
+ (setq section (when (string-match "#" file-stem-name)
+ (substring file-stem-name (match-beginning 0))))
+ (ibut:label-set file-stem-name start end)
+ (hact 'hynote-find-file file section)))))))
+
+(defun hynote-find-file (file &optional section)
+ "Display an existing FILE starting at SECTION.
+SECTION must be the name of a heading from the FILE and should begin
+with \"#\", though this function will add \"#\" if missing.
+
+Return the absolute path to any file successfully found, else nil.
+After successfully finding a file and reading it into a buffer, run
+`hynote-find-file-hook'."
+ (interactive (list (completing-read "Find HyNote file: "
+ (hynote-get-files))))
+ (when (and (stringp file) (file-readable-p file))
+ (when (and (stringp section) (not (string-prefix-p "#" section)))
+ (setq section (concat "#" section)))
+ (hpath:find (concat file section))
+ (hywiki-maybe-highlight-page-names)
+ (run-hooks 'hynote-find-file-hook)
+ file))
+
+(defun hynote-find-file-stem (file-stem-name)
+ "Display an existing FILE-STEM-NAME from `hynote-directory-list'.
+Return the absolute path to any file successfully found, else nil.
+
+After successfully finding a file and reading it into a buffer, run
+`hynote-find-file-hook'."
+ (interactive (list (completing-read "Find HyNote file: "
+ (hynote-get-file-stems))))
+ (when (stringp file-stem-name)
+ (let ((file (hynote-get-file file-stem-name))
+ section)
+ (when (file-readable-p file)
+ (setq section (when (string-match "#" file-stem-name)
+ (substring file-stem-name (match-beginning 0))))
+ (when file
+ (hpath:find (concat file section))
+ (hywiki-maybe-highlight-page-names)
+ (run-hooks 'hynote-find-file-hook)
+ file)))))
+
+;;; ************************************************************************
+;;; Public variables
+;;; ************************************************************************
+
+(defvar hynote-directory-list '("~/org/" "~/org-roam/")
+ "Directories in which to find HyNote Org files.")
+
+;;; ************************************************************************
+;;; Public functions
+;;; ************************************************************************
+
+(defun hynote-get-file (file-stem-name)
+ "Return existing file path in `hynote-directory-list' from FILE-STEM-NAME.
+File name must end with `hyrolo-file-suffix-regexp'. No
+validation of FILE-STEM-NAME is done."
+ ;; Remove any #section from `file-stem-name'
+ (setq file-stem-name (if (string-match "#" file-stem-name)
+ (substring file-stem-name 0 (match-beginning 0))
+ file-stem-name))
+ (locate-file file-stem-name hynote-directory-list
+ '(".org" ".md" ".kotl" ".kot")))
+
+(defun hynote-get-files ()
+ "Return `hynote-directory-list' files ending with
`hyrolo-file-suffix-regexp'.
+File names returned are relative to `hynote-directory-list'."
+ (mapcan
+ (lambda (dir)
+ (make-directory dir t)
+ (when (file-readable-p dir)
+ (directory-files dir nil (concat "^[^#]+" hyrolo-file-suffix-regexp))))
+ hynote-directory-list))
+
+(defun hynote-get-file-stems ()
+ "Return the list of existing HyWiki files sans their `hynote-file-suffixes'.
+This includes both Hynote page files and others. Stems returned are
+relative to `hynote-directory-list'."
+ (mapcar #'file-name-sans-extension (hynote-get-files)))
+
+;;; ************************************************************************
+;;; Private functions
+;;; ************************************************************************
+
+(provide 'hynote)
diff --git a/hypb.el b/hypb.el
index 34a67d26a9..d804b5e064 100644
--- a/hypb.el
+++ b/hypb.el
@@ -476,6 +476,12 @@ the `format' function."
(put 'error 'error-message msg)
(error msg)))
+(defun hypb:eval-debug (sexp)
+ "Eval SEXP and on error show a debug backtrace of the problem."
+ (let ((debug-on-error t)
+ (debug-on-quit t))
+ (eval sexp)))
+
(defun hypb:fgrep-git-log (string)
"List git log entries whose changesets include STRING for selection and
display.
Listing is asynchronous. A press of RET, the Action Key or the
diff --git a/hywiki.el b/hywiki.el
index 89ca51790c..d0fdda29fd 100644
--- a/hywiki.el
+++ b/hywiki.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 21-Apr-24 at 22:41:13
-;; Last-Mod: 23-Jun-24 at 00:12:37 by Mats Lidell
+;; Last-Mod: 29-Jun-24 at 18:56:47 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -105,7 +105,7 @@
(require 'hasht)
(require 'hpath)
(require 'hypb)
-(require 'hui-em-but)
+(require 'hproperty)
(require 'outline) ;; For `outline-mode-syntax-table'
(eval-and-compile
@@ -381,21 +381,6 @@ See the Info documentation at \"(hyperbole)HyWiki\".
;;; Public Implicit Button and Action Types
;;; ************************************************************************
-(defun hywiki-file-stem-start-end-at ()
- "Return (file-stem start-pos end-pos) if on a `hywiki-directory' file stem.
-Otherwise, return (nil nil nil)."
- (or (hpath:delimited-possible-path nil t)
- (list nil nil nil)))
-
-(defib hywiki-file ()
- "When on a HyWiki file name stem, display the file and its optional section."
- (cl-destructuring-bind (file-stem-name start end)
- (hywiki-file-stem-start-end-at)
- (when (and file-stem-name
- (file-readable-p (hywiki-get-file file-stem-name)))
- (ibut:label-set file-stem-name start end)
- (hact 'hywiki-find-file file-stem-name))))
-
(defib hywiki-word ()
"When on a HyWiki word, display its page and optional section."
(let ((page-name (hywiki-word-at)))
@@ -403,26 +388,6 @@ Otherwise, return (nil nil nil)."
(ibut:label-set page-name (match-beginning 0) (match-end 0))
(hact 'hywiki-find-page page-name))))
-(defun hywiki-find-file (file-stem-name)
- "Display an existing non-HyWikiWord FILE-STEM-NAME from `hywiki-directory'.
-Return the absolute path to any file successfully found, else nil.
-
-After successfully finding a file and reading it into a buffer, run
-`hywiki-find-file-hook'."
- (interactive (list (completing-read "Find HyWiki file: "
- (hywiki-get-file-stem-list))))
- (when (stringp file-stem-name)
- (let ((file (hywiki-get-file file-stem-name))
- section)
- (when (file-readable-p file)
- (setq section (when (string-match "#" file-stem-name)
- (substring file-stem-name (match-beginning 0))))
- (when file
- (hpath:find (concat file section))
- (hywiki-maybe-highlight-page-names)
- (run-hooks 'hywiki-find-file-hook)
- file)))))
-
(defun hywiki-find-page (&optional page-name prompt-flag)
"Display HyWiki PAGE-NAME or a regular file with PAGE-NAME nil.
Return the absolute path to any page successfully found; nil if
@@ -440,7 +405,7 @@ successfully finding a page and reading it into a buffer,
run
(if (or (stringp page-name) in-hywiki-directory-flag)
(progn
(when in-page-flag
- ;; Current buffer must be the desired page (called from
'find-file-hook')
+ ;; Current buffer must be the desired page
(unless in-hywiki-directory-flag
(error "(hywiki-find-page): No `page-name' given; buffer file
must be in `hywiki-directory', not %s"
default-directory))
@@ -467,10 +432,10 @@ successfully finding a page and reading it into a buffer,
run
(hywiki-maybe-highlight-page-names)
(run-hooks 'hywiki-find-page-hook)
page-file)))
- ;; When called from `find-file-hook' without a page-name and outside
- ;; hywiki-directory, just find as a regular file and use next line
- ;; to highlight HyWikiWords only if buffer was not previously
- ;; highlighted.
+ ;; When called from without a page-name and outside
+ ;; hywiki-directory, just find as a regular file and use next
+ ;; line to highlight HyWikiWords only if buffer was not
+ ;; previously highlighted.
(hywiki-maybe-highlight-page-names))))
;;; ************************************************************************
@@ -896,12 +861,6 @@ relative to `hywiki-directory'."
hywiki-directory nil
(concat "^[^#]+" (regexp-quote hywiki-file-suffix) "$")))))
-(defun hywiki-get-file-stem-list ()
- "Return the list of existing HyWiki files sans their `hywiki-file-suffix'.
-This includes both HyWiki page files and others. Stems returned are
-relative to `hywiki-directory'."
- (mapcar #'file-name-sans-extension (hywiki-get-files)))
-
(defun hywiki-get-page (page-name)
"Return the absolute path of HyWiki PAGE-NAME or nil if it does not exist."
(if (and (stringp page-name) (not (string-empty-p page-name))
diff --git a/test/hsys-org-tests.el b/test/hsys-org-tests.el
index 9b905d066c..2c7258d58b 100644
--- a/test/hsys-org-tests.el
+++ b/test/hsys-org-tests.el
@@ -3,7 +3,7 @@
;; Author: Mats Lidell <[email protected]>
;;
;; Orig-Date: 23-Apr-21 at 20:55:00
-;; Last-Mod: 9-Apr-24 at 09:32:53 by Mats Lidell
+;; Last-Mod: 29-Jun-24 at 15:13:29 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -41,7 +41,8 @@
(insert "* 1\n** 2\n*** 3\n")
(goto-char 1)
(font-lock-ensure)
- (should (equal (hsys-org-region-with-text-property-value 1 'face) '(1 .
4)))))
+ (should (equal (hproperty:char-property-range 1 'face 'org-level-1)
+ '(1 . 4)))))
;; TODO: org-agenda-item-at-p
diff --git a/test/hui-tests.el b/test/hui-tests.el
index 39c08efc5c..6c5d11fa0d 100644
--- a/test/hui-tests.el
+++ b/test/hui-tests.el
@@ -253,9 +253,9 @@ Ensure modifying the button but keeping the label does not
create a double label
(hy-test-helpers:consume-input-events)
(hy-test-helpers-verify-hattr-at-p :actype
'actypes::link-to-Info-index-item
:args '("(emacs)Package") :loc
file :lbl-key "emacs-package-button"))
- (progn
- (kill-buffer "*info*")
- (hy-delete-file-and-buffer file)))))
+ ;; There may be multiple *info* buffers, e.g. *info*<2>
+ (kill-matching-buffers "^\\*info\\*" nil t)
+ (hy-delete-file-and-buffer file))))
(ert-deftest hui-gibut-create-link-to-file ()
"Programatically create implicit button link to file."