How to advice `evil-delete'
Hi, I've been straggling with this for the entire afternoon and am really really frustrated. What I want is that when deleting an empty line, I don't want it to be yanked, just delete. So I adviced `evil-delete' like this and it worked as I expected. (defadvice evil-delete (around around-delete (beg end type register yank-handler) activate) (if (eq type 'line) (let (here) (save-excursion (goto-char beg) (skip-chars-forward " \n\t" end) (setq here (point))) (if (eq here end) (flet ((evil-yank (&rest args) t)) ad-do-it) ad-do-it)) ad-do-it)) However, as soon as I add another advice on `evil-yank', things stopped working correctly, even thougt the yank advice is empty like the following, things still not working properly. (defadvice evil-yank (around around-yank (beg end type register yank-handler) activate) ad-do-it) The problem is that after I deleted an empty line, I could no longer yank anything, whenever I yank I get the errer: Debugger entered--Lisp error: (wrong-type-argument commandp evil-yank) call-interactively(evil-yank nil nil) Could anybody give me some idea of where the problem is? Am I supposed to advice these "special" operator functions and is there anything "special" in advicing them? Thanks in advace, York
Am Sun, 2 Oct 2011 23:16:06 -0400 schrieb York Zhao <[email protected]>:
Hi,
I've been straggling with this for the entire afternoon and am really really frustrated. What I want is that when deleting an empty line, I don't want it to be yanked, just delete.
So I adviced `evil-delete' like this and it worked as I expected.
(defadvice evil-delete (around around-delete (beg end type register yank-handler) activate) (if (eq type 'line) (let (here) (save-excursion (goto-char beg) (skip-chars-forward " \n\t" end) (setq here (point))) (if (eq here end) (flet ((evil-yank (&rest args) t)) ad-do-it) ad-do-it)) ad-do-it))
However, as soon as I add another advice on `evil-yank', things stopped working correctly, even thougt the yank advice is empty like the following, things still not working properly.
(defadvice evil-yank (around around-yank (beg end type register yank-handler) activate) ad-do-it)
The problem is that after I deleted an empty line, I could no longer yank anything, whenever I yank I get the errer:
Debugger entered--Lisp error: (wrong-type-argument commandp evil-yank) call-interactively(evil-yank nil nil)
I do not know if this is indeed the solution, but `evil-yank' is in the end a usual Emacs command, i.e., it has an interactive-form. Your redefinition does not have an interactive form and is therefore not regarded as a command. Changing your code to ... (flet ((evil-yank (&rest args) (interactive) t)) ... may work. But I haven't tested it. Furthermore it may be easier to just call `delete-region' to remove those lines instead of redefining `evil-yank'. In fact, this is what `evil-delete' does. Frank
I do not know if this is indeed the solution, but `evil-yank' is in the end a usual Emacs command, i.e., it has an interactive-form. Your redefinition does not have an interactive form and is therefore not regarded as a command. Changing your code to
... (flet ((evil-yank (&rest args) (interactive) t)) ...
may work. But I haven't tested it.
Thank you very much for the help. Adding "(interactive)" didn't work, and even worse, previously I could re-evaluate the `evil-yank' (C-M-x) to make yank work again but after adding "(interactive)", "C-M-x" no longer do the trick and I have to restart Emacs to make "yank" work again, provided that I don't delete blank lines.
Furthermore it may be easier to just call `delete-region' to remove those lines instead of redefining `evil-yank'. In fact, this is what `evil-delete' does.
Yes, that would be easier and I may have to go that way finally if I can't make this work. However, in general, I think it is still better not to bypass the the original function altogether ('evil-delete' here) so that I will still be able to take advantage of new changes in the original function without having to monitor possible changes in the original function and port them into my code in the future. But yes, in this particular situation the `evil-delete' may not be changed anymore and your suggestion might be better. However, if possible I would still like to figure out why this doess't work so that I could learn something from it.
On 2011-10-03 05:16 +0200, York Zhao wrote:
The problem is that after I deleted an empty line, I could no longer yank anything, whenever I yank I get the errer:
Debugger entered--Lisp error: (wrong-type-argument commandp evil-yank) call-interactively(evil-yank nil nil)
What does "C-h k y" say? Look for the word "interactive": evil-yank is an interactive Lisp function in `evil-operators.el'. ^^^^^^^^^^^ If your advice somehow turned `evil-yank' into a mere function, it should be indicated here. Also, try using `defadvice' without the ARGLIST argument: (defadvice evil-yank (around around-yank activate) ad-do-it) Although it's possible to advise a function's interactive behavior, this shouldn't really be an issue with simple advices like above -- `defadvice' is smart enough to recognize commands. -- Vegard
What does "C-h k y" say? Look for the word "interactive":
evil-yank is an interactive Lisp function in `evil-operators.el'. ^^^^^^^^^^^
If your advice somehow turned `evil-yank' into a mere function, it should be indicated here.
Thank you very much for the help. I never paid attention to this details in "C-h k", and you are right it didn't say it was an interactive function and only when I add "(interactive)" to the yank advice "C-h k" will report an interactive function, however, it doesn't matter what "C-h k" says, the problem is still the same.
Also, try using `defadvice' without the ARGLIST argument:
(defadvice evil-yank (around around-yank activate) ad-do-it)
Although it's possible to advise a function's interactive behavior, this shouldn't really be an issue with simple advices like above -- `defadvice' is smart enough to recognize commands.
Removing the ARGLIST didn't help, though it counteracted the side effect of adding "(interactive)" to "flet" in that I can again make yank work again by re-evaluate `evil-yank' (C-M-x). I think the real question (and interesting) here is why "flet" doesn't restore the original `evil-yank' after "ad-do-it".
participants (3)
-
Frank Fischer -
Vegard Øye -
York Zhao