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

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

[elpa] externals/hyperbole ce89e7379c 2/5: hywiki.el - second release wi


From: ELPA Syncer
Subject: [elpa] externals/hyperbole ce89e7379c 2/5: hywiki.el - second release with much better wiki-word highlighting
Date: Mon, 27 May 2024 03:58:14 -0400 (EDT)

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

    hywiki.el - second release with much better wiki-word highlighting
---
 ChangeLog     |  49 ++++++
 MANIFEST      |   8 +-
 hargs.el      |  44 +++--
 hui-em-but.el |   2 +-
 hyperbole.el  |   2 +-
 hywiki.el     | 506 +++++++++++++++++++++++++++++++++++++++-------------------
 6 files changed, 421 insertions(+), 190 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a848b11463..da56723425 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2024-05-26  Bob Weiner  <rsw@gnu.org>
+
+* hargs.el (hargs:delimited): Change returned value from 'string' to 'result'.
+    If 'as-key' arg eq 'none, return t or nil as result rather than matching 
string.
+           (hargs:delimited-p): Add to all 'hargs:delimited with 'as-key' arg 
set to
+    'none.
+
+* hywiki.el (hywiki-highlight-on-yank): Add and add to 
'yank-handled-properties'.
+            (hywiki-find-page): Don't turn on `hywiki-mode', let the user do 
that.
+    Call `hywiki-highlight-page-names' when finding a regular file too.
+            (hywiki-highlight-page-names): Fix so in-comment test is within the
+    loop searching for each match.
+            (hywiki--but): Rename to 'hywiki--buts' since will store a 
potential
+    list of HyWiki highlight buttons here.
+            (hywiki-highlight-page-names-in-frame): Allow frame arg of 't to 
mean
+    highlight/dehighlight across all frames.
+            (hywiki-dehighlight-page-names): Do this in buffers other than 
HyWiki
+    pages when 'hywiki-mode' is turned off.  Do it to HyWiki page buffers when
+    `hywiki-word-highlight-flag' is set to nil.
+            (require 'hargs): Add.
+            (hywiki-highlight-page-name): Allow for <> syntax as delim syntax.
+            (hywiki-maybe-at-wikiword-beginning): Allow for '<' as preceding 
char.
+            (hywiki-buttonize-character-commands): Replace seq-find with 
cl-find.
+            (hywiki-mode): Add all open delimiter characters to
+    'hywiki--buttonize-characters'.
+           (hywiki-highlight-all-in-prog-modes): Add and use to specify major 
modes
+    in which to highlight HyWikiWords outside of comments.
+            (hywiki-highlight-page-name, hywiki-highlight-page-names): Clear
+    highlighting within square or angle brackets since these might be Org 
links or
+    targets.
+            (hywiki-highlight-page-name): Trigger on symbol syntax chars 
except "#_-".
+            (hywiki-find-page): Mention 'hywiki-find-page-hook' in doc.
+            (hywiki-buttonize-character-commands,
+             hywiki-buttonize-non-character-commands): Ignore unless
+    'hywiki-word-highlight-flag' is non-nil (the default).
+            (hywiki--org-mode-syntax-table): Add to avoid loading Org mode for
+    HyWikiWord testing.
+            (hywiki-get-buttonize-characters): Use above new variable.
+            (hywiki-highlight-page-names): Highlight only in region if active
+    or given as arguments.
+            (require 'outline): And remove (require 'ol) which is now loaded
+    after org is loaded and then HyWiki's `org-link-set-parameters' is lazily 
run.
+            (hywiki-mode): Make global minor mode.
+            (hywiki-at-wikiword): Don't require Org mode to test if
+    at a HyWikiWord.
+            (hywiki-highlight-page-name, hywiki-highlight-page-names): Make
+    an autoload for use in hywiki defib.
+           (hywiki): Move defib to "hibtypes.el".
+
 * hyrolo.el (window-buffer-change-functions): Use 'add-to-list' instead of 
'push'
     to prevent duplicates.
             (hyrolo-normalize-mode-function): Apply to all windows in the given
diff --git a/MANIFEST b/MANIFEST
index f40aa462e9..f2ded012f9 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -73,15 +73,15 @@ hsmail.el            - GNU Hyperbole buttons in mail 
composer: mail
 kotl/MANIFEST        - Summary of Koutliner files
 kotl/EXAMPLE.kotl    - Sample Koutline document explaining Koutliner features
 
-* --- HYPERBOLE NOTES ---
-hywiki.el            - Hyperbole's auto-wikiword note-taking system
-hasht.el             - Create hash tables from lists and operate on them.
-
 * --- HYPERBOLE ROLO ---
 hyrolo.el            - Hierarchical, multi-file, easy-to-use record management 
system
 hyrolo.py            - Output file header and matching entries from HyRolo 
files via the command-line
 hyrolo-logic.el      - Logic functions for GNU Hyperbole Rolo files
 
+* --- HYPERBOLE WIKI ---
+hywiki.el            - Hyperbole's auto-wikiword note-taking system
+hasht.el             - Create hash tables from lists and operate on them.
+
 * --- USENET NEWS SUPPORT ---
 hgnus.el             - GNU Hyperbole buttons in news reader/poster: GNUS
 
diff --git a/hargs.el b/hargs.el
index 319c4e5c7d..39b240f73c 100644
--- a/hargs.el
+++ b/hargs.el
@@ -227,23 +227,35 @@ button key (no spaces)."
               t)
             (< start end)
             (>= end opoint)
