branch: externals/hyperbole commit 2e4857aef4957eb4e1967c09b199385540c52d27 Merge: 2d2b23c3d5 537e70b48b Author: Robert Weiner <r...@gnu.org> Commit: GitHub <nore...@github.com>
Merge pull request #730 from rswgnu/rsw hypb:in-string-p - Improve performance in large docs; kotl-mode:add-prior-cell - Fix to send raw C-u value with "*P" --- ChangeLog | 13 ++++++++++ hypb.el | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++----- kotl/kotl-mode.el | 14 ++++++----- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7a61caecaf..fa611613d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2025-05-18 Bob Weiner <r...@gnu.org> + +* hypb.el (hypb:in-string-p): Make heuristic to optimize performance; search + back only until the beginning of the first line prior to point that contains + a non-quoted double quote mark. Also add support for 'texinfo-mode' strings + where both "String1" and ``String2'' may be used. Add support for + 'python-mode' single and triple string delimiters as well. + (hypb:in-string-modes-regexps): Add for use in 'hypb:in-string-p'. + Allows customization of major modes with unique string delimiters. + +* kotl/kotl-mode.el (kotl-mode:add-prior-cell): Fix to send raw C-u value + with (interactive "*P") instead of "p". + 2025-05-12 Mats Lidell <ma...@gnu.org> * test/hmouse-drv-tests.el (hmouse-drv--hkey-actions): Test hkey-actions. diff --git a/hypb.el b/hypb.el index af1dc10cb8..9e4c837f1d 100644 --- a/hypb.el +++ b/hypb.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 6-Oct-91 at 03:42:38 -;; Last-Mod: 27-Apr-25 at 12:03:07 by Bob Weiner +;; Last-Mod: 18-May-25 at 17:40:45 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -68,6 +68,22 @@ "Prefix attached to all native Hyperbole help buffer names. This should end with a space.") +(defcustom hypb:in-string-modes-regexps + '(let ((open-regexp "\\(^\\|[^\\]\\)\\(%s\\)") + (close-regexp "\\(^\\|[^\\]\\)\\(%s\\)")) + (cond ((derived-mode-p 'python-mode) + (list (format open-regexp "\"\\|'''\\|\"\"\"\\|'") + (format close-regexp "\"\\|'''\\|\"\"\"\\|'"))) + ((derived-mode-p 'texinfo-mode) + (list (format open-regexp "\"\\|``") + (format close-regexp "\"\\|''"))) + (t + (list (format open-regexp "\"") + (format close-regexp "\""))))) + "Return a list of open/close string delimiter regexps for `hypb:in-string-p'." + :type 'sexp + :group 'hyperbole-commands) + (defvar hypb:mail-address-mode-list '(fundamental-mode prog-mode text-mode) "List of major modes in which mail address implicit buttons are active. @@ -664,7 +680,20 @@ This will this install the Emacs helm package when needed." help-file)))))) (defun hypb:in-string-p (&optional max-lines) - "Return t iff point is within a double quoted string." + "Return t iff point is within a string. + +To prevent searching back to the buffer start and producing slow +performance, this limits its count of quotes found prior to point +to the beginning of the first line prior to point that contains a +non-quoted quote mark. + +Quoting conventions recognized are: + double-quotes: \"str\"; + Markdown triple backticks: ```str```; + Python single-quotes: 'str'; + Python triple single-quotes: '''str'''; + Python triple double-quotes: \"\"\"str\"\"\"; + Texinfo open and close quotes: ``str''." (save-restriction (when (integerp max-lines) (narrow-to-region (line-beginning-position) @@ -672,10 +701,40 @@ This will this install the Emacs helm package when needed." ;; Don't use `syntax-ppss' here as it fails to ignore backquoted ;; double quote characters in strings and doesn't work in ;; `change-log-mode' due to its syntax-table. - (save-match-data - (and (cl-oddp (count-matches "\\(^\\|[^\\]\\)\"" (point-min) (point))) - (save-excursion (re-search-forward "\\(^\\|[^\\]\\)\"" nil t)) - t)))) + (let ((opoint (point)) + (start (point-min)) + (open-match-string "")) + (cl-destructuring-bind (open-regexp close-regexp) + (eval hypb:in-string-modes-regexps) + (cond ((derived-mode-p 'python-mode) + (setq open-regexp (format open-regexp "\"\\|'''\\|\"\"\"\\|'") + close-regexp (format close-regexp "\"\\|'''\\|\"\"\"\\|'"))) + ((derived-mode-p 'texinfo-mode) + (setq open-regexp (format open-regexp "\"\\|``") + close-regexp (format close-regexp "\"\\|''"))) + (t + (setq open-regexp (format open-regexp "\"") + close-regexp (format close-regexp "\"")))) + (save-match-data + (when (re-search-backward open-regexp nil t) + (setq open-match-string (match-string 2)) + (forward-line 0) + (setq start (point)) + (goto-char opoint) + (if (and (derived-mode-p 'texinfo-mode) + (string-equal open-match-string texinfo-open-quote)) + (and (cl-oddp (- (count-matches (regexp-quote open-match-string) + start (point)) + (count-matches (regexp-quote texinfo-close-quote) + start (point)))) + (save-excursion (search-forward texinfo-close-quote nil t)) + t) + (and (cl-oddp (count-matches + (format "\\(^\\|[^\\]\\)\\(%s\\)" + (regexp-quote open-match-string)) + start (point))) + (save-excursion (re-search-forward close-regexp nil t)) + t)))))))) (defun hypb:indirect-function (obj) "Return the function at the end of OBJ's function chain. diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el index fdbe04db22..189f6afdd2 100644 --- a/kotl/kotl-mode.el +++ b/kotl/kotl-mode.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 6/30/93 -;; Last-Mod: 4-May-25 at 11:13:26 by Bob Weiner +;; Last-Mod: 18-May-25 at 10:16:26 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -2518,12 +2518,13 @@ last cell added. Add new cells with optional CONTENTS string, attributes in PLIST, a property list, and NO-FILL flag to prevent any filling of CONTENTS." - (interactive "*p") + (interactive "*P") (when (null cells-to-add) (setq cells-to-add 1)) - (unless (and (natnump cells-to-add) (/= cells-to-add 0)) - (error "(kotl-mode:add-prior-cell): `cells-to-add' must be a positive integer")) - (if (eq cells-to-add '(4)) + (if (equal cells-to-add '(4)) (kotl-mode:add-below-parent) + (setq cells-to-add (prefix-numeric-value cells-to-add)) + (unless (and (natnump cells-to-add) (/= cells-to-add 0)) + (error "(kotl-mode:add-prior-cell): `cells-to-add' must be a positive integer")) (cond ((zerop (kotl-mode:backward-cell 1)) ;; Add preceding sibling if not on first cell at current level (kotl-mode:add-cell cells-to-add contents plist no-fill)) @@ -2533,7 +2534,8 @@ CONTENTS." (kotl-mode:add-child cells-to-add contents plist no-fill)) (t ;; Add preceding sibling when on level 1 first cell - (kotl-mode:add-below-parent cells-to-add contents plist no-fill))))) + (kotl-mode:add-below-parent cells-to-add + contents plist no-fill))))) (defun kotl-mode:demote-tree (arg) "Move current tree a maximum of prefix ARG levels lower in current view.