GNU bug report logs -
#65734
29.1.50; kill-whole-line and visibility of Org subtrees
Previous Next
Reported by: Sebastian Miele <iota <at> whxvd.name>
Date: Mon, 4 Sep 2023 14:49:02 UTC
Severity: normal
Found in version 29.1.50
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
Full log
Message #20 received at 65734 <at> debbugs.gnu.org (full text, mbox):
> From: Eli Zaretskii <eliz <at> gnu.org>
> Date: Tue, 2023-09-05 14:54 +0300
>
> […]
>
> So we could decide that this command needs to become smarter when the
> visual line includes invisible text. That is, improve the command
> without making any Org-specific changes anywhere. Patches to that
> effect are welcome.
The following would do it. I think I tested it rather thoroughly.
During testing I found another bug that is addressed by the let-binding
of kill-read-only-ok during the first kill-region below.
diff --git a/lisp/simple.el b/lisp/simple.el
index abd587245fe..d983cb85ab3 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -6631,28 +6631,50 @@ kill-whole-line
(unless (eq last-command 'kill-region)
(kill-new "")
(setq last-command 'kill-region))
- (cond ((zerop arg)
- ;; We need to kill in two steps, because the previous command
- ;; could have been a kill command, in which case the text
- ;; before point needs to be prepended to the current kill
- ;; ring entry and the text after point appended. Also, we
- ;; need to use save-excursion to avoid copying the same text
- ;; twice to the kill ring in read-only buffers.
- (save-excursion
- (kill-region (point) (progn (forward-visible-line 0) (point))))
- (kill-region (point) (progn (end-of-visible-line) (point))))
- ((< arg 0)
- (save-excursion
- (kill-region (point) (progn (end-of-visible-line) (point))))
- (kill-region (point)
- (progn (forward-visible-line (1+ arg))
- (unless (bobp) (backward-char))
- (point))))
- (t
- (save-excursion
- (kill-region (point) (progn (forward-visible-line 0) (point))))
- (kill-region (point)
- (progn (forward-visible-line arg) (point))))))
+ ;; - We need to kill in two steps, because the previous command
+ ;; could have been a kill command, in which case the text before
+ ;; point needs to be prepended to the current kill ring entry and
+ ;; the text after point appended.
+ ;; - We need to be careful to avoid copying text twice to the kill
+ ;; ring in read-only buffers.
+ ;; - We need to determine the boundaries of visible lines before we
+ ;; do the first kill, because that may change visibility
+ ;; (bug#65734).
+ (let ((regions-begin (point-marker))
+ region1-end)
+ (cond ((zerop arg)
+ (setq region1-end (save-excursion
+ (forward-visible-line 0)
+ (point-marker)))
+ (end-of-visible-line))
+ ((< arg 0)
+ (setq region1-end (save-excursion
+ (end-of-visible-line)
+ (point-marker)))
+ (forward-visible-line (1+ arg))
+ (unless (bobp) (backward-char)))
+ (t
+ (setq region1-end (save-excursion
+ (forward-visible-line 0)
+ (point-marker)))
+ (progn (forward-visible-line arg))))
+ ;; - Pass the marker positions and not the markers themselves.
+ ;; kill-region determines whether to prepend or append to a
+ ;; previous kill by checking the direction of the region. But
+ ;; it deletes the content and hence moves the markers before
+ ;; that. That effectively makes every region delimited by
+ ;; markers an (empty) forward region.
+ ;; - Make the first kill-region emit a non-local exit only if the
+ ;; second kill-region below would not operate on a non-empty
+ ;; region.
+ (let ((kill-read-only-ok (or kill-read-only-ok
+ (/= regions-begin (point)))))
+ (kill-region (marker-position regions-begin)
+ (marker-position region1-end)))
+ (kill-region (marker-position regions-begin)
+ (point))
+ (set-marker regions-begin nil)
+ (set-marker region1-end nil)))
(defun forward-visible-line (arg)
"Move forward by ARG lines, ignoring currently invisible newlines only.
This bug report was last modified 329 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.