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'.