From 758bf2b40a6bbf5aa6d9625f12b2070951a96193 Mon Sep 17 00:00:00 2001 From: bw Date: Sun, 11 Jan 2026 05:58:52 -0500 Subject: [PATCH 1/6] hywiki.el - Rework to use per-buffer command hooks Remove use of 'page-name' in hywiki reference functions. Make hywiki-mode code follow the doc specification. --- ChangeLog | 59 ++++ hibtypes.el | 49 ++- hsys-activities.el | 28 +- hynote.el | 6 +- hyperbole.el | 8 +- hywiki.el | 771 +++++++++++++++++++++++-------------------- hywiki/HyWiki.org | 12 +- man/hyperbole.texi | 26 +- test/hywiki-tests.el | 10 +- 9 files changed, 557 insertions(+), 412 deletions(-) diff --git a/ChangeLog b/ChangeLog index 965f6eb0..e4b52b90 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,62 @@ +2026-01-06 Bob Weiner + +* hywiki.el (hywiki-get-buffers-in-windows): Add and call in + 'hywiki-get-buffers'. + +2026-01-05 Bob Weiner + +* hibtypes.el (hywiki-word): Move from "hywiki.el" to here. + +* hyperbole.el: Add (require 'hywiki). + (hyperb:init): (hywiki-mode :pages) at the end. + +2026-01-02 Bob Weiner + +* hywiki.el (hywiki-maybe-highlight-page-names): Rename to + 'hywiki-maybe-highlight-references'. + (hywiki-maybe-highlight-page-name): Rename to + 'hywiki-maybe-highlight-reference'. + (hywiki-maybe-highlight-between-page-names): Rename to + 'hywiki-maybe-highlight-between-references'. + (hywiki-maybe-highlight-off-page-name): Rename to + 'hywiki-maybe-highlight-off-reference'. + (hywiki-maybe-highlight-on-page-name): Rename to + 'hywiki-maybe-highlight-on-reference'. + (hywiki-maybe-highlight-word): Rename to + 'hywiki-maybe-highlight-region-reference'. + (hywiki-maybe-dehighlight-page-names): Rename to + 'hywiki-maybe-dehighlight-references'. + (hywiki-maybe-dehighlight-between-page-names): Rename to + 'hywiki-maybe-dehighlight-between-references'. + (hywiki-maybe-dehighlight-off-page-name): Rename to + 'hywiki-maybe-dehighlight-off-reference'. + (hywiki-maybe-dehighlight-on-page-name): Rename to + 'hywiki-maybe-dehighlight-on-reference'. + (hywiki-maybe-dehighlight-page-name): Rename to + 'hywiki-maybe-dehighlight-reference'. + +2025-12-30 Bob Weiner + +* hywiki.el (hywiki-get-buffers): Add to return active hywiki-mode buffers. + (hywiki-word-set-auto-highlighting): Rewrite to account for 'hywiki-mode' + setting before and after this call. Apply highlighting hooks locally + to each buffer. Remove interactive use. + (hywiki-word-highlight-buffers, hywiki-word-dehighlight-buffers): Add and use in above function. + +2025-12-27 Bob Weiner + +* hywiki.el (hywiki-word-highlight-flag, hywiki-word-highlight-flag-changed): Remove. + (hywiki-mode, hywiki-in-page-p): Remove 'hywiki-word-highlight-flag' and + update to support` all 'hywiki-mode' values. + (hywiki-maybe-dehighlight-sexp): + (hywiki-active-in-current-buffer-p): + (hywiki-word-set-auto-highlighting): Replace 'hywiki-word-highlight-flag' + with 'hywiki-mode'. + test/hywiki-tests.el (hywiki-tests--active-in-current-buffer-p): + +* hibtypes.el (hywiki-existing-word): + hywiki.el (hywiki-word): Skip if not 'hywiki-active-in-current-buffer-p'. + 2025-12-13 Bob Weiner * MANIFEST: Add "HY-TALK/HYPERBOLEQA.kotl" from EmacsConf2025 talk. diff --git a/hibtypes.el b/hibtypes.el index ce1b8ed7..ed8a83c5 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: 22-Nov-25 at 12:40:34 by Bob Weiner +;; Last-Mod: 5-Jan-26 at 23:42:19 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -108,8 +108,28 @@ ;;; Creates and displays personal wiki pages and sections with auto-wikiword links ;;; ======================================================================== -;; Defines `hywiki-word' ibtype -(load "hywiki" nil t) +(defib hywiki-word () + "When on a non-existing HyWikiWord, create it and display its referent. +A call to (hywiki-active-in-current-buffer-p) must return non-nil +for this to activate. + +If the associated HyWiki referent is a page, 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. + +Existing HyWikiWords are handled by the implicit button type +`hywiki-existing-word'." + (when (hywiki-active-in-current-buffer-p) + (let* ((wikiword-start-end (hywiki-highlight-word-get-range)) + (wikiword (nth 0 wikiword-start-end)) + (start (nth 1 wikiword-start-end)) + (end (nth 2 wikiword-start-end))) + (when wikiword + (unless (or (ibtypes::pathname-line-and-column) + (ibtypes::pathname)) + (ibut:label-set wikiword start end) + (hact 'hywiki-word-create-and-display wikiword)))))) ;;; ======================================================================== ;;; Jumps to source line from Python traceback lines @@ -1713,25 +1733,28 @@ If a boolean function or variable, display its value." (error "(action:help): No action button labeled: %s" label))))) ;;; ======================================================================== -;;; Activates HyWikiWords with existing HyWiki pages. +;;; Activates HyWikiWords with existing referents. ;;; Non-existing HyWikiWords are handled by the (load "hywiki") at a low ;;; priority earlier in this file which defines the `hywiki-word' ibtype. ;;; ======================================================================== (defib hywiki-existing-word () "On a HyWikiWord with an existing referent, display the referent. +A call to (hywiki-active-in-current-buffer-p) must return non-nil +for this to activate. See the implicit button type `hywiki-word' for creation of referents to not yet existing HyWikiWords." - (cl-destructuring-bind (wikiword start end) - (hywiki-referent-exists-p :range) - (when wikiword - (unless (or (ibtypes::pathname-line-and-column) - (ibtypes::pathname)) - (if (and start end) - (ibut:label-set wikiword start end) - (ibut:label-set wikiword)) - (hact 'hywiki-find-referent wikiword))))) + (when (hywiki-active-in-current-buffer-p) + (cl-destructuring-bind (wikiword start end) + (hywiki-referent-exists-p :range) + (when wikiword + (unless (or (ibtypes::pathname-line-and-column) + (ibtypes::pathname)) + (if (and start end) + (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/hsys-activities.el b/hsys-activities.el index 9131ae13..433f381f 100644 --- a/hsys-activities.el +++ b/hsys-activities.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 7-Dec-25 at 22:48:29 -;; Last-Mod: 11-Dec-25 at 22:26:21 by Mats Lidell +;; Last-Mod: 2-Jan-26 at 21:31:06 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -28,8 +28,15 @@ ;;; Requirements ;;; ************************************************************************ +(hypb:require-package 'activities) (require 'hypb) +(add-hook 'activities-tabs-mode-hook + (lambda () + (when activities-tabs-mode + (advice-remove #'activities-resume #'activities-tabs-before-resume) + (advice-add #'hsys-activities-before-resume :before #'activities-tabs-before-resume)))) + ;;; ************************************************************************ ;;; Public declarations ;;; ************************************************************************ @@ -55,27 +62,32 @@ - If activity NAME is not active, switch to its latest state. - If activity NAME is active and current, revert to its default state. - If activity NAME is active and hsys-activity is called with - `current-prefix-arg' set then set the default state." + `current-prefix-arg', then update the default state." (interactive (list (completing-read "Activity: " (activities-names) nil nil))) - (hypb:require-package 'activities) (let ((activity (activities-named name))) (cond ((not activity) (activities-define name) - (message "Activity %s defined." name)) + (message "Activity %s defined" name)) ((let ((current-activity (activities-current))) (and current-activity - (string= + (string-equal (activities-name-for activity) (activities-name-for current-activity)))) (if current-prefix-arg (progn (activities-define name :forcep t) - (message "Activity %s set to new default." name)) + (message "Activity %s set to new default" name)) (activities-revert activity) - (message "Activity %s reverted." name))) + (message "Activity %s reverted" name))) (t (activities-resume activity) - (message "Activity %s resumed." name))))) + (message "Activity %s resumed" name))))) + +(defun hsys-activities-before-resume (activity) + (if (and activities-tabs-mode + (tab-switcher-current-tab nil)) + (activities-revert activity) + (activities-resume activity))) (provide 'hsys-activities) ;;; hsys-activities.el ends here diff --git a/hynote.el b/hynote.el index 4a01fff1..e7099e37 100644 --- a/hynote.el +++ b/hynote.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 23-Jun-24 at 12:50:37 -;; Last-Mod: 1-Sep-24 at 14:26:02 by Bob Weiner +;; Last-Mod: 2-Jan-26 at 20:13:25 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -105,7 +105,7 @@ After successfully finding a file and reading it into a buffer, run (when (and (stringp section) (not (string-prefix-p "#" section))) (setq section (concat "#" section))) (hpath:find (concat file section)) - (hywiki-maybe-highlight-page-names) + (hywiki-maybe-highlight-references) (run-hooks 'hynote-find-file-hook) file)) @@ -126,7 +126,7 @@ After successfully finding a file and reading it into a buffer, run (substring file-stem-name (match-beginning 0)))) (when file (hpath:find (concat file section)) - (hywiki-maybe-highlight-page-names) + (hywiki-maybe-highlight-references) (run-hooks 'hynote-find-file-hook) file))))) diff --git a/hyperbole.el b/hyperbole.el index 00ab699a..b85a01d9 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: 2-Oct-25 at 14:28:52 by Mats Lidell +;; Last-Mod: 6-Jan-26 at 00:54:01 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 @@ -180,6 +180,7 @@ Info documentation at \"(hyperbole)Top\". (require 'set (expand-file-name "set" hyperb:dir)) (require 'hypb) (require 'hui-select) ;; This requires 'hvar which defines the var:append function. +(require 'hywiki) ;;; ************************************************************************ ;;; Public Variables @@ -500,7 +501,7 @@ frame, those functions by default still return the prior frame." ;; loaded parts of Org before his load path is finalized. It loads ;; the newer version of Org, if any, assuming `load-path' is configured ;; correctly. - (hsys-org-fix-version) + ;; (hsys-org-fix-version) ;; ;; When vertico-mode is used, vertico-mouse-mode is needed for the ;; Action Key to properly select completions from the candidate @@ -509,6 +510,9 @@ frame, those functions by default still return the prior frame." (when (fboundp #'vertico-mouse-mode) (add-hook 'vertico-mode-hook (lambda () (vertico-mouse-mode 1)))) ;; + ;; Set HyWiki page auto-HyWikiWord highlighting and `yank-handled-properties' + (hywiki-mode :pages) + ;; ;; Hyperbole initialization is complete. (message "Initializing Hyperbole...done")) diff --git a/hywiki.el b/hywiki.el index e86769e8..2bb55eb2 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: 30-Nov-25 at 18:06:52 by Bob Weiner +;; Last-Mod: 11-Jan-26 at 05:58:25 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -24,7 +24,7 @@ ;; ;; HyWikiWords are also recognized in text buffers after the global ;; minor mode, `hywiki-mode' is enabled via {M-x hywiki-mode RET}. To -;; create or jump to a HyWiki page, simply type out a potential +;; create or jump to a HyWiki page, simply type o ut a potential ;; HyWikiWord or move point onto one and press the Action Key {M-RET}. ;; This will create the associated page if it does not exist. This ;; also highlights any other instances of HyWikiWords across all @@ -68,15 +68,14 @@ ;; When activating a link with a section reference, you will get an ;; error if the section does not exist. ;; -;; The custom setting, `hywiki-word-highlight-flag' (default = t), -;; means HyWikiWords will be auto-highlighted within HyWiki pages. -;; Outside of such pages, `hywiki-mode' must also be enabled for such -;; auto-highlighting. Auto-highlighting depends on pre- and +;; By default (hywiki-mode = :pages), HyWikiWords are +;; auto-highlighted within HyWiki pages only. Outside of such pages, +;; `hywiki-mode' must be set to :all to enable auto-highlighting in +;; programming and text modes. Auto-highlighting depends on pre- and ;; `post-command-hook' settings. If an error occurs running one of -;; these, the associated hook is removed. To restore the auto-highlight -;; hooks either use {M-x hywiki-word-set-auto-highlighting RET} or -;; {C-u C-h h h m} to toggle `hywiki-mode'; this also enables -;; auto-highlighting if `hywiki-word-highlight-flag' is non-nil. +;; these, the associated hook is removed. To restore the +;; auto-highlight hooks use {C-u C-h h h m} to toggle `hywiki-mode'; +;; this also enables auto-highlighting when `hywiki-mode' is non-nil. ;; The custom setting, `hywiki-exclude-major-modes' (default = nil), is ;; a list of major modes to exclude from HyWikiWord auto-highlighting @@ -89,7 +88,7 @@ ;; (default = '(lisp-interaction-mode)). ;; ;; HyWiki adds two implicit button types to Hyperbole: -;; `hywiki-word' - creates and displays HyWikiWord referents; +;; `hywiki-word' - create and display HyWikiWord referents; ;; `hywiki-existing-word' - display an existing HyWikiWord referent. ;; ;; `hywiki-word' is one of the lowest priority implicit button types @@ -231,7 +230,7 @@ Each element is of the form: (wikiword . (referent-type . referent-value)).") "HyWiki hash table for fast WikiWord referent lookup.") ;; Globally set these values to avoid using 'let' with stack allocations -;; within `hywiki-maybe-highlight-page-name' frequently. +;; within `hywiki-maybe-highlight-reference' frequently. (defvar hywiki--any-wikiword-regexp-list nil) (defvar hywiki--current-page nil) (defvar hywiki--highlighting-done-flag t) @@ -254,25 +253,6 @@ Each element is of the form: (wikiword . (referent-type . referent-value)).") ;;; Public variables ;;; ************************************************************************ -(defcustom hywiki-word-highlight-flag t - "The default, non-nil value treats HyWikiWords in HyWiki pages as hyperlinks. -A nil value disables HyWikiWord hyperlink buttons in both HyWiki -pages and all other buffers (since it also disables `hywiki-mode'). - -Outside of HyWiki pages, the global minor mode `hywiki-mode' must be -manually enabled for auto-HyWikiWord highlighting. Interactively, {C-h -h h m a} does this; programmatically, use `(hywiki-mode :all)' to -enable it. - -Use `hywiki-active-in-current-buffer-p' to determine if HyWikiWord -hyperlinks are currently active in a buffer or not. - -Regardless of this flag, HyWikiWords in Org links and targets are not -highlighted nor treated as hyperlinks; they are handled normally by Org." - :type 'boolean - :initialize #'custom-initialize-default - :group 'hyperbole-hywiki) - (defcustom hywiki-exclude-major-modes nil "List of major modes to exclude from HyWikiWord highlighting and recognition." :type '(list symbol) @@ -464,7 +444,7 @@ where PATH is the un-resolvable reference." The file must be below `hywiki-directory'. For reference, this is set when `window-buffer-change-functions' calls -`hywiki-maybe-highlight-page-names' which calls `hywiki-in-page-p'.") +`hywiki-maybe-highlight-references' which calls `hywiki-in-page-p'.") (defcustom hywiki-referent-prompt-flag nil "When t, the Action Key and HyWiki/Create always prompt for referent type. @@ -666,8 +646,8 @@ deletion commands and those in `hywiki-non-character-commands'." (hywiki--extend-region (min hywiki--start hywiki--end) (max hywiki--start hywiki--end)) - (hywiki-maybe-dehighlight-page-names start end) - (hywiki-maybe-highlight-page-names start end)))) + (hywiki-maybe-dehighlight-references start end) + (hywiki-maybe-highlight-references start end)))) ((when (or (memq this-command hywiki-non-character-commands) (and (symbolp this-command) @@ -765,9 +745,9 @@ or activate typed referents such as bookmarks. HyWiki minor mode has three states as tracked by the following values of the `hywiki-mode' variable: - :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'. + `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. HyWikiWord references may also include optional suffixes: @@ -789,6 +769,23 @@ See the Info documentation at \"(hyperbole)HyWiki\". :keymap hywiki-mode-map :group 'hyperbole-hywiki (progn + (unless hywiki-mode-map + (setq hywiki-mode-map (make-sparse-keymap))) + ;; Normalize `hywiki-mode' setting + (cond + ((or (and (integerp hywiki-mode) (= hywiki-mode 1)) + (memq hywiki-mode '(:all t))) + ;; Enable across all editable buffers + (setq hywiki-mode :all)) + ((or (and (integerp hywiki-mode) (<= hywiki-mode 0)) + (null hywiki-mode)) + ;; Disable across all editable buffers. + (setq hywiki-mode nil)) + (t ;; (> hywiki-mode 1) + ;; Enable in HyWiki page buffers only + (setq hywiki-mode :pages))) + + ;; Normalize `arg' and set mode (when (memq arg '(toggle :toggle)) ;; Toggle across all editable buffers (setq arg (if hywiki-mode 1 0))) @@ -796,53 +793,34 @@ See the Info documentation at \"(hyperbole)HyWiki\". ((or (and (integerp arg) (= arg 1)) (memq arg '(:all t))) ;; Enable across all editable buffers + (setq arg :all) ;; Need hyperbole-mode - (require 'hyperbole) (unless hyperbole-mode (hyperbole-mode 1)) - (unless hywiki-mode-map - (setq hywiki-mode-map (make-sparse-keymap))) - ;; Next line triggers a call to `hywiki-word-set-auto-highlighting'. - (set-variable 'hywiki-word-highlight-flag t) - (setq hywiki-mode :all)) + (hywiki-word-set-auto-highlighting hywiki-mode arg) + (setq hywiki-mode arg)) ((or (and (integerp arg) (<= arg 0)) (null arg)) ;; Disable across all editable buffers. + (setq arg nil) ;; Dehighlight HyWikiWords in this buffer when 'hywiki-mode' is ;; disabled and this is not a HyWiki page buffer. If this is a - ;; HyWiki page buffer, then dehighlight when - ;; `hywiki-word-highlight-flag' is nil. + ;; HyWiki page buffer, then dehighlight when `hywiki-mode' is nil. (hywiki-maybe-highlight-wikiwords-in-frame t) - (setq hywiki-mode nil)) + (setq hywiki-mode arg)) (t ;; (> arg 1) ;; Enable in HyWiki page buffers only - ;; Next line triggers a call to `hywiki-word-set-auto-highlighting'. - (set-variable 'hywiki-word-highlight-flag t) - (setq hywiki-mode :pages))))) + (setq arg :pages) + ;; Need hyperbole-mode + (unless hyperbole-mode + (hyperbole-mode 1)) + (hywiki-word-set-auto-highlighting hywiki-mode arg) + (setq hywiki-mode arg))))) ;;; ************************************************************************ ;;; Public Implicit Button and Action Types ;;; ************************************************************************ -(defib hywiki-word () - "When on a non-existing HyWikiWord, create it and display its referent. -If the associated HyWiki referent is a page, 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. - -Existing HyWikiWords are handled by the implicit button type -`hywiki-existing-word'." - (let* ((wikiword-start-end (hywiki-highlight-word-get-range)) - (wikiword (nth 0 wikiword-start-end)) - (start (nth 1 wikiword-start-end)) - (end (nth 2 wikiword-start-end))) - (when wikiword - (unless (or (ibtypes::pathname-line-and-column) - (ibtypes::pathname)) - (ibut:label-set wikiword start end) - (hact 'hywiki-word-create-and-display wikiword))))) - (defun hywiki-display-referent-type (wikiword referent) "Display WIKIWORD REFERENT, a cons of ( . ). Function used to display is \"hywiki-display-\"." @@ -890,15 +868,15 @@ After successfully finding a referent, run `hywiki-display-referent-hook'." wikiword referent) ;; Ensure highlight any page name at point in case called as a ;; Hyperbole action type - (hywiki-maybe-highlight-page-name t) + (hywiki-maybe-highlight-reference t) (hywiki-display-referent-type wikiword referent) - (hywiki-maybe-highlight-page-names) + (hywiki-maybe-highlight-references) (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-references) nil))) (defun hywiki-help () @@ -1014,13 +992,13 @@ with the referent." (defun hywiki-active-in-current-buffer-p () "Return non-nil if HyWikiWord links are active in the current buffer. Exclude the minibuffer if selected and return nil." - (and hywiki-word-highlight-flag + (and hywiki-mode (not (minibuffer-window-active-p (selected-window))) (not (and (boundp 'edebug-active) edebug-active (active-minibuffer-window))) - (or (derived-mode-p 'kotl-mode) - (not (eq (get major-mode 'mode-class) 'special))) (not (apply #'derived-mode-p hywiki-exclude-major-modes)) - (or hywiki-mode (hywiki-in-page-p)))) + (or (and (eq hywiki-mode :pages) (hywiki-in-page-p)) + (derived-mode-p 'kotl-mode) + (not (eq (get major-mode 'mode-class) 'special))))) (defun hywiki-add-activity (wikiword) "Make WIKIWORD resume a prompted for activity. @@ -1546,7 +1524,7 @@ simplifies to: (barf-if-buffer-read-only) ;; Need to be explicit about the region here so does not use markers ;; from a region pointing to another buffer - (hywiki-maybe-highlight-page-names (point-min) (point-max)) + (hywiki-maybe-highlight-references (point-min) (point-max)) (let ((make-index (hywiki-org-get-publish-property :makeindex)) org-link wikiword-and-section @@ -1745,8 +1723,15 @@ After successfully finding any kind of referent, run ;; included. (cl-destructuring-bind (start end) (hywiki--extend-region start end) - (hywiki-maybe-highlight-page-names start (min end (point-max))))) + (hywiki-maybe-highlight-references start (min end (point-max))))) + +(defun hywiki-highlight-page () + "Rehighlight all HyWikiWord references when in a HyWiki page." + (interactive) + (setq hywiki-buffer-highlighted-state nil) + (hywiki-maybe-highlight-references)) +;;;###autoload (defun hywiki-map-words (func) "Apply FUNC across highlighted HyWikiWords in the current buffer and return nil. This temporarily expands the buffer so all HyWikiWord references are processed. @@ -1852,7 +1837,7 @@ This includes the delimiters: (), {}, <>, [] and \"\" (double quotes)." "Insert at point a link to a HyWiki page." (interactive "*") (insert (hywiki-word-read "Link to HyWiki page: ")) - (hywiki-maybe-highlight-page-name)) + (hywiki-maybe-highlight-reference)) (defun hywiki-maybe-dehighlight-balanced-pairs () "Before or after a balanced delimiter, dehighlight HyWikiWords within. @@ -1923,90 +1908,7 @@ Ignore return value; it has no meaning." ;; Dehighlight HyWikiWords in any string following point (hywiki-maybe-dehighlight-sexp 1))))))) -(defun hywiki-maybe-highlight-balanced-pairs () - "Before or after a balanced delimiter, highlight HyWikiWords within. -Include: (), {}, <>, [] and \"\" (double quotes). Exclude Org links -and radio targets. - -Range is limited to the previous, current and next lines, as HyWikiWord -references are limited to two lines maximum. - -Return t if no errors and a pair was found, else nil." - (save-excursion - (save-restriction - (if (hywiki--buttonized-region-p) - (narrow-to-region hywiki--buttonize-start hywiki--buttonize-end) - ;; Limit balanced pair checks to two lines around point for speed - (narrow-to-region (line-beginning-position 0) (line-end-position 2))) - - (let ((result t)) - (condition-case nil - ;; char-before - (cond ((memq (char-before) '(?\[ ?\<)) - (goto-char (1- (point))) - ;; Highlight any HyWikiWords within single opening - ;; square or angle brackets - ;; Dehighlight HyWikiWords within double opening square - ;; or angle brackets, as these are Org links and targets - (hywiki-maybe-highlight-org-element-forward)) - ((memq (char-before) '(?\( ?\{)) - ;; Highlight any HyWikiWords within opening parens or braces - (goto-char (1- (point))) - (hywiki-maybe-highlight-sexp 1)) - ((and (eq (char-before) ?\") - (hypb:in-string-p)) - (goto-char (1- (point))) - (hywiki-maybe-highlight-sexp 1)) - ((memq (char-before) '(?\] ?\>)) - ;; Dehighlight HyWikiWords within double closing square - ;; or angle brackets, as these are Org links and targets - (hywiki-maybe-highlight-org-element-backward)) - ((memq (char-before) '(?\) ?\})) - ;; Highlight any HyWikiWords within closing parens or braces - (hywiki-maybe-highlight-sexp -1)) - ((and (eq (char-before) ?\") - (not (hypb:in-string-p))) - ;; Highlight HyWikiWords in any string preceding point - (hywiki-maybe-highlight-sexp -1)) - (t (setq result nil))) - (error (setq result nil))) - - (when result - (condition-case nil - ;; char-after - (cond ((memq (char-after) '(?\[ ?\<)) - ;; Highlight any HyWikiWords within single opening - ;; square or angle brackets - ;; Dehighlight HyWikiWords within double opening square - ;; or angle brackets, as these are Org links and targets - (hywiki-maybe-highlight-org-element-forward)) - ((memq (char-after) '(?\( ?\{)) - ;; Highlight any HyWikiWords within opening parens or braces - (hywiki-maybe-highlight-sexp 1)) - ((and (eq (char-after) ?\") - (hypb:in-string-p)) - (goto-char (1+ (point))) - (hywiki-maybe-highlight-sexp -1)) - ((memq (char-after) '(?\] ?\>)) - (goto-char (1+ (point))) - ;; Highlight any HyWikiWords within single closing - ;; square or angle brackets - ;; Dehighlight HyWikiWords within double closing square - ;; or angle brackets, as these are Org links and targets - (hywiki-maybe-highlight-org-element-backward)) - ((memq (char-after) '(?\) ?\})) - ;; Highlight any HyWikiWords within closing parens or braces - (goto-char (1+ (point))) - (hywiki-maybe-highlight-sexp -1)) - ((and (eq (char-after) ?\") - (not (hypb:in-string-p))) - ;; Highlight HyWikiWords in any string following point - (hywiki-maybe-highlight-sexp 1)) - (t (setq result nil))) - (error (setq result nil)))) - (when result t))))) - -(defun hywiki-maybe-dehighlight-between-page-names () +(defun hywiki-maybe-dehighlight-between-references () "Dehighlight any non-Org link HyWiki page#section between point. If in a programming mode, must be within a comment or string. Use `hywiki-word-face' to dehighlight." @@ -2031,38 +1933,49 @@ If in a programming mode, must be within a comment or string. Use (equal (hywiki-referent-exists-p :range) '(nil nil nil)) ;; non-existing wikiword - (hywiki-maybe-dehighlight-on-page-name))) + (hywiki-maybe-dehighlight-on-reference))) t))) ((looking-at "[ \t\n\r\f]") - (hywiki-maybe-dehighlight-off-page-name) - (hywiki-maybe-dehighlight-on-page-name)))) + (hywiki-maybe-dehighlight-off-reference) + (hywiki-maybe-dehighlight-on-reference)))) -(defun hywiki-maybe-dehighlight-off-page-name () +(defun hywiki-maybe-dehighlight-off-reference () "Dehighlight any non-Org link HyWiki page#section at or one char before point. If on a whitespace character or at end of buffer, handle dehighlighting for any previous word or punctuation. If in a programming mode, must be within a comment." ;; Dehighlight any page name at point - (hywiki-maybe-dehighlight-page-name + (hywiki-maybe-dehighlight-reference ;; Flag on-page-name if on a whitespace character (or (= (point) (point-max)) (= (if (char-after) (char-syntax (char-after)) 0) ? )))) -(defun hywiki-maybe-dehighlight-on-page-name () +(defun hywiki-maybe-dehighlight-on-reference () "Dehighlight any non-Org link HyWiki page#section at or one char before point. If not on a whitespace character, handle dehighlighting for any page/section name or punctuation. If in a programming mode, must be within a comment." ;; Dehighlight any page name at point - (hywiki-maybe-dehighlight-page-name + (hywiki-maybe-dehighlight-reference ;; Flag on-page-name if not on a whitespace character (and (/= (point) (point-max)) (/= (if (char-after) (char-syntax (char-after)) 0) ? )))) +(defun hywiki-maybe-dehighlight-org-element-backward () + "Dehighlight HyWikiWords within a closing double/single square/angle bracket." + (hywiki--maybe-de/highlight-org-element-backward #'hywiki-maybe-dehighlight-sexp)) + +(defun hywiki-maybe-dehighlight-org-element-forward () + "Dehighlight HyWikiWords within an opening double/single square/angle bracket." + (hywiki--maybe-de/highlight-org-element-forward #'hywiki-maybe-dehighlight-sexp)) + ;;;###autoload -(defun hywiki-maybe-dehighlight-page-name (&optional on-page-name) +(defun hywiki-maybe-dehighlight-reference (&optional on-reference) "Dehighlight any non-Org link HyWiki page#section at or one char before point. -With optional ON-PAGE-NAME non-nil, assume point is within the page or +A call to `hywiki-active-in-current-buffer-p' at point must return non-nil or +this function does nothing. + +With optional ON-REFERENCE non-nil, assume point is within the page or section name. Otherwise, if `pre-command-hook' has set `hywiki--buttonize-start' `hywiki--buttonize-end' global variables, use these as the region in which to dehighlight. @@ -2078,7 +1991,7 @@ If in a programming mode, must be within a comment. Use ;; Non-nil if match is inside a comment or a string (or (nth 4 (syntax-ppss)) (hypb:in-string-p)) t) - (or on-page-name + (or on-reference (and (characterp last-command-event) (string-match (regexp-quote (char-to-string (char-syntax last-command-event))) @@ -2093,14 +2006,14 @@ If in a programming mode, must be within a comment. Use (narrow-to-region hywiki--buttonize-start hywiki--buttonize-end) (goto-char hywiki--buttonize-start)) - (unless on-page-name + (unless on-reference ;; after page name (skip-syntax-backward ">-")) (hywiki-maybe-dehighlight-balanced-pairs) (unless hywiki--highlighting-done-flag - (unless on-page-name + (unless on-reference ;; May be a non-delimiter but HyWikiWord ending punctuation to ;; skip past (skip-chars-backward (hywiki-get-buttonize-characters))) @@ -2129,9 +2042,192 @@ If in a programming mode, must be within a comment. Use 'face hywiki-word-face)))))))) ;;;###autoload -(defun hywiki-maybe-highlight-page-name (&optional on-page-name) +(defun hywiki-maybe-dehighlight-references (&optional region-start region-end) + "Dehighlight any highlighted HyWiki page names in a HyWiki buffer/region. +With optional REGION-START and REGION-END positions (active region +interactively), limit dehighlighting to the region. + +Does nothing if either `hywiki-buffer-highlighted-state' is set to \='d +or a call to `hywiki-active-in-current-buffer-p' at point returns non-nil." + (interactive (when (use-region-p) (list (region-beginning) (region-end)))) + (unless (or (eq hywiki-buffer-highlighted-state 'd) + (hywiki-active-in-current-buffer-p)) + (hproperty:but-clear-all-in-list + (hproperty:but-get-all-in-region + (if (markerp region-start) + (if (marker-position region-start) + region-start + (point-min)) + (or region-start (point-min))) + (if (markerp region-end) + (if (marker-position region-end) + region-end + (point-max)) + (or region-end (point-max))) + 'face hywiki-word-face)) + (unless (or region-start region-end) + (setq hywiki-buffer-highlighted-state 'd)))) + +(defun hywiki-maybe-dehighlight-sexp (direction-number) + "Dehighlight any HyWikiWord within single square/angle bracket. +DIRECTION-NUMBER is 1 for forward scanning and -1 for backward scanning." + ;; Enable dehighlighting in HyWiki pages + (let ((hywiki-mode)) + (hywiki--maybe-de/highlight-sexp + #'hywiki-maybe-dehighlight-references direction-number))) + +;;;###autoload +(defun hywiki-maybe-highlight-balanced-pairs () + "Before or after a balanced delimiter, highlight HyWikiWords within. +Include: (), {}, <>, [] and \"\" (double quotes). Exclude Org links +and radio targets. + +Range is limited to the previous, current and next lines, as HyWikiWord +references are limited to two lines maximum. + +Return t if no errors and a pair was found, else nil." + (save-excursion + (save-restriction + (if (hywiki--buttonized-region-p) + (narrow-to-region hywiki--buttonize-start hywiki--buttonize-end) + ;; Limit balanced pair checks to two lines around point for speed + (narrow-to-region (line-beginning-position 0) (line-end-position 2))) + + (let ((result t)) + (condition-case nil + ;; char-before + (cond ((memq (char-before) '(?\[ ?\<)) + (goto-char (1- (point))) + ;; Highlight any HyWikiWords within single opening + ;; square or angle brackets + ;; Dehighlight HyWikiWords within double opening square + ;; or angle brackets, as these are Org links and targets + (hywiki-maybe-highlight-org-element-forward)) + ((memq (char-before) '(?\( ?\{)) + ;; Highlight any HyWikiWords within opening parens or braces + (goto-char (1- (point))) + (hywiki-maybe-highlight-sexp 1)) + ((and (eq (char-before) ?\") + (hypb:in-string-p)) + (goto-char (1- (point))) + (hywiki-maybe-highlight-sexp 1)) + ((memq (char-before) '(?\] ?\>)) + ;; Dehighlight HyWikiWords within double closing square + ;; or angle brackets, as these are Org links and targets + (hywiki-maybe-highlight-org-element-backward)) + ((memq (char-before) '(?\) ?\})) + ;; Highlight any HyWikiWords within closing parens or braces + (hywiki-maybe-highlight-sexp -1)) + ((and (eq (char-before) ?\") + (not (hypb:in-string-p))) + ;; Highlight HyWikiWords in any string preceding point + (hywiki-maybe-highlight-sexp -1)) + (t (setq result nil))) + (error (setq result nil))) + + (when result + (condition-case nil + ;; char-after + (cond ((memq (char-after) '(?\[ ?\<)) + ;; Highlight any HyWikiWords within single opening + ;; square or angle brackets + ;; Dehighlight HyWikiWords within double opening square + ;; or angle brackets, as these are Org links and targets + (hywiki-maybe-highlight-org-element-forward)) + ((memq (char-after) '(?\( ?\{)) + ;; Highlight any HyWikiWords within opening parens or braces + (hywiki-maybe-highlight-sexp 1)) + ((and (eq (char-after) ?\") + (hypb:in-string-p)) + (goto-char (1+ (point))) + (hywiki-maybe-highlight-sexp -1)) + ((memq (char-after) '(?\] ?\>)) + (goto-char (1+ (point))) + ;; Highlight any HyWikiWords within single closing + ;; square or angle brackets + ;; Dehighlight HyWikiWords within double closing square + ;; or angle brackets, as these are Org links and targets + (hywiki-maybe-highlight-org-element-backward)) + ((memq (char-after) '(?\) ?\})) + ;; Highlight any HyWikiWords within closing parens or braces + (goto-char (1+ (point))) + (hywiki-maybe-highlight-sexp -1)) + ((and (eq (char-after) ?\") + (not (hypb:in-string-p))) + ;; Highlight HyWikiWords in any string following point + (hywiki-maybe-highlight-sexp 1)) + (t (setq result nil))) + (error (setq result nil)))) + (when result t))))) + +(defun hywiki-maybe-highlight-between-references () + "Highlight any non-Org link HyWiki page#section names between point. + +If in a programming mode, must be within a comment. Use +`hywiki-word-face' to highlight. Do not highlight references to +the current page unless they have sections attached." + (cond ((hproperty:char-property-range (point) 'face hywiki-word-face)) + ((cl-destructuring-bind (word start end) + (hywiki-highlight-word-get-range) + (when (and start end) + (save-excursion + (goto-char start) + (when (hywiki-referent-exists-p word) + ;; existing wikiword + (hywiki-maybe-highlight-on-reference))) + t))) + ((cl-destructuring-bind (start end) + (hywiki-at-range-delimiter) + (when (and start end) + (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "-" (line-end-position)) + (unless (equal (hywiki-referent-exists-p :range) + '(nil nil nil)) + ;; existing wikiword + (hywiki-maybe-highlight-on-reference))) + t))) + ((looking-at "[ \t\n\r\f]") + (hywiki-maybe-highlight-off-reference) + (hywiki-maybe-highlight-on-reference)) + (t (hywiki-maybe-highlight-on-reference)))) + +(defun hywiki-maybe-highlight-off-reference () + "Highlight any non-Org link HyWiki page#section at or one char before point. +If at bobp or any preceding char is non-whitespace and any following +character is whitespace or at eobp, handle highlighting for any previous +word or punctuation. + +If in a programming mode, must be within a comment. Use +`hywiki-word-face' to highlight. Do not highlight references to +the current page unless they have sections attached." + (hywiki-maybe-highlight-reference + ;; flag on-reference if on a whitespace character + (and (or (= (point) (point-max)) + (= (if (char-after) (char-syntax (char-after)) 0) ?\ )) + (or (= (point) (point-min)) + (/= (if (char-before) (char-syntax (char-before)) 0) ?\ ))))) + +(defun hywiki-maybe-highlight-on-reference () + "Highlight any non-Org link HyWiki page#section at or one char before point. +If not on a whitespace character, handle highlighting for any page/section +name or punctuation. + +If in a programming mode, must be within a comment. Use +`hywiki-word-face' to highlight. Do not highlight references to +the current page unless they have sections attached." + (hywiki-maybe-highlight-reference + ;; flag on-reference if not on a whitespace character + (and (/= (point) (point-max)) + (/= (if (char-after) (char-syntax (char-after)) 0) ? )))) + +;;;###autoload +(defun hywiki-maybe-highlight-reference (&optional on-reference) "Highlight any non-Org link HyWikiWord#section at or one char before point. -With optional ON-PAGE-NAME non-nil, assume point is within the page or +A call to `hywiki-active-in-current-buffer-p' at point must return non-nil or +this function does nothing. + +With optional ON-REFERENCE non-nil, assume point is within the page or section name. Otherwise, if a HyWiki per-character hook has set `hywiki--buttonize-start' `hywiki--buttonize-end' global variables, use these as the region to highlight. @@ -2146,7 +2242,7 @@ the current page unless they have sections attached." ;; Non-nil if match is inside a comment or string (or (nth 4 (syntax-ppss)) (hypb:in-string-p)) t) - ;; (or on-page-name + ;; (or on-reference ;; (string-match (regexp-quote (char-to-string (char-syntax last-command-event))) ;; " _()<>$.\"'")) (not executing-kbd-macro) @@ -2157,14 +2253,14 @@ the current page unless they have sections attached." (when (hywiki--buttonized-region-p) (goto-char hywiki--buttonize-start)) - (unless on-page-name + (unless on-reference ;; after page name (skip-syntax-backward ">-")) (unless (or hywiki--highlighting-done-flag (hywiki-maybe-highlight-balanced-pairs)) - (unless on-page-name + (unless on-reference ;; May be a non-delimiter but HyWikiWord ending punctuation to ;; skip past (skip-chars-backward (hywiki-get-buttonize-characters) @@ -2200,7 +2296,7 @@ the current page unless they have sections attached." 'face hywiki-word-face)) (if (> (length hywiki--buts) 1) (progn (hproperty:but-clear-all-in-list hywiki--buts) - (hywiki-maybe-highlight-page-names + (hywiki-maybe-highlight-references hywiki--start hywiki--end)) ;; There is only one existing button (setq hywiki--buts (car hywiki--buts) @@ -2209,9 +2305,9 @@ the current page unless they have sections attached." (unless (and (= hywiki--start hywiki--but-start) (= hywiki--end hywiki--but-end)) (hproperty:but-delete hywiki--buts) - (hywiki-maybe-highlight-page-names + (hywiki-maybe-highlight-references hywiki--start hywiki--end))) - (hywiki-maybe-highlight-page-names + (hywiki-maybe-highlight-references hywiki--start hywiki--end)))) ;; Remove any potential earlier highlighting since the ;; previous word may have changed. @@ -2226,134 +2322,19 @@ the current page unless they have sections attached." hywiki--but-end (hproperty:but-end hywiki--buts)) (hproperty:but-delete hywiki--buts))))))))) -(defun hywiki-maybe-highlight-between-page-names () - "Highlight any non-Org link HyWiki page#section names between point. - -If in a programming mode, must be within a comment. Use -`hywiki-word-face' to highlight. Do not highlight references to -the current page unless they have sections attached." - (cond ((hproperty:char-property-range (point) 'face hywiki-word-face)) - ((cl-destructuring-bind (word start end) - (hywiki-highlight-word-get-range) - (when (and start end) - (save-excursion - (goto-char start) - (when (hywiki-referent-exists-p word) - ;; existing wikiword - (hywiki-maybe-highlight-on-page-name))) - t))) - ((cl-destructuring-bind (start end) - (hywiki-at-range-delimiter) - (when (and start end) - (save-excursion - (goto-char (1+ start)) - (skip-syntax-forward "-" (line-end-position)) - (unless (equal (hywiki-referent-exists-p :range) - '(nil nil nil)) - ;; existing wikiword - (hywiki-maybe-highlight-on-page-name))) - t))) - ((looking-at "[ \t\n\r\f]") - (hywiki-maybe-highlight-off-page-name) - (hywiki-maybe-highlight-on-page-name)) - (t (hywiki-maybe-highlight-on-page-name)))) - -(defun hywiki-maybe-highlight-off-page-name () - "Highlight any non-Org link HyWiki page#section at or one char before point. -If at bobp or any preceding char is non-whitespace and any following -character is whitespace or at eobp, handle highlighting for any previous -word or punctuation. - -If in a programming mode, must be within a comment. Use -`hywiki-word-face' to highlight. Do not highlight references to -the current page unless they have sections attached." - (hywiki-maybe-highlight-page-name - ;; flag on-page-name if on a whitespace character - (and (or (= (point) (point-max)) - (= (if (char-after) (char-syntax (char-after)) 0) ?\ )) - (or (= (point) (point-min)) - (/= (if (char-before) (char-syntax (char-before)) 0) ?\ ))))) - -(defun hywiki-maybe-highlight-on-page-name () - "Highlight any non-Org link HyWiki page#section at or one char before point. -If not on a whitespace character, handle highlighting for any page/section -name or punctuation. - -If in a programming mode, must be within a comment. Use -`hywiki-word-face' to highlight. Do not highlight references to -the current page unless they have sections attached." - (hywiki-maybe-highlight-page-name - ;; flag on-page-name if not on a whitespace character - (and (/= (point) (point-max)) - (/= (if (char-after) (char-syntax (char-after)) 0) ? )))) - -(defun hywiki-maybe-dehighlight-org-element-backward () - "Dehighlight HyWikiWords within a closing double/single square/angle bracket." - (hywiki--maybe-de/highlight-org-element-backward #'hywiki-maybe-dehighlight-sexp)) - (defun hywiki-maybe-highlight-org-element-backward () "Highlight HyWikiWords with point at a single closing square/angle bracket. Dehighlight HyWikiWords when on a double closing square/angle bracket, since Org mode highlights those." (hywiki--maybe-de/highlight-org-element-backward #'hywiki-maybe-highlight-sexp)) -(defun hywiki-maybe-dehighlight-org-element-forward () - "Dehighlight HyWikiWords within an opening double/single square/angle bracket." - (hywiki--maybe-de/highlight-org-element-forward #'hywiki-maybe-dehighlight-sexp)) - (defun hywiki-maybe-highlight-org-element-forward () "Highlight HyWikiWords with point at a single opening square/angle bracket. Dehighlight HyWikiWords when on a double opening square/angle bracket, since Org mode highlights those." (hywiki--maybe-de/highlight-org-element-forward #'hywiki-maybe-highlight-sexp)) -(defun hywiki-maybe-dehighlight-sexp (direction-number) - "Dehighlight any HyWikiWord within single square/angle bracket. -DIRECTION-NUMBER is 1 for forward scanning and -1 for backward scanning." - ;; Enable dehighlighting in HyWiki pages - (let ((hywiki-word-highlight-flag)) - (hywiki--maybe-de/highlight-sexp - #'hywiki-maybe-dehighlight-page-names direction-number))) - -(defun hywiki-maybe-highlight-sexp (direction-number) - "Highlight any HyWikiWord within single square/angle bracket. -DIRECTION-NUMBER is 1 for forward scanning and -1 for backward scanning." - (hywiki--maybe-de/highlight-sexp - #'hywiki-maybe-highlight-page-names direction-number)) - -;;;###autoload -(defun hywiki-maybe-dehighlight-page-names (&optional region-start region-end) - "Dehighlight any highlighted HyWiki page names in a HyWiki buffer/region. -With optional REGION-START and REGION-END positions (active region -interactively), limit dehighlighting to the region." - (interactive (when (use-region-p) (list (region-beginning) (region-end)))) - (unless (or (eq hywiki-buffer-highlighted-state 'd) - (hywiki-active-in-current-buffer-p)) - (hproperty:but-clear-all-in-list - (hproperty:but-get-all-in-region - (if (markerp region-start) - (if (marker-position region-start) - region-start - (point-min)) - (or region-start (point-min))) - (if (markerp region-end) - (if (marker-position region-end) - region-end - (point-max)) - (or region-end (point-max))) - 'face hywiki-word-face)) - (unless (or region-start region-end) - (setq hywiki-buffer-highlighted-state 'd)))) - -;;###autoload -(defun hywiki-highlight-page () - "Rehighlight all HyWikiWord references when in a HyWiki page." - (interactive) - (setq hywiki-buffer-highlighted-state nil) - (hywiki-maybe-highlight-page-names)) - -;;###autoload -(defun hywiki-maybe-highlight-page-names (&optional region-start region-end skip-lookups-update-flag) +(defun hywiki-maybe-highlight-references (&optional region-start region-end skip-lookups-update-flag) "Highlight each non-Org link HyWiki page#section in a buffer/region. With optional REGION-START and REGION-END positions or markers (active region interactively), limit highlight adjustment to the region. With @@ -2364,8 +2345,8 @@ Use `hywiki-word-face' to highlight. Do not highlight references to the current page unless they have sections attached. Dehighlight buffers other than HyWiki pages when `hywiki-mode' is -disabled. Highlight/dehighlight HyWiki page buffers whenever the -value of `hywiki-word-highlight-flag' is changed." +disabled. Highlight/dehighlight HyWiki page buffers whenever +`hywiki-mode' is enabled/disabled." (interactive (when (use-region-p) (list (region-beginning) (region-end)))) ;; Avoid doing many lets for efficiency. ;; Highlight HyWikiWords throughout buffers where `hywiki-mode' is enabled @@ -2398,8 +2379,8 @@ value of `hywiki-word-highlight-flag' is changed." ;; whole buffer is being processed; this prevents an ;; error when called from `hywiki-maybe-highlight-sexp'. (unless (and region-start region-end) - (let ((hywiki-word-highlight-flag)) - (hywiki-maybe-dehighlight-page-names))) + (let ((hywiki-mode)) + (hywiki-maybe-dehighlight-references))) (dolist (hywiki-words-regexp hywiki--any-wikiword-regexp-list) (goto-char (point-min)) (let ((highlight-in-comments-and-strings-only @@ -2434,7 +2415,7 @@ value of `hywiki-word-highlight-flag' is changed." ;; include a #section. (unless (string-equal hywiki--current-page (buffer-substring-no-properties hywiki--start hywiki--end)) - (hywiki-maybe-highlight-word hywiki--start hywiki--end)))))))))) + (hywiki-maybe-highlight-region-reference hywiki--start hywiki--end)))))))))) ;; Disable dehighlighting of HyWikiWords between [] and <>. ;; @@ -2473,14 +2454,20 @@ value of `hywiki-word-highlight-flag' is changed." hywiki-org-link-type-required hywiki--save-org-link-type-required))) ;; Otherwise, dehighlight HyWikiWords in this buffer when - ;; 'hywiki-mode' is disabled and this is not a HyWiki page - ;; buffer. If this is a HyWiki page buffer, then dehighlight - ;; when `hywiki-word-highlight-flag' is nil. - (hywiki-maybe-dehighlight-page-names region-start region-end)) + ;; 'hywiki-mode' is disabled or set to ':pages' and this is not a + ;; HyWiki page buffer. If this is a HyWiki page buffer, then + ;; dehighlight when `hywiki-mode' is disabled. + (hywiki-maybe-dehighlight-references region-start region-end)) (unless (hyperb:stack-frame '(hywiki-maybe-highlight-wikiwords-in-frame)) (hywiki-maybe-directory-updated)) nil) +(defun hywiki-maybe-highlight-sexp (direction-number) + "Highlight any HyWikiWord within single square/angle bracket. +DIRECTION-NUMBER is 1 for forward scanning and -1 for backward scanning." + (hywiki--maybe-de/highlight-sexp + #'hywiki-maybe-highlight-references direction-number)) + (defun hywiki-maybe-highlight-wikiwords-in-frame (frame &optional skip-lookups-update-flag) "Highlight all non-Org link HyWiki page names displayed in FRAME. If FRAME is t, then highlight in all windows across all frames, even @@ -2495,15 +2482,12 @@ the current page unless they have sections attached." ;; Display buffer before `normal-mode' triggers possibly ;; long-running font-locking (sit-for 0) - (hywiki-maybe-highlight-page-names nil nil skip-lookups-update-flag))) + (hywiki-maybe-highlight-references nil nil skip-lookups-update-flag))) nil frame) (hywiki-maybe-directory-updated)) (defun hywiki-in-page-p () - "Return non-nil if the current buffer is a HyWiki page. -If this is a HyWiki page and `hywiki-word-highlight-flag' is non-nil -\(the default), also enable auto-highlighting of HyWikiWords as they -are typed in the buffer." + "Return non-nil if the current buffer is a HyWiki page." (or hywiki-page-flag (and buffer-file-name (string-prefix-p (expand-file-name hywiki-directory) @@ -2515,6 +2499,29 @@ are typed in the buffer." (file-name-sans-extension (file-name-nondirectory (or (hypb:buffer-file-name) (buffer-name))))) +(defun hywiki-get-buffers-in-windows () + "Return the set of buffers attached to windows where `hywiki-mode' is active." + (apply #'set:create + (apply #'nconc (mapcar (lambda (frame) (mapcar #'window-buffer + (window-list frame))) + (frame-list))))) + +(defun hywiki-get-buffers (hywiki-buffer-mode) + "Return the list of window buffers active for HYWIKI-BUFFER-MODE. +See the function documentation for `hywiki-mode' for valid input +values (the states of `hywiki-mode')." + (when hywiki-mode + (delq nil (mapcar (lambda (buf) + (with-current-buffer buf + (and (not (and (boundp 'edebug-active) edebug-active (active-minibuffer-window))) + (not (apply #'derived-mode-p hywiki-exclude-major-modes)) + (not (string-prefix-p " " (buffer-name buf))) + (or (and (eq hywiki-buffer-mode :pages) (hywiki-in-page-p)) + (derived-mode-p 'kotl-mode) + (not (eq (get major-mode 'mode-class) 'special))) + buf))) + (hywiki-get-buffers-in-windows))))) + (defun hywiki-get-page-file (file-stem-name) "Return possibly non-existent path in `hywiki-directory' from FILE-STEM-NAME. FILE-STEM-NAME should not contain a directory and may have or may omit @@ -3352,8 +3359,8 @@ non-nil or this will return nil." (when range-flag '(nil nil nil)))) -(defun hywiki-maybe-highlight-word (start end) - "Conditionally highlight HyWiki referent between START and END. +(defun hywiki-maybe-highlight-region-reference (start end) + "Conditionally highlight HyWiki reference between START and END. Do not highlight if any face from `hywiki-ignore-face-list' appears within the given region, e.g. ignore HyWikiWords used in Org links or Hyperbole button names." @@ -3375,7 +3382,7 @@ This does not test whether a referent exists for the HyWikiWord; 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." +non-nil or this will return \\='(nil nil nil)." (cl-destructuring-bind (wikiword start end) (hywiki-word-at :range) ;; Ensure wikiword in buffer is highlighted before @@ -3383,7 +3390,7 @@ non-nil or this will return nil." (when (and wikiword start end (not (hproperty:but-get start 'face hywiki-word-face)) (hywiki-referent-exists-p wikiword)) - (hywiki-maybe-highlight-word start end)) + (hywiki-maybe-highlight-region-reference start end)) (list wikiword start end))) (defun hywiki-highlight-word-move-range () @@ -3509,52 +3516,89 @@ If point is on one, press RET immediately to use that one." (hywiki-get-page-list) nil nil nil nil (hywiki-word-at-point)))) -(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). -Highlight/dehighlight HyWiki page names across all frames on change." - (unless (memq operation '(let unlet)) ;; not setting global value - (set symbol set-to-value) - (hywiki-word-set-auto-highlighting set-to-value))) +(defun hywiki-word-set-auto-highlighting (hywiki-from-mode hywiki-to-mode) + "Set HyWikiWord auto-highlighting based on HYWIKI-FROM-MODE HYWIKI-TO-MODE. +Highlight only those buffers attached to windows. -(defun hywiki-word-set-auto-highlighting (arg) - "With a prefix ARG, turn on HyWikiWord auto-highlighting. -Otherwise, turn it off. +Auto-highlighting uses pre- and post-command hooks. If an error +occurs with one of these hooks, the problematic hook is removed. +Invoke this command with a prefix argument to restore the +auto-highlighting." + (cond ((eq hywiki-from-mode hywiki-to-mode) + nil) + ((null hywiki-from-mode) + (hywiki-word-highlight-buffers (hywiki-get-buffers hywiki-to-mode))) + ((and (eq hywiki-from-mode :all) (eq hywiki-to-mode :pages)) + (hywiki-word-dehighlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) + (hywiki-get-buffers hywiki-to-mode)))) + ((and (eq hywiki-from-mode :pages) (eq hywiki-to-mode :all)) + (hywiki-word-highlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) + (hywiki-get-buffers hywiki-to-mode)))) + ((or (and (eq hywiki-from-mode :all) (eq hywiki-to-mode nil)) + (and (eq hywiki-from-mode :pages) (eq hywiki-to-mode nil))) + (hywiki-word-dehighlight-buffers (hywiki-get-buffers hywiki-from-mode))) + (t + (error "(hywiki-word-set-auto-highlighting): Inputs must be nil, :pages or :all, not '%s' and '%s'" + hywiki-from-mode hywiki-to-mode)))) + +(defun hywiki-word-set-auto-highlighting-buffers (hywiki-from-mode hywiki-to-mode) + "Set HyWikiWord auto-highlighting based on HYWIKI-FROM-MODE HYWIKI-TO-MODE. +Highlight only those buffers attached to windows. Auto-highlighting uses pre- and post-command hooks. If an error occurs with one of these hooks, the problematic hook is removed. Invoke this command with a prefix argument to restore the auto-highlighting." - (interactive "P") - (if arg - ;; enable - (progn - (when hywiki-word-highlight-flag - (add-hook 'pre-command-hook 'hywiki-word-store-around-point 95) - (add-hook 'post-command-hook 'hywiki-word-highlight-post-command 95) - (add-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert) - (add-hook 'window-buffer-change-functions - 'hywiki-maybe-highlight-wikiwords-in-frame) - (add-to-list 'yank-handled-properties - '(hywiki-word-face . hywiki-highlight-on-yank)) - (hywiki-maybe-highlight-wikiwords-in-frame t)) - (when (called-interactively-p 'interactive) - (if hywiki-word-highlight-flag - (message "HyWikiWord page auto-highlighting enabled") - (message "`hywiki-word-highlight-flag' must first be set to t to enable auto-highlighting")))) - ;; disable - (remove-hook 'pre-command-hook 'hywiki-word-store-around-point) - (remove-hook 'post-command-hook 'hywiki-word-highlight-post-command) - (remove-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert) - (hywiki-mode 0) ;; also dehighlights HyWikiWords outside of HyWiki pages - (remove-hook 'window-buffer-change-functions - 'hywiki-maybe-highlight-wikiwords-in-frame) - (hywiki-maybe-highlight-wikiwords-in-frame t) - (setq yank-handled-properties - (delete '(hywiki-word-face . hywiki-highlight-on-yank) - yank-handled-properties)) - (when (called-interactively-p 'interactive) - (message "HyWikiWord page auto-highlighting disabled")))) + (cond ((eq hywiki-from-mode hywiki-to-mode) + nil) + ((null hywiki-from-mode) + (hywiki-word-highlight-buffers (hywiki-get-buffers hywiki-to-mode))) + ((and (eq hywiki-from-mode :all) (eq hywiki-to-mode :pages)) + (hywiki-word-dehighlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) + (hywiki-get-buffers hywiki-to-mode)))) + ((and (eq hywiki-from-mode :pages) (eq hywiki-to-mode :all)) + (hywiki-word-highlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) + (hywiki-get-buffers hywiki-to-mode)))) + ((or (and (eq hywiki-from-mode :all) (eq hywiki-to-mode nil)) + (and (eq hywiki-from-mode :pages) (eq hywiki-to-mode nil))) + (hywiki-word-dehighlight-buffers (hywiki-get-buffers hywiki-from-mode))) + (t + (error "(hywiki-word-set-auto-highlighting): Inputs must be nil, :pages or :all, not '%s' and '%s'" + hywiki-from-mode hywiki-to-mode)))) + +(defun hywiki-word-highlight-buffers (buffers) + "Auto-highlight HyWikiWords in BUFFERS." + (interactive) + (dolist (buf buffers) + (with-current-buffer buf + (add-hook 'pre-command-hook 'hywiki-word-store-around-point 95 :local) + (add-hook 'post-command-hook 'hywiki-word-highlight-post-command 95 :local) + (add-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert :local))) + (add-hook 'window-buffer-change-functions + 'hywiki-maybe-highlight-wikiwords-in-frame) + (add-to-list 'yank-handled-properties + '(hywiki-word-face . hywiki-highlight-on-yank)) + (hywiki-maybe-highlight-wikiwords-in-frame t) + (when (called-interactively-p 'interactive) + (message "HyWikiWord auto-highlighting enabled"))) + +(defun hywiki-word-dehighlight-buffers (buffers) + "Disable auto-highlighting of HyWikiWords in BUFFERS." + (interactive) + (dolist (buf buffers) + (with-current-buffer buf + (remove-hook 'pre-command-hook 'hywiki-word-store-around-point :local) + (remove-hook 'post-command-hook 'hywiki-word-highlight-post-command :local) + (remove-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert :local))) + (hywiki-mode 0) ;; also dehighlights HyWikiWords outside of HyWiki pages + (remove-hook 'window-buffer-change-functions + 'hywiki-maybe-highlight-wikiwords-in-frame) + (hywiki-maybe-highlight-wikiwords-in-frame t) + (setq yank-handled-properties + (delete '(hywiki-word-face . hywiki-highlight-on-yank) + yank-handled-properties)) + (when (called-interactively-p 'interactive) + (message "HyWikiWord auto-highlighting disabled"))) ;;; ************************************************************************ ;;; Private functions @@ -3798,7 +3842,7 @@ the HyWikiWord reference." (setq hywiki--range nil))) )))))) ;; Dehighlight if point is on or between a HyWikiWord - (hywiki-maybe-dehighlight-between-page-names))) + (hywiki-maybe-dehighlight-between-references))) (defun hywiki--maybe-rehighlight-at-point () "Dehighlight any existing HyWikiWord when needed. @@ -3810,16 +3854,16 @@ This must be called within a `save-excursion' or it may move point." (hywiki--maybe-dehighlight-at-point) ;; Highlight wikiwords around point as needed - (hywiki-maybe-highlight-on-page-name) + (hywiki-maybe-highlight-on-reference) (when (hywiki--buttonized-region-p) (hywiki--maybe-de/highlight-sexp - #'hywiki-maybe-highlight-page-names 1 + #'hywiki-maybe-highlight-references 1 hywiki--buttonize-start hywiki--buttonize-end)) (when (= (char-syntax (or (char-before) 0)) ?\ ) (goto-char (1- (point)))) - (hywiki-maybe-highlight-between-page-names)) + (hywiki-maybe-highlight-between-references)) ;;; ************************************************************************ ;;; Private initializations @@ -3848,13 +3892,6 @@ This must be called within a `save-excursion' or it may move point." ;; Use for its side effects, setting variables (eval-after-load "ox-publish" '(hywiki-org-get-publish-project)) -(add-variable-watcher 'hywiki-word-highlight-flag - 'hywiki-word-highlight-flag-changed) - -;; Set HyWiki page auto-HyWikiWord highlighting and `yank-handled-properties' -(hywiki-word-highlight-flag-changed 'hywiki-word-highlight-flag - hywiki-word-highlight-flag 'set nil) - ;; Ensure HyWiki referent lookup table is initialized as are HyWiki Org ;; Publish settings. (hywiki-set-directory 'hywiki-directory hywiki-directory) diff --git a/hywiki/HyWiki.org b/hywiki/HyWiki.org index 009fb89a..009930b4 100644 --- a/hywiki/HyWiki.org +++ b/hywiki/HyWiki.org @@ -50,13 +50,11 @@ Hyperbole's Action Key does the right thing in this context. * HyWiki Settings -The custom setting, 'hywiki-word-highlight-flag' (default = 't'), -means HyWikiWords will be auto-highlighted within HyWiki pages. -Outside of such pages, 'hywiki-mode' must also be enabled for such -auto-highlighting. - -The custom setting, 'hywiki-exclude-major-modes' (default = 'nil'), is -a list of major modes to exclude from HyWikiWord auto-highlighting and +By default, HyWikiWords are auto-highlighted within HyWiki pages. +Outside of such pages, 'hywiki-mode' must be set to `:all' to enable +auto-highlighting in programming and text buffers. The custom +setting, 'hywiki-exclude-major-modes' (default = 'nil'), is a list of +major modes to exclude from HyWikiWord auto-highlighting and recognition. Within programming modes, HyWikiWords are highlighted and hyperlinked diff --git a/man/hyperbole.texi b/man/hyperbole.texi index f76d5232..c30a2738 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: 7-Dec-25 at 20:30:10 by Bob Weiner +@c Last-Mod: 27-Dec-25 at 22:18:46 by Bob Weiner @c %**start of header (This is for running Texinfo on a region.) @setfilename hyperbole.info @@ -4622,6 +4622,24 @@ Disable highlighting HyWikiWord references everywhere. The @{M-x hywiki-mode @key{RET}@} will also toggle between disabling HyWikiWords everywhere and enabling them in all editable buffers. +--------- + "The default, non-nil value treats HyWikiWords in HyWiki pages as hyperlinks. +A nil value disables HyWikiWord hyperlink buttons in both HyWiki +pages and all other buffers (since it also disables `hywiki-mode'). + +Outside of HyWiki pages, the global minor mode `hywiki-mode' must be +manually enabled for auto-HyWikiWord highlighting. Interactively, {C-h +h h m a} does this; programmatically, use `(hywiki-mode :all)' to +enable it. + +Use `hywiki-active-in-current-buffer-p' to determine if HyWikiWord +hyperlinks are currently active in a buffer or not. + +Regardless of this flag, HyWikiWords in Org links and targets are not +highlighted nor treated as hyperlinks; they are handled normally by Org." +-------- + + @cindex HyWikiWord highlighting As HyWikiWords are typed, highlighting occurs after a trailing whitespace or punctuation character is added, or when the HyWikiWord @@ -4630,12 +4648,6 @@ single square brackets. Since Org links use double square brackets and Org targets use double or triple angle brackets, HyWikiWords within these delimiters are ignored once the brackets are in place. -@vindex hywiki-word-highlight-flag -The custom setting, @code{hywiki-word-highlight-flag} (default = -@samp{t}), means HyWikiWords will be auto-highlighted within HyWiki -pages. Outside of such pages, @code{hywiki-mode} must also be enabled -for such auto-highlighting. - @vindex hywiki-exclude-major-modes @cindex HyWiki exclude modes The custom setting, @code{hywiki-exclude-major-modes} (default = diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el index 4fdfdb15..70693936 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: 22-Nov-25 at 13:35:42 by Bob Weiner +;; Last-Mod: 2-Jan-26 at 20:13:25 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -615,11 +615,11 @@ HyWikiWord reference." "Verify `hywiki-active-in-current-buffer-p'." (let* ((hywiki-directory (make-temp-file "hywiki" t)) (wiki-page (cdr (hywiki-add-page "WikiWord"))) - (hywiki-word-highlight-flag t)) + (hywiki-mode t)) (unwind-protect (with-current-buffer (find-file-noselect wiki-page) (should (hywiki-active-in-current-buffer-p)) - (let ((hywiki-word-highlight-flag nil)) + (let ((hywiki-mode nil)) (should-not (hywiki-active-in-current-buffer-p))) (let ((hywiki-exclude-major-modes (list 'org-mode))) (should-not (hywiki-active-in-current-buffer-p))) @@ -2052,7 +2052,7 @@ face is verified during the change." (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) (ert-deftest hywiki-tests--maybe-highlight-page-names () - "Verify `hywiki-maybe-highlight-page-names'. + "Verify `hywiki-maybe-highlight-references'. Start and stop point of all highlighted regions in the buffer, as computed by `hywiki-tests--hywiki-face-regions', are compared to the expected result." @@ -2077,7 +2077,7 @@ expected result." (overlay-regions (cdr v))) (with-temp-buffer (insert input) - (hywiki-maybe-highlight-page-names (point-min) (point-max)) + (hywiki-maybe-highlight-references (point-min) (point-max)) ;; Verify Overlays (ert-info ((format "Text '%s' => Expected overlays '%s'" input overlay-regions)) (should (equal (hywiki-tests--hywiki-face-regions) overlay-regions))))))) From ef2947bab82d5d043c4d21071bb6512e4c142c64 Mon Sep 17 00:00:00 2001 From: bw Date: Tue, 13 Jan 2026 01:04:34 -0500 Subject: [PATCH 2/6] hywiki.el - Enable window-change-based HyWikiWord highlighting --- ChangeLog | 13 ++++- hywiki.el | 111 ++++++++++++++++++++------------------- test/hsys-org-tests.el | 3 +- test/hywiki-tests.el | 92 ++++++++++++++++---------------- test/hywiki-yki-tests.el | 11 ++-- 5 files changed, 123 insertions(+), 107 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4b52b90..53b87cd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2026-01-12 Bob Weiner + +* hywiki.el: (hywiki-word-highlight-in-buffers, hywiki-word-highlight-in-frame): + Add to support window-change-based HyWikiWord highlighting. + +2026-01-11 Bob Weiner + +* test/hsys-org-tests.el (hsys-org:org-link-at-p): Fix 4th test + by ensuring hywiki-mode is off. + 2026-01-06 Bob Weiner * hywiki.el (hywiki-get-buffers-in-windows): Add and call in @@ -52,7 +62,8 @@ (hywiki-active-in-current-buffer-p): (hywiki-word-set-auto-highlighting): Replace 'hywiki-word-highlight-flag' with 'hywiki-mode'. - test/hywiki-tests.el (hywiki-tests--active-in-current-buffer-p): + test/hywiki-tests.el (hywiki-tests--active-in-current-buffer-p): Change let of + 'hywiki-mode' to function call to set the minor mode. * hibtypes.el (hywiki-existing-word): hywiki.el (hywiki-word): Skip if not 'hywiki-active-in-current-buffer-p'. diff --git a/hywiki.el b/hywiki.el index 2bb55eb2..c1910329 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: 11-Jan-26 at 05:58:25 by Bob Weiner +;; Last-Mod: 13-Jan-26 at 01:04:15 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -734,6 +734,8 @@ deletion commands and those in `hywiki-non-character-commands'." ;; Not inside a comment or a string (not (or (nth 4 (syntax-ppss)) (hypb:in-string-p)))))) +(defvar hywiki-prior-mode nil) + ;;;###autoload (define-minor-mode hywiki-mode "Toggle HyWiki global minor mode with \\[hywiki-mode]. @@ -797,7 +799,7 @@ See the Info documentation at \"(hyperbole)HyWiki\". ;; Need hyperbole-mode (unless hyperbole-mode (hyperbole-mode 1)) - (hywiki-word-set-auto-highlighting hywiki-mode arg) + (hywiki-word-set-auto-highlighting hywiki-prior-mode arg) (setq hywiki-mode arg)) ((or (and (integerp arg) (<= arg 0)) (null arg)) @@ -806,7 +808,7 @@ See the Info documentation at \"(hyperbole)HyWiki\". ;; Dehighlight HyWikiWords in this buffer when 'hywiki-mode' is ;; disabled and this is not a HyWiki page buffer. If this is a ;; HyWiki page buffer, then dehighlight when `hywiki-mode' is nil. - (hywiki-maybe-highlight-wikiwords-in-frame t) + (hywiki-word-set-auto-highlighting hywiki-prior-mode arg) (setq hywiki-mode arg)) (t ;; (> arg 1) ;; Enable in HyWiki page buffers only @@ -814,9 +816,15 @@ See the Info documentation at \"(hyperbole)HyWiki\". ;; Need hyperbole-mode (unless hyperbole-mode (hyperbole-mode 1)) - (hywiki-word-set-auto-highlighting hywiki-mode arg) + (hywiki-word-set-auto-highlighting hywiki-prior-mode arg) (setq hywiki-mode arg))))) +(defun hywiki-mode-around-advice (hywiki-mode-fn &optional arg) + (setq hywiki-prior-mode hywiki-mode) + (funcall hywiki-mode-fn arg)) + +(advice-add 'hywiki-mode :around #'hywiki-mode-around-advice) + ;;; ************************************************************************ ;;; Public Implicit Button and Action Types ;;; ************************************************************************ @@ -2335,18 +2343,19 @@ since Org mode highlights those." (hywiki--maybe-de/highlight-org-element-forward #'hywiki-maybe-highlight-sexp)) (defun hywiki-maybe-highlight-references (&optional region-start region-end skip-lookups-update-flag) - "Highlight each non-Org link HyWiki page#section in a buffer/region. + "Highlight each non-Org link HyWiki page#section in the current buffer/region. With optional REGION-START and REGION-END positions or markers (active region interactively), limit highlight adjustment to the region. With optional SKIP-LOOKUPS-UPDATE-FLAG non-nil, HyWiki lookup tables should have already been updated and this is skipped. -Use `hywiki-word-face' to highlight. Do not highlight references to -the current page unless they have sections attached. +Use `hywiki-word-face' to highlight. Do not highlight references +to the current page unless they have sections attached. -Dehighlight buffers other than HyWiki pages when `hywiki-mode' is -disabled. Highlight/dehighlight HyWiki page buffers whenever -`hywiki-mode' is enabled/disabled." +HyWiki mode must be active in the current buffer for highlighting +to occur; otherwise, highlighting is removed and disabled in the +current buffer. Highlight/dehighlight HyWiki page buffers +whenever `hywiki-mode' is enabled/disabled." (interactive (when (use-region-p) (list (region-beginning) (region-end)))) ;; Avoid doing many lets for efficiency. ;; Highlight HyWikiWords throughout buffers where `hywiki-mode' is enabled @@ -2499,15 +2508,17 @@ the current page unless they have sections attached." (file-name-sans-extension (file-name-nondirectory (or (hypb:buffer-file-name) (buffer-name))))) -(defun hywiki-get-buffers-in-windows () - "Return the set of buffers attached to windows where `hywiki-mode' is active." +(defun hywiki-get-buffers-in-windows (&rest frames) + "Return the set of buffers in all windows where `hywiki-mode' is active. +This applies to all windows in all live frames or can be filtered to optional +rest of arguments FRAMES." (apply #'set:create (apply #'nconc (mapcar (lambda (frame) (mapcar #'window-buffer (window-list frame))) - (frame-list))))) + (or frames (frame-list)))))) -(defun hywiki-get-buffers (hywiki-buffer-mode) - "Return the list of window buffers active for HYWIKI-BUFFER-MODE. +(defun hywiki-get-buffers (hywiki-mode-status) + "Return the list of window buffers active for HYWIKI-BUFFER-STATUS. See the function documentation for `hywiki-mode' for valid input values (the states of `hywiki-mode')." (when hywiki-mode @@ -2516,7 +2527,7 @@ values (the states of `hywiki-mode')." (and (not (and (boundp 'edebug-active) edebug-active (active-minibuffer-window))) (not (apply #'derived-mode-p hywiki-exclude-major-modes)) (not (string-prefix-p " " (buffer-name buf))) - (or (and (eq hywiki-buffer-mode :pages) (hywiki-in-page-p)) + (or (and (eq hywiki-mode-status :pages) (hywiki-in-page-p)) (derived-mode-p 'kotl-mode) (not (eq (get major-mode 'mode-class) 'special))) buf))) @@ -3148,6 +3159,8 @@ or this will return nil." (defun hywiki-word-at (&optional range-flag) "Return potential HyWikiWord and optional #section:Lnum:Cnum at point or nil. +`hywiki-mode' must be enabled or this will return nil. + If the HyWikiWord is delimited, point must be within the delimiters. This works regardless of whether the HyWikiWord has been highlighted or not. @@ -3541,62 +3554,52 @@ auto-highlighting." (error "(hywiki-word-set-auto-highlighting): Inputs must be nil, :pages or :all, not '%s' and '%s'" hywiki-from-mode hywiki-to-mode)))) -(defun hywiki-word-set-auto-highlighting-buffers (hywiki-from-mode hywiki-to-mode) - "Set HyWikiWord auto-highlighting based on HYWIKI-FROM-MODE HYWIKI-TO-MODE. -Highlight only those buffers attached to windows. +(defun hywiki-word-highlight-in-frame (frame) + "Auto-highlight HyWikiWords in `hywiki-mode' buffers displayed FRAME." + (hywiki-word-highlight-in-buffers (hywiki-get-buffers-in-windows frame))) -Auto-highlighting uses pre- and post-command hooks. If an error -occurs with one of these hooks, the problematic hook is removed. -Invoke this command with a prefix argument to restore the -auto-highlighting." - (cond ((eq hywiki-from-mode hywiki-to-mode) - nil) - ((null hywiki-from-mode) - (hywiki-word-highlight-buffers (hywiki-get-buffers hywiki-to-mode))) - ((and (eq hywiki-from-mode :all) (eq hywiki-to-mode :pages)) - (hywiki-word-dehighlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) - (hywiki-get-buffers hywiki-to-mode)))) - ((and (eq hywiki-from-mode :pages) (eq hywiki-to-mode :all)) - (hywiki-word-highlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) - (hywiki-get-buffers hywiki-to-mode)))) - ((or (and (eq hywiki-from-mode :all) (eq hywiki-to-mode nil)) - (and (eq hywiki-from-mode :pages) (eq hywiki-to-mode nil))) - (hywiki-word-dehighlight-buffers (hywiki-get-buffers hywiki-from-mode))) - (t - (error "(hywiki-word-set-auto-highlighting): Inputs must be nil, :pages or :all, not '%s' and '%s'" - hywiki-from-mode hywiki-to-mode)))) - -(defun hywiki-word-highlight-buffers (buffers) +(defun hywiki-word-highlight-in-buffers (buffers) "Auto-highlight HyWikiWords in BUFFERS." - (interactive) (dolist (buf buffers) (with-current-buffer buf (add-hook 'pre-command-hook 'hywiki-word-store-around-point 95 :local) (add-hook 'post-command-hook 'hywiki-word-highlight-post-command 95 :local) - (add-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert :local))) - (add-hook 'window-buffer-change-functions - 'hywiki-maybe-highlight-wikiwords-in-frame) + (add-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert 95 :local) + ;; Display buffer before `normal-mode' triggers possibly + ;; long-running font-locking + (sit-for 0) + (hywiki-maybe-highlight-references nil nil t))) + ;; Rebuild lookup tables if any HyWiki page name has changed + (hywiki-get-referent-hasht) + (hywiki-maybe-directory-updated)) + +(defun hywiki-word-highlight-buffers (buffers) + "Setup to auto-highlight HyWikiWords in BUFFERS." + (interactive) + (add-hook 'window-buffer-change-functions 'hywiki-word-highlight-in-frame) (add-to-list 'yank-handled-properties '(hywiki-word-face . hywiki-highlight-on-yank)) - (hywiki-maybe-highlight-wikiwords-in-frame t) + (hywiki-word-highlight-in-buffers buffers) (when (called-interactively-p 'interactive) (message "HyWikiWord auto-highlighting enabled"))) (defun hywiki-word-dehighlight-buffers (buffers) "Disable auto-highlighting of HyWikiWords in BUFFERS." (interactive) + (remove-hook 'window-buffer-change-functions 'hywiki-word-highlight-in-frame) + (setq yank-handled-properties + (delete '(hywiki-word-face . hywiki-highlight-on-yank) + yank-handled-properties)) (dolist (buf buffers) (with-current-buffer buf (remove-hook 'pre-command-hook 'hywiki-word-store-around-point :local) (remove-hook 'post-command-hook 'hywiki-word-highlight-post-command :local) - (remove-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert :local))) - (hywiki-mode 0) ;; also dehighlights HyWikiWords outside of HyWiki pages - (remove-hook 'window-buffer-change-functions - 'hywiki-maybe-highlight-wikiwords-in-frame) - (hywiki-maybe-highlight-wikiwords-in-frame t) - (setq yank-handled-properties - (delete '(hywiki-word-face . hywiki-highlight-on-yank) - yank-handled-properties)) + (remove-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert :local) + ;; Display buffer before `normal-mode' triggers possibly + ;; long-running font-locking + (sit-for 0) + (hywiki-maybe-dehighlight-references))) + (hywiki-maybe-directory-updated) (when (called-interactively-p 'interactive) (message "HyWikiWord auto-highlighting disabled"))) diff --git a/test/hsys-org-tests.el b/test/hsys-org-tests.el index a10103c3..37df30b4 100644 --- a/test/hsys-org-tests.el +++ b/test/hsys-org-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 23-Apr-21 at 20:55:00 -;; Last-Mod: 22-Nov-25 at 12:07:27 by Bob Weiner +;; Last-Mod: 11-Jan-26 at 09:55:03 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -82,6 +82,7 @@ ;; Out side of org-mode (erase-buffer) (fundamental-mode) + (hywiki-mode nil) (insert "[[hy:HyWiki]]\n\n") (goto-char 3) (ert-info ("Accept link if unknown HyWiki button") diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el index 70693936..8eb85c95 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: 2-Jan-26 at 20:13:25 by Bob Weiner +;; Last-Mod: 11-Jan-26 at 10:42:51 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -77,7 +77,7 @@ Last two elements are optional.") (with-temp-buffer (hywiki-tests--preserve-hywiki-mode (org-mode) - (hywiki-mode 1) + (hywiki-mode :all) (mapc (lambda (before-after) (condition-case err @@ -259,10 +259,10 @@ This is for simulating the command loop." (ert-deftest hywiki-tests--verify-preserve-hywiki-mode () "Verify `hywiki-tests--preserve-hywiki-mode' restores `hywiki-mode'." (hywiki-tests--preserve-hywiki-mode - (hywiki-mode 1) + (hywiki-mode :all) (hywiki-tests--preserve-hywiki-mode (should hywiki-mode) - (hywiki-mode 0) + (hywiki-mode nil) (should-not hywiki-mode)) (should hywiki-mode))) @@ -302,7 +302,7 @@ This is for simulating the command loop." (wikifile "WikiWord.org")) (unwind-protect (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "[[hy:WikiWord]]") (goto-char 4) (action-key) @@ -317,7 +317,7 @@ This is for simulating the command loop." (hywiki-directory (make-temp-file "hywiki" t))) (unwind-protect (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "[[hy:WikiWord]]") (goto-char 6) (should (string= "WikiWord" (hywiki-word-at))) @@ -341,7 +341,7 @@ This is for simulating the command loop." (should (file-exists-p hywiki-page-file)) (should-not (file-exists-p hywiki-page-file))) (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "WikiWord\n") (goto-char 4) (action-key) @@ -368,7 +368,7 @@ This is for simulating the command loop." (dolist (v sections) (insert (format "%s\nbody\n" v))) (save-buffer) - (hywiki-mode 1) + (hywiki-mode :all) (dolist (v sections) (with-temp-buffer (insert "WikiWord#" (cadr (split-string v " "))) @@ -393,7 +393,7 @@ line 1 line 2 ") (save-buffer) - (hywiki-mode 1) + (hywiki-mode :all) (dolist (l '(1 2)) (dolist (c '("" ":C0" ":C5")) (with-temp-buffer @@ -414,11 +414,11 @@ line 2 (hywiki-directory (make-temp-file "hywiki" t))) (unwind-protect (with-temp-buffer - (hywiki-mode 0) + (hywiki-mode nil) (insert "WikiWord") (goto-char 4) (should-not (hywiki-word-at)) - (hywiki-mode 1) + (hywiki-mode :all) (should (string= "WikiWord" (hywiki-word-at)))) (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) @@ -431,7 +431,7 @@ line 2 (wiki-page (cdr referent))) (unwind-protect (with-current-buffer (find-file-noselect wiki-page) - (hywiki-mode 0) + (hywiki-mode :pages) (insert "PotentialWikiWord") (newline nil t) (goto-char 4) @@ -447,7 +447,7 @@ line 2 (hywiki-directory (make-temp-file "hywiki" t))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) ;; Matches a WikiWord (dolist (v '("WikiWord" "[WikiWord]" "[[WikiWord]]" "{WikiWord}" "(WikiWord)" @@ -501,7 +501,7 @@ line 2 (if (string= "WikiWord" (hywiki-word-at)) (should v) (should-not v))))) - (hywiki-mode 0) + (hywiki-mode nil) (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) (ert-deftest hywiki-tests--at-wikiword-finds-word-and-section () @@ -516,7 +516,7 @@ line 2 ))) (unwind-protect (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (dolist (w words) (let ((in (if (stringp w) w (car w))) (expect (if (stringp w) w (cdr w)))) @@ -532,7 +532,7 @@ line 2 (let ((hywiki-directory (make-temp-file "hywiki" t))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer (insert "WikiWord#section rest is ignored") (goto-char 4) @@ -559,7 +559,7 @@ HyWikiWord reference." (let ((hywiki-directory (make-temp-file "hywiki" t))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer ; Delimited string allow space (insert "\"WikiWord#section rest\"") (goto-char 4) @@ -615,17 +615,17 @@ HyWikiWord reference." "Verify `hywiki-active-in-current-buffer-p'." (let* ((hywiki-directory (make-temp-file "hywiki" t)) (wiki-page (cdr (hywiki-add-page "WikiWord"))) - (hywiki-mode t)) + (hywiki-mode :all)) (unwind-protect (with-current-buffer (find-file-noselect wiki-page) (should (hywiki-active-in-current-buffer-p)) - (let ((hywiki-mode nil)) - (should-not (hywiki-active-in-current-buffer-p))) + (hywiki-mode nil) + (should-not (hywiki-active-in-current-buffer-p)) (let ((hywiki-exclude-major-modes (list 'org-mode))) (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)))) + (hywiki-mode nil) + (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) @@ -758,7 +758,7 @@ Both mod-time and checksum must be changed for a test to return true." (wikipage (cdr (hywiki-add-page "WikiWord")))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer (insert "WikiWor") (hywiki-tests--command-execute #'self-insert-command 1 ?d) @@ -781,7 +781,7 @@ Both mod-time and checksum must be changed for a test to return true." (unwind-protect (progn (with-temp-buffer - (hywiki-mode 0) + (hywiki-mode nil) (insert "WikiWor") (hywiki-tests--command-execute #'self-insert-command 1 ?d) (goto-char 4) @@ -796,7 +796,7 @@ Both mod-time and checksum must be changed for a test to return true." (wikipage (cdr (hywiki-add-page "WikiWord")))) (unwind-protect (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "Wikiord ") (goto-char 5) (should (looking-at-p "ord ")) @@ -822,7 +822,7 @@ Both mod-time and checksum must be changed for a test to return true." (unwind-protect (progn (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "WikiWord") (hywiki-tests--command-execute #'self-insert-command 1 ? ) (goto-char 1) @@ -848,7 +848,7 @@ Both mod-time and checksum must be changed for a test to return true." (wikipage (cdr (hywiki-add-page "WikiWord")))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer (setq default-directory hywiki-directory) (insert "WikiWord#section:L2:C4") @@ -985,7 +985,7 @@ body B ;; Create temp buffers with WikiWord links to the target ;; WikiWord page and verify they work. (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (let (wiki-link expected-str-at-pos) (condition-case err-msg @@ -1616,7 +1616,7 @@ See gh#rswgnu/hyperbole/669." (let* ((hywiki-directory (make-temp-file "hywiki" t)) (wiki-page (cdr (hywiki-add-page "WikiWord")))) (with-temp-buffer - (hywiki-mode 0) + (hywiki-mode nil) (insert "WikiWor") (hywiki-tests--command-execute #'self-insert-command 1 ?d) (goto-char 4) @@ -1624,7 +1624,7 @@ See gh#rswgnu/hyperbole/669." (unwind-protect (progn (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "WikiWor") (hywiki-tests--command-execute #'self-insert-command 1 ?d) (goto-char 4) @@ -1764,7 +1764,7 @@ resulting state at point is a WikiWord or not." (hywiki-tests--with-face-test nil)) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (dolist (testcase hywiki-tests--wikiword-step-check) (with-temp-buffer (hywiki-tests--run-test-case testcase)))) @@ -1784,7 +1784,7 @@ is a WikiWord at point or not." (wiki-page-list (list wikiHiHo wikiHiho wikiHi wikiHo))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (dolist (testcase hywiki-tests--wikiword-step-check) (with-temp-buffer (hywiki-tests--run-test-case testcase)))) @@ -1804,7 +1804,7 @@ Insert test in the middle of other text." (hywiki-tests--with-face-test nil)) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer (insert hywiki-tests--lorem-ipsum) (goto-char (/ (point-max) 2)) @@ -1838,7 +1838,7 @@ face is verified during the change." (wiki-page (cdr (hywiki-add-page "WikiWord")))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer (emacs-lisp-mode) (insert "\ @@ -1863,7 +1863,7 @@ face is verified during the change." (wiki-page (cdr (hywiki-add-page "WikiWord")))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) ;; Matches a WikiWord (dolist (v '("WikiWord" "[WikiWord]" "[[WikiWord]]" "{WikiWord}" "(WikiWord)" @@ -1907,7 +1907,7 @@ face is verified during the change." (hywiki-tests--preserve-hywiki-mode (unwind-protect (let ((words '("Foo" "Bar" "Baz" "Qux"))) - (hywiki-mode 1) + (hywiki-mode :all) (with-temp-buffer (emacs-lisp-mode) (insert @@ -1932,9 +1932,9 @@ face is verified during the change." (insert "\"DEMO\" \"DEMO.org\"\n") (goto-char 2) (should (looking-at-p "DEMO\" ")) - (hywiki-mode 0) + (hywiki-mode nil) (should (ibtype:test-p 'pathname)) - (hywiki-mode 1) + (hywiki-mode :all) (should (ibtype:test-p 'pathname)) (goto-char 9) ;; Verify that using the org extension selects the WikiWord. @@ -1951,7 +1951,7 @@ face is verified during the change." (hywiki-page-with-section (expand-file-name "WikiWord.org#section" hywiki-directory))) (unwind-protect (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (insert "WikiWord#section") (goto-char 4) (action-key) @@ -1969,7 +1969,7 @@ face is verified during the change." (hywiki-tests--with-face-test t)) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (dolist (testcase '((("\"Hi#a b c\"") (p3 . "Hi#a b c") (p11) (-1) (p3 . "Hi#a") (p10) ("\"") (p3 . "Hi#a b c")) (("(Hi#s n)" . "Hi#s n") (-1) (p3 . "Hi#s") (p8) (")" . "Hi#s n")))) @@ -1987,7 +1987,7 @@ face is verified during the change." (hywiki-tests--with-face-test t)) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) ;; Left part of WikiWord yanked in. (with-temp-buffer (insert "i#s") @@ -2041,7 +2041,7 @@ face is verified during the change." wikiHo) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-current-buffer (find-file wikiHi) (insert "Ho") (save-buffer) @@ -2062,7 +2062,7 @@ expected result." (wikiword (cdr (hywiki-add-page "WiWo")))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (dolist (v `(("WiWo" . ((1 . 5))) ("WiWo text" . ((1 . 5))) ("WiWo WiWo" . ((1 . 5) (6 . 10))) @@ -2131,7 +2131,7 @@ expected result." (wikiHo (cdr (hywiki-add-page "Ho")))) (unwind-protect (progn - (hywiki-mode 1) + (hywiki-mode :all) (with-current-buffer (find-file wikiHo) (insert "123")) (with-current-buffer (find-file wikiHi) @@ -2145,7 +2145,7 @@ expected result." "Verify `hywiki-mode' called interactively toggles mode." (hywiki-tests--preserve-hywiki-mode (with-temp-buffer - (hywiki-mode 1) + (hywiki-mode :all) (should hywiki-mode) ;; Toggle (call-interactively #'hywiki-mode) diff --git a/test/hywiki-yki-tests.el b/test/hywiki-yki-tests.el index 487b00a7..4257a582 100644 --- a/test/hywiki-yki-tests.el +++ b/test/hywiki-yki-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 13-Jul-25 at 19:50:37 -;; Last-Mod: 16-Nov-25 at 11:16:45 by Bob Weiner +;; Last-Mod: 11-Jan-26 at 10:35:55 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -177,13 +177,14 @@ Each test is constructed as three phases: (should (string= stop (hywiki-test--get-buffer-text-with-point-and-highlight))))) (unwind-protect (progn + (hywiki-mode :all) (ert-info ("1" :prefix "Verify point, no highlighting:") - (pre: "hej^hopp") - (post: "hej^hopp")) + (pre: "non^wikiword") + (post: "non^wikiword")) (ert-info ("2" :prefix "Verify point, no highlighting: ") - (pre: "hej^hopp") + (pre: "non^wikiword") (forward-char 1) - (post: "hejh^opp")) + (pre: "nonw^ikiword")) (ert-info ("3" :prefix "Verify highlighting: ") (pre: "^Hi") (post: "^")) From decaa4ea25a77b813f4a22219980f933812f840e Mon Sep 17 00:00:00 2001 From: bw Date: Sun, 18 Jan 2026 18:22:32 -0500 Subject: [PATCH 3/6] hywiki.el - Update tests with hywiki-tests--preserve-hywiki-mode --- ChangeLog | 27 +++ hproperty.el | 15 +- hywiki.el | 79 ++++--- test/hywiki-tests.el | 445 +++++++++++++++++---------------------- test/hywiki-yki-tests.el | 4 +- 5 files changed, 276 insertions(+), 294 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f11892f..638a3d55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2026-01-18 Bob Weiner + +* hywiki.el (hywiki--get-all-references): Handle ref ordering diffs between + Emacs prior to 29 and after so callers do not have to handle. + +* test/hywiki-tests.el (hywiki-tests--hywiki-face-region-at): Remove, unused. + +* hywiki.el (hywiki-highlight-word-get-range): Rename to 'hywiki-word-range-at'. + (hywiki-get-reference-range): Add and use in tests. + (hywiki-word-highlighted-at): Rename to 'hywiki-highlighted-word-at'. + +* test/hywiki-tests.el (hywiki-tests--word-n-face-at): Remove and replace + with calls to 'hywiki-highlighted-word-at'. + +* hproperty.el (hproperty:char-property-face-p): Fix doc to not refer to HyWiki. + (hproperty:but-is-p): Add. + +* test/hywiki-tests.el (hywiki-tests--preserve-hywiki-mode): Fix to use the + actual prior value of 'hywiki-mode' since there are now 3 valid states. + Also setup more of the test scenarios and rewrite tests to not duplicate + this behavior. + (hywiki-tests--face-property-for-wikiword-with-wikipage): Fix this test. + +* test/hywiki-yki-tests.el (hywiki-test--set-buffer-text-with-point-and-highlight): + For clarity change 'hywiki-mode' arg from 1 to :all and move before + 'erase-buffer' call. + 2026-01-12 Bob Weiner * hywiki.el: (hywiki-word-highlight-in-buffers, hywiki-word-highlight-in-frame): diff --git a/hproperty.el b/hproperty.el index 5c63146a..9071b744 100644 --- a/hproperty.el +++ b/hproperty.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 21-Aug-92 -;; Last-Mod: 31-Dec-25 at 16:02:19 by Mats Lidell +;; Last-Mod: 18-Jan-26 at 12:04:29 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -14,7 +14,7 @@ ;;; Commentary: ;; -;; Can't use read-only buttons here because then outline-mode +;; Can't use read-only buttons here because then `outline-mode' ;; becomes unusable. ;;; Code: @@ -28,12 +28,13 @@ ;;; ************************************************************************ (declare-function hattr:get "hbut") +(declare-function hbut:is-p "hbut") (declare-function ibut:map "hbut") (declare-function ebut:map "hbut") -;; Comment out next line out because this triggers loads of kview -;; which loads klink which contains a defib whose priority should be set -;; by loading klink from hibtypes.el instead. +;; Comment out next line out because this loads kview which loads +;; klink which contains a defib whose priority should be set by +;; loading klink from hibtypes.el instead. ;; (eval-when-compile (require 'hyrolo)) ;;; ************************************************************************ @@ -324,6 +325,7 @@ Return nil if none." (overlays-in start end)) nil)) +(defalias 'hproperty:but-is-p 'hbut:is-p) (defun hproperty:but-move (hproperty-but start end &optional buffer) "Set the endpoints of HPROPERTY-BUT to START and END in optional BUFFER. If BUFFER is nil and HPROPERTY-BUT has no buffer, put it in the current buffer; @@ -371,8 +373,7 @@ See `hproperty:but-get'." value))) (defun hproperty:char-property-face-p (pos face-list) - "At POS, skip HyWikiWord highlighting if find any face in FACE-LIST. -Return non-nil in any such case, else nil." + "At POS, return non-nil if find any face in FACE-LIST, else nil." (save-excursion (goto-char pos) (seq-intersection (face-at-point nil t) face-list #'eq))) diff --git a/hywiki.el b/hywiki.el index 578e84d6..000814dc 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: 18-Jan-26 at 08:31:39 by Bob Weiner +;; Last-Mod: 18-Jan-26 at 17:34:29 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -553,6 +553,7 @@ Non-nil is the default." (defun hywiki-word-store-around-point () "Store any HyWikiWord before or after point for post-command comparison. +Markers are stored into `hywiki--buttonize-start' and `hywiki--buttonize-end'. HyWikiWords are stored only outside of `hywiki-non-hook-context-p' contexts. This is triggered by `pre-command-hook' for non-character commands, including deletion commands and those in `hywiki-non-character-commands'." @@ -1747,6 +1748,30 @@ After successfully finding any kind of referent, run (run-hooks 'hywiki-find-referent-hook) referent)) +(defun hywiki-highlighted-word-at (&optional range-flag) + "Return highlighted HyWikiWord and optional #section:Lnum:Cnum at point or nil. +If the HyWikiWord is delimited, point must be within the delimiters. + +With optional RANGE-FLAG, return a list of (HyWikiWord start-position +end-position); the positions include the entire +HyWikiWord#section:Lnum:Cnum string but exclude any delimiters. + +This does not test whether a referent exists for the HyWikiWord; 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 (and (hywiki-active-in-current-buffer-p) + (setq hywiki--range + (hproperty:char-property-range (point) 'face hywiki-word-face))) + (let ((wikiword (buffer-substring-no-properties (car hywiki--range) (cdr hywiki--range)))) + (if (string-match hywiki-word-with-optional-suffix-exact-regexp wikiword) + (if range-flag + (list wikiword (car hywiki--range) (cdr hywiki--range)) + wikiword) + (when range-flag + '(nil nil nil)))))) + (defun hywiki-highlight-on-yank (_prop-value start end) "Used in `yank-handled-properties' called with START and END pos of the text." ;; When yank only part of a delimited pair, expand the range to @@ -2649,13 +2674,19 @@ regexps of wikiwords, if the hash table is out-of-date." ;; walk across all frames here, rehighlighting HyWikiWords. (hywiki-maybe-highlight-wikiwords-in-frame t t)))) +(defun hywiki-get-reference-range (reference) + "Return a (start . end) cons cell from a highlighted HyWikiWord REFERENCE." + (when (hproperty:but-is-p reference) + (cons (hproperty:but-start reference) + (hproperty:but-end reference)))) + (defun hywiki-get-references (&optional start end) "Return a list of all highlighted HyWikiWord references in the current buffer. Optional START and END arguments limit the search to references that at least partially overlap that region." (hywiki--get-all-references #'hproperty:but-get-all-in-region start end)) -(defun hywiki-get-reference-positions (&optional start end) + (defun hywiki-get-reference-positions (&optional start end) "Return a list of all highlighted HyWikiWord reference (start . end) positions. Optional START and END arguments limit the search to references that at least partially overlap that region." @@ -3164,30 +3195,6 @@ Action Key press; with a prefix ARG, emulate an Assist Key press." (hywiki-find-referent word) (hkey-either arg)))) -(defun hywiki-word-highlighted-at-p (&optional range-flag) - "Return highlighted HyWikiWord and optional #section:Lnum:Cnum at point or nil. -If the HyWikiWord is delimited, point must be within the delimiters. - -With optional RANGE-FLAG, return a list of (HyWikiWord start-position -end-position); the positions include the entire -HyWikiWord#section:Lnum:Cnum string but exclude any delimiters. - -This does not test whether a referent exists for the HyWikiWord; 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)) - (let ((wikiword (buffer-substring-no-properties (car hywiki--range) (cdr hywiki--range)))) - (if (string-match hywiki-word-with-optional-suffix-exact-regexp wikiword) - (if range-flag - (list wikiword (car hywiki--range) (cdr hywiki--range)) - wikiword) - (when range-flag - '(nil nil nil))))))) - (defun hywiki-word-at (&optional range-flag) "Return potential HyWikiWord and optional #section:Lnum:Cnum at point or nil. `hywiki-mode' must be enabled or this will return nil. @@ -3412,7 +3419,7 @@ Hyperbole button names." (hproperty:but-add start end hywiki-word-face))) (defun hywiki-highlight-word-get-range () - "Return list of potential (HyWikiWord#section:Lnum:Cnum start end). + "Return list of (HyWikiWord#section:Lnum:Cnum start end) around point. Also highlight HyWikiWord as necessary. If the HyWikiWord reference is delimited, point must be within the @@ -3420,7 +3427,8 @@ delimiters. The delimiters are excluded from start and end. If not at a HyWikiWord, return \\='(nil nil nil). This works regardless of whether the HyWikiWord has been highlighted -or not. +or not. Call `hywiki-highlighted-word-at' to test for a highlighted +HyWikiWord at point. This does not test whether a referent exists for the HyWikiWord; call `hywiki-referent-exists-p' without an argument for that. @@ -3491,7 +3499,8 @@ a HyWikiWord at point." range)))))) (defun hywiki-word-face-at-p (&optional pos) - "Non-nil if but at point or optional POS has `hywiki-word-face' property." + "Non-nil if point or optional POS has the `hywiki-word-face' property. +Return any HyWikiWord reference found." ;; Sometimes this can return a left over button/overlay that points ;; to no buffer. Ignore this case. (hproperty:but-get (or pos (point)) 'face hywiki-word-face)) @@ -3767,10 +3776,14 @@ delimiters." FUNCTION must take four arguments: (buffer-start-pos buffer-end-pos \\='face hywiki-word-face). Optional START and END are sent to the function as the first two arguments; otherwise, the entire buffer is scanned." - (funcall function - (or start (point-min)) - (or end (point-max)) - 'face hywiki-word-face)) + (let ((refs (funcall function + (or start (point-min)) + (or end (point-max)) + 'face hywiki-word-face))) + (if (version< emacs-version "29") + refs + ;; Button/overlay ordering is reversed after Emacs 28 + (nreverse refs)))) (defun hywiki--get-delimited-range-backward () "Return a list of (start end) if not between/after end ]] or >>. diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el index ebe5864a..a06a391b 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: 11-Jan-26 at 10:42:51 by Bob Weiner +;; Last-Mod: 18-Jan-26 at 18:22:23 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -62,8 +62,7 @@ Last two elements are optional.") (ert-deftest hywiki-tests--edit () - (let ((hywiki-directory (make-temp-file "hywiki" t)) - (test-num 0) + (let ((test-num 0) before after name @@ -73,11 +72,10 @@ Last two elements are optional.") start end hywiki-ref-positions) - (unwind-protect - (with-temp-buffer - (hywiki-tests--preserve-hywiki-mode + (hywiki-tests--preserve-hywiki-mode + (unwind-protect + (progn (org-mode) - (hywiki-mode :all) (mapc (lambda (before-after) (condition-case err @@ -90,23 +88,19 @@ Last two elements are optional.") ;; created so their references will be highlighted. (mapc #'hywiki-add-page (delq nil - (mapcar #'hywiki-get-singular-wikiword - (seq-remove #'string-empty-p + (mapcar #'hywiki-get-singular-wikiword + (seq-remove #'string-empty-p (mapcar #'string-trim (hywiki-tests--get-brace-strings after)))))) (unwind-protect - (progn + (progn (pop-to-buffer (current-buffer)) (erase-buffer) (hywiki-tests--insert-by-char before) (hywiki-tests--interpolate-buffer) ;; Markup before string in temp buffer ;; Surround any HyWikiWord refs with braces to match after string. - (setq hywiki-ref-positions - (if (version< emacs-version "29") - (hywiki-get-reference-positions) - ;; Button/overlay ordering is reversed after Emacs 28 - (nreverse (hywiki-get-reference-positions)))) + (setq hywiki-ref-positions (hywiki-get-reference-positions)) (dolist (start-end hywiki-ref-positions) (setq start (car start-end) end (cdr start-end)) @@ -139,13 +133,12 @@ Last two elements are optional.") :before before :after after)))) (cl-incf test-num)) (goto-char (point-min)))) - (error (error "%s ---- %S" err (list :markedup markedup-before + (error (error "%s ---- %S" err (list :markedup markedup-before :test-num test-num :before before :after after))))) - hywiki-tests--edit-string-pairs))) - (dolist (f '("AI.org" "Hi.org" "HiHo.org" "HyWikiWord.org" "MyWikiWord.org" "Non.org" "WikiWord.org")) - (hy-delete-file-and-buffer (expand-file-name f hywiki-directory))) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))) + hywiki-tests--edit-string-pairs)) + (dolist (f '("AI.org" "Hi.org" "HiHo.org" "HyWikiWord.org" "MyWikiWord.org" "Non.org")) + (hy-delete-file-and-buffer (expand-file-name f hywiki-directory))))))) (defun hywiki-tests--get-brace-strings (s) "Return the substrings in S delimited by curly braces {…}, excluding braces. @@ -220,11 +213,12 @@ Assume no nesting of braces, nor any quoting of braces." ;; This creates the 'hbut:current in-memory ibut (ibut:at-type-p 'action)) ;; Force HyWikiWord highlighting - (hywiki-tests--command-execute - 'hbut:act 'hbut:current))))) + (hywiki-tests--command-execute 'hbut:act 'hbut:current) + ;; (hywiki-word-highlight-post-command) + )))) (defun hywiki-tests--command-execute (sexp &rest rest) - "Apply SEXP to REST of arguments as a command and return the result. + "Apply SEXP to REST of arguments as a HyWiki command and return the result. Run pre and post command hooks around the call. This is for simulating the command loop." (let ((buf (current-buffer)) @@ -251,20 +245,29 @@ This is for simulating the command loop." (defmacro hywiki-tests--preserve-hywiki-mode (&rest body) "Restore hywiki-mode after running BODY." (declare (indent 0) (debug t)) - `(let ((current-hywiki-mode hywiki-mode)) + `(let* ((prior-hywiki-mode hywiki-mode) + (hywiki-directory (make-temp-file "hywiki" t)) + (wiki-page (cdr (hywiki-add-page "WikiWord")))) (unwind-protect - (progn ,@body) - (hywiki-mode (if current-hywiki-mode 1 0))))) + (save-window-excursion + (with-temp-buffer + (set-window-buffer (selected-window) (current-buffer)) + (hywiki-mode :all) + (sit-for 0.01) + ,@body)) + (hywiki-mode prior-hywiki-mode) + (hy-delete-file-and-buffer wiki-page) + (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))) (ert-deftest hywiki-tests--verify-preserve-hywiki-mode () "Verify `hywiki-tests--preserve-hywiki-mode' restores `hywiki-mode'." (hywiki-tests--preserve-hywiki-mode (hywiki-mode :all) (hywiki-tests--preserve-hywiki-mode - (should hywiki-mode) + (should (eq hywiki-mode :all)) (hywiki-mode nil) (should-not hywiki-mode)) - (should hywiki-mode))) + (should (eq hywiki-mode :all)))) (ert-deftest hywiki-tests--hywiki-create-page--adds-file-in-wiki-folder () "Verify add page creates file in wiki folder and sets hash table." @@ -753,24 +756,17 @@ Both mod-time and checksum must be changed for a test to return true." "Verify WikiWord for a wiki page gets face property hywiki-word-face." (skip-unless (not noninteractive)) (hywiki-tests--preserve-hywiki-mode - (let* ((hsys-org-enable-smart-keys t) - (hywiki-directory (make-temp-file "hywiki" t)) - (wikipage (cdr (hywiki-add-page "WikiWord")))) - (unwind-protect - (progn - (hywiki-mode :all) - (with-temp-buffer - (insert "WikiWor") - (hywiki-tests--command-execute #'self-insert-command 1 ?d) - (goto-char 4) - (should (hywiki-word-face-at-p))) - (with-temp-buffer - (insert "WikiWord") - (hywiki-tests--command-execute #'newline 1 'interactive) - (goto-char 4) - (should (hywiki-word-face-at-p)))) - (hy-delete-file-and-buffer wikipage) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (let* ((hsys-org-enable-smart-keys t)) + (insert "WikiWor") + (hywiki-tests--command-execute #'self-insert-command 1 ?d) + (goto-char 4) + (should (hywiki-word-face-at-p)) + + (erase-buffer) + (insert "WikiWord") + (hywiki-tests--command-execute #'newline 1 'interactive) + (goto-char 4) + (should (hywiki-word-face-at-p))))) (ert-deftest hywiki-tests--no-face-property-for-no-wikipage () "Verify WikiWord for no wiki page does not get face property hywiki-word-face." @@ -792,53 +788,38 @@ Both mod-time and checksum must be changed for a test to return true." "Verify face property changes when WikiWord is edited." (skip-unless (not noninteractive)) (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikipage (cdr (hywiki-add-page "WikiWord")))) - (unwind-protect - (with-temp-buffer - (hywiki-mode :all) - (insert "Wikiord ") - (goto-char 5) - (should (looking-at-p "ord ")) - (should-not (hywiki-word-face-at-p)) - - (hywiki-tests--command-execute #'self-insert-command 1 ?W) - (goto-char 5) - (should (looking-at-p "Word ")) - (should (hywiki-word-face-at-p)) - - (hywiki-tests--command-execute #'delete-char 1) - (should (looking-at-p "ord ")) - (should-not (hywiki-word-face-at-p))) - (hy-delete-files-and-buffers (list wikipage)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (insert "Wikiord ") + (goto-char 5) + (should (looking-at-p "ord ")) + (should-not (hywiki-word-face-at-p)) + + (hywiki-tests--command-execute #'self-insert-command 1 ?W) + (goto-char 5) + (should (looking-at-p "Word ")) + (should (hywiki-word-face-at-p)) + + (hywiki-tests--command-execute #'delete-char 1) + (should (looking-at-p "ord ")) + (should-not (hywiki-word-face-at-p)))) (ert-deftest hywiki-tests--verify-face-property-when-editing-wikiword-first-char () "Verify face property changes when WikiWord is edited in the first char position." (skip-unless (not noninteractive)) (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikipage (cdr (hywiki-add-page "WikiWord")))) - (unwind-protect - (progn - (with-temp-buffer - (hywiki-mode :all) - (insert "WikiWord") - (hywiki-tests--command-execute #'self-insert-command 1 ? ) - (goto-char 1) - (should (looking-at-p "WikiWord")) - (should (hywiki-word-face-at-p)) + (insert "WikiWord") + (hywiki-tests--command-execute #'self-insert-command 1 ? ) + (goto-char 1) + (should (looking-at-p "WikiWord")) + (should (hywiki-word-face-at-p)) - (hywiki-tests--command-execute #'delete-char 1) - (should (looking-at-p "ikiWord")) - (should-not (hywiki-word-face-at-p)) + (hywiki-tests--command-execute #'delete-char 1) + (should (looking-at-p "ikiWord")) + (should-not (hywiki-word-face-at-p)) - (hywiki-tests--command-execute #'self-insert-command 1 ?W) - (goto-char 1) - (should (looking-at-p "WikiWord")) - (should (hywiki-word-face-at-p)))) - (hy-delete-files-and-buffers (list wikipage)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (hywiki-tests--command-execute #'self-insert-command 1 ?W) + (goto-char 1) + (should (looking-at-p "WikiWord")) + (should (hywiki-word-face-at-p)))) (ert-deftest hywiki-tests--references-to-org-link () "Verify `hywiki-references-to-org-links' converts WikiWords to org links." @@ -1019,22 +1000,22 @@ would return org7c18f23." ;; org-publish does not work properly to support HyWiki export prior ;; to version 9.7, so this will be skipped for Emacs 28 and 29. (skip-unless (string-greaterp org-version "9.6.999")) - (let* ((hywiki-directory (make-temp-file "hywiki_" t)) - org-publish-project-alist - (hywiki-org-publishing-directory (make-temp-file "public_html_" t)) - (wikipage (cdr (hywiki-add-page "WikiPage"))) - (wikipage-html (expand-file-name "WikiPage.html" hywiki-org-publishing-directory)) - (wikiword (cdr (hywiki-add-page "WikiWord"))) - (wikiword-html (expand-file-name "WikiWord.html" hywiki-org-publishing-directory))) - (unwind-protect - (progn - (hywiki-org-set-publish-project) - (should (file-exists-p hywiki-directory)) - (should (file-exists-p wikipage)) - (should (file-exists-p wikiword)) + (hywiki-tests--preserve-hywiki-mode + (let* (org-publish-project-alist + (hywiki-org-publishing-directory (make-temp-file "public_html_" t)) + (wikipage (cdr (hywiki-add-page "WikiPage"))) + (wikipage-html (expand-file-name "WikiPage.html" hywiki-org-publishing-directory)) + (wikiword (cdr (hywiki-add-page "WikiWord"))) + (wikiword-html (expand-file-name "WikiWord.html" hywiki-org-publishing-directory))) + (unwind-protect + (progn + (hywiki-org-set-publish-project) + (should (file-exists-p hywiki-directory)) + (should (file-exists-p wikipage)) + (should (file-exists-p wikiword)) - ;; Setup wiki pages for WikiWord and WikiPage. - (with-current-buffer (find-file-noselect wikiword) + ;; Setup wiki pages for WikiWord and WikiPage. + (find-file wikiword) (insert "\ First line * Asection @@ -1044,111 +1025,109 @@ body B *** Csection-subsection body C ") - (save-buffer)) - (with-current-buffer (find-file-noselect wikipage) + (save-buffer) + (find-file wikipage) (insert "\ WikiWord WikiWord#Asection \"WikiWord#Bsection subsection\" WikiWord#Csection-subsection ") - (save-buffer)) - - ;; Export the wiki - (hywiki-publish-to-html t) - - ;; Verify files and folder are generated - (should (file-exists-p hywiki-org-publishing-directory)) - (should (file-exists-p wikipage-html)) - (should (file-exists-p wikiword-html)) - - (let (idA idB idC) - ;; Verify anchors are generated and fetch their ids - (with-current-buffer (find-file-noselect wikiword-html) - (setq idA (should (hywiki-tests--search-section "Asection"))) - (setq idB (should (hywiki-tests--search-section "Bsection subsection"))) - (setq idC (should (hywiki-tests--search-section "Csection-subsection")))) - - ;; Verify links are generated - (with-current-buffer (find-file-noselect wikipage-html) - ;; (First check we even get the wikipage with sections) - (should (<= 1 (count-matches (regexp-quote "WikiWord") (point-min) (point-max)))) - (should (= 1 (count-matches (regexp-quote "WikiWord#Asection") (point-min) (point-max)))) - (should (= 1 (count-matches (regexp-quote "WikiWord#Bsection subsection") (point-min) (point-max)))) - (should (= 1 (count-matches (regexp-quote "WikiWord#Csection-subsection") (point-min) (point-max)))) - - ;; Then verify the href links are generated - (should (= 1 (count-matches (regexp-quote "WikiWord") (point-min) (point-max)))) - (should (= 1 (count-matches - (format "WikiWord#Asection" idA) (point-min) (point-max)))) - (should (= 1 (count-matches - (format "WikiWord#Bsection subsection" idB) (point-min) (point-max)))) - (should (= 1 (count-matches - (format "WikiWord#Csection-subsection" idC) (point-min) (point-max))))))) - (hy-delete-files-and-buffers (list wikipage wikiword wikipage-html wikiword-html - (expand-file-name "index.org" hywiki-directory) - (expand-file-name "index.html" hywiki-org-publishing-directory))) - (hy-delete-dir-and-buffer hywiki-org-publishing-directory) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))) + (save-buffer) + + ;; Export the wiki + (hywiki-publish-to-html t) + + ;; Verify files and folder are generated + (should (file-exists-p hywiki-org-publishing-directory)) + (should (file-exists-p wikipage-html)) + (should (file-exists-p wikiword-html)) + + (let (idA idB idC) + ;; Verify anchors are generated and fetch their ids + (with-current-buffer (find-file-noselect wikiword-html) + (setq idA (should (hywiki-tests--search-section "Asection"))) + (setq idB (should (hywiki-tests--search-section "Bsection subsection"))) + (setq idC (should (hywiki-tests--search-section "Csection-subsection")))) + + ;; Verify links are generated + (find-file wikipage-html) + ;; (First check we even get the wikipage with sections) + (should (<= 1 (count-matches (regexp-quote "WikiWord") (point-min) (point-max)))) + (should (= 1 (count-matches (regexp-quote "WikiWord#Asection") (point-min) (point-max)))) + (should (= 1 (count-matches (regexp-quote "WikiWord#Bsection subsection") (point-min) (point-max)))) + (should (= 1 (count-matches (regexp-quote "WikiWord#Csection-subsection") (point-min) (point-max)))) + + ;; Then verify the href links are generated + (should (= 1 (count-matches (regexp-quote "WikiWord") (point-min) (point-max)))) + (should (= 1 (count-matches + (format "WikiWord#Asection" idA) (point-min) (point-max)))) + (should (= 1 (count-matches + (format "WikiWord#Bsection subsection" idB) (point-min) (point-max)))) + (should (= 1 (count-matches + (format "WikiWord#Csection-subsection" idC) (point-min) (point-max)))))) + (hy-delete-files-and-buffers (list wikipage wikiword wikipage-html wikiword-html + (expand-file-name "index.org" hywiki-directory) + (expand-file-name "index.html" hywiki-org-publishing-directory))) + (hy-delete-dir-and-buffer hywiki-org-publishing-directory))))) (ert-deftest hywiki-tests--publish-special-cases () "Verify different special cases." ;; org-publish does not work properly to support HyWiki export prior ;; to version 9.7, so this will be skipped for Emacs 28 and 29. (skip-unless (string-greaterp org-version "9.6.999")) - (let* ((hywiki-directory (make-temp-file "hywiki_" t)) - org-publish-project-alist - (hywiki-org-publishing-directory (make-temp-file "public_html_" t)) - (wikipage (cdr (hywiki-add-page "WikiPage"))) - (wikipage-html (expand-file-name "WikiPage.html" hywiki-org-publishing-directory)) - (wikiword (cdr (hywiki-add-page "WikiWord"))) - (wikiword-html (expand-file-name "WikiWord.html" hywiki-org-publishing-directory)) - (href "WikiWord")) - (unwind-protect - (progn - (hywiki-org-set-publish-project) + (hywiki-tests--preserve-hywiki-mode + (let* (org-publish-project-alist + (hywiki-org-publishing-directory (make-temp-file "public_html_" t)) + (wikipage (cdr (hywiki-add-page "WikiPage"))) + (wikipage-html (expand-file-name "WikiPage.html" hywiki-org-publishing-directory)) + (wikiword (cdr (hywiki-add-page "WikiWord"))) + (wikiword-html (expand-file-name "WikiWord.html" hywiki-org-publishing-directory)) + (href "WikiWord")) + (unwind-protect + (progn + (hywiki-org-set-publish-project) - (with-current-buffer (find-file-noselect wikiword) + (find-file wikiword) (erase-buffer) (insert "Text\n") - (save-buffer)) - - (should (file-exists-p hywiki-directory)) - (should (file-exists-p wikipage)) - (should (file-exists-p wikiword)) - - (dolist (v `(("WikiWord WikiWord" . ,(format "%s %s" href href)) - ("\"WikiWord WikiWord\"" . ,(format "\"%s%s\"" href href)) - ;; ^ Missing a space!? - ("WikiWord Text WikiWord" . ,(format "%s Text %s" href href)) - ("\"WikiWord Text WikiWord\"" . ,(format "\"%s%s\"" href href)) - ;; ^ Missing " Text " - ("WikiWord WikiWord WikiWord" . ,(format "%s %s %s" href href href)) - ;; (cons "\"WikiWord WikiWord WikiWord\"" (format "\"%s %s %s\"" href href href)) - ;; ^ Crashes due to (wrong-type-argument integer-or-marker-p nil) caused by buffer-substring-no-properties(nil nil) - )) - (let ((input (car v)) - (regex-output (cdr v))) - ;; Setup WikiPage. - (with-current-buffer (find-file-noselect wikipage) + (save-buffer) + + (should (file-exists-p hywiki-directory)) + (should (file-exists-p wikipage)) + (should (file-exists-p wikiword)) + + (dolist (v `(("WikiWord WikiWord" . ,(format "%s %s" href href)) + ("\"WikiWord WikiWord\"" . ,(format "\"%s%s\"" href href)) + ;; ^ Missing a space!? + ("WikiWord Text WikiWord" . ,(format "%s Text %s" href href)) + ("\"WikiWord Text WikiWord\"" . ,(format "\"%s%s\"" href href)) + ;; ^ Missing " Text " + ("WikiWord WikiWord WikiWord" . ,(format "%s %s %s" href href href)) + ;; (cons "\"WikiWord WikiWord WikiWord\"" (format "\"%s %s %s\"" href href href)) + ;; ^ Crashes due to (wrong-type-argument integer-or-marker-p nil) caused by buffer-substring-no-properties(nil nil) + )) + (let ((input (car v)) + (regex-output (cdr v))) + ;; Setup WikiPage. + (find-file wikipage) (erase-buffer) (insert input) - (save-buffer)) + (save-buffer) - ;; Export the wiki - (hywiki-publish-to-html t) + ;; Export the wiki + (hywiki-publish-to-html t) - ;; Verify Export - (ert-info ((format "Publish '%s' => Expect '%s'" input regex-output)) - (with-current-buffer (find-file-noselect wikipage-html t) + ;; Verify Export + (ert-info ((format "Publish '%s' => Expect '%s'" input regex-output)) + (find-file wikipage-html t) (revert-buffer t t) - (should (= 1 (count-matches regex-output (point-min) (point-max))))))))) - ;; Unwind - (hy-delete-files-and-buffers (list wikipage wikiword wikipage-html wikiword-html - (expand-file-name "index.org" hywiki-directory) - (expand-file-name "index.html" hywiki-org-publishing-directory))) - (hy-delete-dir-and-buffer hywiki-org-publishing-directory) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))) + (should (= 1 (count-matches regex-output (point-min) (point-max)))))))) + ;; Unwind + (hy-delete-files-and-buffers (list wikipage wikiword wikipage-html wikiword-html + (expand-file-name "index.org" hywiki-directory) + (expand-file-name "index.html" hywiki-org-publishing-directory))) + (hy-delete-dir-and-buffer hywiki-org-publishing-directory))))) (ert-deftest hywiki-tests--get-singular-wikiword () "Verify plural WikiWord is converted to singular. @@ -1342,7 +1321,7 @@ Note special meaning of `hywiki-allow-plurals-flag'." (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))) (defmacro hywiki-tests--referent-test (expected-referent &rest prepare) - "Template macro for generated a non-page HyWikiWord referent. + "Template macro for generating a non-page HyWikiWord referent. EXPECTED-REFERENT is the result expected from `hywiki-get-referent'. The template runs the PREPARE body, and that must add the HyWikiWord named WikiReferent with a non-page referent type." @@ -1613,24 +1592,18 @@ See gh#rswgnu/hyperbole/669." "Verify `hywiki-word-face-at-p'." (skip-unless (not noninteractive)) (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wiki-page (cdr (hywiki-add-page "WikiWord")))) - (with-temp-buffer - (hywiki-mode nil) - (insert "WikiWor") - (hywiki-tests--command-execute #'self-insert-command 1 ?d) - (goto-char 4) - (should-not (hywiki-word-face-at-p))) - (unwind-protect - (progn - (with-temp-buffer - (hywiki-mode :all) - (insert "WikiWor") - (hywiki-tests--command-execute #'self-insert-command 1 ?d) - (goto-char 4) - (should (hywiki-word-face-at-p)))) - (hy-delete-file-and-buffer wiki-page) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (hywiki-mode nil) + (insert "WikiWor") + (hywiki-tests--command-execute #'self-insert-command 1 ?d) + (goto-char 4) + (should-not (hywiki-word-face-at-p)) + + (erase-buffer) + (hywiki-mode :all) + (insert "WikiWor") + (hywiki-tests--command-execute #'self-insert-command 1 ?d) + (goto-char 4) + (should (hywiki-word-face-at-p)))) (defun hywiki-tests--hywiki-face-regions () "Return (start . end) for all hywiki--word-face overlays in buffer. @@ -1646,38 +1619,18 @@ comparison with expected overlays stable." (and (= (car x) (car y)) (< (cdr x) (cdr y)))))))) -(defun hywiki-tests--hywiki-face-region-at (&optional pos) - "Get the start and end of the hywiki--word-face overlay at POS or point. -Return nil if not at a `hywiki--word-face' overlay." - (let ((overlays (overlays-at (or pos (point)))) - result) - (when overlays - (dolist (overlay overlays result) - (when (equal (overlay-get overlay 'face) 'hywiki--word-face) - (cl-assert (not result) "There can only be one overlay with `hywiki--word-face'") - (setq result (cons (overlay-start overlay) (overlay-end overlay)))))))) - -(defun hywiki-tests--word-n-face-at () - "Non-nil if at a WikiWord and it has `hywiki--word-face'." - (cl-destructuring-bind (word beg end) - (hywiki-highlight-word-get-range) - (when word - (when (hy-test-word-face-at-region beg end) - (should (equal (hywiki-tests--hywiki-face-region-at beg) (cons beg end))) - word)))) - (defvar hywiki-tests--with-face-test t "Non-nil to perform face validation of WikiWord.") (defun hywiki-tests--word-at () "Choose what test to perform based on value of `hywiki-tests--with-face-test'." (if hywiki-tests--with-face-test - (hywiki-tests--word-n-face-at) + (hywiki-highlighted-word-at) (hywiki-word-at))) (defun hywiki-tests--verify-hywiki-word (expected) "Verify that `hywiki-word-at' returns t if a wikiword is EXPECTED. -If EXPECTED is a string also verify that the wikiword matches the +If EXPECTED is a string, also verify that the wikiword matches the string." (if (not expected) (should-not (hywiki-tests--word-at)) @@ -1776,20 +1729,16 @@ Perform each operation from the step check and verify whether there is a WikiWord at point or not." (skip-unless (not noninteractive)) (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikiHiHo (cdr (hywiki-add-page "HiHo"))) + (let* ((wikiHiHo (cdr (hywiki-add-page "HiHo"))) (wikiHiho (cdr (hywiki-add-page "Hiho"))) (wikiHi (cdr (hywiki-add-page "Hi"))) (wikiHo (cdr (hywiki-add-page "Ho"))) (wiki-page-list (list wikiHiHo wikiHiho wikiHi wikiHo))) (unwind-protect - (progn - (hywiki-mode :all) - (dolist (testcase hywiki-tests--wikiword-step-check) - (with-temp-buffer - (hywiki-tests--run-test-case testcase)))) - (hy-delete-files-and-buffers wiki-page-list) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (dolist (testcase hywiki-tests--wikiword-step-check) + (erase-buffer) + (hywiki-tests--run-test-case testcase)) + (hy-delete-files-and-buffers wiki-page-list))))) (defconst hywiki-tests--lorem-ipsum "\ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse @@ -1834,26 +1783,18 @@ Insert test in the middle of other text." A WikiWord is completed, then last char is deleted and reinserted. The face is verified during the change." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wiki-page (cdr (hywiki-add-page "WikiWord")))) - (unwind-protect - (progn - (hywiki-mode :all) - (with-temp-buffer - (emacs-lisp-mode) - (insert "\ + (emacs-lisp-mode) + (insert "\ (defun func () \"WikiWor) ") - ;; Set point after WikiWor - (goto-char 1) - (should (search-forward "WikiWor")) + ;; Set point after WikiWor + (goto-char 1) + (should (search-forward "WikiWor")) - ;; Complete WikiWord and verify highlighting - (hywiki-tests--run-test-case - '(("d\"" . "WikiWord") (p2 . t) (-1) ("d" . "WikiWord"))))) - (hy-delete-file-and-buffer wiki-page) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + ;; Complete WikiWord and verify highlighting + (hywiki-tests--run-test-case + '(("d" . "WikiWord") ("\"" . "WikiWord") (p2 . t) (-1) ("d" . "WikiWord"))))) (ert-deftest hywiki-tests--wikiword-identified-in-emacs-lisp-mode () "Verify WikiWord is identified when surrounded by delimiters in `emacs-lisp-mode'." diff --git a/test/hywiki-yki-tests.el b/test/hywiki-yki-tests.el index 4257a582..4beff369 100644 --- a/test/hywiki-yki-tests.el +++ b/test/hywiki-yki-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date: 13-Jul-25 at 19:50:37 -;; Last-Mod: 11-Jan-26 at 10:35:55 by Bob Weiner +;; Last-Mod: 18-Jan-26 at 08:45:21 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -132,8 +132,8 @@ buffer. End the insertion of text by turning on hywiki-mode and perform a dummy command to get the pre- and post-hooks executed. This creates the highlighting overlays we want to test." + (hywiki-mode :all) (erase-buffer) - (hywiki-mode 1) (goto-char (hywiki-test--insert-with-point description))) (defun hywiki-test--get-buffer-text-with-point-and-highlight () From 77796165012b8b115f336533e222a55b6bfe0fa7 Mon Sep 17 00:00:00 2001 From: bw Date: Mon, 19 Jan 2026 23:17:19 -0500 Subject: [PATCH 4/6] hywiki-tests--execute-commands - Manually run 'post-self-insert-hook --- ChangeLog | 5 +++++ hywiki.el | 8 ++++---- test/hywiki-tests.el | 23 +++++++++++++---------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 638a3d55..d96e9be3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2026-01-19 Bob Weiner + +* test/hywiki-tests.el (hywiki-tests--execute-commands): Manually run + 'post-self-insert-hook' when appropriate. + 2026-01-18 Bob Weiner * hywiki.el (hywiki--get-all-references): Handle ref ordering diffs between diff --git a/hywiki.el b/hywiki.el index 000814dc..aa44c348 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: 18-Jan-26 at 17:34:29 by Bob Weiner +;; Last-Mod: 19-Jan-26 at 22:15:11 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -2686,7 +2686,7 @@ Optional START and END arguments limit the search to references that at least partially overlap that region." (hywiki--get-all-references #'hproperty:but-get-all-in-region start end)) - (defun hywiki-get-reference-positions (&optional start end) +(defun hywiki-get-reference-positions (&optional start end) "Return a list of all highlighted HyWikiWord reference (start . end) positions. Optional START and END arguments limit the search to references that at least partially overlap that region." @@ -3603,8 +3603,8 @@ auto-highlighting." (dolist (buf buffers) (with-current-buffer buf (add-hook 'pre-command-hook 'hywiki-word-store-around-point 95 :local) - (add-hook 'post-command-hook 'hywiki-word-highlight-post-command 95 :local) (add-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert 95 :local) + (add-hook 'post-command-hook 'hywiki-word-highlight-post-command 95 :local) ;; Display buffer before `normal-mode' triggers possibly ;; long-running font-locking (sit-for 0) @@ -3633,8 +3633,8 @@ auto-highlighting." (dolist (buf buffers) (with-current-buffer buf (remove-hook 'pre-command-hook 'hywiki-word-store-around-point :local) - (remove-hook 'post-command-hook 'hywiki-word-highlight-post-command :local) (remove-hook 'post-self-insert-hook 'hywiki-word-highlight-post-self-insert :local) + (remove-hook 'post-command-hook 'hywiki-word-highlight-post-command :local) ;; Display buffer before `normal-mode' triggers possibly ;; long-running font-locking (sit-for 0) diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el index a06a391b..0d752cbe 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: 18-Jan-26 at 18:22:23 by Bob Weiner +;; Last-Mod: 19-Jan-26 at 23:11:08 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -34,9 +34,9 @@ ;; ("\"WikiWord#section with spaces\"" "\"{WikiWord#section} with spaces") ;; shrink highlight to "{WikiWord#section} ;; These tests pass + ("Hi" "{Hi}") ("HyWikiWord HyWikiWord" "{HyWikiWord} {HyWikiWord}") - ("Hi" "{Hi}") ("HyWikiWord" "{HyWikiWord}") ("HyWikiWord" "{HyWikiWord}") ("HyWiki" "{HyWikiWord}") @@ -186,7 +186,8 @@ Assume no nesting of braces, nor any quoting of braces." "Process all events from `unread-command-events'." (interactive) (while unread-command-events - (let ((event (pop unread-command-events))) + (let ((event (pop unread-command-events)) + (noninteractive nil)) ;; Execute this event as if typed (setq this-command (key-binding (vector event) t) last-command-event event) @@ -194,10 +195,12 @@ Assume no nesting of braces, nor any quoting of braces." ;; event last-command-event this-command) (when this-command (run-hooks 'pre-command-hook) - ;; `command-execute' runs only `post-self-insert-hook' since - ;; this is run during the command; pre- and post-command hooks - ;; therefore are run manually. - (command-execute this-command) + (command-execute this-command) + (when (and (symbolp this-command) + (string-suffix-p "self-insert-command" (symbol-name this-command))) + ;; Force execution of `post-self-insert-hook' since is not + ;; run automatically when not in top-level command processing + (run-hooks 'post-self-insert-hook)) (run-hooks 'post-command-hook))))) (defun hywiki-tests--interpolate-buffer () @@ -984,14 +987,13 @@ body B (hy-delete-file-and-buffer wikipage) (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) - (defun hywiki-tests--search-section (section) "Find SECTION in current buffer and return the id string. Search for elements of type ... for the id string. Example:

1.1.1. section

would return org7c18f23." (save-excursion - (beginning-of-buffer) + (goto-char (point-min)) (when (re-search-forward (format ".* %s" section) nil t) (match-string-no-properties 1)))) @@ -1857,7 +1859,8 @@ face is verified during the change." \"%s.\" nil) " (mapconcat 'identity words " "))) - (goto-line 2) + (goto-char (point-min)) + (forward-line 1) (dolist (v words) (should (search-forward v)) (should (string= v (hywiki-word-at))))))))) From 0f160abc8e0e752328267388ab86bd5c9131a750 Mon Sep 17 00:00:00 2001 From: bw Date: Sun, 25 Jan 2026 12:40:47 -0500 Subject: [PATCH 5/6] hywiki.el - Some fixes needed for hywiki-mode highlighting --- ChangeLog | 40 ++++ hywiki.el | 69 ++++--- test/hywiki-tests.el | 478 +++++++++++++++++++------------------------ 3 files changed, 295 insertions(+), 292 deletions(-) diff --git a/ChangeLog b/ChangeLog index d96e9be3..26b24f9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2026-01-25 Bob Weiner + +* hywiki.el (hywiki-potential-buffer-p, hywiki-non-hook-context-p): Comment + out 'edebug-active' checks, so can examine same behavior when edebugging. + (hywiki-word-set-auto-highlighting): Fix to ensure all hywiki + hooks are removed any time 'hywiki-mode' is disabled. + +* test/hywiki-tests.el (hywiki-tests--interpolate-buffer): Fix to highlight + any HyWiki word at point and create its page by activating it. This is + separate from processing action buttons. + +2026-01-24 Bob Weiner + +* test/hywiki-tests.el (hywiki-tests--wikiword-identified-in-emacs-lisp-mode, + hywiki-tests--wikiword-identified-in-strings-in-emacs-lisp-mode, + hywiki-tests--wikiword-identified-in-emacs-lisp-mode, + hywiki-tests--filename-same-as-wiki-word, + hywiki-tests--verify-removal-of-delimiter-updates-face, + hywiki-tests--wikiword-yanked-with-extra-words, + hywiki-test--hywiki-mode, + hywiki-tests--interactive-hywiki-mode-toggles): + Remove unneeded calls due to 'hywiki-tests--preserve-hywiki-mode' macro. + (hywiki-tests--verify-removal-of-delimiter-updates-face, + (hywiki-tests--maybe-highlight-page-names): Remove expected fail so can + debug. + (hywiki-tests--nonexistent-wikiword-with-section-should-create-wikiword): + Rewrite. + +* hywiki.el (hywiki-active-in-current-buffer-p, hywiki-get-buffers): Fix + minibuffer predicate used to reflect current buffer even if window + not selected. Add and use 'hywiki-potential-buffer-p' to share common + predicates. + (hywiki-get-buffers): Stop filtering out hidden buffers that start + with a space since they may be in a text mode and may be shown in a window. + Also fix usage of 'hywiki-mode-status' argument so is part of the filtering. + (hywiki-in-page-p): Ensure 'buffer-file-name' ends with + 'hywiki-file-suffix'. + (hywiki-active-in-current-buffer-p): Fix filtering when 'hywiki-mode' + is :pages. + 2026-01-19 Bob Weiner * test/hywiki-tests.el (hywiki-tests--execute-commands): Manually run diff --git a/hywiki.el b/hywiki.el index aa44c348..412471f5 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-Jan-26 at 22:15:11 by Bob Weiner +;; Last-Mod: 25-Jan-26 at 12:40:15 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -741,8 +741,8 @@ deletion commands and those in `hywiki-non-character-commands'." (defun hywiki-non-hook-context-p () "Return non-nil when HyWiki command hooks should do nothing." (or (minibuffer-window-active-p (selected-window)) - (and (bound-and-true-p edebug-active) - (active-minibuffer-window)) + ;; (and (bound-and-true-p edebug-active) + ;; (active-minibuffer-window)) (and (derived-mode-p 'prog-mode) (not (apply #'derived-mode-p hywiki-highlight-all-in-prog-modes)) ;; Not inside a comment or a string @@ -1014,12 +1014,17 @@ with the referent." (defun hywiki-active-in-current-buffer-p () "Return non-nil if HyWikiWord links are active in the current buffer. Exclude the minibuffer if selected and return nil." - (and hywiki-mode - (not (minibuffer-window-active-p (selected-window))) - (not (and (boundp 'edebug-active) edebug-active (active-minibuffer-window))) + (if (eq hywiki-mode :pages) + (hywiki-in-page-p) + (and hywiki-mode (hywiki-potential-buffer-p)))) + +(defun hywiki-potential-buffer-p () + "Return non-nil if the current buffer can support HyWikiWords. +This does not mean `hywiki-mode' is presently active in that buffer." + (and (not (minibufferp)) + ;; (not (and (boundp 'edebug-active) edebug-active)) (not (apply #'derived-mode-p hywiki-exclude-major-modes)) - (or (and (eq hywiki-mode :pages) (hywiki-in-page-p)) - (derived-mode-p 'kotl-mode) + (or (derived-mode-p 'kotl-mode) (not (eq (get major-mode 'mode-class) 'special))))) (defun hywiki-add-activity (wikiword) @@ -1295,6 +1300,8 @@ with the page." (defun hywiki-add-page (page-name &optional force-flag) "Add a new or return any existing HyWiki page path for PAGE-NAME. Returned format is: \\='(page . \"\") or nil when none. +PAGE-NAME must be the HyWikiWord that can link to the page (no file-name +prefix or suffix). With optional FORCE-FLAG prefix arg non-nil, force an update to the page's modification time. If PAGE-NAME is invalid, trigger a @@ -2545,11 +2552,13 @@ the current page unless they have sections attached." (hywiki-maybe-directory-updated)) (defun hywiki-in-page-p () - "Return non-nil if the current buffer is a HyWiki page." + "Return non-nil if the current buffer is a HyWiki page. +Note that HyWiki references can occur in non-HyWiki page buffers." (or hywiki-page-flag (and buffer-file-name + (string-suffix-p hywiki-file-suffix buffer-file-name) (string-prefix-p (expand-file-name hywiki-directory) - (or default-directory "")) + buffer-file-name) (setq hywiki-page-flag t)))) (defun hywiki-get-buffer-page-name () @@ -2567,18 +2576,18 @@ rest of arguments FRAMES." (or frames (frame-list)))))) (defun hywiki-get-buffers (hywiki-mode-status) - "Return the list of window buffers active for HYWIKI-BUFFER-STATUS. + "Return the list of HyWiki buffers displayed in any non-minibuffer window. +A HyWiki buffer is one where HyWikiWord references are highlighted +when 'hywiki-mode' is enabled. + See the function documentation for `hywiki-mode' for valid input values (the states of `hywiki-mode')." (when hywiki-mode (delq nil (mapcar (lambda (buf) (with-current-buffer buf - (and (not (and (boundp 'edebug-active) edebug-active (active-minibuffer-window))) - (not (apply #'derived-mode-p hywiki-exclude-major-modes)) - (not (string-prefix-p " " (buffer-name buf))) - (or (and (eq hywiki-mode-status :pages) (hywiki-in-page-p)) - (derived-mode-p 'kotl-mode) - (not (eq (get major-mode 'mode-class) 'special))) + (and (if (eq hywiki-mode-status :pages) + (hywiki-in-page-p) + (hywiki-potential-buffer-p)) buf))) (hywiki-get-buffers-in-windows))))) @@ -3574,22 +3583,22 @@ If point is on one, press RET immediately to use that one." Highlight only those buffers attached to windows. Auto-highlighting uses pre- and post-command hooks. If an error -occurs with one of these hooks, the problematic hook is removed. -Invoke this command with a prefix argument to restore the -auto-highlighting." - (cond ((eq hywiki-from-mode hywiki-to-mode) - nil) +occurs with one of these hooks, the problematic hook is removed." + (cond ((null hywiki-to-mode) + ;; Ensure hooks are removed from all hywiki buffers any time + ;; mode is disabled + (let ((hywiki-mode :all)) + (hywiki-word-dehighlight-buffers (hywiki-get-buffers hywiki-mode)))) ((null hywiki-from-mode) (hywiki-word-highlight-buffers (hywiki-get-buffers hywiki-to-mode))) - ((and (eq hywiki-from-mode :all) (eq hywiki-to-mode :pages)) - (hywiki-word-dehighlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) - (hywiki-get-buffers hywiki-to-mode)))) + ((and (eq hywiki-from-mode :all) (eq hywiki-to-mode :pages)) + (hywiki-word-dehighlight-buffers + (set:difference (hywiki-get-buffers hywiki-from-mode) + (hywiki-get-buffers hywiki-to-mode)))) ((and (eq hywiki-from-mode :pages) (eq hywiki-to-mode :all)) - (hywiki-word-highlight-buffers (set:difference (hywiki-get-buffers hywiki-from-mode) - (hywiki-get-buffers hywiki-to-mode)))) - ((or (and (eq hywiki-from-mode :all) (eq hywiki-to-mode nil)) - (and (eq hywiki-from-mode :pages) (eq hywiki-to-mode nil))) - (hywiki-word-dehighlight-buffers (hywiki-get-buffers hywiki-from-mode))) + (hywiki-word-highlight-buffers + (set:difference (hywiki-get-buffers hywiki-from-mode) + (hywiki-get-buffers hywiki-to-mode)))) (t (error "(hywiki-word-set-auto-highlighting): Inputs must be nil, :pages or :all, not '%s' and '%s'" hywiki-from-mode hywiki-to-mode)))) diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el index 0d752cbe..f4993bd1 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: 19-Jan-26 at 23:11:08 by Bob Weiner +;; Last-Mod: 25-Jan-26 at 11:21:07 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -62,17 +62,17 @@ Last two elements are optional.") (ert-deftest hywiki-tests--edit () - (let ((test-num 0) - before - after - name - doc - markedup-before - markedup-after - start - end - hywiki-ref-positions) - (hywiki-tests--preserve-hywiki-mode + (hywiki-tests--preserve-hywiki-mode + (let ((test-num 0) + before + after + name + doc + markedup-before + markedup-after + start + end + hywiki-ref-positions) (unwind-protect (progn (org-mode) @@ -137,8 +137,9 @@ Last two elements are optional.") :test-num test-num :before before :after after))))) hywiki-tests--edit-string-pairs)) - (dolist (f '("AI.org" "Hi.org" "HiHo.org" "HyWikiWord.org" "MyWikiWord.org" "Non.org")) - (hy-delete-file-and-buffer (expand-file-name f hywiki-directory))))))) + (let ((default-directory hywiki-directory)) + (hy-delete-files-and-buffers + '("AI.org" "Hi.org" "HiHo.org" "HyWiki" "HyWikiW" "HyWikiWord.org" "MyWikiWord.org" "Non.org" "Wiki"))))))) (defun hywiki-tests--get-brace-strings (s) "Return the substrings in S delimited by curly braces {…}, excluding braces. @@ -210,15 +211,16 @@ Assume no nesting of braces, nor any quoting of braces." (hpath:substitute-value str) ;; Replace action buttons with resulting values (goto-char (point-min)) + (when (hbut:at-p) + ;; Force HyWikiWord highlighting at point + (hywiki-tests--command-execute 'hbut:act 'hbut:current)) (while (and (search-forward "<" nil t) (/= (preceding-char) ?\\)) (when (and (hargs:delimited-p "<" ">") ;; This creates the 'hbut:current in-memory ibut (ibut:at-type-p 'action)) - ;; Force HyWikiWord highlighting - (hywiki-tests--command-execute 'hbut:act 'hbut:current) - ;; (hywiki-word-highlight-post-command) - )))) + ;; Force HyWikiWord highlighting at point + (hywiki-tests--command-execute 'hbut:act 'hbut:current) )))) (defun hywiki-tests--command-execute (sexp &rest rest) "Apply SEXP to REST of arguments as a HyWiki command and return the result. @@ -1653,6 +1655,7 @@ or non-nil for a wikiword. The state is checked after all chars of the string are inserted. If equal to a string it is checked for match with the wikiword. Movement of point is relative to point when the function is called." + (erase-buffer) (let ((origin (point))) ;; For traceability when looking through the list of should @@ -1715,15 +1718,9 @@ point when the function is called." Performs each operation from the step check and verifies if the resulting state at point is a WikiWord or not." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (hywiki-tests--with-face-test nil)) - (unwind-protect - (progn - (hywiki-mode :all) - (dolist (testcase hywiki-tests--wikiword-step-check) - (with-temp-buffer - (hywiki-tests--run-test-case testcase)))) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (let ((hywiki-tests--with-face-test nil)) + (dolist (testcase hywiki-tests--wikiword-step-check) + (hywiki-tests--run-test-case testcase))))) (ert-deftest hywiki-tests--wikiword-step-check-verification-with-faces () "Run the step check to verify WikiWord is identified under change. @@ -1751,34 +1748,29 @@ aliquet diam euismod turpis ultricies, et porta sem blandit. Sed vitae." "Run the step check to verify WikiWord is identified under change. Insert test in the middle of other text." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (hywiki-tests--with-face-test nil)) - (unwind-protect - (progn - (hywiki-mode :all) - (with-temp-buffer - (insert hywiki-tests--lorem-ipsum) - (goto-char (/ (point-max) 2)) - (let ((pos (point))) - (insert " HiHo ") - (goto-char (1+ pos)) - (should (looking-at-p "HiHo "))) - (hywiki-tests--run-test-case - '((p3 . t) - (" " . "Hi") - (p1 . t) (p4 . t) (-1 . t)))) - (with-temp-buffer - (insert hywiki-tests--lorem-ipsum) - (goto-char (/ (point-max) 2)) - (let ((pos (point))) - (insert " Hiho ") - (goto-char (1+ pos)) - (should (looking-at-p "Hiho "))) - (hywiki-tests--run-test-case - '((p3 . t) - (" " . "Hi") - (p1 . t) (p4) (-1 . "Hiho"))))) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (let ((hywiki-tests--with-face-test nil)) + (insert hywiki-tests--lorem-ipsum) + (goto-char (/ (point-max) 2)) + (let ((pos (point))) + (insert " HiHo ") + (goto-char (1+ pos)) + (should (looking-at-p "HiHo "))) + (hywiki-tests--run-test-case + '((p3 . t) + (" " . "Hi") + (p1 . t) (p4 . t) (-1 . t))) + + (erase-buffer) + (insert hywiki-tests--lorem-ipsum) + (goto-char (/ (point-max) 2)) + (let ((pos (point))) + (insert " Hiho ") + (goto-char (1+ pos)) + (should (looking-at-p "Hiho "))) + (hywiki-tests--run-test-case + '((p3 . t) + (" " . "Hi") + (p1 . t) (p4) (-1 . "Hiho")))))) (ert-deftest hywiki-tests--wikiword-step-check-edit-wikiword-in-emacs-lisp-mode () "Run the step check to verify WikiWord is identified under change in a docstring. @@ -1801,199 +1793,171 @@ face is verified during the change." (ert-deftest hywiki-tests--wikiword-identified-in-emacs-lisp-mode () "Verify WikiWord is identified when surrounded by delimiters in `emacs-lisp-mode'." (hywiki-tests--preserve-hywiki-mode - (let* ((hsys-org-enable-smart-keys t) - (hywiki-directory (make-temp-file "hywiki" t)) - (wiki-page (cdr (hywiki-add-page "WikiWord")))) - (unwind-protect - (progn - (hywiki-mode :all) - - ;; Matches a WikiWord - (dolist (v '("WikiWord" "[WikiWord]" "[[WikiWord]]" "{WikiWord}" "(WikiWord)" - "" "<>" "{[[WikiWord]]}" "([[WikiWord]])" - "[WikiWord AnotherWord]" - )) - (with-temp-buffer - (emacs-lisp-mode) - (insert (format ";; %s" v)) - (hywiki-tests--command-execute #'newline 1 'interactive) - (goto-char 9) - (should (string= "WikiWord" (hywiki-tests--word-at)))) - - (with-temp-buffer - (emacs-lisp-mode) - (insert (format "(setq var \"%s\")" v)) - (hywiki-tests--command-execute #'newline 1 'interactive) - (goto-char 16) - (should (string= "WikiWord" (hywiki-tests--word-at))))) - - ;; Does not match as a WikiWord - (dolist (v '("WikiWord#")) - (with-temp-buffer - (emacs-lisp-mode) - (insert (format ";; %s" v)) - (hywiki-tests--command-execute #'newline 1 'interactive) - (goto-char 9) - (should-not (hywiki-tests--word-at))) - - (with-temp-buffer - (emacs-lisp-mode) - (insert (format "(setq var \"%s\")" v)) - (hywiki-tests--command-execute #'newline 1 'interactive) - (goto-char 16) - (should-not (hywiki-tests--word-at))))) - (hy-delete-file-and-buffer wiki-page) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (let* ((hsys-org-enable-smart-keys t)) + ;; Matches a WikiWord + (dolist (v '("WikiWord" "[WikiWord]" "[[WikiWord]]" "{WikiWord}" "(WikiWord)" + "" "<>" "{[[WikiWord]]}" "([[WikiWord]])" + "[WikiWord AnotherWord]" + )) + (emacs-lisp-mode) + (insert (format ";; %s" v)) + (hywiki-tests--command-execute #'newline 1 'interactive) + (goto-char 9) + (should (string= "WikiWord" (hywiki-tests--word-at))) + + (erase-buffer) + (insert (format "(setq var \"%s\")" v)) + (hywiki-tests--command-execute #'newline 1 'interactive) + (goto-char 16) + (should (string= "WikiWord" (hywiki-tests--word-at)))) + + ;; Does not match as a WikiWord + (dolist (v '("WikiWord#")) + (erase-buffer) + (insert (format ";; %s" v)) + (hywiki-tests--command-execute #'newline 1 'interactive) + (goto-char 9) + (should-not (hywiki-tests--word-at)) + + (erase-buffer) + (insert (format "(setq var \"%s\")" v)) + (hywiki-tests--command-execute #'newline 1 'interactive) + (goto-char 16) + (should-not (hywiki-tests--word-at)))))) (ert-deftest hywiki-tests--wikiword-identified-in-strings-in-emacs-lisp-mode () "Verify WikiWord is identified when in strings in `emacs-lisp-mode'." (hywiki-tests--preserve-hywiki-mode - (unwind-protect - (let ((words '("Foo" "Bar" "Baz" "Qux"))) - (hywiki-mode :all) - (with-temp-buffer - (emacs-lisp-mode) - (insert - (format "\ + (let ((words '("Foo" "Bar" "Baz" "Qux"))) + (emacs-lisp-mode) + (insert + (format "\ (defun a () \"%s.\" nil) " (mapconcat 'identity words " "))) - (goto-char (point-min)) - (forward-line 1) - (dolist (v words) - (should (search-forward v)) - (should (string= v (hywiki-word-at))))))))) + (goto-char (point-min)) + (forward-line 1) + (dolist (v words) + (should (search-forward v)) + (should (string= v (hywiki-word-at))))))) (ert-deftest hywiki-tests--filename-same-as-wiki-word () "Regular files should not be WikiWords even when hywiki-mode is active." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wiki-page (cdr (hywiki-add-page "DEMO"))) - (default-directory hyperb:dir)) - (unwind-protect - (with-temp-buffer - (insert "\"DEMO\" \"DEMO.org\"\n") - (goto-char 2) - (should (looking-at-p "DEMO\" ")) - (hywiki-mode nil) - (should (ibtype:test-p 'pathname)) - (hywiki-mode :all) - (should (ibtype:test-p 'pathname)) - (goto-char 9) - ;; Verify that using the org extension selects the WikiWord. - (should (looking-at-p "DEMO\\.org\"")) - (should (ibtype:test-p 'hywiki-existing-word))) - (hy-delete-file-and-buffer wiki-page) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (let ((default-directory hyperb:dir)) + (insert "\"WikiWord\" \"WikiWord.org\"\n") + (goto-char 2) + (should (looking-at-p "WikiWord\" ")) + (hywiki-mode nil) + (should (ibtype:test-p 'pathname)) + (hywiki-mode :all) + (should (ibtype:test-p 'pathname)) + (goto-char 9) + ;; Verify that using the org extension selects the WikiWord. + (should (looking-at-p "WikiWord\\.org\"")) + (should (ibtype:test-p 'hywiki-existing-word))))) (ert-deftest hywiki-tests--nonexistent-wikiword-with-section-should-create-wikiword () "Verify action-key on a new WikiWord#section creates proper page filename." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (hywiki-page (expand-file-name "WikiWord.org" hywiki-directory)) - (hywiki-page-with-section (expand-file-name "WikiWord.org#section" hywiki-directory))) + (let* ((wikiword "WikiWd") + (section "#section") + (wikifile (expand-file-name + (concat wikiword hywiki-file-suffix) + hywiki-directory))) (unwind-protect - (with-temp-buffer - (hywiki-mode :all) - (insert "WikiWord#section") - (goto-char 4) - (action-key) - (should-not (file-exists-p hywiki-page-with-section)) - (should (file-exists-p hywiki-page))) - (hy-delete-files-and-buffers (list hywiki-page hywiki-page-with-section)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (progn + (insert (concat wikiword section)) + (goto-char 4) + (action-key) + (sit-for 0.01) + (should-not (file-exists-p (expand-file-name + (concat wikiword hywiki-file-suffix section) + hywiki-directory))) + (should (file-exists-p wikifile))) + (hy-delete-file-and-buffer wikifile))))) (ert-deftest hywiki-tests--verify-removal-of-delimiter-updates-face () "Verify WikiWord highlight face change when adding/removing a delimiter." :expected-result :failed (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikiHi (cdr (hywiki-add-page "Hi"))) - (hywiki-tests--with-face-test t)) - (unwind-protect - (progn - (hywiki-mode :all) - (dolist (testcase - '((("\"Hi#a b c\"") (p3 . "Hi#a b c") (p11) (-1) (p3 . "Hi#a") (p10) ("\"") (p3 . "Hi#a b c")) - (("(Hi#s n)" . "Hi#s n") (-1) (p3 . "Hi#s") (p8) (")" . "Hi#s n")))) - (with-temp-buffer - (hywiki-tests--run-test-case testcase)))) - (hy-delete-file-and-buffer wikiHi) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (let ((hywiki-tests--with-face-test t)) + (setq wiki-page (cdr (hywiki-add-page "Hi"))) + (dolist (testcase + '((("\"Hi#a b c\"") (p3 . "Hi#a b c") (p11) (-1) (p3 . "Hi#a") (p10) ("\"") (p3 . "Hi#a b c")) + (("(Hi#s n)" . "Hi#s n") (-1) (p3 . "Hi#s") (p8) (")" . "Hi#s n")))) + (hywiki-tests--run-test-case testcase))))) (ert-deftest hywiki-tests--wikiword-yanked-with-extra-words () "Verify that a yanked in WikiWord highlights properly." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikiHi (cdr (hywiki-add-page "Hi"))) + (let* ((wikiHi (cdr (hywiki-add-page "Hi"))) (wikiHo (cdr (hywiki-add-page "Ho"))) (hywiki-tests--with-face-test t)) (unwind-protect (progn - (hywiki-mode :all) ;; Left part of WikiWord yanked in. - (with-temp-buffer - (insert "i#s") - (goto-char 1) - (let ((kill-ring (list "H")) - interprogram-paste-function) - (yank)) - (hywiki-tests--verify-hywiki-word "Hi#s")) + (insert "i#s") + (goto-char 1) + (let ((kill-ring (list "H")) + interprogram-paste-function) + (yank)) + (hywiki-tests--verify-hywiki-word "Hi#s") + ;; Right part of WikiWord yanked in. - (with-temp-buffer - (insert "H") - (let ((kill-ring (list "i#s")) - interprogram-paste-function) - (yank)) - (goto-char 2) - (hywiki-tests--verify-hywiki-word "Hi#s")) + (erase-buffer) + (insert "H") + (let ((kill-ring (list "i#s")) + interprogram-paste-function) + (yank)) + (goto-char 2) + (hywiki-tests--verify-hywiki-word "Hi#s") + ;; Non WikiWords in front of WikiWord. - (with-temp-buffer - (let ((kill-ring (list "a b Hi#c")) - interprogram-paste-function) - (yank)) - (goto-char 1) - (hywiki-tests--verify-hywiki-word nil) - (goto-char 6) - (hywiki-tests--verify-hywiki-word "Hi#c")) + (erase-buffer) + (let ((kill-ring (list "a b Hi#c")) + interprogram-paste-function) + (yank)) + (goto-char 1) + (hywiki-tests--verify-hywiki-word nil) + (goto-char 6) + (hywiki-tests--verify-hywiki-word "Hi#c") + ;; Non WikiWords after WikiWord. - (with-temp-buffer - (let ((kill-ring (list "Hi#a b c")) - interprogram-paste-function) - (yank)) - (goto-char 2) - (hywiki-tests--verify-hywiki-word "Hi#a")) + (erase-buffer) + (let ((kill-ring (list "Hi#a b c")) + interprogram-paste-function) + (yank)) + (goto-char 2) + (hywiki-tests--verify-hywiki-word "Hi#a") + ;; Multiple WikiWords with non WikiWords. - (with-temp-buffer - (let ((kill-ring (list "a Hi#b c Ho#d e")) - interprogram-paste-function) - (yank)) - (goto-char 4) - (hywiki-tests--verify-hywiki-word "Hi#b") - (goto-char 11) - (hywiki-tests--verify-hywiki-word "Ho#d"))) - (hy-delete-files-and-buffers (list wikiHi wikiHo)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (erase-buffer) + (let ((kill-ring (list "a Hi#b c Ho#d e")) + interprogram-paste-function) + (yank)) + (goto-char 4) + (hywiki-tests--verify-hywiki-word "Hi#b") + (goto-char 11) + (hywiki-tests--verify-hywiki-word "Ho#d")) + (hy-delete-files-and-buffers (list wikiHi wikiHo)))))) (ert-deftest hywiki-tests--create-wikiword-file-highlights-wikiword () "Verify creating a WikiWord-file highlights the WikiWord in another file." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikiHi (cdr (hywiki-add-page "Hi"))) + (let* ((wikiHi (cdr (hywiki-add-page "Hi"))) (hywiki-tests--with-face-test t) wikiHo) (unwind-protect (progn - (hywiki-mode :all) (with-current-buffer (find-file wikiHi) (insert "Ho") (save-buffer) (setq wikiHo (cdr (hywiki-add-page "Ho"))) (goto-char 2) (hywiki-tests--verify-hywiki-word "Ho"))) - (hy-delete-files-and-buffers (list wikiHi wikiHo)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (hy-delete-files-and-buffers (list wikiHi wikiHo)))))) (ert-deftest hywiki-tests--maybe-highlight-page-names () "Verify `hywiki-maybe-highlight-references'. @@ -2002,37 +1966,33 @@ computed by `hywiki-tests--hywiki-face-regions', are compared to the expected result." :expected-result :failed (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki_" t)) - (wikiword (cdr (hywiki-add-page "WiWo")))) + (let* ((wikiword (cdr (hywiki-add-page "WiWo"))) + input + overlay-regions) (unwind-protect - (progn - (hywiki-mode :all) - (dolist (v `(("WiWo" . ((1 . 5))) - ("WiWo text" . ((1 . 5))) - ("WiWo WiWo" . ((1 . 5) (6 . 10))) - ("WiWo text WiWo" . ((1 . 5) (11 . 15))) - ("\"WiWo\"" . ((2 . 6))) - ("\"WiWo text\"" . ((2 . 6))) - ;; Failing tests below. - ("\"WiWo WiWo\"" . ((2 . 6) (7 . 11))) - ("\"WiWo text WiWo\"" . ((2 . 6) (12 . 16))) - ("\"WiWo WiWo WiWo\"" . ((2 . 6) (7 . 11) (12 . 16))))) - (let ((input (car v)) - (overlay-regions (cdr v))) - (with-temp-buffer - (insert input) - (hywiki-maybe-highlight-references (point-min) (point-max)) - ;; Verify Overlays - (ert-info ((format "Text '%s' => Expected overlays '%s'" input overlay-regions)) - (should (equal (hywiki-tests--hywiki-face-regions) overlay-regions))))))) + (dolist (v `(("WiWo" . ((1 . 5))) + ("WiWo text" . ((1 . 5))) + ("WiWo WiWo" . ((1 . 5) (6 . 10))) + ("WiWo text WiWo" . ((1 . 5) (11 . 15))) + ("\"WiWo\"" . ((2 . 6))) + ("\"WiWo text\"" . ((2 . 6))) + ;; Failing tests below. + ("\"WiWo WiWo\"" . ((2 . 6) (7 . 11))) + ("\"WiWo text WiWo\"" . ((2 . 6) (12 . 16))) + ("\"WiWo WiWo WiWo\"" . ((2 . 6) (7 . 11) (12 . 16))))) + (setq input (car v) + overlay-regions (cdr v)) + (insert input) + (hywiki-maybe-highlight-references (point-min) (point-max)) + ;; Verify Overlays + (ert-info ((format "Text '%s' => Expected overlays '%s'" input overlay-regions)) + (should (equal (hywiki-tests--hywiki-face-regions) overlay-regions)))) ;; Unwind - (hy-delete-file-and-buffer wikiword) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (hy-delete-file-and-buffer wikiword))))) (ert-deftest hywiki-tests--consult-grep () "Verify `hywiki-consult-grep' calls `hsys-consult-grep'." - (let ((hywiki-directory (make-temp-file "hywiki" t)) - (hsys-consult-flag nil)) + (let ((hsys-consult-flag nil)) (unwind-protect (progn ;; No path list @@ -2082,56 +2042,50 @@ expected result." (hywiki-add-path-link "HoRef" wikiHo 3) (should (string= (concat (file-name-nondirectory wikiHo) ":L1:C2") (cdr (hywiki-get-referent "HoRef")))))) - (hy-delete-files-and-buffers (list wikiHi wikiHo)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (hy-delete-files-and-buffers (list wikiHi wikiHo)))))) (ert-deftest hywiki-test--hywiki-mode () "Verify activating local and global `hywiki-mode'." (hywiki-tests--preserve-hywiki-mode - (with-temp-buffer - (should (eq nil (hywiki-mode 0))) - (should (eq nil (hywiki-mode -1))) - (should (eq nil (hywiki-mode nil))) - (should (eq :pages (hywiki-mode 2))) - (should (eq :all (hywiki-mode 1))) - (should (eq :all (hywiki-mode t))) - (should (eq :all (hywiki-mode :all))) - - ;; Toggle - (should (eq nil (call-interactively #'hywiki-mode))) - (should (eq :all (call-interactively #'hywiki-mode))) - (should (eq nil (hywiki-mode 'toggle))) - (should (eq :all (hywiki-mode 'toggle)))))) + (should (eq nil (hywiki-mode 0))) + (should (eq nil (hywiki-mode -1))) + (should (eq nil (hywiki-mode nil))) + (should (eq :pages (hywiki-mode 2))) + (should (eq :all (hywiki-mode 1))) + (should (eq :all (hywiki-mode t))) + (should (eq :all (hywiki-mode :all))) + + ;; Toggle + (should (eq nil (call-interactively #'hywiki-mode))) + (should (eq :all (call-interactively #'hywiki-mode))) + (should (eq nil (hywiki-mode 'toggle))) + (should (eq :all (hywiki-mode 'toggle))))) (ert-deftest hywiki-tests--interactive-hywiki-mode-toggles () "Verify `hywiki-mode' called interactively toggles mode." (hywiki-tests--preserve-hywiki-mode - (with-temp-buffer - (hywiki-mode :all) - (should hywiki-mode) - ;; Toggle - (call-interactively #'hywiki-mode) - (should-not hywiki-mode) - (call-interactively #'hywiki-mode) - (should hywiki-mode)))) + (should hywiki-mode) + ;; Toggle + (call-interactively #'hywiki-mode) + (should-not hywiki-mode) + (call-interactively #'hywiki-mode) + (should hywiki-mode))) (ert-deftest hywiki-tests--directory-dired-edit () "Verify Dired is activated." (hywiki-tests--preserve-hywiki-mode - (let* ((hywiki-directory (make-temp-file "hywiki" t)) - (wikiHi (cdr (hywiki-add-page "Hi"))) + (let* ((wikiHi (cdr (hywiki-add-page "Hi"))) (action-key-modeline-buffer-id-function nil)) ; Avoid treemacs. (unwind-protect - (progn + (progn (hywiki-directory-edit) (should (equal 'dired-mode major-mode)) (should (string= default-directory (file-name-as-directory hywiki-directory)))) - (hy-delete-files-and-buffers (list wikiHi)) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))) + (hy-delete-files-and-buffers (list wikiHi)))))) (ert-deftest hywiki-tests--tags-view () "Verify `hywiki-tag-view' calls `org-tags-view' and sets up `org-redo-cmd'." - (with-temp-buffer + (hywiki-tests--preserve-hywiki-mode (insert "1\n2\n3\n4\n5\n") (goto-char 1) (let ((bn (buffer-name))) @@ -2139,16 +2093,16 @@ expected result." (hywiki-tags-view nil "match" bn) (should (equal (get-text-property 1 'org-redo-cmd) (list #'hywiki-tags-view nil nil bn))) - (should (= (line-number-at-pos) 3))))) - ;; todo-only - (with-temp-buffer - (insert "1\n2\n3\n4\n5\n") - (goto-char 1) - (let ((bn (buffer-name))) + (should (= (line-number-at-pos) 3))) + + ;; todo-only + (erase-buffer) + (insert "1\n2\n3\n4\n5\n") + (goto-char 1) (mocklet (((org-tags-view t "match") => t)) (hywiki-tags-view t "match" bn) (should (equal (get-text-property 1 'org-redo-cmd) - (list #'hywiki-tags-view t nil bn))) + (list #'hywiki-tags-view t nil bn))) (should (= (line-number-at-pos) 3)))))) (provide 'hywiki-tests) From 917cb2edbba403520d5a0bda76e92e3921317d18 Mon Sep 17 00:00:00 2001 From: bw Date: Sun, 25 Jan 2026 19:26:29 -0500 Subject: [PATCH 6/6] hywiki-tests--filename-same-as-wiki-word - Rewrite to correct tests Also, apply small fixes from Mats for 2 others tests --- ChangeLog | 3 +++ hywiki.el | 6 ++++-- test/hywiki-tests.el | 44 +++++++++++++++++++++----------------------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 26b24f9d..de25f5c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2026-01-25 Bob Weiner +* test/hywiki-tests.el (hywiki-tests--filename-same-as-wiki-word): Rewrote + to correct the tests therein. + * hywiki.el (hywiki-potential-buffer-p, hywiki-non-hook-context-p): Comment out 'edebug-active' checks, so can examine same behavior when edebugging. (hywiki-word-set-auto-highlighting): Fix to ensure all hywiki diff --git a/hywiki.el b/hywiki.el index 412471f5..88f38045 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: 25-Jan-26 at 12:40:15 by Bob Weiner +;; Last-Mod: 25-Jan-26 at 16:29:26 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -3589,7 +3589,9 @@ occurs with one of these hooks, the problematic hook is removed." ;; mode is disabled (let ((hywiki-mode :all)) (hywiki-word-dehighlight-buffers (hywiki-get-buffers hywiki-mode)))) - ((null hywiki-from-mode) + ((or (null hywiki-from-mode) + (and (eq hywiki-from-mode :pages) (eq hywiki-to-mode :pages)) + (and (eq hywiki-from-mode :all) (eq hywiki-to-mode :all))) (hywiki-word-highlight-buffers (hywiki-get-buffers hywiki-to-mode))) ((and (eq hywiki-from-mode :all) (eq hywiki-to-mode :pages)) (hywiki-word-dehighlight-buffers diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el index f4993bd1..34d90c67 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: 25-Jan-26 at 11:21:07 by Bob Weiner +;; Last-Mod: 25-Jan-26 at 19:23:58 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -139,7 +139,7 @@ Last two elements are optional.") hywiki-tests--edit-string-pairs)) (let ((default-directory hywiki-directory)) (hy-delete-files-and-buffers - '("AI.org" "Hi.org" "HiHo.org" "HyWiki" "HyWikiW" "HyWikiWord.org" "MyWikiWord.org" "Non.org" "Wiki"))))))) + '("AI.org" "Hi.org" "HiHo.org" "HyWiki.org" "HyWikiW.org" "HyWikiWord.org" "MyWikiWord.org" "Non.org" "Wiki.org"))))))) (defun hywiki-tests--get-brace-strings (s) "Return the substrings in S delimited by curly braces {…}, excluding braces. @@ -1845,18 +1845,18 @@ face is verified during the change." (ert-deftest hywiki-tests--filename-same-as-wiki-word () "Regular files should not be WikiWords even when hywiki-mode is active." (hywiki-tests--preserve-hywiki-mode - (let ((default-directory hyperb:dir)) + (let ((default-directory hywiki-directory)) (insert "\"WikiWord\" \"WikiWord.org\"\n") (goto-char 2) (should (looking-at-p "WikiWord\" ")) (hywiki-mode nil) - (should (ibtype:test-p 'pathname)) + (should-not (ibtype:test-p 'hywiki-existing-word)) (hywiki-mode :all) - (should (ibtype:test-p 'pathname)) - (goto-char 9) + (should (ibtype:test-p 'hywiki-existing-word)) + (goto-char 13) ;; Verify that using the org extension selects the WikiWord. (should (looking-at-p "WikiWord\\.org\"")) - (should (ibtype:test-p 'hywiki-existing-word))))) + (should (ibtype:test-p 'pathname))))) (ert-deftest hywiki-tests--nonexistent-wikiword-with-section-should-create-wikiword () "Verify action-key on a new WikiWord#section creates proper page filename." @@ -1992,22 +1992,20 @@ expected result." (ert-deftest hywiki-tests--consult-grep () "Verify `hywiki-consult-grep' calls `hsys-consult-grep'." - (let ((hsys-consult-flag nil)) - (unwind-protect - (progn - ;; No path list - (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 0 (list hywiki-directory) "prompt") => "match")) - (should (string= (hywiki-consult-grep "regexp" 0 nil "prompt") "match"))) - ;; Path list - (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 0 '("path") "prompt") => "match")) - (should (string= (hywiki-consult-grep "regexp" 0 '("path") "prompt") "match"))) - ;; No Prompt, max-matches = 0 - (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 0 '("path") "Grep HyWiki dir headlines") => "match")) - (should (string= (hywiki-consult-grep "regexp" 0 '("path")) "match"))) - ;; No Prompt, max-matches != 0 - (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 1 '("path") "Grep HyWiki dir") => "match")) - (should (string= (hywiki-consult-grep "regexp" 1 '("path")) "match")))) - (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))) + (hywiki-tests--preserve-hywiki-mode + (let ((hsys-consult-flag nil)) + ;; No path list + (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 0 (list hywiki-directory) "prompt") => "match")) + (should (string= (hywiki-consult-grep "regexp" 0 nil "prompt") "match"))) + ;; Path list + (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 0 '("path") "prompt") => "match")) + (should (string= (hywiki-consult-grep "regexp" 0 '("path") "prompt") "match"))) + ;; No Prompt, max-matches = 0 + (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 0 '("path") "Grep HyWiki dir headlines") => "match")) + (should (string= (hywiki-consult-grep "regexp" 0 '("path")) "match"))) + ;; No Prompt, max-matches != 0 + (mocklet (((hsys-consult-grep "--include *.org" "--glob *.org" "regexp" 1 '("path") "Grep HyWiki dir") => "match")) + (should (string= (hywiki-consult-grep "regexp" 1 '("path")) "match")))))) (ert-deftest hywiki-tests--hywiki-help () "Verify `hywiki-help'."