-            (let ((string (hargs:buffer-substring start end))
-                  (string-with-delims (when (stringp exclude-regexp)
-                                        (hargs:buffer-substring 
start-with-delim
-                                                                
end-with-delim))))
-              (unless (and string-with-delims
-                           (string-match exclude-regexp string-with-delims))
-                ;; Normalize the string
-                (setq string
-                      (if as-key
-                          (hbut:label-to-key string)
-                        (replace-regexp-in-string "[\n\r\f]\\s-*"
-                                                  " " string nil t)))
-                (unless hyperb:microsoft-os-p
-                  (setq string (hpath:mswindows-to-posix string)))
+            (if (eq as-key 'none)
                 (if list-positions-flag
-                    (list string start end)
-                  string))))))))
+                    (list t start end)
+                  t)
+              (let ((result (hargs:buffer-substring start end))
+                    (string-with-delims (when (stringp exclude-regexp)
+                                          (hargs:buffer-substring 
start-with-delim
+                                                                  
end-with-delim))))
+                (unless (and string-with-delims
+                             (string-match exclude-regexp string-with-delims))
+                  ;; Normalize the result
+                  (setq result
+                        (if as-key
+                            (hbut:label-to-key result)
+                          (replace-regexp-in-string "[\n\r\f]\\s-*"
+                                                    " " result nil t)))
+                  (unless hyperb:microsoft-os-p
+                    (setq result (hpath:mswindows-to-posix result)))
+                  (if list-positions-flag
+                      (list result start end)
+                    result)))))))))
+
+(defun hargs:delimited-p (start-delim end-delim
+                         &optional start-regexp-flag end-regexp-flag
+                         list-positions-flag exclude-regexp)
+  "Call `hargs:delimited' with its `as-key' arg set to 'none.
+See `hargs:delimited' for full documentation."
+  (hargs:delimited start-delim end-delim start-regexp-flag
+                  end-regexp-flag list-positions-flag exclude-regexp 'none))
 
 (defmacro hargs:make-iform-vector (&rest iform-alist)
   "Return a vector of interactive command code characters.
diff --git a/hui-em-but.el b/hui-em-but.el
index 689da05227..7bce522728 100644
--- a/hui-em-but.el
+++ b/hui-em-but.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Aug-92
-;; Last-Mod:     18-May-24 at 10:42:36 by Bob Weiner
+;; Last-Mod:     26-May-24 at 17:24:25 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
diff --git a/hyperbole.el b/hyperbole.el
index 46cc6aaf24..b8d1683bb8 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -141,7 +141,7 @@ Use nil for no Hyperbole mode indicator."
 
 ;;;###autoload
 (define-minor-mode hyperbole-mode
-  "Toggle Hyperbole global minor mode.
+  "Toggle Hyperbole global minor mode with \\[hyperbole-mode].
 
 Hyperbole is the Everyday Hypertextual Information Manager.
 
diff --git a/hywiki.el b/hywiki.el
index a9bfe1f8db..e0a29f22d8 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-May-24 at 16:54:09 by Bob Weiner
+;; Last-Mod:     26-May-24 at 20:51:09 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -64,10 +64,13 @@
 ;;; Other required Elisp libraries
 ;;; ************************************************************************
 
+(require 'cl-lib)     ;; For `cl-find'
+(require 'hargs)
+(require 'hbut)       ;; For `hbut:syntax-table'
 (require 'hasht)
 (require 'hpath)
 (require 'hui-em-but)
-(require 'ol)
+(require 'outline)    ;; For `outline-mode-syntax-table'
 
 (eval-and-compile
   '(when (require 'company nil t)
@@ -89,6 +92,9 @@
 (defvar hywiki-directory '"~/hywiki/"
   "Directory in which to find HyWiki page files.")
 
+(defvar hywiki-highlight-all-in-prog-modes '(lisp-interaction-mode)
+  "List of programming major modes to highlight HyWikiWords outside of 
comments.")
+
 (defvar hywiki-non-character-commands
   '(;; Org mode
     org-cycle                         ;; TAB
@@ -108,7 +114,8 @@
 
 ;; Define the keymap for hywiki-mode.
 (defvar hywiki-mode-map nil
-  "Keymap for `hywiki-mode'.")
+  "Keymap for `hywiki-mode'.
+Presently, there are no key bindings; this is for future use.")
 
 (defconst hywiki-org-link-type "hy"
   "HyWiki string prefix type for Org links.  Excludes trailing colon.")
@@ -164,6 +171,18 @@ the HyWiki word and grouping 2 is the #section with the # 
included.")
   "String of single character keys bound to 
`hywiki-buttonize-character-commands'.
 Each such key self-inserts before highlighting any prior HyWiki word.")
 
+;; Redefine the `org-mode-syntax-table' for use in 
`hywiki-get-buttonize-characters'
+;; so do not have to load all of Org mode there.
+(defvar hywiki--org-mode-syntax-table
+  (let ((st (make-syntax-table outline-mode-syntax-table)))
+    (modify-syntax-entry ?\" "\"" st)
+    (modify-syntax-entry ?\\ "_" st)
+    (modify-syntax-entry ?~ "_" st)
+    (modify-syntax-entry ?< "(>" st)
+    (modify-syntax-entry ?> ")<" st)
+    st)
+  "Standard syntax table for Org mode buffers with HyWiki support.")
+
 (defvar hywiki--pages-hasht nil)
 
 ;;; ************************************************************************
@@ -173,14 +192,16 @@ Each such key self-inserts before highlighting any prior 
HyWiki word.")
 (defun hywiki-buttonize-character-commands ()
   "Turn any HyWikiWord before point into a highlighted Hyperbole button.
 Triggered by `post-self-insert-hook' for self-inserting characters."
-  (when (and (characterp last-command-event)
-            (seq-find (lambda (c) (= c last-command-event)) 
hywiki--buttonize-characters))
+  (when (and hywiki-word-highlight-flag
+            (characterp last-command-event)
+            (cl-find last-command-event hywiki--buttonize-characters))
     (hywiki-highlight-page-name)))
 
 (defun hywiki-buttonize-non-character-commands ()
   "Turn any HyWikiWord before point into a highlighted Hyperbole button.
 Triggered by `pre-command-hook' for non-character-commands, e.g. return."
-  (when (memq this-command hywiki-non-character-commands)
+  (when (and hywiki-word-highlight-flag
+            (memq this-command hywiki-non-character-commands))
     (hywiki-highlight-page-name)))
 
 (defun hywiki-get-buttonize-characters ()
@@ -207,13 +228,13 @@ Triggered by `pre-command-hook' for 
non-character-commands, e.g. return."
                    (characterp (cdr key))
                    (<= (cdr key) 256))
               ;; ASCII char range, some of which has punctuation/symbol syntax
-              (with-syntax-table org-mode-syntax-table
+              (with-syntax-table hywiki--org-mode-syntax-table
                 (dolist (k (number-sequence (car key) (cdr key)))
                   (when (memq (char-syntax k) '(?. ?_))
                     (setq result (cons k result)))))))))))
 
 (define-minor-mode hywiki-mode
-  "Toggle HyWiki minor mode with \\[hywiki-mode].
+  "Toggle HyWiki global minor mode with \\[hywiki-mode].
 
 The hywiki-mode minor mode auto-highlights and creates implicit
 buttons from wiki words.  Any such button jumps to the associated
@@ -225,21 +246,24 @@ non-nil.
 See the Info documentation at \"(hyperbole)HyWiki\".
 
 \\{hywiki-mode-map}"
-
+  :global t
   :lighter " HyWiki"
   :keymap hywiki-mode-map
+  :group 'hyperbole-buttons
   (if hywiki-mode
       (progn (unless hywiki-mode-map
                (setq hywiki-mode-map (make-sparse-keymap)))
             ;; Self-insert punct/sym keys that trigger wiki-word
-            ;; highlighting via `hywiki-buttonize-character-commands' in 
`hywiki-mode'.
+            ;; highlighting via `hywiki-buttonize-character-commands'
+            ;; in `hywiki-mode'.
             (unless hywiki--buttonize-characters
               (setq hywiki--buttonize-characters
-                    (concat " \t\r\n\)\]\>\}'" 
(hywiki-get-buttonize-characters))))
+                    (concat " \t\r\n()<>[]{}'" 
(hywiki-get-buttonize-characters))))
             (add-hook 'post-self-insert-hook 
'hywiki-buttonize-character-commands)
             (add-hook 'pre-command-hook 
'hywiki-buttonize-non-character-commands 95))
     (remove-hook 'post-self-insert-hook 'hywiki-buttonize-character-commands)
-    (remove-hook 'pre-command-hook 'hywiki-buttonize-character-commands)))
+    (remove-hook 'pre-command-hook 'hywiki-buttonize-character-commands))
+  (hywiki-highlight-page-names-in-frame (selected-frame)))
 
 ;;; ************************************************************************
 ;;; Public Implicit Button and Action Types
@@ -247,50 +271,57 @@ See the Info documentation at \"(hyperbole)HyWiki\".
 
 (defib hywiki ()
   "When on a HyWiki word, display its page and optional section."
-  (let* ((page-name (hywiki-at-wikiword)))
-    (when page-name
-      (ibut:label-set page-name (match-beginning 0) (match-end 0))
-      (hywiki-highlight-page-name t)
-      (hact 'hywiki-find-page page-name))))
+  (when hywiki-mode
+    (let ((page-name (hywiki-at-wikiword)))
+      (when page-name
+       (ibut:label-set page-name (match-beginning 0) (match-end 0))
+       (hywiki-highlight-page-name t)
+       (hact 'hywiki-find-page page-name)))))
 
 (defun hywiki-find-page (&optional page-name prompt-flag)
-  "Display HyWiki PAGE-NAME.  By default, create any non-existent page.
-With optional PROMPT-FLAG t, prompt to create if non-existent.  If
-PROMPT-FLAG is 'exists, return nil unless the page already exists."
+  "Display HyWiki PAGE-NAME or a regular file with PAGE-NAME nil.
+Return the absolute path to any page successfully found; nil if failed
+or if displaying a regular file.
+
+By default, create any non-existent page.  With optional
+PROMPT-FLAG t, prompt to create if non-existent.  If PROMPT-FLAG
+is 'exists, return nil unless the page already exists.  After
+successfully finding a page and reading it into a buffer, run
+`hywiki-find-page-hook'."
   (interactive (list (completing-read "Find HyWiki page: " 
(hywiki-get-page-list))))
-
   (let ((in-page-flag (null page-name))
        (in-hywiki-directory-flag (string-prefix-p (expand-file-name 
hywiki-directory)
                                                   (or buffer-file-name ""))))
     ;; If called from `find-file-hook' without a page-name and outside
     ;; hywiki-directory, do nothing (just finding a regular file).
-    (when (or (stringp page-name) in-hywiki-directory-flag)
-      (when in-page-flag
-       ;; Current buffer must be the desired page (called from 
'find-file-hook')
-       (unless in-hywiki-directory-flag
-         (error "(hywiki-find-page): No `page-name'; buffer file must be in 
`hywiki-directory', not %s"
-                default-directory))
-       (when (null buffer-file-name)
-         (error "(hywiki-find-page): No `page-name' given in a buffer without 
an attached file"))
-       (setq page-name (file-name-sans-extension (file-name-nondirectory 
buffer-file-name))))
-
-      (let* ((section (when (string-match "#" page-name)
-                       (substring page-name (match-beginning 0))))
-            (page-name (if (string-match "#" page-name)
-                           (substring page-name 0 (match-beginning 0))
-                         page-name))
-            (page-file (or (hywiki-get-page page-name)
-                           (if prompt-flag
-                               (unless (eq prompt-flag 'exists)
-                                 (when (y-or-n-p (concat "Create new `" 
page-name "' page? "))
-                                   (hywiki-add-page page-name)))
-                             (hywiki-add-page page-name)))))
-       (when page-file
-         (unless in-page-flag (hpath:find (concat page-file section)))
-         (unless hywiki-mode (hywiki-mode 1))
-         (hywiki-highlight-page-names)
-         (run-hooks 'hywiki-find-page-hook)
-         page-file)))))
+    (if (or (stringp page-name) in-hywiki-directory-flag)
+       (progn
+         (when in-page-flag
+           ;; Current buffer must be the desired page (called from 
'find-file-hook')
+           (unless in-hywiki-directory-flag
+             (error "(hywiki-find-page): No `page-name'; buffer file must be 
in `hywiki-directory', not %s"
+                    default-directory))
+           (when (null buffer-file-name)
+             (error "(hywiki-find-page): No `page-name' given in a buffer 
without an attached file"))
+           (setq page-name (file-name-sans-extension (file-name-nondirectory 
buffer-file-name))))
+
+         (let* ((section (when (string-match "#" page-name)
+                           (substring page-name (match-beginning 0))))
+                (page-name (if (string-match "#" page-name)
+                               (substring page-name 0 (match-beginning 0))
+                             page-name))
+                (page-file (or (hywiki-get-page page-name)
+                               (if prompt-flag
+                                   (unless (eq prompt-flag 'exists)
+                                     (when (y-or-n-p (concat "Create new `" 
page-name "' page? "))
+                                       (hywiki-add-page page-name)))
+                                 (hywiki-add-page page-name)))))
+           (when page-file
+             (unless in-page-flag (hpath:find (concat page-file section)))
+             (hywiki-highlight-page-names)
+             (run-hooks 'hywiki-find-page-hook)
+             page-file)))
+      (hywiki-highlight-page-names))))
 
 ;;; ************************************************************************
 ;;; Public functions
@@ -320,9 +351,8 @@ nil, else return the file name of the page."
 Does not test whether or not a page exists for the HyWiki word.
 Use `hywiki-get-page' to determine whether a HyWiki page exists."
   ;; Ignore wikiwords preceded by any non-whitespace character, except
-  ;; any of these: ({"'`'
-  (when (or (bolp)
-           (memq (char-before) '(?\( ?\{ ?\" ?\' ?\` ?\  ?\t ?\n ?\r ?\f)))
+  ;; any of these: ({<"'`'
+  (when (or (bolp) (cl-find (char-before) "\(\{\<\"'`\t\n\r\f "))
     t))
 
 (defun hywiki-at-wikiword ()
@@ -334,8 +364,11 @@ Use `hywiki-get-page' to determine whether a HyWiki page 
exists."
       (if wikiword
          ;; Handle an Org link [[HyWikiWord]] [[hy:HyWikiWord]] or 
[[HyWikiWord#section]].
          (progn
-           (setq wikiword
-                 (org-link-expand-abbrev (org-link-unescape (string-trim 
wikiword))))
+           ;; Don't use next line so don't have to load all of Org
+           ;; mode just to check for HyWikiWords; however, disables
+           ;; support for Org mode aliases.
+           ;; (setq wikiword (org-link-expand-abbrev (org-link-unescape 
(string-trim wikiword))))
+           (setq wikiword (string-trim wikiword))
            ;; Ignore prefixed, typed hy:HyWikiWord since Org mode will display 
those.
            (when (hywiki-is-wikiword wikiword)
              wikiword))
@@ -353,7 +386,7 @@ Use `hywiki-get-page' to determine whether a HyWiki page 
exists."
 ;; Globally set these values to avoid using 'let' with stack allocations
 ;; within `hywiki-highlight-page-name' frequently.
 (defvar hywiki--any-page-regexp nil)
-(defvar hywiki--but nil)
+(defvar hywiki--buts nil)
 (defvar hywiki--but-end nil)
 (defvar hywiki--but-start nil)
 (defvar hywiki--current-page nil)
@@ -363,115 +396,230 @@ Use `hywiki-get-page' to determine whether a HyWiki 
page exists."
 (defvar hywiki--save-org-link-type-required nil)
 (defvar hywiki--start nil)
 
-(defun hywiki-highlight-page-names ()
-  "Highlight all non-Org link HyWiki page names in a HyWiki buffer.
-Use `hywiki-word-face' to highlight.  Does not highlight references to
-the current page unless they have sections attached."
-  (interactive)
-  ;; Avoid doing any lets for efficiency.
-  ;; Highlight HyWiki words in buffers where `hywiki-mode' is enabled
-  ;; or with attached files below `hywiki-directory'.
-  (when (and hywiki-word-highlight-flag
-            (or hywiki-mode
-                (string-prefix-p (expand-file-name hywiki-directory)
-                                 (or buffer-file-name ""))))
-    (save-excursion
-      (save-restriction
-       (setq hywiki--any-page-regexp (regexp-opt (hywiki-get-page-list) 'words)
-             hywiki--save-case-fold-search case-fold-search
-             case-fold-search nil
-             hywiki--save-org-link-type-required hywiki-org-link-type-required
-             hywiki-org-link-type-required t
-             hywiki--current-page (hywiki-get-buffer-page-name))
-       (widen)
-       (goto-char (point-min))
-       (while (re-search-forward hywiki--any-page-regexp nil t)
-         (setq hywiki--start (match-beginning 0)
-               hywiki--end   (match-end 0))
-         (save-excursion
-           (goto-char hywiki--start)
-           (when (hywiki-maybe-at-wikiword-beginning)
-             ;; Include any #section.
-             (skip-syntax-forward "^-\)$\>._\"\'")
-             (skip-chars-forward "-#[:alnum:]")
-             (setq hywiki--end (point))
-             ;; Don't highlight current-page matches unless they
-             ;; include a #section.
-             (unless (string-equal hywiki--current-page
-                                   (buffer-substring-no-properties 
hywiki--start hywiki--end))
-               (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face)))))))
-    (setq case-fold-search hywiki--save-case-fold-search
-         hywiki-org-link-type-required hywiki--save-org-link-type-required)))
-
+;;;###autoload
+(defun hywiki-dehighlight-page-names (&optional region-start region-end)
+  "Deighlight 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))))
+  (when (or (not hywiki-word-highlight-flag)
+           (and (not hywiki-mode)
+                (not (string-prefix-p (expand-file-name hywiki-directory)
+                                      (or buffer-file-name "")))))
+    (hproperty:but-clear-all-in-list
+     (hproperty:but-get-all-in-region (or region-start (point-min))
+                                     (or region-end (point-max))
+                                     'face hywiki-word-face))))
+
+(defun hywiki-highlight-on-yank (_prop-value start end)
+  "Used in `yank-handled-properties' called with START and END pos of the 
text."
+  (hywiki-highlight-page-names start end))
+
+;;;###autoload
 (defun hywiki-highlight-page-name (&optional on-page-name)
   "Highlight any non-Org link HyWiki page name one character before point.
 With optional ON-PAGE-NAME non-nil, assume point is within the page or
 section name.
 
+If in a programming mode, must be within a comment.
 Use `hywiki-word-face' to highlight.  Does not highlight references to
 the current page unless they have sections attached."
   (interactive)
   (when (and hywiki-word-highlight-flag
+            (if (and (derived-mode-p 'prog-mode)
+                     (not (apply #'derived-mode-p 
hywiki-highlight-all-in-prog-modes)))
+                ;; Non-nil if match is inside a comment
+                (nth 4 (syntax-ppss))
+              t)
             (or on-page-name
                 (and (eq (char-before) last-command-event) ; Sanity check
-                     (not (eq ?# last-command-event))
-                     (memq (char-syntax last-command-event) '(?\  ?\) ?\$ ?\> 
?. ?\" ?\'))))
+                     (not (memq last-command-event '(?# ?- ?_)))
+                     (cl-find (char-syntax last-command-event)
+                              " _()<>$.\"'")))
              (not executing-kbd-macro)
              (not noninteractive))
-    (save-excursion
-      ;; (when (= (char-syntax (char-before)) ?\))
-       ;; Clear any HyWikiWord highlighting that may just be a part
-       ;; of a larger balanced delimiter text with multiple words.
-       ;; If there is just a single HyWikiWord, it will be
-       ;; re-highlighted later in this function.
-       ;; (ignore-errors
-       ;;   (let* ((sexp-end (point))
-       ;;       (sexp-start (scan-sexps sexp-end -1)))
-       ;;     (when sexp-start
-       ;;       (hproperty:but-clear-all-in-list
-       ;;        (hproperty:but-get-all-in-region sexp-start sexp-end 'face 
hywiki-word-face))))))
-
-      (unless on-page-name
-       ;; after page name
-       (skip-syntax-backward "-"))
-      ;; May be a closing delimiter that we have to skip past
-      (skip-chars-backward (regexp-quote hywiki--buttonize-characters))
-      ;; Skip pass HyWikiWord or section
-      (skip-syntax-backward "^-$()._\"\'")
-      (skip-chars-backward "#[:alpha:]")
-
-      (setq hywiki--save-case-fold-search case-fold-search
-           case-fold-search nil
-           hywiki--save-org-link-type-required hywiki-org-link-type-required
-           hywiki-org-link-type-required t)
-      (if (and (hywiki-maybe-at-wikiword-beginning)
-              (looking-at hywiki-word-optional-section-regexp)
-              (progn
-                (setq hywiki--page-name (match-string-no-properties 1)
-                      hywiki--start (match-beginning 0)
-                      hywiki--end   (match-end 0))
-                (and (hywiki-get-page hywiki--page-name)
-                     ;; Ignore wikiwords preceded by any non-whitespace 
character
-                     ;; (or (bolp) (memq (preceding-char) '(?\  ?\t)))
-                     )))
-         (progn
-           (setq hywiki--current-page (hywiki-get-buffer-page-name))
-           ;; Don't highlight current-page matches unless
-           ;; they include a #section.
-           (unless (string-equal hywiki--current-page
-                                 (buffer-substring-no-properties hywiki--start 
hywiki--end))
-             (if (setq hywiki--but (hproperty:but-get (point) 'face 
hywiki-word-face))
-                 (progn
-                   (setq hywiki--but-start (hproperty:but-start hywiki--but)
-                         hywiki--but-end   (hproperty:but-end hywiki--but))
-                   (unless (and (= hywiki--start hywiki--but-start) (= 
hywiki--end hywiki--but-end))
-                     (hproperty:but-delete hywiki--but)
-                     (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face)))
-               (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face))))
-       ;; Remove any potential earlier highlighting since the
-       ;; previous word may have changed.
-       (skip-syntax-backward "^-$()._\"\'")
-       (hproperty:but-clear (point) 'face hywiki-word-face)))))
+    (with-syntax-table hbut:syntax-table
+      (save-excursion
+       (unless on-page-name
+         ;; after page name
+         (skip-syntax-backward "-"))
+
+       (save-excursion
+         (save-restriction
+           ;; Limit sexp checks to a single line for speed since links and
+           ;; targets should be on a single line.
+           (narrow-to-region (line-beginning-position) (line-end-position))
+           (cond ((memq (char-before) '(?\[ ?\<))
+                  ;; Clear any HyWikiWord highlighting within square or
+                  ;; angle brackets, as this may be a link or target.
+                  (ignore-errors
+                    (goto-char (1- (point)))
+                    (let* ((sexp-start (point))
+                           (sexp-end (scan-sexps sexp-start 1)))
+                      (when sexp-end
+                        (hproperty:but-clear-all-in-list
+                         (hproperty:but-get-all-in-region sexp-start sexp-end 
'face hywiki-word-face))))))
+                 ((memq (char-before) '(?\( ?\{))
+                  ;; Highlight any HyWikiWords within parens or braces.
+                  (ignore-errors
+                    (goto-char (1- (point)))
+                    (let* ((sexp-start (point))
+                           (sexp-end (scan-sexps sexp-start 1)))
+                      (when sexp-end
+                        (hywiki-highlight-page-names sexp-start sexp-end)))))
+                 ((memq (char-before) '(?\] ?\>))
+                  ;; Clear any HyWikiWord highlighting within square or
+                  ;; angle brackets, as this may be a link or target.
+                  (ignore-errors
+                    (let* ((sexp-end (point))
+                           (sexp-start (scan-sexps sexp-end -1)))
+                      (when sexp-start
+                        (hproperty:but-clear-all-in-list
+                         (hproperty:but-get-all-in-region sexp-start sexp-end 
'face hywiki-word-face))))))
+                 ((memq (char-before) '(?\) ?\}))
+                  ;; Highlight any HyWikiWords within parens or braces.
+                  (ignore-errors
+                    (let* ((sexp-end (point))
+                           (sexp-start (scan-sexps sexp-end -1)))
+                      (when sexp-start
+                        (hywiki-highlight-page-names sexp-start 
sexp-end))))))))
+
+       ;; May be a closing delimiter that we have to skip past
+       (skip-chars-backward (regexp-quote hywiki--buttonize-characters))
+       ;; Skip pass HyWikiWord or section
+       (skip-syntax-backward "^-$()<>._\"\'")
+       (skip-chars-backward "#[:alpha:]")
+
+       (setq hywiki--save-case-fold-search case-fold-search
+             case-fold-search nil
+             hywiki--save-org-link-type-required hywiki-org-link-type-required
+             hywiki-org-link-type-required t)
+       (if (and (hywiki-maybe-at-wikiword-beginning)
+                (looking-at hywiki-word-optional-section-regexp)
+                (progn
+                  (setq hywiki--page-name (match-string-no-properties 1)
+                        hywiki--start (match-beginning 0)
+                        hywiki--end   (match-end 0))
+                  (and (hywiki-get-page hywiki--page-name)
+                       ;; Ignore wikiwords preceded by any non-whitespace 
character
+                       ;; (or (bolp) (memq (preceding-char) '(?\  ?\t)))
+                       )))
+           (progn
+             (setq hywiki--current-page (hywiki-get-buffer-page-name))
+             ;; Don't highlight current-page matches unless they
+             ;; include a #section.
+             (unless (string-equal hywiki--current-page
+                                   (buffer-substring-no-properties 
hywiki--start hywiki--end))
+               (if (setq hywiki--buts (hproperty:but-get-all-in-region
+                                       hywiki--start hywiki--end
+                                       'face hywiki-word-face))
+                   (if (> (length hywiki--buts) 1)
+                       (progn (hproperty:but-clear-all-in-list hywiki--buts)
+                              (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face))
+                     ;; There is only one existing button
+                     (setq hywiki--buts (car hywiki--buts)
+                           hywiki--but-start (hproperty:but-start hywiki--buts)
+                           hywiki--but-end   (hproperty:but-end hywiki--buts))
+                     (unless (and (= hywiki--start hywiki--but-start)
+                                  (= hywiki--end hywiki--but-end))
+                       (hproperty:but-delete hywiki--buts)
+                       (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face)))
+                 (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face))))
+         ;; Remove any potential earlier highlighting since the
+         ;; previous word may have changed.
+         (skip-syntax-backward "^-$()<>._\"\'")
+         (hproperty:but-clear (point) 'face hywiki-word-face))))))
+
+;;;###autoload
+(defun hywiki-highlight-page-names (&optional region-start region-end)
+  "Highlight all non-Org link HyWiki page names in a HyWiki buffer/region.
+With optional REGION-START and REGION-END positions (active region
+interactively), limit highlighting to the region.
+
+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 when 
`hywiki-word-highlight-flag'
+is changed."
+  (interactive (when (use-region-p) (list (region-beginning) (region-end))))
+  ;; Avoid doing any lets for efficiency.
+  ;; Highlight HyWiki words in buffers where `hywiki-mode' is enabled
+  ;; or with attached files below `hywiki-directory'.
+  (if (or (not hywiki-word-highlight-flag)
+         (and (not hywiki-mode)
+              (not (string-prefix-p (expand-file-name hywiki-directory)
+                                    (or buffer-file-name "")))))
+      ;; Dehighlight buffers other than HyWiki pages when
+      ;; 'hywiki-mode' is disabled. Dehighlight HyWiki page
+      ;; buffers when `hywiki-word-highlight-flag' is disabled.
+      (hywiki-dehighlight-page-names region-start region-end)
+    (when (or hywiki-mode
+             (string-prefix-p (expand-file-name hywiki-directory)
+                              (or buffer-file-name "")))
+      (unwind-protect
+         (save-excursion
+           (save-restriction
+             (setq hywiki--any-page-regexp (regexp-opt (hywiki-get-page-list) 
'words)
+                   hywiki--save-case-fold-search case-fold-search
+                   case-fold-search nil
+                   hywiki--save-org-link-type-required 
hywiki-org-link-type-required
+                   hywiki-org-link-type-required t
+                   hywiki--current-page (hywiki-get-buffer-page-name))
+             (if (and region-start region-end)
+                 (narrow-to-region region-start region-end)
+               (widen))
+             (goto-char (point-min))
+             (let ((highlight-in-comments-only
+                    (and (derived-mode-p 'prog-mode)
+                         (not (apply #'derived-mode-p 
hywiki-highlight-all-in-prog-modes)))))
+               (while (re-search-forward hywiki--any-page-regexp nil t)
+                 (when (if highlight-in-comments-only
+                           ;; Non-nil if match is inside a comment
+                           (nth 4 (syntax-ppss))
+                         t)
+                   (setq hywiki--start (match-beginning 0)
+                         hywiki--end   (match-end 0))
+                   (save-excursion
+                     (goto-char hywiki--start)
+                     (if (or (hargs:delimited-p "\\[" "\\]" t t t)
+                             (hargs:delimited-p "<" ">" t t t))
+                         ;; Clear any HyWikiWord highlighting that may
+                         ;; just be a part of a larger square brackets or
+                         ;; angle brackets delimited text with multiple words.
+                         (hproperty:but-clear-all-in-list
+                          (hproperty:but-get-all-in-region hywiki--start 
hywiki--end
+                                                           'face 
hywiki-word-face))
+                       ;; Otherwise, highlight any HyWikiWord found, including
+                       ;; any #section.
+                       (when (hywiki-maybe-at-wikiword-beginning)
+                         (with-syntax-table hbut:syntax-table
+                           (skip-syntax-forward "^-\)$\>._\"\'"))
+                         (skip-chars-forward "-#[:alnum:]")
+                         (setq hywiki--end (point))
+                         ;; Don't highlight current-page matches unless they
+                         ;; include a #section.
+                         (unless (string-equal hywiki--current-page
+                                               (buffer-substring-no-properties 
hywiki--start hywiki--end))
+                           (hproperty:but-add hywiki--start hywiki--end 
hywiki-word-face))))))))))
+       (setq case-fold-search hywiki--save-case-fold-search
+             hywiki-org-link-type-required 
hywiki--save-org-link-type-required)))))
+
+(defun hywiki-highlight-page-names-in-frame (frame)
+  "Highlight all non-Org link HyWiki page names displayed in FRAME.
+If FRAME is t, then highlight in all windows across all frames, even
+invisible ones.
+
+Use `hywiki-word-face' to highlight.  Does not highlight references to
+the current page unless they have sections attached."
+  (walk-windows
+   (lambda (window)
+     (with-selected-window window
+       ;; Display buffer before `normal-mode' triggers possibly
+       ;; long-running font-locking
+       (sit-for 0.1)
+       (hywiki-highlight-page-names)))
+   nil frame))
 
 (defun hywiki-is-wikiword (word)
   "Return non-nil if WORD is a HyWiki word and optional #section.
@@ -577,25 +725,47 @@ Use `hywiki-get-page' to determine whether a HyWiki page 
exists."
    (let ((completion-ignore-case t))
      (completing-read "HyWiki page: " (hywiki-get-page-list) nil t))))
 
-(defun hywiki-org-link-store ()
-  "Store a link to a HyWiki word at point, if any."
-  (when (hywiki-at-wikiword)
-    (let* ((page-name (hywiki-at-wikiword))
-           (link (concat
-                 (when hywiki-org-link-type-required
-                   (concat hywiki-org-link-type ":"))
-                 page-name))
-           (description (format "HyWiki page for '%s'" page-name)))
-      (org-link-store-props
-       :type hywiki-org-link-type
-       :link link
-       :description description))))
-
-(org-link-set-parameters hywiki-org-link-type
-                         :complete #'hywiki-org-link-complete
-                        :follow #'hywiki-find-page
-                        :store #'hywiki-org-link-store)
+(eval-after-load 'org
+  '(progn
+     (defun hywiki-org-link-store ()
+       "Store a link to a HyWiki word at point, if any."
+       (when (hywiki-at-wikiword)
+        (let* ((page-name (hywiki-at-wikiword))
+               (link (concat
+                      (when hywiki-org-link-type-required
+                        (concat hywiki-org-link-type ":"))
+                      page-name))
+               (description (format "HyWiki page for '%s'" page-name)))
+          (org-link-store-props
+           :type hywiki-org-link-type
+           :link link
+           :description description))))
+
+     (org-link-set-parameters hywiki-org-link-type
+                              :complete #'hywiki-org-link-complete
+                             :follow #'hywiki-find-page
+                             :store #'hywiki-org-link-store)))
 
 (add-hook 'find-file-hook #'hywiki-find-page t)
+(add-to-list 'window-buffer-change-functions
+            'hywiki-highlight-page-names-in-frame nil 'eq)
+
+(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 valNue
+    (set symbol set-to-value)
+    (if set-to-value
+       (add-to-list 'yank-handled-properties '(hywiki-word-face . 
hywiki-highlight-on-yank))
+      (setq yank-handled-properties
+           (delete '(hywiki-word-face . hywiki-highlight-on-yank) 
'yank-handled-properties)))
+    (hywiki-highlight-page-names-in-frame t)))
+
+(add-variable-watcher 'hywiki-word-highlight-flag 
'hywiki-word-highlight-flag-changed)
+
+;; Sets `yank-handled-properties'
+(hywiki-word-highlight-flag-changed 'hywiki-word-highlight-flag
+                                   hywiki-word-highlight-flag 'set nil)
 
 (provide 'hywiki)



reply via email to

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