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

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

[nongnu] elpa/multiple-cursors 067063a 118/434: Split multiline kill-rin


From: ELPA Syncer
Subject: [nongnu] elpa/multiple-cursors 067063a 118/434: Split multiline kill-ring entry over cursors when num lines match
Date: Sat, 7 Aug 2021 09:20:07 -0400 (EDT)

branch: elpa/multiple-cursors
commit 067063a3467abeffee1903a5a2be42e02b36ba93
Author: Magnar Sveen <magnars@gmail.com>
Commit: Magnar Sveen <magnars@gmail.com>

    Split multiline kill-ring entry over cursors when num lines match
---
 features/multiple-cursors-core.feature | 23 +++++++++++++++++
 multiple-cursors-core.el               | 46 +++++++++++++++++++++++++++++-----
 2 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/features/multiple-cursors-core.feature 
b/features/multiple-cursors-core.feature
index c7ebbec..cba589b 100644
--- a/features/multiple-cursors-core.feature
+++ b/features/multiple-cursors-core.feature
@@ -131,3 +131,26 @@ Feature: Multiple cursors core
     contains
     twice
     """
+
+  Scenario: Split multiline kill-ring entry over cursors when num lines match
+    When I insert:
+    """
+    a
+    b
+    c
+    """
+    And I go to the front of the word "a"
+    And I press "C-SPC"
+    And I go to the end of the word "c"
+    And I press "M-w"
+    And I go to the end of the word "a"
+    And I press "H-SPC"
+    And I press "C-n"
+    And I press "C-n"
+    And I press "C-y"
+    Then I should see:
+    """
+    aa
+    bb
+    cc
+    """
diff --git a/multiple-cursors-core.el b/multiple-cursors-core.el
index eaeb2ad..bf45e97 100644
--- a/multiple-cursors-core.el
+++ b/multiple-cursors-core.el
@@ -62,11 +62,17 @@
      (save-excursion ,@forms)
      (mc/pop-state-from-overlay current-state)))
 
-(defmacro mc/for-each-cursor (&rest forms)
+(defun mc--compare-by-overlay-start (o1 o2)
+  (< (overlay-start o1) (overlay-start o2)))
+
+(defmacro mc/for-each-cursor-ordered (&rest forms)
   "Runs the body for each cursor, fake and real, bound to the name cursor"
   `(let ((real-cursor (mc/create-fake-cursor-at-point)))
-     (mc/for-each-fake-cursor ,@forms)
-     (mc/remove-fake-cursor real-cursor)))
+     (mapc #'(lambda (cursor)
+               (when (mc/fake-cursor-p cursor)
+                 ,@forms))
+           (sort (overlays-in (point-min) (point-max)) 
'mc--compare-by-overlay-start))
+     (mc/pop-state-from-overlay real-cursor)))
 
 (defmacro mc/save-window-scroll (&rest forms)
   "Saves and restores the window scroll position"
@@ -177,6 +183,8 @@ Saves the current state in the overlay to be restored 
later."
     (call-interactively cmd))
   (when deactivate-mark (deactivate-mark)))
 
+(defvar mc--executing-command-for-fake-cursor nil)
+
 (defun mc/execute-command-for-all-fake-cursors (cmd)
   "Calls CMD interactively for each cursor.
 It works by moving point to the fake cursor, setting
@@ -187,7 +195,8 @@ cursor with updated info."
    (mc/save-window-scroll
     (mc/for-each-fake-cursor
      (save-excursion
-       (let ((id (overlay-get cursor 'mc-id))
+       (let ((mc--executing-command-for-fake-cursor t)
+             (id (overlay-get cursor 'mc-id))
              (annoying-arrows-mode nil))
          (mc/add-fake-cursor-to-undo-list
           (mc/pop-state-from-overlay cursor)
@@ -301,13 +310,38 @@ multiple cursors editing.")
       (setq entries (cdr entries)))
     all-equal))
 
-(defun mc--maybe-consolidate-kill-rings ()
+(defun mc--kill-ring-entries ()
   (let (entries)
-    (mc/for-each-cursor
+    (mc/for-each-cursor-ordered
      (setq entries (cons (car (overlay-get cursor 'kill-ring)) entries)))
+    (reverse entries)))
+
+(defun mc--maybe-consolidate-kill-rings ()
+  (let ((entries (mc--kill-ring-entries)))
     (unless (mc--all-equal entries)
       (kill-new (mapconcat 'identity entries "\n")))))
 
+(defun mc--kill-new (entries)
+  (mc/for-each-cursor-ordered
+   (let ((kill-ring (overlay-get cursor 'kill-ring))
+         (kill-ring-yank-pointer (overlay-get cursor 'kill-ring-yank-pointer)))
+     (kill-new (car entries))
+     (setq entries (cdr entries))
+     (overlay-put cursor 'kill-ring kill-ring)
+     (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer))))
+
+(defun mc--maybe-split-kill-ring ()
+  (let ((entries (mc--kill-ring-entries)))
+    (when (mc--all-equal entries)
+      (let ((lines (split-string (car entries) "\n")))
+        (when (= (mc/num-cursors) (length lines))
+          (mc--kill-new lines))))))
+
+(defadvice yank (before maybe-split-kill-ring activate)
+  (when (and (or multiple-cursors-mode rectangular-region-mode)
+             (not mc--executing-command-for-fake-cursor))
+    (mc--maybe-split-kill-ring)))
+
 (define-minor-mode multiple-cursors-mode
   "Mode while multiple cursors are active."
   nil " mc" mc/keymap



reply via email to

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