I'm using evil-mode and trying to make sure that it gets disabled after invoking an ansi-term.

I've tried using before and after advice to advise the ansi-term function, as well as adding a hook to term-mode, but that doesn't seem to disable evil mode in the ansi-term buffer.

I ended up defining a separate interactive function that calls ansi-term with a fixed argument and then disables evil-mode for just the current buffer.

(defun ansi-term-disable-evil ()
  "interactively call ansi-term"
  (ansi-term "/bin/tcsh") ; probably shouldn't be hardcoded
  (evil-local-mode -1))

This function has the desired effect (disabling evil-mode in the ansi-term buffer).

Using after advice, however, does not work and I'm trying to understand why.

Here is what I I tried in an attempt to disable evil-mode locally after executing ansi-term.

(defun ansi-term-post ()
  "configuration settings for ansi-term"
  (evil-local-mode -1))

(advice-add 'ansi-term :after 'ansi-term-post) ; I used an ordinary symbol here, not a function object with #'

However, this didn't actually disable evil-mode in the ansi-term buffer. I'm trying to understand why.

  • 1
    I suggest changing your question to ask why the advice doesn't work (and show what advice your tried). Any attempt to redefine a function like you're asking "without advice" is just going to be a reimplementation of the advice system, and will probably have the same trouble.
    – npostavs
    Apr 19, 2017 at 19:16
  • @npostavs ... that is not necessarily true. It might be possible to grab the function object associated with the old definition, bind it to a local variable (in the value namespace?), and then funcall that value inside the body of the new definition of ansi-term. Advice is visible on the advised function, is disable-able, and IIRC there are a fixed number of advice slots on a function. But yeah I'd like to advise a function in such a way that the advised-ness is not visible to the outside world ... Apr 19, 2017 at 20:04
  • If you want to redefine the function, and you want to completely replace it, then use an around advice or just redefine it using defun. Why don't you want to use an around advice? As @npostavs said: show what you've tried and explain what doesn't "work". And say why you do not want "visible" advice.
    – Drew
    Apr 19, 2017 at 20:11
  • "grab the function object associated with the old definition, bind it to a local variable[...] and then funcall that value inside the body of the new definition of ansi-term" - yeah, that's how the advice system works. Or at least the nadvice.el implementation. And, AFAIK, the traditional advice.el is now built on top of it.
    – npostavs
    Apr 19, 2017 at 20:23
  • @npostavs ... I rewrote the question to be focused on why the after advice I originally wrote does not fire. My original motivation for not wanting to use advice is that the API exposed by an advice-bearing function is more powerful than I need for this case... and I'm trying to get a better understanding of what the alternatives are. Apr 19, 2017 at 20:48

2 Answers 2


Your code has a bug which should trigger an error. Apparently this error is silenced for some reason, but the error is that your ansi-term-post function will be called with the same arguments as ansi-term and this function takes at least 1 argument, so your function will be called with one argument, which will fail since your function does not accept any argument. You need to do something like:

(defun ansi-term-post (&rest _)
  "configuration settings for ansi-term"
  (evil-local-mode -1))

This said, it's likely that wasamasa's answer is a better option.


Disabling Evil is the wrong approach to this problem, customize the initial state for term instead:

(evil-set-initial-state 'term-mode 'emacs)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.