Yet another introduction to Emacs
Table of Contents
- Preliminary remarks
- The minimum knowledge for using Emacs as a text editor
- Basics of Emacs control
- Navigating the Emacs screen: frames, windows, buffers
- Major and minor modes
- Emacs' Info system
- A quick glance at Elisp
- Customization: interactively, and by init files
- Extending Emacs
- Where to go from here
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 themsave-buffers-kill-emacs
: do whatsave-some-buffers
does, then quit Emacshelp
: 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 rightsplit-window-below
: likesplit-window-right
, but opens the new window below the selected windowother-window
: switch window selectiondelete-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 frameother-frame
: switch framedelete-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 positionedInfo-next-reference
: move cursor to the next link in the nodeInfo-prev-reference
: move cursor to the previous link in the nodeInfo-up
: go up one level in the node tree; follows theUp
link in the headerInfo-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 intoinfo-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 targetinfo-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, forwardInfo-search-backward
: regex search an Info file, backwardInfo-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")
Constants
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.
Comments
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:
(global-linum-mode)
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.
Footnotes:
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
.