Package: emacs;
Reported by: frederik <at> ofb.net
Date: Thu, 6 Aug 2015 15:34:01 UTC
Severity: minor
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Frederik Eaton <frederik <at> ofb.net> To: help-gnu-emacs <at> gnu.org Cc: bug-gnu-emacs <at> gnu.org Subject: Re: yank-pop problem Date: Thu, 6 Aug 2015 16:49:43 -0700
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 <at> 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. >
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.