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

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

[elpa] externals/expand-region af2916b89d 2/2: expand-region: Memoize ex


From: ELPA Syncer
Subject: [elpa] externals/expand-region af2916b89d 2/2: expand-region: Memoize expansion results
Date: Thu, 4 Jan 2024 12:58:26 -0500 (EST)

branch: externals/expand-region
commit af2916b89d8b5e520ff4ee7214bab62a0fdb3cec
Author: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
Commit: Magnar Sveen <magnars@gmail.com>

    expand-region: Memoize expansion results
    
    expand-region-core.el (er--expand-region-1, er--saved-expansions): Use
    a new buffer-local variable, `er--saved-expansions`, to hold
    information about the point/mark returned by `er/try-expand-list'.  If
    using `er/expand-region' or `er/contract-region' repeatedly, use this
    memoized data instead of recomputing all expansions.  This speeds up
    expand-region significantly when there are a large number of or
    expensive functions in `er/try-expand-list'.
    
    expand-region.el (er/expand-region): Clear the saved expansion data in
    `er--saved-expansions` on the first (non-chained) invocation of
    `er/expand-region' or `er-contract-region`.
---
 expand-region-core.el | 37 ++++++++++++++++++++++++++-----------
 expand-region.el      |  2 ++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/expand-region-core.el b/expand-region-core.el
index 1f60dbe974..e2829cdcb3 100644
--- a/expand-region-core.el
+++ b/expand-region-core.el
@@ -50,6 +50,12 @@
   "t if this is the first invocation of `er/expand-region' or 
`er/contract-region'."
   (not (memq last-command '(er/expand-region er/contract-region))))
 
+(defvar-local er--saved-expansions nil
+  "List of region data used to avoid redundant computation.
+
+When expand-region or contract-region is called repeatedly, save
+the data here and reuse when possible.")
+
 (defun er--prepare-expanding ()
   (when (and (er--first-invocation)
              (not (use-region-p)))
@@ -109,17 +115,26 @@ moving point or mark as little as possible."
       (setq start (point)))
 
     (er--save-excursion
-       (while try-list
-         (ignore-errors
-           (save-mark-and-excursion
-             (funcall (car try-list))
-             (when (and (region-active-p)
-                        (er--this-expansion-is-better start end best-start 
best-end))
-               (setq best-start (point))
-               (setq best-end (mark))
-               (when (and er--show-expansion-message (not (minibufferp)))
-                 (message "%S" (car try-list))))))
-         (setq try-list (cdr try-list))))
+     (while try-list
+       (ignore-errors
+         (save-mark-and-excursion
+           ;; Try expansion or fetch memoized value
+           (if-let* ((try-func (car try-list))
+                     ((not (er--first-invocation)))
+                     (bounds (alist-get try-func er--saved-expansions))
+                     ((or (>= (point) (car bounds)) (<= (mark) (cadr 
bounds)))))
+               (progn (set-mark (cadr bounds))
+                      (goto-char (car bounds)))
+             (funcall try-func)
+             (setf (alist-get try-func er--saved-expansions) (list (point) 
(mark))))
+           ;; Test expansion against best expansion so far
+           (when (and (region-active-p)
+                      (er--this-expansion-is-better start end best-start 
best-end))
+             (setq best-start (point))
+             (setq best-end (mark))
+             (when (and er--show-expansion-message (not (minibufferp)))
+               (message "%S" (car try-list))))))
+       (setq try-list (cdr try-list))))
 
     (setq deactivate-mark nil)
     ;; if smart cursor enabled, decide to put it at start or end of region:
diff --git a/expand-region.el b/expand-region.el
index ebaaca2967..78a9bef446 100644
--- a/expand-region.el
+++ b/expand-region.el
@@ -157,6 +157,8 @@ before calling `er/expand-region' for the first time."
       (setq arg (- arg 1))
       (when (eq 'early-exit (er--expand-region-1))
         (setq arg 0)))
+    (when (er--first-invocation)
+      (setq-local er--saved-expansions nil))
     (when (and expand-region-fast-keys-enabled
                (not (memq last-command '(er/expand-region 
er/contract-region))))
       (er/prepare-for-more-expansions))))



reply via email to

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