diff --git a/ChangeLog b/ChangeLog index ce4b2dd2..e14bd441 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2026-06-14 Bob Weiner + +* hactypes.el (link-to-ibut): Fix infinite loop in by preventing + ilinks from linking to other ilinks. + +* test/hibtypes-tests.el (ibtypes::ilink-test): Update match to ilink error. + +* hbut.el (ibut:label-set): Make 'label' arg optional. When omitted or nil, + reuse the existing label or if that is null, set it to "temp". This behavior + is used by the ibtypes: elink, glink, and ilink. + (hbut:act): Change from (< delim-text-start (point)) to + (<= delim-text-start (point)) since actions + can move point to the starting delimiter of a button. + +2026-06-12 Bob Weiner + +* hbut.el (ebut:get): Allow a buffer name for 'buffer' argument and prioritize + 'buffer' argument over 'key-src' argument. + hactypes.el (link-to-ebut, link-to-ibut): Rewrite to support links to buttons + in buffers without attached files. + (hactypes:link-to-file-interactively): Fix to handle buffer-type + 'loc attribute. + +* hibtypes.el (hlink:parse-label-and-file): Simplify using 'seq-position' + rather than a loop. + (hlink:parse-label-and-file): Rename to 'hlink:parse-label-and-loc'. + +* hyrolo.el (hyrolo-file-list): Explain that dirs and file wildcards are + allowed. Point to doc of 'hyrolo-expand-path-list' for how entries are + expanded. + +* hibtypes.el (klink, elink, ilink, glink): Move to be higher priority than + action buttons so are not overridden and misfired as an action button. + This manifested as an elink or glink matching to the action of a named + ilink. + man/hyperbole.texi (Implicit Button Types): Update priority ordering of + the above types. + 2026-06-12 Mats Lidell * test/hibtypes-tests.el (ibtypes::elink-test): @@ -29,6 +67,11 @@ optional args set to nil causing it to see different number of arguments depending on whether the code is natively compiled or not. +2026-06-09 Bob Weiner + +* hywiki.el (hywiki-mode): Move doc of 'hywiki-mode' state values here, + from 'hywiki-default-mode', for ease of reference. + 2026-06-07 Bob Weiner * hbut.el (ibut:to-text): Fix missing let of 'name-end' and assign a value. @@ -70,10 +113,6 @@ * hbut.el (ibut:to-text): Error if 'lbl-key' is an empty string. -* hactypes.el: (link-to-ibut): Fix infinite loop in links - by replacing 'hbut:act' call with a call to 'actype:act' which - utilizes the actype computed from the prior 'ibut:at-p' call. - 2026-06-05 Mats Lidell * hui.el (kcell-view:label): Declare function. @@ -5276,7 +5315,7 @@ value to be [[WikiWord]] not [[file:WikiWord.org][WikiWord]]. 2024-10-05 Bob Weiner * hywiki.el (hywiki-kill-buffer-hook): Change to return t iff 'hywiki-directory' - change + changes. 2024-09-30 Bob Weiner @@ -5451,7 +5490,7 @@ value to be [[WikiWord]] not [[file:WikiWord.org][WikiWord]]. 2024-09-01 Bob Weiner -* man/dir (File): Narrow width to better fit with out Info entries. +* man/dir (File): Narrow width to better fit without Info entries. * hyrolo.el (hyrolo-org-mode): Prioritize Org 9.7 folding-spec config over earlier versions to fix a bug that used the wrong version. @@ -5662,7 +5701,7 @@ value to be [[WikiWord]] not [[file:WikiWord.org][WikiWord]]. to 0 since just want to trigger redisplay. (hywiki-publish-to-html): Retrieve HyWiki project by name. (hywiki-directory): Change to a defcustom so can set this before - loading Hyperoble. + loading Hyperbole. (hywiki-org-get-publish-property): (require 'ox-publish). (hywiki-org-maybe-add-title): Add title to HyWiki pages without one using the file or buffer name. @@ -5676,7 +5715,7 @@ value to be [[WikiWord]] not [[file:WikiWord.org][WikiWord]]. properties so that changes trigger updates in 'org-publish-project-alist'. (hywiki-org-maybe-add-title): Add to add the HyWikiWord as the title for each HyWiki page. - (hywiki-org-make-publish-project-alist): Add :sitemap-title property.. + (hywiki-org-make-publish-project-alist): Add :sitemap-title property. (hywiki-org-publishing-sitemap-title): Add to set above property. (hywiki-is-wikiword): Add not 'string-empty-p' test. (hywiki-add-page): Add interactive spec. diff --git a/FAST-DEMO b/FAST-DEMO index 0da00383..07dbbb13 100644 --- a/FAST-DEMO +++ b/FAST-DEMO @@ -449,20 +449,26 @@ To learn how to create new kinds of implicit button and action types, see ** HyWiki - HyWiki is Hyperbole's markup-free personal wiki system for note-taking - and automatic wiki-word highlighting and hyperlinking. It uses Org - mode for note taking and adds automatic hyperlinking of HyWikiWords - within Org files in `hywiki-directory' (default = "~/hywiki"), where - a HyWikiWord is a capitalized word that contains upper and lowercase - letters only and has a corresponding HyWikiWord.org wiki page file - below `hywiki-directory'. HyWikiWords require no delimiters. + HyWiki is Hyperbole's markup-free personal wiki system for note-taking and + automatic wiki-word highlighting and hyperlinking. It uses Org mode for + note taking and adds automatic hyperlinking of HyWikiWords within Org files + directly below the directory given by the variable, `hywiki-directory' + (default = "~/hywiki"). A HyWikiWord is a capitalized word that contains + upper and lowercase letters only and has a corresponding HyWikiWord.org + wiki page file below `hywiki-directory'. HyWikiWords require no + delimiters. + + To create a new HyWikiWord simply type it in an Org file in + `hywiki-directory' and then press {M-RET} with point on the word. This + will create an empty wiki page for that word. Add any text to this file + and save it to create the new HyWikiWord. Use {M-RET} on the first line of the expression below to set a demo HyWiki directory and turn on hywiki-mode so HyWikiWords are highlighted outside of the HyWiki directory. + (hywiki-mode :all)> Now all these wiki-words should be highlighted and can appear in any text buffer and will be treated as hyperlinks. Simply press {M-RET} diff --git a/HY-NEWS b/HY-NEWS index 6c41ed4a..97315224 100644 --- a/HY-NEWS +++ b/HY-NEWS @@ -5,6 +5,41 @@ * V9.0.2pre =========================================================================== +**GNU Hyperbole 9.0.2pre NEWS** + +* **HyWiki** + * **Global Minor Mode**: The new `hywiki-mode` is a global minor mode that enables the highlighting and hyperlinking of **HyWikiWords** in any non-special text buffer and within the comments of programming buffers. + * **Section Linking**: HyWikiWord links now support internal section jumps using the **`#` character** (e.g., `WikiWord#Section-Name`), allowing direct navigation to specific Org headlines within a wiki page. + * **Web Publishing**: Added the `hywiki-publish-to-html` command (bound to `{C-h h h p}`) which utilizes Org mode’s publishing framework to export an entire HyWiki directory to HTML for web use. + * **Interactive Search**: Added `hywiki-consult-grep` (bound to `{C-h h h g}`) for interactive, live-narrowing searches across all HyWiki pages using the Consult package. + * **Customizable Highlighting**: Added `hywiki-word-highlight-flag` to toggle auto-highlighting and `hywiki-exclude-major-modes` to define a list of modes where HyWikiWord recognition should be disabled. + * **Link Requirements**: New variable `hywiki-org-link-type-required` allows users to control whether the `hy:` prefix is required for HyWikiWords when used inside Org-style double square brackets outside of the wiki directory. + +* **Smart Keys** + * **Granular Org Integration**: The custom option `hsys-org-enable-smart-keys` now supports a new value, **`'buttons`**, which limits Hyperbole’s `M-RET` override to only apply when point is on a Hyperbole button, leaving other contexts to native Org mode behavior. + * **Org Table Toggle**: In the Koutliner, pressing the Action Key on a `|` character now toggles **`orgtbl-mode`** for cell-based table editing. + * **Modern Completion Support**: Smart Key argument selection is now fully integrated with the **Vertico and Consult** completion frameworks, allowing for modern interactive selection of buffers, files, and identifiers. + * **Python Tracebacks**: The Action Key now recognizes and jumps to source lines referenced in **Python pdb, traceback, or pytype errors** within any buffer. + +* **Implicit Button Types** + * **Social Media References**: Added the `social-reference` type which automatically recognizes and links hashtags and usernames for platforms including **X (Twitter), Facebook, and Instagram**. + * **Social Default Service**: New variable `hibtypes-social-default-service` sets the default platform (initially "x") used when a hashtag or username is referenced without a specific service prefix. + * **Python Navigation**: Added `python-tb-previous-line` to handle instances where Python tracebacks place the source reference one line above the error description. + * **YouTube Interaction**: Added new action types `yt-play`, `yt-info`, and `yt-search` for specialized interaction with **YouTube videos** and metadata. + +* **HyRolo** + * **Navigation Performance**: All movement commands within HyRolo match buffers (e.g., Next, Previous, Up) have been optimized to use **text properties** rather than overlays, ensuring instantaneous navigation even in buffers containing thousands of search results. + * **Interactive Filtering**: Added `hyrolo-consult-grep` and `hyrolo-helm-org-rifle` to the Rolo menu, permitting interactive full-text search and narrowing over the `hyrolo-file-list`. + * **Org Roam Integration**: HyRolo now includes convenience commands for searching **Org Roam nodes** via the Consult package, accessible through `hsys-org-roam-consult-grep`. + +* **Miscellaneous** + * **Emacs Version Requirements**: While Hyperbole remains compatible with GNU Emacs 27.1, this release is optimized for and recommended for use with **GNU Emacs 28 or above**. + * **Path Variable Expansion**: The function `hpath:expand` has been enhanced to more robustly handle Hyperbole-specific suffixes like `#anchors` and `:line:col` in combination with environment and Lisp variables. + + +------------- + + ** ACE WINDOW PACKAGE INTEGRATION - fast window and buffer switching *** OLD - After installing the ace-window package and loading Hyperbole, execute diff --git a/hactypes.el b/hactypes.el index 705dc44f..f80b0bc9 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: 5-Jun-26 at 08:42:07 by Bob Weiner +;; Last-Mod: 14-Jun-26 at 16:06:31 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -316,9 +316,9 @@ If `mail-user-agent' is `browse-url', do this in the default web browser." (interactive "DDirectory to link to: ") (hpath:find directory)) -(defact link-to-ebut (key &optional key-file) - "Perform explicit button action specified by KEY and optional KEY-FILE. -Interactively, KEY-FILE defaults to the current buffer's file name." +(defact link-to-ebut (key &optional key-src) + "Perform explicit button action specified by KEY and optional KEY-SRC. +Interactively, KEY-SRC defaults to the current buffer's file name." (interactive (let (but-lbl but-file) @@ -341,17 +341,20 @@ Interactively, KEY-FILE defaults to the current buffer's file name." (beep)) (ebut:label-to-key but-lbl)) but-file))) - (let (but - normalized-file) - (if key-file - (setq normalized-file (hpath:normalize key-file)) - (setq normalized-file (hypb:buffer-file-name))) - - (if (setq but (when normalized-file (ebut:get key nil normalized-file))) - (hbut:act but) + (let* ((key-src-buf-flag (or (bufferp key-src) + (and (stringp key-src) (get-buffer key-src)))) + (but (if key-src-buf-flag + (ebut:get key key-src) + (ebut:get key nil key-src)))) + (if but + (ebut:act but) + (unless key-src-buf-flag + (setq key-src (if key-src + (hpath:normalize key-src) + (hbut:get-key-src t)))) (hypb:error "(link-to-ebut): No button `%s' in `%s'" (ebut:key-to-label key) - key-file)))) + key-src)))) (defact link-to-elisp-doc (symbol) "Display documentation for SYMBOL." @@ -374,8 +377,8 @@ list item returned." path-buf) (unwind-protect (let* ((default-directory (or (hattr:get 'hbut:current 'dir) - (file-name-directory - (or (hattr:get 'hbut:current 'loc) "")) + (and (stringp (hattr:get 'hbut:current 'loc)) + (file-name-directory (hattr:get 'hbut:current 'loc))) default-directory)) (file-path (or (car hargs:defaults) default-directory)) (file-point (cadr hargs:defaults)) @@ -482,9 +485,9 @@ LINE-NUM may be an integer or string." col-num))) (hpath:find-line path line-num col-num)))) -(defact link-to-gbut (key &optional _key-file) +(defact link-to-gbut (key &optional _key-src) "Perform an action given by an existing global button, specified by KEY. -Optional second arg, KEY-FILE, is not used but is for calling +Optional second arg, KEY-SRC, is not used but is for calling compatibility with the `hlink' function." (interactive (let ((gbut-file (hpath:validate (hpath:substitute-value (gbut:file)))) @@ -534,10 +537,10 @@ the .info suffix in the format with parentheses." (id-info string) (hypb:error "(link-to-Info-node): Invalid Info node: `%s'" string))) -(defact link-to-ibut (name-key &optional but-src point) - "Activate implicit button given by NAME-KEY, optional BUT-SRC and POINT. +(defact link-to-ibut (name-key &optional key-src point) + "Activate implicit button given by NAME-KEY, optional KEY-SRC and POINT. NAME-KEY must be a normalized key for an ibut <[name]>. -BUT-SRC defaults to the current buffer's file or if there is no +KEY-SRC defaults to the current buffer's file or if there is no attached file, then to its buffer name. POINT defaults to the current point. @@ -560,36 +563,58 @@ on the implicit button to which to link." (unless name-key (hypb:error "(link-to-ibut): Point must be on an implicit button to create a link-to-ibut")) - (let (actype - but - normalized-file) - (if but-src - (unless (and (get-buffer but-src) - (not (hypb:buffer-file-name (get-buffer but-src)))) - (setq normalized-file (hpath:normalize but-src))) - (setq normalized-file (hpath:normalize (hypb:buffer-file-name)))) - (when but-src - (set-buffer (or (get-buffer but-src) (get-file-buffer normalized-file)))) - (widen) - (when (or (not normalized-file) (hmail:editor-p) (hmail:reader-p)) - (hmail:msg-narrow)) - (when (integerp point) - (goto-char (min point (point-max)))) - (setq but (ibut:to-text name-key)) - (cond (but - (setq actype (actype:def-symbol (hattr:get but 'actype))) - (if (eq actype 'link-to-ibut) - (hypb:error "(link-to-ibut): Failed to find implicit button named `%s' in `%s'" - (ibut:key-to-label name-key) - (or but-src (buffer-name))) - (apply #'actype:act (hattr:get but 'actype) - (hattr:get but 'args)))) - (name-key - (hypb:error "(link-to-ibut): No implicit button named `%s' found in `%s'" - (ibut:key-to-label name-key) - (or but-src (buffer-name)))) - (t - (hypb:error "(link-to-ibut): Link reference is null/empty"))))) + + (let* ((key-src-buf-flag (or (bufferp key-src) + (and (stringp key-src) (get-buffer key-src)))) + (but (if key-src-buf-flag + (ibut:get name-key key-src) + (ibut:get name-key nil key-src))) + actype + ;; normalized-file + ) + (if but + (progn (setq actype (actype:def-symbol (hattr:get but 'actype))) + (if (eq actype 'link-to-ibut) + (hypb:error "(link-to-ibut): No button `%s' in `%s'" + (ibut:key-to-label name-key) + (or key-src (buffer-name))) + (ibut:act but))) + (unless key-src-buf-flag + (setq key-src (if key-src + (hpath:normalize key-src) + (hbut:get-key-src t)))) + (hypb:error "(link-to-ibut): No button `%s' in `%s'" + (ibut:key-to-label name-key) + key-src)))) + + + ;; (if key-src + ;; (unless (and (get-buffer key-src) + ;; (not (hypb:buffer-file-name (get-buffer key-src)))) + ;; (setq normalized-file (hpath:normalize key-src))) + ;; (setq normalized-file (hpath:normalize (hypb:buffer-file-name)))) + ;; (when key-src + ;; (set-buffer (or (get-buffer key-src) (get-file-buffer normalized-file)))) + ;; (widen) + ;; (when (or (not normalized-file) (hmail:editor-p) (hmail:reader-p)) + ;; (hmail:msg-narrow)) + ;; (when (integerp point) + ;; (goto-char (min point (point-max)))) + ;; (setq but (ibut:to-text name-key)) + ;; (cond (but + ;; (setq actype (actype:def-symbol (hattr:get but 'actype))) + ;; (if (eq actype 'link-to-ibut) + ;; (hypb:error "(link-to-ibut): Failed to find implicit button named `%s' in `%s'" + ;; (ibut:key-to-label name-key) + ;; (or key-src (buffer-name))) + ;; (apply #'actype:act (hattr:get but 'actype) + ;; (hattr:get but 'args)))) + ;; (name-key + ;; (hypb:error "(link-to-ibut): No implicit button named `%s' found in `%s'" + ;; (ibut:key-to-label name-key) + ;; (or key-src (buffer-name)))) + ;; (t + ;; (hypb:error "(link-to-ibut): Link reference is null/empty"))))) (defact link-to-kcell (file cell-ref) "Display FILE with kcell given by CELL-REF at window top. diff --git a/hbut.el b/hbut.el index 0e545b9a..c244ed14 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: 7-Jun-26 at 16:50:26 by Bob Weiner +;; Last-Mod: 14-Jun-26 at 15:13:00 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -210,22 +210,24 @@ Do not save button data buffer." lbl-instance))) (defun ebut:get (&optional lbl-key buffer key-src start-delim end-delim) - "Return explicit Hyperbole button symbol given by LBL-KEY and BUFFER. -KEY-SRC is given when retrieving global buttons and is the full -source pathname. START-DELIM and END-DELIM are strings that -override default button delimiters. + "Return explicit Hyperbole button symbol given by optional LBL-KEY and BUFFER. +KEY-SRC is given when retrieving global buttons and is the full source +pathname. START-DELIM and END-DELIM are strings that override default +button delimiters. Retrieve button data, convert into a button object and return a symbol which references the button. -All arguments are optional. When none are given, return a symbol for -the button that point is within. BUFFER defaults to the current -buffer. +All arguments are optional. When none are given, return a symbol for the +button that point is within or nil. BUFFER defaults to the current buffer. +If both BUFFER and KEY-SRC are given, BUFFER is used as the button source +location. Return nil if no matching button is found." (hattr:clear 'hbut:current) (save-excursion - (let (but-data + (let ((buf-flag (or (bufferp buffer) (and (stringp buffer) (get-buffer buffer)))) + but-data key-dir key-file lbl-end @@ -237,16 +239,17 @@ Return nil if no matching button is found." lbl-start (nth 1 lbl-key-and-pos) lbl-end (nth 2 lbl-key-and-pos))) (when buffer - (if (bufferp buffer) + (if buf-flag (set-buffer buffer) (error "(ebut:get): Invalid buffer argument: %s" buffer))) - (when (not key-src) + (when (or buf-flag (not key-src)) (when (not (equal lbl-key (ebut:label-p nil start-delim end-delim))) (goto-char (point-min)) (ebut:next-occurrence lbl-key)) (when (setq key-src (ebut:to-key-src 'full)) ;; `ebut:to-key-src' sets current buffer to key-src buffer. - (setq buffer (current-buffer)))) + (setq buffer (current-buffer) + buf-flag t))) (when (and (stringp lbl-key) key-src) (when (stringp key-src) (setq key-dir (file-name-directory key-src) @@ -1087,7 +1090,7 @@ Default is the symbol hbut:current." (unless (and (or (equal loc (hypb:buffer-file-name)) (equal loc (current-buffer))) delim-text-start delim-text-end - (< delim-text-start (point)) + (<= delim-text-start (point)) (>= delim-text-end (point))) (ibut:to-text (hattr:get hbut 'lbl-key)))))) (setq text-point (point-marker)) @@ -2245,13 +2248,15 @@ Insert INSTANCE-FLAG after END, before ending delimiter." (defun ibut:get (&optional lbl-key buffer key-src) "Return implicit Hyperbole button symbol given by LBL-KEY and BUFFER. -KEY-SRC is given when retrieving global buttons and is the full source pathname. +KEY-SRC is given when retrieving global buttons and is the full source +pathname. Return a symbol which references the button. -All arguments are optional. When none are given, return a -symbol for the button or button label that point is within or -nil. BUFFER defaults to the current buffer. +All arguments are optional. When none are given, return a symbol for the +button or button label that point is within or nil. BUFFER defaults to the +current buffer. If both BUFFER and KEY-SRC are given, BUFFER is used as the +button source location. Return nil if no matching button is found." (hattr:clear 'hbut:current) @@ -2343,24 +2348,32 @@ lines." lbl) result))))) -(defun ibut:label-set (label &optional start end) - "Set current implicit button label attributes. -Provide arguments LABEL and optional START, END positions. -Return label. When START and END are given, they specify the -region in the buffer to flash when this implicit button is -activated or queried for its attributes; this typically should -be the text of the button without any delimiters. +(defun ibut:label-set (&optional label start end) + "Set symbol `hbut:current' implicit button label attributes. +Provide optional arguments LABEL, START, and END positions. +Return label. + +LABEL may be: + 1. a string, then set it as the label. + 2. nil, then either leave the current button's label as is if set already + or set it temporarily to the string, \"temp\". + 2. a list, then get all args, LABEL, START and END from the list. -If LABEL is a list, it is assumed to contain all arguments. +When START and END are given, they specify the region in the buffer to flash +when this implicit button is activated or queried for its attributes; this +typically should be the text of the button without any delimiters. For legacy reasons, the label here is actually the text of the implicit button matched contextually and never the optional <[name]> preceding the text." (save-match-data - (cond ((stringp label) + (cond ((or (stringp label) (null label)) (hattr:set 'hbut:current 'loc (save-excursion (hbut:to-key-src 'full))) - (hattr:set 'hbut:current 'lbl-key (hbut:label-to-key label)) + (hattr:set 'hbut:current 'lbl-key (if label + (hbut:label-to-key label) + (or (hattr:get 'hbut:current 'lbl-key) + "temp"))) (when start (hattr:set 'hbut:current 'lbl-start start)) (when end (hattr:set 'hbut:current 'lbl-end end))) ((and label (listp label)) diff --git a/hibtypes.el b/hibtypes.el index b7b2b474..2e65c7ab 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: 4-Jun-26 at 10:32:16 by Bob Weiner +;; Last-Mod: 14-Jun-26 at 15:13:01 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -147,7 +147,8 @@ reference line so since not on a Hyperbole button, move back a line and check for a source reference line again." (save-excursion (unless (/= (forward-line -1) 0) - (ibut:label-set "temp") ;; Real value set in action call below + ;; Set temp label value here; real label value is set in action call below + (ibut:label-set) (hib-python-traceback)))) ;;; ======================================================================== @@ -866,108 +867,6 @@ other buffers." ;; Hyperbole is set to display other referents in another window. (hact 'man topic)))))) -;;; ======================================================================== -;;; Follows links to Hyperbole Koutliner cells. -;;; ======================================================================== - -(load "klink" nil t) - -;;; ======================================================================== -;;; Links to Hyperbole button types -;;; ======================================================================== - -(defun hlink (link-actype label-prefix start-delim end-delim) - "Call LINK-ACTYPE and use LABEL-PREFIX if point is within an implicit button. -LINK-ACTYPE is the action type and button is prefixed with -LABEL-PREFIX. The button must be delimited by START-DELIM and -END-DELIM." - ;; Used by e/g/ilink implicit buttons." - (let* ((label-start-end (hbut:label-p t start-delim end-delim t t)) - (label-and-file (nth 0 label-start-end)) - (start-pos (nth 1 label-start-end)) - (end-pos (nth 2 label-start-end)) - but-key lbl-key key-file partial-lbl) - (when label-and-file - (setq label-and-file (hlink:parse-label-and-file label-and-file) - partial-lbl (nth 0 label-and-file) - but-key (hbut:label-to-key partial-lbl) - key-file (nth 1 label-and-file) - lbl-key (when but-key (concat label-prefix but-key))) - (ibut:label-set (hbut:key-to-label lbl-key) start-pos end-pos) - (hact link-actype but-key key-file)))) - -(defun hlink:parse-label-and-file (label-and-file) - "Parse colon-separated string LABEL-AND-FILE into a list of label and file path." - ;; Can't use split-string here because file path may contain colons; - ;; we want to split only on the first colon. - (let ((i 0) - (len (length label-and-file)) - label - file) - (while (< i len) - (when (= ?: (aref label-and-file i)) - (when (zerop i) - (error "(hlink:parse-label-and-file): Missing label: '%s'" label-and-file)) - (setq label (hpath:trim (substring label-and-file 0 i)) - file (hpath:trim (substring label-and-file (1+ i)))) - (when (string-empty-p label) (setq label nil)) - (when (string-empty-p file) (setq file nil)) - (setq i len)) - (setq i (1+ i))) - (unless (or label (string-empty-p label-and-file)) - (setq label label-and-file)) - (delq nil (list label file)))) - -(defconst elink:start "" - "String matching the end of a link to a Hyperbole explicit button.") - -(defib elink () - "At point, activate a link to an explicit button. -This executes the linked to explicit button's action in the -context of the current buffer. - -Recognizes the format '', -where : button_file_path is given only when the link is to another file, -e.g. ." - (progn - (ibut:label-set "temp") ;; Real value set in action call below - (hlink 'link-to-ebut "" elink:start elink:end))) - -(defconst glink:start "" - "String matching the end of a link to a Hyperbole global button.") - -(defib glink () - "At point, activates a link to a global button. -This executes the linked to global button's action in the context -of the current buffer. - -Recognizes the format '', -e.g. ." - (progn - (ibut:label-set "temp") ;; Real value set in action call below - (hlink 'link-to-gbut "" glink:start glink:end))) - -(defconst ilink:start "" - "String matching the end of a link to a Hyperbole implicit button.") - -(defib ilink () - "At point, activate a link to a labeled implicit button. -This executes the linked to implicit button's action in the context of the -current buffer. - -Recognizes the format '', -where button_file_path is given only when the link is to another file, -e.g. ." - (progn - (ibut:label-set "temp") ;; Real value set in action call below - (hlink 'link-to-ibut "" ilink:start ilink:end))) - ;;; ======================================================================== ;;; Displays files at specific lines and optional column number ;;; locations. @@ -1224,8 +1123,9 @@ xdb. Such lines are recognized in any buffer." (beginning-of-line) (cond ;; Python pdb or traceback, pytype error - ((progn (ibut:label-set "temp") ;; Real value set in action call below - (hib-python-traceback))) + ((progn ;; Set temp label value here; real label value is set in action call below + (ibut:label-set) + (hib-python-traceback))) ;; JavaScript traceback ((or (looking-at "[a-zA-Z0-9-:.()? ]+? +at \\([^() \t]+\\) (\\([^:, \t()]+\\):\\([0-9]+\\):\\([0-9]+\\))$") @@ -1787,6 +1687,105 @@ If a boolean function or variable, display its value." (apply #'actype:eval actype args))) (error "(action:help): No action button labeled: %s" label))))) +;;; ======================================================================== +;;; Follows links to Hyperbole Koutliner cells. +;;; ======================================================================== + +(load "klink" nil t) + +;;; ======================================================================== +;;; Links to Hyperbole button types +;;; ======================================================================== + +(defun hlink (link-actype label-prefix start-delim end-delim) + "Call LINK-ACTYPE and use LABEL-PREFIX if point is within an implicit button. +LINK-ACTYPE is the action type and button is prefixed with +LABEL-PREFIX. The button must be delimited by START-DELIM and +END-DELIM." + ;; Used by e/g/ilink implicit buttons." + (let* ((label-start-end (hbut:label-p t start-delim end-delim t t)) + (label-and-loc (nth 0 label-start-end)) + (start-pos (nth 1 label-start-end)) + (end-pos (nth 2 label-start-end)) + but-key lbl-key key-src partial-lbl) + (when label-and-loc + (setq label-and-loc (hlink:parse-label-and-loc label-and-loc) + partial-lbl (nth 0 label-and-loc) + but-key (hbut:label-to-key partial-lbl) + key-src (nth 1 label-and-loc) + lbl-key (when but-key (concat label-prefix but-key))) + (ibut:label-set (hbut:key-to-label lbl-key) start-pos end-pos) + (hact link-actype but-key key-src)))) + +(defun hlink:parse-label-and-loc (label-and-loc) + "Parse colon-separated string LABEL-AND-LOC into a list of label and src loc." + (let (i + label + file) + (when (and (stringp label-and-loc) (setq i (seq-position label-and-loc ?: '=))) + (when (zerop i) + (error "(hlink:parse-label-and-loc): Missing label: '%s'" label-and-loc)) + (setq label (hpath:trim (substring label-and-loc 0 i)) + file (hpath:trim (substring label-and-loc (1+ i)))) + (when (string-empty-p label) (setq label nil)) + (when (string-empty-p file) (setq file nil))) + (unless (or label (string-empty-p label-and-loc)) + (setq label label-and-loc)) + (delq nil (list label file)))) + +(defconst elink:start "" + "String matching the end of a link to a Hyperbole explicit button.") + +(defib elink () + "At point, activate a link to an explicit button. +This executes the linked to explicit button's action in the +context of the current buffer. + +Recognizes the format '', +where : button-location is given only when the link is to another file, +e.g. ." + (progn + ;; Set temp label value here; real label value is set in action call below + (ibut:label-set) + (hlink 'link-to-ebut "" elink:start elink:end))) + +(defconst glink:start "" + "String matching the end of a link to a Hyperbole global button.") + +(defib glink () + "At point, activates a link to a global button. +This executes the linked to global button's action in the context +of the current buffer. + +Recognizes the format '', +e.g. ." + (progn + ;; Set temp label value here; real label value is set in action call below + (ibut:label-set) + (hlink 'link-to-gbut "" glink:start glink:end))) + +(defconst ilink:start "" + "String matching the end of a link to a Hyperbole implicit button.") + +(defib ilink () + "At point, activate a link to a labeled implicit button. +This executes the linked to implicit button's action in the context of the +current buffer. + +Recognizes the format '', +where button-location is given only when the link is to another file, +e.g. ." + (progn + ;; Set temp label value here; real label value is set in action call below + (ibut:label-set) + (hlink 'link-to-ibut "" ilink:start ilink:end))) + ;;; ======================================================================== ;;; Activates HyWikiWords with existing referents. ;;; Non-existing HyWikiWords are handled by the (load "hywiki") at a low diff --git a/hyperbole.el b/hyperbole.el index d3598cc3..8bb74272 100644 --- a/hyperbole.el +++ b/hyperbole.el @@ -9,7 +9,7 @@ ;; Maintainer: Robert Weiner ;; Maintainers: Robert Weiner , Mats Lidell ;; Created: 06-Oct-92 at 11:52:51 -;; Last-Mod: 28-Mar-26 at 14:44:14 by Bob Weiner +;; Last-Mod: 9-Jun-26 at 10:58:22 by Bob Weiner ;; Released: 10-Mar-24 ;; Version: 9.0.2pre ;; Keywords: comm, convenience, files, frames, hypermedia, languages, mail, matching, mouse, multimedia, outlines, tools, wp @@ -572,9 +572,9 @@ frame, those functions by default still return the prior frame." #'hattr:save)) ;; This next expression initializes the Hyperbole keymap but does not -;; activate Hyperbole. The only user-visible change it should make is -;; to globally bind {C-h h} to 'hyperbole' which when invoked will both -;; activate Hyperbole and show its minibuffer menu. +;; activate Hyperbole, (hyperbole-mode 1) does that. The only user-visible +;; change it should make is to globally bind {C-h h} to 'hyperbole' which +;; when invoked will both activate Hyperbole and show its minibuffer menu. (if after-init-time ;; Initialize Hyperbole key bindings and hooks. (hyperb:init) diff --git a/hyrolo.el b/hyrolo.el index ed80ea97..3cba3864 100644 --- a/hyrolo.el +++ b/hyrolo.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 7-Jun-89 at 22:08:29 -;; Last-Mod: 1-Jun-26 at 01:14:32 by Bob Weiner +;; Last-Mod: 13-Jun-26 at 13:33:38 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -15,9 +15,9 @@ ;;; Commentary: ;; ;; This is Hyperbole's advanced rolo system, HyRolo, for convenient -;; management of hierarchical, record-oriented information. Most -;; often this is used for contact management but it can quickly be -;; adapted to most any record-oriented lookup task, for fast, full-text +;; management of hierarchical, record-oriented information. Most often +;; this is used for contact management but it can quickly be adapted to +;; most any hierarchical record-oriented lookup task, for fast, full-text ;; retrieval. ;; ;; See all the autoloaded functions herein for interactive commands. @@ -194,8 +194,12 @@ executable must be found as well (for Oauth security)." :group 'hyperbole-hyrolo) (defcustom hyrolo-file-list (list hyrolo-default-file) - "List of files containing hyrolo entries. -The first file should be a user-specific hyrolo file, typically in the home + "List of files or directories (wildcards allowed) containing hyrolo entries. +See the documentation string of `hyrolo-expand-path-list' and the manual +section \"(hyperbole)HyRolo Settings\", for how entries in this list are +expanded/resolved. + +The first entry should be a user-specific hyrolo file, typically in the home directory and must have a suffix of either .org (Org mode) or .otl (Emacs Outline mode). Other files in the list may use suffixes of .org, .otl, .md \(Markdown mode) or .kotl (Koutline mode). diff --git a/hywiki.el b/hywiki.el index 9e2e2d6e..46b6ab94 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: 10-May-26 at 11:41:49 by Bob Weiner +;; Last-Mod: 9-Jun-26 at 11:01:49 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -859,12 +859,10 @@ since the command may have moved it off a HyWikiWord." (defcustom hywiki-default-mode :pages "Customizable initial mode setting for HyWiki minor mode. -HyWiki mode has three states, any one of which can be set as the default: - - :pages - highlight HyWikiWords in HyWiki pages only (Org files in - `hywiki-directory') - - :all - highlight HyWikiWords in all editable buffers except those - with a major mode in `hywiki-exclude-major-modes'. - - nil - no highlighting, the mode is disabled." +When Hyperbole minor mode is first activated, e.g. by pressing {C-h h}, +HyWiki minor mode is initialized to the state specified by this variable. +See the documentation for the function, `hywiki-mode', for a summary of +valid state values." :type 'string :group 'hyperbole-hywiki) @@ -926,14 +924,23 @@ valid values." ;;;###autoload (define-minor-mode hywiki-mode "Toggle HyWiki global minor mode with \\[hywiki-mode]. +HyWiki minor mode automatically highlights and turns HyWikiWord references +into Hyperbole implicit buttons that either link to HyWiki pages or activate +typed referents such as bookmarks. + +HyWiki minor mode has three states as tracked by the `hywiki-mode' variable, +with the default state when interactively enabled set by the value of +`hywiki-default-mode': -HyWiki minor mode automatically highlights and turns HyWikiWord -references into implicit buttons that either link to HyWiki pages -or activate typed referents such as bookmarks. + - :pages - highlight HyWikiWords in HyWiki pages only (Org files in + `hywiki-directory'); also enable `hyperbole-mode' minor mode + if off. + + - :all - highlight HyWikiWords in all editable buffers except those + with a major mode in `hywiki-exclude-major-modes'; also + enable `hyperbole-mode' minor mode if off. -HyWiki minor mode has three states as tracked by the `hywiki-mode' -variable. See the documentation for the customization, `hywiki-default-mode', -for valid values. + - nil - no highlighting, the `hywiki-mode' is disabled. HyWikiWord references may also include optional suffixes: diff --git a/man/hyperbole.texi b/man/hyperbole.texi index 9bfa829b..922cdf5e 100644 --- a/man/hyperbole.texi +++ b/man/hyperbole.texi @@ -7,7 +7,7 @@ @c Author: Bob Weiner @c @c Orig-Date: 6-Nov-91 at 11:18:03 -@c Last-Mod: 16-May-26 at 22:48:38 by Bob Weiner +@c Last-Mod: 12-Jun-26 at 13:53:14 by Bob Weiner @c %**start of header (This is for running Texinfo on a region.) @setfilename hyperbole.info @@ -30,8 +30,8 @@ @set txicodequoteundirected @set txicodequotebacktick -@set UPDATED May 16, 2026 -@set UPDATED-MONTH May 2026 +@set UPDATED June 12, 2026 +@set UPDATED-MONTH June 2026 @set EDITION 9.0.2pre @set VERSION 9.0.2pre @@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Edition 9.0.2pre
-Printed May 16, 2026.
+Printed June 12, 2026.
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -213,7 +213,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 @example
 Edition 9.0.2pre
