Re: address@hidden: Kill ring leak in winemacs macros]

> I'm still not convinced this change is worth making now. On X, even
> with clipboard enabled, the actual copying to the clipboard is only
> performed if another application requests it. Andrew Innes suggested
> many years ago that the W32 clipboard should work the same way, but
> noone has picked up that job yet. I don't know which way Mac does it,
> but that can probably be modified to use delayed copying if it does
> not already. So we are talking about reducing the functionality of
> keyboard macros to get around a performance problem that does not
> exist on the most important platforms, and that we know can be fixed
> on others.
The performance problem is entirely secondary (if it even exists); this is
a correctness problem. Consider a macro like, say, this:
C-e C-w C-f C-y C-s . RET
(which would shuffle chunks of lines around based on periods). Now set it
running enough times to take, say, 15 minutes of real time (unlikely for a
macro this simple, but just suppose). While waiting you naturally want to
do something else; you switch into Firefox and do some searches on the
emacs-devel archives. Finding a neat phrase to search for, you copy it.
Unbeknownst to you, Emacs had just finished doing `forward-char' and was
about to do `yank', which then gets your search string instead of whatever
was killed last. Now your text is corrupted, possibly irreversibly (if
the change falls off the end of the undo list and the mark ring before you
can try to recover it). Moreover, it's quite likely that before you can
paste your text, Emacs loops around and kills some more text; your
copy/paste in Firefox has also been broken.
Sorry if this is belaboring the point too much; I just wanted to explain
what the original issue really was.
That said:
Eric Peterson (the bug reporter) did also say that macros seemed slower on
W32 than on some Unix system, and attributed it to the actual
data-copying. I don't know if the slowdown is real, or if the clipboard
is to blame. However, I don't see how copying on W32 (to the clipboard)
can be made any faster, since the W32 clipboard functions much like the
old X cut buffers and is actually real data storage on the part of the
window system. I don't think there's a way to only interact with it "when
you have to", but I could be wrong.
Davis Herring
PS - Eric Peterson is cc'ed on this email in case he doesn't know the
issue is being resolved. Eric: there are several ways to fix this
(emacs-devel is currently deciding among them), and it should be a
customizable option in the next version of Emacs.
Until then, here's two workarounds (put them in your .emacs or so, bind
keys to them, whatever). The first function is self-contained and more
convenient, but if you have some reason to avoid recursive edits, use the
rest of it all together. Note that the "real" fix may look nothing like
this!
(defun private-kills-recursive-edit ()
"Disable interprogram cut and paste and do a recursive edit.
When the recursive edit finishes, any new text available from the window
system will be available for yanking."
(interactive)
(let (interprogram-cut-function interprogram-paste-function)
(recursive-edit)))
(defvar suspended-interprogram-functions nil
"\"Real\" interprogram functions, as a cons: (CUT . PASTE).")
(defun suspend-interprogram-kills ()
"Disable interprogram cut and paste (temporarily).
It can be re-enabled with `resume-interprogram-kills'."
(interactive)
(if suspended-interprogram-functions
(error "Interprogram kills already suspended")
(setq suspended-interprogram-functions
(cons interprogram-cut-function interprogram-paste-function)
interprogram-cut-function nil
interprogram-paste-function nil)))
(defun resume-interprogram-kills ()
"Undo `suspend-interprogram-kills'.
Any new text available from the window system becomes available for
yanking."
(interactive)
(if suspended-interprogram-functions
(setq interprogram-cut-function
(car suspended-interprogram-functions)
interprogram-paste-function
(cdr suspended-interprogram-functions)
suspended-interprogram-functions nil)
(error "Interprogram kills not suspended")))
--
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.