unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#56418: Add duplicate-dwim [PATCH]
@ 2022-07-06  8:29 Mattias Engdegård
  2022-07-08 10:05 ` Mattias Engdegård
  0 siblings, 1 reply; 14+ messages in thread
From: Mattias Engdegård @ 2022-07-06  8:29 UTC (permalink / raw)
  To: 56418

[-- Attachment #1: Type: text/plain, Size: 451 bytes --]

This patch adds duplicate-swim, a command that works like duplicate-line but works on the region if active. It corresponds exactly to upcase-dwim, downcase-dwim and capitalize-dwim which have become quite popular.

Rectangular regions are treated specially by duplicating on the right-hand side. This behaviour turns out to be the most convenient one, and is also confluent with that of ordinary regions when the rectangle is only one line tall.


[-- Attachment #2: 0001-Add-duplicate-dwim.patch --]
[-- Type: application/octet-stream, Size: 4904 bytes --]

From abff5e9e5edcf43c06ca9df2c8c51248f6904b3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Mon, 20 Jun 2022 11:16:26 +0200
Subject: [PATCH] Add duplicate-dwim

Like duplicate-line but duplicates the region instead if active.
Rectangular regions are duplicated on the right-hand side.
The region remains active afterwards, to facilitate further
duplication or other operations on the same text.

* lisp/rect.el (rectangle--duplicate-right):
* lisp/misc.el (duplicate-dwim): New.
* test/lisp/misc-tests.el (misc--duplicate-dwim): New test.
---
 lisp/misc.el            | 37 +++++++++++++++++++++++++++++++++++++
 lisp/rect.el            | 21 +++++++++++++++++++++
 test/lisp/misc-tests.el | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+)

diff --git a/lisp/misc.el b/lisp/misc.el
index 28c5d6e07f..a53571f463 100644
--- a/lisp/misc.el
+++ b/lisp/misc.el
@@ -79,6 +79,43 @@ duplicate-line
       (dotimes (_ n)
         (insert line "\n")))))
 
+(declare-function rectangle--duplicate-right "rect" (n))
+
+;; `duplicate-dwim' preserves an active region and changes the buffer
+;; outside of it: disregard the region when immediately undoing the
+;; actions of this command.
+(put 'duplicate-dwim 'undo-inhibit-region t)
+
+;;;###autoload
+(defun duplicate-dwim (&optional n)
+  "Duplicate the current line or region N times.
+If the region is inactive, duplicate the current line (like `duplicate-line').
+Otherwise, duplicate the region, which remains active afterwards.
+If the region is rectangular, duplicate on its right-hand side.
+Interactively, N is the prefix numeric argument, and defaults to 1."
+  (interactive "p")
+  (unless n
+    (setq n 1))
+  (cond
+   ;; Duplicate rectangle.
+   ((bound-and-true-p rectangle-mark-mode)
+    (rectangle--duplicate-right n)
+    (setq deactivate-mark nil))
+
+   ;; Duplicate (contiguous) region.
+   ((use-region-p)
+    (let* ((beg (region-beginning))
+           (end (region-end))
+           (text (buffer-substring beg end)))
+      (save-excursion
+        (goto-char end)
+        (dotimes (_ n)
+          (insert text))))
+    (setq deactivate-mark nil))
+
+   ;; Duplicate line.
+   (t (duplicate-line n))))
+
 ;; Variation of `zap-to-char'.
 
 ;;;###autoload
diff --git a/lisp/rect.el b/lisp/rect.el
index e717d2ac7e..c41a545e85 100644
--- a/lisp/rect.el
+++ b/lisp/rect.el
@@ -931,6 +931,27 @@ rectangle--unhighlight-for-redisplay
     (mapc #'delete-overlay (nthcdr 5 rol))
     (setcar (cdr rol) nil)))
 
+(defun rectangle--duplicate-right (n)
+  "Duplicate the rectangular region N times on the right-hand side."
+  (let ((cols (rectangle--pos-cols (point) (mark))))
+    (apply-on-rectangle
+     (lambda (startcol endcol)
+       (let ((lines (list nil)))
+         (extract-rectangle-line startcol endcol lines)
+         (move-to-column endcol t)
+         (dotimes (_ n)
+           (insert (cadr lines)))))
+     (region-beginning) (region-end))
+    ;; Recompute the rectangle state; no crutches should be needed now.
+    (let ((p (point))
+          (m (mark)))
+      (rectangle--reset-crutches)
+      (goto-char m)
+      (move-to-column (cdr cols) t)
+      (set-mark (point))
+      (goto-char p)
+      (move-to-column (car cols) t))))
+
 (provide 'rect)
 
 ;;; rect.el ends here
diff --git a/test/lisp/misc-tests.el b/test/lisp/misc-tests.el
index a56feaa049..f84827ab02 100644
--- a/test/lisp/misc-tests.el
+++ b/test/lisp/misc-tests.el
@@ -96,5 +96,43 @@ misc--duplicate-line
     (should (equal (buffer-string) "abc\nabc\n"))
     (should (equal (point) 2))))
 
