unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* yank-pop problem
@ 2015-08-06  7:38 Frederik Eaton
  2015-08-06 23:49 ` Frederik Eaton
  2021-05-26 22:53 ` bug#21199: " Lars Ingebrigtsen
  0 siblings, 2 replies; 3+ messages in thread
From: Frederik Eaton @ 2015-08-06  7:38 UTC (permalink / raw)
  To: help-gnu-emacs; +Cc: bug-gnu-emacs

Dear Help-Gnu-Emacs,

I was chatting on the #emacs freenode.net IRC channel and thought to
ask people about a long-standing annoyance I've had with Emacs. One
IRC user was horrified that I would find anything wrong with Emacs,
but another user suggested that I write up a document with the details
and send it as a bug report. So I wrote up a document which explains
the issue and how I think it should be fixed. I'm pasting it below and
would appreciate your comments. Mostly I'm looking to see if anyone
else has previously implemented this suggestion, and is willing to
share their code. I hope my thoughts are explained clearly enough.

Thanks!

Frederick

P.S. I Cc'ed bug-gnu-emacs@gnu.org because I figured problems go
there, but I haven't subscribed to that list and I'm not really
expecting the core of Emacs to be changed.

P.P.S. After writing this (typically of me) I just noticed that
somebody else posted this problem on stackoverflow.com in 2011!
However, none of the solutions posted there are really suitable in my
opinion. The basic problem, which is that Emacs puts stuff you don't
care about in the kill ring ahead of stuff that you do care about,
isn't ever fixed. Although the first ("jp/yank") solution is nearly
good enough, it still allows text we care about to get clobbered if
there is an intervening yank...

http://stackoverflow.com/questions/5823495/emacs-how-to-yank-the-last-yanked-text-regardless-of-subsequent-kills



----------------------------------------------------------------

Emacs Yank Pointer Problem Description

Problem:

In Emacs, I can use C-y (yank) and then M-y (yank-pop) to go through a
list of recent bits of text which have been killed.

Having done this, the next time I do C-y, it yanks the last bit of
text selected via M-y. This is desired since it means I don't have to
rotate through the list to find my favorite item again. This behavior
is implemented using the variable "kill-ring-yank-pointer" which
points to the last "yank-pop"ed item in the kill ring.

However, when I kill some text, the value of "kill-ring-yank-pointer"
is reset to point to the head of the "kill ring". This resetting means
that when I am interspersing a number of yanks (of the same item of
text) with an editing command such as M-d which also populates the
kill ring, then my "kill-ring-yank-pointer" is reset each time, and
each time I yank, I have to search farther and farther back with an
increasing number of M-y keystrokes, just to get the same item I've
been yanking.

In short, when (say) I am replacing a few strings manually with some
text from the kill ring, I end up doing C-y, then for the next
replacement C-y M-y, then next C-y M-y M-y, and next C-y M-y M-y M-y,
and so on.

I'll give a concrete tutorial. Try replacing every animal in the
following list with "dog", using only "M-d" and "C-y" and "M-y", and
"C-a" and "C-n".

dog
cat
ant
chicken

The kill ring will first look like ("dog"), then ("cat" "dog"), then
("ant" "cat" "dog"), then ("chicken" "ant" "cat" "dog"). After the
final yank-pop of each line, the kill-ring-yank-pointer will point to
"dog" at the end of the kill ring. However, when you use M-d to delete
the animal being replaced, then kill-ring-yank-pointer gets reset, and
so it is never used.


Proposed solution:

The kill ring, which is a list, should be treated as an array by
yank-pop, and rearranged more freely.

Killing text should still put stuff at the front of the list, as
before.

However, each yank-pop'ed item will also be moved to the front of the
kill ring.

Yank-pop should use a new variable to serve the purpose of
"kill-ring-yank-pointer". Rather than pointing to an existing item in
the kill ring, the new variable will be an index into the kill ring,
which just tells yank-pop how to fix up the kill ring in case the last
command was yank-pop. For example, suppose the kill ring looks like
this:

(I) A B C D E

C-y M-y M-y will end up with C being inserted at the cursor. After
that, we DON'T want the kill ring to look like "C D E A B" because we
care more about A and B than about D or E, as they are more recently
used items. What we do want it to look like is