-May 16, 2026 @c AUTO-REPLACE-ON-SAVE
+June 12, 2026 @c AUTO-REPLACE-ON-SAVE
 
 
   Published by the Free Software Foundation, Inc.
@@ -2531,6 +2531,55 @@ minibuffer or the other window.
 When on a HyWikiWord with an existing page, display its page and
 optional section.
 
+@findex ibtypes ilink
+@cindex implicit button link
+@cindex link to implicit button
+@cindex ilink
+@anchor{ilink}
+@item link-to-ibut 
+At point, activate a link to an implicit button within the current
+buffer.  This executes the linked to implicit button's action in the
+context of the current buffer.
+
+Recognizes the format '',
+where button_file_path is given only when the link is to another file,
+e.g. .
+
+@findex ibtypes glink
+@cindex global button link
+@cindex link to global button
+@cindex glink
+@anchor{glink}
+@item link-to-gbut 
+At point, activate a link to a global button.  This executes the
+linked to global button's action in the context of the current buffer.
+
+Recognizes the format '', e.g. .
+
+@findex ibtypes elink
+@cindex explicit button link
+@cindex link to explicit button
+@cindex elink
+@anchor{elink}
+@item link-to-ebut 
+At point, activate a link to an explicit button within the current
+buffer.  This executes the linked to explicit button's action in the
+context of the current buffer.
+
+Recognizes the format '',
+where : button_file_path is given only when the link is to another file,
+e.g. ."
+
+@findex ibtypes klink
+@cindex klink
+@cindex koutline link
+@cindex kcell link
+@anchor{klink}
+@item klink
+Follow a link delimited by <> to a koutline cell.
+See the documentation for @code{actypes::link-to-kotl} for valid link
+specifiers.
+
 @findex ibtypes action
 @cindex action button
 @cindex action implicit button