+(require 'rect)
+
+(ert-deftest misc--duplicate-dwim ()
+  ;; Duplicate a line.
+  (with-temp-buffer
+    (insert "abc\ndefg\nh\n")
+    (goto-char 7)
+    (duplicate-dwim 2)
+    (should (equal (buffer-string) "abc\ndefg\ndefg\ndefg\nh\n"))
+    (should (equal (point) 7)))
+
+  ;; Duplicate a region.
+  (with-temp-buffer
+    (insert "abc\ndef\n")
+    (set-mark 2)
+    (goto-char 7)
+    (transient-mark-mode)
+    (should (use-region-p))
+    (duplicate-dwim)
+    (should (equal (buffer-string) "abc\ndebc\ndef\n"))
+    (should (equal (point) 7))
+    (should (region-active-p))
+    (should (equal (mark) 2)))
+
+  ;; Duplicate a rectangular region.
+  (with-temp-buffer
+    (insert "x\n>a\n>bcde\n>fg\nyz\n")
+    (goto-char 4)
+    (rectangle-mark-mode)
+    (goto-char 15)
+    (rectangle-forward-char 1)
+    (duplicate-dwim)
+    (should (equal (buffer-string) "x\n>a  a  \n>bcdbcde\n>fg fg \nyz\n"))
+    (should (equal (point) 24))
+    (should (region-active-p))
+    (should rectangle-mark-mode)
+    (should (equal (mark) 4))))
+
 (provide 'misc-tests)
 ;;; misc-tests.el ends here
-- 
2.32.0 (Apple Git-132)


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-06  8:29 bug#56418: Add duplicate-dwim [PATCH] Mattias Engdegård
@ 2022-07-08 10:05 ` Mattias Engdegård
  2022-07-26 12:26   ` Mattias Engdegård
  0 siblings, 1 reply; 14+ messages in thread
From: Mattias Engdegård @ 2022-07-08 10:05 UTC (permalink / raw)
  To: 56418

The patch didn't include any changes to the manual because neither `duplicate-line` nor `upcase-dwim` appear there, but perhaps they should, too? Please advise.






^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-08 10:05 ` Mattias Engdegård
@ 2022-07-26 12:26   ` Mattias Engdegård
  2022-07-26 12:46     ` Stefan Kangas
  0 siblings, 1 reply; 14+ messages in thread
From: Mattias Engdegård @ 2022-07-26 12:26 UTC (permalink / raw)
  To: 56418-done

No objections, which is not surprising given the precedence; pushed to master.






^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-26 12:26   ` Mattias Engdegård
@ 2022-07-26 12:46     ` Stefan Kangas
  2022-07-26 12:56       ` Robert Pluim
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan Kangas @ 2022-07-26 12:46 UTC (permalink / raw)
  To: 56418, Mattias Engdegård; +Cc: 56418-done

How about simply replacing 'duplicate-line' with 'duplicate-dwim'?  Thanks.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-26 12:46     ` Stefan Kangas
@ 2022-07-26 12:56       ` Robert Pluim
  2022-07-27  9:01         ` Mattias Engdegård
  0 siblings, 1 reply; 14+ messages in thread
From: Robert Pluim @ 2022-07-26 12:56 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Mattias Engdegård, 56418

>>>>> On Tue, 26 Jul 2022 14:46:51 +0200, Stefan Kangas <stefan@marxist.se> said:

    Stefan> How about simply replacing 'duplicate-line' with
    Stefan> 'duplicate-dwim'?

I think both have merit, sometimes I just want to duplicate a line
with worrying about the region.

-- 





^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-26 12:56       ` Robert Pluim
@ 2022-07-27  9:01         ` Mattias Engdegård
  2022-07-29  3:54           ` Richard Stallman
  0 siblings, 1 reply; 14+ messages in thread
From: Mattias Engdegård @ 2022-07-27  9:01 UTC (permalink / raw)
  To: Robert Pluim; +Cc: 56418, Stefan Kangas

26 juli 2022 kl. 14.56 skrev Robert Pluim <rpluim@gmail.com>:

>    Stefan> How about simply replacing 'duplicate-line' with
>    Stefan> 'duplicate-dwim'?
> 
> I think both have merit, sometimes I just want to duplicate a line
> with worrying about the region.

While I have no particular wish to revisit this now, I will note that:

* Having two functions makes it harder to supply an standard key binding: we would have to select one of them since spending two key bindings is out of the question.

* As many other users I've bound M-u to upcase-dwim (etc) and not once has it bothered me that I can't upcase a word while marking a region.

* I'm not aware of any complaints whatsoever that the standard bindings for M-; and backspace force users to "worry about the region", 

However, peace and consensus is of higher importance and as far as I'm concerned this bug is closed, at least for now.






^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-27  9:01         ` Mattias Engdegård
@ 2022-07-29  3:54           ` Richard Stallman
  2022-07-29  6:11             ` Eli Zaretskii
  2022-07-31  8:36             ` Mattias Engdegård
  0 siblings, 2 replies; 14+ messages in thread
From: Richard Stallman @ 2022-07-29  3:54 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: 56418

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

What is the difference between duplicate-dwim and duplicate-line?

(To minimize duplicate replies, please don't reply unless you're
Mattias.)

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-29  3:54           ` Richard Stallman
@ 2022-07-29  6:11             ` Eli Zaretskii
  2022-08-04  4:01               ` Richard Stallman
  2022-07-31  8:36             ` Mattias Engdegård
  1 sibling, 1 reply; 14+ messages in thread
From: Eli Zaretskii @ 2022-07-29  6:11 UTC (permalink / raw)
  To: rms; +Cc: mattiase, 56418

> Cc: 56418@debbugs.gnu.org
> From: Richard Stallman <rms@gnu.org>
> Date: Thu, 28 Jul 2022 23:54:36 -0400
> 
> What is the difference between duplicate-dwim and duplicate-line?
> 
> (To minimize duplicate replies, please don't reply unless you're
> Mattias.)

How about dwim replies, do they have to be minimized as well?





^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-29  3:54           ` Richard Stallman
  2022-07-29  6:11             ` Eli Zaretskii
@ 2022-07-31  8:36             ` Mattias Engdegård
  2022-08-01  3:33               ` Richard Stallman
  1 sibling, 1 reply; 14+ messages in thread
From: Mattias Engdegård @ 2022-07-31  8:36 UTC (permalink / raw)
  To: rms; +Cc: 56418

29 juli 2022 kl. 05.54 skrev Richard Stallman <rms@gnu.org>:

> What is the difference between duplicate-dwim and duplicate-line?

Roughly, duplicate-dwim is to duplicate-line as upcase-dwim is to upcase-word. Ie, the -dwim commands operate on the region if active.






^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-31  8:36             ` Mattias Engdegård
@ 2022-08-01  3:33               ` Richard Stallman
  2022-08-01 11:29                 ` Eli Zaretskii
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2022-08-01  3:33 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: 56418

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > Roughly, duplicate-dwim is to duplicate-line as upcase-dwim is to upcase-word. Ie, the -dwim commands operate on the region if active.

I think there are already several commands that operate on the region
if it is active, otherwise on some other textual unit.  Would it be
bad for duplicate-line to do this?  Then we wouldn't need a separate
duplicate-dwim.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-08-01  3:33               ` Richard Stallman
@ 2022-08-01 11:29                 ` Eli Zaretskii
  0 siblings, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2022-08-01 11:29 UTC (permalink / raw)
  To: rms; +Cc: mattiase, 56418

> Cc: 56418@debbugs.gnu.org
> From: Richard Stallman <rms@gnu.org>
> Date: Sun, 31 Jul 2022 23:33:22 -0400
> 
>   > Roughly, duplicate-dwim is to duplicate-line as upcase-dwim is to upcase-word. Ie, the -dwim commands operate on the region if active.
> 
> I think there are already several commands that operate on the region
> if it is active, otherwise on some other textual unit.  Would it be
> bad for duplicate-line to do this?  Then we wouldn't need a separate
> duplicate-dwim.

That was suggested, but turned out to be too controversial.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-07-29  6:11             ` Eli Zaretskii
@ 2022-08-04  4:01               ` Richard Stallman
  2022-08-04 18:43                 ` Mattias Engdegård
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2022-08-04  4:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mattiase, 56418

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I've seen no cogent argument against making `duplicate-line' operate
on the region when that is active.  Someone presented this argument,

    Simen proposed something quite similar (added to the CCs), and my only
    objection was that the semantics of the simpler command is quite
    clear -- it always creates a new line, even if we're at a final line in
    a buffer without a newline.  When dealing with regions, it's not quite
    clear what the semantics should be in those corner cases (i.e., regions
    that doesn't end with a newline)...

but "duplicate the region" is totally clear, if interpreted strictly:

    Not much of a edge case, is it? If you select "bon" and duplicate you =
    end up with "bonbon", as promised.

The practical question is, which way will people find more convenient
to use?

Making `duplicate-line' region-sensitive would enable people to do both
operations with one key binding.  That is clearly a plus.  Good key
bindings are scarce and they take up space in the mind.

Making `duplicate-line' region-sensitive could lead to surprises when
the region is active, for a user who only ever uses it to duplicate
lines.  That is clearly a minus -- but how big is it in practice?

If we can only spare one binding for this, which behavior should that
binding have?

I suggest we define `duplicate-lines' with an option to control
whether it is region-sensitive, so that people can try it both ways
and tell us which way they like better.  Then we could set the
default for that option accordingly.


-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-08-04  4:01               ` Richard Stallman
@ 2022-08-04 18:43                 ` Mattias Engdegård
  2022-08-16 11:08                   ` Robert Pluim
  0 siblings, 1 reply; 14+ messages in thread
From: Mattias Engdegård @ 2022-08-04 18:43 UTC (permalink / raw)
  To: rms; +Cc: Eli Zaretskii, 56418, Lars Ingebrigtsen

4 aug. 2022 kl. 06.01 skrev Richard Stallman <rms@gnu.org>:

> I suggest we define `duplicate-lines' with an option to control
> whether it is region-sensitive, so that people can try it both ways
> and tell us which way they like better.

I wouldn't mind but it's not a change I can make unilaterally. The present solution did not require changes to `duplicate-line`.






^ permalink raw reply	[flat|nested] 14+ messages in thread

* bug#56418: Add duplicate-dwim [PATCH]
  2022-08-04 18:43                 ` Mattias Engdegård
@ 2022-08-16 11:08                   ` Robert Pluim
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Pluim @ 2022-08-16 11:08 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Lars Ingebrigtsen, Eli Zaretskii, 56418, rms

>>>>> On Thu, 4 Aug 2022 20:43:33 +0200, Mattias Engdegård <mattiase@acm.org> said:

    Mattias> 4 aug. 2022 kl. 06.01 skrev Richard Stallman <rms@gnu.org>:
    >> I suggest we define `duplicate-lines' with an option to control
    >> whether it is region-sensitive, so that people can try it both ways
    >> and tell us which way they like better.

    Mattias> I wouldn't mind but it's not a change I can make unilaterally. The
    Mattias> present solution did not require changes to `duplicate-line`.

Not everything needs an option to control it. I want duplicate-line to
simply duplicate a line. Others donʼt, they want it to obey the
region. We can coexist peacefully without forcing anybody to configure
anything, and we can each have whatever binding we prefer (I donʼt
think this should be bound to a key by default).

Robert
-- 





^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-08-16 11:08 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-06  8:29 bug#56418: Add duplicate-dwim [PATCH] Mattias Engdegård
2022-07-08 10:05 ` Mattias Engdegård
2022-07-26 12:26   ` Mattias Engdegård
2022-07-26 12:46     ` Stefan Kangas
2022-07-26 12:56       ` Robert Pluim
2022-07-27  9:01         ` Mattias Engdegård
2022-07-29  3:54           ` Richard Stallman
2022-07-29  6:11             ` Eli Zaretskii
2022-08-04  4:01               ` Richard Stallman
2022-08-04 18:43                 ` Mattias Engdegård
2022-08-16 11:08                   ` Robert Pluim
2022-07-31  8:36             ` Mattias Engdegård
2022-08-01  3:33               ` Richard Stallman
2022-08-01 11:29                 ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).