(II) C A B D E

But suppose the next command is also M-y. Then the kill ring should
look like

(III) D A B C E

because we care more about A and B than about C (since C we saw only
on our way to D, and didn't end up using it). In order to obtain this
configuration, yank-pop will have to have inserted C back where it
came from, and moved D to the front. It would presumably do this with
an integer variable which is incremented at each yank-pop, and reset
to 0 in the 'yank' command, to guide the insertion and extraction of
elements from the kill ring.

To be specific, let's call the new variable
"kill-ring-yank-pop-index". In state (I) above,
"kill-ring-yank-pop-index" could have an arbitrary value, but it is
reset to zero by "yank". In state (II) above, it would have the value
2 to indicate that C came from position 2 in the (zero-indexed) kill
ring. In state (III), it would have value 3 - at that point, yank-pop
will have read the value 2 from "kill-ring-yank-pop-index", used that
to put C back into the list at position 2, moved D to the front, and
incremented the value to 3.

The END.



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: yank-pop problem
  2015-08-06  7:38 yank-pop problem Frederik Eaton
@ 2015-08-06 23:49 ` Frederik Eaton
  2021-05-26 22:53 ` bug#21199: " Lars Ingebrigtsen
  1 sibling, 0 replies; 3+ messages in thread
From: Frederik Eaton @ 2015-08-06 23:49 UTC (permalink / raw)
  To: help-gnu-emacs; +Cc: bug-gnu-emacs

I just coded up a solution and posted it under "A Better Yank-Pop
Implementation" in the stackoverflow thread:

http://stackoverflow.com/questions/5823495/emacs-how-to-yank-the-last-yanked-text-regardless-of-subsequent-kills

On Thu, Aug 06, 2015 at 12:38:31AM -0700, Frederik Eaton wrote:
> Dear Help-Gnu-Emacs,
> 
> I was chatting on the #emacs freenode.net IRC channel and thought to
> ask people about a long-standing annoyance I've had with Emacs. One
> IRC user was horrified that I would find anything wrong with Emacs,
> but another user suggested that I write up a document with the details
> and send it as a bug report. So I wrote up a document which explains
> the issue and how I think it should be fixed. I'm pasting it below and
> would appreciate your comments. Mostly I'm looking to see if anyone
> else has previously implemented this suggestion, and is willing to
> share their code. I hope my thoughts are explained clearly enough.
> 
> Thanks!
> 
> Frederick
> 
> P.S. I Cc'ed bug-gnu-emacs@gnu.org because I figured problems go
> there, but I haven't subscribed to that list and I'm not really
> expecting the core of Emacs to be changed.
> 
> P.P.S. After writing this (typically of me) I just noticed that
> somebody else posted this problem on stackoverflow.com in 2011!
> However, none of the solutions posted there are really suitable in my
> opinion. The basic problem, which is that Emacs puts stuff you don't
> care about in the kill ring ahead of stuff that you do care about,
> isn't ever fixed. Although the first ("jp/yank") solution is nearly
> good enough, it still allows text we care about to get clobbered if
> there is an intervening yank...
> 
> http://stackoverflow.com/questions/5823495/emacs-how-to-yank-the-last-yanked-text-regardless-of-subsequent-kills
> 
> 
> 
> ----------------------------------------------------------------
> 
> Emacs Yank Pointer Problem Description
> 
> Problem:
> 
> In Emacs, I can use C-y (yank) and then M-y (yank-pop) to go through a
> list of recent bits of text which have been killed.
> 
> Having done this, the next time I do C-y, it yanks the last bit of
> text selected via M-y. This is desired since it means I don't have to
> rotate through the list to find my favorite item again. This behavior
> is implemented using the variable "kill-ring-yank-pointer" which
> points to the last "yank-pop"ed item in the kill ring.
> 
> However, when I kill some text, the value of "kill-ring-yank-pointer"
> is reset to point to the head of the "kill ring". This resetting means
> that when I am interspersing a number of yanks (of the same item of
> text) with an editing command such as M-d which also populates the
> kill ring, then my "kill-ring-yank-pointer" is reset each time, and
> each time I yank, I have to search farther and farther back with an
> increasing number of M-y keystrokes, just to get the same item I've
> been yanking.
> 
> In short, when (say) I am replacing a few strings manually with some
> text from the kill ring, I end up doing C-y, then for the next
> replacement C-y M-y, then next C-y M-y M-y, and next C-y M-y M-y M-y,
> and so on.
> 
> I'll give a concrete tutorial. Try replacing every animal in the
> following list with "dog", using only "M-d" and "C-y" and "M-y", and
> "C-a" and "C-n".
> 
> dog
> cat
> ant
> chicken
> 
> The kill ring will first look like ("dog"), then ("cat" "dog"), then
> ("ant" "cat" "dog"), then ("chicken" "ant" "cat" "dog"). After the
> final yank-pop of each line, the kill-ring-yank-pointer will point to
> "dog" at the end of the kill ring. However, when you use M-d to delete
> the animal being replaced, then kill-ring-yank-pointer gets reset, and
> so it is never used.
> 
> 
> Proposed solution:
> 
> The kill ring, which is a list, should be treated as an array by
> yank-pop, and rearranged more freely.
> 
> Killing text should still put stuff at the front of the list, as
> before.
> 
> However, each yank-pop'ed item will also be moved to the front of the
> kill ring.
> 
> Yank-pop should use a new variable to serve the purpose of
> "kill-ring-yank-pointer". Rather than pointing to an existing item in
> the kill ring, the new variable will be an index into the kill ring,
> which just tells yank-pop how to fix up the kill ring in case the last
> command was yank-pop. For example, suppose the kill ring looks like
> this:
> 
> (I) A B C D E
> 
> C-y M-y M-y will end up with C being inserted at the cursor. After
> that, we DON'T want the kill ring to look like "C D E A B" because we
> care more about A and B than about D or E, as they are more recently
> used items. What we do want it to look like is
> 
> (II) C A B D E
> 
> But suppose the next command is also M-y. Then the kill ring should
> look like
> 
> (III) D A B C E
> 
> because we care more about A and B than about C (since C we saw only
> on our way to D, and didn't end up using it). In order to obtain this
> configuration, yank-pop will have to have inserted C back where it
> came from, and moved D to the front. It would presumably do this with
> an integer variable which is incremented at each yank-pop, and reset
> to 0 in the 'yank' command, to guide the insertion and extraction of
> elements from the kill ring.
> 
> To be specific, let's call the new variable
> "kill-ring-yank-pop-index". In state (I) above,
> "kill-ring-yank-pop-index" could have an arbitrary value, but it is
> reset to zero by "yank". In state (II) above, it would have the value
> 2 to indicate that C came from position 2 in the (zero-indexed) kill
> ring. In state (III), it would have value 3 - at that point, yank-pop
> will have read the value 2 from "kill-ring-yank-pop-index", used that
> to put C back into the list at position 2, moved D to the front, and
> incremented the value to 3.
> 
> The END.
> 



^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#21199: yank-pop problem
  2015-08-06  7:38 yank-pop problem Frederik Eaton
  2015-08-06 23:49 ` Frederik Eaton
@ 2021-05-26 22:53 ` Lars Ingebrigtsen
  1 sibling, 0 replies; 3+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-26 22:53 UTC (permalink / raw)
  To: Frederik Eaton; +Cc: 21199

Frederik Eaton <frederik@ofb.net> writes:

> Killing text should still put stuff at the front of the list, as
> before.
>
> However, each yank-pop'ed item will also be moved to the front of the
> kill ring.

(I'm going through old bug reports that unfortunately got no response at
the time.)

People have wildly differing usage patterns for killing/yanking, and
there's a bunch of different packages for customising how yanking is to
be performed.  But I don't think it would be appropriate to change how
the built-in yanking is done here -- it would annoy too many people, no
matter how you do it.

(In the concrete example you're describing, I think many people just use
registers instead, because the kill ring is too ephemeral.)

So I'm closing this bug report -- this is best left to different
packages to implement.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-05-26 22:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-06  7:38 yank-pop problem Frederik Eaton
2015-08-06 23:49 ` Frederik Eaton
2021-05-26 22:53 ` bug#21199: " Lars Ingebrigtsen

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).