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

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

[nongnu] elpa/multiple-cursors 25b98b940c 1/2: Support commands with mul


From: ELPA Syncer
Subject: [nongnu] elpa/multiple-cursors 25b98b940c 1/2: Support commands with multiple read-chars
Date: Fri, 28 Jul 2023 04:00:28 -0400 (EDT)

branch: elpa/multiple-cursors
commit 25b98b940cdd360c445db74a5816513c5cf034e0
Author: Andrew Scott <3648487+ayyess@users.noreply.github.com>
Commit: Andrew Scott <3648487+ayyess@users.noreply.github.com>

    Support commands with multiple read-chars
    
    This change fixes commands that read-chars multiple times. Previously, two
    stage commands like embrace-change would read the same char twice 
immediately
    and avy-goto-char-timer would never stop reading input as a cached value was
    always provided during the timer. Instead, the read-char prompt is included 
in
    the cache key so that multiple different calls are cached separately and
    accessible by the fake cursors.
---
 features/multiple-cursors-core.feature             |  7 ++++
 .../step-definitions/multiple-cursors-steps.el     |  5 +++
 multiple-cursors-core.el                           | 44 ++++++++++------------
 3 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/features/multiple-cursors-core.feature 
b/features/multiple-cursors-core.feature
index dd97811017..0c4ed5c9ae 100644
--- a/features/multiple-cursors-core.feature
+++ b/features/multiple-cursors-core.feature
@@ -50,6 +50,13 @@ Feature: Multiple cursors core
     And I press "C-!"
     Then I should see "This aatext contains the word aatext twice"
 
+Scenario: Unknown command with multiple read: yes, do for all
+    Given I have bound C-! to a new command that inserts two read-chars
+    And I have cursors at "text" in "This text contains the word text twice"
+    When I press "C-! b c y"
+    And I press "C-! d e"
+    Then I should see "This bcdetext contains the word bcdetext twice"
+
   Scenario: Unknown command: no, don't do for all
     Given I have bound C-! to another new command that inserts "a"
     And I have cursors at "text" in "This text contains the word text twice"
diff --git a/features/step-definitions/multiple-cursors-steps.el 
b/features/step-definitions/multiple-cursors-steps.el
index 2eb442ed20..0c299a9b75 100644
--- a/features/step-definitions/multiple-cursors-steps.el
+++ b/features/step-definitions/multiple-cursors-steps.el
@@ -130,6 +130,11 @@
            (defun mc-test-temp-command-2 () (interactive) (insert ins))
            (global-set-key (kbd "C-!") 'mc-test-temp-command-2))))
 
+(Given "^I have bound C-! to a new command that inserts two read-chars$"
+       (lambda ()
+         (defun mc-test-temp-command-3 () (interactive) (insert (read-char 
"first: ")) (insert (read-char "second: ")))
+         (global-set-key (kbd "C-!") 'mc-test-temp-command-3)))
+
 (Given "^I have bound C-! to a keyboard macro that insert \"_\"$"
        (lambda ()
          (fset 'mc-test-temp-kmacro "\C-q_")
diff --git a/multiple-cursors-core.el b/multiple-cursors-core.el
index 3d48684ada..02a9e7531d 100644
--- a/multiple-cursors-core.el
+++ b/multiple-cursors-core.el
@@ -28,8 +28,6 @@
 (require 'cl-lib)
 (require 'rect)
 
-(defvar mc--read-char)
-
 (defface mc/cursor-face
   '((t (:inverse-video t)))
   "The face used for fake cursors"
@@ -52,11 +50,6 @@ rendered or shift text."
   :type '(boolean)
   :group 'multiple-cursors)
 
-(defcustom mc--reset-read-variables '()
-  "A list of cache variable names to reset by multiple-cursors."
-  :type '(list symbol)
-  :group 'multiple-cursors)
-
 (defface mc/region-face
   '((t :inherit region))
   "The face used for fake regions"
@@ -326,34 +319,35 @@ cursor with updated info."
 ;; Intercept some reading commands so you won't have to
 ;; answer them for every single cursor
 
-(defvar multiple-cursors-mode nil)
+(defvar mc--input-function-cache nil)
 
 (defun mc--reset-read-prompts ()
-  (mapc (lambda (var) (set var nil))
-        mc--reset-read-variables))
+  (setq mc--input-function-cache nil))
 
-(defmacro mc--cache-input-function (fn-name)
+(defmacro mc--cache-input-function (fn-name args-cache-key-fn)
   "Advise FN-NAME to cache its value in a private variable. Cache
 is to be used by mc/execute-command-for-all-fake-cursors and
-caches will be reset by mc--reset-read-prompts."
+caches will be reset by mc--reset-read-prompts. ARGS-CACHE-KEY-FN
+should transform FN-NAME's args to a unique cache-key so that
+different calls to FN-NAME during a command can return multiple
+values."
   (let ((mc-name (intern (concat "mc--" (symbol-name fn-name)))))
     `(progn
-       (defvar ,mc-name nil)
        (defun ,mc-name (orig-fun &rest args)
          (if (not multiple-cursors-mode)
              (apply orig-fun args)
-           (unless ,mc-name
-             (setq ,mc-name (apply orig-fun args)))
-           ,mc-name))
-       (advice-add ',fn-name :around #',mc-name)
-       (add-to-list 'mc--reset-read-variables ',mc-name))))
-
-(mc--cache-input-function read-char)
-(mc--cache-input-function read-quoted-char)
-(mc--cache-input-function register-read-with-preview) ; used by insert-register
-(mc--cache-input-function read-char-from-minibuffer)  ; used by zap-to-char
-
-(mc--reset-read-prompts)
+           (let* ((cache-key (cons ,(symbol-name fn-name) (,args-cache-key-fn 
args)))
+                  (cached-value (assoc cache-key mc--input-function-cache))
+                  (return-value (if cached-value (cdr cached-value) (apply 
orig-fun args))))
+             (unless cached-value
+               (push (cons cache-key return-value) mc--input-function-cache))
+             return-value)))
+       (advice-add ',fn-name :around #',mc-name))))
+
+(mc--cache-input-function read-char car)
+(mc--cache-input-function read-quoted-char car)
+(mc--cache-input-function register-read-with-preview car) ; used by 
insert-register
+(mc--cache-input-function read-char-from-minibuffer car)  ; used by zap-to-char
 
 (defun mc/fake-cursor-p (o)
   "Predicate to check if an overlay is a fake cursor"



reply via email to

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