From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#45837: 28.0.50; incorrect cursor position in visual-line-mode when word-wrap-by-category is t Date: Thu, 14 Jan 2021 15:51:47 +0200 Message-ID: <83v9bzbp8s.fsf@gnu.org> References: <838s8wdhbf.fsf@gnu.org> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="23163"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 45837@debbugs.gnu.org To: Liu Hui Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Jan 14 14:59:28 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1l039s-0005vp-DF for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 14 Jan 2021 14:59:28 +0100 Original-Received: from localhost ([::1]:36430 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l039r-0001cj-Dy for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 14 Jan 2021 08:59:27 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56710) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l033h-0003PT-3J for bug-gnu-emacs@gnu.org; Thu, 14 Jan 2021 08:53:05 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:54217) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l033e-0003sq-PZ for bug-gnu-emacs@gnu.org; Thu, 14 Jan 2021 08:53:04 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1l033e-0003zg-Ni for bug-gnu-emacs@gnu.org; Thu, 14 Jan 2021 08:53:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 14 Jan 2021 13:53:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 45837 X-GNU-PR-Package: emacs Original-Received: via spool by 45837-submit@debbugs.gnu.org id=B45837.161063232115245 (code B ref 45837); Thu, 14 Jan 2021 13:53:02 +0000 Original-Received: (at 45837) by debbugs.gnu.org; 14 Jan 2021 13:52:01 +0000 Original-Received: from localhost ([127.0.0.1]:37526 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l032e-0003xf-Pn for submit@debbugs.gnu.org; Thu, 14 Jan 2021 08:52:01 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:35076) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1l032a-0003xP-St for 45837@debbugs.gnu.org; Thu, 14 Jan 2021 08:51:59 -0500 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:50722) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l032T-0003PT-Bz; Thu, 14 Jan 2021 08:51:51 -0500 Original-Received: from 84.94.185.95.cable.012.net.il ([84.94.185.95]:4427 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1l032S-0003Kr-LK; Thu, 14 Jan 2021 08:51:49 -0500 In-Reply-To: (message from Liu Hui on Thu, 14 Jan 2021 12:51:12 +0800) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:197945 Archived-At: > From: Liu Hui > Date: Thu, 14 Jan 2021 12:51:12 +0800 > Cc: 45837@debbugs.gnu.org > > BTW, in the case above, if the line wraps after a non-whitespace > character, C-k does not delete this character. How about the following > change to kill-visual-line? Yes, good catch. However, this is not entirely right, as the code you suggest should be _instead_ of skipping the whitespace that follows, not _in_addition_ to it (imagine that the line is wrapped at a non-whitespace character followed by whitespace). And while looking into adapting your patch to avoid removing more than the user intended, I found more issues with the existing code. So I'm proposing the patch below instead, which should correctly handle the following use cases: . visual line that ends in one or more whitespace characters, and the following visual line begins with one or more whitespace characters . visual line that ends with a non-whitespace character (under word-wrap-by-category) that is followed by one or more whitespace characters . line that is continued on the next visual line (visual-line-mode is off) . visual line that is wrapped in the middle of a display string or an overlay string with embedded whitespace characters . visual line that is wrapped in the middle of intangible text (The patch also fixes some minor issues with the documentation of this command.) WDYT? diff --git a/lisp/simple.el b/lisp/simple.el index 54c35c04be..e7421c069f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5606,7 +5606,9 @@ zap-to-char ;; kill-line and its subroutines. (defcustom kill-whole-line nil - "If non-nil, `kill-line' with no arg at start of line kills the whole line." + "If non-nil, `kill-line' with no arg at start of line kills the whole line. +This variable also affects `kill-visual-line' in the same way as +it does `kill-line'." :type 'boolean :group 'killing) @@ -7319,6 +7321,9 @@ kill-visual-line If ARG is zero, kill the text before point on the current visual line. +If `kill-whole-line' is non-nil, and this command is invoked at +start of a line that ands in a newline, kill the newline as well. + If you want to append the killed line to the last killed text, use \\[append-next-kill] before \\[kill-line]. @@ -7331,18 +7336,26 @@ kill-visual-line ;; Like in `kill-line', it's better to move point to the other end ;; of the kill before killing. (let ((opoint (point)) - (kill-whole-line (and kill-whole-line (bolp)))) + (kill-whole-line (and kill-whole-line (bolp))) + (orig-y (cdr (nth 2 (posn-at-point))))) (if arg (vertical-motion (prefix-numeric-value arg)) (end-of-visual-line 1) (if (= (point) opoint) (vertical-motion 1) - ;; Skip any trailing whitespace at the end of the visual line. - ;; We used to do this only if `show-trailing-whitespace' is - ;; nil, but that's wrong; the correct thing would be to check - ;; whether the trailing whitespace is highlighted. But, it's - ;; OK to just do this unconditionally. - (skip-chars-forward " \t"))) + ;; The first condition below verifies we are still on the same + ;; screen line, i.e. that the line isn't continued, and that + ;; end-of-visual-line didn't overshoot due to complications + ;; like display or overlay strings, intangible text, etc.: + ;; otherwise, we don't want to kill a character that's + ;; unrelated to the place where the visual line wrapped. + (and (= (cdr (nth 2 (posn-at-point))) orig-y) + ;; Make sure we delete the character where the line wraps + ;; under visual-line-mode. + (or (looking-at-p "[ \t]") + (and word-wrap-by-category + (aref (char-category-set (following-char)) ?\|))) + (forward-char)))) (kill-region opoint (if (and kill-whole-line (= (following-char) ?\n)) (1+ (point)) (point)))))