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

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

[elpa] externals/hyperbole 6cd7a45434 1/9: hywiki.el - Add global HyWiki


From: ELPA Syncer
Subject: [elpa] externals/hyperbole 6cd7a45434 1/9: hywiki.el - Add global HyWiki page override & custom referent types
Date: Mon, 16 Dec 2024 15:58:30 -0500 (EST)

branch: externals/hyperbole
commit 6cd7a45434e7bc7b8d076a134e5b32eb6be263e4
Author: bw <rsw@gnu.org>
Commit: bw <rsw@gnu.org>

    hywiki.el - Add global HyWiki page override & custom referent types
    
    defcustom hywiki-display-page-function #'hpath:find
      Hyperbole function to display HyWiki pages.
    
    defcustom hywiki-allow-plurals-flag t
      Non-nil means plural HyWikiWords have the same referent as the singular 
form.
    
    Minibuffer menu prompt for per wikiword referent type overrides looks
    like this:
    HyWiki TestAdds Type>  Bookmark  Command  Find  Gbut  HyRolo  Keys  
InfoIndex  infoNode  OrgID  orgRoamNode  Path  Sexp
---
 ChangeLog   |  66 ++++++-
 hactypes.el |   7 +-
 hib-kbd.el  |   4 +-
 hibtypes.el |  13 +-
 hui-menu.el |   4 +-
 hui.el      |   6 +-
 hywiki.el   | 569 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 7 files changed, 581 insertions(+), 88 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1324ae46e7..e1bb43b512 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,67 @@
+2024-11-24  Bob Weiner  <rsw@gnu.org>
+
+* hibtypes.el (hywiki-word:help): Add so Assist Key on a HyWikiWord
+    customizes its referent type and link.
+  hywiki.el its referent type and link.
+
+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-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
@@ -10,8 +74,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..12f609a72d 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:     23-Nov-24 at 12:27:01 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -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)
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..0f4d311303 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:     24-Nov-24 at 01:52:18 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1696,7 +1696,16 @@ If a boolean function or variable, display its value."
       (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)))))
+      (hact 'hywiki-find-referent page-name))))
+
+(defun hywiki-existing-word:help (wikiword)
+  "When on a HyWikiWord, customize its referent type and link."
+  (interactive (list (hywiki-word-at)))
+  (unless (stringp wikiword)
+    (setq wikiword (hywiki-word-at)))
+  (when wikiword
+    (ibut:label-set wikiword (match-beginning 0) (match-end 0))
+    (hywiki-find-referent wikiword t)))
 
 ;;; ========================================================================
 ;;; Inserts completion into minibuffer or other window.
diff --git a/hui-menu.el b/hui-menu.el
index 6687033cb0..38a99585a8 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:     23-Nov-24 at 21:14:02 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -309,7 +309,7 @@ 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]
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/hywiki.el b/hywiki.el
index 0d4572489b..4e3474ad16 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:     24-Nov-24 at 03:24:57 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -137,10 +137,14 @@
 ;;; ************************************************************************
 
 (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 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 hsys-org-at-tags-p "hsys-org")
 (declare-function org-link-store-props "ol" (&rest plist))
 (declare-function org-publish-property "ox-publish" (property project 
&optional default))
@@ -314,7 +318,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,8 +359,21 @@ 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."
+  :initialize #'custom-initialize-default
   :type 'face
