[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/hyperbole c4c5daaa08 9/9: Merge pull request #615 from
From: |
ELPA Syncer |
Subject: |
[elpa] externals/hyperbole c4c5daaa08 9/9: Merge pull request #615 from rswgnu/rsw |
Date: |
Mon, 16 Dec 2024 15:58:32 -0500 (EST) |
branch: externals/hyperbole
commit c4c5daaa08429e36cc38c68cf5d7381736b38769
Merge: e2749c6348 93874b2ec3
Author: Robert Weiner <rsw@gnu.org>
Commit: GitHub <noreply@github.com>
Merge pull request #615 from rswgnu/rsw
hywiki.el - Add global HyWiki page override & custom referent types
---
ChangeLog | 203 +++++++-
hactypes.el | 15 +-
hasht.el | 29 +-
hbdata.el | 3 +-
hbut.el | 127 ++---
hib-kbd.el | 4 +-
hibtypes.el | 26 +-
hmouse-drv.el | 26 +-
hmouse-tag.el | 97 ++--
hpath.el | 6 +-
hsys-org.el | 27 +-
hui-menu.el | 10 +-
hui-mini.el | 20 +-
hui-mouse.el | 6 +-
hui.el | 6 +-
hypb.el | 3 +-
hywiki.el | 1267 +++++++++++++++++++++++++++++++++--------------
test/hbut-tests.el | 71 +--
test/hy-test-helpers.el | 14 +-
test/hywiki-tests.el | 36 +-
20 files changed, 1386 insertions(+), 610 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8d38bf7c24..62e81808a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,98 @@
+2024-12-16 Bob Weiner <rsw@gnu.org>
+
+* test/hbut-tests.el: Change most "/tmp" to "/tmp/" for ease of comparison
+ with 'default-directory'.
+
+2024-12-15 Bob Weiner <rsw@gnu.org>
+
+* test/hywiki-tests.el (hywiki-tests--action-key-on-wikiword-displays-page):
+ Change mocklet call from 'hywiki-add-page' to newer
+ 'hywiki-display-referent' to fix the test.
+
+* test/hywiki-tests.el (hywiki-tests--active-in-current-buffer-p): Force
+ 'hywiki-mode' nil when testing that hywiki is not active.
+
+* hpath.el (hpath:shorten): Fix to normalize directory paths to end with
+ a dir separator char so compare properly to `default-directory'.
+
+* hbut.el (ebut:get): Remove unneeded local 'actype'.
+
+* test/hywiki-tests.el (hywiki-tests--assist-key-on-wikiword-displays-help):
+ Update to not use mocklet and to check WikiWord returned.
+
+* hywiki.el (hywiki-word, hywiki-word-at): Rewrite to get the proper
+ start and end buffer positions of any wikiword string, accounting for
+ Org link complexities much better than before.
+
+* hbut.el (hbut:source): Update doc to reflect that the caller must have
+ successfully searched for 'hbut:source-prefix' prior to calling this.
+ (ibut:set-name-and-label-key-p): Add set of ibut 'loc attribute
+ needed by a number of tests.
+
+* hmouse-tag.el (smart-tags-file-list, smart-ancestor-tag-files): Fix to
+ handle a list of directories as the first argument in which to look
+ for TAGS files, as used by 'smart-man-c-routine-ref' in "hui-mouse.el".
+ hui-mouse.el (smart-man-c-routine-ref): Update to support use of newer
+ 'Man-header-file-path' variable.
+
+2024-12-02 Bob Weiner <rsw@gnu.org>
+
+* hywiki.el (hywiki-clear-pages-hasht): Add and use in defcustom :set
+ method of `hywiki-directory' to ensure hash table is emptied including
+ all non-page referents when 'hywiki-directory' is changed.
+
+2024-12-01 Bob Weiner <rsw@gnu.org>
+
+* hmouse-drv.el (action-key-depress, assist-key-depress, hkey-help): Add
+ calls to (hattr:clear 'hbut:current) to clear 'hbut:current' button
+ attributes before depress,
+
+* hbut.el (ibut:create): Move setting of 'hbut:current HyWiki 'referent
+ attribute from 'hkey-help' to this function, so works with all
+ ibutton reports. Also, remove 'name-and-lbl-key-flag' from check
+ of whether to set attributes to the current button values. Also,
+ move call of 'hbut:report' when called interactively to here from
+ 'ibut:set-name-and-label-key-p' so works with all ibutton reports.
+ (ibut:set-name-and-label-key-p): Fix to return non-nil only when
+ 'lbl-key' or 'name' are set.
+ (ebut:get): Remove Hyperbole V1 setting of 'referent' attribute
+ from (hbdata:referent) so as not to confuse new use of same attribute
+ for HyWiki referents.
+ hibtypes.el (action): Add :name arg to 'ibut:create' call.
+
+* hywiki.el (hywiki-display-page): Set 'referent' attribute for
+ current button.
+
+* hsys-org.el (hsys-org-link-at-p): Change to ignore [[hy:MyWikiWord]]
+ links.
+ hywiki.el (hywiki-word-at): Change to handle [[hy:MyWikiWord]] links.
+ (hywiki-strip-org-link): Also strip hy: prefix from a link.
+
+* hywiki.el (hywiki-get-plural-wikiword): Return non-nil iff
+ 'hywiki-allow-plurals-flag' is set.
+ (hywiki-get-page-hasht): Remove any nil return values from
+ calling 'hywiki-allow-plurals-flag'.
+ (hywiki-allow-plurals-flag): Reset 'hywiki--any-page-regexp-list'
+ whenever this variable is set.
+
+* test/hywiki-tests.el (hywiki-tests--action-key-on-wikiword-displays-page,
+ hywiki-tests--assist-key-on-wikiword-displays-help):
+ Update to test Action and Assist Key behavior.
+
+* hywiki.el: Add additional require, defvar and declare-function to
+ remove byte-compiler warnings.
+
+2024-11-25 Bob Weiner <rsw@gnu.org>
+
+* hywiki.el (hywiki-referent-menu): Make all menu calls interactive
+ and update all hywiki-add-* interactive specs to take any wikiword
+ at point and if not, then prompt with completion for one.
+
+* hui-mini.el (hui:menu-hywiki): HyWiki menu replace FindPage with
+ FindReferent.
+ (hui:menu-act): Fix improper closing parens before end
+ of setq causing a bug where always returned nil.
+
2024-11-25 Mats Lidell <matsl@gnu.org>
* kotl/kmenu.el (kotl-menu-common-body): Use kotl-kview.
@@ -5,6 +100,54 @@
* .github/workflows/static.yaml: Static workflow for publishing the manual
to a static site using GitHub Pages.
+2024-11-24 Bob Weiner <rsw@gnu.org>
+
+* hywiki.el (hywiki-add-page-and-display): Add optional prefix arg
+ PROMPT-FLAG for use in 'hywiki-find-referent' call. Rewrite.
+ Update doc. This allows setting custom referent types when passing
+ a prefix arg to the the HyWiki/Create menu item.
+ (hywiki-display-page, hywiki-get-referent): Call 'hywiki-get-file'
+ to expand page file path, rather than doing it manually. Return referent.
+
+* hmouse-drv.el (hkey-help): If a HyWikiWord ibut, save its referent as an
+ attribute.
+
+* hui-menu.el (hui-menu-hywiki): Rename 'Add-HyWiki-Link' to
'Insert-HyWiki-Link'.
+ hywiki.el (hywiki-add-link): Rename to 'hywiki-insert-link'.
+
+* hywiki.el (hywiki-read-new-page-name, hywiki-read-page-name):
+ Rename to 'hywiki-word-read-new' and 'hywiki-word-read'.
+ Change prompt from "HyWiki Page Name" to "HyWikiWord" since
+ not all referents are pages any more.
+ (hywiki-word-grep): Add to compute and perform HyWikiWord grep.
+ (hywiki-get-page): Rename to 'hywiki-get-referent'.
+ (hywiki-get-singular-page-name): Rename to
+ 'hywiki-get-singular-wikiword'.
+ (hywiki-get-plural-page-name): Rename to
+ 'hywiki-get-plural-wikiword'.
+ (hywiki-page-exists-p): Rename to 'hywiki-referent-exists-p'
+ and improve doc string.
+ (hywiki-display-referent): Fix to use existing referent if any
+ before calling 'hywiki-add-page'.
+ (hywiki-referent-menu): Change 'Path' to 'Link' and add 'Page'
+ to reset to a standard HyWiki Page link.
+ (hywiki-add-path): Rename to 'hywiki-add-link'.
+ (hywiki-add-page): Remove unused 'prompt-flag' arg and replace
+ with optional 'force-flag' to force overwriting an existing HyWikiWord
+ referent.
+ (hywiki-add-to-page): Rename to 'hywiki-add-to-referent' and
+ rewrite to handle referents. Change arg 'start-flag' to 'position'
+ of insert.
+
+* hactypes.el (link-to-buffer-tmp, link-to-file): Fix 'point' arg to
+ accept markers.
+
+* hywiki.el (hywiki-make-pages-hasht): Fix to maintain non-page referent
+ elements when rebuild the hash table.
+
+* hibtypes.el (hywiki-word:help): Add so Assist Key on a HyWikiWord
+ customizes its referent type and link.
+
2024-11-24 Mats Lidell <matsl@gnu.org>
* Makefile (website-local-devel): Update the website files locally for
@@ -12,12 +155,70 @@
(website-devel): Push local updates to go live at
https:/www.gnu.org/software/hyperbole/devel.
+2024-11-23 Bob Weiner <rsw@gnu.org>
+
+* hui.el (hui:link-possible-types): Allow for :CUSTOM_ID: in
+ addition to :ID: matches for Org IDs.
+
+* hib-kbd.el (kbd-key:normalize): Fix interactive expr to read
+ a string rather than a single key sequence.
+
+* hywiki.el (hywiki-get-wikiwords-obarray): Add.
+ (hywiki-read-new-page-name, hywiki-read-page-name):
+ Replace 'hywiki-get-page-list' completion table with
+ 'hywiki-get-wikiwords-obarray' which is more efficient.
+ (hywiki-find-page): Rename to 'hywiki-find-referent'.
+ Rename 'hywiki-find-page-hook' to 'hywiki-find-referent-hook'.
+ (hywiki-word-activate): Change so automatically creates
+ pages that do not exist, except for the first HyWiki page, in
+ which case, prompts before creation.
+ (hywiki-display-page-function): Add this customization
+ function that displays HyWiki pages.
+ (hywiki-display-page): Add to use above variable to
+ display HyWiki pages.
+ (hywiki-word): Update doc with first page prompting.
+ (hywiki-maybe-highlight-page-names): Return nil so
+ 'hywiki-display-referent' returns nil when this is called.
+ (hywiki-get-file, hywiki-display-referent): Improve
+ #section matching to ignore #autosave# file names.
+ (hywiki-allow-plurals-flag): Add new customization,
+ defaults to t to treat plural HyWikiWords the same as singular
+ ones.
+ (hywiki-get-page): Handle HyWikiWord plurals based on
+ the above flag.
+
+* hactypes.el: Document potential second arg of referent (point)
+ when referent is already read into a buffer and user wants
+ to link to the current point.
+
+* hywiki.el (hywiki-add-*): Add to allow each HyWikiWord to have
+ a custom referent when created with a prefix argument. Referent
+ type is prompted for, similar to when creating other Hyperbole
+ buttons.
+ (hywiki-add-prompted-referent): Add to prompt for and
+ link a HyWikiWord to a custom referent or action type.
+ (hywiki-referent-menu): New minibuffer menu used by the
+ above function.
+ (hywiki-get-page): Expand to return all new possible
+ referent types.
+ (hywiki-display-referent): Add to display all of the
+ new referent types.
+ (hywiki-read-new-page-name): Use any potential WikiWord at
+ point as the default.
+
2024-11-23 Mats Lidell <matsl@gnu.org>
* Makefile (BATCHFLAGS): Use debug-on-error's default value nil. Emacs 31
introduces calling man using with-demoted-errors which
causes an error when requiring man when debug-on-error is set to t.
+2024-11-22 Bob Weiner <rsw@gnu.org>
+
+* hywiki.el (hywiki-find-page): Add missing second interactive
+ arg value, current-prefix-arg. Rewrite to allow for
+ different actions per HyWikiWord or a single overriding
+ function.
+
2024-11-19 Bob Weiner <rsw@gnu.org>
* hywiki.el (hywiki-maybe-highlight-page-name): Fix that adding
@@ -30,8 +231,6 @@
man-show where needed. This may allow CI/CD build of docker Emacs
master branch that lacks 'man' package.
-2024-11-18 bw <bw@norlinux>
-
* hui-tests.el (hui--ibut-link-directly-to-org-header-first-column):
Remove dir from fileb when comparing to in-buffer filename and
do the same for other tests in this file.
diff --git a/hactypes.el b/hactypes.el
index 9c8bf7b1a7..fc9c0cc0ef 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: 18-Nov-24 at 23:27:33 by Bob Weiner
+;; Last-Mod: 24-Nov-24 at 12:09:18 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -280,15 +280,15 @@ if any."
(defact link-to-buffer-tmp (buffer &optional point)
"Display a BUFFER scrolled to optional POINT.
-If POINT is given, the buffer is displayed with POINT at the top of
-the window.
+If POINT is given (an integer or marker), the buffer is displayed with
+POINT at the top of the window.
This type of link is for use within a single editor session. Use
`link-to-file' instead for a permanent link."
(interactive "bBuffer to link to: ")
(if (or (stringp buffer) (bufferp buffer))
(and (hpath:display-buffer buffer)
- (integerp point)
+ (integer-or-marker-p point)
(progn (goto-char (min (point-max) point))
(recenter 0)))
(hypb:error "(link-to-buffer-tmp): Not a current buffer: %s" buffer)))
@@ -347,7 +347,10 @@ Interactively, KEY-FILE defaults to the current buffer's
file name."
(describe-symbol symbol)))))
(defun hactypes:link-to-file-interactively ()
- "Get a path to link to and return it as a one item list."
+ "Get a path to link to and return it as a one item list.
+If the path is already read into a buffer, prompt the user whether to
+also include its current (point) and if so, include that as the second
+list item returned."
(let ((prev-reading-p hargs:reading-type)
(existing-buf t)
path-buf)
@@ -423,7 +426,7 @@ the window or as close as possible."
;; the path that use within a key series may have introduced.
(setq path (hpath:trim path))
(and (hpath:find path)
- (integerp point)
+ (integer-or-marker-p point)
(progn (goto-char (min (point-max) point))
(recenter 0))))
(hypb:error "(link-to-file): Invalid file name: \"%s\"" path)))
diff --git a/hasht.el b/hasht.el
index 674911c5d9..bf53ed72d4 100644
--- a/hasht.el
+++ b/hasht.el
@@ -8,7 +8,7 @@
;; AUTHOR: Bob Weiner
;;
;; ORIG-DATE: 16-Mar-90 at 03:38:48
-;; LAST-MOD: 6-Oct-24 at 13:26:58 by Bob Weiner
+;; LAST-MOD: 24-Nov-24 at 15:20:44 by Bob Weiner
;;
;; Copyright (C) 1990-1995, 1997, 2016 Free Software Foundation, Inc.
;; See the file BR-COPY for license information.
@@ -65,11 +65,12 @@ It is sent the two values as arguments.")
(defun hash-add (value key hash-table)
"Add VALUE, any lisp object, referenced by KEY, a string, to HASH-TABLE.
-Replaces any VALUE previously referenced by KEY."
- (if (hashp hash-table)
- (let* ((obarray (hash-obarray hash-table))
- (sym (intern key obarray)))
- (if sym (set sym value)))))
+Replace any VALUE previously referenced by KEY."
+ (when (hashp hash-table)
+ (let* ((obarray (hash-obarray hash-table))
+ (sym (intern key obarray)))
+ (when sym
+ (set sym value)))))
(defun hash-copy (hash-table)
"Return a copy of HASH-TABLE.
@@ -111,7 +112,7 @@ Return nil if KEY is not in HASH-TABLE or non-nil
otherwise."
(let ((htable-copy (hash-make (length (hash-obarray obj)))))
(mapc
(lambda (elt) (hash-add (car elt) (cdr elt) htable-copy))
- (hash-map 'hash-deep-copy obj))
+ (hash-map #'hash-deep-copy obj))
htable-copy))
((vectorp obj)
;; convert to list for mapping
@@ -141,10 +142,11 @@ Return nil if KEY is not in HASH-TABLE or non-nil
otherwise."
"Lookup KEY in HASH-TABLE and return associated value.
If value is nil, this function does not tell you whether or not KEY is in the
hash table. Use `hash-key-p' instead for that function."
- (if (hashp hash-table)
- (let* ((obarray (hash-obarray hash-table))
- (sym (intern-soft key obarray)))
- (if (boundp sym) (symbol-value sym)))))
+ (when (hashp hash-table)
+ (let* ((obarray (hash-obarray hash-table))
+ (sym (intern-soft key obarray)))
+ (when (boundp sym)
+ (symbol-value sym)))))
(defun hash-make (initializer &optional reverse)
"Create a hash table from INITIALIZER.
@@ -201,7 +203,7 @@ in reverse order of occurrence (they are prepended to the
list)."
(cons 'hasht obarray)))
(defun hash-map (func hash-table)
- "Return result of applying FUNC over each (<value> . <key>) in HASH-TABLE.
+ "Return list result of calling FUNC over each (<value> . <key>) in
HASH-TABLE.
<key> is a symbol.
If FUNC is in '(cdr key second symbol-name), then return all <key>s as strings.
@@ -215,7 +217,8 @@ If FUNC is in '(car value first symbol-value), then return
all <value>s."
(t `(lambda (sym) (funcall ,func
(cons (symbol-value sym)
(symbol-name sym)))))))
- (let ((result))
+ (let ((obarray (hash-obarray hash-table))
+ result)
(mapatoms (lambda (sym)
(and (boundp sym)
sym
diff --git a/hbdata.el b/hbdata.el
index 02c128c10d..10253dd8f5 100644
--- a/hbdata.el
+++ b/hbdata.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 2-Apr-91
-;; Last-Mod: 18-Feb-24 at 11:32:03 by Mats Lidell
+;; Last-Mod: 2-Dec-24 at 01:48:15 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -253,7 +253,6 @@ entry, otherwise modify existing one. Nil BUT-SYM means use
(let* ((actype)
(hbdata (list (hattr:get b 'lbl-key)
(hattr:get b 'action)
- ;; Hyperbole V1 referent compatibility, always nil
in V2
(hattr:get b 'referent)
;; Save actype without class prefix.
(and (setq actype (hattr:get b 'actype))
diff --git a/hbut.el b/hbut.el
index 4cd3790bec..1968fa300e 100644
--- a/hbut.el
+++ b/hbut.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 18-Sep-91 at 02:57:09
-;; Last-Mod: 18-Nov-24 at 20:17:13 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 22:35:20 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -45,6 +45,7 @@ Use the function, (hbut:max-len), to read the proper value.")
(defvar hproperty:but-face)
(defvar hproperty:ibut-face)
+(defvar hywiki-org-link-type)
(declare-function hargs:delimited "hargs")
(declare-function hargs:read-match "hargs")
@@ -61,6 +62,7 @@ Use the function, (hbut:max-len), to read the proper value.")
(declare-function hui:ibut-rename "hui")
(declare-function hui:key-dir "hui")
(declare-function hui:key-src "hui")
+(declare-function hywiki-get-referent "hywiki")
(declare-function kbd-key:act "hib-kbd")
(declare-function kbd-key:is-p "hib-kbd")
(declare-function org-context "org")
@@ -222,8 +224,7 @@ buffer.
Return nil if no matching button is found."
(hattr:clear 'hbut:current)
(save-excursion
- (let (actype
- but-data
+ (let (but-data
key-dir
key-file
lbl-end
@@ -262,11 +263,7 @@ Return nil if no matching button is found."
(hattr:set 'hbut:current 'categ 'explicit)
(hattr:set 'hbut:current 'action nil)
(hattr:set 'hbut:current 'actype
- (intern (setq actype (hbdata:actype but-data))))
- ;; Hyperbole V1 referent compatibility
- (when (= (length actype) 2)
- (hattr:set 'hbut:current 'referent
- (hbdata:referent but-data)))
+ (intern (hbdata:actype but-data)))
(hattr:set 'hbut:current 'args (hbdata:args but-data))
(hattr:set 'hbut:current 'creator (hbdata:creator but-data))
(hattr:set 'hbut:current
@@ -1711,7 +1708,9 @@ Return number of buttons reported on or nil if none."
(defun hbut:source (&optional full-flag)
"Return Hyperbole source buffer or file given at point.
-If a file, always return a full path if optional FULL-FLAG is non-nil."
+If a file, always return a full path if optional FULL-FLAG is non-nil.
+Caller must have successfully searched for `hbut:source-prefix' prior
+to calling this."
(save-excursion
(goto-char (match-end 0))
(cond ((looking-at "#<buffer \"?\\([^\n\"]+\\)\"?>")
@@ -1855,7 +1854,6 @@ attribute unless the button text is delimited.
Any implicit button name must contain at least two characters,
excluding delimiters, not just one."
- (interactive)
(let* ((opoint (point-marker))
;; Next line finds the name only if point is on it, not on the
;; text of the button.
@@ -1876,8 +1874,8 @@ excluding delimiters, not just one."
(progn
;; 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.
+ ;; delimited ibuts of a single character since
+ ;; no one should need that.
(goto-char (min (+ 2 (match-end 0))
(point-max)))
(match-end 0))
(prog1 (point)
@@ -1896,7 +1894,14 @@ excluding delimiters, not just one."
(when lbl-start-end
(setq lbl-key (nth 0 lbl-start-end)
lbl-start (nth 1 lbl-start-end)
- lbl-end (nth 2 lbl-start-end)))
+ lbl-end (nth 2 lbl-start-end))
+ (when (and (stringp lbl-key)
+ (string-prefix-p (concat hywiki-org-link-type ":")
lbl-key t))
+ ;; Remove any HyWiki org-link-type prefix
+ (setq lbl-key (substring lbl-key 3)
+ lbl-start (+ lbl-start (length hywiki-org-link-type) 1))))
+ (hattr:set 'hbut:current 'loc (save-excursion
+ (hbut:to-key-src 'full)))
(when lbl-start
(hattr:set 'hbut:current 'categ 'implicit)
(hattr:set 'hbut:current 'lbl-key lbl-key)
@@ -1927,10 +1932,7 @@ excluding delimiters, not just one."
(when (and name-start name-end)
(hattr:set 'hbut:current 'name-start name-start)
(hattr:set 'hbut:current 'name-end name-end))
- (when lbl-start
- (when (called-interactively-p 'any)
- (let (help-window-select)
- (hbut:report)))
+ (when (or lbl-key name)
t))
(goto-char opoint)
(setq opoint nil))))
@@ -1951,6 +1953,7 @@ return nil if no implicit button is found at point.
If a new button is created, store its attributes in the symbol,
\\='hbut:current."
+ (interactive)
;; :args is ignored unless :categ or :action is also given.
;; `lbl-key' attribute will be set from `but-sym' if any, the button
@@ -2033,83 +2036,57 @@ If a new button is created, store its attributes in the
symbol,
name-start
name-end)
- (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 (and current-name (or but-sym-flag (null name)))
+ (setq name current-name))
(when name
(hattr:set 'hbut:current 'name name))
- (cond ((and but-sym-flag current-name-start)
- (setq name-start current-name-start))
- ((or name-start name-and-lbl-key-flag))
- (current-name-start
- (setq name-start current-name-start)))
+ (when (and current-name-start (or but-sym-flag (null name-start)))
+ (setq name-start current-name-start))
(when name-start
(hattr:set 'hbut:current 'name-start name-start))
- (cond ((and but-sym-flag current-name-end)
- (setq name-end current-name-end))
- ((or name-end name-and-lbl-key-flag))
- (current-name-end
- (setq name-end current-name-end)))
+ (when (and current-name-end (or but-sym-flag (null name-end)))
+ (setq name-end current-name-end))
(when name-end
(hattr:set 'hbut:current 'name-end name-end))
- (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 (and current-lbl-key (or but-sym-flag (null lbl-key)))
+ (setq lbl-key current-lbl-key))
(when lbl-key
(hattr:set 'hbut:current 'lbl-key lbl-key))
- (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 (and current-lbl-start (or but-sym-flag (null 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 (and current-lbl-end (or but-sym-flag (null 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 (and current-loc (or but-sym-flag (null loc)))
+ (setq loc (or (save-excursion
+ (hbut:to-key-src 'full))
+ 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 (and current-dir (or but-sym-flag (null dir)))
+ (setq dir (or (hui:key-dir (current-buffer))
+ 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 (and current-action (or but-sym-flag (null action)))
+ (setq action current-action))
(when action
(hattr:set 'hbut:current 'action action))
- (cond ((and but-sym-flag current-categ)
+ (cond ((and current-categ but-sym-flag)
(setq categ current-categ))
- (categ)
- (t
+ ((null categ)
(setq categ (or is-type current-categ 'implicit))))
(when categ
(hattr:set 'hbut:current 'categ categ))
@@ -2126,11 +2103,8 @@ If a new button is created, store its attributes in the
symbol,
(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)))
+ (when (and current-actype (or but-sym-flag (null actype)))
+ (setq actype current-actype))
(unless actype
(setq actype (or
;; Hyperbole action type
@@ -2140,7 +2114,16 @@ If a new button is created, store its attributes in the
symbol,
(hattr:set 'hbut:current 'actype actype)
(when args
- (hattr:set 'hbut:current 'args (if actype (cdr args) args))))
+ (hattr:set 'hbut:current 'args (if actype (cdr args) args)))
+
+ (when (and lbl-key (eq actype #'hywiki-find-referent))
+ ;; If a HyWikiWord ibut, save its referent as an attribute
+ (hattr:set 'hbut:current 'referent (hywiki-get-referent
lbl-key)))
+
+ (when lbl-key
+ (when (called-interactively-p 'any)
+ (let (help-window-select)
+ (hbut:report)))))
(hbdata:ibut-instance-next (ibut:label-to-key name))))
(set-marker opoint nil))))
diff --git a/hib-kbd.el b/hib-kbd.el
index 8dd80b222b..53cb6a2d3d 100644
--- a/hib-kbd.el
+++ b/hib-kbd.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 22-Nov-91 at 01:37:57
-;; Last-Mod: 30-Jun-24 at 02:19:16 by Bob Weiner
+;; Last-Mod: 23-Nov-24 at 21:15:04 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -298,7 +298,7 @@ The KEY-SERIES is without any surrounding {}. Return the
normalized but still human-readable format. Use
`kbd-key:key-series-to-events' to add the key series to Emacs'
keyboad input queue, as if they had been typed by the user."
- (interactive "kKeyboard key sequence to normalize (no {}): ")
+ (interactive "sKeyboard key sequence to normalize (no {}): ")
;;
;; Hyperbole developers: see `edmacro-parse-keys' in "edmacro.el"
;; for further details on key formats.
diff --git a/hibtypes.el b/hibtypes.el
index fda2bdf1f6..061b52e32a 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: 13-Nov-24 at 13:08:00 by Mats Lidell
+;; Last-Mod: 1-Dec-24 at 20:33:59 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -65,8 +65,8 @@
(declare-function hui:help-ebut-highlight "hui")
(declare-function hyperb:stack-frame "hversion")
(declare-function hyrolo-get-file-list "hyrolo")
-(declare-function hywiki-get-singular-page-name "hywiki")
-(declare-function hywiki-page-exists-p "hywiki")
+(declare-function hywiki-get-singular-wikiword "hywiki")
+(declare-function hywiki-referent-exists-p "hywiki")
(declare-function markdown-footnote-goto-text "ext:markdown")
(declare-function markdown-footnote-marker-positions "ext:markdown")
(declare-function markdown-footnote-return "ext:markdown")
@@ -1571,6 +1571,7 @@ action type, function symbol to call or test to execute,
i.e.
<mail nil \"user@somewhere.org\">."
(let ((hbut:max-len 0)
(lbl-key (hattr:get 'hbut:current 'lbl-key))
+ (name (hattr:get 'hbut:current 'name))
(start-pos (hattr:get 'hbut:current 'lbl-start))
(end-pos (hattr:get 'hbut:current 'lbl-end))
actype actype-sym action args lbl var-flag)
@@ -1647,8 +1648,9 @@ action type, function symbol to call or test to execute,
i.e.
;; Create implicit button object and store in symbol hbut:current.
(ibut:label-set lbl)
- (ibut:create :lbl-key lbl-key :lbl-start start-pos :lbl-end end-pos
- :categ 'ibtypes::action :actype actype :args args)
+ (ibut:create :name name :lbl-key lbl-key :lbl-start start-pos
+ :lbl-end end-pos :categ 'ibtypes::action :actype actype
+ :args args)
;; Necessary so can return a null value, which actype:act cannot.
(let ((hrule:action
@@ -1689,14 +1691,14 @@ If a boolean function or variable, display its value."
;;; ========================================================================
(defib hywiki-existing-word ()
- "On a HyWiki word with an existing page, display its page and optional
section."
- (cl-destructuring-bind (page-name start end)
- (hywiki-page-exists-p :range)
- (when page-name
+ "On a HyWikiWord with an existing referent, display the referent."
+ (cl-destructuring-bind (wikiword start end)
+ (hywiki-referent-exists-p :range)
+ (when wikiword
(if (and start end)
- (ibut:label-set page-name start end)
- (ibut:label-set page-name))
- (hact 'hywiki-find-page (hywiki-get-singular-page-name page-name)))))
+ (ibut:label-set wikiword start end)
+ (ibut:label-set wikiword))
+ (hact 'hywiki-find-referent wikiword))))
;;; ========================================================================
;;; Inserts completion into minibuffer or other window.
diff --git a/hmouse-drv.el b/hmouse-drv.el
index c748fced8b..e9a3583353 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 04-Feb-90
-;; Last-Mod: 25-Jun-24 at 02:13:58 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 22:38:04 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -63,14 +63,15 @@
(declare-function hkey-quit-window "hmouse-drv") ; Alias defined in this file.
-(declare-function hattr:report "hbut")
-(declare-function hattr:list "hbut")
(declare-function br-in-browser "hpath")
-(declare-function hbut:label "hbut")
+(declare-function hattr:clear "hbut")
(declare-function hattr:get "hbut")
+(declare-function hattr:list "hbut")
+(declare-function hattr:report "hbut")
+(declare-function hbut:label "hbut")
+(declare-function hkey-set-key "hyperbole")
(declare-function hui:ebut-link-directly "hui")
(declare-function hui:ibut-link-directly "hui")
-(declare-function hkey-set-key "hyperbole")
(declare-function org-todo "org")
;;; ************************************************************************
@@ -198,6 +199,8 @@ This permits the Smart Keys to behave as paste keys.")
(defun action-key-depress (&rest args)
"Register depress of the Hyperbole Action Mouse Key."
(interactive)
+ (hattr:clear 'hbut:current)
+ (action-key-clear-variables)
(cond (assist-key-depressed-flag
(or action-key-help-flag
(setq assist-key-help-flag t)))
@@ -223,6 +226,7 @@ This permits the Smart Keys to behave as paste keys.")
(defun assist-key-depress (&rest args)
"Register depress of the Hyperbole Assist Mouse Key."
(interactive)
+ (assist-key-clear-variables)
(cond (action-key-depressed-flag
(or assist-key-help-flag
(setq action-key-help-flag t)))
@@ -352,6 +356,7 @@ the `action-key-default-function' variable is run. Return t
unless the `action-key-default-function' variable is not bound to
a valid function."
(interactive)
+ (hattr:clear 'hbut:current)
(action-key-clear-variables)
(unwind-protect
(prog1 (action-key-internal)
@@ -1052,6 +1057,7 @@ With optional ASSISTING prefix arg non-nil, display help
for the
Assist Key command. Return non-nil iff associated help
documentation is found."
(interactive "P")
+ (hattr:clear 'hbut:current)
(let* ((mouse-flag (when (mouse-event-p last-command-event)
(or action-key-depress-position
assist-key-depress-position)))
(mouse-drag-flag (hmouse-drag-p))
@@ -1142,8 +1148,10 @@ documentation is found."
(when (memq cmd-sym '(hui:hbut-act hui:hbut-help))
(let ((actype (or (actype:elisp-symbol (hattr:get
'hbut:current 'actype))
(hattr:get 'hbut:current 'actype)))
+ ;; (lbl-key (hattr:get 'hbut:current 'lbl-key))
(categ (hattr:get 'hbut:current 'categ))
(attributes (nthcdr 2 (hattr:list 'hbut:current))))
+
(princ (format "%s %s BUTTON SPECIFICS:\n"
(htype:def-symbol
(if (eq categ 'explicit) actype categ))
@@ -1159,9 +1167,11 @@ documentation is found."
(replace-regexp-in-string "^" " "
(documentation categ)
nil t))))
(if assisting
- (let ((type-help-func (or (intern-soft
- (concat (htype:names
'ibtypes categ)
- ":help"))
+ (let* ((custom-help-func (intern-soft
+ (concat (htype:names
'ibtypes categ)
+ ":help")))
+ (type-help-func (or (and custom-help-func
(fboundp custom-help-func)
+ custom-help-func)
'hbut:report)))
(princ (format "\n%s ASSIST SPECIFICS:\n%s\n"
type-help-func
diff --git a/hmouse-tag.el b/hmouse-tag.el
index c003267d5e..94f1f89c6b 100644
--- a/hmouse-tag.el
+++ b/hmouse-tag.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 24-Aug-91
-;; Last-Mod: 16-Aug-24 at 22:30:09 by Mats Lidell
+;; Last-Mod: 16-Dec-24 at 00:34:24 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1115,24 +1115,31 @@ When optional NO-FLASH, do not flash."
;;; Private functions
;;; ************************************************************************
-(defun smart-ancestor-tag-files (&optional path name-of-tags-file)
- "Walk up PATH tree looking for NAME-OF-TAGS-FILE.
-Return list from furthest to deepest (nearest)."
- (or path (setq path default-directory))
+(defun smart-ancestor-tag-files (&optional dirs name-of-tags-file)
+ "Walk up DIRS trees looking for NAME-OF-TAGS-FILE.
+DIRS may be a list of directory or a single directory.
+Return a tags table list in DIRS order, where for each directory,
+list the found tags tables from furthest to nearest."
+ (or dirs (setq dirs default-directory))
(let ((tags-table-list)
tags-file)
- (while (and
- (stringp path)
- (setq path (file-name-directory path))
- (setq path (directory-file-name path))
- ;; Not at root directory
- (not (string-match
- (concat (file-name-as-directory ":?") "\\'")
- path)))
- (setq tags-file (expand-file-name (or name-of-tags-file "TAGS") path))
- (if (file-readable-p tags-file)
- (setq tags-table-list (cons tags-file tags-table-list))))
- tags-table-list))
+ (apply #'nconc
+ (mapcar (lambda (dir)
+ (setq tags-table-list nil
+ tags-file nil)
+ (while (and
+ (stringp dir)
+ (setq dir (file-name-directory dir))
+ (setq dir (directory-file-name dir))
+ ;; Not at root directory
+ (not (string-match
+ (concat (file-name-as-directory ":?") "\\'")
+ dir)))
+ (setq tags-file (expand-file-name (or name-of-tags-file
"TAGS") dir))
+ (if (file-readable-p tags-file)
+ (setq tags-table-list (cons tags-file
tags-table-list))))
+ tags-table-list)
+ (if (listp dirs) dirs (list dirs))))))
(defun smart-asm-include-file ()
"If point is on an include file line, try to display file.
@@ -1562,27 +1569,39 @@ cannot be expanded via a tags file."
(and (featurep 'hsys-org) (hsys-org-mode-p) (org-in-src-block-p t)))
;;;###autoload
-(defun smart-tags-file-list (&optional curr-dir-or-filename name-of-tags-file)
- "Return tag files list for optional CURR-DIR-OR-FILENAME or
`default-directory'.
-Optional NAME-OF-TAGS-FILE is the literal filename (no directory) for which
-to look. If no tags file is found, an error is signaled."
- (let* ((path (or (and (smart-tags-org-src-block-p) (hsys-org-get-value :dir))
- curr-dir-or-filename default-directory))
- (tags-table-list (smart-ancestor-tag-files path name-of-tags-file)))
- ;; If no tags files were found and the current buffer may contain Emacs
Lisp identifiers and
- ;; is in a 'load-path' directory, then use the default Emacs Lisp tag
table.
- (if (and (not tags-table-list)
- (stringp curr-dir-or-filename)
- smart-emacs-tags-file
- (smart-emacs-lisp-mode-p)
- (let ((path (file-name-directory curr-dir-or-filename)))
- (when path
- (delq nil (mapcar
- (lambda (p)
- (when p
- (equal (file-name-as-directory p) path)))
- load-path)))))
- (setq tags-table-list (list smart-emacs-tags-file)))
+(defun smart-tags-file-list (&optional curr-dirs-or-filename name-of-tags-file)
+ "Return tag files list for optional CURR-DIRS-OR-FILENAME or
`default-directory'.
+CURR-DIRS-OR-FILENAME may also be a list of directories in which to
+find tags files. Tag files returned may not yet exist.
+
+Optional NAME-OF-TAGS-FILE is the literal filename (no directory) for
+which to look; when null, use \"TAGS\". If the list returned is empty,
+signal an error."
+ (let* ((dirs (or (and (smart-tags-org-src-block-p) (hsys-org-get-value :dir))
+ curr-dirs-or-filename default-directory))
+ (tags-table-list (smart-ancestor-tag-files dirs name-of-tags-file)))
+ ;; If no tags files were found and the current buffer may contain
+ ;; Emacs Lisp identifiers and is in a 'load-path' directory, then
+ ;; use the default Emacs Lisp tag table.
+ (unless tags-table-list
+ (cond ((and (stringp curr-dirs-or-filename)
+ smart-emacs-tags-file
+ (smart-emacs-lisp-mode-p)
+ (let ((dir (file-name-directory curr-dirs-or-filename)))
+ (when dir
+ (delq nil (mapcar
+ (lambda (p)
+ (when p
+ (equal (file-name-as-directory p) dir)))
+ load-path)))))
+ (setq tags-table-list (list smart-emacs-tags-file)))
+ ((and curr-dirs-or-filename (listp curr-dirs-or-filename))
+ (setq tags-table-list
+ (delq nil (mapcar
+ (lambda (p)
+ (when (stringp p)
+ (expand-file-name "TAGS" p)))
+ curr-dirs-or-filename))))))
;; Return the appropriate tags file list.
(cond (tags-table-list
;; GNU Emacs when tags tables are found or provided by the user
@@ -1593,7 +1612,7 @@ to look. If no tags file is found, an error is signaled."
tags-table-computed-list)
((when (boundp 'tags-file-name) tags-file-name)
(list tags-file-name))
- (t (error "Needed tags file not found; see `man etags' for how to
build one")))))
+ (t (error "(smart-tags-file-list): Needed tags file not found; see
`man etags' for how to build one")))))
;;; ************************************************************************
;;; Private functions
diff --git a/hpath.el b/hpath.el
index 30a297b2d4..ec9fb619fc 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: 18-Nov-24 at 20:16:58 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 23:45:41 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -2034,6 +2034,10 @@ ${var}) with their values in PATH. The first matching
value for
variables like `${PATH}' is used. Then abbreviate any remaining
path."
(setq path (expand-file-name (hpath:substitute-value path)))
+ (when (file-directory-p path)
+ ;; Force path to have a final directory separator so comparisons
+ ;; to `default-directory' work
+ (setq path (file-name-as-directory path)))
(unless relative-to
(setq relative-to default-directory))
(when (stringp relative-to)
diff --git a/hsys-org.el b/hsys-org.el
index ebc7dbc1bd..f46fdecd86 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: 16-Sep-24 at 22:19:53 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 22:39:45 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -56,10 +56,11 @@
(defvar hywiki-org-link-type-required) ; "hywiki.el"
(defvar org-agenda-buffer-tmp-name) ; "org-agenda.el"
-(declare-function hywiki-at-tags-p "hywiki")
-(declare-function hywiki-tags-view "hywiki")
+(declare-function hycontrol-windows-grid "hycontrol")
(declare-function hyrolo-tags-view "hyrolo")
(declare-function hyrolo-at-tags-p "hyrolo")
+(declare-function hywiki-at-tags-p "hywiki")
+(declare-function hywiki-tags-view "hywiki")
(declare-function hsys-org-roam-tags-view "hsys-org")
(declare-function org-babel-get-src-block-info "org-babel")
@@ -496,25 +497,17 @@ Match to all todos if `keyword' is nil or the empty
string."
(defun hsys-org-link-at-p ()
"Return non-nil iff point is on a square-bracketed Org mode link.
-Assume caller has already checked that the current buffer is in `org-mode'
-or is looking for an Org link in another buffer type."
+Ignore [[hy:HyWiki]] buttons and return nil (handle these as
+implicit buttons). Assume caller has already checked that the
+current buffer is in `org-mode' or is looking for an Org link in
+another buffer type."
(unless (or (smart-eolp) (smart-eobp))
(with-suppressed-warnings nil
(let ((in-org-link (org-in-regexp org-link-bracket-re nil t)))
(when in-org-link
(save-match-data
- ;; If this Org link matches a HyWiki word, let Org handle
- ;; it with its normal internal link handling only if it
- ;; has a `hywiki-org-link-type' prefix or if
- ;; `hywiki-org-link-type-required' is non-nil. Otherwise,
- ;; return nil from this function and let ibtypes handle this
- ;; as a HyWiki word.
- (if (fboundp 'hywiki-word-at)
- (if (hywiki-word-at)
- (when (or hywiki-org-link-type-required
- (hyperb:stack-frame '(hywiki-word-at)))
- in-org-link)
- in-org-link)
+ ;; If this Org link matches a potential HyWiki word, ignore it.
+ (unless (and (fboundp 'hywiki-word-at) (hywiki-word-at))
in-org-link)))))))
;; Assume caller has already checked that the current buffer is in org-mode.
diff --git a/hui-menu.el b/hui-menu.el
index 6687033cb0..7b5ef134c1 100644
--- a/hui-menu.el
+++ b/hui-menu.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 28-Oct-94 at 10:59:44
-;; Last-Mod: 27-Oct-24 at 17:59:52 by Bob Weiner
+;; Last-Mod: 24-Nov-24 at 16:38:36 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -309,15 +309,15 @@ Return t if cutoff, else nil."
["Activate-HyWiki-Word" hywiki-word-activate t]
["Create-HyWiki-Page" hywiki-add-page-and-display t]
["Edit-HyWiki-Pages" hywiki-directory-edit t]
- ["Find-HyWiki-Page" hywiki-find-page t]
+ ["Find-HyWiki-Referent" hywiki-find-referent t]
(when (fboundp 'consult-grep) ;; allow for autoloading
["Grep-Consult-Pages" hywiki-consult-grep t])
["Help" hkey-help t]
- ["Add-HyWiki-Link" hywiki-add-link t]
- hui-menu-org-meta-return-options
["HyWiki-Mode-Toggle" hywiki-mode t]
- ["Publish-HyWiki" hywiki-publish-to-html t]
["HyWiki-Tag-Find" hywiki-tags-view t]
+ ["Insert-HyWiki-Link" hywiki-insert-link t]
+ hui-menu-org-meta-return-options
+ ["Publish-HyWiki" hywiki-publish-to-html t]
(when (fboundp 'consult-grep) ;; allow for autoloading
["HyWiki-Word-Consult" hywiki-word-consult-grep t])))
"Menu items for HyWiki editing and publishing.")
diff --git a/hui-mini.el b/hui-mini.el
index c5c8a570b7..b3f465fcde 100644
--- a/hui-mini.el
+++ b/hui-mini.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 15-Oct-91 at 20:13:17
-;; Last-Mod: 27-Oct-24 at 18:10:37 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 22:43:50 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -19,9 +19,11 @@
;;; Other required Elisp libraries
;;; ************************************************************************
-(require 'hypb)
-(require 'hsettings) ; For hyperbole-web-search-alist
(require 'browse-url)
+(require 'hsettings) ; For hyperbole-web-search-alist
+(require 'hypb)
+(unless (fboundp 'string-replace)
+ (load "subr")) ;; for `string-replace'
;;; ************************************************************************
;;; Public declarations
@@ -196,8 +198,8 @@ documentation, not the full text."
(unless (eq act-form t)
(set--this-command-keys hui:menu-keys)
(setq show-menu nil
- this-command act-form)
- rtn (call-interactively act-form)))
+ this-command act-form
+ rtn (call-interactively act-form))))
((stringp act-form)
(if (or doc-flag help-string-flag)
(setq show-menu nil
@@ -207,8 +209,8 @@ documentation, not the full text."
))
(t (set--this-command-keys hui:menu-keys)
(setq show-menu nil
- this-command act-form)
- rtn (eval act-form)))))
+ this-command act-form
+ rtn (eval act-form))))))
(t (setq show-menu nil))))
rtn))
@@ -1032,7 +1034,7 @@ support underlined faces as well."
"Create and display a new HyWiki page. Shows existing page names
to aid in new naming.")
'("EditPages" hywiki-directory-edit
"Display and edit HyWiki directory.")
- '("FindPage" hywiki-find-page
+ '("FindReferent" hywiki-find-referent
"Prompt with completion for and display a HyWiki page ready for
editing.")
(when (fboundp 'consult-grep) ;; allow for autoloading
'("GrepConsult" hywiki-consult-grep
@@ -1042,7 +1044,7 @@ support underlined faces as well."
'("Info" (id-info "(hyperbole)HyWiki")
"Display Hyperbole manual section on HyWiki.")
'("Link" hywiki-add-link
- "Prompt for and add a link at point to a HyWiki page.")
+ "Prompt for and add a HyWikiWord that links to a path and possible
position.")
'("ModeToggle" hywiki-mode
"Toggle whether HyWikiWords are highlighted and active in buffers
outside of the HyWiki page directory.")
'("Org-M-RET/" (menu . cust-org)
diff --git a/hui-mouse.el b/hui-mouse.el
index f852e28701..e675946165 100644
--- a/hui-mouse.el
+++ b/hui-mouse.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 04-Feb-89
-;; Last-Mod: 17-Nov-24 at 12:01:54 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 13:17:27 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1759,7 +1759,9 @@ locate the definition."
(match-beginning 1) (match-end 1)))))))
(if ref
(list 'smart-tags-display ref nil
- (smart-tags-file-list (and (boundp 'man-path) man-path))))))
+ (smart-tags-file-list (or (and (boundp 'Man-header-file-path)
+ Man-header-file-path)
+ (and (boundp 'man-path) man-path)))))))
(defun smart-man-file-ref ()
"Return form to eval to display file whose name is at point.
diff --git a/hui.el b/hui.el
index 0d060b0928..608012261b 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: 18-Nov-24 at 20:05:31 by Bob Weiner
+;; Last-Mod: 23-Nov-24 at 20:35:50 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -1848,9 +1848,9 @@ Buffer without File link-to-buffer-tmp"
(list (cond ((and (featurep 'org-id)
(cond ((save-excursion
(beginning-of-line)
- (when (looking-at "[ \t]*:ID:[
\t]+\\([^ \t\r\n\f]+\\)")
+ (when (looking-at "[
\t]*:\\(CUSTOM_\\)?ID:[ \t]+\\([^ \t\r\n\f]+\\)")
;; Org ID definition
- (list 'link-to-org-id
(match-string 1)))))
+ (list 'link-to-org-id
(match-string 2)))))
(t (let* ((id (thing-at-point 'symbol
t)) ;; Could be a uuid or some other form of id
(bounds (when id
(bounds-of-thing-at-point 'symbol)))
(start (when bounds (car
bounds)))
diff --git a/hypb.el b/hypb.el
index 3728198bcc..91864f00ad 100644
--- a/hypb.el
+++ b/hypb.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 6-Oct-91 at 03:42:38
-;; Last-Mod: 30-Sep-24 at 01:00:10 by Bob Weiner
+;; Last-Mod: 15-Dec-24 at 22:49:02 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -33,6 +33,7 @@
(declare-function helm-info "ext:helm")
(declare-function helm-apropos "ext:helm")
(declare-function devdocs-lookup "ext:devdocs")
+(declare-function native-comp-available-p "comp.c")
;; interaction-log
(defvar ilog-buffer-name)
diff --git a/hywiki.el b/hywiki.el
index 0d4572489b..242101f075 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: 19-Nov-24 at 00:21:19 by Bob Weiner
+;; Last-Mod: 16-Dec-24 at 01:03:45 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -118,14 +118,18 @@
;;; ************************************************************************
(require 'cl-lib) ;; For `cl-find'
+(require 'hactypes) ;; For `link-to-file-interactively'
(require 'hargs)
-(require 'hbut) ;; For `hbut:syntax-table'
(require 'hasht)
+(require 'hbut) ;; For `hbut:syntax-table'
(require 'hpath)
-(require 'hypb) ;; Requires `seq'
(require 'hproperty)
(require 'hsys-consult)
+(require 'hui) ;; For `hui:actype'
+(require 'hui-mini) ;; For `hui:menu-act'
+(require 'hypb) ;; Requires `seq'
(require 'outline) ;; For `outline-mode-syntax-table'
+(require 'subr-x) ;; For `string-remove-prefix'
(require 'thingatpt)
(eval-and-compile
@@ -136,16 +140,79 @@
;;; Public declarations
;;; ************************************************************************
-(defvar action-key-modeline-buffer-id-function) ;; "hui-mouse"
-(defvar org-agenda-buffer-tmp-name) ;; "org-agenda.el"
-(defvar org-export-with-broken-links);; "ox.el"
-(defvar org-publish-project-alist) ;; "ox-publish.el"
-
+(defvar action-key-modeline-buffer-id-function) ;; "hui-mouse.el"
+(defvar bookmark-current-bookmark) ;; "bookmark.el"
+(defvar hywiki-referent-menu nil) ;; "hywiki.el"
+(defvar org-agenda-buffer-tmp-name) ;; "org-agenda.el"
+(defvar org-export-with-broken-links) ;; "ox.el"
+(defvar org-publish-project-alist) ;; "ox-publish.el"
+
+(declare-function activities-completing-read "activities" (:prompt prompt
:default default))
+(declare-function activities-new "activities" (name))
+(declare-function activities-resume "activities" (activity :resetp resetp))
+(declare-function bookmark-completing-read "bookmark" (prompt &optional
default))
+(declare-function bookmark-location "bookmark" (bookmark-name-or-record))
(declare-function hsys-org-at-tags-p "hsys-org")
(declare-function org-link-store-props "ol" (&rest plist))
+(declare-function org-roam-node-read "org-roam" (&optional initial-input
filter-fn sort-fn require-match prompt))
(declare-function org-publish-property "ox-publish" (property project
&optional default))
(declare-function smart-treemacs-edit "hui-treemacs" (&optional dir))
+;;; ************************************************************************
+;;; Private variables
+;;; ************************************************************************
+
+;; Must be set after `hywiki-get-buttonize-characters' is defined
+(defconst hywiki--buttonize-characters nil
+ "String of single character keys bound to
`hywiki-buttonize-character-commands'.
+Each such key self-inserts before highlighting any prior HyWiki word
+in `hywiki-mode'.")
+
+(defconst hywiki--buttonize-character-regexp nil
+ "Regexp matching a single separating character following a HyWiki word.")
+
+(defconst hywiki--word-and-buttonize-character-regexp nil
+ "Regexp matching HyWikiWord#section plus a valid word separating character.")
+
+(defvar hywiki--directory-checksum ""
+ "String checksum for `hywiki-directory' page names.")
+
+(defvar hywiki--directory-mod-time nil
+ "Last mod time for `hywiki-directory' or nil if the value has not been read.
+See `current-time' function for the mod time format.")
+
+;; Redefine the `org-mode-syntax-table' for use in
`hywiki-get-buttonize-characters'
+;; so do not have to load all of Org mode there.
+(defvar hywiki--org-mode-syntax-table
+ (let ((st (make-syntax-table outline-mode-syntax-table)))
+ (modify-syntax-entry ?\" "\"" st)
+ (modify-syntax-entry ?\\ "_" st)
+ (modify-syntax-entry ?~ "_" st)
+ (modify-syntax-entry ?< "(>" st)
+ (modify-syntax-entry ?> ")<" st)
+ st)
+ "Standard syntax table for Org mode buffers with HyWiki support.")
+
+(defvar hywiki--pages-directory nil)
+(defvar hywiki--pages-hasht nil)
+
+;; Globally set these values to avoid using 'let' with stack allocations
+;; within `hywiki-maybe-highlight-page-name' frequently.
+(defvar hywiki--any-page-regexp-list nil)
+(defvar hywiki--buts nil)
+(defvar hywiki--but-end nil)
+(defvar hywiki--but-start nil)
+(defvar hywiki--buttonize-end (make-marker)) ;; This must always stay a
marker
+(defvar hywiki--buttonize-start (make-marker)) ;; This must always stay a
marker
+(defvar hywiki--current-page nil)
+(defvar hywiki--end nil)
+(defvar hywiki--highlighting-done-flag t)
+(defvar hywiki--page-name nil)
+(defvar hywiki--range nil)
+(defvar hywiki--save-case-fold-search nil)
+(defvar hywiki--save-org-link-type-required nil)
+(defvar hywiki--start nil)
+
;;; ************************************************************************
;;; Public variables
;;; ************************************************************************
@@ -192,7 +259,11 @@ Use nil for no HyWiki mode indicator."
See `hywiki-org-publishing-directory' for exported pages in html format."
:initialize #'custom-initialize-default
:set (lambda (option value)
- (set option (file-name-as-directory value))
+ (unless (and (boundp 'hywiki-directory)
+ (equal hywiki-directory (file-name-as-directory value)))
+ (set option (file-name-as-directory value))
+ (hywiki-clear-pages-hasht)
+ (hywiki-make-pages-hasht))
(hywiki-org-set-publish-project))
:type 'string
:group 'hyperbole-hywiki)
@@ -314,7 +385,7 @@ where PATH is the un-resolvable reference."
:with-toc nil)))
(defvar-local hywiki-page-flag nil
- "Set to t after a `find-file' of a HyWiki page file, else nil.
+ "Set to t after finding a HyWiki page file, else nil.
The file must be below `hywiki-directory'.
For reference, this is set when `window-buffer-change-functions' calls
@@ -355,64 +426,25 @@ the HyWiki word and grouping 2 is the #section with the #
included.")
(defcustom hywiki-word-face 'hywiki--word-face
"Hyperbole face for HyWiki word highlighting."
- :type 'face
:initialize #'custom-initialize-default
+ :type 'face
:group 'hyperbole-hywiki)
-;;; ************************************************************************
-;;; Private variables
-;;; ************************************************************************
-
-;; Must be set after `hywiki-get-buttonize-characters' is defined
-(defconst hywiki--buttonize-characters nil
- "String of single character keys bound to
`hywiki-buttonize-character-commands'.
-Each such key self-inserts before highlighting any prior HyWiki word
-in `hywiki-mode'.")
-
-(defconst hywiki--buttonize-character-regexp nil
- "Regexp matching a single separating character following a HyWiki word.")
-
-(defconst hywiki--word-and-buttonize-character-regexp nil
- "Regexp matching HyWikiWord#section plus a valid word separating character.")
-
-(defvar hywiki--directory-checksum ""
- "String checksum for `hywiki-directory' page names.")
-
-(defvar hywiki--directory-mod-time nil
- "Last mod time for `hywiki-directory' or nil if the value has not been read.
-See `current-time' function for the mod time format.")
-
-;; Redefine the `org-mode-syntax-table' for use in
`hywiki-get-buttonize-characters'
-;; so do not have to load all of Org mode there.
-(defvar hywiki--org-mode-syntax-table
- (let ((st (make-syntax-table outline-mode-syntax-table)))
- (modify-syntax-entry ?\" "\"" st)
- (modify-syntax-entry ?\\ "_" st)
- (modify-syntax-entry ?~ "_" st)
- (modify-syntax-entry ?< "(>" st)
- (modify-syntax-entry ?> ")<" st)
- st)
- "Standard syntax table for Org mode buffers with HyWiki support.")
-
-(defvar hywiki--pages-directory nil)
-(defvar hywiki--pages-hasht nil)
+(defcustom hywiki-display-page-function #'hpath:find
+ "Hyperbole function to display HyWiki pages.
+Only argument is the page name concatenated with optional #section."
+ :initialize #'custom-initialize-default
+ :type 'string
+ :group 'hyperbole-hywiki)
-;; Globally set these values to avoid using 'let' with stack allocations
-;; within `hywiki-maybe-highlight-page-name' frequently.
-(defvar hywiki--any-page-regexp-list nil)
-(defvar hywiki--buts nil)
-(defvar hywiki--but-end nil)
-(defvar hywiki--but-start nil)
-(defvar hywiki--buttonize-end (make-marker)) ;; This must always stay a
marker
-(defvar hywiki--buttonize-start (make-marker)) ;; This must always stay a
marker
-(defvar hywiki--current-page nil)
-(defvar hywiki--end nil)
-(defvar hywiki--highlighting-done-flag t)
-(defvar hywiki--page-name nil)
-(defvar hywiki--range nil)
-(defvar hywiki--save-case-fold-search nil)
-(defvar hywiki--save-org-link-type-required nil)
-(defvar hywiki--start nil)
+(defcustom hywiki-allow-plurals-flag t
+ "Non-nil means plural HyWikiWords have the same referent as the singular
form."
+ :initialize #'custom-initialize-default
+ :set (lambda (option value)
+ (set option value)
+ (setq hywiki--any-page-regexp-list nil))
+ :type 'boolean
+ :group 'hyperbole-hywiki)
;;; ************************************************************************
;;; hywiki minor mode
@@ -537,62 +569,190 @@ See the Info documentation at \"(hyperbole)HyWiki\".
;;; ************************************************************************
(defib hywiki-word ()
- "When on a HyWiki word, display its page and optional section.
-If the associated HyWiki page does not exist, create it automatically."
- (let ((page-name (hywiki-word-at)))
- (when page-name
- (ibut:label-set page-name (match-beginning 0) (match-end 0))
- (hact 'hywiki-find-page page-name))))
-
-;;;###autoload
-(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
-failed or if displaying a regular file (read in via a `find-file'
-call).
-
-By default, create any non-existent page. When not in batch mode,
-with optional PROMPT-FLAG t or if this is the first HyWiki page in
-`hywiki-directory', prompt to create if non-existent. If
-PROMPT-FLAG is :existing or with a prefix argument when called
-interactively, return nil unless the page already exists. After
-successfully finding a page and reading it into a buffer, run
-`hywiki-find-page-hook'."
- (interactive (list (if current-prefix-arg
- (hywiki-read-page-name "Find existing HyWiki page: ")
- (hywiki-read-new-page-name "Find HyWiki page: "))))
- (let ((in-page-flag (null page-name))
+ "When on a HyWikiWord, display its referent.
+If the associated HyWiki referent is a page and it does not exist,
+create it automatically unless it is the first HyWiki page to be
+created, in which case, prompt the user whether to create it to
+prevent any unexpected HyWiki use."
+ (let* ((wikiword-start-end (hywiki-word-at t))
+ (wikiword (nth 0 wikiword-start-end))
+ (start (nth 1 wikiword-start-end))
+ (end (nth 2 wikiword-start-end)))
+ (when wikiword
+ (ibut:label-set wikiword start end)
+ (hact 'hywiki-find-referent wikiword))))
+
+(defun hywiki-display-page (&optional wikiword)
+ "Display an optional WIKIWORD page and return the page file.
+Use `hywiki-display-page-function' to display the page.
+
+If WIKIWORD is omitted or nil and `hywiki-display-page-function'
+is an interactive function, it is called interactively and prompts for
+an existing or new HyWikiWord."
+ (if (and (null wikiword) (commandp hywiki-display-page-function))
+ (call-interactively hywiki-display-page-function)
+ (when (null wikiword)
+ (setq wikiword (hywiki-word-read-new "Find HyWiki page: ")))
+ (let ((referent (hywiki-get-file wikiword)))
+ (funcall hywiki-display-page-function referent)
+ ;; Set 'referent attribute of current implicit button
+ (hattr:set 'hbut:current 'referent referent)
+ referent)))
+
+(defun hywiki-display-referent (&optional wikiword prompt-flag)
+ "Display HyWiki WIKIWORD or a regular file with WIKIWORD nil.
+Return the WIKIWORD's referent if successfully found or nil otherwise.
+
+For details, see documentation for `hywiki-find-referent'.
+After successfully finding a page and reading it into a buffer, run
+`hywiki-display-referent-hook'."
+ (let ((in-page-flag (null wikiword))
(in-hywiki-directory-flag (hywiki-in-page-p)))
- (if (or (stringp page-name) in-hywiki-directory-flag)
+ (if (or (stringp wikiword) in-hywiki-directory-flag)
(progn
(when in-page-flag
;; 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"
+ (error "(hywiki-display-referent): No `wikiword' given; buffer
file must be in `hywiki-directory', not %s"
default-directory))
- (when (null buffer-file-name)
- (error "(hywiki-find-page): No `page-name' given; buffer must
have an attached file"))
- (setq page-name (file-name-sans-extension (file-name-nondirectory
buffer-file-name))))
-
- (let* ((section (when (string-match "#" page-name)
- (substring page-name (match-beginning 0))))
- (page-name (if (string-match "#" page-name)
- (substring page-name 0 (match-beginning 0))
- page-name))
- (page-file (or (hywiki-get-page page-name)
- (hywiki-add-page page-name prompt-flag))))
- (when page-file
+ (unless buffer-file-name
+ (error "(hywiki-display-referent): No `wikiword' given; buffer
must have an attached file"))
+ (setq wikiword (file-name-sans-extension (file-name-nondirectory
buffer-file-name))))
+ (when (string-match "#[^#]+$" wikiword)
+ (setq wikiword (substring wikiword 0 (match-beginning 0))))
+ (let* ((section (when (string-match "#[^#]+$" wikiword)
+ (substring wikiword (match-beginning 0))))
+ (referent (cond (prompt-flag
+ (hywiki-add-prompted-referent wikiword))
+ ((hywiki-get-referent wikiword))
+ (t (hywiki-add-page wikiword)))))
+ (when referent
;; Ensure highlight any page name at point in case called as a
;; Hyperbole action type
(hywiki-maybe-highlight-page-name t)
- (unless in-page-flag (hpath:find (concat page-file section)))
+ (cond ((or (symbolp referent) (functionp referent))
+ ;; function or actype symbol
+ (hact referent wikiword prompt-flag))
+ ((and (consp referent) (fboundp (car referent)))
+ ;; e.g. (kbd "key sequence")
+ (eval referent))
+ ((and (null referent) (stringp section)
+ (string-match-p "^\\(#[^#]+\\)$" section))
+ ;; "#in-buffer-section"
+ (hywiki-display-page section))
+ ((stringp referent)
+ (let ((case-fold-search t))
+ (cond
+ ((string-match-p "^\\({.+}\\)$" referent)
+ ;; "{key series}"
+ (hact 'kbd-key referent))
+ ((and (featurep 'org-id)
+ (string-match "^\\(CUSTOM_\\)?ID:[ \t]+\\(.*[^
\t]\\)" referent))
+ ;; "ID: org-id"
+ (setq referent (match-string 2 referent))
+ (hact 'link-to-org-id referent))
+ ((string-match-p "^\\(<\\[.+\\]>\\|<(.+)>\\)$" referent)
+ ;; "<(global explicit button name)>"
+ ;; "<[global implicit button name]>"
+ (gbut:act (string-trim (substring referent 2 -2))))
+ ((string-match-p "^(.+).+$\\|.+\\.info\\([.#]\\|$\\)"
referent)
+ ;; (info-manual)node-or-index-item
+ (hywiki-display-page referent))
+ (t
+ ;; page path, the default
+ (unless in-page-flag
+ (hywiki-display-page (concat referent section))))))))
(hywiki-maybe-highlight-page-names)
- (run-hooks 'hywiki-find-page-hook)
- page-file)))
- ;; When called without a page-name and outside hywiki-directory,
+ (run-hooks 'hywiki-display-referent-hook)
+ referent)))
+ ;; When called without a wikiword 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))))
+ (hywiki-maybe-highlight-page-names)
+ nil)))
+
+;;; ************************************************************************
+;;; Public referent menus and utility functions
+;;; ************************************************************************
+
+(unless hywiki-referent-menu
+ (makunbound 'hywiki-referent-menu))
+(defcustom hywiki-referent-menu
+ (delq nil
+ (list
+ '("HyWiki Add>")
+ (when (fboundp #'activities-new)
+ '("Activity" hywiki-add-activity
+ "Add a HyWikiWord that activates a saved activity from the
Activities package."))
+ '("Bookmark" hywiki-add-bookmark
+ "Add a HyWikiWord that jumps to an Emacs bookmark.")
+ '("Command" hywiki-add-command
+ "Add a HyWikiWord that runs an Emacs command or Hyperbole action
type.")
+ '("Find" hywiki-add-find
+ "Add a HyWikiWord that greps through `hywiki-directory' for its
matches.")
+ ;; "<(global explicit button name)>"
+ ;; "<[global implicit button name]>"
+ '("Gbut" hywiki-add-global-button
+ "Add a HyWikiWord that activates a named Hyperbole global button.")
+ '("HyRolo" hywiki-add-hyrolo
+ "Add a HyWikiWord that searches `hyrolo-file-list' for matches.")
+ ;; "{key series}" wikiword)
+ '("Keys" hywiki-add-key-series
+ "Add a HyWikiWord that executes a key series.")
+ ;; "(hyperbole)action implicit button"
+ '("InfoIndex" hywiki-add-info-index
+ "Add a HyWikiWord that displays an Info index item.")
+ ;; "(hyperbole)Smart Keys"
+ '("infoNode" hywiki-add-info-node
+ "Add a HyWikiWord that displays an Info node.")
+ '("LinkPath" hywiki-add-link
+ "Add a HyWikiWord that links to a path and possible position.")
+ ;; "ID: org-id"
+ '("OrgID" hywiki-add-org-id
+ "Add a HyWikiWord that displays an Org section given its Org ID.")
+ '("orgRoamNode" hywiki-add-org-roam-node
+ "Add a HyWikiWord that displays an Org Roam node given its title.")
+ ;; "pathname:line:col"
+ ;; "#in-buffer-section"
+ '("Page" hywiki-add-page
+ "Add/reset a HyWikiWord to link to its standard HyWiki page.")
+ ;; e.g. (kbd "key sequence")
+ '("Sexp" hywiki-add-sexpresion
+ "Add a HyWikiWord that evaluates an Elisp sexpression.")))
+ "*Menu of HyWikiWord custom referent types of the form:
+\(LABEL-STRING ACTION-SEXP DOC-STR)."
+ :set (lambda (var value) (set-default var value))
+ :type '(cons (list string) (repeat (list string sexp string)))
+ :group 'hyperbole-buttons)
+
+(defun hywiki-add-prompted-referent (wikiword)
+ "Prompt for, add to HyWiki lookups and return a WIKIWORD custom referent."
+ (interactive (list (hywiki-word-read-new "Add/Edit HyWikiWord: ")))
+ (unless (stringp wikiword)
+ (setq wikiword (hywiki-word-read-new "Add/Edit HyWikiWord: ")))
+ (let ((referent
+ (hui:menu-act 'hywiki-referent-menu
+ (list (cons 'hywiki-referent-menu
+ (cons (list (format "Set HyWiki '%s' Actype>"
+ wikiword))
+ (cdr hywiki-referent-menu)))))))
+ (or referent
+ (when (called-interactively-p 'interactive)
+ (user-error "(hywiki-add-prompted-referent): Invalid HyWikiWord:
'%s'; must be capitalized, all alpha" wikiword)))))
+
+(defun hywiki-add-referent (wikiword referent)
+ (when (hywiki-word-is-p wikiword)
+ (when (match-string-no-properties 2 wikiword)
+ ;; Remove any #section suffix in PAGE-NAME.
+ (setq wikiword (match-string-no-properties 1 wikiword)))
+ (hash-add referent (hywiki-get-singular-wikiword wikiword)
+ (hywiki-get-page-hasht))
+ (setq hywiki--any-page-regexp-list nil)
+ (unless (hyperb:stack-frame '(hywiki-maybe-highlight-page-names-in-frame))
+ (hywiki-directory-set-mod-time)
+ (hywiki-directory-set-checksum))
+ (run-hooks 'hywiki-add-referent-hook)
+ referent))
;;; ************************************************************************
;;; Public functions
@@ -608,33 +768,256 @@ Exclude the minibuffer if selected and return nil."
(not (apply #'derived-mode-p hywiki-exclude-major-modes))
(or hywiki-mode (hywiki-in-page-p))))
-;;;###autoload
-(defun hywiki-add-link ()
- "Insert at point a link to a HyWiki page."
- (interactive "*")
- (insert (hywiki-read-page-name "Link to HyWiki page: "))
- (hywiki-maybe-highlight-page-name))
-
-(defun hywiki-add-page (page-name &optional prompt-flag)
+(defun hywiki-add-activity (wikiword)
+ "Make WIKIWORD resume a prompted for activity.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the activity, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (require 'activities)
+ (let ((activity (activities-completing-read :prompt "Resume activity"
:default nil)))
+ (hywiki-add-referent wikiword `(activities-resume ,activity :resetp nil))))
+
+(defun hywiki-add-bookmark (wikiword)
+ "Make WIKIWORD display a bookmark and return the action.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the bookmark, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (require 'bookmark)
+ (let* ((bookmark (bookmark-completing-read "Bookmark: "
+ bookmark-current-bookmark))
+ (loc (bookmark-location bookmark))
+ ;; Use Hyperbole-specified display location
+ (bkm-display `(progn
+ (cond ((bufferp ,loc)
+ (hpath:display-buffer ,loc))
+ ((get-buffer ,loc)
+ (hpath:display-buffer (get-buffer ,loc)))
+ ((stringp ,loc)
+ (hywiki-display-page ,loc)))
+ (bookmark-jump ,bookmark))))
+ (hywiki-add-referent wikiword bkm-display)))
+
+(defun hywiki-add-command (wikiword)
+ "Set a custom command symbol for WIKIWORD and return it.
+Command is the symbol used in the definition expression, which
+may be an Emacs command or a Hyperbole action type.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the actype, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (let ((command (hui:actype nil (format "Command for %s: " wikiword))))
+ (hywiki-add-referent wikiword command)))
+
+(defun hywiki-add-find (wikiword)
+ "Make WIKIWORD grep across `hywiki-directory' for matches to itself.
+Return the command to invoke.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the grep, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (hywiki-add-referent wikiword #'hywiki-word-grep))
+
+(defun hywiki-add-global-button (wikiword)
+ "Make WIKIWORD evaluate a prompted for global button.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the button link, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (let ((gbut-name (hargs:read-match "Global button: "
+ (mapcar #'list (gbut:label-list))
+ nil t nil 'gbut)))
+ (hywiki-add-referent wikiword `(gbut:act ,gbut-name))))
+
+(defun hywiki-add-hyrolo (wikiword)
+ "Make WIKIWORD search and display `hyrolo-file-list' matches.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the hyrolo search, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (require 'hyrolo)
+ ;; !! TODO: Change PaulAllenWinter to search for "Winter, Paul Allen".
+ (hywiki-add-referent wikiword `(hyrolo-fgrep ,wikiword)))
+
+(defun hywiki-add-info-index (wikiword)
+ "Make WIKIWORD display an Info manual index item and return it.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the Info index item, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (let ((item (save-window-excursion
+ (info)
+ (Info-read-index-item-name "Info index item: "))))
+ (when (stringp item)
+ (unless (= (aref item 0) ?\()
+ (setq item (format "(%s)%s" (Info-current-filename-sans-extension)
item)))
+ (hywiki-add-referent wikiword `(Info-goto-node ,item)))))
+
+(defun hywiki-add-info-node (wikiword)
+ "Make WIKIWORD display an Info manual node and return it.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the Info node, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (let ((node (save-window-excursion
+ (info)
+ (Info-read-node-name "Info node: "))))
+ (when (stringp node)
+ (unless (= (aref node 0) ?\()
+ (setq node (format "(%s)%s" (Info-current-filename-sans-extension)
node)))
+ (hywiki-add-referent wikiword `(Info-goto-node ,node)))))
+
+(defun hywiki-add-key-series (wikiword)
+ "Make WIKIWORD invoke a prompted for key series and return it.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the key series, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (let ((key-series (read-string "Key series (with or without {}): ")))
+ (unless (string-match-p "\\`{.+}\\'" key-series)
+ (setq key-series (concat "{" (string-trim key-series) "}")))
+ (hywiki-add-referent wikiword key-series)))
+
+(defun hywiki-add-link (wikiword)
+ "Set a path link and possible position for WIKIWORD and return it.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the path link, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (let ((referent (hactypes:link-to-file-interactively)))
+ (when (= (length referent) 2)
+ (setq referent (hpath:file-position-to-line-and-column
+ (car referent) (cadr referent))))
+ (hywiki-add-referent wikiword referent)))
+
+(defun hywiki-add-org-id (wikiword)
+ "Make WIKIWORD evaluate a prompted for sexpression and return it.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the sexpression, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (cl-destructuring-bind (_src-window referent-window)
+ (hmouse-choose-link-and-referent-windows)
+ (with-selected-window referent-window
+ (unless (hsys-org-mode-p)
+ (user-error "(hywiki-add-org-id): Referent buffer <%s> must be in
org-mode, not %s"
+ (buffer-name)
+ major-mode))
+ (let ((org-id (org-id-get nil nil nil t)))
+ (when (and (null org-id) buffer-read-only)
+ (user-error "(hywiki-add-org-id): Referent buffer <%s> point has no
Org ID and buffer is read-only"
+ (buffer-name)))
+ (unless org-id
+ (setq org-id (org-id-get-create)))
+ (hywiki-add-referent wikiword (concat "ID: " org-id))))))
+
+(defun hywiki-add-org-roam-node (wikiword)
+ "Make WIKIWORD display an Org Roam Node and return the action.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the action, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (require 'org-roam)
+ (let* ((org-roam-node (org-roam-node-read))
+ (referent `(org-roam-node-open ,org-roam-node
+ (or (alist-get 'file
org-link-frame-setup)
+ (alist-get hpath:display-where
hpath:display-where-alist)))))
+ (hywiki-add-referent wikiword referent)))
+
+(defun hywiki-add-page (page-name &optional force-flag)
"Add or edit the HyWiki page for PAGE-NAME and return its file.
If file exists already, just return it. If PAGE-NAME is invalid,
trigger a `user-error' if called interactively or return nil if
not.
-By default, create any non-existent page. When not in batch mode,
-with optional PROMPT-FLAG t or if this is the first HyWiki page in
-`hywiki-directory', prompt to create if non-existent. If
-PROMPT-FLAG is :existing or with a prefix argument when called
-interactively, return nil unless the page already exists. After
-successfully adding a page, run `hywiki-add-page-hook'.
+By default, create any non-existent page. When not in batch or
+ert test results mode, if this is the first HyWiki page in
+`hywiki-directory', prompt to create it.
+
+After successfully adding a page, run `hywiki-add-page-hook'.
Use `hywiki-get-page' to determine whether a HyWiki page exists."
- (interactive (list (hywiki-read-new-page-name "Add/Edit HyWiki page: ")
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWiki page: "))
current-prefix-arg))
(if (hywiki-word-is-p page-name)
- (unless (or (eq prompt-flag :existing)
- (and prompt-flag (null noninteractive)
- (not (y-or-n-p (concat "Create new HyWiki page `"
page-name "'? ")))))
+ (when (or noninteractive
+ (not (hash-empty-p (hywiki-get-page-hasht)))
+ (hyperb:stack-frame '(ert-run-test))
+ (y-or-n-p (concat "Create new HyWiki page `" page-name "'? ")))
(when (match-string-no-properties 2 page-name)
;; Remove any #section suffix in PAGE-NAME.
(setq page-name (match-string-no-properties 1 page-name)))
@@ -642,51 +1025,76 @@ Use `hywiki-get-page' to determine whether a HyWiki page
exists."
(let* ((page-file (hywiki-get-file page-name))
(page-file-readable (file-readable-p page-file))
(pages-hasht (hywiki-get-page-hasht))
- (page-in-hasht (hywiki-get-page page-name)))
+ (page-in-hasht (hywiki-get-referent page-name)))
(unless page-file-readable
- (write-region "" nil page-file nil 0))
- (unless page-in-hasht
+ (if (file-writable-p page-file)
+ (write-region "" nil page-file nil 0)
+ (user-error "(hywiki-add-page): No permission to write HyWikiWord
page file:\n \"%s\"" page-name)))
+ (when (or force-flag (not page-in-hasht))
(hash-add page-file page-name pages-hasht)
(setq hywiki--any-page-regexp-list nil))
(unless (or (hyperb:stack-frame
'(hywiki-maybe-highlight-page-names-in-frame))
- (and page-file-readable page-in-hasht))
+ (and (not force-flag) page-file-readable page-in-hasht))
(hywiki-directory-set-mod-time)
(hywiki-directory-set-checksum))
(run-hooks 'hywiki-add-page-hook)
page-file))
(when (called-interactively-p 'interactive)
- (user-error "(hywiki-add-page): Invalid page name: '%s'; must be
capitalized, all alpha" page-name))))
+ (user-error "(hywiki-add-page): Invalid HyWikiWord: '%s'; must be
capitalized, all alpha" page-name))))
-(defun hywiki-add-page-and-display (page-name)
- "Add and display the HyWiki page for PAGE-NAME and return its file.
-If file exists already, just return it. If PAGE-NAME is invalid,
-trigger a `user-error'.
+(defun hywiki-add-page-and-display (wikiword &optional prompt-flag)
+ "Display the HyWiki referent for WIKIWORD and return it.
+If there is no existing WIKIWORD referent, add a HyWiki page for it.
+See doc for `hywiki-find-referent' for use of optional prefix arg
+PROMPT-FLAG.
Use `hywiki-get-page' to determine whether a HyWiki page exists."
- (interactive (list (hywiki-read-new-page-name "Add and display HyWiki page:
")))
- (let ((page-file (hywiki-add-page page-name)))
- (if page-file
- (hywiki-find-page (file-name-base page-file))
- (user-error "(hywiki-add-page-and-display): Invalid page name: '%s';
must be capitalized, all alpha" page-name))))
-
-(defun hywiki-add-to-page (page-name text start-flag)
- "Add to PAGE-NAME TEXT at page start with START-FLAG non-nil, else end.
-Create page if it does not exist. If PAGE-NAME is invalid, return
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add and display HyWiki page: "))
+ current-prefix-arg))
+ (let* ((normalized-word (hywiki-get-singular-wikiword wikiword))
+ (referent (hywiki-find-referent normalized-word prompt-flag)))
+ (cond (referent)
+ ((and (null referent) (hywiki-word-is-p normalized-word))
+ (when (hywiki-add-page normalized-word)
+ (hywiki-display-page normalized-word)))
+ (t (user-error "(hywiki-add-page-and-display): Invalid HyWikiWord:
'%s'; must be capitalized, all alpha" wikiword)))))
+
+(defun hywiki-add-sexpression (wikiword)
+ "Make WIKIWORD evaluate a prompted for sexpression and return it.
+
+If WIKIWORD is invalid, trigger a `user-error' if called interactively
+or return nil if not.
+
+After successfully adding the sexpression, run `hywiki-add-referent-hook'.
+
+Use `hywiki-get-page' to determine whether WIKIWORD exists prior to
+calling this function."
+ (interactive (list (or (hywiki-word-at)
+ (hywiki-word-read-new "Add/Edit HyWikiWord: "))))
+ (hywiki-add-referent wikiword (read--expression "Sexpression: ")))
+
+(defun hywiki-add-to-referent (wikiword text position)
+ "Display WIKIWORD referent and insert TEXT at POSITION.
+Create page if it does not exist. If WIKIWORD is invalid, return
nil, else return the file name of the page."
- (let* ((page-file (hywiki-add-page page-name))
- (page-buf (when page-file (find-file-noselect page-file))))
- (when page-buf
+ (let* ((referent (hywiki-add-page wikiword)))
+ (when referent
+ (hywiki-find-referent wikiword)
+ (barf-if-buffer-read-only)
(save-excursion
- (with-current-buffer page-buf
- (barf-if-buffer-read-only)
- (save-restriction
- (widen)
- (goto-char (if start-flag (point-min) (point-max)))
- (unless (bolp) (insert (newline)))
- (insert text)
- (unless (bolp) (insert (newline)))
- (goto-char (if start-flag (point-min) (point-max)))
- page-file))))))
+ (save-restriction
+ (widen)
+ (when position
+ (goto-char position))
+ (unless (bolp)
+ (insert (newline)))
+ (insert text)
+ (unless (bolp)
+ (insert (newline)))
+ (when position
+ (goto-char position)))))
+ referent))
(defun hywiki-at-tags-p (&optional at-tag-flag)
"Return non-nil if point is in a HyWiki buffer and at Org tags."
@@ -695,7 +1103,7 @@ nil, else return the file name of the page."
;;;###autoload
(defun hywiki-consult-grep (&optional regexp max-matches path-list)
- "Interactively search `hywiki-directory' with a consult package grep command.
+ "Interactively search with a consult package grep command.
Search for optional REGEXP up to MAX-MATCHES in PATH-LIST or
`hywiki-directory'.
Use ripgrep (rg) if found, otherwise, plain grep. Initialize search with
@@ -739,102 +1147,6 @@ Use `hywiki-get-page' to determine whether a HyWiki page
exists."
(when (or (bolp) (cl-find (char-before) "\[\(\{\<\"'`\t\n\r\f "))
t))
-(defun hywiki-word-activate (&optional arg)
- "Display HyWiki page for wiki word at point, creating the page if needed.
-If found, return the full path of the page.
-
-If on a HyWikiWord without a wiki page, then prompt before creating
-the page.
-
-If not on a HyWikiWord and optional prefix ARG is null, emulate an
-Action Key press; with a prefix ARG, emulate an Assist Key press."
- (interactive "P")
- (let ((word (hywiki-word-at)))
- (if word
- (hywiki-find-page word t)
- (hkey-either arg))))
-
-(defun hywiki-word-at ()
- "Return HyWikiWord and optional #section at point or nil if not on one.
-Point must be prior to any whitespace character within #section.
-
-Return nil if the HyWikiWord is a prefixed, typed hy:HyWikiWord, since
-these are handled by the Org mode link handler.
-
-Do not test whether or not a page exists for the HyWiki word; call
-`hywiki-page-exists-p' without an argument for that.
-
-A call to `hywiki-active-in-current-buffer-p' at point must return non-nil
-or this will return nil."
- (when (hywiki-active-in-current-buffer-p)
- (if (setq hywiki--range
- (hproperty:char-property-range (point) 'face hywiki-word-face))
- (buffer-substring-no-properties (car hywiki--range) (cdr hywiki--range))
- (save-excursion
- (let ((wikiword (progn (when (looking-at "\\[\\[")
- (goto-char (+ (point) 2)))
- (hargs:delimited "[[" "]]"))))
- (if wikiword
- ;; Handle an Org link [[HyWikiWord]] [[hy:HyWikiWord]]
- ;; or [[HyWikiWord#section][Description Text]].
- (progn
- ;; Get the HyWikiWord link reference, ignoring any
- ;; description given in the link
- (setq wikiword (hywiki-strip-org-link wikiword))
- (if (string-match (concat "\\`" hywiki-org-link-type ":")
wikiword)
- ;; Ignore prefixed, typed hy:HyWikiWord since Org mode will
- ;; display those.
- nil
- ;; Don't use next line so don't have to load all of Org
- ;; mode just to check for HyWikiWords; however, disables
- ;; support for Org mode aliases.
- ;; (setq wikiword (org-link-expand-abbrev (org-link-unescape
(string-trim wikiword))))
- (when (hywiki-word-is-p wikiword)
- wikiword)))
- ;; Handle a HyWiki word with optional #section; if it is an Org
- ;; link, it may optionally have a hy: link-type prefix.
- ;; Ignore wikiwords preceded by any non-whitespace
- ;; character, except any of these: "([\"'`'"
- (let ((case-fold-search nil)
- start
- end)
- (skip-chars-backward "-_*#[:alnum:]")
- (when (hywiki-maybe-at-wikiword-beginning)
- (cond ((looking-at hywiki--word-and-buttonize-character-regexp)
- (setq start (match-beginning 0)
- end (match-beginning 3)
- wikiword (string-trim
- (buffer-substring-no-properties start
end))))
- ((looking-at (concat
hywiki-word-with-optional-section-regexp "\\'"))
- (setq start (match-beginning 0)
- end (match-end 0)
- ;; No following char
- wikiword (string-trim
- (buffer-substring-no-properties start
end)))))
- wikiword))))))))
-
-;;;###autoload
-(defun hywiki-word-consult-grep (word)
- "Use `hywiki-consult-grep' to show occurrences of a prompted for HyWikiWord.
-Default to any HyWikiWord at point."
- (interactive (list (hywiki-read-page-name)))
- (if (and (stringp word) (not (string-empty-p word)))
- (hywiki-consult-grep (concat "\\b" (regexp-quote word) "\\b"))
- (user-error "(hywiki-word-consult-grep): Invalid HyWikiWord: '%s'; must be
capitalized, all alpha" word)))
-
-(defun hywiki-word-is-p (word)
- "Return non-nil if WORD is a HyWiki word and optional #section.
-The page for the word may not yet exist. Use `hywiki-get-page'
-to determine whether a HyWiki word page exists.
-
-Return nil if WORD is a prefixed, typed hy:HyWikiWord, since
-these are handled by the Org mode link handler."
- (and (stringp word) (not (string-empty-p word))
- (let (case-fold-search)
- (or (string-match hywiki-word-with-optional-section-exact-regexp word)
- (eq (string-match (concat "\\`"
hywiki-word-with-optional-section-regexp "\\'") word)
- 0)))))
-
(defun hywiki-directory-edit ()
"Edit HyWiki pages in current `hywiki-directory'.
Use `dired' unless `action-key-modeline-buffer-id-function' is set to
@@ -895,6 +1207,37 @@ Use `dired' unless
`action-key-modeline-buffer-id-function' is set to
"Store the last page mod time for `hywiki-directory' as an integer."
(setq hywiki--directory-mod-time (hywiki-directory-get-mod-time)))
+;;;###autoload
+(defun hywiki-find-referent (&optional wikiword prompt-flag)
+ "Display optional HyWiki WIKIWORD referent or if nil, use current buffer.
+If called interactively, prompt for a new or existing WIKIWORD
+and use any prefix argument as PROMPT-FLAG.
+
+Return the referent if successfully found or nil otherwise.
+See `hywiki-referent-menu' for valid referent types.
+
+If the referent is a HyWiki page:
+ Return the absolute path to any page successfully found; nil
+ if failed or if displaying a regular file (read in via a
+ `find-file' call).
+
+ By default, create any non-existent page. When not in batch
+ mode, with optional PROMPT-FLAG t or if this is the first
+ HyWiki page in `hywiki-directory', prompt to create if
+ non-existent. If PROMPT-FLAG is :existing or with a prefix
+ argument when called interactively, return nil unless the
+ page already exists. After successfully finding a page and
+ reading it into a buffer, run `hywiki-display-referent-hook'.
+
+After successfully finding any kind of referent, run
+`hywiki-find-referent-hook'."
+ (interactive (list (hywiki-word-read-new "Add/Edit HyWikiWord: ")
+ (when current-prefix-arg t)))
+ (let ((referent (hywiki-display-referent wikiword prompt-flag)))
+ (run-hooks 'hywiki-find-referent-hook)
+
+ referent))
+
(defun hywiki-highlight-on-yank (_prop-value start end)
"Used in `yank-handled-properties' called with START and END pos of the text.
Have to add one character to the length of the yanked text so that any
@@ -960,6 +1303,13 @@ This includes the delimiters: (), {}, <>, [] and \"\"
(double quotes)."
(sort result #'<)
(list nil nil))))))
+;;;###autoload
+(defun hywiki-insert-link ()
+ "Insert at point a link to a HyWiki page."
+ (interactive "*")
+ (insert (hywiki-word-read "Link to HyWiki page: "))
+ (hywiki-maybe-highlight-page-name))
+
(defun hywiki-maybe-dehighlight-balanced-pairs ()
"Before or after a balanced delimiter, dehighlight HyWikiWords within.
Include: (), {}, <>, [] and \"\" (double quotes). Exclude Org links
@@ -1189,7 +1539,7 @@ If in a programming mode, must be within a comment. Use
(setq hywiki--page-name (match-string-no-properties 1)
hywiki--start (match-beginning 0)
hywiki--end (match-beginning 3))
- (and (hywiki-get-page hywiki--page-name)
+ (and (hywiki-get-referent hywiki--page-name)
;; Ignore wikiwords preceded by any non-whitespace
character
;; (or (bolp) (memq (preceding-char) '(?\ ?\t)))
)))
@@ -1264,7 +1614,7 @@ the current page unless they have sections attached."
hywiki--start (match-beginning 0)
;; This excludes optional char after the
page#section
hywiki--end (match-beginning 3))
- (hywiki-get-page hywiki--page-name)))
+ (hywiki-get-referent hywiki--page-name)))
(progn
(setq hywiki--current-page (hywiki-get-buffer-page-name))
;; Don't highlight current-page matches unless they
@@ -1519,7 +1869,8 @@ value of `hywiki-word-highlight-flag' is changed."
(hywiki-maybe-dehighlight-page-names region-start region-end))
(unless (hyperb:stack-frame '(hywiki-maybe-highlight-page-names-in-frame))
(hywiki-directory-set-mod-time)
- (hywiki-directory-set-checksum)))
+ (hywiki-directory-set-checksum))
+ nil)
(defun hywiki-maybe-highlight-page-names-in-frame (frame &optional
skip-lookups-update-flag)
"Highlight all non-Org link HyWiki page names displayed in FRAME.
@@ -1563,8 +1914,8 @@ value returns nil."
(unless (or (null file-stem-name) (string-empty-p file-stem-name))
;; Remove any #section from `file-stem-name' and make it singular
(setq file-stem-name
- (hywiki-get-singular-page-name
- (if (string-match "#" file-stem-name)
+ (hywiki-get-singular-wikiword
+ (if (string-match "#[^#]+$" file-stem-name)
(substring file-stem-name 0 (match-beginning 0))
file-stem-name)))
(if (string-suffix-p hywiki-file-suffix file-stem-name)
@@ -1572,24 +1923,43 @@ value returns nil."
(concat (expand-file-name
file-stem-name hywiki-directory) hywiki-file-suffix))))
-(defun hywiki-get-page (page-name)
- "Return the absolute path of HyWiki PAGE-NAME or nil if it does not exist."
- (when (and (stringp page-name) (not (string-empty-p page-name))
- (string-match hywiki-word-with-optional-section-exact-regexp
page-name))
- (when (match-string-no-properties 2 page-name)
- ;; Remove any #section suffix in PAGE-NAME.
- (setq page-name (match-string-no-properties 1 page-name)))
-
- (let ((relative-page-file
- (or (hash-get page-name (hywiki-get-page-hasht))
- ;; Handle typical pluralized words ending in 's' (not preceded
- ;; by an 's') or 'es'
- (when (string-match "[eE][sS]$" page-name)
- (hash-get (substring page-name 0 -2) (hywiki-get-page-hasht)))
- (when (string-match ".[^eEsS]s$" page-name)
- (hash-get (substring page-name 0 -1)
(hywiki-get-page-hasht))))))
- (when (stringp relative-page-file)
- (expand-file-name relative-page-file hywiki-directory)))))
+(defun hywiki-get-referent (wikiword)
+ "Return the referent of HyWiki WIKIWORD or nil if it does not exist.
+If it is a pathname, expand it relative to `hywiki-directory'."
+ (when (and (stringp wikiword) (not (string-empty-p wikiword))
+ (string-match hywiki-word-with-optional-section-exact-regexp
wikiword))
+ (let* ((section (when (match-string-no-properties 2 wikiword)
+ (prog1 (substring wikiword (match-beginning 2))
+ ;; Remove any #section suffix in `wikiword'.
+ (setq wikiword (match-string-no-properties 1
wikiword)))))
+ (referent (hash-get (hywiki-get-singular-wikiword wikiword)
+ (hywiki-get-page-hasht))))
+ (cond ((or (symbolp referent) (functionp referent)
+ (and (consp referent)
+ (symbolp (car referent))
+ (fboundp (car referent))))
+ ;; function or actype symbol
+ ;; e.g. (kbd "key sequence")
+ referent)
+ ((stringp referent)
+ (let ((case-fold-search t))
+ (cond ((and (null referent) (stringp section)
+ (string-match-p "^\\(#[^#]+\\)$" section))
+ ;; "#in-buffer-section"
+ section)
+ ((string-match-p "^\\({.+}\\|\\(CUSTOM_\\)?ID:[
\t]+.+\\|<\\[.+\\]>\\|<(.+)>\\)$"
+ referent)
+ ;; "{key series}"
+ ;; "ID: org-id"
+ ;; "<(global explicit button name)>"
+ ;; "<[global implicit button name]>"
+ referent)
+ ((string-match-p "^(.+).+$\\|.+\\.info\\([.#]\\|$\\)"
referent)
+ ;; (info-manual)node-or-index-item
+ referent)
+ ;; path, expand to absolute
+ (t (hywiki-get-file referent)))))
+ (t nil)))))
(defun hywiki-get-page-files ()
"Return the list of existing HyWiki page file names.
@@ -1619,8 +1989,8 @@ regexps of page names."
(mapcar (lambda (page-sublist)
;; Add plurals to the list
(setq page-sublist
- (nconc page-sublist
- (mapcar #'hywiki-get-plural-page-name
page-sublist)))
+ (delq nil (nconc page-sublist
+ (mapcar #'hywiki-get-plural-wikiword
page-sublist))))
(concat (regexp-opt page-sublist 'words)
"\\("
hywiki-word-section-regexp "?\\)"
@@ -1634,35 +2004,46 @@ regexps of page names."
"Return a list of the HyWiki page names."
(hash-map #'cdr (hywiki-get-page-hasht)))
-(defun hywiki-get-plural-page-name (page-name)
- "Return the pluralized version of the given PAGE-NAME."
+(defun hywiki-get-wikiwords-obarray ()
+ "Return an obarray of existing HyWikiWords."
+ (cdr (hywiki-get-page-hasht)))
+
+(defun hywiki-get-plural-wikiword (wikiword)
+ "Return the pluralized version of the given WIKIWORD.
+`hywiki-allow-plurals-flag' must be non-nil or nil is always returned."
;; You add "-es" to make a noun plural when the singular noun ends
;; in "s", "x", "z", "sh", or "ch". However, there are some
;; exceptions to this rule, such as words ending in "-ch" that are
;; pronounced with a hard "k", like "monarchs" and "stomachs".
- (cond ((let ((case-fold-search t))
- (string-match-p "\\(es\\|.[^es]s\\)$" page-name))
- ;; Already plural
- page-name)
- ((let ((case-fold-search t))
- (string-match-p "\\(ch\\|sh\\|[sxz]\\)$" page-name))
- (concat page-name (if (string-match-p "[[:lower:]]" page-name)
- "es"
- "ES")))
- (t (concat page-name (if (string-match-p "[[:lower:]]" page-name)
- "s"
- "S")))))
-
-(defun hywiki-get-singular-page-name (page-name)
- "Return the singular version of the given PAGE-NAME."
- (or (when (let ((case-fold-search t))
- (string-match-p "\\(ch\\|sh\\|[sxz]\\)es$" page-name))
- (substring page-name 0 -2))
- (when (let ((case-fold-search t))
- (and (string-match-p ".[^s]s$" page-name)
- (not (string-match-p "emacs$" page-name))))
- (substring page-name 0 -1))
- page-name))
+ (when hywiki-allow-plurals-flag
+ (cond ((let ((case-fold-search t))
+ (string-match-p "\\(es\\|.[^es]s\\)$" wikiword))
+ ;; Already plural
+ wikiword)
+ ((let ((case-fold-search t))
+ (string-match-p "\\(ch\\|sh\\|[sxz]\\)$" wikiword))
+ (concat wikiword (if (string-match-p "[[:lower:]]" wikiword)
+ "es"
+ "ES")))
+ (t (concat wikiword (if (string-match-p "[[:lower:]]" wikiword)
+ "s"
+ "S"))))))
+
+(defun hywiki-get-singular-wikiword (wikiword)
+ "Return the singular version of the given WIKIWORD.
+If `hywiki-allow-plurals-flag' is nil, return WIKIWORD unchanged."
+ (if (and hywiki-allow-plurals-flag (stringp wikiword))
+ (or (when (let ((case-fold-search t))
+ ;; Handle typical pluralized words ending in 's' (not preceded
+ ;; by an 's') or 'es'
+ (string-match-p "\\(ch\\|sh\\|[sxz]\\)es$" wikiword))
+ (substring wikiword 0 -2))
+ (when (let ((case-fold-search t))
+ (and (string-match-p ".[^eEsS]s$" wikiword)
+ (not (string-match-p "emacs$" wikiword))))
+ (substring wikiword 0 -1))
+ wikiword)
+ wikiword))
(defun hywiki-kill-buffer-hook ()
"Delete file attached to HyWiki buffer if the file is zero-sized.
@@ -1676,14 +2057,13 @@ If deleted, update HyWikiWord highlighting across all
frames."
t)
nil))
-(defun hywiki-make-pages-hasht ()
- (let* ((page-files (hywiki-get-page-files))
- (page-elts (mapcar (lambda (file)
- (cons file (file-name-sans-extension file)))
- page-files)))
- (setq hywiki--any-page-regexp-list nil
- hywiki--pages-directory hywiki-directory
- hywiki--pages-hasht (hash-make page-elts))))
+(defun hywiki-clear-pages-hasht ()
+ "Clear all elements from the HyWiki referent hash table and return it."
+ (if (hashp hywiki--pages-hasht)
+ (progn (hash-map (lambda (key) (hash-delete key hywiki--pages-hasht))
+ (hash-map #'cdr hywiki--pages-hasht))
+ hywiki--pages-hasht)
+ (hash-make (length (hywiki-get-page-files)))))
(eval-and-compile
'(when (featurep 'company)
@@ -1702,6 +2082,32 @@ If deleted, update HyWikiWord highlighting across all
frames."
collect key))))
('sorted t))))))
+(defun hywiki-make-pages-hasht ()
+ (let* ((page-files (hywiki-get-page-files))
+ (non-page-elts (when (hashp hywiki--pages-hasht)
+ (delq nil
+ (hash-map #''hywiki-non-page-elts
+ hywiki--pages-hasht))))
+ (non-page-hasht (hash-make non-page-elts))
+ (key)
+ (page-elts (delq nil (mapcar (lambda (file)
+ (setq key (file-name-sans-extension
file))
+ (unless (hash-get key non-page-hasht)
+ (cons file key)))
+ page-files))))
+ (setq hywiki--any-page-regexp-list nil
+ hywiki--pages-directory hywiki-directory
+ hywiki--pages-hasht (hash-merge (hash-make non-page-elts)
+ (hash-make page-elts)))))
+
+(defun hywiki-non-page-elts (val-key)
+ (let ((suffix-regexp (concat (regexp-quote hywiki-file-suffix) "$"))
+ value)
+ (setq value (car val-key))
+ (unless (and (stringp value)
+ (string-match-p suffix-regexp value))
+ val-key)))
+
(defun hywiki-org-export-function (&rest _)
"Add to `write-contents-functions' to convert HyWikiWord links to Org links.
This is done automatically by loading HyWiki."
@@ -1730,7 +2136,7 @@ If not found, set it up and return the new project
properties."
(concat
(when hywiki-org-link-type-required
(concat hywiki-org-link-type ":"))
- (hywiki-read-page-name)))
+ (hywiki-word-read)))
;;; Next two functions derived from the denote package.
;;;###autoload
@@ -1777,7 +2183,7 @@ word section). If page is not found, return nil."
(word (if (and section (not (string-empty-p section)))
(substring link 0 (match-beginning 0))
link))
- (path (and word (hywiki-get-page word))))
+ (path (and word (hywiki-get-referent word))))
(when path
(cond
(full-data
@@ -1825,47 +2231,9 @@ variables."
'(org-link-set-parameters hywiki-org-link-type
:complete #'hywiki-org-link-complete
:export #'hywiki-org-link-export
- :follow #'hywiki-find-page
+ :follow #'hywiki-find-referent
:store #'hywiki-org-link-store))
-(defun hywiki-page-exists-p (&optional word start end)
- "Return an existing HyWiki page name from optional WORD or word at point.
-Word may be of form: HyWikiWord#section with an optional #section.
-If no such page exists, return nil.
-
-If WORD is the symbol, :range, and there is a HyWikiWord at point
-with an existing page, then return the tuple of values: (word
-word-start word-end) instead of a string,
-
-When using the word at point, a call to
-`hywiki-active-in-current-buffer-p' at point must return non-nil
-or this will return nil."
- (setq hywiki--page-name word
- word (hywiki-strip-org-link word))
- (if (or (stringp word)
- (setq word (hywiki-word-at)))
- (unless (hywiki-get-page (hywiki-page-strip-section word))
- (setq word nil))
- (setq word nil))
- (when (and (listp word) (= (length word) 3))
- (setq start (nth 1 word)
- end (nth 2 word)
- word (nth 0 word)))
- (if (eq hywiki--page-name :range)
- (if (and word (setq hywiki--range
- (hproperty:char-property-range
- (point) 'face hywiki-word-face)))
- (list word (or start (car hywiki--range)) (or end (cdr
hywiki--range)))
- (list word start end))
- word))
-
-(defun hywiki-strip-org-link (link-str)
- "Return the hy:HyWikiWord#section part of an Org link string.
-Strip any square bracket delimiters, any description and leading or
-trailing whitespace."
- (when (and (stringp link-str) (not (string-empty-p link-str)))
- (string-trim (car (delete "" (split-string link-str
"\\[\\[\\|\\]\\[\\|\\]\\]"))))))
-
(defun hywiki-page-strip-section (page-name)
"Return PAGE-NAME with any optional #section stripped off.
If an empty string or not a string, return nil."
@@ -1889,18 +2257,52 @@ Customize this directory with:
(interactive "P")
(org-publish-project "hywiki" all-pages-flag))
-(defun hywiki-read-new-page-name (&optional prompt)
- "Prompt with completion for and return a new HyWiki page name."
- (let ((completion-ignore-case t))
- (completing-read (if (stringp prompt) prompt "HyWiki Page Name: ")
- (hywiki-get-page-list))))
+(defun hywiki-referent-exists-p (&optional word start end)
+ "Return an optional HyWiki WORD or word at point, if has an existing
referent.
+If no such referent exists, return nil.
-(defun hywiki-read-page-name (&optional prompt)
- "Prompt with completion for and return an existing HyWiki page name.
-If on a page name, immediately pressing RET will use that name as the default."
- (let ((completion-ignore-case t))
- (completing-read (if (stringp prompt) prompt "HyWiki Page Name: ")
- (hywiki-get-page-list) nil t nil nil (hywiki-word-at))))
+Word may be of form:
+ 1. HyWikiWord#section with an optional #section.
+ 2. If WORD is the symbol, :range, and there is a HyWikiWord at point
+ with an existing referent, return the tuple of values: (word
+ word-start word-end) instead of the word.
+
+When using the word at point, a call to `hywiki-active-in-current-buffer-p'
+at point must return non-nil or this function will return nil."
+ (setq hywiki--page-name word
+ word (hywiki-strip-org-link word))
+ (if (or (stringp word)
+ (setq word (hywiki-word-at)))
+ (unless (hywiki-get-referent
+ (hywiki-get-singular-wikiword
+ (hywiki-page-strip-section word)))
+ (setq word nil))
+ (setq word nil))
+ (when (and (listp word) (= (length word) 3))
+ (setq start (nth 1 word)
+ end (nth 2 word)
+ word (nth 0 word)))
+ (if (eq hywiki--page-name :range)
+ (if (and word (setq hywiki--range
+ (hproperty:char-property-range
+ (point) 'face hywiki-word-face)))
+ (list word (or start (car hywiki--range)) (or end (cdr
hywiki--range)))
+ (list word start end))
+ word))
+
+(defun hywiki-strip-org-link (link-str)
+ "Return the hy:HyWikiWord#section part of an Org link string.
+Strip any square bracket delimiters, description and leading or
+trailing whitespace, and type prefix. Return nil, if no match."
+ (when (and (stringp link-str) (not (string-empty-p link-str)))
+ (string-remove-prefix
+ (concat hywiki-org-link-type ":")
+ (let ((blank "[[:blank:]\r\n]+"))
+ (string-trim (car (delete ""
+ (mapcar (lambda (str)
+ (string-trim
(replace-regexp-in-string blank " " str t t)
+ blank blank))
+ (split-string link-str
"\\[\\[\\|\\]\\[\\|\\]\\]")))))))))
;;;###autoload
(defun hywiki-tags-view (&optional todo-only match view-buffer-name)
@@ -1930,6 +2332,143 @@ optional VIEW-BUFFER-NAME, use that rather than the
default,
,org-agenda-buffer-name)))
(forward-line 2))))
+(defun hywiki-word-activate (&optional arg)
+ "Display HyWiki referent for wikiword at point.
+If referent is a non-existent HyWiki page, create it. When this
+is the first HyWiki page, prompt before creating in case this is
+not what was intended.
+
+If found, return the referent.
+
+If not on a HyWikiWord and optional prefix ARG is null, emulate an
+Action Key press; with a prefix ARG, emulate an Assist Key press."
+ (interactive "P")
+ (let ((word (hywiki-word-at)))
+ (if word
+ (hywiki-find-referent word)
+ (hkey-either arg))))
+
+(defun hywiki-word-at (&optional range-flag)
+ "Return HyWikiWord and optional #section at point or nil if not on one.
+Point must be prior to any whitespace character within #section.
+With optional RANGE-FLAG, return a list of (HyWikiWord start-position
+end-position); the positions are for only the HyWikiWord itself.
+
+Do not test whether or not a page exists for the HyWiki word; call
+`hywiki-referent-exists-p' without an argument for that.
+
+A call to `hywiki-active-in-current-buffer-p' at point must return non-nil
+or this will return nil."
+ (when (hywiki-active-in-current-buffer-p)
+ (if (setq hywiki--range
+ (hproperty:char-property-range (point) 'face hywiki-word-face))
+ (buffer-substring-no-properties (car hywiki--range) (cdr hywiki--range))
+ (save-excursion
+ ;; Don't use `cl-destructuring-bind' here since the `hargs:delimited'
call
+ ;; can return nil rather than the 3 arg list that would be required
+ (let* ((wikiword-start-end
+ (let ((start-regexp (concat "\\[\\[\\(" hywiki-org-link-type
":\\)?")))
+ (save-excursion
+ (skip-chars-backward (concat hywiki-org-link-type ":["))
+ (when (looking-at start-regexp)
+ (goto-char (match-end 0)))
+ (hargs:delimited (concat "\\[\\[\\(" hywiki-org-link-type
":\\)?")
+ "\\(\\]\\[\\|\\]\\]\\)" t t t))))
+ (wikiword (nth 0 wikiword-start-end))
+ (start (nth 1 wikiword-start-end))
+ (end (nth 2 wikiword-start-end)))
+ (when (if wikiword
+ ;; Handle an Org link [[HyWikiWord]] [[hy:HyWikiWord]]
+ ;; or [[HyWikiWord#section][Description Text]].
+ ;; Get the HyWikiWord link reference, ignoring any
+ ;; description given in the link
+ ;; Don't use next line so don't have to load all of Org
+ ;; mode just to check for HyWikiWords; however, disables
+ ;; support for Org mode aliases.
+ ;; (setq wikiword (org-link-expand-abbrev
(org-link-unescape (string-trim wikiword))))
+ (progn
+ (setq wikiword (hywiki-strip-org-link wikiword))
+ (when (and wikiword end)
+ ;; Update start and end to newly stripped
+ ;; string positions
+ (save-excursion
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (when (search-forward wikiword nil t)
+ (setq start (match-beginning 0)
+ end (match-end 0))))))
+ (hywiki-word-is-p wikiword))
+ ;; Handle a non-delimited HyWiki word with optional #section;
+ ;; if it is an Org link, it may optionally have a hy:
+ ;; link-type prefix. Ignore wikiwords preceded by any
+ ;; non-whitespace character, except any of these:
+ ;; "([\"'`'"
+ (let ((case-fold-search nil))
+ (skip-chars-backward "-_*#[:alnum:]")
+ (when (hywiki-maybe-at-wikiword-beginning)
+ (cond ((looking-at
hywiki--word-and-buttonize-character-regexp)
+ (setq start (match-beginning 0)
+ end (match-beginning 3)
+ wikiword (string-trim
+ (buffer-substring-no-properties
start end))))
+ ((looking-at (concat
hywiki-word-with-optional-section-regexp "\\'"))
+ (setq start (match-beginning 0)
+ end (match-end 0)
+ ;; No following char
+ wikiword (string-trim
+ (buffer-substring-no-properties
start end))))))))
+ (if range-flag
+ (list wikiword start end)
+ wikiword)))))))
+
+;;;###autoload
+(defun hywiki-word-consult-grep (word)
+ "Use `hywiki-consult-grep' to show occurrences of a prompted for HyWikiWord.
+Default to any HyWikiWord at point."
+ (interactive (list (hywiki-word-read)))
+ (if (and (stringp word) (not (string-empty-p word)))
+ (hywiki-consult-grep (concat "\\b" (regexp-quote word) "\\b"))
+ (user-error "(hywiki-word-consult-grep): Invalid HyWikiWord: '%s'; must be
capitalized, all alpha" word)))
+
+(defun hywiki-word-grep (wikiword)
+ "Grep for occurrences of WIKIWORD with `consult-grep' or normal-grep'.
+Search across `hywiki-directory'."
+ (if (fboundp 'consult-grep) ;; allow for autoloading
+ (hywiki-word-consult-grep wikiword)
+ (grep (string-join (list grep-command (format "'%s'" wikiword)
+ (concat (file-name-as-directory hywiki-directory)
+ "*" hywiki-file-suffix))
+ " "))))
+
+(defun hywiki-word-is-p (word)
+ "Return non-nil if WORD is a HyWiki word and optional #section.
+The page for the word may not yet exist. Use `hywiki-get-page'
+to determine whether a HyWiki word page exists.
+
+Return nil if WORD is a prefixed, typed hy:HyWikiWord, since
+these are handled by the Org mode link handler."
+ (and (stringp word) (not (string-empty-p word))
+ (let (case-fold-search)
+ (or (string-match hywiki-word-with-optional-section-exact-regexp word)
+ (eq (string-match (concat "\\`"
hywiki-word-with-optional-section-regexp "\\'") word)
+ 0)))))
+
+(defun hywiki-word-read-new (&optional prompt)
+ "Prompt with completion for and return a new HyWiki page name."
+ (let ((completion-ignore-case t))
+ (completing-read (if (stringp prompt) prompt "HyWikiWord: ")
+ (hywiki-get-wikiwords-obarray)
+ nil nil nil nil (hywiki-word-at))))
+
+(defun hywiki-word-read (&optional prompt)
+ "Prompt with completion for and return an existing HyWiki page name.
+If on a page name, immediately pressing RET will use that name as the default."
+ (let ((completion-ignore-case t))
+ (completing-read (if (stringp prompt) prompt "HyWikiWord: ")
+ (hywiki-get-wikiwords-obarray)
+ nil t nil nil (hywiki-word-at))))
+
(defun hywiki-word-highlight-flag-changed (symbol set-to-value operation
_where)
"Watch function for variable ``hywiki-word-highlight-flag'.
Function is called with 4 arguments: (SYMBOL SET-TO-VALUE OPERATION WHERE).
diff --git a/test/hbut-tests.el b/test/hbut-tests.el
index 2e8e5caefa..cfdb987113 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: 14-Apr-24 at 21:52:52 by Mats Lidell
+;; Last-Mod: 16-Dec-24 at 00:55:21 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -26,10 +26,10 @@
(require 'hy-test-helpers "test/hy-test-helpers")
(defun hbut-tests:should-match-tmp-folder (tmp)
- "Check that TMP matches either 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 (and (stringp tmp) (string-match-p
"\"?\\(/\\|./\\|/private/\\)tmp\"?\\'" tmp) t)))
+/tmp/ can be a symbolic link."
+ (should (and (stringp tmp) (string-match-p
"\"?\\(/\\|./\\|/private/\\)tmp/\"?\\'" tmp) t)))
(ert-deftest ebut-program-link-to-directory ()
"Programatically create ebut with link-to-directory using
`temporary-file-directory`."
@@ -75,7 +75,7 @@ Create button with link-to-directory using
`temporary-file-directory`."
(unwind-protect
(progn
(find-file file)
- (ebut:program "label" 'link-to-directory "/tmp")
+ (ebut:program "label" 'link-to-directory "/tmp/")
(should (hbut:at-p))
(should (hui:hbut-delete))
(should-not (hbut:at-p)))
@@ -84,7 +84,7 @@ Create button with link-to-directory using
`temporary-file-directory`."
(ert-deftest ebut-delete-removes-ebut-in-non-file-buffer ()
"Remove an ebut from non file buffer."
(with-temp-buffer
- (ebut:program "label" 'link-to-directory "/tmp")
+ (ebut:program "label" 'link-to-directory "/tmp/")
(should (hbut:at-p))
(should (hui:hbut-delete))
(should-not (hbut:at-p))))
@@ -93,7 +93,7 @@ Create button with link-to-directory using
`temporary-file-directory`."
"Remove an ebut from `message-mode' buffer."
(with-temp-buffer
(message-mode)
- (ebut:program "label" 'link-to-directory "/tmp")
+ (ebut:program "label" 'link-to-directory "/tmp/")
(should (hbut:at-p))
(should (hui:hbut-delete))
(should-not (hbut:at-p))))
@@ -105,8 +105,8 @@ Create button with link-to-directory using
`temporary-file-directory`."
(unwind-protect
(with-mock
(mock (hpath:find-noselect (expand-file-name hbmap:filename
hbmap:dir-user)) => test-buffer)
- (mock (ebut:program "label" 'link-to-directory "/tmp") => t)
- (gbut:ebut-program "label" 'link-to-directory "/tmp"))
+ (mock (ebut:program "label" 'link-to-directory "/tmp/") => t)
+ (gbut:ebut-program "label" 'link-to-directory "/tmp/"))
(hy-delete-file-and-buffer test-file))))
(ert-deftest gbut-program-link-to-directory ()
@@ -117,7 +117,7 @@ Create button with link-to-directory using
`temporary-file-directory`."
(progn
(with-mock
(mock (hpath:find-noselect (expand-file-name hbmap:filename
hbmap:dir-user)) => test-buffer)
- (gbut:ebut-program "global" 'link-to-directory "/tmp"))
+ (gbut:ebut-program "global" 'link-to-directory "/tmp/"))
(with-current-buffer test-buffer
(should (eq (hattr:get (hbut:at-p) 'actype)
'actypes::link-to-directory))
(hbut-tests:should-match-tmp-folder (car (hattr:get (hbut:at-p)
'args)))
@@ -181,7 +181,7 @@ Create button with link-to-directory using
`temporary-file-directory`."
(ert-deftest hypb:program-create-ebut-in-buffer ()
"Create button with hypb:program in buffer."
(with-temp-buffer
- (ebut:program "label" 'link-to-directory "/tmp")
+ (ebut:program "label" 'link-to-directory "/tmp/")
(should (eq (hattr:get (hbut:at-p) 'actype) 'actypes::link-to-directory))
(hbut-tests:should-match-tmp-folder (car (hattr:get (hbut:at-p) 'args)))
(should (equal (hattr:get (hbut:at-p) 'lbl-key) "label"))))
@@ -189,10 +189,10 @@ Create button with link-to-directory using
`temporary-file-directory`."
(ert-deftest hypb:program-create-ebut-in-buffer-with-same-label ()
"Create button with same label shall add number so it is unique."
(with-temp-buffer
- (ebut:program "label" 'link-to-directory "/tmp")
+ (ebut:program "label" 'link-to-directory "/tmp/")
(should (equal (hattr:get (hbut:at-p) 'lbl-key) "label"))
(goto-char (point-max))
- (ebut:program "label" 'link-to-directory "/tmp")
+ (ebut:program "label" 'link-to-directory "/tmp/")
(goto-char (- (point-max) 2))
(should (equal (hattr:get (hbut:at-p) 'lbl-key) "label:2"))))
@@ -218,8 +218,8 @@ Create button with link-to-directory using
`temporary-file-directory`."
(ert-deftest hbut-tests-ibut-program-link-to-directory ()
"Programmatically create ibut link-to-directory."
(with-temp-buffer
- (ibut:program "name" 'link-to-directory "/tmp")
- (should (string= "<[name]> - \"/tmp\"" (buffer-string)))))
+ (ibut:program "name" 'link-to-directory "/tmp/")
+ (should (string= "<[name]> - \"/tmp/\"" (buffer-string)))))
(ert-deftest hbut-tests-ibut-program-link-to-file ()
"Programatically create ibut link to file."
@@ -235,14 +235,15 @@ Create button with link-to-directory using
`temporary-file-directory`."
(ert-deftest hbut-tests-ibut-insert-text-link-to-dir ()
"Insert link to dir."
(with-temp-buffer
- (ibut:program "name" 'link-to-directory "/tmp")
- (should (string= "<[name]> - \"/tmp\"" (buffer-string)))
+ (ibut:program "name" 'link-to-directory "/tmp/")
+ (should (string= "<[name]> - \"/tmp/\"" (buffer-string)))
(goto-char 3)
(let ((but (ibut:at-p)))
+ (should but)
(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)))))))
+ ;; 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."
@@ -374,7 +375,7 @@ Create button with link-to-directory using
`temporary-file-directory`."
(with-temp-buffer
;; Create in-buffer and in-memory ibut
(let (buf-str)
- (insert "/tmp")
+ (insert "/tmp/")
(goto-char 2)
(should (hbut:at-p))
(should (eq (hattr:get 'hbut:current 'actype) 'actypes::link-to-file))
@@ -399,7 +400,7 @@ See #10 for the proper way to add an ibutton name.
(with-temp-buffer
;; Create in-buffer and in-memory ibut
(let (buf-str)
- (insert "/tmp")
+ (insert "/tmp/")
(goto-char 2)
(should (hbut:at-p))
;; Test that ibut:operate errors and leaves in-buffer button unchanged
@@ -419,7 +420,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[name]> - /tmp")
+ (let ((ibut-str "<[name]> - /tmp/")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -443,7 +444,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[name]> - /tmp")
+ (let ((ibut-str "<[name]> - /tmp/")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -466,7 +467,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[name]> - \"/tmp\"")
+ (let ((ibut-str "<[name]> - \"/tmp/\"")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -493,7 +494,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[name]> - /tmp")
+ (let ((ibut-str "<[name]> - /tmp/")
buf-str)
(insert ibut-str "\nabcd")
(mark-whole-buffer)
@@ -518,7 +519,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "region - /tmp")
+ (let ((ibut-str "region - /tmp/")
buf-str)
(insert ibut-str)
(goto-char (point-min))
@@ -541,7 +542,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[abcd]> - \"/tmp\"")
+ (let ((ibut-str "<[abcd]> - \"/tmp/\"")
buf-str)
(insert ibut-str)
(mark-whole-buffer)
@@ -566,7 +567,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[name]> - \"/tmp\"")
+ (let ((ibut-str "<[name]> - \"/tmp/\"")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -590,7 +591,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "/tmp")
+ (let ((ibut-str "/tmp/")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -615,7 +616,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "\"/tmp\"")
+ (let ((ibut-str "\"/tmp/\"")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -640,7 +641,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
;; Create in-buffer and in-memory ibut
- (let ((ibut-str "<[name]> - \"/tmp\"")
+ (let ((ibut-str "<[name]> - \"/tmp/\"")
buf-str)
(insert ibut-str)
(goto-char 2)
@@ -664,7 +665,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
(let (buf-str)
- (insert "<[name]> - /tmp")
+ (insert "<[name]> - /tmp/")
(goto-char 2)
(should (hbut:at-p))
(set-mark (point-max))
@@ -685,7 +686,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
(let (buf-str)
- (insert "<[name]> - /tmp")
+ (insert "<[name]> - /tmp/")
(goto-char 2)
(should (hbut:at-p))
(set-mark (point-max))
@@ -706,7 +707,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
(let (buf-str)
- (insert "/tmp")
+ (insert "/tmp/")
(goto-char 2)
(should (hbut:at-p))
(set-mark (point-max))
@@ -727,7 +728,7 @@ See #10 for the proper way to add an ibutton name.
(hattr:clear 'hbut:current)
(with-temp-buffer
(let (buf-str)
- (insert "/tmp")
+ (insert "/tmp/")
(goto-char 2)
(should (hbut:at-p))
(set-mark (point-max))
diff --git a/test/hy-test-helpers.el b/test/hy-test-helpers.el
index 4f36f3c99e..a0f64a0920 100644
--- a/test/hy-test-helpers.el
+++ b/test/hy-test-helpers.el
@@ -3,7 +3,7 @@
;; Author: Mats Lidell <matsl@gnu.org>
;;
;; Orig-Date: 30-Jan-21 at 12:00:00
-;; Last-Mod: 6-Aug-24 at 00:09:45 by Mats Lidell
+;; Last-Mod: 15-Dec-24 at 14:24:42 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -72,12 +72,12 @@
(cl-defun hy-test-helpers-verify-hattr-at-p (&key actype args loc lbl-key name)
"Verify the attribute of hbut at point.
Checks ACTYPE, ARGS, LOC, LBL-KEY and NAME."
- (let ((hbut-at-p (hbut:at-p)))
- (should (eq (hattr:get hbut-at-p 'actype) actype))
- (should (equal (hattr:get hbut-at-p 'args) args))
- (should (equal (hattr:get hbut-at-p 'loc) loc))
- (should (equal (hattr:get hbut-at-p 'lbl-key) lbl-key))
- (should (equal (hattr:get hbut-at-p 'name) name))))
+ (hbut:at-p)
+ (should (eq (hattr:get 'hbut:current 'actype) actype))
+ (should (equal (hattr:get 'hbut:current 'args) args))
+ (should (equal (hattr:get 'hbut:current 'loc) loc))
+ (should (equal (hattr:get 'hbut:current 'lbl-key) lbl-key))
+ (should (equal (hattr:get 'hbut:current 'name) name)))
(defun hy-delete-file-and-buffer (file)
"Delete FILE and buffer visiting file."
diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el
index 1c972d0a0e..9d9020b6ad 100644
--- a/test/hywiki-tests.el
+++ b/test/hywiki-tests.el
@@ -3,7 +3,7 @@
;; Author: Mats Lidell
;;
;; Orig-Date: 18-May-24 at 23:59:48
-;; Last-Mod: 17-Nov-24 at 12:53:21 by Bob Weiner
+;; Last-Mod: 16-Dec-24 at 00:07:45 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -36,7 +36,7 @@
(with-mock
(not-called hywiki-add-page)
(should (string= hywiki-page-file
- (hywiki-get-page "WikiWord")))))
+ (hywiki-get-referent "WikiWord")))))
(hy-delete-file-and-buffer hywiki-page-file)
(hy-delete-dir-and-buffer hywiki-directory))))
@@ -51,21 +51,36 @@
(should-not (hywiki-add-page "notawikiword"))
(hy-delete-dir-and-buffer hywiki-directory))))
-(ert-deftest hywiki-tests--wikiword-with-prefix-creates-a-new-page ()
+(ert-deftest hywiki-tests--action-key-on-wikiword-displays-page ()
"Verify `action-key' on a prefixed WikiWord, outside of hywiki-directory,
creates a new page."
(defvar wikifile)
(let ((hsys-org-enable-smart-keys t)
(hywiki-directory (make-temp-file "hywiki" t))
- (wikifile (make-temp-file "wikifile")))
- (hywiki-mode -1)
+ (wikifile (make-temp-file "wikifile" nil ".org")))
(unwind-protect
(with-temp-buffer
+ (hywiki-mode 1)
(insert "[[hy:WikiWord]]")
(goto-char 4)
- (mocklet (((hywiki-add-page "WikiWord" nil) => wikifile))
+ (mocklet (((hywiki-display-referent "WikiWord" nil) => wikifile))
(action-key)))
(hy-delete-file-and-buffer wikifile))))
+(ert-deftest hywiki-tests--assist-key-on-wikiword-displays-help ()
+ "Verify `assist-key' on a prefixed WikiWord, outside of hywiki-directory,
displays help for the WikiWord link."
+ (defvar wikifile)
+ (let ((hsys-org-enable-smart-keys t)
+ (hywiki-directory (make-temp-file "hywiki" t))
+ (wikifile (make-temp-file "wikifile" nil ".org")))
+ (unwind-protect
+ (with-temp-buffer
+ (hywiki-mode 1)
+ (insert "[[hy:WikiWord]]")
+ (goto-char 4)
+ (should (string= "WikiWord" (hywiki-word-at)))
+ (assist-key))
+ (hy-delete-file-and-buffer wikifile))))
+
(ert-deftest hywiki-tests--not-a-wikiword-unless-in-hywiki-mode ()
"Verify WikiWord is not a WikiWord unless in `hywiki-mode'."
(let ((hsys-org-enable-smart-keys t)
@@ -152,8 +167,9 @@
(should-not (hywiki-active-in-current-buffer-p)))
(let ((hywiki-exclude-major-modes (list 'org-mode)))
(should-not (hywiki-active-in-current-buffer-p)))
- (mocklet ((hywiki-in-page-p => nil))
- (should-not (hywiki-active-in-current-buffer-p)))
+ (let (hywiki-mode)
+ (mocklet ((hywiki-in-page-p => nil))
+ (should-not (hywiki-active-in-current-buffer-p))))
(dired-mode)
(should-not (hywiki-active-in-current-buffer-p)))
(hy-delete-file-and-buffer wiki-page)
@@ -244,7 +260,7 @@ Both mod-time and checksum must be changed for a test to
return true."
(ert-deftest hywiki-tests--get-page-list-when-new-wiki-directory ()
"Verify `hywiki-get-page-list' is empty for new `hywiki-directory'."
(let* ((hywiki-directory (make-temp-file "hywiki" t))
- (wiki-page (hywiki-add-page "WikiWord")))
+ (wikipage (hywiki-add-page "WikiWord")))
(unwind-protect
(progn
(should (= 1 (length (hywiki-get-page-list))))
@@ -253,7 +269,7 @@ Both mod-time and checksum must be changed for a test to
return true."
(progn
(should (= 0 (length (hywiki-get-page-list)))))
(hy-delete-dir-and-buffer hywiki-directory))))
- (hy-delete-file-and-buffer wiki-page)
+ (hy-delete-file-and-buffer wikipage)
(hy-delete-dir-and-buffer hywiki-directory))))
;; Following three test cases for verifying proper face is some what
- [elpa] externals/hyperbole updated (e2749c6348 -> c4c5daaa08), ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole 6cd7a45434 1/9: hywiki.el - Add global HyWiki page override & custom referent types, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole a335b73d0f 3/9: hywiki.el - Fix custom HyWikiWord referents for single session use, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole f9df63b217 5/9: hywiki.el - Add require, defvar and declare-function for warnings, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole 5a91e7abaa 4/9: hywiki.el - Redo hywiki-add-page-and-display and hywiki-referent-menu, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole ebad245f63 2/9: Merge branch 'master' into rsw, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole 4eb1d46dbc 6/9: Merge branch 'master' into rsw, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole c4c5daaa08 9/9: Merge pull request #615 from rswgnu/rsw,
ELPA Syncer <=
- [elpa] externals/hyperbole 4bff008242 7/9: hywiki.el - Many fixes and updates plus Smart Key fixes, ELPA Syncer, 2024/12/16
- [elpa] externals/hyperbole 93874b2ec3 8/9: test/hbut-tests.el: Change most "/tmp" to "/tmp/", ELPA Syncer, 2024/12/16