From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Luc Teirlinck Newsgroups: gmane.emacs.devel Subject: Re: Various simple.el patches Date: Tue, 20 May 2003 22:12:04 -0500 (CDT) Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <200305210312.h4L3C4907897@eel.dms.auburn.edu> References: <200305132031.h4DKVp58013718@rum.cs.yale.edu> <84llx9hhwp.fsf@lucy.is.informatik.uni-duisburg.de> <20030514124245.GA24487@gnu.org> <843cjhtytp.fsf@lucy.is.informatik.uni-duisburg.de> <20030514144839.GA6241@gnu.org> <844r3xr0ar.fsf@lucy.is.informatik.uni-duisburg.de> <84fznfzb9t.fsf@lucy.is.informatik.uni-duisburg.de> <84k7co464e.fsf@lucy.is.informatik.uni-duisburg.de> <84iss7mlgd.fsf@lucy.is.informatik.uni-duisburg.de> NNTP-Posting-Host: main.gmane.org X-Trace: main.gmane.org 1053486871 12275 80.91.224.249 (21 May 2003 03:14:31 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Wed, 21 May 2003 03:14:31 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Wed May 21 05:14:28 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19IK3g-0003Bo-00 for ; Wed, 21 May 2003 05:14:28 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 19IKEG-0001m4-00 for ; Wed, 21 May 2003 05:25:24 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.20) id 19IK45-0000a6-If for emacs-devel@quimby.gnus.org; Tue, 20 May 2003 23:14:53 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.20) id 19IK3U-0000CK-4Z for emacs-devel@gnu.org; Tue, 20 May 2003 23:14:16 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20) id 19IK2d-0005y2-Lh for emacs-devel@gnu.org; Tue, 20 May 2003 23:13:55 -0400 Original-Received: from manatee.dms.auburn.edu ([131.204.53.104]) by monty-python.gnu.org with esmtp (Exim 4.20) id 19IK1O-0004Un-M8 for emacs-devel@gnu.org; Tue, 20 May 2003 23:12:06 -0400 Original-Received: from eel.dms.auburn.edu (eel.dms.auburn.edu [131.204.53.108]) h4L3C2oc003698; Tue, 20 May 2003 22:12:02 -0500 (CDT) Original-Received: (from teirllm@localhost) by eel.dms.auburn.edu (8.11.6+Sun/8.11.6) id h4L3C4907897; Tue, 20 May 2003 22:12:04 -0500 (CDT) X-Authentication-Warning: eel.dms.auburn.edu: teirllm set sender to teirllm@dms.auburn.edu using -f Original-To: kai.grossjohann@gmx.net In-reply-to: <84iss7mlgd.fsf@lucy.is.informatik.uni-duisburg.de> (kai.grossjohann@gmx.net) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Emacs development discussions. List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:14031 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:14031 There are still problems with the present version of `kill-whole-line'. Start out with: word1 word2 and place point between word1 and word2. Now S- C-y yields: word2 (followed by a newline) M-0 S- C-y yields: word2 (without newline) and M--1 S- C-y yields: word1 (without trailing space or newline) Makes no sense. The problem is that kill-region sets this-command to 'kill-region, but only when the command returns to the command loop will this result in last-command being set to 'kill-region and kill-region checks last-command to figure out whether to append or not. So we have to bind last-command to the appropriate value explicitly. The: ((< arg 0) (forward-visible-line 1) which I suggested to add has to be removed, since it moves point without killing, potentially messing up the kill ring. There goes the M-- S- C-x z z z z fun. Not the end of the problems. Things need to work out OK in read-only buffers. But there killed text does not really get removed and, as a result, it winds up getting copied twice in certain situations. Hence the need for save-excursion's. After all of this we wind up with version 1 of kill-whole-line below. That version works more or less OK, but some things seem less than ideal: 1. As already mentioned, the possibility of killing backward with M-- S- C-x z z z is gone. 2. The now more complex function gets very vulnerable to any possible future changes (including possible customization variables) in the not very primitive function kill-line. So on second thought, it might actually be better to write the function entirely in terms of kill-region after all. 3. Killing in read-only buffers turns out not to be either terribly convenient or terribly intuitive. Version 2 of the function (see below) seems to take care of all three problems. Maybe somewhat strange at first is that S- with a negative argument leaves point at the *end* of the preceding non killed line. But M-0 S- already leaves point at the end of a line in read-only buffers, even in version 1. I believe that the behavior of version 2 can easily be understood, by the user, in the following terms: with zero argument, point first moves to the beginning of the line and then the line gets killed without killing the newline. With positive argument, point also first moves to the beginning of the line and then a number of lines and the following newline are killed. With negative argument, point first moves to the end of the line and the killing ends with the kill of the last *preceding* newline. This way, the resulting behavior seems intuitive, even in read-only buffers. We can not really implement the function in this straightforward way, because that could severely mess up the kill ring. (This is what makes the actual implementation somewhat complicated.) But except for the fact that the kill ring gets handled correctly, the behavior is equivalent. I include below the two versions. They differ in behavior for negative arguments. Version 2 does not use kill-line. Once we decide on which version to use (1 or 2 or some other one), I will still do some further checking of that version in other situations, such as in the presence of invisible text, just to make sure. Personally, I prefer version 2. Version 1: ===File ~/kwlversion1======================================= (defun kill-whole-line (&optional arg) "Kill current line. With prefix arg, kill that many lines from point. If arg is negative, kill backwards. If arg is zero, kill current line but exclude the trailing newline." (interactive "P") (setq arg (prefix-numeric-value arg)) (cond ((zerop arg) (save-excursion (kill-region (point) (progn (forward-visible-line 0) (point)))) (let ((last-command (if (eq this-command 'kill-region) 'kill-region last-command))) (kill-region (point) (progn (end-of-visible-line) (point))))) ((< arg 0) (save-excursion (kill-line 1)) (let ((last-command (if (eq this-command 'kill-region) 'kill-region last-command))) (kill-line (1+ arg)))) (t (save-excursion (kill-line 0)) (if (eobp) (signal 'end-of-buffer nil)) (let ((last-command (if (eq this-command 'kill-region) 'kill-region last-command))) (kill-line arg))))) ============================================================ Version 2: ===File ~/kwlversion2======================================= (defun kill-whole-line (&optional arg) "Kill current line. With prefix arg, kill that many lines from point. If arg is negative, kill backwards. If arg is zero, kill current line but exclude the trailing newline." (interactive "P") (setq arg (prefix-numeric-value arg)) (cond ((zerop arg) (save-excursion (kill-region (point) (progn (forward-visible-line 0) (point)))) (let ((last-command (if (eq this-command 'kill-region) 'kill-region last-command))) (kill-region (point) (progn (end-of-visible-line) (point))))) ((< arg 0) (save-excursion (kill-region (point) (progn (end-of-visible-line) (point)))) (let ((last-command (if (eq this-command 'kill-region) 'kill-region last-command))) (kill-region (point) (progn (forward-visible-line (1+ arg)) (unless (bobp) (backward-char)) (point))))) (t (if (and (bolp) (eobp)) (signal 'end-of-buffer nil)) (save-excursion (kill-region (point) (progn (forward-visible-line 0) (point)))) (let ((last-command (if (eq this-command 'kill-region) 'kill-region last-command))) (kill-region (point) (progn (forward-visible-line arg) (point))))))) ============================================================