Subject: Re: bug#79197: [PATCH] ; * lisp/simple.el (yank): Update docstring., Re: bug#79197: [PATCH] ; * lisp/simple.el (yank): Update docstring., Re: bug#79197: [PATCH] ; * lisp/simple.el (yank): Update docstring.

From: James Thomas <[email-masked]>
Date: Mon, 11 Aug 2025 18:37:38 +0530

Eli Zaretskii <[email-masked]> writes:

>> From: James Thomas <>
>> Cc: [email-masked],  [email-masked]
>> Date: Mon, 11 Aug 2025 11:01:35 +0530
>> 
>> >   (insert-for-yank (current-kill (cond
>> > 				  ((listp arg) 0)
>> > 				  ((eq arg '-) -2)
>> > 				  (t (1- arg)))))
>> 
>> Eli Zaretskii <[email-masked]> writes:
>> 
>> >> Cc: [email-masked]
>> >> Date: Sat, 09 Aug 2025 09:15:50 +0300
>> >> From: Eli Zaretskii <[email-masked]>
>> >> 
>> >> Your patch is the exact opposite of commit 8e5d85ffc0, and will make
>> >> "C-u -" produce a different effect from "C-u - 1", which is very
>> >> surprising.  So at least we need to also change the handling of
>> >> negative numerical argument as well, to make them consistent.
>> 
>> Here's my story:
>> 
>> In the kill-'ring', the position is only relative, not an absolute one
>> of the order in which kills were entered. The 'negative prefix' argument
>> yielding what it does seems to have been an attempt to get the 'earliest
>> kill available': which is ultimately doomed, because no such state is
>> stored specifically. Normally, -2 would give you that. But if the
>> kill-ring pointer is ever moved backward (by C-y, M-y ... or C-u <n>
>> C-y) the assumption breaks down.
>> 
>> >
>> > Oh, and when you look into this, please also consider what should be
>> > the meaning of a zero argument.
>> 
>> C-u 0 simply gives the 'next' kill. For instance, I often use: C-y, M-y
>> ... until I find the first one in a series of kills, then follow up with
>> C-u 0 C-y, ... to recreate the whole.
>
> OK, so given these observations, how do you propose to continue?  Do
> you have a patch to propose, either for the doc string or for the code
> or both? if so, please show the patch, and let's take it from there.

diff --git a/lisp/simple.el b/lisp/simple.el
index cd13e0a55f4..97701ead69d 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5758,9 +5758,10 @@ kill-new
 	  (setcar kill-ring string)
         (let ((history-delete-duplicates nil))
           (add-to-history 'kill-ring string kill-ring-max t))))
-    (setq kill-ring-yank-pointer kill-ring)
+    (prog1
+        (setq kill-ring-yank-pointer kill-ring)
     (if interprogram-cut-function
-        (funcall interprogram-cut-function string))))
+        (funcall interprogram-cut-function string)))))
 
 ;; It has been argued that this should work like `self-insert-command'
 ;; which merges insertions in `buffer-undo-list' in groups of 20
@@ -6399,7 +6400,8 @@ yank
   (push-mark)
   (insert-for-yank (current-kill (cond
 				  ((listp arg) 0)
-				  ((eq arg '-) -1)
+				  ((eq arg '-) (- (length kill-ring)
+                                                  (length kill-ring-yank-pointer)))
 				  (t (1- arg)))))
   (if (consp arg)
       ;; This is like exchange-point-and-mark, but doesn't activate the mark.

(Because the earlier one might've been malformed)

--