Configuring a major mode in Emacs requires understanding hooks in Lisp. A hook is a Lisp list whose elements are functions that are executed at a certain triggering event. Every major mode features a built-in hook whose triggering event is the activation of that mode and whose name is constructed as {MODE NAME}-hook
. For instance, the Python mode hook is python-mode-hook
, the shell mode hook is sh-mode-hook
, the Java mode hook is java-mode-hook
, and so on.
You do not have to construct a hook in order to configure a major mode; rather, you write your desired configuration as a Lisp function, and then you add that function to the major mode's hook using the add-hook
Lisp function.
Like many things in open source programming, the add-hook
method is dumbly named: when using it, you're not adding a hook variable to anything, as the name would imply; rather, you're adding an element to an already-existing hook list. Mentally replacing add-hook
with add-to-hook
as you read Emacs configuration will make a great deal of it more comprehensible. Its usage is
(add-hook '{EXISTING HOOK} '{FUNCTION TO ADD TO EXISTING HOOK})
where
{EXISTING HOOK}
is the name of an existing hook, and
{FUNCTION TO ADD TO EXISTING HOOK}
is the name of the function you'd like to add to that hook.
Note the use of the single-apostrophe '
shortcut for quote()
with both arguments; add-hook
is written to allow either argument to be a function that returns the name of the hook or of the function to be added, so the shortcuts are needed to indicate to add-hook
that we're supplying these names as literals instead.
Since the elements of a hook are functions, using add-hook
to insert your desired configuration directives into a major mode's hook requires you to define that configuration as a function. In principle this requires nontrivial knowledge of how to define functions in Lisp, but in practice it isn't too hard as long as the configuration you're adding is a basic series of self-contained expressions.
Lisp functions are defined by the defun
("define function") function, which has the form
(defun {NAME} {ARGUMENT LIST} {BODY})
where
{NAME}
is the name you give your function, which can be any normal variable name, like "my-config
,"
{ARGUMENT LIST}
is a Lisp list (including parentheses) of variables representing input arguments, and
{BODY}
is the series of expressions to be executed whenever the function is executed, called the "body" of the function.
Typically you won't have arguments to your configuration function (if you do, it's most likely that you're doing something complex enough that either you already know what you're doing or that this guide won't help you with if you don't), so you'll use an empty list ()
, and the body is where your configuration expressions will go.
Putting this all together, Emacs configuration that you might find suggested in a blog post or on a forum, like
(setq indent-tabs-mode nil)
(setq tab-width 4)
(setq indent-line-function 'insert-tab)
can be added to the .emacs
configuration of a particular major mode -- say, javascript-mode
-- like so:
;; Define the configuration function
(defun shell-indent-config ()
;; Your configuration directives go here
(setq indent-tabs-mode nil)
(setq tab-width 4)
(setq indent-line-function 'insert-tab)
)
;; Add the configuration function to the JavaScript mode hook
(add-hook 'javascript-mode-hook 'shell-indent-config)
[hooks] mode hook
on this site. The Emacs manual contains an excellent introduction: [Hooks ](gnu.org/software/emacs/manual/html_node/emacs/Hooks.html), as does the "Programming in Emacs Lisp" book,add-hook
are, so after reading it I'm still left with no clue how I'm supposed to use it to configure a major mode's indentation. The second link goes to a table of contents, none of the entries of which have anything obvious to do with either major modes or hooks, so I'm not sure what I'm supposed to get from that.add-hook
.M-x customize-group RET <group>
for the major mode's group (which is often the name of that mode).