+  :group 'hyperbole-hywiki)
+
+(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)
+
+(defcustom hywiki-allow-plurals-flag t
+  "Non-nil means plural HyWikiWords have the same referent as the singular 
form."
   :initialize #'custom-initialize-default
+  :type 'boolean
   :group 'hyperbole-hywiki)
 
 ;;; ************************************************************************
@@ -537,30 +554,66 @@ 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))))
+  "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 (hywiki-word-at)))
+    (when wikiword
+      (ibut:label-set wikiword (match-beginning 0) (match-end 0))
+      (hact 'hywiki-find-referent wikiword))))
+
+(defalias 'hywiki-word:help 'hywiki-existing-word:help)
 
 ;;;###autoload
-(defun hywiki-find-page (&optional page-name prompt-flag)
+(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-read-new-page-name "Add/Edit HyWikiWord: ")
+                    (when current-prefix-arg t)))
+  (prog1 (hywiki-display-referent wikiword prompt-flag)
+    (run-hooks 'hywiki-find-referent-hook)))
+
+(defun hywiki-display-page (&optional wikiword)
+  "Display an optional WIKIWORD page.
+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-read-new-page-name "Find HyWiki page: ")))
+    (funcall hywiki-display-page-function wikiword)))
+
+(defun hywiki-display-referent (&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: "))))
+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 page-name))
        (in-hywiki-directory-flag (hywiki-in-page-p)))
     (if (or (stringp page-name) in-hywiki-directory-flag)
@@ -568,32 +621,138 @@ successfully finding a page and reading it into a 
buffer, run
          (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 `page-name' 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"))
+           (unless buffer-file-name
+             (error "(hywiki-display-referent): 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)
+         (when (string-match "#[^#]+$" page-name)
+           (setq page-name (substring page-name 0 (match-beginning 0))))
+         (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
+                (referent (if prompt-flag
+                              (hywiki-add-prompted-referent page-name)
+                            (hywiki-add-page page-name prompt-flag))))
+           (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 page-name prompt-flag))
+                   ((and (consp referent) (fboundp (car referent)))
+                    ;; e.g. (kbd "key sequence")
+                    (hact #'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))))
+                       (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)))
+             (run-hooks 'hywiki-display-referent-hook)
+             referent)))
       ;; When called without a page-name and outside hywiki-directory,
       ;; just find as a regular file and use next line to highlight
       ;; HyWikiWords only if buffer was not previously highlighted.
       (hywiki-maybe-highlight-page-names))))
 
+;;; ************************************************************************
+;;; 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 wikiword)
+            "Add a HyWikiWord that activates a saved activity from the 
Activities package."))
+        '("Bookmark"     (hywiki-add-bookmark wikiword)
+          "Add a HyWikiWord that jumps to an Emacs bookmark.")
+        '("Command"      (hywiki-add-command wikiword)
+          "Add a HyWikiWord that runs an Emacs command or Hyperbole action 
type.")
+        '("Find"         (hywiki-add-find wikiword)
+          "Add a HyWikiWord that greps through `hywiki-directory' for its 
matches.")
+        ;; "<(global explicit button name)>"
+        ;; "<[global implicit button name]>"
+        '("Gbut"         (hywiki-add-global-button wikiword)
+          "Add a HyWikiWord that activates a named Hyperbole global button.")
+        '("HyRolo"       (hywiki-add-hyrolo wikiword)
+          "Add a HyWikiWord that searches `hyrolo-file-list' for matches.")
+        ;; "{key series}" wikiword)
+        '("Keys"         (hywiki-add-key-series wikiword)
+          "Add a HyWikiWord that executes a key series.")
+        '("InfoIndex"    (hywiki-add-info-index wikiword)
+          "Add a HyWikiWord that displays an Info index item.")
+        '("infoNode"     (hywiki-add-info-node wikiword)
+          "Add a HyWikiWord that displays an Info node.")
+        ;; "ID: org-id"
+        '("OrgID"        (hywiki-add-org-id wikiword)
+          "Add a HyWikiWord that displays an Org section given its Org ID.")
+        '("orgRoamNode"  (hywiki-add-org-roam-node wikiword)
+          "Add a HyWikiWord that displays an Org Roam node given its title.")
+        ;; "pathname:line:col"
+        ;; "#in-buffer-section"
+        '("Path"         (hywiki-add-path wikiword)
+          "Add a HyWikiWord that links to a path and possible position.")
+        ;; e.g. (kbd "key sequence")
+        '("Sexp"         (hywiki-add-sexpresion wikiword)
+          "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-read-new-page-name "Add/Edit HyWikiWord: ")))
+  (unless (stringp wikiword)
+    (setq wikiword (hywiki-read-new-page-name "Add/Edit HyWikiWord: ")))
+  (let ((referent
+        (hui:menu-act 'hywiki-referent-menu
+                      (list (cons 'hywiki-referent-menu
+                                  (cons (list (format "HyWiki %s Type>"
+                                                      wikiword))
+                                        (cdr hywiki-referent-menu)))))))
+    (or referent
+       (when (called-interactively-p 'interactive)
+         (user-error "(hywiki-add-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-page-name 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,6 +767,165 @@ Exclude the minibuffer if selected and return nil."
        (not (apply #'derived-mode-p hywiki-exclude-major-modes))
        (or hywiki-mode (hywiki-in-page-p))))
 
+(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 (hywiki-read-new-page-name "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 (hywiki-read-new-page-name "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 (hywiki-read-new-page-name "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 (hywiki-read-new-page-name "Add/Edit HyWikiWord: ")))
+  (let ((grep-cmd (if (fboundp 'consult-grep) ;; allow for autoloading
+                     #'hywiki-word-consult-grep
+                   #'grep)))
+    (hywiki-add-referent wikiword (list grep-cmd wikiword))))
+
+(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 (hywiki-read-new-page-name "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 (hywiki-read-new-page-name "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 (hywiki-read-new-page-name "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 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 (hywiki-read-new-page-name "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 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 (hywiki-read-new-page-name "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)))
+
 ;;;###autoload
 (defun hywiki-add-link ()
   "Insert at point a link to a HyWiki page."
@@ -615,6 +933,67 @@ Exclude the minibuffer if selected and return nil."
   (insert (hywiki-read-page-name "Link to HyWiki page: "))
   (hywiki-maybe-highlight-page-name))
 
+(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 (hywiki-read-new-page-name "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 (hywiki-read-new-page-name "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-path (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 (hywiki-read-new-page-name "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-page (page-name &optional prompt-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,
@@ -666,9 +1045,22 @@ 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))
+       (hywiki-find-referent (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-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 (hywiki-read-new-page-name "Add/Edit HyWikiWord: ")))
+  (hywiki-add-referent wikiword (read--expression "Sexpression: ")))
+
 (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
@@ -740,18 +1132,19 @@ Use `hywiki-get-page' to determine whether a HyWiki page 
exists."
     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.
+  "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 on a HyWikiWord without a wiki page, then prompt before creating
-the page.
+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-page word t)
+       (hywiki-find-referent word)
       (hkey-either arg))))
 
 (defun hywiki-word-at ()
@@ -1519,7 +1912,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.
@@ -1564,7 +1958,7 @@ value returns nil."
     ;; 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)
+          (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)
@@ -1573,23 +1967,37 @@ value returns nil."
               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."
+  "Return the referent of HyWiki PAGE-NAME or nil if it does not exist.
+If it is a pathname, expand it relative to `hywiki-directory'."
   (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)))))
+    (let* ((section (when (match-string-no-properties 2 page-name)
+                     (prog1 (substring page-name (match-beginning 2))
+                       ;; Remove any #section suffix in PAGE-NAME.
+                       (setq page-name (match-string-no-properties 1 
page-name)))))
+          (referent (hash-get (hywiki-get-singular-page-name page-name)
+                              (hywiki-get-page-hasht))))
+      (cond ((or (symbolp referent) (functionp referent)
+                (and (consp 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)
+                    ;; path, expand to absolute
+                    (t (expand-file-name referent hywiki-directory)))))
+            (t nil)))))
 
 (defun hywiki-get-page-files ()
   "Return the list of existing HyWiki page file names.
@@ -1634,6 +2042,10 @@ regexps of page names."
   "Return a list of the HyWiki page names."
   (hash-map #'cdr (hywiki-get-page-hasht)))
 
+(defun hywiki-get-wikiwords-obarray ()
+  "Return an obarray of existing HyWikiWords."
+  (cdr (hywiki-get-page-hasht)))
+
 (defun hywiki-get-plural-page-name (page-name)
   "Return the pluralized version of the given PAGE-NAME."
   ;; You add "-es" to make a noun plural when the singular noun ends
@@ -1654,15 +2066,20 @@ regexps of page names."
                               "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))
+  "Return the singular version of the given PAGE-NAME.
+If `hywiki-allow-plurals-flag' is nil, return PAGE-NAME unchanged."
+  (if hywiki-allow-plurals-flag
+      (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$" page-name))
+           (substring page-name 0 -2))
+         (when (let ((case-fold-search t))
+                 (and (string-match-p ".[^eEsS]s$" page-name)
+                      (not (string-match-p "emacs$" page-name))))
+           (substring page-name 0 -1))
+         page-name)
+    page-name))
 
 (defun hywiki-kill-buffer-hook ()
   "Delete file attached to HyWiki buffer if the file is zero-sized.
@@ -1825,7 +2242,7 @@ 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)
@@ -1893,14 +2310,16 @@ Customize this directory with:
   "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))))
+                    (hywiki-get-wikiwords-obarray)
+                    nil nil nil nil (hywiki-word-at))))
 
 (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))))
+                    (hywiki-get-wikiwords-obarray)
+                    nil t nil nil (hywiki-word-at))))
 
 ;;;###autoload
 (defun hywiki-tags-view (&optional todo-only match view-buffer-name)



reply via email to

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