Open duianto opened 5 years ago
Same spotted on Linux Emacs 26.1.
If someone has a good elisp fu, then perhaps an easy solution would be to make a copy of all text registers before the multiple cursors are made. Then when the cursors are killed the registers are restored...food for thought.
EDIT: For the time being I am removing register-alist here and then byte-recompiling the file. Works just fine, it's not that I need named registers while multiple cursors are active anyway.
No, the "fix" below only works when creating additional cursors with (evil-mc-make-cursor-here)
.
The named registers are still removed if one creates a cursor with for example:
(evil-mc-make-and-goto-next-match)
.
I might have found a possible solution that doesn't remove the named registers.
By wrapping the call to (evil-mc-cursors-before)
in a temporary register-alist
variable.
(defun evil-mc-run-cursors-before ()
"Runs `evil-mc-cursors-before' if there are no cursors created yet."
(when (not (evil-mc-has-cursors-p))
(let (register-alist)
(evil-mc-cursors-before))))
The optimal solution would be to be able to paste from a register at every cursor, but with this "fix" it only pastes from a register at the main cursor.
But the major issue of not removing the named registers is probably enough for now.
If someone has a good elisp fu, then perhaps an easy solution would be to make a copy of all text registers before the multiple cursors are made. Then when the cursors are killed the registers are restored...food for thought.
EDIT: For the time being I am removing register-alist here and then byte-recompiling the file. Works just fine, it's not that I need named registers while multiple cursors are active anyway.
(setq ~+multiple-cursors--evil-mc-registers-copy '())
(defun ~+multiple-cursors*evil-mc-run-cursors-before (&rest r)
(cl-loop for reg from 97 to 122 do
(setq ~+multiple-cursors--evil-mc-registers-copy (nconc ~+multiple-cursors--evil-mc-registers-copy (cons (get-register reg) nil)))))
(defun ~+multiple-cursors*evil-mc-run-cursors-after (&rest r)
(cl-loop for reg in ~+multiple-cursors--evil-mc-registers-copy
for i from 97 do
(when reg
(set-register i reg)))
(setq ~+multiple-cursors--evil-mc-registers-copy nil))
(advice-add #'evil-mc-run-cursors-before :before #'~+multiple-cursors*evil-mc-run-cursors-before)
(advice-add #'evil-mc-run-cursors-after :after #'~+multiple-cursors*evil-mc-run-cursors-after)
@sooqua
That only seems to work with:
evil-mc-make-and-goto-next-match
and evil-mc-make-and-goto-prev-match
It doesn't work with:
evil-mc-make-cursor-here
or evil-mc-make-all-cursors
And there might be an off by one issue, because while I was storing text in the a
, b
and c
registers and creating evil-mc cursors, then it would sometimes show that the same text was stored in the }
and |
registers.
The author of this Spacemacs issue: Problem persisting registers https://github.com/syl20bnr/spacemacs/issues/12606
Says:
On exiting spacemacs the register list seems to persist alphabetic and numeric registers differently, as regards the buffer name.
In the - rather longer than is probably necessary - line below from .emacs.desktop the numeric registers seems to be stored along with the full path name of the buffer. Whereas a lot of registers seem to refer only to the file name.
That might be why the alphabetic registers are erased when evil-mc cursors are created.
Quick fix:
(defun ~+multiple-cursors*evil-mc-write-cursor-state (state)
"Write the state of the real cursor with values from STATE."
(let ((names (evil-mc-get-cursor-variables)))
(dolist (name names)
(when (boundp name)
(let ((p (evil-mc-get-cursor-property state name)))
(when (not (and (string= name "register-alist") (null p)))
(set name (evil-mc-get-cursor-property state name))))))))
(advice-add #'evil-mc-write-cursor-state :override #'~+multiple-cursors*evil-mc-write-cursor-state)
That seems to work for all evil-mc cursor creation commands 👍
It seems to also keep the 0
register from being deleted.
There's an open issue about it:
Nils out evil-was-yanked-without-register #70
Could that solution or something similar be implemented to also prevent the position markers from being removed when evil-mc cursors are created?
Position markers (I might not be the correct name), can be store with ma
, mb
, etc.
And jumped to with:
`a
(backtick and a) to jump to the character where the mark was set.'a
(single quote and a) to jump to the beginning of that markers lineYeah. I'm not sure why (null p)
check doesn't work with evil-markers-alist
, it seems like it doesn't write null in there but something breaks anyway.
(defun ~+multiple-cursors-evil-mc-write-cursor-state-a (state)
"Write the state of the real cursor with values from STATE."
(let ((names (evil-mc-get-cursor-variables)))
(dolist (name names)
(when (boundp name)
(let ((p (evil-mc-get-cursor-property state name)))
(when (not
(or
(eq name 'register-alist)
(eq name 'evil-markers-alist)))
(set name p)))))))
(advice-add #'evil-mc-write-cursor-state :override #'~+multiple-cursors-evil-mc-write-cursor-state-a)
You could probably just remove register-alist
and evil-markers-alist
from evil-mc-cursor-variables
at this point instead of overriding evil-mc-write-cursor-state
, for some negligible performance benefit, but I don't know what these variables are used for anyway.
(when (featurep! :editor multiple-cursors)
(after! evil-mc
(setq evil-mc-cursor-variables (mapcar
(lambda (s)
(remove 'register-alist (remove 'evil-markers-alist s)))
evil-mc-cursor-variables))))
I'm using Doom Emacs, you will have to modify everything before and including after!
to run this code only after evil-mc is loaded.
This seems to work to prevent the removal of:
(with-eval-after-load 'evil-mc
(setq evil-mc-cursor-variables
(mapcar
(lambda (s)
(remove 'register-alist
(remove 'evil-markers-alist
(remove evil-was-yanked-without-register s))))
evil-mc-cursor-variables)))
Thanks
Observed behavior
Stored registers are removed when multiple cursors are created.
Expected behavior
That stored registers remained after cursor creation.
Steps to reproduce
abc
abc
in register a:"ayiw
:reg
RET
, there an entry for:C-w w
grh
a
is gone.Notes
Any registers that were stored while multiple cursors were active. Remain after pausing, resuming or undoing the cursors.
System information