This chapter uses the source code of the GNU Readline library as an example.
You can grab it (by
cding to a directory of your choice and then issuing the
git clone git://git.savannah.gnu.org/readline.git) or
follow along using your own C or C++ code.
Start Emacs and open (
C-x C-f) the file
Find file: .../readline/examples/rl.c
Because this is a C source file, Emacs has automatically activated an editing mode called “c-mode”, which provides some custom keybindings and knowledge of C indentation rules and syntax highlighting. We will study c-mode in depth later on.
shell command (that is,
M-x shell RET).
This creates a new buffer running the shell specified by environment variable
SHELL. The buffer is called
*shell* (the asterisks are part of the name,
so you have to type them when switching to this buffer with
cd to the
readline directory and run the following shell commands:
*shell* buffer’s editing mode is
shell-mode. You can run almost any
shell command inside shell-mode; the exceptions are anything that requires real
terminal support, like pagers (
less) and curses-based programs. You lose
bash’s readline completion and any custom bash-completion scripts, or the
equivalent in your shell of choice (though Emacs provides its own command
history and tab-completion). For these reasons, I tend to have a real terminal
running (outside of Emacs) for some tasks, as well as a shell in Emacs. (Trying
to do everything in Emacs reaches a point of diminishing returns.)
The big advantage of
shell-mode is that all output is available for you to
search through, copy, paste, and otherwise act upon, all with the standard
Emacs commands; you don’t have to move your hand to the mouse just to select
Shell-mode adds a number of keybindings:
Type C-x 1 to delete the help window, C-M-v to scroll help.
The Help window
C-h m and read the documentation on shell-mode and its keybindings.
(For now, don’t bother reading the help text about customization—the variables and hooks shell-mode provides to modify its behavior. After shell-mode comes documentation for all the active minor modes; you don’t need to read that either.)
Figure out how to send signals (e.g. C-c) to the shell. (Hint: search the help buffer for “interrupt” and “stop”.)
If you’re not particularly wedded to bash or any other shell, instead of
shell you might consider using
eshell, a shell totally implemented in Emacs
lisp. Among other advantages, running eshell on Windows doesn’t require Cygwin;
you can enter lisp code or any Emacs command by name directly at the shell
prompt; and you can redirect command output to the Emacs clipboard or to any
open Emacs buffer.
I don’t use eshell myself, but many do. For now it might be simplest to stick with the shell you know (running inside Emacs).
The final option for running a shell under Emacs is
ansi-term. This is a full
terminal emulator, and it will pass most key presses directly to the program
running in the terminal. This includes
TAB, so it will be the shell, not
Emacs, performing tab-completion for you.
C-c are still processed by Emacs; for
M-x you’ll have to type
C-x M-x. You can switch from “raw” character mode to “line” mode to get
normal Emacs behavior back (e.g. for moving the cursor around so you can copy
some previous output); nothing will be sent to the terminal until you press
To run a one-off shell command without opening a full shell buffer, use
M-! date RET
M-|) is similar but sends the current region to
the shell command’s standard input. Let’s use it to calculate the line count
Shell command on region: wc -l
If you forget the names of these commands, type
M-x shell TAB TAB.
The help for this one is pretty long, but the important information is near the top. Ignore the paragraph on coding systems, and everything about noninteractive arguments (which are for calling this function from lisp scripts, as opposed to interactively like we have been doing).
The sentence “Prefix arg means replace the region with [the output of the shell
command]” refers to providing a numeric argument to the command. You’ll
remember numeric arguments from the tutorial. In this case the value of the
argument doesn’t matter, so
M-2 M-| or
C-u M-| will do.
Unsaved modifications indicator
Open the file
If you are not particularly comfortable with shell scripting, I apologize for dumping you into a 12,000-line programmatically-generated script, but it’s the closest one I had for an example.
The mode for editing shell scripts is
sh-mode (as opposed to
running an interactive shell session, which we’ve seen already). If Emacs
didn’t figure out that the file is a shell script (perhaps it’s missing the
hash-bang interpreter directive on the first line) you can enter
with, you guessed it,
I don’t really have much to say about
sh-mode. It will do syntax highlighting
and indentation for a variety of shells; and it provides keybindings to run the
script, and to insert certain shell constructs (
etc.) with the correct syntax for the current shell. If Emacs gets it wrong
(again with the missing hash-bang!) you can tell Emacs which shell to use.
By now you know where to find out how.
Back in the
configure script, invoke
info-lookup-symbol and when prompted
Assuming that the Info documentation for the
bash shell is correctly
installed on your system (which should be the case for any Linux or OS X
system, at least) you will see an Info window showing the
bash manual at
the very line for the
Follow the link to “Bash Conditional Expressions”. If you don’t want to use
TAB moves the point to the next link and
RET does the obvious
C-h m will show all the keybindings for
info mode. For once,
though, don’t bother remembering all the keybindings, nor reading through the
rather tedious Info tutorial. All you need to know is:
DELfor scrolling; when you get to the end of a “node” (a page or section), pressing
SPCagain goes to the next node in the sequence. I must warn you,
DELis sometimes buggy when you reach the first node in a chapter.
l(the letter ell) moves back in history.
^moves up to the nearest enclosing table of contents. Pressing
urepeatedly will get you to the main Info directory containing all the Info manuals found on your system. (The Emacs-related manuals are also available on the web.)
C-r); when you reach the end of a node, pressing
C-sagain will continue searching through the rest of the manual.
As you can see from the Info directory, there are many Info manuals, including
manuals for Emacs itself, an Emacs Lisp reference and intro, and manuals for
the more complex Emacs editing modes like
I can’t overstate how useful the Info documentation is. If you’re maintaining a
Makefile you can look up the meaning of esoteric symbols like
$@. Need to do
some socket programming? In a later chapter we will install the
Info manuals for glibc (the GNU implementation of the Unix standard library).
info-lookup-symbol uses the mode of the current buffer to determine which
manual to look in. Sometimes it can’t tell, so it will prompt you: Enter
c-mode or whatever (
TAB to show all
possible options). With a
info-lookup-symbol will always ask.
M-x compile (and accept the default shell command of
Compilation exited abnormally with code 2
Anyway, back to the
*compilation* window. Compilation-mode has its own
special keybindings, of course:
Try out the keybindings for
intriguing, try that out too.
The compilation command is run from the buffer’s associated directory; normally
this is the directory containing the buffer’s file. To run
make on a
different Makefile, you could specify the
make options; or you can change the buffer’s default directory
M-x cd before
To search for all occurrences of a string (or regular expression) in a project,
rgrep. This puts the matches in a new buffer, which you can navigate
just like the compilation buffer (in fact, grep-mode inherits its functionality
and keybindings from compilation-mode).
rgrep to search the
readline source (
*.[ch] files) for
“rl_insert_comment” (make sure you search in the
readline directory, not in
You can control the exact grep command line used: Read the documentation for
rgrep to find out how, or use
grep-find instead. The
documentation is an adequate reference, but the Info manual (
C-h F rgrep)
provides a better introduction.
Emacs has a set of commands, all starting with “
vc-”, that provide a
consistent interface to various version control systems. The
we are using in this tutorial are in a git repository, but the basic commands
are the same for subversion or cvs. More advanced commands (such as altering
repository settings, or pushing and pulling to remote repositories in git and
other distributed vc systems) you will still have to do outside of Emacs.
(If you find yourself missing clickable tabs for switching between buffers,
C-x b is more scalable—it works better when you have hundreds
of buffers open. Later on we will see how to save
a lot of typing under
rl.c probably has changes from when we were messing with it earlier. Invoke
vc-revert to, well, revert it to the latest version in the repository.
Now for argument’s sake, let’s say we find
rl.c’s documentation for the “-u”
command-line flag somewhat confusing:
C-s) both instances of the documentation for “-u” and replace
the word “unit” with “fd”. Save your changes.
You can run the command `vc-diff' with C-x v =
Ask Emacs to show you a diff of this file. (If you need a hint, it’s in the first sentence of this section.)
The diff will be shown in diff-mode, which is also used for viewing patch files. diff-mode has some useful tricks—read its documentation when you have a spare minute.
All the vc commands are bound to key sequences starting with
C-x v. If you
were paying attention when you invoked the diff command by its full name, you
may have noticed that Emacs told you the corresponding keybinding.
This also works with any other prefix. Try it with
C-x 4—you might notice
some parallels with keybindings you already know.
vc has a (long!) section in the Emacs manual.
Personally, I prefer to use the
git gui tools, or git’s
command-line interface directly, for adding, staging, committing, reverting,
merging, branching. But I do use the Emacs
vc is limited to the common denominator of the backend systems it
supports, people have written custom modes for specific version control
Magit is one such mode for git; but as we haven’t yet learned how to
install extensions, we’ll stick with
vc can do a thing or two
magit doesn’t do—have I mentioned
A couple of sections ago, I asked you to grep the readline sources for “rl_insert_comment”.
Switch to the
*grep* buffer if you still have it around, or do a new
Remember, when switching buffers with
C-x b you have to enter the asterisks
as part of the buffer name. (Incidentally, the asterisks are for buffers not
associated with a file on disk. This is just a convention; you could always
*grep* buffer to something without asterisks —see
rename-buffer— or save it to disk if you wanted to.)
The first hit should have been in
emacs_keymap.c. Jump to that match.
Let’s find out which release of readline added the Meta-# keybinding:
*Annotate emacs_keymap.c (rev master)*
With point on the “Meta-#” line, press
d to view the diff of the revision
where this line was last changed.
Now we’re in diff-mode. It seems that this revision consisted mostly of
whitespace changes. Find the exact change to “Meta-#”. You can press
C-w to hide whitespace-only changes in the hunk surrounding point, and
to jump to the next hunk.
Nope, this revision wasn’t it. Press
q to exit the diff buffer, then
run annotate again, starting from the revision before this line’s revision.
Now make sure your point is on the right line (if the new revision is
different enough from the newer one, the line we’re interested in may have
moved around). Then press
d again, and in diff-mode
n until you find the
right hunk. Yes, this is the change we’re looking for!
Go back to the annotate buffer (
l to view the log message for
this revision. See, readline’s “Meta-#” binding dates back to version 2.1! If
you want some context you can press
D (that’s shift-d) to view the diff
of all files changed in this revision.
Of course, annotate is more useful when the commits are more granular and the commit messages are more descriptive, with links to bug tracker entries and so on. But you get the idea.
Right now I don’t expect you to remember all these keybindings, but I do expect you to know how to find them when you need them.
ediff is a more powerful mode for viewing differences between files or
Switch to buffer rl.c if necessary.
M-x ediff-revision. Accept the default values of rl.c, its latest revision,
and its current state.
? for help. Figure out how to step through each diff. Figure out how
to show the files side-by-side.
q when you’re done.
ediff-revision you can supply any two revisions, not just the
latest revision and the current working copy. You can also diff any 2 buffers
ediff-buffers) or files (
I suggest you stay away from
ediff-directories (if you want to know why, try
etags is a program that indexes source files and creates a
TAGS file that
Emacs can use to find definitions of variables, functions and types.
The Makefiles of most open-source projects include the
TAGS target. For those
that don’t, you can use a combination of
etags from the
shell to generate the
TAGS file manually (read the man pages for those tools
if you need to).
etags you just ran was probably the one that shipped with Emacs. There’s
an alternate implementation called “Exuberant ctags” that supports more languages. Install it with
your package manager (e.g.
yum install ctags) and call it with
Back in Emacs, invoke
rl_insert_comment as the
tag to find, and then the location of the
TAGS file you just generated.
From the help for
find-tag, figure out how to jump back to the location you
were at before invoking the command, and how to find the next match if there
is more than one. (You might find the documentation from
C-h F find-tag
clearer than that from
To use a different
If you’re a C++ programmer, you’ll soon find that
etags is not
perfect when it comes to classes and namespaces. As a 90% solution, it’s good
enough, most of the time. Hopefully someone will come up with a clang-based indexer sometime soon.
We’re going to run the
rl program under the GNU debugger, gdb.
readline and then in
The compilation should succeed, as long as you haven’t introduced any errors in any of the source files. If you have, you know how to view and back out your changes.
M-x gdb. When prompted for the command-line to use, specify the program
examples/rl as an argument to
gdb: if you’re in the
directory, the command-line will look like
gdb ‑‑annotate=3 ./rl. The default
gdb may differ on your system so you may want to use them
You are now running
gdb inside Emacs, so the standard
gdb commands apply.
Let’s set a breakpoint in the
readline function, start the
rl program, and
when we reach the breakpoint step through a few lines.
Type the following commands at the
Note how Emacs displays the corresponding source file and line in a separate window.
The above commands are all interpreted directly by the
allows you to abbreviate them to
respectively. Pressing return on an empty line repeats the previous
command—useful for multiple
For serious debugging, Emacs can open additional windows showing the current
stack frames, breakpoints, local variables and registers. See the Emacs manual
C-h r opens the Emacs manual in the Info browser, then search
for the chapter titled “GDB Graphical Interface”.
You may be feeling somewhat overwhelmed at this point. Spend a few days using
Emacs as your main editor, painful though it may be, before moving on to the
next chapter of this guide. If you’ve forgotten a command I’ve taught you, try
to figure it out yourself (use
C-h k and
before looking it up here.
As part of your commitment to learning Emacs, try to run your shell within Emacs as much as possible. (If you need help configuring your shell to work well within Emacs, or configuring Emacs to work well with your shell, we will revisit shell-mode in the “General customization” chapter of this guide.)
: On Windows you will need a shell provided by Cygwin or similar.
These keybindings aren’t arbitrary.
C-c C-s mirrors
C-x C-s, which you
already know for saving the entire buffer to a file (“global” keybindings
tend to start with
C-c is a prefix for mode-specific
C-M-l performs a similar function in other editing modes—in
c-mode it tries to bring into view the whole function surrounding the point.
If you’re feeling overwhelmed by the number of keybindings to memorize, don’t
worry; you can always find them again with
On Windows you will need
grep commands provided by Cygwin or
: I haven’t tested this on Windows, but I’m assuming that Cygwin installs the necessary compiler, headers and libraries.