home · contact · privacy

Yet another introduction to Emacs

Table of Contents

Preliminary remarks

This introduction to Emacs assumes you have a rough idea what Emacs is, and have a desire to learn how to use it. I therefore won't list its great many uses, or try to convince you of its effectiveness as a text editor, organizer, IDE etc. Instead, I'll try to explain it as a self-documenting, programmable machine or environment. That's the kind of introduction I wished for when I started using it, and this document here mostly grew out of writing it for myself.

Most Emacs introductions drop a lot of keybindings on the reader. This one will drop the names of Emacs commands instead (to which key combos are mostly just shortcuts): They are descriptive, they don't depend on specific keymap configurations – and the matching key combination is usually easy to find given the command name, if you want to know that instead.

The following assumes you're using Emacs with an unmodified/default configuration. If you don't, all bets are off: As customizable as Emacs is, a non-default config might turn it into an entirely different piece of software. If you start Emacs from the command line, you can make it ignore any local config file by starting it as emacs --no-init-file or emacs -q.

Installing Emacs is no topic of this introduction. If you need advice on that, look at the "How do I install Emacs?" section of the GNU Emacs FAQ.

This introduction was written with GNU Emacs 24.5.1 on Debian GNU/Linux Stretch as the reference implementation. Other Emacs variants might differ slightly to what this introduction describes.

The minimum knowledge for using Emacs as a text editor

Contrary to what people may tell you, you barely need to learn anything to use Emacs – if all you want is a basic text editor.

Just start Emacs by clicking on its icon, or entering emacs in your command prompt. You'll see something pop up that looks mostly like an ordinary text editor window.

On top is a menu bar: Click File, then Open File... in the dropdown menu to open some text file. Once the file is open, use the arrow keys, or keys like Page up and Page down, Backspace etc. on the file content, just as you would use them in other editors. When you're done editing the file, click File again, and then Save in the dropdown menu.

That's at least how it works if you run the GUI version of Emacs. If you open Emacs in a mouse-unfriendly terminal, you reach the menu bar with the F10 key, and can navigate it with your arrow keys, and Return. (This also works in the GUI version.) Open File... will then make a prompt appear at the bottom of the terminal to enter a relative or absolute file path. Tab completion is available: Type the Tab key twice to see a list of files available from the current path.

There is also a Visit New File... selection available on the File menu, if you want to create a new file instead of opening an old one. There's Save As... to save the text in front of you at a file path that might be different from where you got it from. And there's a Quit at the bottom of the File menu once you've had enough.

Congratulations! You now know how to use Emacs as a text editor – at least semi-productively. There is much more that can be done with Emacs of course. But you can now start using Emacs for basic text editing tasks.

Basics of Emacs control

Let's forget about clicking through menus for now. Because that's the most un-cool way to use Emacs. The cool way is by weird key combinations.

M-x and C-g

