branch: externals/hyperbole
commit 4bb81f423bab4e33e94bad8816c3543303c85c16
Author: bw <r...@gnu.org>
Commit: bw <r...@gnu.org>

    hywiki.el - Fix yanking and deleting one paired delimiter properly
---
 ChangeLog | 12 +++++++++++
 hywiki.el | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 77 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d0a9f318d1..51e731c4f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,10 +15,22 @@
 * hywiki.el (hywiki-make-referent-hasht): Return hasht when rebuilding from
     load data.
 
+2025-02-07  Bob Weiner  <r...@gnu.org>
+
+* hywiki.el (hywiki--extend-yanked-region): Add and call in 
'hywiki-highlight-on-yank'
+    to extend a yanked region to include the rest of a delimited pair or 
string.
+
 * hui-select.el (hui-select-string-p): Fix to make multi-line string selection
     work properly whether on the opening or closing double quote mark, using
     'scan-sexps'.  Update doc string.
 
+2025-02-06  Bob Weiner  <r...@gnu.org>
+
+* hywiki.el (hywiki-debuttonize-non-character-commands,
+             hywiki-buttonize-non-character-commands): Add support for 'kill'
+    commands and fix that removing a trailing delimiter did not rehighlight
+    HyWikiWords properly.
+
 2025-02-05  Mats Lidell  <ma...@gnu.org>
 
 * hywiki.el (hywiki-add-org-id): Suppress byte compile warnings for calling 
org-id-get with
diff --git a/hywiki.el b/hywiki.el
index 04190ac5fc..ddd716e0e2 100644
--- a/hywiki.el
+++ b/hywiki.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    21-Acpr-24 at 22:41:13
-;; Last-Mod:      8-Feb-25 at 22:56:32 by Mats Lidell
+;; Last-Mod:      9-Feb-25 at 10:10:14 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -564,16 +564,18 @@ deletion commands and those in 
`hywiki-non-character-commands'."
                   (active-minibuffer-window)))
     (when (or (memq this-command hywiki-non-character-commands)
              (and (symbolp this-command)
-                  (string-match-p 
"^\\(org-\\)?delete-\\|-delete-\\|insert\\(-\\|$\\)" (symbol-name 
this-command))))
+                  (string-match-p 
"^\\(org-\\)?\\(delete-\\|kill-\\)\\|\\(-delete\\|-kill\\|insert\\)\\(-\\|$\\)" 
(symbol-name this-command))))
       (if (and (marker-position hywiki--buttonize-start)
               (marker-position hywiki--buttonize-end))
+         ;; This means the command just deleted an opening or closing
+         ;; delimiter of a range that now needs any HyWikiWords
+         ;; inside to be re-highlighted.
          (save-excursion
            (goto-char hywiki--buttonize-start)
            (let ((opening-char (char-after))
                  closing-char)
              (when (memq opening-char '(?\( ?\"))
-               (delete-char 1)
-               (insert " "))
+               (delete-char 1))
              (goto-char hywiki--buttonize-end)
              (setq closing-char (char-before))
              (when (memq closing-char '(?\) ?\"))
@@ -582,7 +584,6 @@ deletion commands and those in 
`hywiki-non-character-commands'."
              (goto-char hywiki--buttonize-start)
              (hywiki-maybe-highlight-between-page-names)
              (when (memq opening-char '(?\( ?\"))
-               (delete-char 1)
                (insert opening-char))
              (when (memq closing-char '(?\) ?\"))
                (goto-char (1+ hywiki--buttonize-end))
@@ -599,7 +600,7 @@ deletion commands and those in 
`hywiki-non-character-commands'."
     (set-marker hywiki--buttonize-end nil))
   (when (or (memq this-command hywiki-non-character-commands)
            (and (symbolp this-command)
-                (string-match-p "\\`\\(org-\\)?delete-\\|-delete-"
+                (string-match-p 
"\\`\\(org-\\)?\\(delete-\\|kill-\\)\\|-delete-\\|-kill-"
                                 (symbol-name this-command))))
     (cl-destructuring-bind (start end)
        (hywiki-get-delimited-range) ;; includes delimiters
@@ -1543,10 +1544,16 @@ After successfully finding any kind of referent, run
 Have to add one character to the length of the yanked text so that any
 needed word-separator after the last character is included to induce
 highlighting any last HyWikiWord."
-  (hywiki-maybe-highlight-page-names start (min (1+ end) (point-max))))
+  ;; When yank only part of a delimited pair, expand the range to
+  ;; include the whole delimited pair before re-highlighting
+  ;; HyWikiWords therein, so that the whole delimited expression is
+  ;; included.
+  (cl-destructuring-bind (start end)
+      (hywiki--extend-yanked-region start end)
+    (hywiki-maybe-highlight-page-names start (min (1+ end) (point-max)))))
 
 (defun hywiki-map-words (func)
-  "Apply FUNC across all HyWikiWords in the current buffer and return nil.
+  "Apply FUNC across highlighted HyWikiWords in the current buffer and return 
nil.
 FUNC takes 1 argument, the Emacs overlay spanning the start and end buffer
 positions of each HyWikiWord and its optional #section."
   (save-excursion
@@ -2934,6 +2941,56 @@ invalid.  Appended only if the referent-type supports 
suffixes."
                (cons referent-type referent-value))
            referent))))))
 
