aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Miele2024-06-19 15:48:59 +0200
committerEli Zaretskii2024-06-27 10:48:18 +0300
commit058bb4ca25adb8f4bf78cc0f09a65d730dbd797d (patch)
tree8c361b2ac539898c038903439a6ee18da67086a6
parente45173d114e37d5a652b5393ce7bcab1acea3f1a (diff)
downloademacs-058bb4ca25adb8f4bf78cc0f09a65d730dbd797d.tar.gz
emacs-058bb4ca25adb8f4bf78cc0f09a65d730dbd797d.zip
kill-whole-line: Honor visibility; fix kill-ring when read-only (bug#65734)
* lisp/simple.el (kill-whole-line): Use visibility state before performing any edits as reference instead of expecting that visibility cannot change. First of the two calls to `kill-region' may trigger `after-change-functions' that might alter the visibility state. Make sure that we populate the `kill-ring' with the contents of the whole line when buffer is in `read-only-mode'.
-rw-r--r--lisp/simple.el69
1 files changed, 47 insertions, 22 deletions
diff --git a/lisp/simple.el b/lisp/simple.el
index c798ee010b1..17625fad66f 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -6703,28 +6703,53 @@ If ARG is zero, kill current line but exclude the trailing newline."
6703 (unless (eq last-command 'kill-region) 6703 (unless (eq last-command 'kill-region)
6704 (kill-new "") 6704 (kill-new "")
6705 (setq last-command 'kill-region)) 6705 (setq last-command 'kill-region))
6706 (cond ((zerop arg) 6706 ;; - We need to kill in two steps, because the previous command
6707 ;; We need to kill in two steps, because the previous command 6707 ;; could have been a kill command, in which case the text before
6708 ;; could have been a kill command, in which case the text 6708 ;; point needs to be prepended to the current kill ring entry and
6709 ;; before point needs to be prepended to the current kill 6709 ;; the text after point appended.
6710 ;; ring entry and the text after point appended. Also, we 6710 ;; - We need to be careful to avoid copying text twice to the kill
6711 ;; need to use save-excursion to avoid copying the same text 6711 ;; ring in read-only buffers.
6712 ;; twice to the kill ring in read-only buffers. 6712 ;; - We need to determine the boundaries of visible lines before we
6713 (save-excursion 6713 ;; do the first kill. Otherwise `after-change-functions' may
6714 (kill-region (point) (progn (forward-visible-line 0) (point)))) 6714 ;; change visibility (bug#65734).
6715 (kill-region (point) (progn (end-of-visible-line) (point)))) 6715 (let (;; The beginning of both regions to kill
6716 ((< arg 0) 6716 (regions-begin (point-marker))
6717 (save-excursion 6717 ;; The end of the first region to kill. Moreover, after
6718 (kill-region (point) (progn (end-of-visible-line) (point)))) 6718 ;; evaluation of the value form, (point) will be the end of
6719 (kill-region (point) 6719 ;; the second region to kill.
6720 (progn (forward-visible-line (1+ arg)) 6720 (region1-end (cond ((zerop arg)
6721 (unless (bobp) (backward-char)) 6721 (prog1 (save-excursion
6722 (point)))) 6722 (forward-visible-line 0)
6723 (t 6723 (point-marker))
6724 (save-excursion 6724 (end-of-visible-line)))
6725 (kill-region (point) (progn (forward-visible-line 0) (point)))) 6725 ((< arg 0)
6726 (kill-region (point) 6726 (prog1 (save-excursion
6727 (progn (forward-visible-line arg) (point)))))) 6727 (end-of-visible-line)
6728 (point-marker))
6729 (forward-visible-line (1+ arg))
6730 (unless (bobp) (backward-char))))
6731 (t
6732 (prog1 (save-excursion
6733 (forward-visible-line 0)
6734 (point-marker))
6735 (forward-visible-line arg))))))
6736 ;; - Pass the marker positions and not the markers themselves.
6737 ;; kill-region determines whether to prepend or append to a
6738 ;; previous kill by checking the direction of the region. But
6739 ;; it deletes the content and hence moves the markers before
6740 ;; that. That effectively makes every region delimited by
6741 ;; markers an (empty) forward region.
6742 ;; - Make the first kill-region emit a non-local exit only if the
6743 ;; second kill-region below would not operate on a non-empty
6744 ;; region.
6745 (let ((kill-read-only-ok (or kill-read-only-ok
6746 (/= regions-begin (point)))))
6747 (kill-region (marker-position regions-begin)
6748 (marker-position region1-end)))
6749 (kill-region (marker-position regions-begin)
6750 (point))
6751 (set-marker regions-begin nil)
6752 (set-marker region1-end nil)))
6728 6753
6729(defun forward-visible-line (arg) 6754(defun forward-visible-line (arg)
6730 "Move forward by ARG lines, ignoring currently invisible newlines only. 6755 "Move forward by ARG lines, ignoring currently invisible newlines only.