branch: externals/easy-kill
commit be7e9e2aa9907cea43b25959deea7ca50bf4777f
Author: Akinori Musha <[email protected]>
Commit: Leo Liu <[email protected]>

    Add easy-dup commands for duplicating selections
    
    Introduce `easy-dup-after` (aliased as `easy-dup`) and
    `easy-dup-before` to duplicate the current selection after or before
    it.  These commands work with `easy-kill`/`easy-mark` selections,
    active regions, and `rectangle-mark-mode`.  When no selection is
    active, `easy-mark` is entered using the new `easy-dup-try-things`
    customization variable.
---
 README.rst   | 12 ++++++++++++
 easy-kill.el | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/README.rst b/README.rst
index 1934cd7c57..33d73a3cf2 100644
--- a/README.rst
+++ b/README.rst
@@ -80,6 +80,18 @@ sexp even when in the middle of one. ::
 
    (global-set-key [remap mark-sexp] 'easy-mark)
 
+easy-dup
+~~~~~~~~
+
+``easy-dup`` (``easy-dup-after``) and ``easy-dup-before`` duplicate
+the current selection after or before it respectively.  When not in
+easy-kill/easy-mark, the active region is used if available.  If there
+is no active region, easy-mark is entered using
+``easy-dup-try-things`` to select something to duplicate.
+``rectangle-mark-mode`` is also supported.
+
+A numeric prefix argument specifies the number of copies to insert.
+
 Install
 ~~~~~~~
 
diff --git a/easy-kill.el b/easy-kill.el
index 596034acc0..e6f1299b5e 100644
--- a/easy-kill.el
+++ b/easy-kill.el
@@ -79,6 +79,11 @@ string) for appending current selection to previous kill."
   :type '(repeat symbol)
   :group 'killing)
 
+(defcustom easy-dup-try-things '(line)
+  "A list of things for `easy-dup-before' and `easy-dup-after' to try."
+  :type '(repeat symbol)
+  :group 'killing)
+
 (defface easy-kill-selection '((t (:inherit secondary-selection)))
   "Faced used to highlight kill candidate."
   :group 'killing)
@@ -615,6 +620,63 @@ Temporally activate additional key bindings as follows:
       (setf (easy-kill-get thing) 'sexp)
       (easy-kill-thing 'sexp n))))
 
+(declare-function rectangle--duplicate-right "rect" (n displacement))
+
+;;;###autoload
+(defun easy-dup (&optional n before)
+  "Insert a copy of the current selection after it, or before it if BEFORE.
+When not in easy-kill/easy-mark, use the active region if available, or
+enter easy-mark using `easy-dup-try-things' to select something to
+duplicate.  `rectangle-mark-mode' is also supported.  N specifies the
+number of copies to insert."
+  (interactive "*p")
+  (or
+   (pcase (easy-kill-get bounds)
+     (`(,x . ,x)
+      (ignore x)
+      (cond
+       ((bound-and-true-p rectangle-mark-mode)
+        (rectangle--duplicate-right n (if before n 0))
+        t)
+       ((use-region-p)
+        (let* ((beg (region-beginning))
+               (end (region-end))
+               (text (buffer-substring beg end)))
+          (save-excursion
+            (goto-char (if before beg end))
+            (if before
+                (dotimes (_ (or n 1)) (insert-before-markers text))
+              (dotimes (_ (or n 1)) (insert text)))))
+        t)
+       (t (let ((easy-mark-try-things easy-dup-try-things))
+            (easy-mark 1)
+            nil)))))
+   (pcase (easy-kill-get bounds)
+     (`(,x . ,x) (ignore x) (easy-kill-echo "Empty region"))
+     (`(,beg . ,end)
+      (let ((text (buffer-substring beg end)))
+        (save-excursion
+          (goto-char (if before beg end))
+          (if before
+              (dotimes (_ (or n 1)) (insert-before-markers text))
+            (dotimes (_ (or n 1)) (insert text))))
+        (and before
+             (setf (easy-kill-get origin) (easy-kill-get start)))))))
+  (setq deactivate-mark nil))
+
+;;;###autoload
+(defalias 'easy-dup-after #'easy-dup)
+
+;;;###autoload
+(defun easy-dup-before (&optional n)
+  "Insert a copy of the current selection before it.
+When not in easy-kill/easy-mark, use the active region if available, or
+enter easy-mark using `easy-dup-try-things' to select something to
+duplicate.  `rectangle-mark-mode' is also supported.  N specifies the
+number of copies to insert."
+  (interactive "*p")
+  (easy-dup n t))
+
 ;;;; Extended things
 
 ;;; Handler for `buffer-file-name'.

Reply via email to