From: Jens Schmidt via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: 66780@debbugs.gnu.org
Subject: bug#66780: [PATCH] Improve rectangle-mark-mode when transient-mark-mode is off
Date: Fri, 27 Oct 2023 22:31:24 +0200 [thread overview]
Message-ID: <0b1f5f23-b683-4367-beae-332a8d850d32@vodafonemail.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 5686 bytes --]
Severity: minor
All issues reported here are about using rectangle-mark-mode (RMM) when
Transient Mark mode (TMM) is off.
Bug#42663 already has mentioned a few issues of this combination, but
IMO did not completely describe or solve them.
So suppose you start in the Emacs source directory tree
./src/emacs -Q --eval='(transient-mark-mode -1)' README
When you then press `C-x <SPC>' to enable RMM, the following happens,
which is expected:
1. The mark is NOT activated and, hence, the region-rectangle is NOT
shown when you move point. Also, point movement stays regular, in
that you cannot advance point to after EOL, for example.
Again, this restriction is expected and is described already in commit
06dcd2be5d42 provided by Sean to solve bug#42663.
However, what has not been described yet is that some parts of RMM
actually _are_ active when one enables it with TMM off:
2. The key bindings in `rectangle-mark-mode-map', so that, for example,
`C-x C-x' does not exchange point and mark, but instead cycles
through the corners of the rectangle spanned by mark and point (using
closest accessible buffer positions as an approximation for those
positions where point regularly cannot be moved to).
(Short reproducer when starting off the "emacs -Q ..." above:
M-: (rectangle-mark-mode -1) RET
M-< C-x <SPC> C-4 C-n C-e C-x C-x C-x C-x C-x C-x)
3. Advices on `region-extract-function' and `region-insert-function', so
that C-w and C-y still operate on the current rectangle, and not the
regular region.
(Short reproducer when starting off the "emacs -Q ..." above:
M-: (rectangle-mark-mode -1) RET
M-< C-x <SPC> C-4 C-n C-4 C-f C-w)
I found 2. and 3. surprising because I would have expected that RMM is
completely off. Moreover, RMM does not provide a minor mode lighter so
you cannot easily tell whether it is on or off.
I have attempted to improve the situation by providing documentation
(fix A) in a patch on emacs-29, and some minor code fixes (B and C) in a
patch on emacs-master. That latter patch still has a placeholder
"bug#XXXXX" which needs to be updated once I have a bug number.
* Fix A: Improve Documentation
Here is the text that Sean has already added to emacs/killing.tex in
commit 06dcd2be5d42:
+The region-rectangle works only when the mark is active. In
+particular, when Transient Mark mode is off (@pxref{Disabled Transient
+Mark}), in addition to typing @kbd{C-x @key{SPC}} you will need to
+activate the mark.
I first tried to extend on that, but then decided to completely redo the
material, like this:
+ rectangle-mark-mode behaves in a slightly different way when
+Transient Mark mode is off (@pxref{Disabled Transient Mark}). In this
+case, when you enable rectangle-mark-mode, the region-rectangle is not
+automatically enabled. Accordingly, cursor movement with @kbd{C-f},
+@kbd{C-n} etc.@: is confined to the regularly accessible buffer
+positions. However, killing and yanking still operate on the
+rectangle spanned by point and mark. Also @kbd{C-x C-x} still cycles
+through the corners of that rectangle, but only as far as these are at
+buffer positions that are regularly accessible.
+
+ As mentioned above, rectangle-mark-mode persists as long the region
+is active: If the region gets deactivated, rectangle-mark-mode gets
+deactivated as well. But with disabled Transient mark mode there is
+usually no active region that would get deactivated, and so you have
+to explicitly switch off rectangle-mark-mode when you no longer want
+to use it.
+
+ To experience all benefits of rectangle-mark-mode and the
+region-rectangle when Transient Mark mode is off, you can temporarily
+activate Transient Mark mode after enabling rectangle-mark-mode, for
+example, with @kbd{C-@key{SPC} C-@key{SPC}}. @xref{Disabled Transient
+Mark}.
I also replaced the somewhat unhelpful reference to parent node
"@xref{Killing}" further up by references to sibling nodes:
so in a rectangular fashion, and killing and yanking operate on the
-rectangle. @xref{Killing}. The mode persists only as long as the
-region is active.
+rectangle. @xref{Deletion and Killing}, @ref{Yanking}. The mode
+persists only as long as the region is active.
* Fix B: Use a Minor Mode Lighter
With TMM off and RMM on, the most important indicator of RMM (the
region-rectangle) is not visible. And since RMM's minor mode lighter is
nil, one has no visible feedback of it still being active. That can be
surprising since some of its features are still active as described
above.
I tried to improve that by using a minor mode lighter that goes on only
if TMM is off, like this:
+(defvar rectangle-mark-mode-lighter nil
+ "Lighter displayed for `rectangle-mark-mode'.")
+
;;;###autoload
(define-minor-mode rectangle-mark-mode
"Toggle the region as rectangular.
Activates the region if it's inactive and Transient Mark mode is
on. Only lasts until the region is next deactivated."
- :lighter nil
+ :lighter rectangle-mark-mode-lighter
(rectangle--reset-crutches)
(when rectangle-mark-mode
+ ;; Make us more visible when Transient Mark mode is off and there
+ ;; is no rectangle (bug#XXXXX).
+ (setq rectangle-mark-mode-lighter
+ (and (not transient-mark-mode) " Rect"))
* Fix C: Mark RMM Movement Commands as Shift-Selectable
Finally, to make RMM better usable with shift-select-mode, I added the
necessary interactive specifiers to the RMM-specific movement commands
rectangle-right-char
rectangle-left-char
rectangle-forward-char
rectangle-backward-char
rectangle-next-line
rectangle-previous-line
Please review.
Thanks.
[-- Attachment #2: 0001-29-Improve-rectangle-mark-mode-when-transient-mark-mode.patch --]
[-- Type: text/x-patch, Size: 2900 bytes --]
From 6d7d83f158c3371e59877e02b88c38c664cb0ff9 Mon Sep 17 00:00:00 2001
From: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
Date: Wed, 25 Oct 2023 21:32:17 +0200
Subject: [PATCH] Improve rectangle-mark-mode when transient-mark-mode is off
* doc/emacs/killing.texi (Rectangles): Add documentation on specifics
of rectangle-mark-mode when transient-mark-mode is off.
---
doc/emacs/killing.texi | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 47e0b5e37ae..e6a8fe2848e 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -939,13 +939,8 @@ Rectangles
(first activating the region if necessary). When this mode is enabled,
commands that resize the region (@kbd{C-f}, @kbd{C-n} etc.)@: do
so in a rectangular fashion, and killing and yanking operate on the
-rectangle. @xref{Killing}. The mode persists only as long as the
-region is active.
-
-The region-rectangle works only when the mark is active. In
-particular, when Transient Mark mode is off (@pxref{Disabled Transient
-Mark}), in addition to typing @kbd{C-x @key{SPC}} you will need to
-activate the mark.
+rectangle. @xref{Deletion and Killing}, @ref{Yanking}. The mode
+persists only as long as the region is active.
Unlike the standard region, the region-rectangle can have its corners
extended past the end of buffer, or inside stretches of white space
@@ -962,6 +957,29 @@ Rectangles
to modify the dimensions of the region-rectangle before invoking an
operation on the marked text.
+ rectangle-mark-mode behaves in a slightly different way when
+Transient Mark mode is off (@pxref{Disabled Transient Mark}). In this
+case, when you enable rectangle-mark-mode, the region-rectangle is not
+automatically enabled. Accordingly, cursor movement with @kbd{C-f},
+@kbd{C-n} etc.@: is confined to the regularly accessible buffer
+positions. However, killing and yanking still operate on the
+rectangle spanned by point and mark. Also @kbd{C-x C-x} still cycles
+through the corners of that rectangle, but only as far as these are at
+buffer positions that are regularly accessible.
+
+ As mentioned above, rectangle-mark-mode persists as long the region
+is active: If the region gets deactivated, rectangle-mark-mode gets
+deactivated as well. But with disabled Transient mark mode there is
+usually no active region that would get deactivated, and so you have
+to explicitly switch off rectangle-mark-mode when you no longer want
+to use it.
+
+ To experience all benefits of rectangle-mark-mode and the
+region-rectangle when Transient Mark mode is off, you can temporarily
+activate Transient Mark mode after enabling rectangle-mark-mode, for
+example, with @kbd{C-@key{SPC} C-@key{SPC}}. @xref{Disabled Transient
+Mark}.
+
@node CUA Bindings
@section CUA Bindings
@findex cua-mode
--
2.30.2
[-- Attachment #3: 0001-30-Improve-rectangle-mark-mode-when-transient-mark-mode.patch --]
[-- Type: text/x-patch, Size: 3445 bytes --]
From 2edc489f4f82a72b91624a779f06b488e586507f Mon Sep 17 00:00:00 2001
From: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
Date: Wed, 25 Oct 2023 22:36:15 +0200
Subject: [PATCH] Improve rectangle-mark-mode when transient-mark-mode is off
* lisp/rect.el (rectangle-mark-mode-lighter): Add new variable ...
(rectangle-mark-mode): ... and use it here to make rectangle-mark-mode
more visible.
(rectangle-right-char, rectangle-left-char, rectangle-forward-char)
(rectangle-backward-char, rectangle-next-line)
(rectangle-previous-line): Declare as shift-translatable motion
commands.
---
lisp/rect.el | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/lisp/rect.el b/lisp/rect.el
index 8dc188b1de0..f0b5a9b806a 100644
--- a/lisp/rect.el
+++ b/lisp/rect.el
@@ -646,15 +646,22 @@ rectangle-mark-mode-map
"<remap> <next-line>" #'rectangle-next-line
"<remap> <previous-line>" #'rectangle-previous-line)
+(defvar rectangle-mark-mode-lighter nil
+ "Lighter displayed for `rectangle-mark-mode'.")
+
;;;###autoload
(define-minor-mode rectangle-mark-mode
"Toggle the region as rectangular.
Activates the region if it's inactive and Transient Mark mode is
on. Only lasts until the region is next deactivated."
- :lighter nil
+ :lighter rectangle-mark-mode-lighter
(rectangle--reset-crutches)
(when rectangle-mark-mode
+ ;; Make us more visible when Transient Mark mode is off and there
+ ;; is no rectangle (bug#XXXXX).
+ (setq rectangle-mark-mode-lighter
+ (and (not transient-mark-mode) " Rect"))
(advice-add 'region-beginning :around #'rectangle--region-beginning)
(advice-add 'region-end :around #'rectangle--region-end)
(add-hook 'deactivate-mark-hook
@@ -727,29 +734,29 @@ rectangle--*-char
(defun rectangle-right-char (&optional n)
"Like `right-char' but steps into wide chars and moves past EOL."
- (interactive "p") (rectangle--*-char #'right-char n #'left-char))
+ (interactive "^p") (rectangle--*-char #'right-char n #'left-char))
(defun rectangle-left-char (&optional n)
"Like `left-char' but steps into wide chars and moves past EOL."
- (interactive "p") (rectangle--*-char #'left-char n #'right-char))
+ (interactive "^p") (rectangle--*-char #'left-char n #'right-char))
(defun rectangle-forward-char (&optional n)
"Like `forward-char' but steps into wide chars and moves past EOL."
- (interactive "p") (rectangle--*-char #'forward-char n #'backward-char))
+ (interactive "^p") (rectangle--*-char #'forward-char n #'backward-char))
(defun rectangle-backward-char (&optional n)
"Like `backward-char' but steps into wide chars and moves past EOL."
- (interactive "p") (rectangle--*-char #'backward-char n #'forward-char))
+ (interactive "^p") (rectangle--*-char #'backward-char n #'forward-char))
(defun rectangle-next-line (&optional n)
"Like `next-line' but steps into wide chars and moves past EOL.
Ignores `line-move-visual'."
- (interactive "p")
+ (interactive "^p")
(let ((col (rectangle--point-col (point))))
(forward-line n)
(rectangle--col-pos col 'point)))
(defun rectangle-previous-line (&optional n)
"Like `previous-line' but steps into wide chars and moves past EOL.
Ignores `line-move-visual'."
- (interactive "p")
+ (interactive "^p")
(let ((col (rectangle--point-col (point))))
(forward-line (- n))
(rectangle--col-pos col 'point)))
--
2.30.2
next reply other threads:[~2023-10-27 20:31 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-27 20:31 Jens Schmidt via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2023-10-28 6:24 ` bug#66780: [PATCH] Improve rectangle-mark-mode when transient-mark-mode is off Eli Zaretskii
2023-10-28 10:50 ` Jens Schmidt via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-10-28 10:58 ` Eli Zaretskii
2023-10-28 12:51 ` Jens Schmidt via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-10-28 13:17 ` Eli Zaretskii
2023-10-28 16:36 ` Jens Schmidt via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-10-28 16:47 ` Eli Zaretskii
2023-10-28 18:30 ` Jens Schmidt via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-10-28 18:48 ` Eli Zaretskii
2023-10-29 14:49 ` Jens Schmidt via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-02 6:33 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0b1f5f23-b683-4367-beae-332a8d850d32@vodafonemail.de \
--to=bug-gnu-emacs@gnu.org \
--cc=66780@debbugs.gnu.org \
--cc=jschmidt4gnu@vodafonemail.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).