22

I'm looking to run some code every time Emacs creates a buffer. Is there a hook for this? Something with a name like after-make-buffer-functions?

Edit: If anyone wants to know what I wanted this for, you can read the relevant portion of my Emacs config here: https://github.com/DarwinAwardWinner/dotemacs/blob/master/site-lisp/settings/tempbuf-settings.el

Basically, I want tempbuf-mode to be enabled in all buffers with certain major modes. So Lindydancer's answer is actually more appropriate than what I was originally looking for.

I know that I could already enable tempbuf-mode in specific modes by adding the tempbuf mode hook to all of those major mode hooks, but I wanted to make it editable through M-x customize, and this was the easiest way.

Ryan C. Thompson
  • 40,856
  • 28
  • 97
  • 159
  • 3
    There is no hook like what you want, but perhaps if you give more detail about what you are really trying to accomplish there could be another way to do it. – scottfrazer Oct 26 '11 at 14:37

2 Answers2

16

Unfortunately, no. Emacs use the low-level function ´get-buffer-create´ to create buffers, and it does not provide any hook mechanism.

You could use advice to pick-up all calls to this function, even though I would not recommend this method as it is quite intrusive. (Update: The advice hook will only see calls from elisp, not calls from the Emacs C core parts.)

There are some alternatives which you could use, depending on what you are implementing:

  • change-major-mode-hook -- called before a major mode change.
  • after-change-major-mode-hook -- called when the major mode is beginning to change.
Lindydancer
  • 25,428
  • 4
  • 49
  • 68
  • 2
    As someone who finds advice a fabulous approach in situations such as this, I have to ask in what respect is advice "intrusive"? (and/or why is that a bad thing?). – phils Oct 26 '11 at 12:06
  • 3
    You are correct there is no hook, but advice won't pick up all calls because there are a number of calls to that function in C code and advice doesn't hook in at that level. – Trey Jackson Oct 26 '11 at 12:07
  • 3
    @phils, by being "intrusive", I meant that if you don't write your code carefully, you could break other packages if they don't expect things to happen when creating buffers. Also, I know (from personal experience) that the Emacs maintainers are reluctant to accept packages that use *advice*, as they think that everything provided by the Emacs standard distribution should manage without them. – Lindydancer Oct 26 '11 at 15:49
  • 3
    `after-change-major-mode-hook` does what I want. My function won't run in fundamental-mode buffers, but it doesn't need to. – Ryan C. Thompson Oct 26 '11 at 20:04
  • 2
    Lindydancer: Okay, that's all common sense. I fully understand the maintainers not wanting any advice in the standard distribution, but for end-user purposes in tweaking the editor to one's own purposes, advice is incredibly useful. – phils Oct 26 '11 at 20:40
  • Yes, advice is great and I use it a lot, but you always have to think carefully before advising core functions like `get-buffer-create`, both because C-level calls will ignore the advice and because if your advice breaks the function, it will probably leave Emacs in a broken state that would require you to kill and restart it. – Ryan C. Thompson Oct 27 '11 at 07:48
  • There's also find-file-hook, fwiw. – Christopher Done Jul 04 '13 at 21:04
  • 1
    `find-file-hook` is OK too, but in my case I want something that works on non-file buffers as well. – Ryan C. Thompson Nov 28 '13 at 00:08
  • Does `buffer-list-update-hook` also belong on this list? – Brian Z Mar 17 '15 at 13:23
10

You can use buffer-list-update-hook

buffer-list-update-hook

This is a normal hook run whenever the buffer list changes

You can define a function to do whatever you want.

 (defun awesome-foo ()
     ;;  do awesome things
   )

Hook that function to buffer list hook

 (add-hook 'buffer-list-update-hook 'awesome-foo)
Community
  • 1
  • 1
Chillar Anand
  • 27,936
  • 9
  • 119
  • 136
  • 2
    Unfortunately it doesn't work. It completely breaks Emacs, with message «Command atttepmpted to use minibuffer while in minibuffer». – Hi-Angel Jul 15 '16 at 13:01
  • 2
    Yay, I fixed it with a code like `(if (not (active-minibuffer-window)) (do-something-as-it-is-not-minibuffer)`! – Hi-Angel Jul 15 '16 at 13:08