Take the 2-minute tour ×

For some reason my shell script mode hooks do not get executed. Example in my .emacs:

(add-hook 'shell-script-mode-hook '(lambda () (rainbow-delimiters-mode 1)))

causes the variables to be set, but the mode is not loaded for the opened script files. What is the proper way to hook here?

I use the default shell script mode (modeline says e.g. Shell-script[bash]). Do I have to hook for each shell type individually (sh, bash, zsh)? If yes can you please tell me how?

Thank you very much!


It turned out to be due a conflict of textmate-mode with the skeleton-pair-insert in sh-mode (I tried to avoid the conflict by disabling textmate in sh-mode, which then left the sh-mood-hook aparatus in ruins. I've removed textmate-mode completely and use now the standard skeleton-pair approch globaly.

I'll accept phils answer - without him I'd probably not be able to debug this on my own.


Thanks to phils, I think his comment takes us closer to solution. It's not a problem with rainbow-delimiters though. I removed all sh-mode-hook except your hello message one and restart Emacs. When I open a .sh file I get this:

Setting up indent for shell type bash setting up indent stuff Indentation variables are now local. Indentation setup for shell type bash File mode specification error: (void-function nil)

Note no "hello" message. The value of sh-mode-hook is: (nil (lambda nil (message "hello")))

I think the problem is this first nil value - though I don't see that it would be set anywhere.

If I eval this:

(setq sh-mode-hook t) (add-hook 'sh-mode-hook '(lambda () (message "hello")))

I see the hello message, though after restart (I've put those lines in .emacs) it is gone again (the nil is again on top of the hook).

Any idea what to do to have active hook at setup?

EDIT1: I've tried also:


with same negative result - not sure if this is relevant though...

share|improve this question

2 Answers 2

up vote 7 down vote accepted

shell-script-mode is an alias for sh-mode. I haven't checked, but I would suspect that only the hook variable for the 'real' function name is evaluated, so I think sh-mode-hook would be the one to use.

Anyhow, there's nothing broken about your syntax, so there may be something amiss with the use of (rainbow-delimiters-mode 1). For instance, you should be able to observe that the following works correctly:


FWIW, for hooks I recommend not using anonymous functions at all, simply because it's much easier to update your hook function if it is named (removing the old lambda expression from the variable before adding an updated one is just annoying in my books).

share|improve this answer
Thanks this helped to narrow down the problem. If you have time can you please have a look at EDIT2 of the original question since it got long. I'll try to clean up things for posteriority if we manage to find a solution. –  user673592 Jan 17 '12 at 14:40
Perhaps you could M-x rgrep your .el files for sh-mode-hook to see if anything else is messing with it. It sounds as if subsequent to your add-hook, something else is doing something akin to (add-hook 'sh-mode-hook nil). –  phils Jan 18 '12 at 6:21
Incidentally, I'm confused by your (setq sh-mode-hook t) instead of (setq sh-mode-hook nil). It doesn't appear to cause problems, but what does it do? –  phils Jan 18 '12 at 6:26
I've commented all sh-mode-hook accross my whole config (except the hello message). However, I've just realized that AutoComplete and yasnippets are loaded for sh-mode - maybe they screw up the hook... (setq sh-mode-hook t) is just something I've tried out of desperation after noticing the nil value. –  user673592 Jan 19 '12 at 7:13
nil and () are the same thing in Emacs Lisp, so (setq sh-mode-hook nil) sets the variable to the empty list (as opposed to a list containing the value nil, which is what you were seeing). I was surprised that add-hook works on a variable with value t (i.e. not a list), but I see it happily creates a list. –  phils Jan 19 '12 at 9:19

Try to remove ':

(add-hook 'shell-script-mode-hook (lambda () (rainbow-delimiters-mode 1)))
share|improve this answer
Unfortunately that doesn't help... the same construction works e.g. for python-mode-hook etc. –  user673592 Jan 17 '12 at 11:03
Both forms will work. The only difference is that '(lambda) expressions will not be compiled. (lambda) is actually self-quoting and (nowadays) equivalent to (function (lambda)), so in general it is better to leave lambdas expressions unquoted. –  phils Jan 17 '12 at 12:58

Your Answer