You actually only need to know two weird key combos (and won't be taught many more by this guide). By Emacs convention, they're written as M-x and C-g. C-g means: Push the Control key (probably labeled "Ctrl" on your keyboard), and, while you hold it, also push the g key. M-x follows the same formula – just replace the g key with the x key, and the Control key with the Meta key.

The Meta key? Well, Emacs was originally developed for ancient keyboards that had a key labeled "Meta". Modern keyboards rarely do. If you're lucky with your keyboard config, you can just use your keyboard's left Alt key as the Meta key. If you're not lucky1, you might have to use the Escape key, and release it before you hit the x in M-x.

M-x opens a command prompt at the bottom of your Emacs screen. Hundreds of different commands can be typed in here to control Emacs' behavior. For example, do M-x, then type split-window-right, then hit Return. This should visibly change the layout of the Emacs in front of you. Afterwards, do M-x, then type delete-window, then hit Return to return Emacs to the previous state.

When talking about input sequences like the above, Emacs users often use a special notation that basically concatenates individual key presses (or mouse clicks etc.), key combos, and the typing of command names into single strings, which use spaces as separators. In this notation, the above input sequences would be written as M-x split-window-right RET and M-x delete-window RET, with RET a name of the Return key.

C-g aborts any process of entering an Emacs command. Try it out: Do M-x, then type something without hitting Return, then do C-g (i.e. do M-x blabla C-g). The command prompt will then be replaced with the word Quit (which signifies the quitting of the individual command input process, not of Emacs as a whole).

Commands and keybindings

Here are some M-x commands useful to know for an Emacs beginner:

  • find-file: prompt for a file path to open for editing (tab completion is available)
  • save-some-buffers: for all unsaved open files, ask whether to save them
  • save-buffers-kill-emacs: do what save-some-buffers does, then quit Emacs
  • help: open comprehensive Emacs help system

There are other commands you will use often – such as left-char, right-char, previous-line, and next-line. They move the cursor left, right, up and down inside a text. You could call them via M-x, but probably won't – since you can just use the arrow keys. Each arrow key is bound to one of these commands: pressing the key with the arrow up is a shortcut to what M-x previous-line RET does. Such shortcuts through binding keys to commands are called keybindings.

Anything you do in Emacs is done through commands. This includes typing an individual character into editable text: There is a command self-insert-command, to which by default many keyboard keys of printable characters are bound equally. It inserts the value of the key through which it was called: If you press the x key in isolation (not as part of any longer input sequence), the keybinding of x to the self-insert-command is called. The self-insert-command thus triggered asks Emacs by the key of what character it was called, and then inserts the answer – x – into the text you're currently editing.

Most users of Emacs control it through a large variety of keybindings – many of them combinations of three or more keys. So instead of typing M-x save-buffers-kill-emacs RET, for example, they would type C-x C-c, which is bound to the same command. (Note that you can also abort such a sequence of keys by entering C-g in the middle of them: C-x C-g.) But almost any Emacs commanding can be done via the M-x prompt. The self-insert-command is one of the rare exceptions, as it is pretty useless if not called through a keybinding. (Even M-x and C-g themselves are mere keybindings to commands that can be entered via M-x, namely execute-extended-command and keyboard-quit – try it out.)

Typing key combos is obviously more efficient than entering commands via M-x – if you know the combos. If you don't, but want to, call the where-is command. It will ask you for a command name, and answer with the keys that are bound to the command (if any are). Often, entering a command via M-x will also be answered by the bottom bar (where the command prompt lives) telling you what keybinding you could have entered instead.

There is a mirror command to where-is: describe-key. It prompts for a key combo to get the name of the command it is bound to.

The Elisp core

As a piece of software, Emacs is made up of lots of code – most of it written in the Elisp (short for: Emacs Lisp) scripting language. Basically, Emacs is lots of Elisp functions and variables interacting with each other. M-x commanding is just a form of calling certain Elisp functions and manipulating certain Elisp variables which are optimized for easy access by the user. Proper Elisp code looks slightly different than M-x commanding does, but shares much of the vocabulary.

Not all that can be done with Elisp has a shortcut in the form of M-x commands. So there is sometimes good reason to directly write and evaluate Elisp code. We will look at real Elisp code later in this guide. What matters for now is the vocabulary shared between M-x commanding and Elisp code. We can use the M-x command describe-function to examine the documentation of any Elisp function. Since all M-x commands share their name with the Elisp function they call, this also serves to document M-x commands. Try it out: M-x describe-function RET find-file RET.

Elisp variables make up the configuration of Emacs. To change Emacs' behavior, one may manipulate its internal variables. This naturally can be done with Elisp code, but it also can be done with the set-variable command. Use describe-variable to examine the documentation and current value of a variable. For some variables, specific commands to set them exist – such as set-fill-column for the variable fill-column. Some of these commands might do slightly different things than a raw set-variable would do – if you're curious about the differences, read the documentation of both variable and command/function.

Navigating the Emacs screen: frames, windows, buffers

Elements of the Emacs screen, and buffers

Let's take a second look at the elements that make up the Emacs screen.

We already played with the top line, the menu bar. As mentioned before, you can access it with the mouse, or the F10 key – which is just a keybinding to the command menu-bar-open. If you haven't done so yet, navigate around the different menus for an overview of some commonly used Emacs features. In the GUI version of Emacs, a tool bar may be found below the menu bar. It sports some graphical buttons for common tasks. Menu and tool bar offer but a tiny subset of the features available via keybindings or M-x. Naturally, both bars can be turned off – but that's a topic for later.

For our M-x shenanigans, we interacted with the line at the bottom of the screen. This line (which may actually grow to more than one line on some occasions) is the echo area, since it often echoes the keys you type (as long as they're part of a key combo, and you wait one second after starting to type before finishing an input sequence). The echo area is also used to display some command results and other messages that might pop up, and for context-dependent input prompts – such as the M-x prompt. When turned into an input prompt, the echo area can be used just like any other text editing area: You can write and delete text, navigate through the text with the cursor, etc. The text editing area in the echo area is then called the minibuffer. If the number of meaningful inputs here (command names, file paths etc.) is limited, you can usually hit the Tab key to auto-complete a sufficiently defined input, or for a list of plausible input continuations.

Which brings us to the topic of buffers in general. A buffer in Emacs is a body of text to be displayed, navigated, and possibly manipulated in Emacs. It may represent almost anything: the contents of a text file, a view of your filesystem, a command line interface – whatever can be drawn in printable characters. (The previously introduced find-file command, when finished, creates a new buffer representing the contents of the selected file.) Buffers also hold some metadata, such as, if the buffer represents the contents of a file, the name of that file. The whole area between menu und tool bar on the top and the echo area on the bottom is dedicated to the display of buffers and metadata about them.

Buffers are displayed in windows. If you're running Emacs inside a window system, probably inside a window of its own, this terminology may be confusing: Emacs "windows" are their own thing inside of Emacs. The area between the upper top bars and the lower echo area may contain several such windows, being split among them horizontally or vertically. Only one window at a time is selected though: It sports the only, or the most prominent cursor. Different windows may show different buffers – or different views of the same buffer. The bottom line of each window is the mode line. It displays metadata about the specific window, such as the name of its buffer.

An arrangement of Emacs "windows" that can be displayed on the screen is called a frame. If the GUI version of Emacs is run inside a window system, different frames open up as different windows of that surrounding window system – each of which may then contain several Emacs windows. If Emacs is run in a single terminal or terminal emulator window, only one frame may be visible at a time, while other frames stay hidden until conjured up to replace it. In the terminal, frames are identified by names (by default F1, F2, F3 etc.) in the mode line, to the left of the buffer name.

Layouting the Emacs screen

First, some useful commands to handle windows:

  • split-window-right: create new window, initially displaying the same buffer as the selected window, to its right
  • split-window-below: like split-window-right, but opens the new window below the selected window
  • other-window: switch window selection
  • delete-window: close selected window, if it's not the only one in the frame

If you close a window, this does not close the buffer associated with it. While every window displays some buffer, buffers can exist well without any windows displaying them. Some buffers will exist by default from the start of any Emacs session, possibly without you ever noticing them – such as a buffer *Messages* that logs informative Emacs messages to the user, or *scratch* that is for, among other purposes, short-term note taking.

Use the command switch-to-buffer to change the buffer that a selected window displays. It will prompt for a buffer name. On the empty prompt, press the Tab key to get a list of all currently open buffers to choose from.

Some useful commands to handle frames:

  • make-frame-command: create a new frame
  • other-frame: switch frame
  • delete-frame: close visible frame, if it's not the only one in the Emacs session

Major and minor modes

Emacs is highly configurable: Its overall behavior, its keybindings, the way it displays and highlights content, its interactions with other parts of the system can all be manipulated via Elisp functions and variables. Such adjustments to Emacs' behavior can be bundled in sets optimized, and callable, for certain tasks or contexts. Such sets of adjustments are called modes. An example might be a set of keybindings and syntax highlighting rules that make much sense for editing Python code. Another might be a set of display rules and keybindings that make sense for browsing documentation files.

Modes are differentiated into major and minor ones. Each buffer has one, and only one, major mode. If you use find-file to open a file, that file's buffer's initial major mode is decided by a ruleset that involves analyzing the file content and looking at the filename extension. A file whose first line is #!/bin/sh and the name of which ends in .sh will thereby open in Shell-script mode, which is a mode optimized for the editing of shell code.

Minor modes can customize Emacs behavior just as strongly as major modes. In contrast to major modes, a buffer can be in several minor modes at the same time. Minor modes' customizations add to, and may shadow, the customizations enabled by the major mode. Minor modes are often enabled automatically by major modes. Many minor modes bundle adjustments that may be useful in different contexts, so that different major modes may call the same minor mode. Different major modes may just be different sets of minor mode activations.

Major modes affect only the buffers for which they are explicitely selected – they are buffer-local. The same holds true for many minor modes, but not all. Some minor modes are global: They affect the overall behavior of the Emacs session, no matter the buffer. The Tool-Bar minor mode for example enables the tool bar in the Emacs GUI so that it is visible no matter what buffer is selected. In contrast, the Read-Only minr mode disables editing the content of only the buffer for which it is set.

The mode line at the bottom of a window lives up to its name by containing a string in parentheses that lists the buffer's major mode, and some or all of its minor modes.

For each mode, there is a command to either (for major modes) switch the buffer to it, or (for minor modes) toggle it on or off. These commands can be identified by ending in -mode, and are usually some spelling of the mode's name. The modes mentioned above are set by shell-script-mode, tool-bar-mode, and read-only-mode.

A helpful tool for interacting with modes is the command describe-mode. It will open a buffer that contains short descriptions of the modes active for the buffer from which it was called, including keybindings. Be careful about the keybindings though: Depending on how carefully it was crafted, this part of the documentation may be hard-coded, and thereby ignore any keybinding customizations or shadowings by other modes that might make it untrue.

Emacs' Info system

Emacs prides itself on its self-documentation. Almost every aspect and detail of Emacs is explained in some text you can conjure via an Emacs command, such as describe-function or describe-variable. But the documentation available via commands whose name start with describe- is often pretty terse, and provides little context. If you want broader overview and introductory texts, a lot of prose explaining Emacs (and possibly other software) in concepts and details is available via Emacs' Info system.

Emacs' Info system is at the core a browser for Info files. These are hypertextual documentation files, internally divided into text nodes that may link to each other like pages of a website would. The nodes in an Info file are usually hierarchized as a tree of one Top node linking to some child nodes, which themselves may link to grand-child nodes, etc. – so nodes may have parents, siblings, and children. Nodes may also link to each other non-hierarchically, as happens with index nodes which list keywords, concepts etc., with links to anywhere in the document where they are explained.

Info files are a documentation format popular with the GNU Project, which packages its software releases with them – including GNU's implementation of Emacs. Since their usage has grown beyond Emacs, there also exist stand-alone browsers for them, like GNU's info tool. If you want to learn a bit more about Info files and the info tool, I have written an introduction on them of its own.

On Unix systems, Info files are usually installed into a directory such as /usr/share/info/. A directory of Info files is supposed to contain an Info file named dir or dir.info that contains links to the Top nodes of all other Info files of the directory. Like a web browser that would point to the index.html file of a website by default, an Info browser would point to this dir file as an entrance to the available documents.

Emacs' built-in Info browser is mostly just a major mode optimized for viewing Info files: Info mode. One could open an Info file in other modes, such as the standard mode for handling plain text files, Text mode – but in that case, one would see a plain text view of the full length of the Info file, with some control characters scattered throughout. If properly2 summoned in Info mode, the same file turns into hypertext, and only one node at a time is displayed. The mode line will display the filename sans any .info suffix, followed by the name of the currently visible node.

The simplest way to get into Emacs' Info system is through the info command. This opens a hypertext overview of available Info documents – a buffer in Info mode constructed from all the dir Info files of the directories listed in the Info-directory-list variable (see M-x describe-variable RET Info-directory-list RET). From this overview one can jump into all Info files known to Emacs – which may include documentation on topics that have nothing to do with Emacs proper. Info files may come packaged with the software they document, or as a separate package – on Debian Stretch, for example, one may need to install the package emacs24-common-non-dfsg for Emacs' Info files.

Inside any Info node (such as the one created by the info command), Emacs' usual text navigation commands like next-line, right-char etc. will work. The top of the window though includes an area called header that the cursor cannot reach by these: It contains some special navigation links (which can be mouse-clicked if Emacs is run under mouse support). To navigate Info files hypertextually, one may use specific Info mode commands, such as:

  • Info-follow-nearest-node: follow the link to another node on which the cursor is positioned
  • Info-next-reference: move cursor to the next link in the node
  • Info-prev-reference: move cursor to the previous link in the node
  • Info-up: go up one level in the node tree; follows the Up link in the header
  • Info-history-back: move to the node previously visited; like a web browser's "back" button

(This may be a good moment to remember that you can use where-is to get keybindings for commands. The default keybindings for the above commands are ridiculously simple. It is much saner to just hit Return rather than type M-x Info-follow-nearest-node RET once the cursor sits on a link.)

From within Info mode, one can jump to any Info file node – no matter where in the file system it is located – via the command Info-goto-node. It prompts for a node path that may consist of a file path in parentheses, followed by a node name. Thus one might do M-x Info-goto-node RET (/usr/share/info/grep.info.gz)Top RET to jump to the Top node in the grep Info file. One may omit the suffixes .info.gz, Emacs will still know what to look for. In this specific case, one may even omit the whole /usr/share/info/ path before the filename, if that path is included in the Info-directory-list variable that Emacs will search by default for Info files: M-x Info-goto-node RET (grep)Top RET will still produce the same result. If the selected buffer already opens the Info file whose node we want to visit, we can even omit the whole part in parentheses: M-x Info-goto-node RET Top RET. Discovery of Info file paths and node names are helped by the command's tab completion.

Note that Info-goto-node only works when called from within Info mode, i.e. when the currently selected buffer is in Info mode. This is the case for all commands that start with uppercase Info-. Commands that start with lowercase info- can be called from outside Info mode, though they usually create and select a buffer set in it. Some useful examples:

  • info-display-manual: enter the name of an Info file to jump into
  • info-emacs-manual: jump straight into the Emacs Info file

One useful way to navigate Info files is through their indices:

  • Info-index: enter an index keyword or phrase to jump to its target
  • info-apropos: create and open index node of all Info files' index entries that match a given string

Finally, a simple full-text search of an Info file text is also available:

  • Info-search-next: regex search an Info file, forward
  • Info-search-backward: regex search an Info file, backward
  • Info-search-case-sensitively: regex search an Info file case-sensitively

Useful Emacs Info pages

From now on I will, when appropriate, point to useful Info pages commonly distributed with Emacs. I might point to whole Info manuals – for example, I might point to the Info system's own manual available via M-x info-display-manual RET info RET. I might also point to a specific page in such a manual by writing out an Info-goto-node path like (info)Advanced. Remember that the latter only works from within Info mode, so to get there you might have to do a full M-x info RET M-x Info-goto-node RET (info)Advanced RET. I will use the Info-goto-node path form in general, even when refering to the whole of a manual – so even for the whole manual, I would point you to (info).

Here are some useful Info manuals and pages to repeat and delve deeper into some of the other topics covered so far – call them as described in the previous paragraph:

  • (efaq)No Meta key
  • (emacs)Screen
  • (emacs)Commands
  • (emacs)M-x
  • (emacs)Buffers
  • (emacs)Windows
  • (emacs)Frames
  • (emacs)Modes

A quick glance at Elisp

As mentioned earlier, a basic knowledge of the Elisp scripting language is useful for many Emacs purposes: All you can do with commands can be done in raw Elisp, but not all you can do in raw Elisp can be done with commands. And if you want any of your Emacs configurations to stay persistent even after you close Emacs, you may want to edit the configuration file read by Emacs on startup – which is also written in Elisp.

The following introduction should provide a foundation to start using Elisp, but there is obviously much more to learn. It should suffice for basic messing around with one's configuration files, as is explored in the section afterwards.

Lists, their elements and evaluations

An Elisp expression is usually a sequence of symbols (names refering to some function or value), strings (pieces of text), numbers, or other sequences – all these elements separated by spaces and surrounded by parentheses. The following is an example:

(+ 3 4 5)

This is a sequence of the symbol + and the numbers 3, 4 and 5. More properly, it should be called a list. Anything surrounded by parentheses in Elisp is called such, even if it contains only a single element, or none: Both (+) and () are lists. When lists contain lists as members, parentheses may stack up:

(+ (+ 1 2) (+ 2 2) (+ 3 (+ 1 1)))

Elisp expressions are evaluated by Elisp interpreters. Emacs' built-in interpreter can be called with the eval-expression command: It prompts a minibuffer to enter an Elisp expression, to be evaluated upon pressing Return. Try it out: M-x eval-expression RET (+ 3 4 5) RET. This should produce an answer in the echo area that might seem confusing at first: the number twelve, followed by some gibberish (actually, alternate ways of writing out the same number).

You can also point Emacs' interpreter to Elisp code inside a selected buffer window: Move the cursor to the end of an Elisp expression, then do M-x eval-last-sexp RET (the command name means "evaluate last symbolic expression"), which will output an evaluation of the expression to the echo area, just like eval-expression does.

Evaluation of an Elisp list usually goes like this: The first element is read as the name of a function, to which the remaining list elements are passed as arguments. Thus the above (+ 3 4 5) is treated as a call to Elisp's built-in + function, which adds together its arguments. The result of adding 3, 4 and 5, the number twelve, is what the list evaluates to.

Some elements of a list are atomic – evaluating them means to return them as they are written. A number is atomic: 3 can only be evaluated to 3. But in the list (+ 3 (+ 2 2)), the element (+ 2 2) is not atomic: Evaluating it returns 4 rather than (+ 2 2). When a list is evaluated, its non-atomic interior members are usually evaluated before they are passed as arguments to any parent function call: (+ 3 (+ 2 2) will first be evaluated to (+ 3 4), and only then will the leftmost + be called.

In some cases we want to suppress this interior evaluation. Let's assume a function collect-number-lists that collects lists of numbers to do who-knows-what with them. If we wrote the following, we would get into trouble: (collect-number-lists (1 2 3) (4 5 6)). Why? Because the interpreter, eager to evaluate the interior list members, and lists as function calls, would process 1 in (1 2 3) as the name of a (probably non-existant) function to call, to which 2 and 3 should be passed as arguments. The same would happen with (4 5 6). The solution is to suppress evaluation of these list elements:

The special form function – a kind of function in whose presence the interpreter may behave different than usually – named quote returns an un-evaluated element as the argument to the parent function call. It can be used like this: (collect-number-lists (quote (1 2 3)) (quote (4 5 6))). For reasons of convenience, the syntax can be shortened to a single quote mark prefixing the targeted element:

(collect-number-lists '(1 2 3) '(4 5 6))

Variables, set and setq

While + and our hypothetical collect-number-lists refer to functions in our examples, symbols may also refer to things like numbers, strings, or lists.3 Insofar as we can change these mappings of symbols to values, we may call them variables.

We already encountered two commands for examining and changing variables: describe-variable and set-variable. In Elisp proper, we may just evaluate the symbol of a variable to get its value: M-x eval-expression RET float-pi RET will return the value of Pi into the echo area.

Instead of using the set-variable command, we can use the function named set to change the value of Pi:

(set 'float-pi 3.45)

Note that we quote the float-pi symbol here. If we did not, the Elisp interpreter, eager to evaluate interior list members first, would try to evaluate the symbol as the value it refers to – probably a number. But set expects a symbol as its first argument, not what the symbol refers to. Therefore we need to suppress evaluation of the symbol expression. For convenience, the special form function setq is often used. Its usage tells the interpreter to avoid evaluation of the second list member, so we could simply write:

(setq float-pi 3.45)

To wreak more havoc with mathematics and physics, we could set the value of Pi to a string rather than a number. Strings are written as delimited by double quotes: (setq float-pi "three point something"). Strings may contain any characters, but double quotes need to be escaped by prefixing them with backslashes, and backslashes need to be escaped as well by prefixing them with backslashes. To set float-pi to A '\' is called "backslash"!, do:

(setq float-pi "A '\\' is called \"backslash\"!")

The setq form allows several variables to be set in one go, by just adding more pairs of symbol and target value: (setq one 1) – pointing the symbol one to the number 1 – is as valid as (setq one 1 two 2 three "three") – which additionally points two to 2, and three to the string "three". As Elisp does not care about how you format your whitespace, a popular form for setting several variables at once splits up a setq into several incremented lines:

(setq one 1
      two 2
      three "three")


Some symbols are constants: The value they point to cannot be changed. Two such symbols that are used very often are nil, which refers to the empty list () and is also used as a boolean "false", and t, which is used as a boolean "true". Both of these evaluate to themselves and therefore need not be quote'd.


As in most programming languages, you can write comments that are not interpreted. A comment starts with the ; character (obviously only if outside a string) and continues until the end of the line. By convention, comments are often prefixed with more than one ;, but for the interpreter everything beyond the first ; is irrelevant:

; this is a comment
;; and so is this
;;;;;;;;;;;;;; and this

More Elisp

If you want to learn more Elisp, you could start with the beginner-friendly Emacs Lisp Intro at (eintr). A more technical and detailed examination of Elisp can be found in (elisp) – though actually that document explains not just Elisp, but the whole inner workings of Emacs.

Furthermore, you might be interested in studying the Elisp source code of the modes, functions, and variables you interact with. If the Elisp source files of Emacs are installed on your system (which is not the default with Debian Stretch, for example, but can be done by installing the package emacs24-el), you can jump straight into them from the buffers that describe-function, describe-variable and describe-mode open: The top line should then read somethling like …

float-pi is a variable defined in `float-sup.el'.

Mov your cursor over the float-sup.el file name, and enter the help-follow command. This will throw you into the named source file right to where the described object is defined. (The describe- family of commands opens buffers in the major mode Help, which like Info mode is a sort of hypertext system. The help-follow command is by default bound to by the Return key or mouse clicking.)

Customization: interactively, and by init files

I you want any Emacs setting to stay into future Emacs sessions, you better put it into an initialization file (short: init file). Such configuration files are read by Emacs on startup for Elisp code to execute. Emacs looks for a user-specific init file in your home directory at ~/.emacs, ~/.emacs.el and ~/.emacs.d/init.el (with .el the ending for Elisp code files), using the first of these it finds, if any.

The most Emacs customization you can perform is setting or toggling certain variables or modes:

Setting modes

Let's use the minor mode Linum as an example. When enabled, it displays text line numbers at the left margin of buffer windows. Inside a running Emacs, you can toggle it with the command linum-mode for a selected buffer, and global-linum-mode for all buffers. By default, it is disabled.

If we want to enable Linum mode by default, we just need to call the global-linum-mode function in the init file. Note that we have to do so in the form of an evaluable Elisp expression, i.e. as a list with parentheses:


In this case, a single element list suffices: We can call the Elisp function just like we call the command, without arguments. That is not always the case: Some Emacs commands are shortcuts to Elisp functions that need arguments, while the command does not. And strictly speaking, the Elisp function global-linum-mode does not behave quite like the command global-linum-mode without arguments: The command can toggle the mode on or off. When called without argument, the function will only turn it on.

Functions to enable and disable minor modes usually allow an optional first argument. If called with an argument that is zero or negative, they disable the mode. If called with any other kind of argument (including nil), they still enable it. You don't have to remember these rules in detail – you can always check out the specific behavior of a mode setting function via describe-function (try it out on global-linum-mode).

One example of a mode that is enabled by default is Menu Bar. The command menu-bar-mode toggles the menu bar line at the top of the Emacs screen. If we want to get rid of it, we cloud write the following mode-disabling Elisp expression into our init file:

(menu-bar-mode 0)

Setting variables

If you hit the Tab key, what width of whitespace should that enter into your text buffer? In Emacs, that question is decided by the Elisp variable tab-width, which defaults to 8. Try it out with the set-variable command – change it to 4. Note that the minibuffer will prompt you with these words:

Set tab-width buffer-locally to value:

This tells you that your action will only affect tab-width for the selected buffer. Just like with minor modes, the setting of some Elisp variables affects the entirety of Emacs, and the setting of others affects only a specific buffer.

The variables that set-variable allows you to manipulate4 all start with an Emacs-wide "original" value. Insofar as this value is Emacs-wide, we may call such a variable global (just as we did with some minor modes). Various mechanisms may create a child variable from it that is only visible within a certain scope (such as a buffer or a frame). Such a child will have the same name and might even carry an equal value as its parent. But changing its value will not affect the parent's value. Any reference in its scope to the name it shares with its parent will call for the child and its value instead. Such a child variable is called local. If its scope is a buffer, it is called buffer-local (again, just as with certain minor modes).

Some variables will automatically spawn buffer-local children for any new buffer you create. Others will only do so when explicitely asked to. Activations of buffer-local minor modes often create such buffer-local child variables. If you examine a variable with describe-variable, you will not only learn its current value in the context of the selected buffer, but its global parent's value (if it is a child variable and that value differs), and its "original" value (if that is different). In the case of tab-width we also get told that it "[a]utomatically becomes buffer-local when set" – which will become relevant in a second.

If you run set-variable on a buffer-local variable, don't expect it to change anything beyond the selected buffer. The same holds true for using the setq function. If you put a mere (setq tab-width 4) into your init file, that will not actually achieve much: The describe-variable quote about its buffer-locality in the previous paragraph describes the fact that setting it by default just creates a buffer-local child variable with the requested value.5 The global variable remains unaffected, and further children will derive their initial value from this global original, not from the child created via setq.

The solution is to use a different variable setting function: setq-default changes the global value pointed to by a given variable name, no matter whether the current scope only shows the global variable, or a local child of it. To manipulate variables like tab-width on startup, put something like this in your init file:

(setq-default tab-width 4)

Other variables are by default global and can safely be set with setq. But if you are unsure, just use setq-default everywhere in your init file.

Confusion through mode variables

When an Elisp symbol name ends in -mode, that usually refers to a function or even command to turn on or off a major or minor mode. In a few cases though, it merely refers to a variable you can set with set-variable, set or setq. Run describe-variable on indent-tabs~mode for one example.

Adding hooks

When Emacs runs a command, a function, a mode initialization, it executes a number of steps defined in the respective algorithm. You can of course manipulate those algorithms and steps in many ways once you write raw Elisp code. One common approach is to just add some basic function calls as additional steps.

Major modes often are just a collection of minor modes enabled by calling its major mode command. Such a major mode is defined by the function behind such a command – a function which would contain calls to the functions that enable the respective minor modes. A simple approach to extend such a major mode would be to just add more of these minor mode function calls. Thankfully, major mode functions make it easy to do so. They include code that basically says: Call all functions whose symbol you find listed in a certain global variable. All you have to do to extend the major mode is to add function symbols to that variable.

Such variables are called hooks. You can identify them by their names ending in -hook. They exist for major and minor mode functions (such as the variable Info-mode-hook), and for many other functions that direct the workings of Emacs. If, for example, you want some function to be called when you exit Emacs, there's a kill-emacs-hook.

Now that you know set-variable and setq and setq-default, it may be tempting to use those to manipulate hook variables. But hook variables are used for lists of function symbols, and often you just want to add to such a list, not redefine it completely. If you were to setq a hook variable to just some function symbol, that would remove all symbols previously collected in that variable. For convenience, there is a function to just append a symbol to a hook variable, without removing symbols already contained in it: add-hook. It expects as its first argument a hook symbol, and as its second one the symbol of the function to be added:

(add-hook 'some-mode-hook 'some-minor-mode)

Extending Emacs

Loading Elisp files

Once you get familiar with Elisp, it's easy to add all kinds of customizations and new features. You can get quite creative in your init file – up to a point where it may grow to an unsustainable size. It's wise then to move parts of it into separate files. To execute the Elisp code in such a file (and thereby pull in its variable settings, symbol definitions etc.), use within your init file the load function with the appropriate file path as its first argument:

(load "~/my_other_elisp_code.el")

People bundle together all kinds of Emacs customizations and extensions into such Elisp files: new major and minor modes, new functions and commands, keybinding settings, etc. Many of those are distributed online. You could in theory download such files by hand and then point load calls at them in your init file. Or you could use Emacs' built-in package management to search, download, and "install" them – i.e. prepare them in a way that they are loaded automatically on startup, without you having to change anything in your init file.

Emacs packages

As the term "package management" implies, such Emacs extensions distributed online are called packages. The simplest possible package is just an Elisp file with some metadata in its comments; a more complex one may be an archive file that bundles several Elisp and documentation files. In the metadata one would find things such as a description of the package's purpose and the name of its author, but also the names of other packages upon whose installation the package's working depends.

Once you have a package file, you can point the command package-install-file at it. This will handle the package's files in a way that ensures their code's availability to the current Emacs session as well as to future Emacs sessions. Most importantly, it puts them into a directory where Emacs knows to automatically look for installed extensions (usually, a subdirectory of ~/.emacs.d/elpa/). On Emacs startup, the command/function package-initialize is run automatically, which looks for packages installed that way and more or less6 loads them.

Searching and downloading package files can also be done within Emacs. Emacs just needs to know where on the Internet people host packages. This knowledge is stored in the variable package-archives. Its value is an association list, a special type of Elisp list that is supposed to map key words to values. A member of such a list takes the form (key . value). The following code fills package-archives with two package archive URLs, to which the names gnu and melpa-stable are mapped:

(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
                         ("melpa-stable" . "https://stable.melpa.org/packages/")))

Once you made Emacs' Elisp interpreter evaluate the above, run the command list-packages to retrieve, display, and navigate a list of available packages from the respective servers. The buffer opened by the command runs in the Package Menu major mode – do describe-mode to learn about its controls. You can use the Package Menu mode to manage your package installations in various ways. You can also just use the package-install command on one of the available package names to do what package-install-file did, but without the additional prologue of downloading necessary package files for you. To remove a package, just delete the directory into which the package was installed – commonly a subdirectory of ~/.emacs.d/elpa/ named after the package.

Be careful if you want to interact with installed packages in your init file. By default, Emacs runs package-initialize on its startup only after it interprets your init file (since you might also use your init file to customize what package-initialize does). As with everything in Emacs, you can change that: Just call package-initialize earlier, from within your init file. (The Emacs Info file (emacs)Package Installation recommends to also set the package-enable-at-startup variable to nil then, which stops Emacs from re-initializing packages after the init file evaluation.) In some cases, due to the way package-initialize works6, you may even need to follow package-initialize with an explicit call to load the package via load or its close relative require (which in contrast to load accepts a mere package name as argument), if you want some specific contents of it available in the init file.

Where to go from here

After working through the text above, you should have a basic grasp of the principles by which Emacs works, can be interacted with, and configured by. Now might be a good time to study some of its capabilities as an expert text editor, file system browser, mail client, life organizer, game engine, video editing suite, and path to spiritual growth.

The Emacs Info files are good starting point to learn more. For example, (emacs)Text describes a number of major modes for editing various types of text files. (emacs)Programs extends this to the writing of computer program code. (emacs)Dired describes the use of Emacs for browsing your file system. In general it is worthwile to read through the whole (emacs) Info file – though probably not in one go.

Further resources can be found online. There is a comprehensive Emacs Wiki which lists entrypoints into the Emacs community.



This depends on the way your system environment maps your keyboard, and often can be changed. See the EmacsWiki's "Meta Key Problems" page for some suggestions.


The most useful ways to jump into Info files are explained in the following paragraphs. But if you feel adventurous, just run find-file on an Info file – which should turn up in a plain-text view of the entire file content. Simply now calling M-x Info-mode RET on the result may not suffice to start proper Info file browsing on it: It will miss some initialization work done by the methods to enter Info files. Run M-x Info-on-current-buffer RET instead, which will perform the necessary initializations.


In fact, the same symbol may carry references to a function and to some variable value at the same time. An Elisp symbol has multiple slots for different kinds of references, and the interpreter decides by context which of these to follow (i.e. at the beginning of a list to evaluate, the function slot will be called). For details, see (elisp)Symbol Components.


Not all Elisp variables are created equal. Some are created on Emacs startup as customizable. Those that are not can be manipulated by the setq function, but not by the set-variable command.


I'm not actually sure I understand all of this: What is the buffer to which it becomes local when set in the init file? Do the init file's Elisp expressions run in some kind of specific initialization buffer? Someone with better Emacs understanding than me please write me an explanation.


It does not quite load them in the way that the load function does. In addition to putting the original Elisp files into the package directory, commands such as package-install-file also create a special Elisp file that sort of contains a dummy variant of the package: It defines relevant symbols and help messages of the package, but without the original functions and values. What package-initialize does is read that dummy variant of the package, to make its symbols and features known to Emacs, available for tab-completion in the command prompt etc. The real Elisp code is loaded once Emacs starts evaluating those symbols for the values and functions they point to. All this mostly serves to reduce the Emacs startup time. For details, see (elisp)Packaging Basics and (elisp)Autoload.

Author: Christian Heller / http://www.plomlompom.de

Created: 2019-02-12 Tue 10:45

Emacs 24.5.1 (Org mode 8.2.10)