@@ -2701,55 +2750,6 @@ with the following format: @file{[#]:[:
 Line and column can also include a leading and optional character, L
 for line and C for column.
 
-@findex ibtypes ilink
-@cindex implicit button link
-@cindex link to implicit button
-@cindex ilink
-@anchor{ilink}
-@item link-to-ibut 
-At point, activate a link to an implicit button within the current
-buffer.  This executes the linked to implicit button's action in the
-context of the current buffer.
-
-Recognizes the format '',
-where button_file_path is given only when the link is to another file,
-e.g. .
-
-@findex ibtypes glink
-@cindex global button link
-@cindex link to global button
-@cindex glink
-@anchor{glink}
-@item link-to-gbut 
-At point, activate a link to a global button.  This executes the
-linked to global button's action in the context of the current buffer.
-
-Recognizes the format '', e.g. .
-
-@findex ibtypes elink
-@cindex explicit button link
-@cindex link to explicit button
-@cindex elink
-@anchor{elink}
-@item link-to-ebut 
-At point, activate a link to an explicit button within the current
-buffer.  This executes the linked to explicit button's action in the
-context of the current buffer.
-
-Recognizes the format '',
-where : button_file_path is given only when the link is to another file,
-e.g. ."
-
-@findex ibtypes klink
-@cindex klink
-@cindex koutline link
-@cindex kcell link
-@anchor{klink}
-@item klink
-Follow a link delimited by <> to a koutline cell.
-See the documentation for @code{actypes::link-to-kotl} for valid link
-specifiers.
-
 @findex ibtypes man-apropos
 @cindex UNIX manual
 @cindex man pages
@@ -6768,7 +6768,7 @@ Yank            hyrolo-yank             Insert the first matching
 @end example
 
 The 'File' menu item displays and edits the first file listed in
-@code{hyrolo-file-list} unless given a prefix argument, in which case
+@code{hyrolo-file-list}, unless given a prefix argument, in which case
 it prompts with completion for the file to edit.
 
 A prefix argument used with any of the above menu items that have 'Find'
@@ -7058,18 +7058,19 @@ current frame to its state prior to the rolo search.
 @vindex hyrolo-file-list
 @cindex rolo, personal
 The files used in any rolo search are given by the
-@code{hyrolo-file-list} variable, whose default first value is given
-by the variable, @code{hyrolo-default-file} originally set to
-@code{"~/.rolo.org"}, unless the older @code{~/.rolo.otl} exists when
-Hyperbole is loaded.  You can customize @code{hyrolo-file-list} to
-include files with variables in them, wildcard patterns and
-directories, as explained below.  Any paths added to this list should
-be absolute.
+@code{hyrolo-file-list} variable, whose default first value is
+specified by the variable, @code{hyrolo-default-file}.  Its standard
+value is @code{"~/.rolo.org"}, unless the older @code{~/.rolo.otl}
+exists when Hyperbole is loaded, in which case it is used.  You can
+customize @code{hyrolo-file-list} to include files with variables in
+them, wildcard patterns and directories, as explained below.  Any
+paths added to this list should be absolute.
 
 If you include file wildcards in paths for this variable and
-@code{find-file-wildcards} is non-nil (the default), then any files
-matching the pattern (which can include [char-matches] or * wildcards
-and regular text) when the variable is set will be included in HyRolo
+@code{find-file-wildcards} is non-nil (the default), then any existing
+files matching the pattern (which can include square bracketed
+[character matches], optional characters followed by ?, or *
+wildcards) when the variable is set will be included in future HyRolo
 searches.  For more on wildcards, see @ref{Wildcards,,,emacs,the GNU
 Emacs Manual}.
 
@@ -7109,12 +7110,12 @@ following to your Emacs initialization file:
 @cindex BBDB
 @cindex Big Brother DataBase
 If you use the Big Brother DataBase (BBDB) Emacs package to capture
-email addresses and store contact information, the rolo automatically
+email addresses and store contact information, HyRolo automatically
 works with it.  If the BBDB package is loaded before HyRolo, then your
 @code{bbdb-file} of contacts is added as the second entry in
-@code{hyrolo-file-list} and will be searched automatically for any matches by
-the rolo find commands.  Presently there is no support for editing
-BBDB entries, just finding them.
+@code{hyrolo-file-list} and will be searched automatically for any
+matches by the rolo find commands.  Presently there is no support for
+editing BBDB entries, just finding them.
 
 For finding matches within only BBDB, there are the commands
 @code{hyrolo-bbdb-fgrep} (string finding) and @code{hyrolo-bbdb-grep}
@@ -7123,15 +7124,15 @@ For finding matches within only BBDB, there are the commands
 @cindex contacts, Google
 @cindex Google Contacts
 @cindex Gmail Contacts
-If you use Google/Gmail Contacts, you can configure the HyRolo to
-query your Google Contacts for matches.  First you must download and
-install the external @file{google-contacts} package using the Emacs
-Package Manager.  Then you must install the non-Emacs GNU Privacy
-Guard (GPG) package from @uref{https://gnupg.org} so that
-the @file{gpg} or @file{gpg2} executable is in your command-line
-search path.  Once these are in place, either restart Emacs or
-use @bkbd{M-x hyrolo-initialize-file-list @key{RET}} to add Google
-Contacts to your searches.
+If you use Google/Gmail Contacts, you can configure HyRolo to query
+your Google Contacts for matches.  First you must download and install
+the external @file{google-contacts} package using the Emacs Package
+Manager.  Then you must install the non-Emacs GNU Privacy Guard (GPG)
+package from @uref{https://gnupg.org} so that the @file{gpg} or
+@file{gpg2} executable is in your command-line search path.  Once
+these are in place, either restart Emacs or use @bkbd{M-x
+hyrolo-initialize-file-list @key{RET}} to add Google Contacts to your
+searches.
 
 When you next do a search, you will be prompted for your Google
 Contacts password and may also have to enter an authorization code
diff --git a/test/hibtypes-tests.el b/test/hibtypes-tests.el
index 469b02ca..e3afb297 100644
--- a/test/hibtypes-tests.el
+++ b/test/hibtypes-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell 
 ;;
 ;; Orig-Date:    20-Feb-21 at 23:45:00
-;; Last-Mod:     12-Jun-26 at 20:05:17 by Mats Lidell
+;; Last-Mod:     14-Jun-26 at 15:57:15 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -392,7 +392,7 @@
           (goto-char 4)
           (let ((err (should-error (ibtypes::ilink))))
             (should
-             (string-match-p (rx "No implicit button named " (any punct) "Button" (any punct) " found")
+             (string-match-p (rx "No button " (any punct) "Button" (any punct) " in")
                              (cadr err)))))
       (hy-delete-file-and-buffer file))))