+(defun hywiki--extend-yanked-region (start end)
+  "Return a list of (START END) with the specified range extended to include 
any delimited regions.
+Typically used to extend a yanked region to fully include any strings or 
balanced pair delimiters."
+  (let ((delim-distance 0)
+       (result (list start end))
+       opoint)
+
+    ;; Skip past all delimited ranges and extend `end' as needed
+    (save-excursion
+      (goto-char start)
+      (while (and (<= (point) end)
+                 (not (zerop (setq delim-distance (skip-syntax-forward "^\(" 
end)))))
+       (condition-case nil
+           (progn (goto-char (+ (point) delim-distance))
+                  (setq opoint (point))
+                  (setq end (max end (goto-char (scan-sexps (point) 1)))
+                        result (list start end)))
+         (error (goto-char (min (1+ opoint) end))))))
+
+    ;; Skip past all double-quoted ranges and extend `start' and `end' as 
needed
+    (save-excursion
+      (goto-char start)
+      (while (and (<= (point) end)
+                 (not (zerop (setq delim-distance (skip-syntax-forward "^\"" 
end)))))
+       (condition-case nil
+           (progn (goto-char (+ (point) delim-distance))
+                  (setq opoint (point))
+                  (if (hypb:in-string-p)
+                      (progn (goto-char (1+ (point)))
+                             (setq start (min start (goto-char (scan-sexps (1+ 
(point)) -1))))
+                             (goto-char (min (1+ opoint) end)))
+                    ;; before a string
+                    (setq end (max end (goto-char (scan-sexps (point) 1)))))
+                  (setq result (list start end)))
+         (error (goto-char (min (1+ opoint) end))))))
+
+    ;; Skip past closing delimiter and extend `start' if needed
+    (save-excursion
+      (goto-char start)
+      (while (and (<= (point) end)
+                 (not (zerop (setq delim-distance (skip-syntax-forward "^\)" 
end)))))
+       (condition-case nil
+           (progn (goto-char (+ (point) delim-distance))
+                  (setq opoint (point))
+                  (setq start (min start (goto-char (scan-sexps (1+ (point)) 
-1)))
+                        result (list start end))
+                  (goto-char (min (1+ opoint) end)))
+         (error (goto-char (min (1+ opoint) end))))))
+      result))
+
 (defun hywiki--get-delimited-range-backward ()
   "Return a list of (start end) if not between/after end ]] or >>.
 Otherwise, return nil."

Reply via email to