Using Emacs is kind of like making a piece of art. You start with a big block
and you slowly chip away, bringing it closer and closer to what you want. —
Mary Rose Cook
[Emacs is] a Lisp Machine with several compatible user interface modalities.
Which is just amazingly helpful to [blind] people like me […] who are
typically forgotten about these days. […] Emacs is a shining beacon in a dark
age of canvases and decorative user interface design. — Mario Lang
It wouldn’t make sense to start out with anything other than Emacs. I don’t
think there has been a piece of software which has had a larger impact on my
life. I began using this about fifteen years ago, and it has followed me across
operating systems, jobs, roles (I used it to manage my teams), languages, and
needs. Every time I start something new, Emacs has been there to make it just a
little easier, and the more I do in it, the easier everything gets. I believe
this power comes from Emacs being the closest thing we have to a working Lisp
Machine. — Katherine Cox-Buday
Emacs outshines all other editing software in approximately the same
way that the noonday sun does the stars. It is not just bigger and
brighter; it simply makes everything else vanish.
— Neal Stephenson
Emacs is the King of Editors because it’s a Lisp interpreter.
Each and every key you tap runs some Emacs Lisp code snippet, and since
Emacs Lisp is an interpreted language, that means that you can configure
any key to run any arbitrary code. You just, like, do it. — Lars Magne Ingebrigtsen
I’m using Linux. A library that Emacs uses to communicate with Intel
hardware. — Erwin, #emacs, Freenode
OSs and GUIs come and go, only Emacs has lasting power. — Per Abrahamsen
I am large, I contain multitudes. — Walt Whitman
Table of Contents
- PREFACE
- FUNDAMENTALS
- Introduction
- Emacs as Operating System
- Quickstart
- The Fundamental Emacs Concepts
- The Keyboard and Key Bindings
- Files, Buffers and Windows in Brief
- Selecting Text: the Point, the Mark, and the Region
- Cutting, Copying, and Pasting
- Editing with Textual Objects
- Other Ways to Move Around
- Variables and Symbols
- Help, Discovery, and Documentation
- Info: The Emacs Documentation Reader
- Messages, Errors, and Lossage
- The Minibuffer
- Completion
- What is Text?
- Buffers
- Modes, Major and Minor
- Application Buffers
- UNFINISHED Windows
- The Mode Line in Detail
- Frames
- Files
- Visiting Files
- Find File at Point
- Persisting Files Across Sessions
- Large Files
- Saving Files
- Read-Only Buffers, or, Emacs is More
- Reverting Buffers
- Auto-Reverting (Watching Files)
- Backup Files
- Auto-Save Files
- Lock Files
- Files Modified Behind Emacs’s Back
- Compressed Files
- Encrypted Files
- Archive Files
- Document Files (PDFs and the Like)
- Image Files
- Binary Data Files
- UNFINISHED Quoting File Names
- UNFINISHED Filesets
- References
- Directory Editing with Dired
- Basic File Operations
- Subdirectories
- Compressing and Archiving Files
- Deleting Files by Flagging
- Marking Files
- The Mark Keymap
- Mass Name Changes by Regular Expression
- What Went Wrong?
- Writable Dired
- Two-Panel Dired
- Searching and Replacing
- Diffing and Comparing
- Reverting and Sorting the Dired Buffer
- Omitting Uninteresting Files
- Running External Commands
- Image-Dired
- Tagging and Commenting Images
- Remote Directories
- More Dired Entry Points
- Third-Party Directory Tools
- References
- Searching …
- Incremental Search
- Failing Searches and Making Corrections
- Editing Your Search
- Aborting Your Search
- Quick Search Exit
- Scrolling
- The Region is Set for Free
- Changing Directions
- Restarting Your Last Search
- Searching for Funny Characters
- Case Sensitivity and Whitespace
- Varieties of Isearch
- Nonincremental Search
- Yanking Into the Search
- Transitioning to Other Search Types
- Help
- Occurrences
- Multi-Buffer Searching
- Incremental Search
- … and Replacing
- Meet the Greps
- Regular Expressions
- Unlimited Undo with Redo
- Approaching Programming: Keyboard Macros
- The Customize Facility
- The Package Manager
- Updates and Bugs
- Exiting Emacs
- Starting Emacs!
- ADDITIONAL TOPICS
- Completion at Point
- Registers
- Rectangles
- Bookmarks
- Abbreviations
- Recursive Edit
- Visual Display and Color
- Manipulating Plain Text
- Folding Text
- International Character Set Support
- Remote File Editing with Tramp
- Client / Server
- UNFINISHED Ubiquitous Capture
- UNFINISHED Printing
- UNFINISHED Org Mode
- UNFINISHED Third-Party Packages
- UNFINISHED Security Concerns
- UNFINISHED Authentication
- Programming the Lisp Machine
- The Emacs Community
- NEVER LEAVE EMACS: APPLICATIONS
- External Commands, Shells and Terminals
- Running One Command
- Which shell is being used?
- Where’s the output?
- What happens to the output Buffer if I do
M-!
twice? - What do you mean, synchronously?
- Isn’t there an easier way to insert command output?
- What about standard input?
- Can I run any program this way?
- What if I don’t want to wait?
- Managing Asynchronous Processes
- Run Commands from Dired
- Interactive Shells
- Terminal Emulation
- Remote Shells
- Eshell
- Running One Command
- Browsing the Web
- The Calendar, Diary, and Clocks
- Version Control
- Supported Version Control Systems
- VC “Modes”
- VC File Mode in One Command
- More VC File Mode Commands
- Initializing a Repository
- Diffing and Comparing
- Examining the Logs
- Viewing Older Revisions
- Discarding Changes
- Other File Operations
- Tagging
- Branching and Merging
- Working With Remote Repositories
- VC Project Mode
- VC Grepping
- Diffing and Merging
- Playing Music
- UNFINISHED Mail, News, and Feeds
- UNFINISHED Address Book: The Insidious Big Brother Database (BBDB)
- UNFINISHED Drawing Pictures
- UNFINISHED DNS Lookups
- UNFINISHED EUDC: Emacs Unified Directory Client (LDAP)
- UNFINISHED FTP (File Transfer Protocol)
- UNFINISHED Editing Processes with
proced
- UNFINISHED Unix Manual Pages
- UNFINISHED Calc
- UNFINISHED EasyPG Assistant
- UNFINISHED Emacs Speaks Statistics: Data Analysis
- UNFINISHED Maps
- UNFINISHED Chat
- UNFINISHED Emacs as Window Manager
- Games and Amusements
- External Commands, Shells and Terminals
- EMACS FOR…
- THE BACK OF THE BOOK
- Appendices
- Bibliography
- Colophon
- Acknowledgments
- About the Author
PREFACE
This document was originally written around 1997 for GNU Emacs version 19.29 and
published under the title A Tutorial Introduction to GNU Emacs. It has
subsequently been updated for version 28.2, and
thoroughly revised and expanded. This is document version 28.2.43 and is an
unfinished work-in-progress.
This work by Keith Waclena is copyright 2023 and is licensed
under a CC BY-NC-ND 3.0 License.
FUNDAMENTALS
Introduction
What GNU Emacs Is
GNU Emacs is a free, portable, extensible, internationalized, self-documenting
text editor. That it is free means specifically that the source code is freely
copyable and redistributable, so Emacs can never be discontinued and disappear.
That it is portable means that it runs on many computers under many different
operating systems, so that you can probably count on being able to use the same
program no matter what computer you’re using. That it is extensible means that
you can not only customize all aspects of its usage (from keystrokes through
fonts, colors, mousage and menus), but that you, and the community, can modify
and program Emacs, even while Emacs is running, to do entirely new things that
its designers never thought of. That it is internationalized means that it has
full Unicode1 support, including bidirectional text and many input methods
for non-Latin scripts. That it is self-documenting means that every keystroke,
menu item, and function can thoroughly explain itself and its usage, and that
Emacs contains 395,759 lines of hypertext reference manuals and
tutorial documentation about itself and its subsystems.
Because of all this, GNU Emacs is an extremely successful program (having been
in continuous development for 38 years2),
and does more for you than any other editor. It’s particularly good for
programmers. No matter what programming language you use, Emacs probably
provides a mode that makes it especially easy to edit code in that language,
providing syntax highlighting, context sensitive indentation, and layout. It also
allows you to compile your programs inside Emacs, with links from error messages
to source code; debug your programs inside Emacs, with links to the source;
interact directly with the language interpreter (REPL); jump across multiple files to
the definition of a symbol in your source code; and interact with your version
control system3.
Emacs also provides many built-in applications such as:
- mail readers (at least half a dozen)
- web browsers (at least two)
- a powerful file manager like Windows Explorer (File Explorer) or Apple’s macOS Finder
- interactive shells, logins (ssh, ftp, sudo), and terminal emulators
- a powerful and easy to use macro system to automate your tasks
- diffing and merging of files
- calendars, project planning, TODO lists, scheduling, and agendas
- a powerful infinite precision programmable calculator with symbolic algebra and data graphics
- image, PDF, DVI, ebook (EPUB), OpenDocument, Microsoft Office, and PostScript
viewers (via DocView Mode), and inline images in plain text - typesetting and publication of text or source code to HTML, PDF, and
presentation slideshows (this document is an example) - literate programming
- interactive notebooks: that is, documents that contain live code, data,
equations, visualizations, and text - client / server mode (connect to a running local Emacs from any terminal, or
to a remote Emacs running on a different computer) - multilingual spell checking, dictionaries, and thesauri (available in all of
the above applications and subsystems, too) - transparent editing of encrypted and compressed files, and of files inside
containers (like tar and zip archives) - remote file editing (any file or directory you want to edit can be
transparently accessed via ssh, ftp and the like) - spreadsheets (three)
- music players (at least half a dozen)
- chat / messaging systems (like IRC, Jabber, Slack)
- native Emacs games and interfaces to external games
- a Rogerian therapist (in case this is all a little overwhelming)
In addition, Emacs’s extensibility has resulted in a vibrant ecosystem; users
share packages that provide new functionality, and it’s easy to browse a few
thousand of these via the built-in package manager, and install the ones of
interest. Many more Emacs packages are available on GitHub and in the Emacs
Wiki.
The image above shows Emacs “in use”. It’s a little unrealistic in that I, at
least, never want that many windows open simultaneously, but it’s a real screen
shot. Going across the columns from left to right, we have email (a folder
and a message) and an agenda from my project planner; OCaml source code with a
compilation error message and a type-throwback window; a Google search in one of
Emacs’s web browsers above a PDF; and finally, a directory in the file manager,
a shell, and a paused game of Tetris.
At the very bottom of the screen, I’m in the middle of typing an Emacs command
by its name (M-x list
), and have hit TAB
to get completion — the completions
window has temporarily popped up and spans the width of the screen.
In the grey mode line along the bottom of the completions window (and
replicated, albeit truncated, in slightly different form at the bottom of every
other window) you can see that I have incoming email that I haven’t yet seen
(red envelope icon) and an unseen chat message from someone named “Tex”.
What GNU Emacs Is Not
First and foremost, Emacs is not a WYSIWYG word processor. This is because
Emacs leverages plain text to get maximum flexibility and avoid lock-in to
opaque file formats. But Emacs is also used to edit and typeset documents by
people who use document preparation systems and markup languages like LaTeX,
Markdown, and Emacs’s own Org markup language4.
Actually, this is about the only thing I can think of that GNU Emacs is not.
Emacs as Operating System
Emacs is one of those rare pieces of software that can change your life. It’s
not really a text editor, nor an IDE. It’s really the last remaining Lisp
Machine, a synergistic system that you live in, which replaces most of the
dozens of single-purpose applications you’d otherwise be using, some of which
lock you into black-box file formats or corporate licensing.
The more things you do in Emacs, the more those things multiplicatively enhance
each other.
Imagine you use Emacs (as I do) for your document creation, web site publishing,
interactive development environment (IDE), email, TODO lists, file manager, web
browser (sometimes), shells and terminals, calendar and agenda, and chat system.
As a result, in all of these:
- you use the same exact completion system (with history), whether entering
command names, file names, email addresses, or web urls - you search with the exact same regular expression syntax and the same
keystrokes - you can copy any text from anyplace5
- you can search across all or a subset of the windows running these
applications at once (“which window did I see that error message in?”; “which
browser tab is that text in?”) - you can dynamically highlight lines and words in various colors to make them
stand out or distinguish between them - you automate tasks within and across all these systems with the same macro facility
- you have the same spellcheck interface and dictionaries
- after a restart (we all have to reboot occasionally), you can have most of
these windows and files come back with everything (down to your cursor
location) exactly where you left it - you configure and customize all these applications in the same configuration
language (and in a single file, unless you choose to split it up), and the
language is a complete programming language - you can modify, extend, fix bugs, and generally hack all of these
applications, live, while they’re running - you can program entirely new applications by combining functions and elements
from any of the others
Emacs insulates you from the operating system. If you full-screen your Emacs,
you will barely be able to tell whether it’s Linux, BSD, Mac OS, Windows, or ChromeOS
underneath. You can use the same configuration everywhere, and since the config
language is Lisp, you have conditionals to make any OS- or computer-specific
tweaks that might be necessary. You can even load your config over the network
— from a web page if you like.
Quickstart
Installing Emacs
If you are running Unix, Emacs may already be installed. If not, it will
certainly be easily installed via your package manager.
Arch Linux | sudo pacman -S emacs-nativecomp |
Debian | sudo apt-get install emacs |
Fedora | sudo yum install emacs |
Ubuntu | sudo apt-get install emacs |
When I last used Mac OS X, Emacs came preinstalled, but was very out of date.
You could install an up-to-date version via one of the Mac’s many third-party
package managers (such as Homebrew), but I recommend David Caldwell’s Emacs For
Mac OS X6; it’s always up-to-date, and, as Caldwell says, is “Pure Emacs!
No Extras! No nonsense!”. I would discourage you from using Aquamacs, which
attempts to make a more Mac-like Emacs but ends up rendering it painful to use
(IMHO).
If you are running Windows, I recommend the Free Software Foundation (FSF)’s
Windows build, available from the download page7. You can also install
Emacs in the Windows Subsystem for Linux (WSL); just follow the instructions
above for whatever version of Linux you chose. See the Appendix for how to
install Emacs on a Chromebook; you can even install Emacs on your Android phone.
For the cheapest possible complete Emacs computing environment, you can run
Emacs on a $100 Raspberry Pi that comes with a keyboard, mouse, and cable to
connect to your TV.
And, since Emacs is free software, you can of course download and compile your
own copy from source.
Starting Up and Running Emacs
Emacs can run in two different modes: a graphical version, which requires a
window system like X11 (or the Mac or Windows native interface), and a
“text-only” terminal version, like old-school Unix programs such as vi
or vim
.
I say you should run the graphical version; in the terminal version (forced
via the -nw
(“no windows”) option if a window system is running), you won’t be able to
display images or combine multiple fonts, and many useful key combinations will be
impossible to type, requiring clunkier alternatives8. Mouse-button and
-motion combinations will be severely limited.
Note that using the graphical version doesn’t imply working in a GUI style with
heavy mouse action; I never use the mouse, and configure my Emacs so that the
graphical version looks like vim
in a terminal (right down to my beloved
fixed-pitch font). However, because I’m running the graphical version, I get
better font and character set support, can view images and PDFs, and make use of
all the exotic keys on my keyboard. If what you like about an editor such as vim
is the way its invocation is tightly bound to your shell and working directory,
or its fast startup speed, running the graphical Emacs in client / server mode
achieves exactly the same thing.
Unless you go out of your way to change this (e.g. with -nw
), the graphical
version is what you’ll get if you invoke Emacs from an X11, Mac, or Windows
desktop launcher, or from a shell in a terminal under one of those desktops. This
book everywhere assumes you’re running the graphical version.
Entering Emacs
To enter Emacs, you just say:
emacs
on the command line, or invoke it from your desktop via a launcher, menu or
icon9. When it comes up, you won’t be editing any file. You can then use
the file commands to read in files for editing. Alternatively, you can fire up
Emacs with an initial file (or files) by saying:
emacs foo.py
Note that for many Emacs users, starting Emacs is something that’s done very
rarely: I only do it when I’ve needed to reboot my computer. You don’t use
Emacs the way you use vim
, starting it in a shell to edit one file, then exiting
to compile, then lather rinse repeat. Loading and unloading files, compiling,
debugging, file management, version control, and everything else is done inside
Emacs with special commands that provide very tight and seamless integration.
If you really prefer to work
in a many-sessions, multi-terminal style after trying the native Emacs approach,
the way to do it is via client / server mode: start up an Emacs server, and then
repeatedly run emacsclient
in your terminals as you navigate around, just the
way you’d run vim
.
Exiting Emacs
You can exit Emacs from the menu via File / Quit, or type the two keys Control+x
followed by Control+c (which we write as C-x C-c)
. If you’ve made any changes to a
file, you’ll be asked if you want to save them.
What Emacs Looks Like
The Screen
If you started up Emacs without loading a file, you’ll be looking at the splash
screen 10; this is not something you’ll see in everyday use. Otherwise,
you’ll be looking at your file.
The default Emacs screen looks pretty conventional, if old-fashioned: it has a
menu bar at the top, a toolbar beneath that, and a scrollbar on the left (you
can ultimately disable any of these; I have, and my Emacs has the clean retro
look of vi
); the rest of the screen is completely devoted to the text of your
file, except for the bottom line of the screen — the echo area — and the
line above that — the mode line.
The Mode Line
The Mode Line displays some essential information, in particular the name of the
file you’re editing and whether or not you’ve modified it, what line you’re on,
and what Mode you’re in. It’s completely customizable and can show lots of
other information too, such as the time, load average, mail availability (biff),
and version control status. See The Mode Line in Detail below.
The Echo Area
The blank line below the mode line is the Echo Area. The Echo Area is used by
Emacs to display short messages, and also for input when Emacs is prompting you
to type something (it may want you to type yes or no in answer to a question,
the name of a file to be edited, the long name of a command, etc). Unless you
are actively using the mouse, Emacs will typically not use a modal dialog box
for this sort of thing.
Using Emacs Like It’s Notepad?
Emacs has a reputation of being difficult to use, but in fact anybody can
readily use Emacs out of the box with no instruction11 by using the menu
bar and toolbar. Simply choose File / Open File from the menu; for common
programming languages, you’ll see syntax highlighting automatically. Navigate
conventionally with the scrollbar, mouse, and the Page Up, Page Down, and arrow
keys. To insert text, just start typing (Emacs isn’t modal like vim
(not by
default, anyway12)); delete text with Delete or Backspace. Finally, choose
File / Save and then File / Quit from the menu.
This ought to sound extremely familiar.
And pretty boring. You may not be impressed, but you’ll be able to get a lot of
work done right away.
But if you want to use Emacs efficiently and give it a chance to change your
life, you need to learn to control it the way it was originally designed: via
the keyboard.
The enormous Emacs keyboard command set is indeed daunting. Fortunately, you
can learn the keystrokes incrementally, using the menus for things you don’t
yet know how to do. Eventually, you may stop using the menus entirely; I turned
off the menu bar, tool bar and even the scroll bars years ago to save screen
real estate and haven’t missed them.
Configuring Emacs
Don’t. Yet. Emacs is all about customizing and making it act the way you want,
but in my opinion, you should learn the basics in a stock, mostly uncustomized Emacs,
so that if you have questions or problems and look up an answer, that answer
will apply to you.
In recent years, there’s been something of a cottage industry in Emacs “starter
kits” (such as Prelude, Doom Emacs, Emacs Starter Kit, Spacemacs,
etc13): distributions that give you a heavily pre-customized, sexy-looking
Emacs to fix what are perceived to be “old-fashioned defaults” and load and
start up everything you could conceivably want. I would avoid these at first for
the same reason14. In fact, some of these starter kits change so much about
the experience that large parts of this book will appear to be completely
inapplicable to you, so bear that in mind.
I hope browsing this book will convince you that there’s great stuff to come,
and that therefore you’ll be able to resist immediately adding a million bits of
other people’s configuration tweaks and third-party packages for just a little
while, until you get up to speed with the basics.
However, there are a few places where I do recommend some
customizations that I think make a significant improvement to the
Emacs experience, even while you’re learning. These will pop up from
time to time and are all collected together in an appendix.
My own Emacs is so heavily customized from decades of use that I can barely
function in a stock Emacs! I’m all in favor of customizing15, but don’t jump in
too early.
The Built-In Emacs Tutorial
If you want to dive in immediately and start using Emacs as it ought to be used,
now is a good time to run the built-in learn-by-doing Emacs tutorial. This is a
simply a special text file that explains some basic Emacs commands and has you
try them out, explaining how to get back to where you were and continue. It’s
very effective and you don’t have to finish it all at once — it’ll remember
where you left off for next time.
If you fire up Emacs without a filename and are looking at the splash screen,
you’ll notice that your cursor is sitting right on a “clickable” button labeled
“Emacs Tutorial” — just hit return or click the label with the mouse and the
tutorial will start up.
If you aren’t looking at the splash screen, you can start (or continue) the
tutorial at any time by typing C-h t
(that’s Control+h followed
by the letter t). If you type instead C-u C-h t
Emacs will ask what national
language to use for the tutorial; it’s available in twenty languages: Brazilian,
Portuguese, Chinese, Czech, Dutch, English, Esperanto, French, German, Hebrew,
Italian, Japanese, Korean, Polish, Romanian, Russian, Slovak, Slovenian,
Spanish, Swedish and Thai. The default is to use the language of your computing
environment, if available.
The Fundamental Emacs Concepts
To really make Emacs work for you requires an appreciation of its fundamental
concepts and how they work together to form a synergistic system.
Functions
Everything you do in Emacs involves the invocation of functions16 and these
functions take arguments and have help and documentation.
The Keyboard and Key Bindings
Most of the time you invoke these functions with simple keystrokes — even just
typing a single letter into a file invokes a specific function, as do all the
editing operations (like deleting a word), and all things like opening files or
setting a reminder or sending an email. Most of these functions are associated
with keystrokes in a malleable, context-sensitive hierarchical organization with
an (at least aspirational) mnemonic scheme.
Variables
Emacs also contains variables exactly like those of any programming language,
which store a huge variety of data. Most of them are used only by programmers,
but a subset of them are Customizable Variables (a.k.a. User Options), which
you’ll use to configure Emacs to your liking. These variables aren’t something
that you just set up once in a configuration file: you’ll soon be comfortable setting
and inspecting them on the fly as you’re using Emacs.
Discovery, Help and Completion
No one wants to memorize all the thousands of Emacs key bindings17,
including those they might use only weekly or monthly. Less frequently used
functions are invoked by name with a powerful and extensible completion system,
unknown functions are discovered with the Apropos facility, the Help system
tells you how to use them, and the Info hypertext documentation system provides
even more complete discursive documentation (and there’s a clickable link from
the help for any function to its source code, if you really want to know what’s
going on).
Buffers
The text of any file you’re editing is stored in a Buffer. But so is almost
everything else: documentation, error messages, and the user interfaces (UIs) to
the many Emacs subsystems (file managers, email, REPLs, etc). This means that
to a great extent you can manipulate a UI using the same commands you use to
manipulate the text you’re editing, which is very powerful and means you have
less to learn.
Plain Text
The power of the Buffer is due to the fact that Emacs prioritizes plain text.
Almost everything you see in Emacs is plain text. This doesn’t mean everything
looks plain; the typical Emacs Buffer is colorized, uses a variety of fonts and
possibly character sets, and may include “clickable”18 buttons, read-only
sections, dynamically updating data, icons and full-size images, and more: but
the Buffer still consists of plain text and the enhancements are applied on top
of it.
Windows
Windows are the viewports into your Buffers. You can have an arbitrary number
of open windows at any time, divided up horizontally and vertically, and Emacs
acts like a tiling window manager to manage them for you.
Search
Emacs has a very wide variety of search commands which do more than simply find
the next occurrence of “foo” in your file. You can search within a Buffer,
across multiple Buffers, across files that aren’t loaded into Emacs yet, and
across the web. You can search back in time by searching version control
history. You can search more than just files: since Emacs subsystems (like
calendars, shells, and email) run in Buffers, you can search their user
interfaces and outputs. You can search all the Emacs documentation, and you can
search for things by their names as well as by what they contain. Searches can
take you directly to a match or pop up a Buffer of all the matches (rather like
a page of Google search results), from which you can jump to the actual
locations. All these searches come in a flexible variety of modes (fixed text,
lax spacing, case- and diacritic-folding, word search, regular expression, and
more), and since you’re doing all this searching in Emacs rather than in a dozen
distinct programs, they share the same options and syntax.
Undo and Redo
While common now, unlimited Undo with redo probably debuted in Emacs in the
early 1980s. You can undo all changes (even back through file saves) and redo
them (undo the undo) all the way forward again, in any combination (you can undo
the redo of the undo of the undo). Undo is smart in that it groups togther tiny
changes (e.g. consecutive single-character insertions) to make undoing less
tedious, and commands that make big structured changes (like search-and-replace)
arrange for undo to happen in sensible units. There’s an alternative Undo that
works in a tree-structured manner. Most powerful is that you can mark off a
specific subregion of the Buffer, and then undo only the changes made within
that region (even if you’ve since made other changes elsewhere).
Major and Minor Modes
Every Buffer has a Major Mode that’s specialized for some particular sort of
text. The specializations typically affect the visual display of the text,
tweak general-purpose commands to better suit the text, and provide key bindings
for new commands written specifically to work with that kind of text. The
classic case is a Major Mode for editing the source code of a given programming
language — for example, the mode specializations of python-mode
turn Emacs
into a Python IDE.
In addition to Major Modes, we also have Minor Modes. A Major Mode implements
sweeping specializations — you wouldn’t want to edit HTML in python-mode
—
but Minor Modes are like mix-ins: each Minor Mode implements some sort of tweak
to behavior or appearance that’s usually suitable to add to any number of Major
Modes. While any Buffer has exactly one Major Mode, you might turn on a few
dozen Minor Modes as well. Minor Modes can implement additional varieties of
navigation, formatting, indentation, highlighting, templating, diagramming,
spellcheck, footnotes, tables, outlining, text folding, hypertext linking, and
much more.
My Emacs at the moment has 638 major and minor modes ready to be
enabled.
Customization
One of the hallmarks of Emacs is that virtually every aspect of it can be
customized. Not only can you customize fonts, colors, and keystrokes but you
can customize them all differently in different parts of Emacs (one font set for
Python, another for Haskell). Conversely, if you use Emacs for your email and
someone mails you a snippet of Python, you see it, in the email, colorized
according to your preferences. Emacs customization is sometimes thought of as
unfathomable unless you’re a Lisp programmer, but for decades Emacs has had an
interactive forms-based customization system (called Customize) that lets
anybody easily tweak anything.
Programmabililty
But if you are willing to learn a little Lisp (or a lot), you can also customize
Emacs in the programming language that it’s implemented in, Emacs Lisp
(a.k.a. Elisp); having used Emacs since before the Customize system existed,
I still do all my customizations this way.19 But with Elisp you can go well
beyond mere customization: you can add completely new features to Emacs that
never existed. This could range from three lines of code to add an
idiosyncratic way of scrolling text (I’ve defined a keystroke to scroll by
paragraphs) to building large software systems that would, in a non-Emacs
universe, be standalone applications. The popular Magit front-end to the Git
version control system comprises 30,000 lines of Elisp code. Gnus, one of
several Emacs mail readers, comprises 117,485 lines! Emacs itself is about 79%
Elisp (the rest being a C core that implements the Lisp interpreter).
Note that Emacs Lisp isn’t an ad hoc scripting language invented for use in just
one editor. It’s a dialect of the famous programming language Lisp, which means
it has a decades-old well-designed syntax and semantics. It’s a real
programming language: in addition to the multiple books and articles written
about Elisp, you can also learn from the hundreds of books and articles written
about Lisp itself. And, what you learn about Elisp sets you on the way to
becoming a real Lisp programmer.
But if you’re not interested in learning Lisp, you can still program your Emacs
via the incredibly powerful macro system called Keyboard Macros. You simply
start defining a macro, perform a sequence of editing actions (e.g., search for
a keyword, capitalize it, delete the next two words, and add another word at the
end of the line), then indicate you’re done. Now a keystroke runs the macro to
repeat those actions. Once you’re convinced it’s working, you can tell Emacs to
repeat the macro until it’s processed everything. Macros aren’t limited to
operating on just one Buffer: you can use any Emacs commands in defining one,
and so can switch Buffers mid-macro at will.
But Emacs goes well beyond the capabilities of most macro systems. Since
invoking an external shell command is a basic capability of Emacs, you can do
that in your macro and use the result. You can have many macros defined at
once. You can edit your macro (rather than having to redefine it) if you
discover it’s not quite right. You can save your macro with a name for use in
future Emacs sessions. A macro can count (to do things like numbering). It can
ask for confirmation of a step, or allow you to do a localized tweak at
each invocation. All this without being a programmer.
Free Software
Finally, GNU Emacs is free software. This doesn’t mean that you don’t have to
pay for Emacs (though you don’t). It means that the project is built upon what
the Free Software Foundation (FSF) calls the “four freedoms” — the freedom to
(0) run the program, (1) study and change the program in source code form, (2)
redistribute exact copies, and (3) distribute modified versions. The FSF
achieves this via the frankly amazing invention of the Copyleft license.
Without it, Emacs probably wouldn’t exist as the long-lived, continuously
improving project that it is. And it assures that Emacs can never be taken away
from you by any corporate entity.
The Keyboard and Key Bindings
It makes sense for someone who spends most of their time manipulating
text to learn a group of obscure key combinations. It saves time and
increases productivity. Learning to use Emacs properly reminds me of
playing Jazz on the piano. I’ve learnt all those chords and runs and
fills so that I can use them without thinking when I’m improvising.
Likewise, I’ve practised using Emacs key strokes such asM-f
, [M-c
]
andC-M-
so often I use them without thinking when editing. I
rely onM-/
to complete words, and I can’t do withoutM-h
andC-e
to
select and move around text. — Tony Ballantyne (SF and Fantasy Writer)
For Emacs, every keystroke is actually a command (i.e., a function that does
something), even simple keystrokes like the letter A: printing characters like
this are commands to insert themselves into your text. Non-printing characters
(like control characters) are editing commands, which might move the cursor,
scroll some text, delete or copy text, rename a file, initiate sending an email,
etc.
Every command has a long name, which you can look up in the documentation, like
kill-line
, delete-backward-char
, or
self-insert-command
. Many commands are bound to keystrokes
for convenient editing. We call such a pairing of keystroke and command a key
binding, or binding for short.
The set of all bindings make up the Emacs command set. However, Emacs is an
extensible, customizable editor. This means that:
- bindings can be different when editing different types of text, by virtue of
extensibility - bindings can be different for different users, by virtue of customizability
In this document I describe the standard, uncustomized, Emacs key bindings.
Notation
I use the standard Emacs notation to describe keystrokes:
C-x
- For any x, the keystroke Control+x.
M-x
- For any x, the keystroke Meta+x (see below for more details on Meta
keystrokes). C-M-x
- For any x, the keystroke Control+Meta+x (which is exactly
the same as Meta+Control+x.). S-x
- For any x, the keystroke Shift+x
s-x
- For any x, the keystroke Super+x20
RET
- The return key.
SPC
- The space bar.
ESC
- The escape key.
Control, Meta, and Super are modifier keys, i.e. they only take effect when held
down simultaneously with another key, exactly like Shift. If you hold down
Shift, Control, or Meta alone, and then simply release it, Emacs doesn’t even
know you’ve done so: you must add a non-modifier key for the combination to
register as a keystroke. You can combine as many modifier keys together as you
have fingers for.
Your keyboard may have even more modifier keys. Emacs is aware of these other
modifiers but doesn’t have any standard bindings that use them (you can use them
for your own purposes though). In fact, because of arbitrary differences
between the keyboards of different computer manufacturers21, Emacs’s Meta
modifier really stands for “your preferred non-Control modifier key”.
We don’t typically mention Shift as a modifier key, usually just writing X
instead of S-x
, and only use the S-
notation occasionally for disambiguation or
emphasis. The S-
modifier can of course be combined with other modifiers
(e.g. S-M-x
, which is equivalent to M-X
, or S-C-M-5
, which is equivalent to
C-M-%
). Unless you choose to make a distinction with a custom binding, Emacs
almost always equates a shifted letter in a keystroke with the lowercase version
of the same keystroke: so for example both M-x
and M-X
(a.k.a. S-M-x
) are
equivalent: both invoke execute-extended-command
. See
Shift Selection for the only major exception.
Simple Keys
There are 95 different basic printable characters22, and they are all bound to
self-insert-command
so that they insert themselves as text
when typed. For editing commands, Emacs uses all the control characters: C-a
,
C-b
, etc. But this is only 32 characters, and Emacs has more than 32 editing
commands.23
To provide access to more key bindings, Emacs uses a Meta key24. This gives
us access to keystrokes such as M-a
, M-b
, etc.
Since Control and Meta are both shift-like modifier keys, what happens if you
hold down both and then type a key? These combinations are valid keystrokes as
well; they are notated C-M-a
, etc. Because both Control and Meta are modifier
keys, C-M-a
must necessarily be the same keystroke as M-C-a
. For consistency we
always write the former.
Prefix or Compound Keys
The Control and Meta keys plus the printing characters give us 256 possible
keystrokes25, or 160 editing commands after eliminating the self-inserting
characters. But Emacs has many more than 160 commands! To handle this we also
use prefix commands. A prefix command is a keystroke that, when typed, waits
for another keystroke to be typed, making a pair (sequence) of keystrokes bound
to one command. Each prefix command adds another 256 keystrokes that we can
bind commands to. Prefix commands often group together commands that are
somehow related.
The most important prefix commands are:
C-h
- The help prefix, used for Help commands.
C-x
- The extended prefix; this prefix is used mostly for commands that
manipulate files, buffers and windows. C-c
- The context-specific prefix. Used for commands that are specific to
particular Modes, so they are free to be used for different commands depending
on context. This prefix also reserves a set of keystrokes specifically for
the user to use for their own purposes. These are the most variable of Emacs
commands.
These three prefixes give us another 768 keystrokes, for a total of 928. But
Emacs has far more than 928 commands! To handle this, you can bind one of the
subcommands of a prefix command to another prefix command, like C-x 4
for
example, or C-x v
, each such binding yielding potentially another 256
keystrokes. A number of these two-character prefixes exist, but they’re rather
specialized, and don’t contain a full set of 256 commands (usually there are
only a few, and the prefix is just used for a mnemonic grouping). There are
even three character prefixes, but most people won’t admit to using them.
Aborting a Command
What if you start typing a prefix, like C-x
, and then decide you didn’t mean it?
Emacs will be sitting there, showing this in the Echo Area:
C-x-
waiting for you to finish. You can abort this partially completed prefix by
typing C-g
(keyboard-quit
).26
You can also interrupt a command that’s asking you a question, or for
information (like a file name): if you type the command to open a file and it’s
asking you for the filename, but you’ve changed your mind, C-g
will abort it.
It will also interrupt a running command that you want to now stop. Perhaps
you’re editing a file and have initiated a search-and-replace operation, and
after several replacements, you see it was not what you wanted: C-g
will
interrupt it in the middle (and, of course, you can then Undo what you’d already
done).
Using Extended Commands
By now we’ve entered a sort of rarefied atmosphere: even the most hardcore
Emacs nerd doesn’t really use all these key bindings. Some Emacs commands are
used very rarely, and, when you need one, it’s easier to invoke the command by
typing its long name directly, using the completion system to remind you of the
precise name.
There’s one Emacs command that can be used to execute any other command by
typing its long name: M-x
(mnemonic: “eXecute” or “eXtended”). When you type
M-x
, Emacs prompts you, in the Echo Area27, for the name of any command (with
completion), even if that command is bound to one or more keys already, and then
executes it.
The prompt looks like:
M-x
and the completion works rather like that of any Unix shell, by typing an
initial part of the command and hitting TAB
28. So you might type:
M-x backw
and hit TAB
at that point; Emacs will partially complete this to:
M-x backward-
and if you then type:
M-x backward-sen
and hit another TAB
, it will complete the entire command (because the prefix is
now unambiguous):
M-x backward-sentence
Now you can hit return (RET
) to execute the command or if that’s not what you
meant, you can edit what you’ve typed (using any Emacs editing commands)
and keep completing as you go; of course a C-g
will abort the M-x
.
If you hit TAB
again at the point at which you’ve achieved a partial completion
(at the point of backw
or backward-
or backward-sen
above), Emacs will pop up a
transient buffer showing all the possible completions (you may discover some
surprising and interesting-sounding commands this way).
This can be a lot of commands! If you type M-x
and immediately hit TAB
, Emacs
will pop up a buffer showing all the interactive commands that exist at the
moment. In a stock Emacs, freshly started, this will be over 4,000 commands; in
my current Emacs session, with many third-party packages loaded, I get about
8,000.
When you see something like this “ M-a
(backward-sentence
)”
in this book, it means that the keystroke M-a
is bound (by default) to the
command backward-sentence
(in most Modes, or in the Mode I’m currently talking
about), and so at any moment you can use M-x backward-sentence
or M-a
, as you
prefer.
Too Many Commands?
How does anyone remember these 928 commands? Simple: you don’t. Every Emacs
user knows a different subset of commands. I’ve used Emacs for
44 years (starting with the original
TECO Emacs), and I learn useful Emacs commands that are new to me all the time.
Often I notice another Emacs user doing something and I have no idea how they’ve
done it, so I ask and learn some Emacs command that I just never came across, or
never developed as a habit, or once knew and forgot!
Some Emacs users just learn the most basic commands and are completely happy.
Most users learn the basics and then some advanced commands that suit their
needs. Some users are constantly learning new commands to speed their editing.
A nerdy few progress to writing their own totally new Emacs commands.
Giving Commands Arguments
Many Emacs commands take arguments, the way a procedure or function takes
arguments in a programming language. Most commands prompt you for their
arguments: e.g., a command to read in a file will prompt you for the filename.
There’s one kind of argument that’s so commonly accepted that there’s a special
way to provide it: a numeric argument. Many commands will interpret a numeric
argument as a request to repeat themselves that many times. For example, the
C-d
(delete-char
) command, which normally deletes one
character to the right of the cursor, will delete N characters if given a
numeric argument of N. It works with M-x
commands and self-inserting commands
too: try giving a numeric argument to a printing character, like a hyphen.
To give a command a numeric argument of, say, 12, type C-u 12
before typing the
command. If you type very slowly, you’ll see:
C-u 1 2-
in the Echo Area. Then type C-d
and you’ll have given delete-char
an argument
of 12. You can type any number of digits after C-u
. A leading hyphen (C-u - 1
) makes a negative argument; a lone hyphen (
2C-u -
) is the same as an argument
of -1 (which makes many commands “go backwards” in some sense). If you begin
typing a numeric argument and change your mind, you can of course type C-g
to
abort it.
Because a numeric argument is given before you type the command, it’s also
called a prefix argument; see “Arguments” in the Emacs manual.
Since one often isn’t interested in precisely how many times a command is
repeated, there’s a shorthand way to get numeric arguments of varying
magnitudes. C-u
by itself, without any subsequent digits, is equal to a numeric
argument of 4. Another C-u
multiplies that by 4 more, giving a numeric argument
of 16. Another C-u
multiplies that by 4 more, giving a numeric argument of 64,
etc. So C-u C-u C-u C-d
would delete the next 64 characters.
C-u
can be used before any other command, and for this reason C-u
is called the
universal argument. But note that commands aren’t required to interpret numeric
arguments as specifying repetitions. It depends on what’s appropriate: some
commands ignore numeric arguments, some interpret them as Boolean (the presence
of a numeric argument — any numeric argument — as opposed to its absence),
etc. Read the documentation for a command before trying it.
Disabled Commands
Some commands that are especially confusing for novices are disabled by
default. When a command is disabled, invoking it subjects you to a brief
dialog, popping up a window displaying the documentation for the command, and
giving you four choices; for example:
You have typed C-x n n, invoking disabled command narrow-to-region. It is disabled because new users often find it confusing. Here’s the first part of its description: Restrict editing in this buffer to the current region. The rest of the text becomes temporarily invisible and untouchable but is not deleted; if you save the buffer in a file, the invisible text is included in the file. C-x n w makes all visible again. See also ‘save-restriction’. Do you want to use this command anyway? You can now type y to try it and enable it (no questions if you use it again). n to cancel--don’t try the command, and it remains disabled. SPC to try the command just this once, but leave it disabled. ! to try it, and enable all disabled commands for this session only.
If you invoked the command by accident, just hit n
. If you’re sure you know
what you’re doing, hit y
. Otherwise, SPC
is the way to go, until for any given
command you’re comfortable enough with it to say y
.
In this book, I make occasional recommendations to un-disable certain commands I
consider very useful; you can see them all in my recommended Initial Init File.
Felicity in Key Bindings
I define a felicitous key binding to be one that can be easily repeated, possibly
even auto-repeated by your keyboard. The most felicitous binding is a single
keystroke, like C-f
; you can repeat it easily by just holding down Control and
tapping away af f
. Even chorded single keystrokes like C-M-f
are maximally
felicitous.
Any prefix binding is less so. A two-character prefix binding that uses the
same modifier key in each case, such as C-x C-t
, is not too bad, as you can just
keep the modifier held down and quickly tap x
and t
. But when the modifiers
differ, we have maximum infelicity.
Consider the horrible horizontal scrolling key-binding
C-x <
(scroll-left
),29 which is effectively C-x S-,
.
Repeatedly invoking this command while observing the change in the visible part
of the text in the Window is like playing a particularly complex arpeggiated
piano part: hold down Control, hit x
, lift finger from x
and lift finger from
Control, hold down Shift, hit <
, lift finger from Shift and from <
, and finally
repeat.
Since any Emacs command can be bound to more than one keystroke, in some cases
like this, I provide Init File snippets with additional more felicitous
bindings, like my S-C-<
for scroll-left
, which can be easily tapped out or
auto-repeated.
In most cases, the felicity of key bindings is a minor issue, but for commands
that you tend to repeat in sequences, like scrolling commands, Window-switching
commands, and dragging commands, more felicitous bindings can make a big
difference.
About Mouse Bindings
As mentioned, I don’t use the mouse in Emacs at all (and barely at all in an
external web browser, my only other GUI application), so I won’t be devoting
much space to it, except to say that Emacs fully supports it.
The mouse is a much more complex user interface device than the keyboard.
Consider the traditional hand-held mouse (ignoring laptop touchpads for the
moment). The minimal mouse has one button, which, like a key on a keyboard, can
be pressed (or clicked) to generate an event that can be bound to an Emacs
command. Also like a key-press, this button-click can be modified by any of the
keyboard modifier keys, such as Shift, Control, Meta, and the like.
But the complexity of a single mouse click goes way beyond this. We need to
potentially distinguish between a button-press and a button-release, a simple
in-place click versus a drag, motion without clicking, and double- and triple-clicks
(or even more).
But that’s not all: many mice have more than one button: mice on Unix systems
traditionally have three buttons, and two- and five-button mice are common.
Unlike non-modifier keyboard keys, multiple mouse buttons can be chorded: that
is, pressing or clicking two or more buttons simultaneously counts as a
completely different button!30 Many mice have a scroll wheel, which acts as
another, more complex button, which may also tilt. Laptop touchpads add more
complexity. And the keyboard modifier keys can be mixed into all of this.
Emacs defines an abstraction of all this complexity, defines a set of default
global mouse bindings, and of course allows you to modify or add mouse bindings
yourself.31
All that said, I’ll just summarize the most basic default global mouse bindings;
you can get complete details in
the manual.
- clicking button 1 moves Point to the location of the click
- dragging with button 1 selects text
- clicking button 2 moves Point and pastes the contents of the system
clipboard32 - clicking button 3 copies the text between Point and the clicked location to the kill ring
Files, Buffers and Windows in Brief
Figure 3: Emacs Data Structures
Legend:
* | One or more |
1 | Exactly one |
1? | One or none |
Emacs has three data structures (actually four) that are intimately related,
and essential to appreciate.
- File
- A file is the actual file on disk. You are never directly editing the
data in this file. Rather, you read a copy into Emacs to initialize a buffer,
edit the buffer’s copy, and write the contents of the buffer back out to the
file to save it. A file of course contains text: characters in some character
set, say, Unicode33. - Buffer
- A buffer is the internal data structure that holds the text you
actually edit. Emacs can have any number of buffers at any moment. Many
buffers, but by no means all, are associated with a file. Buffers have names;
a buffer that has been initialized from a file is almost always named for that
file, and we say that the buffer is visiting the file. This means, in
particular, that when you save the buffer, it’s saved to the proper file. At
any given instant exactly one buffer is selected or current (even if several are
visible): this is the buffer that your focused cursor is in, and this is where
most of the commands you type take effect (including self-insert commands).
Buffers can be deleted at will; deleting a buffer in no way deletes any file
on disk, and if you have any unsaved editing changes, Emacs won’t let you
delete the buffer (unless you insist). See Buffers for details. - Window
-
A window is a view into a buffer. You can split any window,
horizontally or vertically, into as many windows as you like (or at least have
room for), each viewing a different buffer. It’s also possible to have
several windows viewing different portions of the same buffer. The
relationship between buffers and windows is transient: typically, many buffers
have no window viewing them at any moment and in general, buffers outnumber
windows by a large margin.Windows can be created and deleted at will; deleting a window in no way
deletes the buffer associated with the window. Each window has its own Mode
Line, but there’s still only the one Echo Area. See Windows for details.Don’t confuse Emacs windows with windows on your desktop! Emacs had
multiple windows two years before Graphical User Interfaces were commercially
available. Once GUI desktops became common and used the term “window” for their own
purposes, Emacs added support for these “desktop windows”, but needed to use a
new name for them: Frame. - Frame
- A frame is a “desktop window” that is treated as a separate entity
under a windowing system like X. When Emacs starts up, it creates one frame
for you, but you can have as many as you like. Each frame can hold several
Emacs windows, and, in fact, has it’s own Echo Area (I lied above), but all
buffers are shared in common across all frames. I won’t be discussing frames
much, as I rarely want more than one. But see Frames for details.
Basic File Concepts and Commands
The most common things you do with files are load them and save them.
-
C-x C-f
(find-file
) - This is the main command used to
read a file into a buffer for editing and is what the menu item File / Open
File does. It’s actually rather subtle. When you execute this command, it
prompts you for the name of the file (with completion). Then it checks to see
if you’re already editing that file in some buffer; if you are, it simply
switches to that buffer and doesn’t actually read in the file from disk again.
If you’re not, a new buffer is created, named for the file, and initialized
with the contents of the file. To create a brand new file, just type a nonexistent
file name; you’ll get an empty buffer that will create a new file when saved34. In
any case, the current window is switched to view this buffer. -
C-x C-s
(save-buffer
) - This is the main command used to
save a file, or, more accurately, to write a copy of the current buffer out
to the disk, overwriting the buffer’s file, and handling backup versions. -
C-x s
(save-some-buffers
) - This command allows you to
save all your buffers that are visiting files and have modifications, querying
you for each one and offering several options for each (save it, don’t save
it, peek at it first then maybe save it, just save all of them without asking,
etc).35
See Files for more information.
Basic Commands to Manipulate Buffers
The most common things you do with buffers, which you can for now think of as
opened files, are switch between them, list them (in case you’ve forgotten which
ones you’ve opened), and occasionally clean them up. But to paraphrase
Philidor, “The buffers are the soul of Emacs” and in short order you’ll be doing
a lot more with them.
-
C-x b
(switch-to-buffer
) - Prompts for a buffer name
(with completion) and switches the buffer of the current window to that
buffer. Doesn’t change your window configuration (if you had three windows
before, you still have three afterwards). This command will also create a new
empty buffer if you type a new name; this new buffer will not be visiting any
file, no matter what you name it (until you save it, at which point it will be
visiting the just-created file). -
C-x C-b
(list-buffers
) - Pops up a new window which
lists all your buffers, showing for each the name, state (modified or not),
size in bytes, the buffer’s major mode, and the file the buffer is visiting
(if any). This is an interactive buffer, meaning that, within it, you’re in a
special mode that allows you to manipulate buffers: select them, delete them,
save them, search a subset of them, etc. -
C-x k
(kill-buffer
) - Prompts for a buffer name (with
completion) and removes the entire data structure for that buffer from Emacs.
If the buffer is modified and is visiting a file, you’ll be given an
opportunity to save it. Note that this in no way removes or deletes the
associated file (nor does it delete the window; that window will simply start
displaying some other buffer).kill-buffer
is happy to delete a modified non-file buffer
without any warning however, so don’t keep important notes in buffers like
this (such as the*scratch*
buffer). (Emacs has better ways of note-taking
anyway.)
-
C-x C-q
(read-only-mode
) - Make a buffer read-only (so
that attempts to modify it are treated as errors), or make it read-write if it
was read-only. If you open a file that you don’t have permission to modify,
Emacs sets the buffer to read-only, to prevent you from wasting your time
editing it when you won’t be able to (directly) save it. This command lets
you have your way with it.
See Buffers for more information.
Basic Commands to Manipulate Windows
Just like the windows on your desktop, the most common things you do with Emacs
windows are create them, delete them, resize them, switch between them (i.e.,
change the focus), and scroll around in them. Emacs manages its windows in a
tiling manner, like one of those tiling window managers that are all the rage
these days.
See Windows for more information.
Create a New Window
To create a new window, you have to pick an existing window (there’s always at
least one!) and split it in two. You can split it vertically (which means you
now have less vertical space in the original window) or horizontally.
-
C-x 2
(split-window-below
) - Splits the current window
in two, vertically (into two windows, one below the other). This creates a
new window, but not a new buffer: the same buffer will now be viewed in the
two windows. This allows you to view two different parts of the same
buffer simultaneously, by moving around independently in the two windows.
Of course you can switch to a different buffer in one of these two windows
with, say,C-x b
(switch-to-buffer
) or
C-x C-f
(find-file
). Mnemonic: “2 windows where there was 1”. -
C-x 3
(split-window-right
) - Splits the current
window in two, horizontally (into two windows, side by side). This also
creates only a new window, and not a new buffer: the same buffer will now be
viewed in the two windows. Mnemonic: “slightly different fromC-x 2
”.
Delete a Window
-
C-x 0
(delete-window
) - Deletes just the current window,
resizing the other windows in the current frame appropriately. This does not
delete the buffer (nor file) associated with the window. Mnemonic: “zero this
window”. -
C-x 1
(delete-other-windows
) - Deletes all other windows
in the frame except the current one, making one window in the frame. Does not
delete the buffers (or files) associated with the other windows. Mnemonic:
“show me just this 1 window”.
Resize Windows
Since Emacs tiles windows, you can’t resize just one window36. If you want to
make it bigger, you have to steal real estate from some other window, and if you
want to make it smaller, you have to donate real estate.
I think the default Emacs key bindings for resizing windows are very awkward;
see “Change Window” in the Emacs manual. This is easily fixed with some
custom bindings; I’ll give the ones I’ve used for years later.
In graphical mode, you can use the mouse: just point the mouse at the Mode Line
that’s between the two windows whose mutual sizes you want to adjust. Point
anywhere in the mode line as long it’s not on top of any text or icon, and then
click and drag with the left mouse button.
Side-by-side windows (as created by C-x 3
(split-window-right
)) don’t have a Mode Line between them, of course, but
there is a vertical dividing line that you can likewise use, with the mouse, for resizing.
Switch Windows
The simplest way to switch windows is to cycle through all of them with C-x o
,
stopping at the one you wanted to get to. I rarely do it this way and will
discuss better, less tedious methods later. In graphical mode, you can use the
mouse to switch windows: just click anywhere in the desired window with the left
mouse button.
-
C-x o
(other-window
) - Switch to another window, making
it the active window. Repeated invocation of this command moves through all
the windows in the frame, left to right and top to bottom, and then circles
around again.
Scroll Within a Window
Scrolling horizontally is only necessary if you have a combination of skinny
windows and long lines; we’ll ignore that for now. But it’s very common for a
file to have many more lines than will fit vertically in a window.
You can of course scroll with the mouse and the scrollbar (or the scroll wheel)
if you don’t mind taking your hands off the keyboard.
-
C-v
(scroll-up
) - The basic command to scroll forward
(towards the end of the file) by one screenful. (Is this up or down? Depends
on your point of view.) By default Emacs leaves you two lines of context
from the previous screen. Mnemonic: “View more of the buffer” or “The V
points toward the text you want to see”.scroll-up
is also bound to the
key37. -
M-v
(scroll-down
) - Just like
C-v
, but scrolls
backwards. Mnemonic: “Meta V goes the other way”.scroll-down
is also bound
to the
key.
You can also directly scroll a window other than the one you’re in. This is
just a shorthand for switching to the window you want to scroll, scrolling it,
and switching back to the window you came from. If you have a lot of windows in
your frame, that’s exactly what you’ll have to do, but for the common case of
two windows, we have a simple command:
-
C-M-v
(scroll-other-window
) - Just like
C-v
, but scrolls
the other window. This works with more than two windows, in which case the
other window is the window thatC-x o
would switch to. You can give it a
negative argument to make it scroll backwards.
There’s more about scrolling to come.
Selecting Text: the Point, the Mark, and the Region
Selecting a range of text is fundamental to editing. It enables you to act
upon the text: delete it, copy it, modify it, change how it’s displayed
(highlight or colorize it, change its font or size), investigate it (count its
words or lines), search for other occurrences of it, focus on it (search or undo
within it, narrow to it so that’s all you can see), feed it to something outside
of Emacs.
The Emacs term for a range of selected text is the Region (“Using Region” in the Emacs manual):
it’s simply the text in your buffer between the Point and the Mark.
The Point
Point (“Point” in the Emacs manual) is the Emacs term for what we’ve been loosely
calling your cursor up to now; the cursor always shows the position of Point.
Point is where text is inserted when you type, and where most editing operations
happen. When you “move” in a buffer, you’re simply adjusting the location of
Point.
Point is really just a number: the offset, in characters, from the beginning of
the buffer, of the character after Point. You typically don’t care about this
number as such unless you’re writing Elisp, but if you want to know the value of
Point, C-x =
(what-cursor-position
) will report it in the echo
area (along with some other interesting information).
Point always identifies a location between two characters. By default, Emacs
displays, in the current window, a cursor at Point in the form of a solid box.
The box seems to be on top of a character, but Point is before that character.
(You could ask Emacs to instead display the cursor as a thin vertical line,
which would make the position of point as between two characters more obvious.)
Every window has a distinct Point which is always visible in that window. This
means that if you visit a file and split the window into two, you can have Point
in a different position in each window, so you can look at distant parts of the
file at the same time.
The Mark
The Mark (“Setting Mark” in the Emacs manual) is a sort of additional, invisible,
Point. A buffer has only one Mark38, and every buffer’s is distinct.
However, unlike Point, there’s no Mark in a buffer until you set one (explicitly
or implicitly).
The main purpose of the Mark is to determine one end of the Region, Point being
the other.
You set the Mark (at the same location as Point) with a special command,
C-SPC
(set-mark-command
); C-@
is an old synonym. Then, as
you move Point, the Mark stays where you set it and whatever is between the two
forms the Region.
The Region
The Region is the text between Point and Mark. If the Mark exists in a buffer,
so does the Region (because Point always exists). The Region can be of any
size: a few words, many paragraphs, the next 253 characters. If you set the
Mark and don’t move Point, the Region is of size zero. (Yes, an empty Region is
useful.) If you set the Mark at the end of the buffer, and move Point to the
beginning of the buffer, then the Region encompasses the entire buffer.
In fact, the Region is the same regardless of whether Point comes first in the
buffer or Mark does; it makes no difference, just do what’s convenient.
This scheme predates the commercial availability of the mouse, and provides a
keyboard-driven equivalent of sweeping out text with the mouse. In fact, if you
click mouse button 1 (usually the left button) at a position in the buffer, and
drag the mouse pointer in any direction, and then let go of the button, Emacs
sets the Mark at the place where you clicked, and the Point at the place where
you let go — another way to set the region.
When you explicitly set the Mark with C-SPC
(or the mouse), the Mark is activated,
and the Region is suddenly colored differently so you can visualize it (see
Figure 4). If the color becomes distracting, a C-g
will deactivate
the Region, as will most commands that operate on the Region after they’re done
with it (so the Active Region is typically transient: set it — color! — act
on it — color gone).
But remember, the Region still exists (because there’s a Mark) even if inactive
and invisible: you can still use it39. If at any time you’re not sure
of its extent, C-x C-x
(exchange-point-and-mark
) will
reactivate the Region (and hence colorize it); it also swaps Point and Mark,
which is handy if you want to fine-tune the extent of the Region with additional
motion commands, or if you want to get to, or just peek at, the other end (the
Region might be big enough that you can’t see both ends at the same time).
Once you’ve got a Region, you can do stuff to it. What kind of stuff? Delete
it; copy it; duplicate it; capitalize or otherwise change the case of it;
search-and-replace or undo within it; narrow your view of the buffer to it; do a
web search for it; treat it as a rectangle; write it out to a different file;
colorize it; comment it out, count the words, characters, and lines within it; pipe it through a
shell command. There are hundreds, nay, thousands, of Emacs commands that
operate on the Region, and you can readily make your own.
In a typical GUI editor like Microsoft Word or Google Docs, you spend much of
your time sweeping out or selecting text with the mouse and then activating a
menu or toolbar item; the Emacs equivalent is to set the Region and then execute
a command with a keystroke. In Emacs, you can likewise use the mouse and a
menu, but you can also do everything with the keyboard, and in addition to
setting the Region by setting the Mark and explicitly moving, you can set it
implicitly via textual object commands, search commands, and more.
So now you know how to define the Region: let’s do stuff to it.
-
C-w
(kill-region
) - Kills the Region. (You can yank it
back elsewhere.) Other editors call this operation cut. Mnemonic: wipe the
region. -
M-w
(kill-ring-save
) - Saves the Region without removing
it from the buffer (so you can yank a copy back elsewhere). Other editors
call this operation copy. Mnemonic: a “bigger” wipe (which includes a “paste”). -
C-x C-i
(indent-rigidly
) - Rigidly indents (or dedents)
the Region using the arrow keys;C-u 12 C-x C-i
indents the region exactly 12
characters, without using the arrow keys. -
C-x C-l
(downcase-region
) - Convert the entire Region to
lowercase. This command is disabled by default. -
C-x C-u
(upcase-region
) - Convert the entire Region to
uppercase. This command is disabled by default. -
M-q
(fill-region
) - Fills, i.e., justifies with a ragged
right margin, all the paragraphs within the Region; with a prefix argument,
right justify the paragraphs.
There are hundreds more commands that act on the Region, and the Region is
fundamental to the way cutting and pasting is done in Emacs.
Cutting, Copying, and Pasting
Cutting, copying, and pasting to and from the clipboard — the fundamental
editing operations — in most applications exist as three keyboard shortcuts,
known as Control+x, Control+c and Control+v respectively, called CUA40.
Emacs, of course, uses different terminology and key bindings — how can it
not, predating the CUA “standard” by close to ten years?
CUA Menu Item | Key | Mac OS | Emacs Command | Key |
---|---|---|---|---|
Cut | Control+x | Command+x | kill-region |
C-w |
Copy | Control+c | Command+c | kill-ring-save |
M-w |
Paste | Control+v | Command+v | yank |
C-y |
Select All | Control+a | Command+a | mark-whole-buffer |
C-x h |
Emacs calls cutting, “killing”; and it calls pasting, “yanking”. So select your
text (by setting the Region), and then use the Emacs keystrokes in the table
above, and things will work mostly as you expect.
Aside from the keystrokes, this is directly analogous to the way cutting and pasting
is done everywhere else. If you really can’t face the idea of learning these
four keystrokes, you can enable CUA Mode, which will let you use the keystrokes
you’re used to.
Now we’re done with this chapter, right? Feel free to skip ahead to the next
chapter to continue your Emacs exploration, but be sure to come back here
later for a little more info.
Welcome back!
It’s time for some tough love. Emacs cut-and-paste goes significantly beyond
that of most applications, but, I have to admit, at the cost of a significant
learning curve. The advanced features are probably the most complicated part of
beginner-level Emacs knowledge. The reason is just that it’s all very abstract
and tenuous, and you have to picture invisible things in your head.
What are these advanced features?
- Commands to precisely select (i.e. set the region around) a whole range of
textual objects: words, symbols, lines, sentences, paragraphs, and more.
We cover these in the next chapter. There are commands to directly kill (cut)
these objects. - A history of previously killed and copied text. The Mac OS and Windows
clipboards only hold one item—the last piece of text you killed or copied.
Emacs remembers your 60 most
recent items, and there’s no limit—you can increase it if you like.41
Emacs calls its “clipboard” the Kill Ring, and it’s an invisible (albeit
inspectable) data structure that you normally have to picture in your mind’s eye
as you use and change it.
With the addition of one more command, new in version 28 of Emacs, your suite of
cutting and pasting commands looks like this:
Action | Key | Emacs Command |
---|---|---|
Cut | C-w |
kill-region |
Copy | M-w |
kill-ring-save |
Paste | C-y |
yank |
Paste from History | M-y |
yank-pop |
C-y
yanks (“pastes”) your most recent kill (or copy), but you can get back any
of your last 60 kills by instead
using M-y
. It presents all your kills using the Completion system: just choose
the text you want to yank, as in Figure 5.
This function works best with an Incremental Narrowing Framework like Ivy or
Selectrum (Ivy is shown in Figure 5).
Until you read Yanking Older Kills, you shouldn’t invoke this command
immediately after C-y
: it will have a different effect. If you need to use M-y
right after a C-y
, just precede it with C-g
(keyboard-quit
).
The Kill Ring
When you kill the Region with C-w
, Emacs adds the killed text to a data
structure called the Kill Ring, which holds the last several kills. This
allows you to get older kills back. When you yank with C-y
, the most recent
kill from the Kill Ring is inserted into the buffer at Point; it’s not removed
or popped off the Kill Ring, so if you yank again, you get another copy.
The Kill Ring is really a linear list, and killing with C-w
feels like pushing
onto a stack; but the commands that deal with it actually treat it as a circular
structure, so we call it a ring.
The Kill Ring is a global data structure, shared by all buffers: this is so that
you can use the Kill Ring to move text from one buffer to another: kill some
text in buffer A, switch to buffer B and yank it: you’ve moved the text.
What about copying text? Clearly, you can copy and paste by doing C-w
to kill,
immediately yank it back to where it was with C-y
, and then move elsewhere and
yank again (your text is still at the front because yanking doesn’t pop the Kill
Ring). That’s C-w C-y
(move somewhere) C-y
.
M-w
is a shortcut for C-w C-y
, so we usually use that for copying: M-w
(move
somewhere) C-y
.
Yanking Older Kills (“Clipboard History”)
Here’s how yanking older kills worked in olden times (before v28’s new
M-y
(yank-pop
) command). Unless you’re a connoisseur of
Emacs history (this all still works…), I suggest you skip ahead!
Suppose we kill the word “foo” in some buffer. This pushes it onto the front of
the Kill Ring (who knows what else is behind it):
The arrow points to what C-y
will yank, by default the latest kill. Then we do
some more work, and kill the word “bar” somewhere else. Now the Kill Ring looks
like this:
Now we want to paste the “foo” somewhere42. How do we get at it?
We yank with C-y
and “bar” (what the arrow points to) is inserted. But now we
immediately type M-y
(yank-pop
). When invoked immediately
after C-y
, it moves the yank-pointer back one step:
and simultaneously replaces the just-yanked “bar” at Point with “foo”. If we
immediately type M-y
again, it would move the yank-pointer back one more step,
and replace “foo” with whatever is next oldest in the Kill Ring.
You don’t really need to picture the Kill Ring. When you want something from
it, just type C-y
and then if you think, “no, older” type M-y
, and if you think,
“no, older”, type another M-y
and so on.
The only trick here is that you have to type M-y
immediately after a C-y
, or
after a M-y
: if you do anything in between — moving, typing, popping up the
calendar — M-y
will do the wonderful new thing of offering up older
kills for Completion; if your Emacs is older then v28, it will complain with
“Previous command was not a yank”.
If you actually type 60 M-y
’s, you would then cycle around to the front of the
Kill Ring again!
Suppose the Kill Ring looks like this:
echo | delta | charlie | bravo | alpha | … |
↑ |
Let’s look at the results of some yanks (each of these examples is an
alternative to any of the others):
C-y
would yank “echo”- instead,
C-y M-y
would yank “delta” - or,
C-y M-y M-y
would yank “charlie” - or,
C-y M-y M-y C-y
would yank “charliecharlie” (C-y
always yanks from the
pointer)
Note that C-y
takes a numeric argument (positive or negative), so that C-u 3 C-y
in our example is the same as C-y M-y M-y
. M-y
works the same way.
What if you type several M-y
’s and decide you don’t want what you end up with?
Usually you just undo them, but note that this undoes the changes to your
buffer, but doesn’t undo the motion of the yank pointer. If you do C-y M-y M-y
,
yielding “charlie”, you can undo, yielding “delta”. But your next C-y
will yank
“charlie” again, since that’s where you left the yank pointer.
When you’ve got your yanked text (whether acquired by one C-y
or a chain of
M-y
’s, or the new Completion-based M-y
), the Mark is set for you at the
beginning of the restored kill, to make it easy for you to jump there (with
C-x C-x
(exchange-point-and-mark
); see also the Mark Ring)
— remember that you may have just yanked back a very large chunk of text, so
the beginning could be a long way away.
Undoing a Yank
I stole a function from the EmacsWiki that I call undo-yank
(originally
named yank-pop-forwards
), that lets you reverse direction in the middle of a
sequence of M-y
’s, in case you overshoot; this actually moves the yank pointer,
so you can think of it as an undo for yanks.
;; thanks to an anonymous EmacsWiki coder (defun undo-yank (arg) "Undo the yank you just did. Really, adjust just-yanked text like \[yank-pop] does, but in the opposite direction." (interactive "p") (yank-pop (- arg))) (global-set-key (kbd "C-M-Y") 'undo-yank)
I Can’t Picture This!
Ever feel that ’C-y M-y M-y M-y …’ is not a great way of trying to find that
piece of text you know you killed a while back? — Colin Walters
Emacs’s abstract approach to the Kill Ring (an invisible data structure with an
invisible yank-pointer), which may seem a mite austere, is very fast and
efficient once you get used to it. But you might occasionally prefer a sort of
WYSIWYG alternative, that lets you browse the Kill Ring interactively: see its
entire contents and search it too. The new functionality of M-y
command does
this for you; an alternative is Colin Walters’ third party package
browse-kill-ring
.
Other Ways to Set the Region
So far, we’ve been talking about killing (or copying) the Region: as if you were
always going to be sweeping out text, mouse-like (even if with the keyboard).
But really, it’s much more common to work in terms of textual objects — in
other words, kill a word or a line or a paragraph without bothering to sweep out
its boundaries. We’ll discuss textual objects in detail in the next chapter.
Appending to a Kill
Since the Kill Ring is a sequence of kills, you might think to use it to
accumulate several separate chunks of text that you want to yank back elsewhere.
Kill the first piece of text, move to the next and kill it; repeat several times
and you’ve now got everything you want, in several chunks at the front of the
Kill Ring.
But when it comes time to yank all these chunks back, you’ll have to do a bit of
a dance with a combination of C-y
’s and M-y
’s in a somewhat surprising order
(because the kills are accumulated on the Kill Ring backwards).
What you want to do instead is append to a single kill at the front of the Kill
Ring, with C-M-w
(append-next-kill
). So you kill the first
piece of text, move to the second, but now type C-M-w
before killing it with
C-w
; this causes the second piece to be appended to the text of the front kill,
instead of added as a new kill as usual. Think of C-M-w C-w
as a single append
to the kill command.
If the three pieces of text are “alpha”, “beta”, and “gamma”, the process looks
like:
-
move to “alpha”, set the Region, and
C-w
: -
move to “beta”, set the Region, and
C-M-w C-w
: -
move to “gamma”, set the Region, and
C-M-w C-w
:
Now you can move elsewhere, and with one C-y
, you yank back “alphabetagamma”.
Obviously, C-M-w
works the same with M-w
, if you want to leave the original text
in place.
C-M-w
is a pretty low-level tool; Emacs has better ways of approaching the task
of accumulating scattered chunks of text that don’t use
the Kill Ring at all.
Move to the first piece of text you want to collect—let’s say the word
“alpha”—and set the Region, but don’t bother to kill or copy; instead say
M-x
append-to-buffer
. You’ll be prompted for a buffer name which
will collect all the pieces of text you’re gathering; just make up any name you
like! If you’re collecting Greek letters, you could call the buffer “greek” or
“g”.
Now find your “beta”. M-x
append-to-buffer
again and use the same
buffer name. Repeat for “gamma” and as many other things you’re looking to
collect.
When you’re done, go to the place you want to “yank” your collection, and say
M-x
insert-buffer
: the entire contents of your accumulation buffer
is inserted at Point.
This scheme has several advantages over the Kill Ring for ambitious text
rearrangement.
- You can do your collecting and appending over a span of hours (or even days).
- It allows you to use the Kill Ring as you like in between accumulations.
- You can freely use several different collection buffers for different sorts of
text, and intermix your accumulations. - The accumulation buffer is just a buffer like any other, so you can switch to
it at any point to fix it up, or save it to a file; you also aren’t required
to useM-x
insert-buffer
to get your text; you can kill or copy
the text you’ve accumulated to extract what you’ve collected in any order or
combination.
See Mass Line Deletion for another solution, and “Accumulating Text” in the Emacs manual for more information.
The Clipboard
The Kill Ring is a data structure to which only Emacs has access. But every
time you kill or copy text to the Kill Ring — with any of the many commands
that do so, not just C-w
and M-w
— Emacs also copies that text to the system
clipboard. This is the data structure that all your other non-Emacs
applications paste from (with the CUA keystroke Control+v, probably). So this
gives you a simple way passing text to them.
It also works in the other direction: if the contents of the system clipboard
are newer than the Kill Ring — because you did a cut or copy in a non-Emacs
application — then C-y
instead inserts the clipboard text — not the first
item in the Kill Ring.
There are several configuration variables to control exactly how Emacs and the
clipboard43 interoperate; see “Clipboard” in the Emacs manual.
CUA Mode
If you’re a long-time Windows user and the Control+x, Control+c and Control+v
keystrokes are so thoroughly wired into your fingers that you just can’t get
used to C-w
, M-w
, and C-y
, don’t give up hope. Just say
M-x
cua-mode
and Emacs will let you use the commands you’re used to.
In order not to completely clobber the hundreds of key bindings on the C-x
and
C-c
prefixes, the CUA bindings are only operative when the Region is active
(colorized). There are several subtleties and extra features, so see
“CUA Bindings” in the Emacs manual for the complete story.
If you like cua-mode
, you can turn it on by default in your init file with this
line of code:
Editing with Textual Objects
Editing in general consists of inserting text, either by typing it or acquiring
it from some existing source; and then, over time, moving from one spot to
another in order to make changes (i.e. transform it).
In Emacs, both moving around and making changes are done largely via textual
objects — things like characters, words, lines, sentences, and such — and
you can:
- move in terms of them, and by moving, optionally:
- select them, and after selecting them,
- copy them,
- kill them, or
- transform them.
For each such object, there is a motion command that moves forward over it and
another that moves backward (you can also think of this as moving to the end and
to the beginning). All these motion commands interpret numeric arguments as
repetitions, so with an argument of N, you can move over N objects with one
command.
But of course, if you simply set the mark before moving, then when you’ve moved,
you’ve also selected text — that is, you’ve put the Region around whatever
you’ve moved over. Having selected, you can now immediately copy or kill the
text, or transform it.
Suppose Point is the |
in this line — you’re in the middle of the word
“telecommunications” — and you want to kill that word:
the intermediary of some telecommu|nications program, where the
To do so, you can move to the beginning of the word, set the mark, move to the
end, and kill: that’s four keystrokes:
1 | M-b |
backward-word |
2 | C-SPC |
set-mark-command |
3 | M-f |
forward-word |
4 | C-w |
kill-region |
Besides being completely general (killing a sentence just requires you to
substitute sentence-motion commands for the word-motion commands, for example)
this technique means that all you need to learn to use textual objects are the
motion commands. But most of the textual objects also have a special command
that marks, i.e. selects, them, which saves you a keystroke, so we could also
kill “telecommunications” with just:
1 | M-b |
backward-word |
2 | M-@ |
mark-word |
3 | C-w |
kill-region |
In addition, most of the objects also define a command to kill them, which can
save you another keystroke:
1 | M-b |
backward-word |
2 | M-d |
kill-word |
Or if you happen to already be at the beginning of the word, it’s just one
keystroke:
You can choose how much mental effort to put into learning these additional
commands, knowing that you can always achieve your goal in the 4-step manner.
But most expert Emacs users eventually learn all of these special commands: even
micro-optimizations pay off for things you do frequently.
Shift Selection
If you execute any of the motion commands while also holding the Shift key, you
can short-cut the selection process via Shift Selection. Consider M-f
(forward-word
). If
you instead use S-M-f
, the Mark is automatically set at Point, and then you move
forward one word: so the word is automatically selected. S-M-f
is essentially
C-SPC M-f
. In our example:
1 | M-b |
backward-word |
2 | C-SPC |
set-mark-command |
3 | M-f |
forward-word |
4 | C-w |
kill-region |
we can instead do:
1 | M-b |
backward-word |
2 | S-M-f |
forward-word (shifted) |
4 | C-w |
kill-region |
The same thing is true for motion backwards, and for any of the other textual
object motion commands. Just add the Shift.
And, if you type a shifted motion command, and immediately repeat it (while
holding down the Shift key), the selection is enlarged until you finally issue a
non-shifted-motion command. So if you say S-M-f S-M-f S-M-f
you will have set
the Region around three words.
You can mix different objects too: S-M-f S-C-n S-C-f
is also legitimate.
Transposing and Dragging Objects
A special case is transposing (or swapping) two objects: that is, put Point
between two objects (say, sentences) and swap them — the left hand sentence is
now the right hand sentence and vice versa. One single command replaces a more
complicated pattern of killing, moving, and yanking.
For example, here in line 0 Point (|
) is between “one” and “two”. If we
transpose-words
with M-t
, we get the result in line 1:
0 one | two three four five 1 two one | three four five 2 two three one | four five
Note that Point has moved forward, or if you prefer, it remains after “one”.
This means that another M-t
will result in line 2. So several transpose
commands in a row can be chained together. You might think of this as dragging
“one” to the right.
Most of the transpose commands react to a numeric argument of N by transposing
the object to the left of Point with the one N objects to the right. This means
that an argument of 1
is the same as no argument (on line 0 above, the word
“two” is one word away from the left-hand word “one”).
But if we say C-u 2 M-t
, we get this result, because “three” is two words to the
right of “one”:
0 one | two three four five 1 two three | one four five
Personally I think it’s easier to chain several transpose commands to achieve
the equivalent effect, but your brain may work differently.
A negative argument transposes in the opposite direction (backwards, rather than
forwards). In addition, a numeric argument of 0
(which would otherwise not do
anything!) is interpreted specially: it swaps the object containing or after
Mark with the object containing or after Point, no matter how far apart they
are! This is a long-distance transposition, with no chaining or counting
required. Here in line 0 ^
indicates Mark (in “one”), and |
Point (in
“eleven”); we say C-u 0 M-t
:
0 ^one two three four five six seven eight nine ten ele|ven twelve thirteen 1 ele|ven two three four five six seven eight nine ten ^one twelve thirteen
(Frankly I’ve never internalized this and always just Kill, move, and Yank in
this use case.)
The exact definition of what makes up a given textual object is often
customizable and may vary slightly from mode to mode. This is useful because it
means that you can use the same motion commands and yet have them automatically
customized for different types of text.
Here’s the complete list of standard Emacs textual objects, with their backward-
and forward-motion, marking, killing, and transposing key bindings:
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
Character | C-b , ← |
C-f , → |
C-d |
C-t |
|
Word | M-b |
M-f |
M-@ |
M-d |
M-t |
Horizontal Line | C-a |
C-e |
C-k |
||
Vertical Line | C-p , ↑ |
C-n , ↓ |
C-x C-t |
||
Sentence | M-a |
M-e |
M-x ... |
M-k |
M-x ... |
Paragraph | M-{ |
M-} |
M-h |
M-h C-w |
M-x ... |
Sexp | C-M-b |
C-M-f |
C-M-@ |
C-M-k |
C-M-t |
Defun | C-M-a |
C-M-e |
C-M-h |
C-M-h C-w |
|
Page | C-x [ |
C-x ] |
C-x C-p |
C-x C-p C-w |
|
Buffer | M-< |
M-> |
C-x h |
C-x h C-w |
N.B.: in these charts, M-x ...
means that the obvious command exists but isn’t,
by default, bound to a key — that is, M-x
mark-end-of-sentence
,
M-x
transpose-sentences
, and M-x
transpose-paragraphs
.
Characters, Words, and Lines
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
Character | C-b , ← |
C-f , → |
C-d |
C-t |
|
Word | M-b |
M-f |
M-@ |
M-d |
M-t |
Horizontal Line | C-a |
C-e |
C-k |
||
Vertical Line | C-p , ↑ |
C-n , ↓ |
C-x C-t |
Characters
Object | Backward | Forward | Mark | Delete | Transpose |
---|---|---|---|---|---|
(left, right) | |||||
Character | C-b , ← |
C-f , → |
DEL , C-d |
C-t |
The character is the smallest, the atomic, textual object.
-
C-b
(backward-char
) - Moves backward (to the left) over
a character. This is mostly the same thing that the left-arrow
(
(left-char
)) does (but there are subtle
differences in the context of bi-directional text). -
C-f
(forward-char
) - Moves forward (to the right) over a
character. Same deal with right-arrow (
(right-char
)).
The f for forward and b for backward mnemonic will recur.
-
DEL
(delete-backward-char
) - Deletes the character to
the left of Point; note that this is not a Kill and the deleted character
doesn’t go on the Kill Ring (because at one keystroke per character, it’s
quicker to retype it than to kill and yank it). -
C-d
(delete-char
) - Deletes the character to the right
of Point; also not a Kill. -
C-t
(transpose-chars
) - Swap the characters around Point;
at the very end of the line, swap the two previous characters.
Words
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
(left, right) | |||||
Word | M-b |
M-f |
M-@ |
M-DEL , M-d |
M-t |
-
M-f
(forward-word
) - Moves forward over a word.
-
M-b
(backward-word
) - Moves backward over a word.
Note the f/b mnemonic. Also, as another mnemonic, note that M-f is like a
“bigger” version of C-f.
-
M-@
(mark-word
) - Sets the Mark at the end of the
current word; immediately repeating this command moves the Mark to the end of
the next word, enlarging the Region by one word (this is generally the way
all marking commands work). -
M-d
(kill-word
) - Kills text forward from Point to the
end of the word. -
M-DEL
(backward-kill-word
) - Kills text backward to the
beginning of the word. -
M-t
(transpose-words
) - Swap the words around Point.
Lines
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
Horizontal Line | C-a |
C-e |
C-k |
||
Vertical Line | C-p , ↑ |
C-n , ↓ |
C-x C-t |
Lines can be considered vertically or horizontally. Horizontal first.
-
C-a
(move-beginning-of-line
) - Moves to the beginning of the current line.
-
C-e
(move-end-of-line
) - Moves to the end of the current
line.
A for the beginning of the alphabet, E for “end”.
Strangely, there’s no command to set the region around the entire current line
(though it’s very easy to write one!).
-
C-k
(kill-line
) - Kills from Point to the end of the
current line, not including the newline unless the line is blank. Thus, if
you’re at the beginning of a non-blank line it takes two C-k’s to kill the
whole line and close up the whitespace. -
C-u 0 C-k
(kill-line
) - Kills to the beginning of the
current line, not including the newline.
Now let’s consider lines vertically.
-
C-p
(previous-line
) - Moves up to the previous line;
also on↑
. -
C-n
(next-line
) - Moves down to the next line; also on
↓
. -
C-x C-t
(transpose-lines
) - Swap the line containing
Point and the previous line, leaving Point after both (allowing chaining).
When moving vertically by lines, the cursor tries to stay in the same column,
but if the target line is too short, the cursor will be at the end of the line
instead: Emacs doesn’t automatically insert spaces at the ends of lines (end of
line is unambiguous)44.
It doesn’t seem too intuitive to kill lines vertically by analogy with C-n
and
C-p
; I know of no such commands.
Prose Objects: Sentences and Paragraphs
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
Sentence | M-a |
M-e |
M-x ... |
M-k |
M-x ... |
Paragraph | M-{ |
M-} |
M-h |
M-h C-w |
M-x ... |
Sentences
When you’re editing prose, motion by sentences and paragraphs is very
convenient. Note that, by default, for the purposes of motion, sentences need
to end with two spaces after their terminal punctuation (period, exclamation
point, or question mark). This has become something of a cause célèbre
lately, but don’t worry, you can change sentence-ending to only require one
space by customizing sentence-end-double-space
.
-
M-a
(backward-sentence
) - Moves to the beginning of the
current sentence. -
M-e
(forward-sentence
) - Moves to the end of the current
sentence.
Note the mnemonic relationship between C-a / M-a and C-e / M-e. Again the Meta
version is for a “bigger” object.
-
M-x
mark-end-of-sentence
- Sets Mark at the end of the current
sentence; this command doesn’t have a default key binding (but you could give
it one). -
M-k
(kill-sentence
) - Kill the text from Point to the end
of the sentence. -
C-u -1 M-k
(kill-sentence
) - Kill the text from Point to
the beginning of the sentence.
Paragraphs
You can similarly move by paragraphs — but what is a paragraph exactly? It
depends on the Major Mode and you can tweak the definition yourself45, but most
commonly, paragraphs are delimited by blank lines.
-
M-{
(backward-paragraph
) - Move to the beginning of the
current paragraph. -
M-}
(forward-paragraph
) - Move to the end of the current
paragraph. -
M-h
(mark-paragraph
) - Sets the Region around the entire
current paragraph; unlike the marking commands for smaller objects, in
addition to setting the Mark at the end of the object, this one also moves
Point to the beginning (this turns out to be much more useful for large
objects). -
M-x
kill-paragraph
- Kill the text from Point to the end of the
paragraph.
Larger Objects: Pages and Buffers
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
Page | C-x [ |
C-x ] |
C-x C-p |
C-x C-p C-w |
|
Buffer | M-< |
M-> |
C-x h |
C-x h C-w |
Pages are separated by form feed characters (C-l
— that’s L, not the digit 1),
just as lines are separated by newline characters. This used to be a common
concept back when Emacs was young; when printing, you had to manually indicate
where a page break should occur, causing the printer to skip to the top of the next
page (or “form”), and to do this you would insert a form feed character.
Since form feeds count as whitespace in most programming and markup languages,
pages are still a useful idea, and Emacs has several commands that do things in terms
of them. You can insert a form feed into your file by typing C-q C-l
(see
Quoted Insert).
So while it’s rare now to use a form feed to actually force a new page when
printing46, it’s handy to be able to separate a large file into “pages” which are
really just bigger sections than paragraphs. A typical organization in a file
of source code is to precede each section header comment with a form feed, and
then you can navigate by these logical sections via C-x [
and C-x ]
.
Here’s what it looks like in a file of my Emacs Lisp source code (Elisp comments
start with one or more semicolons, and a form feed character displays as ^L
):
^L ;;; parsing and unparsing
That ^L
is not two characters, as you can clearly see if you move your cursor
across it one character at a time: it just looks like it.
-
C-x [
(backward-page
) - Moves to the beginning of the
current page. -
C-x ]
(forward-page
) - Moves to the end of the current
page. -
C-x C-p
(mark-page
) - Sets the Region around the entire
current page; unlike most marking commands, in addition to setting the
Mark at the end of the object, this one also moves Point to the beginning.
Finally, it’s useful to be able to jump directly to the beginning or the end of
the buffer without having to scroll.
-
M-<
(beginning-of-buffer
) - Moves to the beginning of
the buffer. -
M->
(end-of-buffer
) - Moves to the end of the buffer.
Mnemonic: the beginning of the buffer is a location that’s less-than any other
location, and vice versa.
-
C-x h
(mark-whole-buffer
) - Move Point to the beginning
of the buffer and set Mark at the end of the buffer. -
M-x
mark-beginning-of-buffer
- Set Mark at the beginning of the
buffer, without moving Point, -
M-x
mark-end-of-buffer
- Set Mark at the end of the buffer,
without moving Point.
Code Objects: Balanced Parentheses and Function Definitions
Object | Backward | Forward | Mark | Kill | Transpose |
---|---|---|---|---|---|
Sexp | C-M-b |
C-M-f |
C-M-@ |
C-M-k |
C-M-t |
Defun | C-M-a |
C-M-e |
C-M-h |
C-M-h C-w |
An S-expression47 (“sexp” for short) is the name, in Lisp, for atoms
(symbols, numbers, and quoted strings) and the balanced parentheses that enclose
them, recursively. In Emacs, this useful notion is available everywhere; it’s
especially useful for editing programming languages, but even in prose it’s very
useful to be able to move over, copy, or kill a parenthesized phrase. The
characters that Emacs recognizes as parens are usually regular parentheses (aka
round brackets), square brackets, and braces (aka curly brackets), but it
depends on the Major Mode (for some languages, angle brackets (i.e. <
and >
) may
act as parens too).
But sexps are more than just balanced parens. A symbol (roughly, a word) that
doesn’t contain any parens also counts as a sexp, as does a number. In most
programming language modes, quoted strings are sexps (using either single or
double quotes, depending on the syntax of the language). A sexp is any of
those, or a parenthesized sequence of them, recursively.
These commands may seem confusing at first, but for editing most programming
languages they’re fantastic. Not only do they move you around quickly and
accurately, but they help spot syntax errors while you’re editing, because
they’ll generate an error if your parens or quotes are unbalanced.
-
C-M-b
(backward-sexp
) - Moves backward over the next
sexp. If your cursor is just to the right of an opening paren,C-M-b
will
beep, because there’s no sexp to the left to move over: you have to move up. -
C-M-f
(forward-sexp
) - Moves forward over the next sexp.
Same error if your cursor is just to the left of a closing paren.
Here’s an example of linear movement via sexps. The location of Point is shown
by |, and we move forward with C-M-f
each time. After three C-M-f
’s Point is
after “Emacs” in line 3
, because each of the first three words count as symbols
and thus are sexps. But the next C-M-f
leaps over the entire parenthesized
expression in line 4
.
0. |In 1976, Emacs (in its original TECO form) was invented. 1. In| 1976, Emacs (in its original TECO form) was invented. 2. In 1976|, Emacs (in its original TECO form) was invented. 3. In 1976, Emacs| (in its original TECO form) was invented. 4. In 1976, Emacs (in its original TECO form)| was invented.
-
C-M-u
(backward-up-list
) - Move backward up one level of
parens. In other words, move to the opening paren of the parens containing
the cursor, skipping over balanced sexps. -
C-M-d
(down-list
) - Move down one level of parens. In
other words, move to the inside of the next opening paren, skipping
over intervening sexps.
Let’s move up in nested parentheses with C-M-u
. On line 0
, Point is in front of
the word “Lisp”. We type C-M-u
and on line 1
, Point is now in front of the
nested parentheses. One more C-M-u
and Point moves in front of the leftmost
paren.
0. (in its original TECO form (which preceded the |Lisp implementation)) 1. (in its original TECO form |(which preceded the Lisp implementation)) 2. |(in its original TECO form (which preceded the Lisp implementation))
Nested parentheticals may be poor prose style, but they’re extremely common in
source code in almost any programming language.
Now let’s move down with C-M-d
. On line 0
, Point is on the return type of this
C function definition; on line 1, after C-M-d
, Point is inside the formal
parameter list:
0. |void synctex_updater_free( synctex_updater_t updater) { 1. void synctex_updater_free(|synctex_updater_t updater) {
-
C-M-@
(mark-sexp
) - Set Mark at the end of this sexp.
-
C-M-k
(kill-sexp
) - Kills the sexp after Point.
Since function defintions are such an important unit of text in programming
languages, whether they’re called defuns, subroutines, procedures, procs, or
whatever, they also count as textual objects. Like the sexp commands, these
commands work appropriately in most programming language modes. Emacs calls
this generic notion of function or procedure defun, again after Lisp.
-
C-M-a
(move-beginning-of-defun
) - Move to the beginning of
the current function definition. -
C-M-e
(end-of-defun
) - Move to the end of the current
function definition. -
C-M-h
(mark-defun
) - Sets the Mark at the end of the
current defun.
Note the mnemonic analogy with lines and sentences.
Extending Kills
If you kill several times in a row, with any combination of kill commands, but
without any non-kill commands in between, these kills are appended together in
one entry on the Kill Ring — there’s no need to precede the kills with
C-M-w
(append-next-kill
). For example you can kill the next
six words as a unit with M-d M-d M-d M-d M-d M-d
, move elsewhere and yank back
all six (with their intervening whitespace) with one C-y
. C-u 6 M-d
would be
equivalent. You can kill a block of lines with a sequence of several C-k
’s, or
you could kill the next sentence and the following two words with M-k C-u 2 M-d
(note that the numeric argument C-u 2
doesn’t break up the sequence of kills,
because C-u 2
is part of the following M-d
command).
Adjusting the Region
After setting the Region around one or more textual objects, whether by setting
the Mark and moving, or Shift Selection, or by object-specific mark commands,
you can fine-tune the Region by lengthening or shortening it at either end with
any other motion commands — perhaps you selected a paragraph with M-h
but you
don’t want the blank line at the front of it, or selected a sentence and
want to add the two words at the beginning of the following sentence. Just move Point in any
manner. If you want to adjust the other end, where Mark is, use C-x C-x
(exchange-point-and-mark
): now Point is where the Mark was and you can
adjust that end.
Other Ways to Move Around
The textual object motion commands covered in the last chapter are probably the
most important means of motion in Emacs. But there are several other ways to
move around.
Move by Searching
You can exploit your knowledge of the contents of your text by using Emacs’s
many search capabilities to move around. If you want move to where you were
discussing Ursula K. Le Guin, just search for her name.
Follow a Breadcrumb Trail (The Mark Ring)
We learned in Selecting Text that there’s only one Mark in any buffer. This is
strictly true, but there’s an additional data structure in each buffer called
the Mark Ring (see Info) that holds a
history of previous Mark locations48.
You set these Marks explicitly whenever you set the Region, whether with
C-SPC
(set-mark-command
) or a mouse selection, or implicitly
with textual object mark commands (like M-h
(mark-paragraph
)). They’re also left for you automatically at places where
you’ve done “significant” things, like changing text, moving a long way away in
one big jump (there being many ways to do this), the spot where you issued a
search command, and the like49.
Thus a breadcrumb trail of Marks is left for you to find your way back,
Theseus-like, to where you’ve been, and provides a quick way to get back to
these previous locations. The way to jump back to the previous Mark location is
to give C-SPC
(set-mark-command
) an argument, so C-u C-SPC
.
It also rotates the Mark Ring, so that a repeated, uninterrupted sequence of C-u
commands will take you back in time through your previous Mark locations.
C-SPC
The Mark Ring is a circular structure, so when you hit the end, you’ll circle
round to the most recent Mark location again. You’ll notice the analogies to
the operation of the Kill Ring.
It’s a common idiom to set the Mark explicitly as a breadcrumb to jump back to,
rather than as part of selecting some text. If you set the Mark, which
activates the Region, and immediately set it again in the same spot, the Region
is deactivated; this is nice for using the Mark to record your position —
you’re not really setting the Region, so why be distracted by the color of the
active region? So remember C-SPC C-SPC
as the breadcrumb-dropping command.
The Global Mark Ring
In addition to each buffer’s specific Mark Ring, there’s a also a Global Mark
Ring: this records a history of your locations in previous buffers. So if you
want to jump to the last place you were in the previous buffer you were in, just
use C-x C-SPC
(pop-global-mark
). The setting of these
global marks is automatic: whenever you switch buffers, Emacs pushes the buffer
you just left (and your location there) onto the Global Mark Ring. You can
cycle through this ring, too.
Move Via Your History of Changes
Perhaps the most surprising way of moving is by undoing; if you recently made a
change to your text (possibly just by adding some more) and then moved
elsewhere, it’s pretty common to want to go back to where you made that change,
and the easiest way to get there is to just undo it, because wherever you may be
now, an undo pops you right back to the last change in that buffer. You can use
this trick even if you don’t want to undo your change — because you can
instantly restore it by a redo.
Obviously this trick gets much trickier if you want to move back to where you
were, say, three changes ago: three undos gets you to the right spot, but assuming
you liked your changes, if you redo them you’re now back where you came from!
The third-party packages goto-last-change
and goto-chg
solve the problem by
going to the undo locations without actually undoing!
Mode-specific Motion
Various Major Modes may implement special ways of moving. Perhaps the most
obvious is moving by identifiers (names) in programming language modes: you can
move from a use of a function or variable to the definition, for example, or
move through all the uses of an identifier. This typically works across all the
files in a defined project. Some languages have a bespoke way of handling this
via the language server protocol (LSP)50, but Emacs also supports various
language-agnostic approaches, such as the Xref subsystem.
Move by Scrolling
Sometimes, rather than moving pointedly to get to a precise location, you just
want to scroll through your text to get an overview and stop at the spot that
catches your fancy; scrolling is covered in the chapter on Windows.
Goto Commands
Most of the textual-object motion commands can be thought of as moving
relatively: when you move forward by one word (sentence, paragraph, …) you’re
moving relative to the location of Point.
But occasionally it’s useful to move to an absolute position (though
much less often than one might think). The most common type of
absolute motion is to move to a specific line by its line number. For
example, according to M-x
what-line
, this line as I’m
writing it is line 1,497. If I move elsewhere, I can come right back
here by jumping to line 1,497!
Of course, since I’m editing, in a few minutes that line probably
isn’t line 1,497 anymore, and I probably won’t remember that number
for more than a few seconds, and anyway, if I wanted to come back here
why don’t I just use the Mark Ring or search?
I think most people who use line numbers as motion targets have line numbers
turned on.
Emacs doesn’t display line numbers by default, though it does show
the current line number in the mode line, but you can toggle the traditional
left-margin display of line numbers on and off with M-x
linum-mode
,
or arrange for them to always be on in every buffer51. To me they just
waste screen real estate.
But what if you’re compiling a program in your terminal and it reports a syntax
error on line 563? Well, you should be compiling that program in Emacs with
M-x
compile
, and then you can jump to that error with a keystroke,
with no need to type any line number; see Compiling Code.
However, it’s true that you do occasionally get a line number foisted upon you
in an unpredictable manner — say, from a stack trace when a program blows up,
or from some log file. When you do, M-g g
(goto-line
)
will prompt you for the number and jump there.
Much more rarely, you’ll have a byte (character) offset from the beginning of
some file; M-g c
(goto-char
) will take you there.
Finally, M-g TAB
(move-to-column
) is what you need for
absolute positioning on the other axis: it moves to the given character offset
from the left margin. There are lots of subtleties to this command — like,
how do you count tab characters in the line, or multibyte (say, Unicode)
characters? — but hopefully you’ll never need it; I’d never used it before I
had to write this paragraph! See the documentation for details.
Variables and Symbols
Usually the programming language in which a program is implemented is only of
incidental interest to the user of the program. But all Emacs users know that
it’s implemented in Emacs Lisp, because the Lisp interpreter is always there,
running Emacs and interacting with you to a degree that’s unheard of in most
programs.
One of the most important parts of the running Lisp interpreter is the
collection of symbols that it contains: 40,974 at
startup. A symbol — which is a name like what-line
or compile
or
kill-paragraph
— can hold a function, in which case the symbol
serves as the name of the function, which you can use to execute the
function via M-x
(execute-extended-command
) or by
which it can be attached to a keystroke via a key binding.
A symbol can also be a variable—initially Emacs has
15,121 of them— and have a value. We say the value
is bound to the variable. Most of these variables are used only by
programmers in the implementation of the functions they write for you
to use, but a subset of them—2,885—are
Customizable Variables (a.k.a. User Options), which you can use to
configure Emacs to your liking.
In this chapter we’ll be talking mostly about User Options. They’re
fundamentally the same as plain old variables, but distinguished by being
variables that you’re expected to want to customize, and they have additional
features to assist in this. But you can customize almost any variable if you
want to, and some lazy Elisp programmers52 simply might not bother to mark
their variables as customizable. So I’ll generally just use the term “variable”
here.
What Are These Variables For?
Emacs is famously malleable and customizable: you can make it work and look
exactly the way you want, and this is mostly achieved through variables. Do you
not like the red color of the squiggles under your spelling errors? That
color53 is specified in the variable
flyspell-incorrect
, so you can change it.
Do you wish Emacs wouldn’t beep at you when an error occurs? The
visible-bell
variable lets you change that.
Throughout this book, I make some recommendations for tweaks to some variables,
and give examples of others that you might want to change.
Types of Variable Values
A variable can hold any kind of Lisp value, and there are several types:
truth values (corresponding to true / false or on / off: called Booleans by
programmers), numbers, text (called strings by programmers), functions, and,
perhaps most importantly, lists, which are sequences or collections of values of
any types54. Also, and I don’t want to blow your mind here, but a variable (which
is a symbol, you’ll recall) can also hold… a symbol.
Let’s look at some examples of real Emacs variables and the (typical) types of
values they hold.
Variable Name | Default Value | Type |
---|---|---|
visible-bell |
t |
Boolean |
delete-by-moving-to-trash |
nil |
Boolean |
kill-ring-max |
60 |
number |
report-emacs-bug-address |
"bug-gnu-emacs@gnu.org" |
string |
tool-bar-position |
top |
symbol |
split-window-preferred-function |
split-window-sensibly |
function |
image-types |
(svg png gif tiff jpeg xpm xbm pbm) |
list |
In Table 2, we see that visible-bell
is on (because t
is the
Elisp Boolean true value) while delete-by-moving-to-trash
is off (because nil
is the Boolean false value).
kill-ring-max
determines the size of the Kill Ring.
report-emacs-bug-address
is the email address for Emacs bug reports such as
those generated by report-emacs-bug
, and as such must be a
string.
tool-bar-position
specifies where the tool bar should be displayed, and must be
one of the four symbols top
, bottom
, left
, or right
.55
split-window-preferred-function
is a variable that holds a function that is
actually called to split a window; split-window-sensibly
is a symbol that names
a function suitable for this purpose. Variables that hold a function are
typically set to the symbol that names the function.
Finally, image-types
is a list—of symbols, in this case, but Elisp lists can
hold any types or combination of types (including nested lists).
Changing the Value of a Variable
As the name implies, you can also change the value that’s bound to a variable.
There are three times at which you might do this:
- when Emacs starts up, via your Init File;
- explicitly and interactively, while you are using Emacs;
- whenever you visit a given file.
For cases 1 and 2, it’s best to use the Customize Facility, because it provides
documentation about how the variable works, guides you though the possibilities,
prevents you from making common mistakes, and allows you to revert your changes
or save them for future sessions. It’s equally good for making settings for
your startup configuration, for setting a value just for this session, or just
to try out a new value for a while. You’ll know you can use Customize when C-h
says, “You can customize this variable.”
v
Note, however, that Customize only works for User Options. If you want to
change a variable that hasn’t been defined as such, you’ll have to learn a
little about Elisp.
Buffer-Local Variables
Variables can have different values in different buffers. For example, you
might want to indent lines differently when you’re writing a Python program than
when you’re writing prose. We call these buffer-local variables. They start
out with a default value, but if you change the value of such a variable, the
change only applies in the current buffer.56
You can’t change the local value of a buffer-local variable with Customize; you
either do it via Elisp in your Init File (if you want the change in every Emacs
session; see Hooks below), or else you use M-x
set-variable
to do it
just for now, in the current buffer.
To set a variable with set-variable
, you need to know the type of value the
variable expects; that means you need to read its documentation with C-h v
. You
also need to know enough about Elisp to understand the syntax of the different
types. There’s a difference between the number (256) and a string
containing the three digits (2), (5), and (6).
If you say M-x set-variable
, Emacs will prompt you for the name of a variable.
You might enter:57
Set variable: report-emacs-bug-address
The next prompt would be:58
Set report-emacs-bug-address globally to value:
According to the documentation, this value needs to be a string; if you were to
enter:
Set report-emacs-bug-address globally to value: myself@example.com
you would get a type error:
user-error: Value ‘myself@example.com’ does not match type string of report-emacs-bug-address
Table 3 provides a cheat-sheet for entering values of the
major data types in the correct syntax; see
“Init Syntax” in the Emacs manual for details, and also for how to set
variables in your Init File. But remember, prefer
M-x
customize-variable
whenever possible.
Type | Example | Another Example |
---|---|---|
Boolean (true or on) | t |
|
Boolean (false or off) | nil |
|
number | 256 | 1 |
string | “256” | “myself@example.com” |
symbol | flyspell-incorrect |
top |
function (same as symbol) | find-file |
set-variable |
list | (1 4 12) |
("/tmp") |
The syntax of Booleans is very simple: the true value is spelled t
and the false
value, nil
.59 I could give you other examples of the true and of the false
values, but it would require a little
too much explanation.
Numbers are represented as a sequence of base 10 digits, like 256
, possibly
including a decimal point, as in 3.141593
. There’s a special syntax to enter
numbers in other bases.
Strings are enclosed in double-quotes; there are some tricks here, like how to
include a double-quote in a string---"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"
is no good, because the enclosed
(second) "
terminates the string: you have to escape it with a backslash like
this: ""http://www2.lib.uchicago.edu/"
. There are also other “escapes” so that you can include control
characters and such; see “String Type” in the Elisp manual.
Symbols look rather like strings without quotes (they don’t need quotes because
they can’t contain spaces); you can just type their names. As discussed above,
a function is typically represented by the symbol that names it (though for the
Elisp programmer, there are other possibilities) and so uses the syntax of
symbols.
Lists are simply zero or more space-separated instances of any types enclosed in
parentheses. The empty list is ()
. There’s no problem nesting lists: this list
contains two values, a string followed by a list of three numbers: ("foo" (1 2
.
3))
This should be enough syntax for you to enter values at the set-variable
prompt.
File- and Directory-Local Variables
Elisp also lets you initialize buffer-local variables inside arbitrary files:
these are called file-local variables. When you visit such a file, the
variables are automatically given their values in the buffer that the file
initializes. This is especially useful as a way to set the Major Mode in which
the file should be edited—see Mode via File-Local Variable—but you can set
additional variables too (subject to Security limitations).
You can also set buffer-local variables on a per-directory basis; this is very
convenient when you would otherwise be repeatedly setting (or forgetting to
set…) the same file-local variables every time you add a file to a directory;
see “Directory Variables” in the Emacs manual.
Hooks
An essential part of Emacs’s customizability is provided by hook variables.
They cleverly solve the problem of how you can customize, in your Init File,
dynamic things that haven’t happened yet, like all future buffers in some
particular Major Mode, or an Emacs application like Eww (the web browser), Dired
the file manager, or a third-party application like Magit that doesn’t even
ship with Emacs.
A hook is nothing more than an ordinary variable that’s used in a conventional
way by Emacs programmers. The value of a hook is a list of functions, such that
at some documented and distinguished time—like when you visit a file in, say,
python-mode
, or pull up a web page in Eww, or start playing an audio file in
EMMS—the functions are executed, or run.
Most hooks have a default value of the empty list: when the hook is run, nothing
happens! But the important point is that you can add your choice of functions
to the hook to cause magical things to occur. For example, you might add the
function flyspell-prog-mode
to the
python-mode-hook
variable to enable spell-checking of
Python comments. Now you’ll get this spell-checking in every Python file that
you visit.
Minor Modes are a very common class of functions to add to hooks, as is a
function that changes the value of one or more buffer-local variables, whether
one of the 98 predefined buffer-locals, or one defined
specifically by a Major Mode for customization purposes. You can also write a
function yourself to do any crazy thing that no one else could have thought of
in advance, like send an email to somebody mentioning that you’ve started
editing that Python file.
Hooks are almost always set in the Init File, rather than via
M-x
set-variable
; see Programming the Lisp Machine.
Help, Discovery, and Documentation
All kinds of help for Emacs is never more than a keystroke away — no need to
switch to a web browser. The Help system (commands on the prefix key C-h
)
provides quick access, especially for known-item searches (“what is”, “where
is”, “what does it do”). The Apropos facility is more like a Google search,
used when you want to do something but don’t know what commands or modes or
subsystems are available to do it (a query like “version control diff”, say).
Finally, Emacs has a built-in hypertext documentation reader, called Info, for
long-form, book-length documentation. To enter it, type C-h i
. See the Info chapter for more information.
Help
Emacs’s extensive online help is available via the help key,
C-h
60. C-h
is a prefix key. Type C-h
twice to get a
window describing all the following commands and more (a SPC
will scroll this window).
Some of the most useful help commands are:
-
C-h a
(apropos-command
) - Prompts for keywords and then
lists all the commands whose names match. If you’ve forgotten the name of the
command that counts words,C-h a word count
will reveal it. -
C-h k
(describe-key
) - Prompts for a keystroke and
describes the function bound to that key, if any. If you remember
M-=
but
can’t recall what it is, useC-h k
(it’s count-words-region
). -
C-h w
(where-is
) - Prompts (with completion) for the
name of a function and tells you (in the Echo Area) what keystrokes will
invoke it. If you cheekily typeC-h w where-is
, you’ll see:C-h w,
.w,
w -
C-h o
(describe-symbol
) - Prompts (with completion) for
the name of a function, a variable, or a face61 and describes all the
matches. If you remembercount-words-region
but not what it does,C-h o
will tell you. (
count-words-regionC-h f
will do the same but only for
functions, andC-h v
only for variables, if you want to narrow it down.) -
C-h m
(describe-mode
) - Describes the current major mode
and its particular key bindings. -
C-h r
(info-emacs-manual
) - Enters the Info hypertext
documentation reader at the Emacs manual, which contains many hundreds of
pages of documentation. -
C-h p
(finder-by-keyword
) - Runs an interactive
subject-oriented browser of installable Emacs packages62. These lists of
packages are actually presented by the package manager itself, so you can
directly install packages from here. -
C-h t
(help-with-tutorial
) - Run the Emacs tutorial.
Have you done this yet?
There are 39 more help commands on C-h
, which C-h C-h
will reveal.
Of the commands I list above, C-h k
, C-h o
, C-h f
, C-h v
, C-h m
(and a few of
the other 39) bring up a Help Buffer. This is something of a simplification,
but there are three main varieties of the Help Buffer:
- help for commands and functions, whether acquired via a keystroke or via a
command name - help for variables
- help for modes
Let’s see what these are like.
The Help Buffer
Let’s get help from C-h k
for whatever C-x C-b
is! This is the same kind of
buffer you’d get from C-h f
(describe-function
).
First note that the help pops up in its own buffer (named *Help*
) in a new
window (stealing some screen real estate from the PKGBUILD
buffer I was looking
at); the buffer is in help-mode
(which of course usefully
redefines some keystrokes).
Often a quick glance at this buffer is enough to answer your question and you
just get rid of it with a quick C-x 1
(delete-other-windows
), perhaps after giving it a quick scroll with
C-M-v
(scroll-other-window
).
If you’re in an investigative mood, you might jump into the help buffer with
C-x o
(other-window
), where you can exploit its clickable
buttons (cyan text) and the the key bindings of help-mode
.
Parsing the Help Buffer
The first line identifies the function that C-x C-b
runs: list-buffers
, and
tells us which keymap (global-map
) the keystroke was found in63.
It also tells us what kind of a function list-buffers
is — “an interactive
compiled Lisp function”; it might also be a “built-in function” (which would
mean it’s implemented in C, rather than Elisp) — and it tells us which file of
source code the function is defined in. You don’t need to worry about any of
this as a person just learning to use Emacs, but it isn’t just idle chat: the
cyan color of the file name means that it’s a hypertext link, and if you “click”
it (with mouse button 1 or by hitting return) it will take you directly to the
definition of that function in that file and you can read the source code
yourself.
As an aside: this is an incredibly powerful tool for learning how to extend
Emacs. I guarantee that if you are wondering what function the back-arrow
button in Firefox runs when you click it, you’ll have to spend a lot of time
plowing through the >1 GB of source code (after you download it) and cross your
fingers when you search for “back”. And if we were talking about the bold-face
toolbar button in Google Docs or Microsoft Word, you wouldn’t even be allowed to
download the proprietary source code.
The next paragraph lists all the key bindings which run list-buffers
— this is
just what C-h w
(where-is
) would tell you.
The next line (“(list-buffers &optional ARG)
”) shows you how you would call the
list-buffers
function if you were writing Elisp, and after that, how old this
function is in terms of the Emacs version number (this is mostly useful for
programmers who might not want to write code using a new bleeding-edge function
that won’t be available in older Emacsen64).
The remainder of the buffer describes precisely what list-buffers
does. This
text may include more hyperlinks to other, related, functions or variables (like
buffer-menu
here).
The help for a command can be extensive. But this is because the documentation
includes everything an Elisp programmer might need to know; usually the first
line or two tells you everything you need for interactive use.
Finally, if this isn’t the first help buffer you’ve popped up in this Emacs
session, at the bottom of the buffer will be a button labeled “[back]” which
will take you to the previous help buffer you looked at. Once you’ve gone back,
there will be a “[forward]” button to return you to where you came from. These
are just like the back and forward buttons in your web browser and make it easy
to browse through the hypertext of the Emacs help system. Note that there’s
really only one *Help*
buffer, to keep from cluttering your Emacs; the
navigation buttons recreate the previous text in the same *Help*
buffer.
I mentioned that the help buffer is in Help Mode. This gives you 25 useful key
bindings for use when you’re in the *Help*
buffer. For example, SPC
is bound to
scroll-up-command
and S-SPC
to
scroll-down-command
for easy reading. C-c C-b
and C-c C-f
are keyboard equivalents of the “[back]” and “[forward]” buttons. TAB
and
(a.k.a S-TAB
) take you to the next and previous clickable button
respectively.
Help for a Variable
Now let’s look at the help for the variable completion-styles
, which we could
see by executing C-h o completion-styles
(or C-h v
).
It’s very similar to the help for a function, but it tells you right up front
the most important thing about a variable: what it’s current value is (here, the
list of symbols
(basic partial-completion substring initials flex)
). Interestingly, it also
tells you that its original value was (basic partial-completion emacs22)
: this
is the default value in a fresh Emacs: I changed it to demonstrate this
feature. There may also be a hyperlink into the Customize facility, as here.
The rest of the buffer is the documentation for the variable, with the same
features as for functions.
For some variables, the help will say “Automatically becomes
buffer-local when set.” This means that the variable can have distinct values
in different buffers, which is very useful for customization. For some
variables, a buffer-local value doesn’t really make a lot of sense, like
confirm-kill-emacs
, which lets you specify whether you want
to be asked to confirm your intention when you give the exit command. But you
may well prefer the values of other variables to vary from buffer to buffer or
mode to mode, such as indicate-empty-lines
,
fill-column
, or truncate-lines
.
The help for some variables may also address the safety of the variable with a
statement like “This variable is safe as a file local variable if its value
satisfies the predicate ‘integerp’.”; see Security Concerns.
Help for a Mode
To get help for a Major Mode, just switch to a buffer that’s in that mode and do
C-h m
. The help buffer gives a description of the mode, and lists all the
mode-specific key bindings. In addition, each enabled Minor Mode is described
separately.
You can also access Major Mode help from any Buffer using C-h f
and the name of
the Mode, e.g. C-h f org-mode
.
Discoverability via Apropos
Most of the Help commands described above answer specific questions about known
items: what is this key? what does this function do? what kind of values can I
set this variable to? The Apropos facility is how you search for unknown
functions and variables related to what you want to do.
We’ve been introduced to the Apropos facility via C-h a
above. This is
M-x
apropos-command
which searches for commands by name.
Command is the technical term for an interactive function: that is, a
function you can call via a key binding or with M-x
. The reason for making
this distinction is purely practical. Emacs has tens of thousands of functions,
most of which would only ever be called by an Emacs Lisp programmer. Commands
are functions that are likely to be useful to the non-programmer (or to the
programmer when she’s acting like a non-programmer).
If you’re interested in seeing non-command functions as well, you can give C-h a
an argument (e.g. C-u C-h a
).
Even more broad-minded is just plain M-x
apropos
, which includes all
functions, variables, and faces.
If you want to limit your search to variables, you can use
M-x
apropos-variable
. But there are other Apropos commands to make
finer distinctions among variables:
-
M-x
apropos-user-option
- only considers user-customizable
variables (sometimes called options) -
M-x
apropos-local-variable
- only considers buffer-local
variables defined in the current buffer
All of the above commands are only searching by function or variable name, to
avoid overwhelming you. But you can include in your search all the text of the
function’s or variable’s documentation with C-h d
(apropos-documentation
). This is just like C-h a
but instead of limiting
its search to the names of commands, it includes all symbols (like variables)
and also searches the full text of the documentation of these symbols. This is
a much broader search, and for reasons of both speed and concision, it limits
the search to the standard built-in Emacs commands. If you give C-h d
an
argument, i.e., C-u C-h d
, it searches the documentation of literally all
symbols in your running Emacs, including those from third-party packages you may
have loaded.
Finally, you can also search the values of variables with
M-x
apropos-value
. This is a pretty big search. My Emacs at
the moment has 15,121 defined variables, and some of them have
pretty big values.
The Apropos Query Language
All the Apropos commands use the same query language. Your query can take any
of the following three forms:
- a single word
- all the results must contain this word
- two or more words
- all the results must contain at least two of these words
- a regular expression
- all the results must match this regular expression.
Additional Information
The Help key has several additional subcommands that provide access to more
information. Some of these are shortcuts into the Emacs or Elisp manuals in
Info, but some are standalone files.
C-h C-a
- Information about Emacs (recreates the splash screen you saw when
you started up Emacs). C-h C-c
- Emacs copying permission (displays the complete text of the GNU
General Public License, which gives you your freedom to copy, modify, and
redistribute Emacs and its source code). C-h C-d
- Instructions for debugging GNU Emacs. This is for real hard-core
programmers hacking on Emacs to fix deep bugs. C-h C-e
- External packages and information about Emacs.
C-h C-f
- Emacs FAQ (the Frequently Asked Questions list).
C-h C-m
- How to order printed Emacs manuals.
C-h C-n
- News of recent Emacs changes; see Updates and Bugs.
C-h C-o
- Emacs ordering and distribution information. This used to provide
postal addresses you could write to in order to get copies of Emacs mailed to
you on giant 9-track magnetic tapes to load on your mainframe! Nowadays, it
just contains a few URLs and notes how you can make donations to the Free
Software Foundation. C-h C-p
- Info about known Emacs problems. This is a broad summary of the
standout Emacs bugs; the real bug list is available on the Web in the Bug
Tracker, which is also available in Emacs via thedebbugs
package; see
Reporting Bugs. C-h C-t
- Emacs TODO list. If you’re a Lisp or C programmer and want to
contribute to the development of Emacs, you can start here. C-h C-w
- Information on absence of warranty for GNU Emacs.
Info: The Emacs Documentation Reader
Emacs has a built-in documentation reader called Info. It dates from
1985 and actually predates GNU Emacs (it was present in ITS TECO
Emacs) and was one of the earliest freely available hypertext systems,
predating the World Wide Web by five to ten years.
The Emacs manual is the most important Info document, but Emacs ships with
63 additional manuals, comprising 395,759
lines of text, describing various subsystems and major modes (e.g. Org, Gnus,
Calc).
Info documents are written in their own markup language, called Texinfo, and
Texinfo is used to document many other non-Emacs software projects65. The
non-Emacs packages I’ve installed on my Arch Linux system include an additional
75 Info manuals. (Non-Emacs users read these
manuals with the info
command-line documentation reader, which is sort of like a
clone of the Emacs Info system for Vim users and other Emacs-averse types, I suppose.)
The main entry points for Info are:
C-h i
orM-x info
- Lists all installed manuals (there will be at least
sixty, if you’ve done a full install of Emacs). C-h r
orM-x info-emacs-manual
- Skip the top-level list and enter the Emacs
manual directly. -
C-h R
(info-display-manual
) - Open a specific manual by
name, with completion.C-h R calc
would go directly to the Calc manual, for
example. -
C-h F
(Info-goto-emacs-command-node
) - This is like
C-h f
(describe-function
)—it prompts for the name of an
Emacs function—except it tries to find a discussion of the function in the
Emacs manual (while every Emacs function has Help documentation, they aren’t
all described in detail in the manual). -
C-h K
(Info-goto-emacs-key-command-node
) - This command is
toC-h k
(describe-key
) asC-h F
is toC-h f
.
Info is of course documented in its own Info-manual, which you can read with:
M-x info-display-manual RET info RET
(or just navigate to it from the main Info menu via C-h i
).
Info has its own interactive tutorial66, modeled on the Emacs Tutorial, to teach
you how the hypertext system works. Ideally, you should take it before you
start using Info; you can start the tutorial by typing h
( Info-help
) from anywhere in Info. But you can read any
Info document in its entirety by just hitting
SPC
(Info-scroll-up
), so feel free to just dive in; if you
want more or need help, hit h
.
A typical page in an Info document (called a node) looks like that in Figure
8. The very first line is a header line with next, previous,
and up navigation links for mouse navigation. The next line is a breadcrumbs line that
shows your position in the document hierarchy with clickable links. The rest of
the page consists of text, typically with clickable hyperlinks to other pages.
Often there is (as here) a menu of links to subsections of the chapter; these
are exactly the same kind of links as appear interspersed in the text.
You can move around in Info within a node, or between nodes. The usual motion
and scrolling commands work fine for the former, along with the convenient
bindings SPC
and DEL
for scrolling up and down by screenfuls.
Moving between nodes is more interesting. If you’re looking at the bottom of a
node67, SPC
will move on to the next node, in the order you’d use to read
the entire document (DEL
does the same backwards if you’re at the top of a
node).
Like any hypertext, an Info document has a tree structure68. While SPC
moves node by node through the whole tree in reading order (that’s a depth-first
traversal), you can cut across the branches at any level (breadth-first-wise)
with n
(Info-next
) and p
(Info-prev
). So,
if you’re in the node for Chapter 3, n
will go directly to Chapter 4, skipping
all subsections of Chapter 3, and if you’re in subsection 4 of section 2 of
Chapter 6, n
will go to subsection 5, and so on. p
does the same thing
backwards. In other words, n
and p
are the keyboard shortcuts for the Next:
and
Prev:
links in the node’s header line. u
will go up to the parent of this node.
You can also move through nodes in the order in which you visited them: that is,
move via your node-browsing history. The
l
(Info-history-back
) command goes left to the last node you
were in; more l
’s go further back in time. The
r
(Info-history-forward
) command goes right, forward in time,
assuming you’ve already gone backward. These commands have no relation to the
order of the nodes in the document, but only to the order in which you’ve read
them. L
(Info-history
) takes you to a node containing the
history of all the nodes you’ve visited, as a Menu.
Hyperlinks
Info documents wouldn’t be hypertexts if they didn’t have hyperlinks. These are
exactly like the links in a web page and look similar: colorized and underlined.
You can navigate from link to link in a node with TAB
(S-TAB
goes in reverse)
and then follow a link by “clicking” on it (either with RET
or the mouse). Info
links can take you to other places within a node, to other nodes in the
document, and also to nodes in other Info documents.69 Links to places in
the same page are formatted like footnotes.
You can also follow any of the links in the current node (even if you can’t see
some of them) without navigating to them with
f
(Info-follow-reference
), which prompts you for the text of
the link. You can use Completion to complete any of the links in the node; note
that Menu links and Footnote links are excluded from the Completion, because
they have their own shortcut commands.
Menus
Many Info nodes have menus, especially in the first node of a document and in
each chapter. Menus are nothing more than a list of hyperlinks and work the
same way; it’s just a convention for organizing an Info document. Menus
typically list all the children of a given node: that is, a chapter menu will
list all the sections in that chapter, and a section menu all its subsections.
You can use Completion to select a Menu item by typing
m
(Info-menu
), analogous to the f
command for cross
references, and the digit keys will jump directly to the node of the
corresponding menu item: e.g., 3
would jump to the node named in the 3rd menu
item and so on.
Searching
Since an Info node is just a buffer, you can obviously search within it with the
usual search commands like C-s
(isearch-forward
),
M-x
occur
, and the like. Incremental search commands like C-s
will
beep when you get to the end of the node, but if you force the search with one
more C-s
then instead of wrapping to the beginning of the buffer, they will skip
ahead to the next hit in the next node of the document.
Indexes
In addition to full text searching, most Info documents are actually manually
indexed by their authors, and everybody knows that a good index, what with
synonyms, related terms, and inversion, can offer accessibility that full text
searching can’t. In addition, an index allows for the possibility of Completion
on index terms!
An Info document can have one or more indexes—Emacs-related documents
will often have separate indexes of Key Bindings, User Options, Commands, Variables,
and Concepts (the Emacs manual has all of these).
The index pages of document are always listed at the end of the top-level menu
of the document (its table of contents), but from any node the
i
(Info-index
) command prompts you for an index term, with
Completion, from any of the document’s indexes. Since a given term can point to
any number of nodes, it will take you to the first occurrence, and if there are
more, you might see a message like this in the Echo Area:
Found ‘INDEXTERM’ in Concept Index. (20 total; use ‘,’ for next)
and indeed, the comma key will step you through all the hits.
Alternatively, you can instead use I
(Info-virtual-index
),
which presents the same hits as i
but lists them all in a dynamically-generated
Menu.
You can also search across all sixty-plus Info documents at once with
M-x
info-apropos
, the search-engine of Info commands. It works like
other Apropos commands but targets the text of the indexes of all installed Info
files, and generates a dynamic Menu page from the hits.
Higher-Level Navigation
You can jump directly to the top of the current Info document, with its master
Menu table of contents, with t
(Info-top-node
), and the
d
(Info-directory
) command goes to the Menu at the root of the entire
Info system, listing all installed Info documents (the same place that C-h i
takes you to).
Write Your Own Manual
If you are writing a book-length document, especially a manual for software, and
very especially a new manual for an Emacs subsystem or Mode, you might consider
using Texinfo format.70 You’ll get many output options—PDF, HTML,
DocBook, EPUB, and of course Info, which can be read in Emacs and even by non-Emacs
users via the info
command-line reader that’s standard on most Unix systems.
And Emacs is of course especially suited for authoring with its Texinfo Mode;
see Emacs For Writers for more information.
Messages, Errors, and Lossage
Messages
Various brief messages appear in the Echo Area from time to time. This includes
error messages (like, trying to save a file that you don’t have permission to write),
and also informational messages. Some commands exist only to print informational
messages, such as C-x l
(count-lines-page
), which tells you
how many lines there are in your buffer71:
Page has 5549 lines (2407 + 3143)
If you miss a message like this, or if you want to make a copy of the message,
you can use C-h e
(view-echo-area-messages
). This pops up
the *Messages*
buffer, which you can switch to for copies of the N most recent72
Echo Area messages. It’s just a buffer like any other, so you can copy and
paste from it.
There’s a separate buffer for warnings. Warnings are obviously
like errors, but less severe. While errors go to the Echo Area, and behind the
scenes are copied to the *Messages*
buffer, warnings instead go to a separate
*Warnings*
buffer, and when a warning is generated this buffer pops up and is
very noticeable. It seems counterintuitive that warnings should be more
in-your-face than errors; I think the reason is two-fold: 1. the special
handling of warnings is a relatively new feature, dating from about Emacs
version 22; and 2. an error terminates whatever function raised it — it beeps,
and you’ll look at the Echo Area — whereas a function that generates a warning
will continue with what it was doing, but wants you to know something that you
might need to act upon. There’s no special command to pop up the *Warnings*
buffer; if you’ve deleted the window that popped up, and you want to reexamine
it, you can just switch to it by name with C-x b
(switch-to-buffer
) (which you can also do to get to *Messages*
).
What Just Happened?
Occasionally as you’re working, you might suddenly notice that something
unexpected has happened — perhaps a chunk of text has disappeared before your
eyes, or you’re suddenly in a completely different location! What happened?
Almost certainly this means you accidentally hit some unintended combination of
keystrokes, and since so many such combinations are bound to commands, this
means you inadvertently told Emacs to do something.
If a change to your text occurred, you can just undo it and continue on. While
you can’t undo a location change, you can use the Mark Ring or the Global Mark
Ring to return to where you were. But you might want to know what keystrokes
and command you invoked so that you can avoid hitting it in the future — or
perhaps you’ve discovered a new useful command to use intentionally!
The C-h l
(view-lossage
) command73 pops up a Help Buffer
showing the last 300 keystrokes you’ve typed. The lines look like this:
M-> ;; end-of-buffer q ;; quit-window C-x b ;; switch-to-buffer c ;; self-insert-command o ;; self-insert-command
showing you the keystroke and the command name. You can ask for help for any of
the command names (with C-h f
(describe-function
))
which can help you figure out what happened.
The Minibuffer
Sometimes a command needs to ask you a question. C-x C-f
asks,
“What file did you want?” C-x b
asks, “What buffer did you
want?” M-x
asks, “What long-named command did you want me to
execute?”
To get your answer, Emacs uses its most general and most powerful data
structure, the Buffer, but to avoid constantly popping up a new one and messing
with your window layout, it uses a special buffer called the Minibuffer
(see “Minibuffer” in the Emacs manual), which is always displayed in a compact form in
the same location. In fact, the Minibuffer reuses the fixed window that’s used
for the Echo Area at the bottom of the screen. The question, or prompt, appears
in the Echo Area, which is automatically focused to receive your response, and
when you hit RET
, the little excursion is over.
The advantage of using a Buffer, rather than something like a modal GUI dialog
widget, would be that you already know how buffers work, and you can interact
with this Minibuffer using the same commands you use all day long.74
The Echo Area, and thus the Minibuffer’s window, is normally only one line high
— just enough space for a typical prompt and your response, though it will
dynamically expand to more lines as needed, and you can change the default
height if you like.
The Minibuffer has its own Major Mode, with a few specialized key
bindings. Most notable is that hitting RET
is how you indicate that
you’re done typing your answer: RET
deactivates the Minibuffer and
your cursor is returned to the window it was in when the interaction
started.
While it has some special behavior and a few restrictions, the
Minibuffer is otherwise very much a fully-functional Emacs buffer.
All the usual editing commands work — you can move around within it
to correct mistakes, you can even do fancy things like search within
it, you can kill and yank text, use spelling correction, or anything
else75.
Minibuffer History
In addition to the special treatment of RET
, the Minibuffer’s Major Mode
provides convenient history commands. You can instantly recall your previous
input — command name, filename, buffer name… — with M-p
(previous-history-element
); subsequent M-p
’s will go further back, and you
can switch directions and go forward again with M-n
(next-history-element
) — the up- and down-arrow keys are synonyms.
(Rather than navigating the history, C-p
and C-n
navigate multi-line input as in
any buffer — multiple lines, while atypical, are completely supported in the
Minibuffer).
You can also search backward in the history with
C-r
(isearch-backward
) or
C-M-r
(isearch-backward-regexp
). You could, say,
quickly pull up the last Org Mode file you edited with C-x C-f C-r
, even if you last typed that filename days ago.
.org
Note that any individual command can have its own distinct history list. This
is typically done to tamp down the completion possibilities for any given
command to those that are most likely to be useful. Since the Minibuffer is
used for all prompted inputs, if it only had one history list, then you’d have
to wade through buffer names, command names, color names, variable names — you
get the idea — no matter what you were about to enter.
Instead, all the file-visiting commands, like C-x C-f
, share a
single history list which only contains filenames; likewise for
C-x b
and buffer names, M-x
and command names,
etc.
Future History
One of the lesser-known features of the Minibuffer76 is that its
history extends into the future: that is, Emacs can predict inputs
that you haven’t typed yet! More prosaically, you could call these
predictions, defaults. You access these defaults with
M-n
(next-history-element
) — use it immediately
after you’ve been prompted for input by some command and it’ll offer
up suggestions: if you’re at the end of the history, the next history
element is from the future!
For example, after C-x b
(switch-to-buffer
), M-n
will offer
up names of buffers that you’ve recently visited (even if you haven’t ever
explicitly input their names). C-x C-f
will do something
similar, but in addition, if, before you invoked C-x C-f
, Point happened to be
in the name of an existing file, it will offer up that filename. Sometimes the
things M-n
comes up with can seem telepathic. (The flip side is that sometimes
it won’t have any guesses for you.)
Recursive Minibuffers
The Minibuffer is the sole, unified way to get prompted input, and
you can use any commands you like when you’re entering text there. So
what happens if you type M-x
eww
to pull up a web page in
the Emacs web browser. Eww is now using the Minibuffer to read a URL,
prompting you with:
Enter URL or keywords:
Then you realize you don’t remember the precise URL you need, but you know it’s
in a file. So you naturally type C-x C-f
(find-file
) so you
can observe and copy that URL.
But no! Emacs will beep at you and refuse to execute C-x C-f
, saying:
Command attempted to use minibuffer while in minibuffer
That is, you’re in the Minibuffer (entering a URL) but C-x C-f
now
needs to use the Minibuffer to read a filename!
This is not really a limitation of Emacs, which actually has no
problem allowing you to invoke the Minibuffer recursively to any
(reasonable) depth. However, this feature is disabled by default —
because it’s been found to confuse Emacs newbies.
But this many pages into this book, you’re no longer a newbie! While
my example may be somewhat contrived, recursive Minibuffers are very
useful and you’ll probably want them several times in a day. I
recommend turning them on with this snippet of code in your init file:
(setq enable-recursive-minibuffers t)
If you recursively invoke a Minibuffer and change your mind about it,
just hit C-g
(keyboard-quit
) as usual; it will
abort the most recent Minibuffer and you’ll be back in the previous
one and can complete your input there as you like.
Temporary Excursions
When you’re entering information in the Minibuffer, you may occasionally realize
that you don’t actually know what you need to type, as in our URL example. You
have to check something first.
The normal procedure is just to use C-g
(keyboard-quit
) to
cancel the command that’s using the Minibuffer, do your investigation, and then
reissue the command. How very modal of you.
But you can instead just temporarily switch out of the Minibuffer with any
command that switches windows. Normally that would be C-x o
(other-window
) but any window-changing command, or clicking in another
window with the mouse, is fine.
Now you’re in one of your “normal” windows, and the Echo Area, instead of being
blank, as usual, still contains the Minibuffer prompt and whatever else was
displayed there when you jumped out: the Minibuffer is frozen the way you left
it, waiting for you to return and finish what you were doing. In a graphical
mode Emacs, you’ll notice that the Minibuffer cursor has changed from a solid
rectangle to a hollow one.
While you’re away, you can do anything you like: continue editing, play a game
with M-x
tetris
, copy some text you need for the Minibuffer:
you can even, of course, use a command that uses the Minibuffer!77 You can stay
away as long as you like. When you’re ready to get back to where you left off,
just navigate to the Minibuffer (again, C-x o
or a mouse click is the most natural), and complete your action, perhaps yanking
in some text you copied for the purpose. Hit RET
to execute the patient,
long-suffering command-in-progress, and you’ll be returned to wherever you were
when you started this excursion — the window layout and your buffer position
will be restored as they were, even if, during your excursion, you changed
windows around radically. This is the essence of non-modal editing!
Repeating Complex Commands
Among people who use Emacs mostly as a text editor, the Minibuffer is probably
most heavily used to input file names, followed by buffer names. But as you use
Emacs for more things, the use of the Minibuffer to enter command names with
M-x
(execute-extended-command
) probably dominates. So Emacs
provides special history support for these.
We know that if you type M-x
you can retrieve previous commands from the history
with M-p
, C-r
, and M-r
, but some
commands have multi-part inputs. Consider M-x
rgrep
(see
Meet the Greps). It’s nice that the Minibuffer history helps you avoid typing all
five characters of “rgrep” to run a new Rgrep, but what if you want to rerun a
previous Rgrep exactly?
M-x
rgrep
prompts you for three things: a search term or regular
expression, a file type wildcard pattern (e.g., *.org
), and a base directory
from which to start the search. You can use the history commands at each of
these prompts, but that can be a little tedious if you just want to rerun the
command exactly: M-x M-p RET M-p RET M-p RET M-p RET
.
Instead, you can use C-x ESC ESC
(repeat-complex-command
).
You get a Minibuffer prompt showing your previous M-x
command, in its true Elisp
form; it might look like this:
Redo: (rgrep "minibuffer"http://www2.lib.uchicago.edu/"*.org"http://www2.lib.uchicago.edu/"~/txt/" nil)
Even if you’re not an Elisp programmer (yet), this should be recognizable as
your grep for the string “minibuffer” in Org Mode files contained (recursively)
in ~/txt/
; just hit RET
to re-run it, with no need to reenter the three
parameters. You can edit the command beforehand (perhaps to tweak the regexp,
or the file type, or the base directory)78.
You can use the Minibuffer history (M-p
, C-r
, M-r
) as usual here to choose a
different prior command. Note that the history includes any command that used
the Minibuffer, even if you invoked it via a key binding, so you’ll find old
friends like C-x C-f
(find-file
) and
C-x b
(switch-to-buffer
) here as well.
You can view a buffer of the N most recent79 M-x
commands with
M-x
list-command-history
. The commands are in their true
Elisp form, as for C-x ESC ESC
, one per line. In this buffer you
can re-run the command at Point by typing x
( command-history-repeat
).
Since the default command history list is so short, and since I think RET
in
this buffer should execute the command at Point, I recommend this snippet for
your init file:
(with-eval-after-load 'chistory (setq list-command-history-max 120) (define-key command-history-map (kbd "" ) 'command-history-repeat))
An Aside Concerning Completion Frameworks
Note that alternative completion frameworks, and Incremental Narrowing
Frameworks in particular, may radically alter the nature of the Minibuffer,
making it seem less like a normal buffer, and some of the things described in
this chapter may not work precisely the same way.
Completion
Everyone is familiar with completion, perhaps under the name “autofill”, which
usually refers to the automatic completion of fields in forms. Web browsers,
spreadsheets, and smartphone applications autofill via drop-downs, and Unix
users are of course familiar with the TAB-completion of commands, options,
and filenames in any conventional shell80.
Emacs definitely had completion for the Minibuffer by 1985 and as a
text-oriented computing interface that prioritizes the keyboard over menus, it’s
fundamental to using Emacs. Completion is pervasive: almost anytime Emacs
prompts you for information — command names, variable names, filenames, color
names, lists of words — completion is available; it’s also available at Point
in many buffers (e.g., to complete symbols and keywords in programming
languages, as you type).
This is not to be confused with the predictive autocompletion or autocorrect for
prose that you’re used to from the text messaging app on your phone, where every
word you enter is automatically turned into a typo for you!81 Instead, you
can autocomplete natural language words via an explicit keystroke; Emacs
calls this expanding dynamic abbreviations.
Neither is it to be confused with template expansion, where an entire
complex piece of text, like say a case
statement in a programming
language, is expanded from one word.
As completion examples I’ll use M-x
commands, because the basic set of them is
common to all Emacs users — filenames and buffer names are going to be unique
to each person — but don’t forget that it works the same for everything.
A Shortcut to Completion
Emacs has a number of ways of performing completion that I’ll call completion
frameworks. The default framework is roughly the way completion has always
worked since about 1985, but you definitely want to use a more modern framework
of the type known as incremental narrowing. Even here, Emacs has more than one
choice.
I’m going to recommend you start right off with Vertico82, which you can
install from the GNU ELPA Package Repository; see Figure
9.
You’ll need to add this to your Init File and restart your Emacs83:
(setq completion-styles '(partial-completion substring flex)) (unless (package-installed-p 'vertico) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'vertico))) (with-demoted-errors "%s" (vertico-mode +1))
An incremental narrowing framework (INF) generally lets you complete a string
(whether a M-x
command name, file name, buffer name, or anything else) by typing
a pattern consisting of clusters of adjacent letters separated by punctuation.
So to complete the command switch-to-buffer
, you can type
sw-to-bu
which rapidly narrows the matches down from 20,313
possible commands to a mere 7.
The entire line of one of the matches will be highlighted; this is the match
that will be used if you hit RET
. If switch-to-buffer
is not highlighted
yet, you’ll need to either narrow it down further, by adding more letters, or,
when the number of matches is small enough, just navigate to it with C-n
or the
down-arrow key.
If there are more than the default 10 matches, you can scroll through them until
you spot the one you want, or edit your pattern (with the usual Minibuffer
editing commands) to narrow it down further. The usual Minibuffer history
commands work as well. See Table 4.
Key | Type | Action |
---|---|---|
C-n , ↓ |
Move | Move down to highlight next match |
C-p , ↑ |
Move up to highlight previous match | |
RET |
Done | Select the highlighted match |
C-RET |
Use the exact text that you typed | |
C-v |
Scroll | Scroll down to reveal the next 10 matches |
M-v |
Scroll up to reveal the previous 10 matches | |
M-> |
Scroll to the bottom of the matches | |
M-< |
Scroll to the top of the matches | |
M-p |
History | Pull up the previous history element |
M-n |
Pull up the next history element |
Done!
When your target is properly highlighted, you’re done. Hit RET
to select it.
If you’re completing a M-x
command, the command will be executed. However, if
you’re entering a filename for, say, find-file
or a buffer
name for switch-to-buffer
, you may be intentionally typing
a nonexistent name, to create a new file or buffer, which therefore can’t
possibly have a match! In this case, you use C-RET
to select not the
highlighted match, but the exact text you’ve typed, as is.
Complementary Packages
Vertico is designed to be enhanced and customized via a set of complementary
packages. I also recommend installing Marginalia, which provides annotations in
the Minibuffer adjacent to command names, file names, buffer names, and more.
(unless (package-installed-p 'marginalia) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'marginalia))) (with-demoted-errors "%s" (marginalia-mode +1))
Now M-x sw-to
looks like Figure 10 and C-x C-f
looks like Figure
11:
Other Incremental Narrowing Frameworks
I think Vertico is one of the best INFs, but Emacs has a few other built-in INFs
to choose from, and more in the Package Manager. The built-in INFs are
Icomplete ( M-x
icomplete-mode
), Ido ( M-x
ido-mode
)
(“Incremental Do”: see the Ido manual) and Fido
( M-x
fido-mode
). Unlike most modern INFs, their interface is
horizontal. When you hit M-x
, you’ll see something like this:
M-x {execute-extended-command | enable-theme | dired-at-point | …}
You navigate through the matches with the left- and right-arrow keys.
(I’m showing an abbreviated version; you’ll typically see half-a-dozen
candidates, possibly spread across at most two minibuffer lines.)
Note that you don’t need to hit TAB
to see these candidates: that’s a
big part of what makes an INF more efficient. These will narrow as you type.
They all work together, and if you want to use them, you should probably turn
all three of them on in your Init File:
(icomplete-mode 1) (ido-mode 1) (fido-mode 1)
Most modern INFs have chosen, like Vertico, to go for a vertical presentation of
the candidates, using a multiple-line expanding Minibuffer; this gives more room
for long command and file names, and in some frameworks, useful extra
information like that provided by Marginalia.
The other vertical INF in the GNU package repository is Ivy; it has more built-in
features, which are quite powerful, but due to its complexity, it may not
interact as well with some Emacs subsystems. (Vertico aims for 100%
compatibility and comes very close by being simple.)
Third-Party INFs
The king of Emacs INFs for some time had been Helm, which dramatically remakes
dozens, perhaps hundreds of Emacs commands (though you can configure it to be
more or less intrusive). Its completion buffer can take up the bulk of your
screen and present scads of additional information. It allows you to do a
variety of actions (like, deleting files) in mid-completion, and its fans are
very devoted. I find it to be too bulky, too intrusive, and too complex and
confusing. It’s also now apparently abandonware.
For Emacs purists who want to do their editing with mental powers alone, there’s
Icicles. It’s amazingly powerful and I used it for some time, but I ultimately
abandoned it because I had trouble getting it to work with Tramp; in addition,
the author chooses not to make it available via the Package Manager and so
it’s daunting to acquire84.
There are other options like Raven, Sallet, and Snails, but I have
recently settled on Selectrum, one of the newest (but surely not the
last) Emacs INFs. For me it combines simplicity and utility
perfectly, and instead of taking a kitchen-sink approach to features,
can use the same optional add-ons (like Marginalia) as Vertico.
Completion in Normal Buffers
In this chapter, we’ve discussed completion in the Minibuffer, but Emacs also
does completion in normal buffers. It comes in two flavors:
explicitly-activated completion at Point, and implicitly-activated completion
via a popup menu.
For the former, when you’re half-finished typing a word, you hit
M-/
(dabbrev-expand
), and Emacs completes the word for you.
This an amazing feature and an essential skill to pickup; see
Completion at Point.
For the latter, you can arrange to have a (lightweight, non-GUI, plain-text)
menu pop up as you’re typing, showing you possible completions, any of which you
can select by quickly navigating to it with the arrow keys. This popup
completion isn’t typically enabled for ordinary words in prose, but rather in
buffers whose Major Mode usefully limits the candidates. In particular, in
programming language modes, where library functions and symbols in the buffer
are presented. See Pop-up Menu Completion.
What is Text?
I call Emacs the “Plain Text Computing Environment”, but what exactly is text?
The notion of text is fairly intuitive to Unix users, elderly computer users of
any stripe, and programmers, but may actually be puzzling to younger users who
have spent all their lives interacting with GUI desktop applications, or tablets
and smartphones only.
Classically, text consists of the printing characters from the ASCII character
set: that is, upper- and lowercase letters, digits, punctuation marks, and a few
whitespace characters. These are the characters that make up the bulk of your
keyboard. Here’s the complete ASCII character set: ignoring whitespace, the
printing characters are those from (decimal) 33 through 126:85
Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex 0 00 NUL 16 10 DLE 32 20 48 30 0 64 40 @ 80 50 P 96 60 ` 112 70 p 1 01 SOH 17 11 DC1 33 21 ! 49 31 1 65 41 A 81 51 Q 97 61 a 113 71 q 2 02 STX 18 12 DC2 34 22 " 50 32 2 66 42 B 82 52 R 98 62 b 114 72 r 3 03 ETX 19 13 DC3 35 23 # 51 33 3 67 43 C 83 53 S 99 63 c 115 73 s 4 04 EOT 20 14 DC4 36 24 $ 52 34 4 68 44 D 84 54 T 100 64 d 116 74 t 5 05 ENQ 21 15 NAK 37 25 % 53 35 5 69 45 E 85 55 U 101 65 e 117 75 u 6 06 ACK 22 16 SYN 38 26 & 54 36 6 70 46 F 86 56 V 102 66 f 118 76 v 7 07 BEL 23 17 ETB 39 27 ' 55 37 7 71 47 G 87 57 W 103 67 g 119 77 w 8 08 BS 24 18 CAN 40 28 ( 56 38 8 72 48 H 88 58 X 104 68 h 120 78 x 9 09 HT 25 19 EM 41 29 ) 57 39 9 73 49 I 89 59 Y 105 69 i 121 79 y 10 0A LF 26 1A SUB 42 2A * 58 3A : 74 4A J 90 5A Z 106 6A j 122 7A z 11 0B VT 27 1B ESC 43 2B + 59 3B ; 75 4B K 91 5B [ 107 6B k 123 7B { 12 0C FF 28 1C FS 44 2C , 60 3C < 76 4C L 92 5C 108 6C l 124 7C | 13 0D CR 29 1D GS 45 2D - 61 3D = 77 4D M 93 5D ] 109 6D m 125 7D } 14 0E SO 30 1E RS 46 2E . 62 3E > 78 4E N 94 5E ^ 110 6E n 126 7E ~ 15 0F SI 31 1F US 47 2F / 63 3F ? 79 4F O 95 5F _ 111 6F o 127 7F DEL
You’ll notice right away that this 1963 American standard doesn’t really
accommodate non-English speakers, which is why there are so many other character
sets86. Nowadays, text would be defined to include all the printing
characters, international and specialized, in the enormous standardized Unicode
character set (Emacs knows 64,414 of them by name) and the
267-odd other character sets Emacs supports.
The Structure of Text
Lines are the fundamental unit of organization for most (but not all) text.
Text consists of a sequence of lines, and lines are separated by end-of-line
characters.87 We usually loosely call the end-of-line character a newline
(but see International Character Set Support for the gnarly details). You can
enter a newline, and thus begin a new line, by hitting the key Emacs calls RET
or
, which on your keyboard might also be labeled ENTER
.
The end of a line at the very end of a Buffer is somewhat ambiguous88.
Suppose we have a Buffer whose text consists of “foo”, a newline, and “bar”;
that’s 7 characters, but how many lines is it? In your Buffer it looks like:
and to me, that’s unquestionably two lines. Emacs agrees.
C-x l
(count-lines-page
) reports:
Page has 2 lines (0 + 2)
and — further confirmation — if we invoke M-x
linum-mode
, the
buffer looks like:
But there’s no newline after “bar”! If we add one, the buffer looks the same,
and C-x l
and linum-mode
both still report two lines. In other words, the
number of lines is not necessarily exactly the same as the number of newline
characters.
Unfortunately, this ambiguity is simply a fact of computing life. The good news
is, 1. it doesn’t usually cause any problems, and 2. Emacs has extensive
facilities for dealing with it; see Manipulating Plain Text for details.
When Emacs was fresh and new in the 1970s, people entering prose text would
typically hit RET
after typing 72 characters or so, and almost always before
80.89 Paragraphs were typically separated by an empty or blank line (i.e.,
a line consisting solely of a newline, or possibly a sequence of whitespace
characters followed by a newline), or by a line with leading indentation (i.e., a
few spaces), or both: exactly how you’d type it on a typewriter. Emacs’s Text
Mode (see “Text Mode” in the Emacs manual) is designed for this kind of prose text
and has support for automatic wrapping, indenting, and filling of paragraphs.
But there’s no limit to the length of a text line, and in fact in the modern
world, the current convention is that each line of typed text is in fact an
entire paragraph, and paragraphs therefore no longer even need to be separated
by blank lines (though they may be). This convention arose with GUI
applications, whose windows weren’t limited to 80 column lines and whose widths
could be resized at will: single-line paragraphs auto-fill as the screen is
resized, but multi-line paragraphs do not. Emacs of course supports this
convention but it’s not the default, primarily because Emacs was written by and
for programmers, and both computer programs and computer data files are
typically expressed as lines with explicit newlines, and the lines may have
semantic significance.
For details on how long lines are displayed and what you can do to change it,
see The Display of Lines.
What Isn’t Text?
There’s no law that says text can’t include non-printing characters, like, say,
a C-a
(which is ASCII 1 decimal). If a file contains only printing characters,
it clearly deserves the label “text”; if it contains none, it clearly doesn’t
and instead we call it binary data. But in between, the label is a judgment
call. Regardless, Emacs needs to show you non-printing characters when they
occur.
(I’m afraid this section has to be very nerdy; none of this will surprise a
programmer, but the explanation of it all involves the distant history of
computing, computing Standards (gulp), and a variety of number bases. Feel free
to skip ahead!)
When one of the ASCII control characters—those in the range decimal
0–3190—occurs in a Buffer, Emacs displays it specially, using the traditional
programmer’s notation for control characters: a circumflex followed by an
uppercase letter (or punctuation mark in six cases), for example ^A
, which is
the same character that Emacs refers to as C-a
. Table 5 shows these
in the “Control” column.
Dec | Hex | ASCII | Control | Dec | Hex | ASCII | Control |
---|---|---|---|---|---|---|---|
0 | 00 | NUL | ^@ |
16 | 10 | DLE | ^P |
1 | 01 | SOH | ^A |
17 | 11 | DC1 | ^Q |
2 | 02 | STX | ^B |
18 | 12 | DC2 | ^R |
3 | 03 | ETX | ^C |
19 | 13 | DC3 | ^S |
4 | 04 | EOT | ^D |
20 | 14 | DC4 | ^T |
5 | 05 | ENQ | ^E |
21 | 15 | NAK | ^U |
6 | 06 | ACK | ^F |
22 | 16 | SYN | ^V |
7 | 07 | BEL | ^G |
23 | 17 | ETB | ^W |
8 | 08 | BS | ^H |
24 | 18 | CAN | ^X |
9 | 09 | HT | ^I |
25 | 19 | EM | ^Y |
10 | 0A | LF | ^J |
26 | 1A | SUB | ^Z |
11 | 0B | VT | ^K |
27 | 1B | ESC | ^[ |
12 | 0C | FF | ^L |
28 | 1C | FS | ^ |
13 | 0D | CR | ^M |
29 | 1D | GS | ^] |
14 | 0E | SO | ^N |
30 | 1E | RS | ^^ |
15 | 0F | SI | ^O |
31 | 1F | US | ^_ |
Thus, in your Buffer, a single control character displays as a pair of
characters. This is ambiguous: is that ^A
one character, ASCII decimal 1 aka
SOH
, or is it the two printing characters, ^
followed by A
? There are two ways
tell:
- by movement: your cursor will skip over a control character with a single
C-f
(forward-char
), where it would take twoC-f
’s to move
over the pair of printing characters; - by color: the control characters are colored differently than the printing
characters; if your Buffer text is black-on-white, the control characters
will be red e.g.
^A
;
if your Buffer text is white-on-black91, the control
characters will be cyan e.g.
^A
.
There are other characters, which are tricky to classify as printing or
non-printing, that aren’t part of the original ASCII character set: they would
occupy the slots from 128–255 decimal in an expanded table. If these
characters appear in a Buffer (one using the binary
Coding System), they are
represented as a backslash followed by a three-digit number e.g. 304
.92
Again, your cursor will move over such a character in one step, and they’re
colored the same as the control characters.
Inserting Non-Printing Characters
If you’re curious and want to see some of these non-printing characters in a
Buffer, you can just visit a native-code executable file on your
computer.93 But what if you need to insert one? Obviously you can’t
insert a ^A
by typing C-a
—that will just move your cursor to the beginning of
the line!
The basic command for this is C-q
(quoted-insert
). Inserting
a control character is easy: to insert a ^A
, just type C-q C-a
. You can
also needlessly quote printing characters—say, C-q A
—which just inserts the
printing character normally.
What if you want to insert “international”, non-Latin, characters from Unicode,
or you want to type fancy glyphs like Æ, or ¶? See International Character Set
Support for details.
Buffers
Just as in Unix “everything is a file”, in Emacs “everything is a buffer”.
[…] In most […] editors (and most other applications, for that matter), we
have things such as dialog windows, non-editable text areas […],
file-selecting widgets, etc. Not in Emacs: here, all these are buffers.
— Marcin Borkowski, “TEXing in Emacs”
A buffer is a very complex data structure. Most importantly a buffer contains
text, but additionally each buffer keeps track of various locations (where you
are now and where you’ve been recently) and parameters (like how much to indent
lines), maintains an undo history, has a Major Mode that customizes commands run
in the buffer to work distinctively on the type of text it contains, may have
several Minor Modes to further tweak behavior to your taste, and has a set of
key bindings that may be different from those in other buffers. If it’s
visiting a file, the buffer keeps track of its state compared to the file on
disk.94
In this chapter we’re mostly going to talk about buffers as unitary objects, as
distinct from what they contain. The text in the buffer is much more than just
a sequence of alphanumeric characters; how it is entered and displayed is the
subject of its own chapter.
The maximum buffer size is plenty big enough for most purposes:
2,305,843,009,213,693,951 bytes; that’s about
2.3 exabytes. Practically
speaking, the maximum buffer size is limited by the amount of memory available
on your system for Emacs to use.
Switching Buffers
To switch buffers means, specifically, to change which buffer is displayed in a
given Window. The basic command to do this is
C-x b
(switch-to-buffer
); it displays a different buffer in
the current window, prompting for the new buffer by name, using Completion. You
can also use one of these variant versions:
-
C-x 4 b
(switch-to-buffer-other-window
) - Switch to a
different buffer not in this window, but in the “other” window.95 -
C-x 5 b
(switch-to-buffer-other-frame
) - Switch to a
different buffer not in this frame, but in another frame; if the buffer is
already displayed in a window in another frame, switch to that frame and
window; if not, a brand new frame is created and the buffer is displayed in the
window in that frame.
You can also switch quickly to buffers you’ve recently used without specifying
their names. Emacs maintains its list of buffers in a ring in recency order.
-
C-x
(previous-buffer
) - switch to the previous
buffer you were in (in this frame); repeating this command goes further back
in the buffer-recency timeline -
C-x
(next-buffer
) - the same, but go forward in
timeline order.
(You can also use the less felicitous bindings C-x
and C-x
.)
The User Option switch-to-prev-buffer-skip
allows you to
customize which buffers these two commands consider to be candidates.
The Global Mark Ring provides another way of switching buffers:
C-x C-SPC
(pop-global-mark
) will jump to previous Mark
locations in other buffers.
The Tab Line
Outside of Emacs, Tabs (not to be confused with the ASCII TAB character nor with
tab stops) are a pervasive graphical user interface design element for
navigating between multiple “objects” in an application: whether web pages, word
processor documents, desktop windows, or whatever. The objects being the subject
matter of the application, they would correspond to Buffers in Emacs. Yet Emacs
hasn’t had Tabs until quite recently96: Completion and the Buffer Menus
have sufficed for Emacs users for decades.
But now you can turn on the Tab Line. The Tab
Line is a per-Window construct: a special sticky line of tabs at the top of your
Window, each tab shows the name of a buffer that has been displayed in this
particular Window.97 There’s also a +
-sign at the right that, when clicked, pops
up a classified GUI menu that allows you to switch to any other buffer, thus
adding another tab to the bar.
This is obviously a feature for mouse users, but if you’re a keyboard-only
person like me, I suppose you might still want the Tab Line for its visuals.
Note that the buffers shown in the Tab Line are the same ones you can navigate
through with C-x
(previous-buffer
) and
C-x
(next-buffer
).
You can turn the Tab Line on for any Window with M-x
tab-line-mode
.
If you want this for all your Windows, say M-x
global-tab-line-mode
;
you can make this your default by adding this to your Init File:
(global-tab-line-mode 1)
The Package Manager is full of third-party packages for selecting buffers;
pretty much any approach any other program or operating system has used for
something similar can be found as an Emacs package: from a very visual Mac Os
Exposé-like switcher, to my favorite, the very abstract buffer-stack
.
Creating Buffers
Buffers are typically created for you, implicitly, by any number of commands:
the file visiting commands, of course, but also by many of the thousands of
other commands: the Help commands create *Help*
buffers, for example, and any of
the Emacs “applications” like the File Manager (Dired) or the Web Browser (Eww)
create buffers to present their user interfaces. Buffers are used for almost
everything in Emacs, and you won’t even be aware of most of them; I have 175 in
my Emacs as I write this.
You can also just create a new buffer anytime you want. The command for this is
good old C-x b
(switch-to-buffer
); typically, this command is
used to display a different, existing, buffer in the current window, as
described in the previous section. But when
switch-to-buffer
prompts you for the buffer name, if you
enter a new, non-existent, one, it instead creates a brand new, empty, buffer.
This buffer will be in fundamental-mode
unless your chosen
name looks like a filename with an extension (say, foo.org
), in which case the
Major Mode will be determined as described in How a Mode Happens to Your
File. Regardless, there will be no file associated with this new buffer.
To Save or Not to Save
When you exit, Emacs will offer to save modified buffers that are visiting
files, so that you don’t lose your work. But non-file buffers don’t get this
treatment, no matter how much work you may have done in them!98 You can always
use C-x C-w
(write-file
) to associate a file with such a
buffer after the fact.
It may be tempting to create new non-file buffers or use the *scratch*
buffer
just to take some transient notes, but such notes have a way of surreptitiously
becoming important, and you will lose them if you exit without saving them
somewhere. Emacs has better ways for you to take notes.
Buffer Names
This inspires me to mention the fact that every buffer has a name. There are no
anonymous buffers. Not only must every buffer have a name, but that name must
also be unique. When there are natural name conflicts, Emacs will usually
disambiguate the newer buffer name for you. Buffers that aren’t visiting a file
typically get numeric suffixes, like *shell*<2>
and *shell*<3>
, but for files
things are more interesting.
The name of a Buffer that’s visiting a file is typically the basename of that
file; for example, if you visit /etc/passwd
, the Buffer will be named passwd
.
Since there could be any number of files named passwd
in various directories, in
order for you to be able to visit more than one of them, Emacs must uniquify the
buffer name. You can choose from a variety of uniquification algorithms. Using
the default algorithm, if you visit /tmp/passwd
, having already visited
/etc/passwd
, the new Buffer will be named passwd
. See
“Uniquify” in the Emacs manual for details.
You can rename buffers at will with M-x
rename-buffer
. Since some
applications manage their buffers by name, renaming them might break the app!
But many, probably most, buffers are perfectly safe to rename. While uncommon,
you can rename any file-visiting buffer; the buffer name won’t affect the
filename. It’s quite common to rename the buffers of commands that re-use the
same name. Although help-mode
has commands to navigate
back and forth through your history of Help invocations, you might want to
rename a given *Help*
buffer to keep it around and easily accessible.
M-x
shell
is the opposite: when you run it, if that buffer already
exists, it simply switches to it (kind of like
C-x C-f
(find-file
); if you want a second shell, you can
first rename the existing Shell buffer to whatever you like.99
M-x
rename-uniquely
will automatically rename any buffer for you,
using a numeric suffix.
Asterisks
It’s conventional that non-file-visiting Buffers created by Emacs commands are
named with *asterisks*
; for example, the Help commands use (and reuse) the
Buffer name *Help*
, and Emacs starts up with a *scratch*
Buffer. When
explicitly creating your own Buffers, you can observe this convention or not, as
you like.
Hidden Buffers
Unix users are familiar with the utility of
dot files: any file basename that begins with a period is by default excluded
from the directory listing of the ls(1)
command. This reduces clutter in a
directory listing from files that are always present (like .
and ..
in any
directory, or configuration files like .bashrc
in a home directory). Of course,
you can see these “hidden” files when you need to (by passing the -a
option to
ls
, for example).
The same concept applies to buffer names. Many Emacs applications that present
themselves via a buffer, such as the document viewer Doc View or the web browser
Eww, use hidden buffers to manage their state. A hidden buffer is any buffer whose
name begins with a space character, and by default, they are not offered for
completion nor listed by the buffer listing commands. Hidden buffers are mainly
created by Elisp programmers and you probably don’t want to use buffer names
that begin with a space for your own purposes. They’re not really suitable for
interactive use; in particular, Undo is turned off by default in such buffers.
The Default Directory
In addition to a name, every buffer has a default directory. This is analogous
to the working directory of a process in Unix. The default directory of a
file-visiting buffer is the directory where the file was located. If you’re in
a shell in a terminal, and you give a filename to some command via a relative
path, that filename is interpreted relative to the shell’s current working
directory: Emacs works the same way. If a command prompts you for a filename,
the prompt will be preset to contain the buffer’s default directory; you can
delete or edit it to name a file in some other directory, of course, but if you
completely delete any directory and just enter a relative path, it will be taken
as relative to the default directory.
If you create a non-file buffer, its default directory will generally be
inherited from the buffer you were in when you created it. But any Emacs
command that creates a buffer is free to set its default directory to whatever
is appropriate.
The default directory is just a buffer-local variable named
default-directory
. You can check what it is with
M-x
pwd
, which prints the value of this variable in the Echo
Area,100 and you can change a buffer’s default directory with
M-x
cd
, which sets the variable to whatever directory you specify.
Note that changing the default directory of a file-visiting buffer does not
change the directory of the file you’re editing—not even if you re-save the
buffer. It only affects prompt defaults and the resolution of relative
pathnames you give to commands while you’re in that buffer. To change the
directory of a file you’re editing, use C-x C-w
(this is equivalent to making
a new copy of the file).
Reverting Buffers
File-visiting buffers can be reverted with M-x
revert-buffer
to make
the text in the buffer match the text in its file. There are two major reasons
for doing this: either to throw away all the unsaved modifications you’ve made
without undergoing a tedious sequence of Undos (and restore the buffer’s text to
what’s in the file), or because the file has been changed behind Emacs’s back
by some other process and you want the buffer to reflect this. See Files: Reverting
Buffers, Auto-Reverting (Watching Files), and Files Modified Behind Emacs’s
Back for more information.
Many non-file buffers implementing Emacs applications can also be reverted; the
exact meaning of “revert” in these buffers depends on the application. For
example, C-x C-b
(list-buffers
) pops up a buffer containing a
list of all your buffers (see Buffer Menus), but if a new buffer is created
later, the list won’t (for good reasons, IMHO101) be automatically updated to
show it; reverting the buffer list will do so. In Major Modes descended from
Special Mode, the key g
is often bound to revert-buffer
,
but check with C-h m
(describe-mode
) first.
Killing Buffers
There are many ways to delete or, as we say in Emacs, kill buffers, but why
would you want to? There are two main reasons:
- Each buffer takes up in memory at least as much space as the file takes up on
disk; when you kill a buffer, you free up that space and Emacs has that much
more to work with.102 - Lots of old buffers means clutter; more buffers to ignore in buffer listings,
more to ignore when doing buffer-name completion, more buffers to search
through if you ask Emacs to do so. If you run Emacs as a long-running process
in Server Mode (as I recommend), you might accumulate many buffers over the
space of weeks or even months!103
We’ve already seen the basic command for killing a single buffer, by name and
with completion: C-x k
(kill-buffer
);
C-x 4 0
(kill-buffer-and-window
) kills the current buffer and
also deletes the window that was displaying it; it’s especially useful when
popping up hits from a Grep command. There are also several commands
to clean up unneeded buffers:
-
M-x
kill-some-buffers
- asks whether or not to kill each buffer
in your Emacs; it makes it clear whether or not the buffer is modified. This
command is way too tedious unless you have hardly any buffers, and if you have
a lot, a sort of highway hypnosis can set in that might result in you killing
a buffer you didn’t want to. -
M-x
kill-matching-buffers
- This command prompts for a Regular
Expression and only asks about the buffers whose names match it, so this might
be a little bit better. I still wouldn’t use this one! -
M-x
clean-buffer-list
- is a totally automatic way to clean up a
lot of buffers, with no prompting and no questions asked. It will of course
never kill a modified buffer, but it will instantly get rid of buffers that
you haven’t looked at in a while (by default,
3
days). It’s highly customizable, so you can define certain buffers that it
should never clean up; examineM-x customize-group RET midnight RET
. See also
Midnight Mode.
I think the best thoughtful (i.e. not totally automatic) way of cleaning up
buffers is via one of the Buffer Menu commands below, which give you a
Dired-like interface to the task.
Buffer Menus
C-x
(previous-buffer
) and
C-x
(next-buffer
), along with
C-x b
(switch-to-buffer
) (coupled with a good Completion
framework) will form the vanguard of your buffer navigation. But sometimes
you’ll need a way to get an overview of all your buffers, and some tools to
manage them. This is what the Buffer Menus provide. A Buffer Menu is to
buffers what Dired is to files.
There are three main choices:
list-buffers
, bs-show
, and
ibuffer
.
The most basic command is C-x C-b
(list-buffers
); it pops up
a *Buffer List*
buffer that lists all the buffers in your emacs, giving, along
with their names, their sizes, Major Modes, and visited file name (if any):
CRM Buffer Size Mode File .% passwd 1699 Conf[Colon] /etc/passwd % *Calendar* 531 Calendar % *Help* 554 Help *scratch* 145 Lisp Interaction %* *Messages* 305 Messages
The cryptic CRM
Column shows the current buffer (indicated by a period in the C
column), a %
under R
if the buffer is read-only, and a *
under M
if the buffer
is modified.
This buffer is in buffer-menu-mode
, and if you switch into
it, a number of buffer-management commands are available. Just move to anywhere
within a buffer’s line and the special commands will operate on that buffer.
Some operate immediately, but some only mark the buffers and perform the
operation when indicated. See table 6.
Key | Action |
---|---|
RET |
replace Buffer Menu with this buffer |
1 |
like RET C-x 1 |
o |
select buffer in Other window |
V |
… in view-mode . |
C-o |
display buffer in Other window (without switching) |
m |
mark this buffer for v or M-s a … |
v |
display this and all marked buffers |
u |
remove all marks from this line |
DEL |
back up a line and remove marks |
U |
remove all marks in the Buffer Menu |
M-DEL |
remove a particular mark from all lines |
T |
Toggle display of only file buffers |
S |
Sort lines by the column that contains Point |
{ |
narrow this column |
} |
widen this column |
b |
Bury the buffer listed on this line |
t |
visit Tags table of this buffer |
~ |
clear modified-flag |
% |
make buffer read-only |
s |
mark for Save upon x |
C-k |
mark for Kill upon x , move down |
C-d |
mark for kill upon x, move up |
x |
eXecute kill or save marks |
M-s a C-s |
Incremental Search in the marked buffers |
M-s a C-M-s |
Isearch for regexp in the marked buffers |
M-s a C-o |
Occur in the marked buffers |
g |
revert (update) the Buffer Menu |
q |
hide the Buffer Menu |
bs-show
is very similar to
list-buffers
; it has a very similar command set104,
but is more customizable and, in its default configuration, is a bit more
colorful. I’d recommend it over list-buffers
just for that reason; you can bind
it to C-x C-b
with:
(global-set-key (kbd "C-x C-b") 'bs-show)
The Buffer Menu that I use is ibuffer
. It’s even more
colorful than bs-show
, but it has the largest command set and is more like Dired
than the other two.105 It has a more extensive set of marking commands, a
much larger, stackable, set of commands to filter the Buffer Menu (e.g., by
Major Mode, by visited directory name, by size), and a much larger set of
sorting commands. It has so many commands that I won’t attempt to summarize
them here; say C-h f ibuffer-mode
.
I recommend it, and I bind it to C-x C-b
with:
(global-set-key (kbd "C-x C-b") 'ibuffer)
Note that neither list-buffers
nor bs-show
will list hidden buffers (those
starting with a space). ibuffer
can do this, however.
Narrowing
Many commands that perform repetitive operations (like Query Replace) will limit
their operation to the active region. Some (like Keyboard Macros) do not, but
these recalcitrant commands can be convinced to do so by narrowing the buffer to
the Region (whether active or not).
C-x n n
(narrow-to-region
) hides the parts of the buffer
outside the region, making them almost completely inaccessible. After
narrowing, you can run any command on the entire buffer without worrying that it
will affect the hidden parts. Narrowing can also be useful just to focus your
attention on a part of your text, say a particular paragraph, or a gnarly
function, with no distractions.
Once you’ve narrowed, it’s as if the rest of the buffer is gone. The buffer
size indicator in the Mode Line will report the size of the narrowed portion as
if it’s the entire buffer, and any displayed line numbers will be reset from 1.
If you save a narrowed file-visiting buffer, you will always save the entire
buffer, including the invisible parts—don’t worry that you might lose data by
saving only the narrowed part to the file!
The Mode Line will include the word “Narrow” in the parenthesized list of Minor
Modes (even though narrowing isn’t, strictly speaking, a Minor Mode). There are
a few other giveaways. The value of Point, which you’ll recall is the offset,
in characters, from the beginning of the buffer, remains relative to the entire
unnarrowed Buffer. One command that reveals the value of Point is
C-x =
(what-cursor-position
). Suppose you narrow your 500K
buffer to one paragraph in the middle of the text; what-cursor-position
will
show that Point is something like 254,120 rather than 1. Go ahead and try it!
But wait, first I’d better tell you how to restore your buffer after narrowing
it! C-x n w
(widen
) does the job. Point remains where it
was, and all the hidden parts blossom forth again.
If someone new to Emacs accidentally narrows a buffer, the usual assumption is
that, somehow, much text has mysteriously been lost, and the reaction is
dismay. For this reason, C-x n n
(narrow-to-region
) is
disabled by default. But it’s a very useful command, and I recommend you
enable it after you’ve tried it a couple of times.
Modes, Major and Minor
Major Mode | Minor Modes | |
---|---|---|
Specialization | X | |
Preferences | X |
The main way Emacs specializes different kinds of text — prose, programming
languages, data file formats — is through Major Modes. Major Modes typically
provide customized fonts, colors, and other styling; layout (indentation and
such); key bindings; templating; integration with compilers, interpreters, and
debuggers; and more.
Every buffer always has a single Major Mode, and may have zero or more Minor Modes
enabled. While Major Modes implement broad sets of features suited to a
particular kind of text or application (an application like, say, a web
browser), Minor Modes are typically independent of any particular kind of text,
and instead implement user preferences and features that are generic
and could enhance many or all Major Modes: things like spell check, line
numbers, or folding text.
The Major Mode is, by default, shown in the Mode Line as the first word in
parentheses. If your buffer is in python-mode
, the Mode Line will show:
(Python)
(the Major Mode indicator may be followed by a list of space-separated Minor
Mode indicators).
Many Major Modes are for particular programming languages, but they also exist
for markup languages (TeX and LaTeX, Troff, HTML, Markdown, Org), config file
formats (for INI files, and many application-specific formats like Apache, Git,
Kubernetes, etc), data file formats (Json, CSV, XML, Turtle (RDF), YAML,
BibTex), image files, PDF files, and more.
An important role for Major Modes is to implement interfaces to external
programs, like version control systems (Git, Mercurial, etc), databases,
shells, Grep, and programming language REPLs; more modes implement 100%-Emacs
applications like file managers, email systems, games, and web browsers.
At the moment, there are at least
412 more Major Modes
available in the Package Manager, and even more on
Github and the like. Basically, if you’re editing some
kind of structured text, there’s an Emacs mode to make the editing better.
How a Mode Happens to Your File
When you visit a file, Emacs chooses a Major Mode for you automatically,
typically based on a file extension. Files ending in .org
will automatically be
in org-mode
; files ending in .py
will automatically be in
python-mode
.
But Major Mode selection is really more complex. Emacs has a decision tree that
proceeds from the file contents, through the file name, to your chosen overall
default. Here’s the complete sequence.
Mode via File-Local Variable
You can explicitly set the Major Mode by including a string like this:
-*- MODE -*-
somewhere on the first non-blank line of the file, where MODE
is the name of the
mode, leaving off the trailing -mode
. So this line:
-*- python -*-
will cause Emacs to choose python-mode
when it visits the file. Likewise:
-*- emacs-lisp -*-
selects emacs-lisp-mode
.
The mode string can be preceded on its line by any text, and followed by even
more text. This allows you to put the mode string in a comment; thus:
/* -*- c -*- */
selects c-mode
and
# -*- python -*-
selects python-mode
.
File local variables, in their full
glory, are a concept originated by Emacs.106 You can set additional variables this
way:
-*- python; python-indent: 4 -*-
and you can also set them at the end of the file, if your language is particular
about the top, or if you just prefer them there (they might be less
distracting).
Mode via Shebang, or Interpreter Directive
If the Major Mode wasn’t chosen due to a file-local variable, Emacs next looks
to see if the file begins with a shebang, or interpreter directive. This is a
Unix concept that allows executable text files to be run as scripts by a variety
of programming language interpreters. So if your file begins with:
#!/bin/sh
Emacs will select shell-script-mode
. By default, Emacs knows how to map
46 interpreter names to the
right Major Mode; you can customize the variable
interpreter-mode-alist
to tweak these choices or add more.
Unix says that the shebang must be the first line of a file, so if you also want
some file-local variables, you’ll need to set them via the
end-of-file syntax.
Mode via Filename
If the Major Mode was chosen neither by a file-local variable nor a shebang,
Emacs next checks to see if the file extension determines the mode.107 This
is controlled by the variable auto-mode-alist
, so you can
override the defaults to suit your preference. Out of the box, auto-mode-alist
encodes 0 different file extension / mode
pairings.
This variable actually allows more sophisticated choices than just the file
extension: you can base the choice on the structure of the entire file name,
including the directory (so you can set a default mode for all the files in a
given directory, regardless of their basenames or extensions), and (as is
typically the case in such customizations) you can even base the choice on the
result of a function call.
Mode via Magic Fallback
If the Major Mode has still not been chosen, Emacs now checks
magic-fallback-mode-alist
, which examines the content of
the file to determine the mode. This default value of this variable contains
patterns and functions that recognize image formats and make distinctions about
HTML and XML file formats (which can’t easily be made via file extension).
The Last Resort
Finally, if the Major Mode remains undetermined after this entire process, the
default value of the variable major-mode
is used. The
default default (!) is fundamental-mode
, the ultra-minimal Major Mode that does
absolutely nothing special.
You can change the default Major Mode to something else, like for example:
(setq-default major-mode 'text-mode)
after which you’ll get text-mode
as your default. (If you’re a programmer or system
administrator — one who edits system files — I highly recommend keeping
fundamental-mode
as the default value of major-mode
; any other choice might
modify a file while you’re editing without your noticing.108)
But really there’s one final, ultimate, decision: in the case that major-mode
’s
default value is nil
, which will only be the case if you choose to make it so,
the Major Mode will be that of the buffer you were in before you switched to a
new buffer (by visiting a file, or creating a new buffer say by giving
C-x b
(switch-to-buffer
) a nonexistent buffer name).
Setting the Mode Explicitly
You can always set the Major Mode of a buffer explicitly, either because the
usual process came up with fundamental-mode
, or chose the wrong mode (perhaps
due to an unusual or nonexistent file extension), or just because you prefer an
alternative mode at the moment.
Conventionally, Major Modes exist as commands named according to the pattern
major-mode-name-mode
,
so you can switch to Org Mode by invoking M-x
org-mode
or to Emacs
Lisp Mode with M-x
emacs-lisp-mode
. After switching, there might be
a visual change as the new mode’s syntax colorization takes effect; for example,
after switching to fundamental-mode
, any colorization will disappear, since
fundamental-mode
doesn’t do any syntax highlighting (this is one of the most
common manual mode changes, because since fundamental-mode
does nothing visually
to the characters in the file, you can be sure you’re seeing the precise contents).
To restore Emacs’s choice of mode, you could reinvoke the mode’s function by
name, but the simplest way is to say M-x
normal-mode
. normal-mode
is not a Major Mode, but rather just a function that instructs Emacs to go
through the entire Major Mode-choosing process again.
Help for Your Mode
If you want to know what’s up with the Major Mode Emacs has chosen, just say
C-h m
(describe-mode
). The *Help*
buffer will first list all
the enabled Minor Modes (because Major Modes often turn on a set of Minor
Modes); these are hyperlinked to complete descriptions later in the buffer.
Then the documentation for the Major Mode will be presented (for some modes,
this is quite extensive), and then typically a complete list of Major
Mode-specific key bindings will be given (there might only be a couple; for some
modes, like org-mode
, there might be several hundred!).
Finally the documentation and key bindings for all the Minor Modes will be
given. This can be a lot of documentation; for me, the Org Mode *Help*
buffer is
over 900 lines long!
Customizing Modes
It’s very common to want to customize the way a Major Mode109 works, and
well-written Major Modes (the majority of them!) provide many ways to do so.
You might want to change the default indentation level or the color of comments
or string literals in a programming language mode. You might want to change
some of its key bindings to ones that are more mnemonic or easier to type. You
might want to disable an annoying command that you find yourself accidentally
invoking (I do a lot of this!).
The simplest type of customization is to modify the value of a user option,
i.e. an Emacs variable that’s explicitly intended to be used to tweak a mode’s
behavior. The easiest way to do this is to go to a buffer that has the Major
Mode you’re wanting to tweak and invoke M-x
customize-mode
; this
gathers all of the mode’s user options together and you can use the Customize
facility to change them. You can also just set these options in your Init File
via Elisp, e.g.:
(setq python-indent-offset 2)
see User Options.
How do you find out what user options exist to be customized? Browsing the
customize-mode
buffer is a good way; you can also use
M-x
apropos-user-option
with a query like python indent
, and don’t
forget to read the Info manual for Modes which have one.
Customize doesn’t give you a way to change key bindings, so you’ll need to hack
your Init File to do that! See Modifying Key Bindings for instructions.
Finally, you may want to customize a mode in a manner that never occurred to the
programmer who wrote the mode, and so there’s no handy user variable to tweak.
A common desire is to turn on several specific Minor Modes whenever you’re in a
given Major Mode: for example, spell checking. But that’s just one of any
number of possible Minor Modes. The programmer of the Foo Major Mode shouldn’t
try to provide user options like foo-enable-spellcheck
because even though spell
checking is a common desire, there’s more than one way the user might want to do
it, and more to the point, there is an unlimited number of extant and
not-yet-written potential Minor Modes of interest. And you may want to enable a
behavior that’s not even a formal Minor Mode110.
Fortunately, Emacs has a general purpose mechanism to solve this problem; it’s
pervasive and part of what makes Emacs so malleable: Hooks. Hooks exist to
provide a way for an action of some kind to also perform some other arbitrary
actions at your behest. Every Major and Minor Mode FOO-mode
respects a
variable FOO-mode-hook
which is intended to contain a list of functions. Each
function in this list is executed, in order, after the mode is done initializing
the buffer. You simply add functions to this list; the functions can do
whatever you want.
So, if you want spell checking in Org Mode, and you prefer
flyspell-mode
to ispell-minor-mode
,
you can add this line to your Init File:
(add-hook 'org-mode-hook 'flyspell-mode)
If you don’t generally want line numbers turned on, but you do want them in
python-mode
, add this line:
(add-hook 'python-mode-hook 'linum-mode)
As the name implies, the add-hook
function adds an
additional function to a hook variable, at the front of the list. add-hook
is
clever and only adds the function if it isn’t already present (that way it
doesn’t run twice).
flyspell-mode
and linum-mode
are both Minor Modes, and Minor Modes are designed
to be easy to add to hooks. But you can add arbitrary functions as long as they
make sense. Want to give yourself a little encouragement whenever you open an
Elisp buffer?
(add-hook 'emacs-lisp-mode-hook (lambda () (message "Don't fear the parentheses!")))
More complex modes will define more than just the default
after-mode-initialization hook, and will run these hooks when certain actions
occur. org-mode
, for example, an especially complex Major Mode, has
80 hooks.
Hooks are not really just for modes. There are many defined for Emacs actions
that occur “globally” — hooks for when Emacs starts up and when it exits, for
example — and individual functions defined outside of any major mode can have
their own hooks so that you can customize their behavior.
Derived Modes and Inheritance
Almost all Major Modes are derived from some preexisting mode that’s in some way
similar. This way, the new mode inherits behavior from the parent (which may
have inherited behavior from its parent, and so on). The new mode inherits the
parent’s keybindings, syntax table, abbreviations, and Major Mode hook, and can
then change anything it’s inherited, or not. Note that the new mode’s hook will
run after all the inherited mode hooks. So if someone invents a new variant of
the Lisp programming language, say “Neolisp”, a new Emacs neolisp-mode
might
well be derived from lisp-mode
.
There are five Major Modes that are commonly used as parent modes:
text-mode
, for a new mode that deals with something similar
to natural-language prose; prog-mode
, for new programming language modes;
special-mode
, for modes that let you view data more than they let you edit it
(this includes most applications); tabulated-list-mode
, for modes that present a
view of data in sortable columns (and which is itself derived from
special-mode
); and finally, fundamental-mode
, the most minimal mode of all.
Note that prog-mode
, special-mode
, and tabulated-list-mode
exist only to be
derived from, whereas text-mode
and fundamental-mode
are themselves often used
as Major Modes.
Basic Major Modes
Here are a few basic Major Modes that can be useful when Emacs doesn’t have a
better idea for your text.
fundamental-mode
This is the basic mode in reference to which many other modes are defined. It’s
perfectly fine for editing any kind of text, it just doesn’t provide any special
features: it has no mode-specific key bindings and no colors to distinguish
different kinds of text. Every character in the buffer looks exactly like
itself.
It’s occasionally useful to turn off the fancy features of a specialized mode by
switching a buffer into fundamental-mode
; see
Setting the Mode Explicitly.
text-mode
For editing plain, unspecialized, natural language prose, i.e. blank-line
separated paragraphs consisting of sentences. This is the Mode Agatha Christie
would have used for her books, if she’d had Emacs instead of her typewriter.
Quite minimal.
outline-mode
You can add a little more structure to your prose by using
outline-mode
(see “Outline Mode” in the Emacs manual).
Lines that start with an asterisk form the nested headlines of an outline, and
you can fold (hide) and unfold the text of the outline levels, easily reorder
them without cutting and pasting, etc.
* My Header Some text. ** A Nested Sub-Header * Next Header
In recent years, outline-mode
has been largely subsumed under Org Mode, which
includes all its features, with friendlier key bindings, and adds so much more.
In my opinion you should skip over outline-mode
and go direct to Org.
Programming Language Modes
As of version 28.2, Emacs ships with Major Modes for at least
Ada, Assembly Language, AWK, C, C++, Common Lisp, Emacs Lisp, Fortran, Icon,
Java, Javascript, M4, Makefiles, Metafont, Modula2, Object Pascal, Objective-C,
Octave, Pascal, Perl, Pike, PostScript, Prolog, Python, Ruby, Scheme, Shell
(Bourne-, C-shell-, and rc
-derived flavors), Simula, SQL, Tcl, Verilog, and
VHDL.
In such a mode, Emacs does all the sorts of things you expect of an integrated
development environment (IDE): syntax highlighting to colorize and fontify the
different syntactic elements of the code, specialize textual objects for the
language (so Emacs’s symbols match the languages identifiers, and its functions
match the languages function definitions), balance parentheses, complete
identifiers, enable commands to insert and delete comments, indent and dedent
the lines appropriately, show documentation of built-in functions, jump from
function and identifier uses to their definitions, expand source code templates,
send function definitions to the language interpreter (REPL), interact with a
debugger, compile code, and jump from compiler error messages to the locations
in question.
Some of the common features of IDE’s are handled by independent, orthogonal
Minor Modes. On-the-fly syntax and style checking (linting) is often handled by
Flycheck111 or for languages that use the Language Server Protocol, Eglot or
lsp-mode
. Spellcheck in comments is handled by
flyspell-prog-mode
. Project navigation is the domain of
Projects or the much fancier Projectile. Version control has
its own chapter, as do build tools, searching, and
debugging.
Minor Modes
Minor Modes work like mix-ins:
enable as many as you like. Emacs turns on a dozen by default to implement
things like the automatic handling of compressed or encrypted files, and I
typically have a couple dozen other Minor Modes enabled too. At the moment,
there are at least 155 more
minor modes available in the Package Manager, and even more on Github and the like.
Minor Modes come in two flavors, global and buffer-local, and some come in both.
When you turn on a buffer-local Minor Mode, it’s only enabled in the current buffer;
if you want it on in another buffer too, you need to turn it on there
separately. This is why we often add Minor Modes to a Major Mode’s startup
hook: so that they’re automatically turned on in all buffers in that Major Mode.
But Minor Modes that are likely to be generally useful in any Major Mode often
come in a global flavor; when you turn on a global Minor Mode, it’ll be on in every
buffer that’s created. We’ve seen how you turn on line-numbers in a buffer with
M-x
linum-mode
; but there’s also M-x
global-linum-mode
.
It’s up to the programmer who implements a Minor Mode to decide whether to
provide a global command, a buffer-local command, or both.
Some Minor Modes will be listed in the parentheses of the Mode Line, after the
Major Mode. Right now, my Mode Line shows:
(Org Ind Fly PgLn NoMouse! Fill)
org-mode
is the Major Mode and all the rest are Minor Modes. Minor Modes may
shorten their Mode Line indicator112 dramatically (“Ind” above is org-indent-mode
),
and some choose to provide no indicator at all (global ones tend to use no
indicator). Minor Modes are used so heavily nowadays they can take up a lot of
Mode Line space. Each of these indicators provides various actions for mouse
clicks; see the Mode Line chapter.
We’ve seen how to add Minor Modes to hooks, but you can also turn them on and
off manually. Any Minor Mode command, like M-x
flyspell-mode
, will
toggle that mode: if it’s currently off, it’ll be turned on, and vice versa.
(This is different from Major Mode commands, which only turn the mode on; since
there’s always one and only one Major Mode in a buffer, you can’t simply turn it
off: all you can do is turn on (and thus replace it with) a different one.)
Global Minor Modes work the same way, affecting all buffers. The only practical
way to turn on buffer-local Minor Modes in your Init File is via hooks, but you
can directly turn global Modes on in your Init File like, for example:
Application Buffers
Broadly speaking, there are two kinds of Buffers in Emacs: those that are
visiting files, and those that aren’t. In file-visiting Buffers, we are editing
(or at least viewing) the contents of a file.
Non-file-visiting Buffers can be loosely subdivided into two further types. The
first is temporary Buffers. When you ask Emacs to display some information with
a command like M-x
list-colors-display
or M-x
calendar
,
the results are displayed in temporary Buffers. Of course, you can create a
brand-new, empty, non-file-visiting Buffer as simply as
C-x b
(switch-to-buffer
) NEWNAME
. You might even scribble
notes in it, or use it to gather text from other buffers for editing. Such
Buffers are transitory and thus unimportant: if one becomes important to you,
you save it to a file with C-x C-s
(save-buffer
): now it’s a
file-visiting Buffer.
The second type of non-file-visiting Buffer is what I’ll call Emacs
Applications: Buffers that implement the user interfaces of special purpose
programs: Buffers that you interact with. Such Applications include file
managers, web browsers, shells and terminals, version control programs, mail
user agents, games, and much more.
As I write this, my Emacs has 59 non-hidden Buffers, and 34 of them, the
majority, are Applications: I would say that proportion is completely typical.
Application Buffers are what make Emacs a Lisp Machine: a plain-text computing
environment. You could turn that around and say that Application Buffers exist
because Emacs is a Lisp Machine: the fact that it’s so readily programmable has
resulted in people using it to create so many Applications.
We’ve already discussed a few Applications without emphasizing it: the Help,
Apropos, and Info subsystems; and the Minibuffer. These Applications, and many
more, exist as user interfaces to Emacs itself, but most, as we’ll see soon, are
Emacs front-ends to your computer, to the network (and the web), and to Unix
command-line applications. And some are completely stand-alone Applications,
rather than front-ends to anything else (for example: the Calculator, Calendar, and
various Games and Amusements).
(You can also think of the fancier file-visiting Major Modes as applications:
IDE’s for programming languages, document viewers, and the like; in a Lisp
Machine, it’s really hard to make these distinctions.)
Every Application is unique, but most of them start out inheriting behavior from
a Major Mode called special-mode
. As a result, lots of
Applications share a certain amount of behavior and key bindings, which I’ll
discuss briefly here.
But first and foremost, an Application Buffer is just that: a Buffer. Most of
what you’ve learned about Buffers applies to Applications. Of course, there
will be differences, but in general in any Application you already know things like:
- how to navigate within it (use the motion and search commands)
- how to copy text (or data) from it (just select text and use
M-w
(kill-ring-save
)) - how to get help about it (
C-h m
(describe-mode
)) - how to switch between Applications (just switch Buffers)
- how to kill an Application (
C-x k
(kill-buffer
))
This is one of the advantages of Emacs as a computing environment: you have less
to learn because you already know these things.
Application Buffers start out and almost always remain read-only, and inherit
the following key bindings from special-mode
(see Table 7), but
remember that any Application will add more bindings, and very often
change some of the inherited ones, in the name of usability. Almost
all special-mode
commands are just handy shorthands for commands you already
know, shown in the “Also” column.
Key | Also | Action |
---|---|---|
SPC |
C-v |
scroll forward |
DEL , S-SPC |
M-v |
scroll backward |
< |
M-< |
go to beginning-of-buffer |
> |
M-> |
go to end-of-buffer |
- |
C-u - |
give next command a negative arg |
0 …9 |
C-u 0 ... |
give next command a numeric arg |
? , h |
C-h m |
show help for mode |
g |
C-x x g |
revert the buffer |
q |
C-x 0 |
hide the Application window |
Note that most Applications don’t have a command to stop or terminate them; you
can just switch away from their Window (special-mode
’s q
command is an easy way)
and never come back. As usual if, you want to clean up, you can just kill the
Application’s buffer.
UNFINISHED Windows
Figure 12: Emacs Data Structures
Legend:
* | One or more |
1 | Exactly one |
1? | One or none |
When Emacs starts up, it presents a Frame containing a single window. This
window displays a Buffer, and has its own Point. Optionally, a window (almost
always) has a Mode Line, and (less frequently) any of a Header Line, a left
Fringe and a Right Fringe; see Figure 13.
Figure 13: The Parts of a Window
The Frame can be tiled into multiple windows in a rectangular grid; that is, any
window can be recursively subdivided into more windows, horizontally or
vertically; see Figure 14.
At any moment, one window is the distinguished selected window113; most
editing commands, including self-inserting commands, take effect in the Buffer
of the selected window.
Different windows may display the same Buffer114, and they don’t need to
display the exact same part of the Buffer: one could display the beginning of
the Buffer while another displays the end, and there may or may not be any
overlap. If you can see the same part of the Buffer in two windows, and you
modify the text there, you will see the modifications in both windows. Since
each window has its own Point, you can move and scroll independently in
different windows displaying the same buffer.
Splitting Windows
Since it’s impossible to have a Frame with no windows, there’s no command to
create a window out of thin air. If you want a new window, you have to pick an
existing window; switch to it, if it’s not the selected window; and split it.
We’ve already discussed this in Basic Commands to Manipulate Windows. The
fundamental commands are C-x 2
(split-window-below
) and
C-x 3
(split-window-right
).
Deleting Windows
There are two basic command for deleting windows:
C-x 0
(delete-window
) and
C-x 1
(delete-other-windows
): in other words, you either
delete this, the selected, window, keeping all the rest, or you delete all the
other windows, keeping only this one.
M-x
delete-windows-on
prompts for the name of a buffer and deletes
all the windows that happen to be displaying it.
None of these three commands in any way affect the buffer being displayed: in
particular, they do not kill the buffer.
Switching Windows
To “switch windows” means to change the selected window, without necessarily
changing the number or layout of the windows. Mouse users can switch windows by
just clicking anywhere in another one. For those of us that prefer the
keyboard, the most basic command to change the selected window is
C-x o
(other-window
), which switches to the Other Window;
repeated invocations cycle through all the windows in the current Frame.
Which window is the “other” one? Simple: it’s the next window in a pre-order,
depth-first traversal of the window tree arranged in a cyclic ring! It’s a
little hard to express in a less-nerdy manner, but if your window configuration
were that in Figure 15, and the selected window was the window labeled
S
(for selected), then the Other Window is window 1
, and repeating C-x o
would
cycle through the windows in numeric order, returning to window S
after window
6
.
Figure 15: The Mysterious Other Window
C-x o
is fine when you have only two windows (a very common configuration), and
okay for three, but after that it’s frankly kind of tedious and if you
overshoot, you have to circle all the way around again!115
Optional packages to the rescue! I use the windmove
package, which essentially
gives you four new directional versions of C-x o
: switch to the window to the
right, the left, the one above, and the one below. By default these are on the
shifted arrow keys. So in Figure 15, if you’re at S
and want to
switch to 5
, you can just say
(or take another
route, like
) rather than six C-x o
’s. windmove
is
not so much about minimizing the keystrokes as making them more direct and easy
to think about.
Another package that’s well-liked is Oleh Krehel’s ace-window
, which gives you
one new function, which you would probably bind to C-x o
; when executed, the
windows all display a transient label in their upper-left-hand corners—by
default a digit—and you just type the label of the window to which you want to
switch. That’s three keystrokes to switch to any window, regardless of how many
windows are in your frame. It’s also kind of visually sexy.
You can choose between either of these, or use both, or search the Packages for
many other possible solutions to the problem. Here’s a recommended Init File
snippet that sets up windmove
:
(unless (package-installed-p 'windmove) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'windmove))) ;;switches windows (with-demoted-errors "%s" (windmove-default-keybindings))
If you want ace-window
, replace or supplement the snippet above with this one;
feel free to choose a different keystroke if you want to preserve C-x o
.
(unless (package-installed-p 'ace-window) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'ace-window))) (global-set-key (kbd "C-x o") 'ace-window)
Finally, there are of course innumerable commands that have the side-effect of
switching windows. I’ll just mention here the C-x 4
family of commands that
switch to the Other Window and then do something in it; these commands are great
when you can think just one step ahead, knowing not only that you want to switch
windows but what you intend to do when you get there; see Table 8.
(See KIlling Buffers for C-x 4 0
, which I think is more of a buffer-killing
command.)
Key | Action in Other Window |
---|---|
C-x 4 C-f |
Find a file |
C-x 4 f |
… the same |
C-x 4 r |
… the same, but read-only |
C-x 4 b |
switch to a different Buffer (with completion) |
C-x 4 C-o |
… the same |
C-x 4 d |
open Dired on some directory |
C-x 4 C-j |
Jump to this buffer’s directory in Dired |
C-x 4 m |
compose an email |
C-x 4 . |
find the definition of the identifier at Point |
C-x 4 a |
find ChangeLog file and Add an entry |
Window Configurations
Often, working in Emacs consists of a fugue-like state of rapidly and almost
automatically switching from Buffer to Buffer, with windows coming and going, as
you multitask between, say, authoring, coding, doing email, managing files, and
browsing the web. But sometimes you need an exact configuration of windows and
Buffers to stick around (for example, see Figure 47). In this case,
a popped-up window showing *Help*
or an email can be an irritant if it means you
have to manually restore your Window Configuration.
There are several facilities to cope with this. The oldest is to use a
Register: set up your windows and Buffers exactly as you want them and then
store that configuration in a register with
C-x r w
(window-configuration-to-register
). It will prompt
you for a single-character Register name; pick a (preferably) mnemonic letter.
Now, after the usual vicissitudes of the day—popped-up Calendars, Shells, and
Web Browsers—have messed-up your beautiful layout, just restore it with
C-x r j
(jump-to-register
), which will prompt for the
Register name you’ve used.
To be precise, a Window Configuration records the exact sizes and relative
positions of all the windows in the current Frame, and exactly which Buffer was
displayed in each window, and what portion of the Buffer was visible. (You can
also save and restore all the Window Configurations in all your Frames in one
go; see Frames.)
Using Registers requires a little forethought, but it does guarantee perfect
restoration of your layout. A more on-the-fly if less precise method is to use
Winner Mode. This is a global Minor
Mode that essentially allows you to Undo window configuration changes. So when
your carefully-arranged layout is messed up because you had to send that email,
and needed to get help while doing it, just use
C-c
(winner-undo
) (perhaps repeated a few times)
until you get your configuration back. If you overshoot, you can undo the undo
with C-c
(winner-redo
).
I use Winner Mode all day long and consider it essential. I recommend this Init
File snippet (the bindings I describe are my own more felicitous versions
of the defaults):
(winner-mode 1) ; undo window config changes ;; add more felicitous bindings (define-key winner-mode-map [(control c) (control left)] 'winner-undo) (define-key winner-mode-map [(control c) (control right)] 'winner-redo)
There are of course other third-party Packages that deal with window
configurations; I might mention the Hyperbole package that does that (and also
many other things).
The Tab Bar
Another way to manage Window Configurations is via the very new
Tab Bar. Not to be confused with the Tab
Line, the Tab Bar is a Frame-specific set of different transient Window
Configurations.
Really, I think the Tab Bar is best thought of as a task-based desktop
organizational framework. Many people use distinct window manager “desktops” or
“tabs” to separate their applications this way: you’ve got your email
application and its many windows in one desktop, your game’s windows in
another, your word processor in a third, and maybe your web browser in a fourth.
The Emacs way is to do all (or most) of these activities in Emacs, and the Tab
Bar gives you that same kind of organization. A given “task” is not so much a
precise, unchanging window configuration, but rather the set of windows and
buffers as you were last using them when you were working on that task. The Tab
Bar lets you switch between tasks rather than preserving precise window
configurations.
Before the introduction of the Tab Bar, people would often use a dedicated Frame
for each “task” or “desktop”. The Tab Bar lets you do it in one Frame.
Note the differences between a Tab and a window config in a Register:
- Tabs have long names, while Register names are restricted to single
characters. - The set of available configurations is (by default) visible in a Tab Bar at
the top of the Frame, while the Register config is hidden away. - The configuration of Windows and Buffers in a Tab can be changed as you work,
whereas a Register config can only be created from whole cloth once and then
restored, precisely, many times.
Turn on the Tab Bar with M-x
tab-bar-mode
; this is a global Minor
Mode and so the Tab Bar will be active in all current and future Frames. When
you enable the Mode, a single configuration will be created, named for the
current buffer. You can change the configuration at will: split windows and
change buffers all you like. So far it doesn’t seem any different from not
using tab-bar-mode
.
Suppose you’ve laid out a nice configuration for editing your book, but now you
want to read your email for a while. Since this is a distinct task that will
implicitly use a different set of windows and buffers, you should create a new config
with C-x t 2
(tab-new
) (or use your mouse to click the
right-hand +
sign in the Tab Bar). Now, in this new, second, config (which
you’ll notice has popped up in the Frame’s Tab Bar), you can open your mailer
and read and compose emails. To get back to your book, just click on the
book-tab, or switch configs with one of the tab-switching commands in Table
9: your windows and buffers are restored to the way they were right before
you started reading mail. You can now switch back and forth between tasks, or
add a new task when needed.
Key | Action |
---|---|
C-x t 2 |
create a 2nd (really, a new) tab |
C-x t C-f |
… by Finding a File |
C-x t f |
… (the same) |
C-x t b |
… by switching to a Buffer |
C-x t d |
… by Dired |
C-x t o |
switch to the Other (next) tab |
C-x t RET |
… by name (with completion) |
C-x t 0 |
zero (delete) this tab |
C-x t 1 |
make this tab the only 1 (delete all others) |
C-x t r |
Rename this tab |
C-x t m |
Move this tab to the right |
A Register configuration has one advantage that a Tab Bar config doesn’t have: a
Register config is immutable. You’ll note that while you’re in a given Tab, you
can change the windows, buffers and their visual relationship at will, so once
you’ve laid out a precise configuration in your Tab, you may still want to store
it in a Register so you can get it back, or use Winner Mode to undo config
changes.
If you use desktop-save-mode
to save and restore the state of your Emacs between
sessions, using tab-bar-mode
will result in all your Tabs being restored as
well.
I must admit that before writing this section, I was completely confused about
the Tab Bar and the Tab Line. So what is the difference between them?
- There’s one Tab Bar per Frame, but there’s one Tab Line per Window
- Each tab in the Tab Bar is a (fluid) named window configuration, whereas each
tab in the Tab Line is a Buffer that you’ve displayed in the current Window.
Tweaking Window Sizes
Speaking of window configurations with precise layouts, well, how exactly do you
arrive at those precise window sizes?
Mouse users can just click and drag with mouse button 1 on a Mode Line to resize
a window in the vertical axis (that is, make a window taller or shorter), or on
the window divider line between two side-by-side windows to make a window
narrower or wider. Of course, to make one window taller or wider, Emacs will
have to steal space from a neighboring window (because tiling). And note that when
clicking in a Mode Line, you need to avoid clicking on any of the Mode Line
components that have their own response to mouse clicks—most printed text or
graphics in the Mode Line reacts to mouse clicks. Find a spot (typically
blanks) where the mouse cursor changes to a double-headed arrow before clicking.
For us mouse avoiders, there are key bindings that achieve the same effects; see
Table 10.
Key | Action |
---|---|
C-x ^ |
make selected window one line taller |
C-x } |
make selected window one character wider |
C-x { |
make selected window one character narrower |
C-x - |
shrink this window if its buffer doesn’t need so many lines |
C-x + |
make all windows the same height (balance windows) |
The first three commands in Table 10 can take a positive numeric
argument (N) to operate (N) lines (or characters) at a time, and can take a
negative arg to operate in the opposite direction. But fiddling with window
sizes is tricky and when you want to, say, make a window wider, usually a
precise number of characters doesn’t immediately jump to mind such that you
efficiently utter something like C-u 17 C-x }
. You really want to repeatedly
invoke C-x }
, perhaps with your keyboard’s auto-repeat, until it looks exactly
right. But these two-stroke bindings are infelicitous and can’t be
autorepeated, so I recommend the following felicitous bindings (unassigned in a
stock Emacs) for your Init File:
(global-set-key (kbd "C-{") 'shrink-window-horizontally) (global-set-key (kbd "C-}") 'enlarge-window-horizontally) (global-set-key (kbd "C-^") 'enlarge-window)
The windsize
package defines four mnemonic key bindings on the control-shifted
arrow keys which by default resize by 8 columns or 4 rows per keystroke; I
include these in the Init File:
(require 'windsize) (windsize-default-keybindings) # resize windows on C-S-etc
Finally, C-x -
(shrink-window-if-larger-than-buffer
) is very
handy when you’re working in a buffer that only has a few lines in it, but whose
Window eats up 50% of your screen real estate, and
C-x +
(balance-windows
) divides all the Frame-space evenly
between all the Windows.
Vertical Scrolling
Even though there are often better ways to move, if you just need to move one
character forward, nothing beats C-f
(forward-char
) or
(right-char
). On the other hand, if you know you
need to move somewhere, but don’t really know exactly where, nothing beats
scrolling for an overview of your text.
We’ve already met C-v
, M-v
, and
C-M-v
in an earlier chapter, and you can of course also use the
scroll bars and the mouse wheel.
Remember that moving means “moving Point”, i.e. changing your position in the
buffer. Strictly speaking, scrolling isn’t a way of moving Point: it’s a way of
adjusting the portion of the buffer’s text that’s visible in a window; but this
often has the side-effect of moving Point.
Here we have a 10-line window. Imagine that the buffer is hundreds of lines
larger than the window. The window line numbers are at the left, and the buffer
line numbers are to the right of them.
The word “FOO” is in the middle of buffer line 655, which happens to be shown in
window line 5 at the moment, and Point, indicated by |
, is at the beginning of
“FOO”. (Lines 650 and 661, and many more, are outside the window.)
650 Lorem ipsum dolor sit amet, consectetuer adipiscing elit +---------------------------------------------------------------------+ | 1 | 651 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 2 | 652 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 3 | 653 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 4 | 654 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 5 | 655 | Lorem ipsum dolor sit |FOO, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 6 | 656 | Lorem ipsum dolor sit BAR, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 7 | 657 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 8 | 658 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 9 | 659 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 10 | 660 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit | +---------------------------------------------------------------------+ 661 Lorem ipsum dolor sit amet, consectetuer adipiscing elit
If we scroll up by 4 lines, say with C-u 4 C-v
, the line with FOO will now be
displayed in window line 1; Point remains at the beginning of “FOO”.
654 Lorem ipsum dolor sit amet, consectetuer adipiscing elit +---------------------------------------------------------------------+ | 1 | 655 | Lorem ipsum dolor sit |FOO, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 2 | 656 | Lorem ipsum dolor sit BAR, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 3 | 657 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 4 | 658 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 5 | 659 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 6 | 660 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 7 | 661 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 8 | 662 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 9 | 663 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit "http://www2.lib.uchicago.edu/" 10 | 664 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit | +---------------------------------------------------------------------+ 665 Lorem ipsum dolor sit amet, consectetuer adipiscing elit
This is why Emacs calls C-v
“scroll-up-command
”, rather than “scroll-down”: the
buffer lines have moved up in the window. It’s also true that more buffer lines
are suddenly visible at the bottom of the window (lines 661-664).
So scrolling isn’t really moving: the position of Point has not changed!
However, it is a rule that Point is always visible in the window, so if we were
to scroll up one more line, Point would have to move to remain in the window.
If we scroll by large amounts — bigger than the size of the window, say by a
screen-full at a time — then Point will be moving every time. But the motion of
Point is really just a side-effect.
Conversely, if you move Point off the top or bottom of the window with a true
Point-moving command like C-p
(previous-line
) or
C-n
(next-line
), because Point must remain visible, Emacs
will scroll the window to achieve this! By how much will it scroll? The
default is to scroll Point to the center of the window, which I hate – I think
it makes scrolling jumpy and my eyes lose track of Point.
Different people simply don’t agree about these things, but Emacs being Emacs,
all aspects of scrolling can be fine-tuned with a variety of variables. I use:
(setq scroll-conservatively 100000)
The result of this (just trust me…) is that the window only scrolls by one
line if I move one line off the top or bottom. (If you read the documentation
for that variable, the number will make sense.)
Where in the Window is Point?
Sometimes you want Point to stay where it is in the buffer (in front of some
given word, perhaps), but you want it to be on some other window-line. If Point
is on the bottom line of the window, you might want to center it so that you can
see as many lines before and after it as possible.
You can do that by fiddling with numeric arguments for C-v
and M-v
, but as usual
there are commands to make that easier. C-l
(recenter-top-bottom
) will scroll the window so that Point is in the center
line; immediately repeating C-l
will scroll Point’s line to be at the top of the
window; one more C-l
scrolls it to the bottom; yet one more starts the cycle
over116. I use this command constantly; so much nicer than vaguely yanking
the scroll bar.
Conversely117, you might want to really move Point to a particular,
different, window line, without scrolling the lines at all.
M-r
(move-to-window-line-top-bottom
) does that, and it
cycles through the same positions that C-l
does when you repeat it; first Point
jumps to the line at the center, then the top and finally the bottom: the
visible lines remain the same, in the same positions.
These are easy to understand if you just try them out: pull up some text that’s
significantly bigger than your window ( C-h C-c
(describe-copying
) will probably do), scroll a few screenfulls in with two
or three C-v
’s, and then type several C-l
’s in a row until you get the idea.
Now do the same with a sequence of M-r
’s.
Finally, new to me as I write this paragraph in 2021118 is C-M-l
(reposition-window
), which recenters the window heuristically, trying to
bring useful information into the window, like a complete paragraph or a
complete function definition.
The Display of Lines
While the size of a Buffer is effectively unlimited
(2.3 exabytes), the size of a
Window definitely is not. It depends on the resolution of your display, your
chosen font size, the current size of your Frame, and the sizes of any other
windows in that Frame. Scrolling copes well for buffers with many more lines
than the window has room for, but (in my opinion) is basically awful for lines
longer than the window is wide.
Continuation Lines
By default, horizontal scrolling is completely avoided by virtue of continuation
lines. When the actual length of a line in a buffer—i.e., the number of
characters between the beginning of the line and a newline character—is longer
than the window width, Emacs displays it wrapped on as many window lines as it requires.
So there are two kinds of lines: actual lines (determined by the content of the
buffer), which Emacs calls logical lines, and the screen lines needed to display
the logical line in full. Any extra screen lines needed for this are called
continuation lines.
Continuation lines imply some ambiguity: the additional screen
line-breaks would masquerade as actual newlines in the buffer text. To solve this
problem, the continuation line-breaks are indicated by bent arrows in the right
and left Fringes of the window119; if you have
linum-mode
turned on, you’ll note that the continuation
lines don’t get line numbers; see Figure 16.
All the line-motion commands work in terms of logical lines, so
getting to the last word in a logical line continued into many screen lines (say
from the cursor in Figure 16 to the word “estates”) requires
using horizontal motion commands (or, of course, Incremental Search).
Line Truncation
The occasional continuation line is no hardship, and if you have many, it may
be because your window is only temporarily too skinny and will soon be
wider. But when every line in the buffer is too long to fit (as in Figure
16), it can really be annoying. I use a tiling window manager
and as result, my Emacs frame can often be somewhat narrow, and Emacs itself
tiles its windows, so every C-x 3
(split-window-right
) can
mean more continuation lines. What to do?
My solution is to use line truncation
instead of continuation lines, via this Init File snippet:
(setq-default truncate-lines t) ; good for tiling window managers
With this setting, there are no continuation lines: the line is (visually)
truncated at the right-hand window boundary and the right fringe shows a
right-pointing arrow to indicate that there’s more of the logical line off to
the right. This avoids the disconcerting continuation lines, but at the cost of
horizontal scrolling.
Since I hinted that I hate horizontal scrolling (especially yanking back and
forth on a horizontal scroll bar), this may sound like a
counterintuitive choice, but of course, if you simply move Point into the
off-screen part of a truncated line, Emacs scrolls automatically; remember,
Point is always visible in the Window, so this means anything that moves Point,
like searching, causes automatic horizontal scrolling as needed.
Still, even automatic horizontal scrolling can be annoying, but thanks to Winner
Mode, which lets me use C-x 1
(delete-other-windows
) to get a
wide window and with one keystroke restore my previous window configuration,
truncated-lines
work for me.120 See Figure 17 (and notice
how many more (partial) lines are visible).
You probably don’t want truncated lines as a global default the way I have it,
but you can switch any window back and forth between continuation and truncated
with M-x
toggle-truncate-lines
.
Visual Line Mode
Neither truncated lines nor continuation lines are suitable for actually working
with (i.e., editing or reading) the modern style of single-line paragraphs, or
any other bunch of really long lines. For this purpose, you want
Visual Line Mode.
Visual Line Mode wraps your lines into continuation lines at word boundaries,
exactly the way your phone does it; Emacs inserts no indication of wrapped lines
at the fringes (though linum-mode
still gives it away).
Let’s pretend my copy of War and Peace is formatted with single-line paragraphs.
In Visual Line Mode it would look like Figure 18.
The biggest difference is that in Visual Line Mode, the vertical line motion
commands (like C-n
(next-line
) and
C-p
(previous-line
)) move by screen lines, rather than
logical lines. So this is definitely the natural way to work with single-line
paragraphs.
You can use M-x
visual-line-mode
to switch in and out of this
mode in any window, and if, unlike me, most of your files are structured as
single-line paragraphs, you can make it your default everywhere with this Init
File snippet:
(global-visual-line-mode +1) ; single-line paragraphs rule
The Horizontal Scroll Bar: the Last Resort?
With truncated lines, sometimes you actually do need to scroll horizontally. In
a graphical-mode Emacs, you may have a horizontal scroll bar, which is certainly
one way to do it. If you don’t have a horizontal scroll bar and you want one,
you can turn it on and off in the current window with
M-x
toggle-horizontal-scroll-bar
, or make it a global default with
this Init File snippet:
(horizontal-scroll-bar-mode +1)
You can also scroll horizontally with C-x >
(scroll-right
)
and C-x <
(scroll-left
), which are the keyboard equivalents
of yanking on the horizontal scroll bar. By default each invocation scrolls by
the window’s width (with a slight overlap), but of course they take a numeric
argument; multiple C-u
’s are useful here. Naturally you can also change the
default scroll units.
The defaults are very infelicitous bindings so I recommend adding this to your
Init File and using these instead.
(global-set-key (kbd "C-<") 'scroll-left) (global-set-key (kbd "C->") 'scroll-right)
The Header Line
A Window can optionally display a Header Line at the top which is rather like an
additional Mode Line. Header lines are generally created by certain Major Modes
and the most common use is to display headers for column-oriented data. Try
M-x
list-buffers
to see one in action; like most columnized Header
Lines, you can usually sort the columns by mouse-clicking in the Header. The
Header is really a display of the contents of the Buffer-Local Variable
header-line-format
; it’s in no way part of the window’s
Buffer’s text.
The Fringes
The left and right Fringes are very narrow areas of the window mainly used to
display graphical indicators that are matched to window lines, most commonly
continuation lines and truncated lines (see The Display of Lines), but also
buffer boundaries that eliminate the ambiguity of the presence of blank lines at
the end of a buffer (see
Displaying Boundaries and
“Useless Whitespace” in the Emacs manual); to indicate added and deleted lines in
diff-mode
; and in the special modes for running debuggers
for various programming languages (including, of course, Elisp).
If you’d like a see a Fringe in action, try making a new buffer (C-x b
), make it the only window in the Frame (
newbufferC-x 1
), and type in one line
of text. Note all the blank screen lines after your single logical line. How
do you know those screen lines aren’t actual empty lines in the Buffer
(consisting of many blanks and/or newlines)? Now say:
M-x set-variable RET indicate-empty-lines RET t RET
You should see a change in the left Fringe. Now actually add a few empty lines
at the end of the Buffer by hitting RET
a few times: note how the Fringe makes
clear which lines are really in the Buffer and which are just an artifact of the
display.
Follow Mode
If you have a very wide, high-resolution display, it may seem like you’re
wasting screen real estate when you’re editing a buffer whose lines are
significantly shorter than its window’s width: much of the right-hand side of
the window will just be blank space. The Unix system dictionary
file---/usr/share/dict/words
on my machine—is a particularly skinny example,
since each of its 123,985 lines is a
single word; see Figure 19.
Follow Mode lets you exploit this empty space to show more lines of your Buffer. Just
say M-x
follow-mode
and now split your Window with
C-x 3
(split-window-right
). Normally, after C-x 3
, the new
window initially shows exactly the same text as the old window: the top screen line of
the old window is the top screen line of the new window. But when Follow Mode
is active, the top line of the new window is the line after the bottom line of
the old window: it’s as if the two windows comprise a single virtual window that’s
twice as tall as the original. Another C-x 3
gives you a virtual window that’s
three times as tall. You can have as many splits as make sense, given the
lengths of your logical lines. Figure 20 shows the same file after six
C-x 3
’s; I’ve turned on linum-mode
to show how the screen
lines are related to the Buffer’s logical lines.
Follow Mode isn’t just a trick to initialize the positions of the lines in the
windows! If you move Point off the bottom of one window with some invocations
of C-n
(next-line
), the cursor will appear at the top of the
next window. If you search for a word that’s visible in one of the other
windows, Point (and the cursor) will just jump there without scrolling any of
the windows. And if you do scroll, all the other windows scroll in lock-step to
maintain the tall virtual window effect. You can delete windows and re-split
them at will, and you can have C-x 2
(split-window-below
)
splits with different Buffers in the same Frame; Follow Mode will keep all the
windows that are displaying the same buffer in sync.
There’s a related Minor Mode, next-error-follow-minor-mode
,
which is typically bound to a keystroke in modes like
grep-mode
, occur-mode
,
compilation-mode
, and the like, which makes motion in the
hits Buffer cause automatic scrolling in the associated target Buffer.
Scrolling Many Different Buffers at Once
This style of lock-step scrolling can be useful with different Buffers displayed
in separate windows, too. Suppose you have two Buffers with related data: the
information on line (N) of the first Buffer is related to that on line (N) of
the second Buffer, and so on. You can display these two Buffers side by side,
with their lines lined-up, but if you scroll one of them, now you’re out of
sync. M-x
scroll-all-mode
will synchronize all the windows in the
Frame as you scroll one of them.
The Mode Line in Detail
Every Window has a Mode Line at its lower
edge121. If your Frame only has one Window, its Mode Line is above the Frame’s
Echo Area. The Mode Line displays dynamic information about the Window’s
Buffer—the Buffer name, its Major Mode, and more: some of this info is shown
in a terse and even cryptic form.
The Mode Line is completely customizable, but out of the box it has the
following main components:122
U:@**- *scratch* All L1 Hg:94daf (ELisp ElDoc) CEFBB- BUF POS LINE VC (MAJOR MINOR ...)
- C
- a terse indication of the Buffer’s Coding System or character set
- E
- the Buffer’s end-of-line convention
- F
- an
@
if this is a client frame - B
- the Buffer’s state relative to the file on disk (if it’s visiting a file)
- BUF
- the Buffer’s name (which is typically also the name of the file it’s
visiting, if any) - POS
- the position of the visible Window text vis à vis the Buffer text
- LINE
- the number of the line Point is in
- VC
- the Version Control state (if the Buffer is visiting a file under
Version Control) - MAJOR
- the Buffer’s Major Mode
- MINOR
- (some of) the Buffer’s Minor Modes
C — Coding Systems
There are about 50 single-character values indicating the most common Coding
Systems that can appear in the C column. Here are a few of them; how likely you
are to see any of these depends on where you live, what language you speak, and
the kind of files you edit. The real way to learn a Buffer’s encoding is to
execute M-x
describe-current-coding-system
in the Buffer.
U |
various Unicode UTF encodings |
1 |
ISO Latin-1 |
- |
US ASCII |
= |
raw, unencoded (binary) data |
* |
Windows 1250 |
D |
various DOS code pages |
c |
Chinese GB2312 |
B |
Chinese BIG5 |
J |
Japanese |
K |
Korean |
E — End-of-Line Encodings
This can be a single character if the Buffer’s end-of-line encoding is the
normal one for your operating system, or else a word in parentheses.
: |
(Unix) |
Unix newlines (line-feeds) |
|
(DOS) |
MS-DOS (Windows) CRLFs |
/ |
(Mac) |
Old Macintosh carriage returns |
F — Client Frame Indicator
If there is an @
in this position it indicates that this Frame was created by
the Emacsclient (and so this Emacs is necessarily an Emacs Server); see Client / Server.
B — Buffer State
This indicates the Window’s Buffer’s state versus the file it’s visiting, if any.
-- |
Buffer unmodified |
** |
Buffer modified |
%% |
Buffer read-only and unmodified |
%* |
Buffer read-only and modified |
BUF — Buffer Name
This is simply the Buffer name, which for file-visiting Buffers is usually the
basename of the file, possibly modified for disambiguation.
POS — Visible Text Position
This is a hint of how much of the Buffer is visible in the Window.
Top |
Beginning of Buffer is visible |
Bot |
End of Buffer is visible |
All |
All of Buffer is visible |
NN% |
NN percent of Buffer precedes visible portion |
LINE — Point’s Line Number
Self-explanatory.
VC — Version Control State
If the Buffer’s file is under Version Control (VC), the Mode Line will indicate
the file’s VC state in the form: BE-ID (for example, Hg:94daf
):
- BE
- the (abbreviated) name of the VC back-end
- -
- the status of the file, indicated by a single character
- ID
- the version number (or version identifier) of the file
For the possible values of BE, see the list of version control systems (VCS’s)
in Version Control. ID is whatever your system uses to identify a version
number; for RCS it might look like 1.22
whereas for a distributed VCS like
Mercurial or Git it will probably be a hexadecimal number like 94daf
.
The : can actually be any of the following status indicators:
- |
file is unmodified (or unlocked) |
: |
file is modified (or locked) |
! |
file contains merge conflicts or was removed from VC |
? |
file is in VC but missing from the working directory |
@ |
file was added locally but is not committed |
Note that in an old-fashioned lock-based VCS (like RCS), a username may also be
present---e.g., RCS:jim:1.3
—indicating that user jim
has the file locked.
MAJOR — Major Mode Name
The name of the Buffer’s Major Mode, with the -mode
elided, so e.g. Fundamental
for fundamental-mode
, Org
for org-mode
.
MINOR — Minor Modes
This is a space-separated list of strings, called “indicators” or “lighters”,
identifying enabled Minor Modes. Unlike the Major Mode indicator, these are
optional: a given Minor Mode may choose to use a very abbreviated indicator, or
none at all. So many Minor Modes are typically in use that many of the ones
that are enabled by default—e.g. auto-encryption-mode
,
auto-compression-mode
—use no indicator just to save space
in the Mode Line.
The Mode Line and the Mouse
The Mode Line, being one of the few things in Emacs that’s inaccessible to the
keyboard, has a small number of mouse bindings. They come in two flavors:
- mouse clicks on Mode Line text (or images) (e.g. the Buffer name, a Mode
indicator, the Coding System character (class C above)), and - mouse clicks in any of the blank space between the textual elements; these
clicks allow you to select, resize, or delete windows.
Taking the latter category first, we have the following:
Mouse Button | Mouse Action | Effect |
---|---|---|
mouse-1 |
click | select the Mode Line’s Window |
drag | resize Windows vertically | |
mouse-2 |
click | like C-x 1 in the Mode Line’s Window |
C-mouse-2 |
click | like C-x 3 in the Mode Line’s Window |
mouse-3 |
click | like C-x 0 in the Mode Line’s Window |
As for mouse clicks in the textual or graphical elements, they vary to suit: just hover the
mouse over the element and, in the Echo Area, you’ll see a brief description of
the element and what various clicks will do.
Optional Mode Line Features
There are several optional Mode Line features that you can turn on, and you can
customize the appearance with a variety of formats and Faces. The best way to
do this is via M-x
customize-group
RET mode-line
.
-
size-indication-mode
- displays the total size of the
Buffer after POS, in a form like74% of 712k
. -
column-number-mode
- displays Point’s column number next
to the line number -
display-time-mode
- displays the current time, load
average, and an indicator when you have new mail.123 -
display-battery-mode
- displays the percentage remaining
of your laptop’s battery charge.
There are also at least 56
third-party packages to enhance your Mode Line, including popular theming to
make your Emacs look a little less Emacs-like.
Frames
Figure 22: Emacs Data Structures
Legend:
* | One or more |
1 | Exactly one |
1? | One or none |
When you fire up Emacs, a new “window” pops up: not an Emacs Window, but
an operating system or desktop window. Earlier I mentioned that, since Emacs
had multiple windows two years before Graphical User Interfaces were
commercially available, it needed a new term for this object: a Frame.
A Frame consists of at least one Window, and has a Menu Bar, Tool Bar, Scroll
Bars (vertical and horizontal)124, and an Echo Area, as in Figure 23.
You can create as many additional Frames as you like, and use them as another
way to organize your work, as you can with the Tab Bar for example.
You can of course delete any Frames you create; deleting a Frame does necessarily
delete all the Windows in it, but as usual in no way kills the Buffers in those
Windows. Deleting the last and only Frame is the same thing as exiting Emacs
with C-x C-c
(save-buffers-kill-terminal
);125 as always, Emacs
will ask for confirmation if you have any unsaved Files.
Frame Commands
The main commands for working with Frames are all on the C-x 5
prefix (see Table
11); they’re completely analogous to the C-x 4
family
of Other Window commands: where a C-x 4
command is a shortcut to something in
another Window, the corresponding C-x 5
command does the same thing in a new
Frame.
Key | Type | Action |
---|---|---|
C-x 5 2 |
Create | create a 2nd Frame |
C-x 5 C-f |
Find a file in a new Frame | |
C-x 5 f |
… the same | |
C-x 5 r |
… the same, but read-only | |
C-x 5 b |
switch to a Buffer in a new Frame | |
C-x 5 C-o |
Open a buffer in another frame | |
C-x 5 m |
compose an eMail in another Frame | |
C-x 5 d |
open a Dired in another Frame | |
C-x 5 . |
find the definition of the identifier at Point | |
C-x 5 0 |
Delete | zero-out (delete) the current Frame |
C-x 5 1 |
make the current Frame the 1 and only Frame | |
C-x 5 o |
Switch | switch to the Other Frame |
The fundamental Frame-creation command is
C-x 5 2
(make-frame-command
) (mnemonic: makes a 2nd Frame);
you can also make a new Frame initialized with some file, Buffer, or the like.
C-x 5 0
(delete-frame
) deletes the current Frame; as
mentioned above, if the current Frame is the only Frame, this is equivalent to
exiting Emacs. C-x 5 1
(delete-other-frames
) deletes
all your Frames except for the current one. These two commands are analogous
to C-x 0
(delete-window
) and
C-x 1
(delete-other-windows
).
Finally, C-x 5 o
(other-frame
) is like
C-x o
(other-window
), but it always switches to another
Window in a Frame other than the current one (so it has no effect if you only
have one Frame). If you repeat this command, it cycles through all the Frames
you have open. Note that Emacs has to delegate this action to your window
manager (WM) or operating system (the WM is in charge!), so you may have to
tweak your WM or Emacs itself to make this work the way you want; see
“Frame Commands” in the Emacs manual for details.
Frames and Monitors
Some lucky people have more than one monitor connected to their desktop computer
(especially in an office situation). You can pop up a Frame on a particular
monitor with M-x
make-frame-on-monitor
; you’ll be able to use
Completion on whatever monitor names your operating system has assigned.126
Controlling Graphical Window Elements
Some people find the various GUI elements of Frames to be an annoyance. While I
recommend that you exploit the Menu Bar and Tool Bar while you’re getting
comfortable with Emacs, here’s how to disable any of these elements if and when
you want to (I disable all of these).
Best is to use Customize via M-x
customize-group
RET frames
. If
you’re inclined to disable any of these elements, you may also want to disable
GUI dialog boxes and tool tips (and use Emacs Completion instead)127; use
M-x
customize-group
RET menu
. You can also just add one or more of
these snippets to your Init File:
(menu-bar-mode -1) ;turn off menu bar (tool-bar-mode -1) ;turn off tool bar (scroll-bar-mode -1) ;turn off vertical scroll bar (horizontal-scroll-bar-mode -1) ;turn off horizontal scroll bar (tooltip-mode -1) ; turn off GUI tooltips (setq use-file-dialog nil use-dialog-box nil) ; turn off GUI dialogs
Customizing Frame Appearance
You can extensively customize the appearance of your Frames: things like size,
position on your monitor, fonts, colors, cursors, and much, much more. Many of
these can’t be done via Customize; see “Frame Parameters” in the Emacs manual.
If you use desktop-save-mode
, it will remember any changes to your Frame
parameters, including implicit changes: if you embiggen the font or screen
position of a Frame, the next time you start up Emacs, that Frame will be
restored at its last screen position and font size (assuming your window manager
is okay with this).
Saving Frame Configurations
We discussed how you can save your Window configuration in a Register with
C-x r w
(window-configuration-to-register
) so that you can
restore it with a keystroke. That Window configuration is merely the set of
Windows in your current Frame. But you can also save your entire configuration
of all Frames with all their Windows in one step with
C-x r f
(frameset-to-register
).
Frames in Non-Graphical Mode
Even a non-graphical Emacs supports multiple Frames, but in a very limited
manner: each Frame always uses the full screen of the terminal it’s running in,
so you can only see one at a time, and elaborate Frame parameters aren’t
supported (just because terminals can only do so much compared to what Emacs can
do in graphical mode).
Files
Most of what we think of as “editing files” really consists of editing Buffers,
but there are a number of topics that apply specifically to files and how they
relate to Buffers. For files as the contents of directories, and performing
file maintenance operations like copying, renaming, and the like, see
Directories.
Visiting Files
As already mentioned, the usual way to visit a file (i.e., load it into Emacs
for editing) is C-x C-f
(find-file
), but there are a few
other useful variants. First, we have variants for finding files in specific ways:
-
C-x C-r
(find-file-read-only
) - This is just like
C-x C-f
followed byC-x C-q
(read-only-mode
); you can use this
when you want to make sure you don’t forget and start editing a file you only
want to look at. -
M-x
find-file-existing
- This is just like
C-x C-f
but it won’t
let you create a new file. I’ve never used it; it’s probably most useful if you’re
trying to pull up a file whose name contains wild cards (glob characters),
like*
or?
, because it won’t expand them. It’s a little-known (and by me,
little used) feature of find-file
that if you use wild
cards in the file name, it will load all the matching files into multiple
Buffers.
Let’s talk about neatness. Some people accumulate dozens of file Buffers in
their Emacs (even hundreds, for users of server-mode
), but others like to keep
a lean and mean Emacs by killing Buffers ASAP when they’re done with them.
C-x C-v
(find-alternate-file
) is designed for the ASAPers.
It replaces the file you’re editing with a different file, whereas C-x C-f
adds
an additional file to your Emacs. It’s just like doing C-x k
(kill-buffer
) immediately followed by C-x C-f
, except it
also reuses the window of the killed Buffer, so your window layout doesn’t
change at all. This is also often used when you visit a file and immediately
realize that it wasn’t the file you meant: C-x C-v
let’s you correct the
mistake. Note that this is a brand-new Buffer, so if you’ve made any
Buffer-local changes to the previous file’s Buffer, like say turning on a Minor
Mode, they are lost.
Then we have a family of convenience commands that simply open a file in a
different window. C-x C-f
, C-x C-r
, and
find-file-existing
all open the file in the current window;
these commands save you the effort of splitting windows and rearranging Buffers:
C-x 4 f
(find-file-other-window
)C-x 4 r
(find-file-read-only-other-window
)C-x 5 f
(find-file-other-frame
)C-x 5 r
(find-file-read-only-other-frame
)
Finally, M-x
find-file-literally
visits a file but shows you the
literal contents of the file. This means that the Major Mode will be
fundamental-mode
, regardless of what it would normally be
(so no syntax highlighting); line ending- and character set-conversion will not
be done, and multi-byte characters (as in Unicode) will be shown as individual
bytes. Normally helpful features like automatic handling of compressed,
encrypted, and archive files (see below) will not be done.
When visiting a non-existent file (to create it), you might want to specify a
path that contains one or more non-existent directories. Suppose the directory
~/txt
exists, but contains only plain files—no subdirectories—and you say
C-x C-f ~/txt/emacs/how-to.org
. Emacs will happily open up a new Buffer for
you, but you’ll see this message in the Echo Area:
Use M-x make-directory RET RET to create the directory and its parents
You should take the advice. You don’t have to do it immediately, but as soon as
you start typing in this Buffer, you’ll start getting warning messages as Emacs
repeatedly tries, but fails, to create the Buffer’s checkpoint file in the
non-existent directory:128
Error (auto-save): Auto-saving how-to.org: Opening output file: No such file or directory, ~/txt/emacs/#how-to.org#
You can also use M-x
make-directory
anytime you need a new
directory, just as with mkdir
in the shell; note that make-directory
always acts
like mkdir -p
and makes all necessary intermediate directories for you.
Find File at Point
M-x
find-file-at-point
is extremely useful for when you’re looking
at the name of a file in some Buffer, and want to open that file129. Just
move Point to immediately before, within, or immediately after the file name,
and issue the command (it’ll give you a chance to tweak the name in the
Minibuffer). In addition to filenames, it also handles URLs at Point via the
Browse URL subsystem.
The command M-x
ffap-menu
will offer up for completion all the files
and URLs mentioned in the current Buffer130.
If you really like ffap
, you can invoke ffap-bindings
in your Init
File and it will remap 18 file-visiting
commands (e.g. C-x C-r
or C-x 4 C-f
) to use
ffap
.
Persisting Files Across Sessions
You can arrange for the complete set of files you’re currently editing to be
restored when you exit and then restart Emacs. See The Desktop.
Large Files
When you visit a file, the entire contents of the file is loaded into memory.
Modern computers have so much memory available that this is rarely an issue, but
disk is still bigger than RAM, and you don’t want your Emacs to slow down, much
less be terminated by the operating system, because it uses too much memory.
When you visit a large file, Emacs will ask you to confirm that you really want
to open it:
File Delicate Friction.zip is large (106.1 MiB), really open? (y)es or (n)o or (l)iterally
If you choose “(l)iterally”, the file will be opened with
find-file-literally
. One of the problems with huge files
is that syntax-highlighting may be slow; visiting the file literally will use
fundamental mode and there won’t be any syntax-highlighting to slow you down.
So what defines a “large” file? The variable
large-file-warning-threshold
. It’s default value is a
conservative
10,000,000 bytes; I
recommend setting it to at least 100MB.
(setq large-file-warning-threshold (* 100 1024 1024)) ; 100MB
If you need to edit truly large files that won’t fit in memory (say multiple
gigabytes in size), you can do it with the VLF package. See The Package
Manager for more information.
A related issue is files with extremely long lines, which can cause certain
Major Modes to struggle. Files with such lines are typically computer-generated
and aren’t usually intended to be edited by humans: things like minified
Javascript or byte-code.131 The solution to this problem is
global-so-long-mode
; it automatically switches buffers
visiting files with long lines to so-long-mode
, which
handles them with no problem. I recommend it for your Init File:
(when (version<= "27.1" emacs-version) ; only available recently... (global-so-long-mode +1)) ; speed up long lines
Saving Files
We’ve already mentioned the basic commands for saving files (really, saving
Buffers): C-x C-s
(save-buffer
) and
C-x s
(save-some-buffers
). You can additionally save an
edited Buffer under a different file name with
C-x C-w
(write-file
) (this effect is sticky: if you continue
editing and save again, it will use the new name you chose). If you want to
make a modified version of an existing file, rather than copying it first to a
new name, you can just do C-x C-f
and then immediately do C-x C-w
to save it
under the new name.
You can also tell Emacs to ignore any modifications you’ve made to a Buffer, so
that you don’t accidentally save them to the file with a C-x s
or an impulsive
C-x C-s
. Just use M-~
(not-modified
); after doing it,
you’ll notice that the modification asterisks **
in the Mode Line have changed
back to --
, indicating the unmodified state, and Emacs won’t ask you about
saving this Buffer (until you modify it again).
Read-Only Buffers, or, Emacs is More
Emacs makes an excellent pager—i.e., a replacement for programs like more(1)
and less(1)
. Just do C-x C-r
(find-file-read-only
) (so that
you don’t accidentally modify the file) and now you can view the file and scroll
and search through it.
Even better is to turn on the Minor Mode view-mode
, which
makes the Buffer read-only (if it isn’t already) and let’s you page through it
with SPC
and backwards with DEL
; it also redefines many printing characters to
scroll by half-screenfuls, by lines, set marks and jump back to them, and many
other things handy for browsing.
You can arrange to have view-mode
turned on automatically whenever you make your
Buffer read-only (which also happens if you visit a file that you don’t have
permission to edit). I recommend turning this on in your init file:
Reverting Buffers
We’ve all experienced the regret of making extensive changes to a Buffer, and
then wishing we hadn’t! If you change your mind about all the edits you’ve done
since your last save, you might think you need to enter upon a long, tedious
sequence of Undos until you get back to the unmodified version, or use
C-x k
(kill-buffer
) and then revisit the file132. But
really, all you need to do is ask Emacs to
revert the buffer with
M-x
revert-buffer
or the new command
C-x x g
(revert-buffer-quick
): this means that Emacs will
refresh the Buffer contents from the file on disk (you’ll be asked for
confirmation), and you can then start over with your editing. Remember that if
you made changes and saved them, then reverting can’t undo the changes you
saved; you need Version Control for that. Note that, when you revert, this is
the same exact Buffer, so if you’ve made any Buffer-local changes, they are
preserved.
You naturally can’t revert Buffers that aren’t visiting files. Or can you?
Actually, many dynamic Application Buffers can be reverted! Examples include Buffers
viewing web pages in the Web Browser (reverting reloads the page), Dired Buffers
(reverting updates the Buffer to match the directory on disk), the Buffer Menu, and
many more. You’ll commonly find revert-buffer
bound to g
in Application Buffers.
Auto-Reverting (Watching Files)
Sometimes you want to visit a file that’s regularly changing on disk. In
view-mode
, you can use F
( View-revert-buffer-scroll-page-forward
) to manually revert
the Buffer from disk to see any updates, but you can also put a Buffer into
auto-revert-mode
, and it will watch the file and
automatically revert the Buffer whenever there’s a change.
This is very handy when you’re editing a LaTeX or Org Mode document and
periodically generating a new PDF which you’re viewing in
doc-view-mode
as you work (see PDFs and Image Files).
Log files are notable in that they are only appended to. You can use
auto-revert-mode
here, but a better choice is
auto-revert-tail-mode
, since it doesn’t reload the entire
(possibly huge) file every time: it just loads new lines from the end. (This is
like the shell’s tail -f
command.)
Backup Files
Emacs never modifies your file on disk until you tell it to, but it’s very
careful about saving your work for you in a number of ways.
- Backup files
-
Emacs preserves the previous version of your file when you save.
If your file is namedfoo
, the backup will be calledfoo~
(note the tilde).Backup files are, by default, stored in the same directory as the file being
backed up, but you can arrange for the backups to go in a subdirectory, or in
a completely different location, by Customizing
backup-directory-alist
.Note that, by default, if your file is under version control, Emacs won’t
bother to make any kind of backup files, unless you tell it to (see
vc-make-backup-files
).133
- Numbered Backups
-
You can also have Emacs make numbered backups, so that you
can keep more than just the previous version. The oldest numbered backup file
of the filefoo
would be namedfoo~1~
;foo~2~
would be newer, and the most
recent is the one with the highest number (there’s no limit to the number
kept!). Numbered backups are off by default; you can set them as your
default, but you can also manually rename any one backup file to it’s numeric
form:M-x rename-file RET foo~ RET foo~1~ RET
and from that point on, Emacs will make numbered backups of that file (that
is, until you delete all the backups; then it would start over with simple
backups).I don’t recommend numbered backups; in general using your preferred version
control system is much better practice, and Emacs has excellent VCS support.
Auto-Save Files
Emacs also, by default, auto-saves your file while you’re editing
it134; I think of these as checkpoint files. The auto-save file for a file
foo
is called #foo#
. If Emacs (or the system) were to crash before you could
save your edits, you could recover almost all of them from this file.
Auto-saving happens (by default) every 300 characters you type, or every 30 seconds that
you’ve been idle, or when a system error is encountered, whichever comes first.
You can of course tweak these parameters if you’re either more paranoid or
over-confident.
You can recover lost data by manually fiddling with the file and its contents
from the auto-save file, but the simplest approach is just to visit the file you
were editing and then say:
M-x recover-file
and, after a cautious confirmation dialog, Emacs will replace the contents of
the Buffer with the auto-save file contents. In fact, if you visit a file
which has an auto-save file which is newer than the file itself, Emacs will
offer to do this recovery automatically.
If your entire session crashes (dropped connection to a remote host, laptop
battery runs down) and you’ve been lazy about saving your work, you can fire
up Emacs again and say:
M-x recover-session
and Emacs will walk you through the recover-file
process for each file that
needs it.
If you like to live dangerously, you can turn auto-saving off, but I really
discourage this; there’s no noticeable overhead and the auto-save file is
deleted every time you do an explicit save with C-x C-s
, so they don’t clutter
up your directories. I would also discourage the micro-management of exactly
how auto-saving works which Emacs allows (EIPNIF). But see
“Auto Save” in the Emacs manual for the gory details.
Lock Files
You can’t (normally) edit two copies of the same file in the same Emacs, because
of the way C-x C-f
works.135 But what if you fire up two Emacsen
and edit the same file in both? A recipe for disaster? Well, there’s no need
to worry as the two Emacsen will detect the conflict and notify you (but only if
you try to modify the file when the other Emacs already has it modified). Emacs
will ask:
FILENAME locked by keith@krampus... (pid 290502): (s, q,p,?)?
If you type s
you can “steal” the file from the other Emacs—this is safe; it
just flips the roles of the two participants, and now if the other Emacs user
tries to modify their Buffer, they will be the intruder and be asked the same
question.
You can also type q
to abandon the attempt, or type p
to proceed into danger
with no protection, if you insist.
Lock files are implemented (on Unix systems) as symbolic links and look
something like this example (I mention this only in case you stumble upon one,
and wonder what it is):
.#emacs-tutorial.org -> keith@krampus.1173283:1613350748
Files Modified Behind Emacs’s Back
Sometimes a file in your Emacs will be modified by some other process, behind
Emacs’s back. For example, you might synchronize files across multiple
computers with an application like Syncthing, and thus you might change a file
on your phone or desktop when you also have the file loaded in the Emacs on your
laptop.136 If you start to modify the Buffer (say, by typing in it), when the file
has changed on disk, Emacs will ask:
FILENAME changed on disk; really edit the buffer? (y, n, r or C-h)
If you’re not surprised at this (in the file synchronization case above, you
probably won’t be), you can type r
to revert the Buffer.
If you are surprised, you can type n
and your attempt to edit will be aborted;
now you can investigate the situation. If you’re lucky, you’ll discover that
you do indeed want the changes that were made on disk, and you can say
M-x
revert-buffer
to refresh the contents of the Buffer and get back
to work. (If you type C-h
at the prompt, all these options will be summarized.)
If your Buffer was already modified in Emacs when the disk file got changed137,
then the question will be:
FILENAME has changed since visited or saved. Save anyway? (yes or no)
This is a much more annoying situation. If you proceed with your save, you will
lose the changes on disk, but if you revert, you will lose the changes in your
Buffer! If you don’t care about one of the two, you’re okay: you can revert,
throwing away your Buffer changes, or else save and allow the text currently in
the Buffer to trump the contents on disk. But as Emacs says, “you risk ruining
the work of whoever rewrote the file”.138
If you want the best of both worlds, you’ll need to combine the two versions.
The solution in that case is M-x
ediff-current-file
, which uses the
very powerful Ediff subsystem to let you merge changes in the disk file into
your Buffer, and vice versa; see Diffing and Merging.
The cryptic Table 12 summarizes your options when your
Buffer and your file are at odds. As in the Mode Line, --
indicates unmodified
and **
indicates modified; :-)
means we want the modifications, and :-(
means we
don’t.
Buffer Disk | -- |
** :-( |
** :-) |
---|---|---|---|
-- |
C-x C-w¹ |
M-x revert-buffer |
|
** :-) |
C-x C-s |
C-x C-s² |
M-x ediff-current-file |
** :-( |
M-x revert-buffer |
C-x k³ |
M-x revert-buffer |
Notes:
- We don’t want the disk file content; since the Buffer’s not modified,
C-x C-s
has nothing to save, butC-x C-w
will write the Buffer out: just use the same
filename. - Since the Buffer is modified,
C-x C-s
will write it out, but you’ll have to
confirm that you really mean to clobber the modified disk file. - In this case, you should kill your unwanted modified Buffer, and use Version
Control to recover the version of the file that you want.
Compressed Files
Emacs handles compressed files transparently. If you visit a file that’s been
compressed by any of the common Unix compression tools
(compress, bzip2, gzip, lzip, lzma, xz, and zstd), it will be automatically uncompressed into the Buffer, and when you
save it, the changed Buffer will be recompressed.139
The Major Mode for a compressed file will be chosen in the usual way; the file
extension used to choose the mode will be the one “underneath” the compression
extension (e.g., a file foo.org.bz2
will use bzip2(1)
for the compression, but
the Buffer will be in org-mode
).
This is all actually handled by the Minor Mode
auto-compression-mode
, which is on globally (i.e. in all
Buffers) by default. If you don’t like this behavior, you can toggle the mode
off as usual.
Encrypted Files
Emacs handles encrypted files in the same transparent manner that it handles
compressed files. Unlike compression, there are not that many general-purpose
encryption tools; Emacs only directly supports GNU Privacy Guard (GnuPG)140
— see its manual in Info. The default file
extension is .gpg
; if you visit an encrypted file with that extension, it will
be decrypted into the Buffer, and when you save, it will be encrypted back to the
file on disk.
The Major Mode for an encrypted file Buffer will be chosen in the usual way
based on the underlying file extension, if any, so foo.org.gpg
will come up in
org-mode
.
This is all actually handled by the Minor Mode
auto-encryption-mode
, which is on globally (i.e. in all
Buffers) by default. If you don’t like this behavior, you can toggle the mode
off as usual.
There are some differences compared to compressed files, of course. Emacs turns
off auto-save-mode
for the Buffer of an encrypted file, to avoid exposing your
unencrypted text in a checkpoint file. Additionally, encrypting and decrypting
a file requires you to specify a passphrase or key of some kind, for which
you’ll be prompted.
GnuPG is a complex program and you’ll have to do some studying to really
understand it. The most important concept is the distinction between symmetric
and public key encryption. Public key requires some setup and preparation, but
you can easily do symmetric encryption without any.
See EasyPG Assistant for more information on Emacs GnuPG integration.
Archive Files
You can also directly edit archive files, like tar files; 7z, ar, arc, lzh, lzh-exe, rar, rar-exe, squashfs, squashfs, zip, and zoo
archives; and all types of OpenDocument files (word processing, spreadsheet,
presentation, graphics, and formula files, which are stored as ZIP archives
containing multiple parts). The interface has many similarities to Dired.
When you visit an archive, you are shown what looks like the table of contents
listing of that archive format. Here’s the Buffer contents I see when I visit
the tar archive for one of my Emacs packages via C-x C-f
refer-mode-1.18.0.tar
:
drwxr-xr-x keith/keith 0 refer-mode-1.18.0/ -rw-r--r-- keith/keith 72 refer-mode-1.18.0/refer-mode-pkg.el -rw-r--r-- keith/keith 612 refer-mode-1.18.0/dir -rw-r--r-- keith/keith 50555 refer-mode-1.18.0/refer-mode.el -rw-r--r-- keith/keith 30243 refer-mode-1.18.0/refer-mode.info -rw-r--r-- keith/keith 437 refer-mode-1.18.0/README
Note that the Mode Line will show the size of visible Buffer text, which is what
it always does (see, for example, Narrowing), but this is deceiving. For the
above tar file, the Mode Line says the Buffer contains 384 bytes, but Emacs
really has loaded the entire tar file into memory, and its size is actually
92K. I mention this just because it’s not unusual for archive files to be very
large. If you try to visit a really big archive, you’ll get the large file
warning, to make sure you really want to do it.
Via the Buffer of an archive file, you can edit any of the component files
transparently. Just position Point on the desired file’s line and hit e
, f
, or
RET
141 You’ll now be in a Buffer containing the contents of that file; the
Buffer name in the Mode Line will be something like refer-mode.info (refer-mode-1.18.0.tar)
.
You can edit at will using all the features of Emacs; when you save the Buffer,
the edited contents will replace that file in the archive---but only in the
archive Buffer: the archive file on disk won’t be modified until you save the
archive Buffer itself. So fully saving a file from an archive is a two step
process: save the file, then save the archive containing it. When you save the
Buffer of the component file, you’ll see a message like this one in the Echo
Area:
Saved into tar-buffer ‘refer-mode-1.18.0.tar’. Be sure to save that buffer!
In addition to editing the archive contents, you can manipulate the archive
itself. You can delete, rename, or change the owner, group, or mode of any of
the component files. You can copy a file out of the archive to the disk, and
you can add a new file to the archive (you’ll get a new empty Buffer to which you
can add content). In the archive Buffer, just do the usual C-h m
(describe-mode
) or hit ?
for help; see “File Archives” in the Emacs manual.
Many archive formats implement their own compression scheme, but tar archives
don’t; they are usually compressed by any of the standard Unix compression
programs (like gzip(1)
or bzip(1)
); tar-mode
works on compressed tar archives,
too.
Most of the other archive formats support the same kinds of operations, with the
same key bindings, but there are a few lacunae (in particular, not all the other
archive formats support changing owner, group, or mode—probably because these
are Unix concepts and the other archive formats were developed on MS Windows).
Emacs’s support for tar files is fully implemented in Elisp, so you don’t need
to have a tar(1)
program installed, but the other archive formats require the
appropriate program to be installed as a helper.
Document Files (PDFs and the Like)
Emacs can display various types of formatted documents, in particular,
PDFs142, OpenDocument (and older Microsoft Office) files, EPUB e-books,
PostScript, and DVI files. (Since most of these documents aren’t plain text, Emacs
needs to be running in graphical mode to display them; otherwise it will
necessarily fall back to a degraded view.)
All of these file types require some supporting non-Emacs software to be
installed via your operating system’s package manager, and EPUB files also
require a 3rd-party Emacs package; see Table 13.
All of these document types (except EPUB) are handled by
doc-view-mode
,
which provides scrolling and paging commands (somewhat similar to
view-mode
); see Table 14.
Key | Action |
---|---|
RET , C-n ,
|
Scroll one line forward (or next page) |
C-p ,
|
Scroll one line backward (or previous page) |
SPC |
Scroll one window forward (or next page) |
DEL , S-SPC |
Scroll one window backward (or previous page) |
n ,
|
Go to next page |
p ,
|
Go to previous page |
< |
Go to top of page |
> |
Go to bottom of page |
M-< |
Go to beginning of document |
M-> |
Go to end of document |
There are six commands to change the size of the page text:
P |
assure full page is visible in window |
H |
assure full height is visible in window |
W |
assure full width is visible in window |
+ |
enlarge the page text |
- |
shrink the page text |
0 |
reset the page text size |
If the document you’re viewing is one that you’re also authoring (say in LaTeX,
org-mode
, or some other markup language), you can update it
after you’ve made changes by reverting the Buffer with the g
( revert-buffer
) command (or equivalently, r
). But I recommend
using M-x
auto-revert-mode
(see Reverting Buffers); you can add this
snippet to your init file to make it your default for doc-view-mode
:
(add-hook 'doc-view-mode-hook 'auto-revert-mode)
Toggling the Display Mode
All these document formats have an underlying encoding. PostScript and PDF
files really have a plain-text encoding; DVIs have a binary encoding, and EPUBs
and OpenDocument files are Zip archives that contain several files in a variety
of formats. The point being, you might want to view the underlying encoding,
the raw data, rather than view the document. The command
C-c C-c
(doc-view-toggle-display
) will toggle back and forth
between the two views.145
Just the Text, Please
Viewing “documents” may sometimes be necessary, and even superficially
attractive, but it clashes with the very nature of Emacs as a plain-text engine.
These documents are basically images, and the more you have to deal with them,
the more you’ll miss the ability to use keyboard macros, powerful searching,
textual objects, and all the rest of the synergistic power that Emacs provides.
This can be mitigated somewhat with C-c C-t
(doc-view-open-text
),
which toggles the Buffer to a plain-text version of the document, where you can
use all your powers. C-c C-c
(doc-view-toggle-display
) will
toggle back to the graphical view.
Searching
Searching in doc-view-mode
is awkward compared to searching in plain text
Buffers because it can’t highlight the matched hits the way
isearch-forward
does146.
C-s
(doc-view-search
) does a regular expression search
forward, but since it can’t highlight the hits, it simply reports the number of
hits in the Minibuffer with a message like “DocView: search yielded 5 matches.”
Now hit C-s
again to jump to the page with the first hit. Subsequent C-s
’s
advance to further pages with hits. To initiate a brand new search (with a
prompt for a new regexp), use C-u C-s
. The same procedure works backwards with
C-r
(doc-view-search-backward
).
This is obviously a little sad, as it can be tricky to spot matches in a page.
One solution for arbitrary document formats is to switch to text mode with
C-c C-t
and do your search there. I find this pretty satisfactory, really.
Additionally, after you’ve initiated a search and moved to a given page of hits,
you can pop up a GUI tooltip window that lists all the hits on the page with
some context by hitting C-t
(doc-view-show-tooltip
).
But for PDFs, PDF Tools implements incremental search in a completely normal
manner, with highlighting of the hits in the graphical view. Highly
recommended.
Slicing
Since graphical documents are fundamentally designed with print in mind, they
often have a large amount of whitespace around their edges, sometimes excessive
amounts (I’m looking at you, default LaTeX format…). A more compact
view with minimal borders can be achieved with the slicing commands. Easiest to
use is s b
doc-view-set-slice-from-bounding-box
which does
the slice automatically; you can also manually set the slice with the mouse
after executing s m
doc-view-set-slice-using-mouse
. To
restore the whitespace, invoke s r
doc-view-reset-slice
.
Better PDF Handling with PDF Tools
If you install the 3rd-party package pdf-tools
, you will have a much-enhanced
version of doc-view-mode
for PDFs (only). It requires you to install the
external package poppler
from your OS package manager.
Some of its advantages are that pages are rendered into memory on the fly147; it
has a true incremental search with highlighted hits in the graphical view and
even has M-x occur
; you can follow links; make and view annotations;
manipulate attachments; and display a document outline (table of contents).
C-c C-c
will toggle between pdf-view-mode
and doc-view-mode
; there are a few
things PDF Tools can’t do that doc-view-mode
can.
I recommend auto-revert-mode
for pdf-view-mode
also:
(add-hook 'pdf-view-mode-hook 'auto-revert-mode)
Image Files
You can view image files (Emacs knows dozens of formats) as well as document
files. Just visit an image file and it will be displayed (only in a graphical
mode Emacs, of course). There are two non-graphical displays:
C-c C-c
(image-toggle-display
) toggles between graphical and
the raw underlying bytes (you’ll be in fundamental-mode
),
while C-c C-x
(image-toggle-hex-display
) will switch to a
hex-dump display of the raw data (see Binary Data Files).
Browsing Images
You can visit the next image file in the same directory with
n
( image-next-file
);
p
( image-previous-file
) goes the other way.
w
( image-mode-copy-file-name-as-kill
) will copy the absolute
pathname of the file to the Kill Ring.
You can also mark images with m
( image-mode-mark-file
) so
that you can define a collection of files for later manipulation. This works by
setting marks in a Dired Buffer; when you’re done, you can switch to the Dired
Buffer and do, well, anything: change permissions, tar or zip up the files into
an archive, copy or mass rename the files, or use Tramp to upload the files to
another machine. Dired also has a mode for viewing thumbnails of image files.
Resizing Images and Animations
When you visit a file it will be resized to fit the window. If you resize the
window, by default the image will be resized with it. There are several
commands for explicitly scaling the image; if you do this, the automatic
resizing when the window size changes will be disabled until you reset the image
with s 0
; see Table 15.
Keys | Action |
---|---|
s h |
Show full Height in window |
s w |
Show full Width in window |
s b |
Show Both full height and width in window |
s o |
Show image unscaled at Original size |
s 0 |
reset image scaling to auto |
RET |
start or stop animating the current image |
If you set the image to its original, unscaled, size, you can scroll it in the
window with most of the usual view-mode
motion and
scrolling commands; see Table 16.
Key | Action |
---|---|
SPC | scroll image up |
DEL, S-SPC | scroll image down |
C-b, |
scroll image left |
C-f, |
scroll image right |
Binary Data Files
We’ve just seen that, while Emacs is primarily a plain-text engine, it has
helpful modes for displaying graphical data files like images and formatted
documents. Most graphical data files are actually binary data148, i.e., a
sequence of arbitrary bytes not intended to be interpreted as characters —
letters, digits, punctuation — in any character set149. There are many
other types of binary data files, including compiled executable programs,
database files, audio files, and so on. You may never need to view this raw
data (unless you’re a programmer or system administrator), but if you do, Emacs
is ready.
If you visit a binary data file for which Emacs doesn’t have a special Major
Mode defined, it will come up in fundamental-mode
, and you’ll be looking at
the raw bytes. Here’s what the beginning of an MP3 file from my collection
looks like:
(See What Is Text? for an explanation of the cyan characters.)
You can see, for example, that the MP3 format allows for text in the audio file
(these are ID3 tags for metadata). Emacs supports a friendlier or at least more
traditional format for displaying binary data, called a hex dump, via
M-x
hexl-mode
—Figure 25 shows the beginning of the
same file in hexl-mode
:
(If you know you’re visiting a binary file you can skip the mode-change via the
shortcut M-x
hexl-find-file
.) As with many alternative-display
modes, you can switch back to the previous Major Mode with C-c C-c
.
All the usual motion commands work appropriately in hexl-mode
, and you can
modify the Buffer by typing self-inserting characters (hexl-mode
also has a
number of other ways to insert bytes — but either way, make sure you know what
you’re doing).
Note that because many binary data formats contain fixed-length sections and
have alignment restrictions150, hexl-mode
puts the Buffer in
overwrite-mode
(you can change that if you know what you’re
doing). If you’re going to edit binary data in fundamental-mode
, you probably
want to turn on binary-overwrite-mode
for the same reason.
Editing binary files is only for Real Programmers and not the faint of heart,
but if you have to do it, it actually works in Emacs: which is to say, it won’t
work in many other editors, which may corrupt the file when you save it (say by
deleting or adding white space or helpfully converting assumed-character sets).
What you see in the Buffer in fundamental-mode
or hexl-mode
in Emacs is exactly
what will get written to disk.
Directory Editing with Dired
Emacs is thought by the uninitiated to be a (mere) text editor, so of course it
can edit files. But it can also edit directories (“folders” to some). What
does it mean to “edit” a directory? It means to do the sorts of things that are
normally done with Unix shell commands (like cp(1)
, rm(1)
, or chmod(1)
) or a
file manager, like Windows Explorer (File Explorer), Apple’s macOS Finder,
or the venerable Norton Commander and its Unix clone, Midnight Commander.
Emacs handles directories via a special Major Mode,
dired-mode
(Dired for short). Dired was one the first file
managers, having existed in ITS TECO Emacs since at least 1978. Dired is to
files what Buffer Menu is to buffers.
To invoke Dired, just visit a directory, rather than a file, with
C-x C-f
(find-file
) or any other file-visiting command.
(Make sure your completion system doesn’t instead helpfully choose a filename
within that directory.) You can also invoke Dired directly with
C-x d
(dired
). The result will be a buffer that looks like
the output of the Unix ls(1)
command with its -l
option151. Here’s the
source code directory of one of my Emacs packages:
This is not the same as the result of M-!
(shell-command
) ls
which would look superficially similar; nor is it the same
-l ~/src/refer-mode
as M-x
list-directory
. For one thing Dired has colorized some of
the filenames, but most importantly, rather than being in
fundamental-mode
, the Dired buffer is in
dired-mode
.
In dired-mode
you can of course move around in and search the buffer with all
the usual commands you already know, but the buffer is read-only so you can’t
modify it152, and many printing characters are bound to useful commands for
manipulating the files. For example, if you move Point to any of the lines
representing a file, then hitting RET
invokes
dired-find-file
and visits that file in a new buffer.
Dired is even more useful with the many enhancements from the
Dired Extra package. I recommend adding
this to your Init File:
(add-hook 'dired-load-hook (lambda () (require 'dired-x)))
and this chapter will assume you have done so.
Basic File Operations
Key | Unix | Action |
---|---|---|
RET , e , f |
cat |
visit (Edit, Find) this line’s file |
a |
… and clobber Dired buffer | |
o |
… in other window | |
v |
more , less |
… in view-mode |
^ |
ls .. |
open Dired on the parent of this directory |
F |
visit all marked files | |
C |
cp |
Copy file |
c |
tar -cZ |
Compress files into a tar archive |
D |
rm |
Delete file |
G |
chgrp |
change Group |
H |
ln |
make Hardlink to this file |
i |
insert this subdirectory into Dired | |
M |
chmod |
change Mode (permissions) |
O |
chown |
change Ownership |
P |
lpr |
Print file |
R |
mv |
Rename file |
S |
ln -s |
make absolute Symlink to this file |
T |
touch |
update file’s Timestamp |
Y |
ln -s |
make relative symlink to this file |
w |
copy this file’s basename to the kill ring | |
0 w |
… absolute pathname | |
C-u w |
… relative filename | |
W |
firefox |
view this presumably HTML file in your Web browser |
Z |
gzip , tar |
(un)compress and/or (un)tar this file |
= |
diff |
compare this file to another |
+ |
mkdir -p |
create a new subdirectory |
! , X , & |
run shell command on file (see below) | |
? |
1-line help or describe errors | |
B |
Byte-compile elisp files | |
L |
Load elisp files into Emacs | |
: d |
Decrypt file | |
: e |
Encrypt file | |
: s |
Sign file | |
: v |
Verify signature |
Table 17 lists some of the basic Dired file operations; the Unix column
gives roughly analogous shell commands. All the commands operate on the file
named on the current line — you don’t have to have Point precisely on the
filename part of the line. Some of the commands operate immediately (e.g., the
file visiting commands), but most will either ask for confirmation or for
additional information. C
will ask for the name of the new, copied, file; M
will ask for the new file mode; D
will ask if you’re sure you want to delete the
file, and so on.
Most of these commands can be applied to multiple files; see below.
Subdirectories
Inevitably some of the files in your Dired buffer will be directories
themselves (initially at least, every Dired buffer will contain the standard
Unix .
and ..
directories). There are two ways to work with the contents of a
subdirectory:
- open it in its own Dired buffer (just use any of the Dired file visiting
commands such asRET
,e
f
,o
, ora
), or - insert (expand) its contents into the current Dired buffer with
i
(dired-maybe-insert-subdir
).
Both approaches have merit. I usually prefer inserting unless I want to start
working in two-panel mode with Dired DWIM.
When you insert a subdir, it looks much like it does when you run ls -lR
.
Here I’ve issued the i
command from the makefiles
line:
-rw-r--r-- 1 keith keith 231 Oct 16 2008 Makefile drwxr-xr-x 2 keith keith 4.0K Jun 29 13:29 makefiles -rw-r--r-- 1 keith keith 437 Feb 7 17:34 README.ascii /home/keith/src/refer-mode/makefiles: total used in directory 28K available 93.5 GiB drwxr-xr-x 2 keith keith 4.0K Jun 29 13:29 . drwxr-xr-x 4 keith keith 4.0K Jun 30 13:07 .. -rw-r--r-- 1 keith keith 290 Jan 19 17:15 Makefile.gnumake -rw-r--r-- 1 keith keith 1.2K Jan 19 17:18 Makefile.help -rw-r--r-- 1 keith keith 1.2K Feb 7 17:35 Makefile.org
(If you type i
on a non-directory, it’s an error; if you type it on a directory
that’s already inserted, Point will jump to the first file in that
subdirectory.)
The subdirectory header lines — e.g. /home/keith/src/refer-mode/makefiles:
in
the above — support some special actions. Typing l
( dired-do-redisplay
) on one of these lines updates the
contents, so that a file newly created (by some other program) in the
subdirectory will appear, deleted files disappear, and any changes to file
sizes, permissions, etc, will also be updated. $
( dired-hide-subdir
) will toggle the visibility of the
contents of the subdir, leaving the header line.
<
and >
move Point from directory file to directory file in the buffer, and the
usual list-motion key bindings (C-M-n
, C-M-p
, C-M-u
, C-M-d
) move in terms of
inserted directory header lines.
When any subdirectories are inserted, all the files visible in them can be
manipulated along with all the files in the directory proper; this includes all
the file marking commands discussed below.
Compressing and Archiving Files
Z
( dired-do-compress
) is somewhat special. If applied to a
single regular file, or several marked files, it compresses or uncompresses
them, based on the file extension153.
If applied to a directory (a subdirectory of the Dired buffer, which includes
the .
and ..
entries), Z
creates a compressed tar archive of all the files in
that directory154. If applied to an archive file, the Z
command will
extract its contents. Dired knows some
17
compression and archive types.
Dired is the easiest way I know to create a tar archive containing a precise and
arbitrary set of files. It’s easy to tar up a directory of files from the shell
with tar cvzf archive.tar.gz some-directory
. But what if you only want a subset
of the files in some-directory
? Maybe just the .mp3
files but not the .jpg
and
.pdf
files, but including the README.txt
? You can carefully list all the files
to be included on the command line: pretty tedious! Or use tar’s --exclude
option,
but that’s going to be even more tedious if there are lots of files to exclude.
With Dired, it’s easy. Just use the powerful file marking commands to select
exactly the files you want, and then invoke
c
(dired-do-compress-to
), and the tar file will contain
exactly the files you marked.
Deleting Files by Flagging
In addition to D
( dired-do-delete
), which deletes the
current file, you can take a more
thoughtful approach to cleaning up a directory by flagging a set of files for
deletion, and then, after suitable contemplation, delete them all. The command
d
( dired-flag-file-deletion
), rather than deleting a file,
sets the D
flag in the Dired buffer; here I’ve typed d
on all the squiggle-file
lines:
D -rw-r--r-- 1 keith keith 436 Jan 19 16:49 README.org~ -rw-r--r-- 1 keith keith 50K May 1 15:47 refer-mode.el D -rw-r--r-- 1 keith keith 1.2K Dec 22 2017 refer-mode.el~ -rw-r--r-- 1 keith keith 21K Jun 28 15:30 refer-mode.org D -rw-r--r-- 1 keith keith 1.6K Sep 7 2020 refer-mode.org~
If you change your mind about any of them, you can undo the flag with
u
( dired-unmark
). When you’re ready, you can actually
execute all the deletions with x
( dired-do-flagged-delete
).
The confirmation prompt will clearly list all the files about to be deleted to
help avoid tragic mistakes.155
For more convenience in cleanup, the command
% &
(dired-flag-garbage-files
) will add D
flags to all the
files that look like “garbage”156 and
% d
(dired-flag-files-regexp
) will flag all files whose names
match a regular expression.
The flagging commands---d
and its friends—are actually a special case of the general Dired
concept of marking.
Marking Files
When manipulating files in the shell, you can use wildcards (glob characters)
to handle multiple files at once. Dired itself doesn’t support wildcards, but
it has a few (superior) tricks up its sleeve.
Most of the basic commands in Table 17 take a numeric argument; given
an argument of (N), the command will be applied to the next (N) files. So C-u 2
will delete the file on the current line and the file on the line after it.
D
dired-mode
is descended from special-mode
and like most
Special Modes, you can use the digits alone as numeric arguments, so just plain
2 D
is equivalent.
However, this is really only ever used for a very small number of files, like
two or three, because having to count is both annoying and error-prone. On top
of that, the files you want to operate on might not be contiguous! The
solution is to mark the set of files of interest.
We saw above how the d
command flags files for deletion, but Dired also has a
general purpose mark, spelled *
. You can apply this mark to any file or
directory (and advance Point to the next file) with m
( dired-mark
);
u
( dired-unmark
) will remove the mark on the current line
and advance (DEL
unmarks and moves in reverse), and U
( dired-unmark-all-marks
) will remove all the marks in the
Dired buffer. m
itself takes a numeric argument; or, if the Region is
activated, will mark all the files within it. Finally, if you hit m
on an
expanded subdirectory header line, it will mark all the files within that
directory (if you hit m
on a directory proper, it only marks that directory
filename). Here I’ve marked two README
files; in addition to the *
mark, the
filenames are colored a bold orange:
drwxr-xr-x 2 keith keith 4.0K Jun 29 13:29 makefiles * -rw-r--r-- 1 keith keith 437 Feb 7 17:34 README.ascii * -rw-r--r-- 1 keith keith 455 Jan 19 19:26 README.org -rw-r--r-- 1 keith keith 436 Jan 19 16:49 README.org~
Sometimes it would be easier to mark the files you’re not interested in, rather
than those you are. Just mark the uninteresting files and hit t
( dired-toggle-marks
), and the marks will all flip. The
easiest way to mark all the files in the Dired buffer is to hit t
when no files
are marked (you can always achieve that state with U
, or can memorize the
sequence U t
as “mark all files”).
You can move from marked file to marked file with
M-}
( dired-next-marked-file
)
and M-{
( dired-prev-marked-file
).
When there are *
marks in the buffer, most of the basic Dired commands will
operate on all the marked files, instead of on the current line.157 So to
copy 10 files to a different directory, just mark the files and say C
. Some
commands have to make specific interpretations in the presence of marks,
or may ignore them if they just don’t make sense.
Some Dired commands will add their own special marks to files. The C
command
adds a C
mark to the new file that just got created by the copy; the H
command
will likewise add an H
mark and the S
and Y
commands an S
mark to the new files
they create158. Here’s part of my Dired buffer after I’ve copied (with the
C
command) the upload.el
file to the name Y
, hard-linked it to X
with the H
command, and relatively-symlinked it to Z
(with the Y
command). That’s three
new files that weren’t in the directory (and hence weren’t in the Dired buffer)
previously.
-rw-r--r-- 1 keith keith 3.6K Jun 26 13:44 TODO H -rw-r--r-- 2 keith keith 251 Jan 19 16:40 X S lrwxrwxrwx 1 keith keith 9 Jun 28 15:02 Z -> upload.el C -rw-r--r-- 1 keith keith 251 Jan 19 16:40 Y -rw-r--r-- 2 keith keith 251 Jan 19 16:40 upload.el
These marks serve as an indicator that the operations were done and these files
won’t be affected by any commands operating on the standard *
or D
marks that
may be in the buffer. But they aren’t just cosmetic.
Suppose you make copies of 10 files. All the copies will be marked
with the C
mark. Now perhaps you want to change the file permissions of the
copied files to read-only. Just change the C
marks to *
marks with
* c
( dired-change-marks
) and now
M
( dired-do-chmod
) will change the modes of the 10 copied
files.
The Mark Keymap
Manually marking files with m
may not seem like any competition for shell glob
patterns, so Dired has a whole slew of commands to make marking multiple files
easier; they can be found on the *
-prefix key in dired-mode
; see Table
18.
Key | Action |
---|---|
* * |
mark all executable files |
* / |
mark all directories |
* @ |
mark all files that are symlinks |
* . |
mark all files with a given file extension |
* % |
mark all files matching a regexp |
* s |
mark all files in the current Subdirectory |
* O |
mark all Omitted files |
* c |
Change all given marks to some other mark |
* N |
display Number of marked files |
If you’re familiar with the ls(1)
command’s -F
(--classify
) option, the
mnemonics for * *
, * /
and * @
will be obvious. * %
’s mnemonic is that Dired has
a %
prefix full of regexp operations.
Issue any of these marking commands and the matching files will be marked with
*
’s. You can combine several of them, and also mix in t
, m
and u
commands until
you’ve got exactly the combination of files you want.
All of these marking commands will instead unmark if given a prefix argument via
C-u
(universal-argument
).
Why is there no command to mark plain files, i.e., non-directory files? That
seems like an oversight! The reason is that you can achieve that effect in
several ways: you can mark all the files with U t
and then say C-u * /
to unmark the
directories, or you can unmark all with U
, mark the directories with * /
, and
then toggle the marks with t
.
* N
( dired-number-of-marked-files
) is a little out of place
in the *
Keymap, in that it doesn’t mark any files, but it’s a handy command
that will display in the Echo Area the number of marked files and their total
size.
Mass Name Changes by Regular Expression
A classic file management problem that was left unsolved by the founding fathers
of Unix (Ken, Dennis, Brian, et al.) is operating on many files while changing
their names according to some pattern: for example, copying a bunch of files but
adding a .bak
extension, renaming files to their lowercase equivalents, and the
like. People used to resort to verbose and error-prone shell for-loops or scripts involving sed(1)
or
perl(1)
, and a number of special-purpose utilities have appeared over the years
to address this need (such as rename(1)
, mmv(1)
, zsh(1)
’s zmv
), but how to do it
is still a popular query in the search engines.
Dired provides a suite of commands to handle this, on the %
prefix (mnemonic:
kind of like C-M-%
(query-replace-regexp
)); see Table 19.
Key | Action |
---|---|
% R , % r |
Rename files with new names |
% l |
rename files to Lowercase equivalents |
% u |
rename files to Uppercase equivalents |
% C |
Copy files with new names |
% H |
Hardlink files with new names |
% S |
Symlink files with new names |
% Y |
symlink files relatively with new names |
% m |
Mark files that Match regexp |
% g |
mark files containing regexp matches |
Note that for all these commands, we are using Emacs regular expressions, not
shell wildcard (glob) patterns!
The exemplar for all these commands is % R
( dired-do-rename-regexp
). Suppose we want to rename the
two files README.ascii
and README.org
to about.ascii
and about.org
— in other
words, we want to change the README
part of each filename to about
, preserving
any other parts of the filenames (such as, the extensions).
First, we have to mark the two README
files, and then invoke % R
.159 The
prompts go as follows:
Rename from (regexp): README Rename README to: about
and now we start renaming:
Rename ‘README.ascii’ to ‘about.ascii’? [Type yn!q or C-h]
This prompt is similar in spirit to the way query-replace-regexp
works:
y or SPC |
to perform this renaming |
n or DEL |
to skip to the next renaming |
! |
to perform this and all renamings with no questions |
q |
skip this renaming and quit |
C-h |
explain these options |
If we don’t choose !
or q
, then we’ll be asked the same question about each of
the remaining files:
Rename ‘README.org’ to ‘about.org’? [Type yn!q or C-h]
You need to be familiar with regular expressions to do fancier stuff160;
for example, we can add a .bak
extension to a set of files by specifying $
as
the from regexp and .bak
as the replacement (because $
is the regexp that
matches the end of any filename).
Note that the regexp is only applied to the basename of the file —
e.g. README.org
not /home/keith/src/refer-mode/README.org
. If you give any of
these commands a 0
numeric argument, then the regexp is applied to the absolute
pathname, and you can then modify the directory structure as well.
% l
and % u
are convenient ways to do a simple case transformation on the entire
basename of the file (including the extension if any).
The % C
, % H
, % S
, and % Y
commands work like % R
, mutatis mutandis.
Finally, we have two commands that merely mark files (with no action) based on
regular expressions. They consider all the files in the buffer and mark the
ones that match. % m
(also available as * %
) just does the match based on the
file basename, so % m x
would mark all files whose names contain the letter x
.
% g
is just like % m
except that it applies the regexp to the complete contents
of the files, rather than to their names. It marks all the files that contain a
match for the regexp. Think of it as the Grep of marking commands.
If you give either of these last two commands a prefix argument, they unmark,
instead of marking.
What Went Wrong?
We’ve learned a number of useful file manipulation commands, but we have to
face the fact that sometimes, some of them are going to fail. Errors in Emacs
are usually simple: you hear a beep and there’s a message in the Echo Area
telling you what went wrong. But if you’re having Dired act on several, even
hundreds, of files in one stroke, you neither want to miss an error, nor be swamped
by too many.
Suppose we try to copy a bunch of files to a different directory, but it turns
out we don’t have permission. Dired will display a message like this:
Copy: 17 of 17 files failed--type ? for details ((refer-mode.org README.org ...))
and we can use ?
to pop up the *Dired log*
buffer for a complete record of which
operations failed (and why); in this case we’d see lines like:
Thu Jul 1 11:58:13 2021 Buffer ‘refer-mode’ Copy: ‘/home/keith/src/refer-mode/GNUmakefile’ to ‘/etc/GNUmakefile’ failed: (file-error Opening output file Permission denied /etc/GNUmakefile)
Writable Dired
Dired buffers are read-only buffers, so that you can’t accidentally corrupt the
contents and confuse Dired. What if you edited the name of one of the files and
then tried to operate on it? You’d get errors.
On the other hand, what if, when you edited the name of a file, it magically
renamed the file to the new name? That would be an easy and natural way to
rename files. More importantly, it would allow you to rename files using all
your Emacs skills: use M-l
(downcase-word
) to change part of
a filename to lowercase; use M-%
(query-replace
),
C-M-%
(query-replace-regexp
), or Rectangle commands to
mass-rename a set of files without needing to mark them: even use a Keyboard
Macro!
This is exactly what Wdired allows. You simply switch the Dired buffer from the
default read-only mode with the natural keystroke
C-x C-q
(dired-toggle-read-only
) which you’ll recall normally
toggles read-only-mode
on and off. The mode indicator in the Modeline will
change to Editable Dired
, and now you can change filenames via whatever means
you like. You can even change a file name like foo.org
to /tmp/foo.org
to move
it to a different directory; you can use relative or absolute paths for this,
and Dired will create new subdirectories as needed!
The changes don’t happen instantly, so you can take your time; edit one
filename, think about things, and edit another. Maybe then change one of them
back (with Undo if you like!). When you’re done with your changes, you commit
them with C-c C-c
and then all your renames happen at once161; the buffer is
then restored to the normal read-only dired-mode
. If you experience Renamer’s
Remorse, you can instead cancel all your changes with C-c ESC
.162
But there’s more. If you have a symlink, you can edit either the symlink name,
its target, or both. If you kill or delete a filename completely, the file
will be deleted.163 And if you edit the permission string of a file, it
will be chmod
’ed (so you could remove the write permissions on a file by editing
-rw-r--r--
into -r--r--r--
).164 Any of these changes only take effect when
you commit.
This trick of editing a read-only buffer to effect real, but indirect, changes
is used elsewhere in Emacs.
Two-Panel Dired
Many file managers use a two-panel design: they divide a window into two
(usually side-by-side), to make it easy to copy or move files from one directory
to another. It’s useful to run Dired this way as well. I recommend adding this
to your Init File:
(setq dired-dwim-target t) ; suggest other visible dired buffer
With this setting, you can just arrange for two Dired buffers to be visible, and
when you give any command that needs a target directory (like C
(copy) or R
(rename)), the default will be the directory of the other Dired. You don’t have
to accept this new default destination when prompted—you can override it in
any individual case—and this setting only has an effect when you have two
visible Dired Buffers.
DWIM, by the way, stands for “Do What I Mean”, and is named for an
error-correcting feature in an old Lisp system dating from 1966.
Searching and Replacing
Normally, if you want to search through all the files in a directory you use
M-x
grep
, M-x
lgrep
, or M-x
rgrep
(see Meet
the Greps). But you can also use the power of Dired marks to limit your search
to a possibly idiosyncratic selection of the files in your Dired buffer.
Just set your marks and run A
( dired-do-find-regexp
); any
marked directories will be searched recursively, and if you don’t have any
marks, the file or directory at Point will be searched.
A Xref buffer containing all the hits will pop up and you can navigate through
them; see Figure 27.
This search is really more of an Occur. You can also do an Incremental Search
through the marked files. This is done with M-s a C-s
( dired-do-isearch
) or M-s a C-M-s
( dired-do-isearch-regexp
)165. These are basically
entry points to multi-isearch-files
, with the marked files
eliminating the need to enter a bunch of filenames; see Multi-Isearch for details
You can also do a search and replace across your marked files with Q
( dired-do-find-regexp-and-replace
). This pulls up all the
files with hits, one at a time, and in each runs a
M-%
(query-replace
) for you. There are other ways (which I prefer) to do a
search and replace across multiple files; see Xref and Writable Grep.
Diffing and Comparing
You can compare (“diff”) the file at Point with another file with =
( dired-diff
). You’ll be prompted for the second file; if
the first file has a backup file, that will be the default (and vice versa). If
the Region is active, the files at Point and Mark are the ones compared. A
prefix argument will let you specify the options given to diff(1)
.
You can also compare two directories in an interesting manner. Open two Dired
buffers on two different directories166; for the best demonstration, the
directories should be similar but not identical, e.g. one might be an older
version of the other. Then, in either buffer, say
M-x
dired-compare-directories
. Hit RET
at the prompt:
Mark if (lisp expr or RET):
Now you’ll (most likely) see that there are marked files in both directories:
these are the files in each directory with unique names. So in directory (A),
if the file foo
is marked, it means that there is no file named foo
in directory
(B), and so on. Or, equivalently, the unmarked files in each directory are
those that also exist (with the same names) in the other directory. Keep in
mind that this comparison is done purely at the level of the file names; the
contents do not enter into it.
Even just as a visual aid, this is useful for eyeballing the differences between
the two directories. You can make use of the marks in either or both
directories to do further comparisons (with =
), deletions, or copying.
If you know a little Elisp, you can mark the files more precisely than by
comparing their names; you can mark them based on their sizes, modification
times, owner, permission, etc. Do:
C-h f dired-compare-directories
for more information.
Reverting and Sorting the Dired Buffer
The contents of a directory can change out from under Emacs, so you can refresh
Dired’s notion of the directory contents with g
, which is bound to
revert-buffer
(as you might expect). This will reveal any
new files, omit any files that were deleted outside of Emacs, and make the
displayed file sizes, permissions, etc reflect the current state.
The l
command ( dired-do-redisplay
) is a less broad version
of this: it only redisplays the info for the marked files (or next (N) files, if
given a numeric argument), or the files in a subdirectory, if issued on a subdir
headline.
You can also sort the Dired buffer by modification time (most recent files
first), rather than the default alphabetical order, with s
( dired-sort-toggle-or-edit
). With a prefix arg, you’ll be
prompted to set the options for the ls(1)
command that lists the files; the
default options are -al
167; the -a
option causes files whose names begin
with .
to be included. If you don’t want to see dot files, do C-u s -l RET
(removing the a
option) and the buffer will be refreshed to exclude them. You
can also throw in other ls(1)
sorting options, like -r
, -S
, -t
; see the ls(1)
man page with M-x
manual-entry
. New options given in this manner
are sticky in that they persist through subsequent g
’s.
While the -l
option is mandatory, you can hide everything but the filename with
(
( dired-hide-details-mode
). That gives you a minimalist
skinny Dired buffer. Another (
brings the details back.
You can customize the default ls
options by setting
dired-listing-switches
in your Init File; I add -h
(--human-readable
) to print file sizes in a friendlier format (like 1K, 234M, 2G),
for example. But check the variable’s documentation for details; some ls
options can break Dired.
Finally, the Dired buffer supports a limited version of Undo, bound to the usual
keys (e.g. C-/
). This command can’t magically undelete files,
but it can revert changes to the buffer itself. You can use it to recover
changed marks, killed lines, or hidden subdirectories.
Omitting Uninteresting Files
Certain files can be considered uninteresting because you rarely want to
manipulate them (except perhaps to delete them): you typically don’t want to
visit them, copy them, or anything else. These files include build artifacts;
checkpoint, lock and backup files; and the .
and ..
directories. The problem
with these files in Dired is that they take up screen real estate (requiring
more scrolling), and often have to be unmarked after you’ve marked, say, all
directories, or all the files that match a regexp.
You can omit these files from your Dired listing with C-x M-o
( dired-omit-mode
), which toggles Omit Mode on and off.
You can also mark all the files that Omit Mode would omit with * O
( dired-mark-omitted
).
If you’d like to have these files omitted from your Dired buffers by default, as
soon as you open up any Dired buffer, add this to your Init File:
(add-hook 'dired-mode-hook 'dired-omit-mode)
You can un-omit them after that with C-x M-o
.
The precise definition of which files are omittable is controlled by the
variables dired-omit-files
and
dired-omit-extensions
. See
the Dired Extra manual for details and
examples.
Running External Commands
If Point is on a file line in a Dired buffer, then !
( dired-do-shell-command
) prompts for a command and runs it
synchronously on that file; &
( dired-do-async-shell-command
) does the same thing
asynchronously. So if Point is on a file foo.sh
, and you want to know how many
lines or words are in that file, you just type ! wc
, and the result is displayed in
the Echo Area; this is equivalent to M-! wc foo.sh
(except you didn’t have to
type the filename), and the output is handled in the same way. You won’t be
surprised that & wc
is equivalent to M-& wc foo.sh
, and runs the wc
command
asynchronously.
But these commands are not exact equivalents. When you type !
the prompt looks
like this:
! on foo.sh [sh]:
The sh
in the brackets is the suggested default command, so if you wanted to run
this shell script rather than count its lines, you could just hit return. There
may be more suggestions than just the one shown; you can use M-n
( next-history-element
) to scroll through them in the usual
way; see Future History. Emacs has commands to suggest for
55
possible files types and you can of course add your own via the
dired-guess-shell-alist-user
variable.
!
and &
operate on multiple files in the standard Dired ways, via numeric
arguments and marks. When you run a command on multiple files, a window will
open above the prompt listing all the files that will be affected—a nice
reassurance.
What is the nature of the command?
Dired’s !
and &
actually take an arbitrary shell command, so you can add options
to the command (e.g. ! wc -l
) and it can even contain pipes and other
shell-specific stuff, with the filename appended to the end of the command.
Emacs quotes all the filenames for you and the command is run once for each
file. So if you mark the files bar
, baz
, and foo
, and say ! wc
, Emacs will run
wc bar
, wc baz
, and then wc foo
, synchronously.
You can run just one wc
command for all the files by saying ! wc *
; this
wildcard is interpreted by Emacs and NOT given to the shell.168 Instead of
expanding to all the files in the directory as it would in the shell, Emacs will
put the list of filenames being operated on at the location of the *
, so cp *
will work correctly169. The filenames being operated on are
some-directory
the marked files, or the file at Point, or the (N) files at Point if you uses a
numeric argument of (N), in the usual Dired interpretation. The order of the
files in the expanded file list will match the order in which they occur in the
Dired buffer.
If you use ?
instead of *
, Emacs will run a separate invocation of the command
for each of the multiple files, just like in the no-*
case.170 What’s the
point of this, then? Well, you can repeat the ?
in the command and Emacs
replaces each ?
with the same filename. The silly command ! mv ? /tmp/ && touch ?
will move each file to /tmp/
and then replace it (in the original directory)
with a new empty file of the same name.
Again, this special interpretation of ?
only applies if it’s surrounded by
whitespace. But there’s one more special wildcard:
`?`
,
which is interpreted exactly as ?
except for the surrounded-by-whitespace
requirement. This means you can make backup files with a command like
! cp ? `?`.bak
.171
You mentioned running commands in parallel?
The &
command operates exactly like the !
command, except that it runs
asynchronously. So if you want to run your external PDF viewer on that Dired
file, you probably want &
. If you use &
with (N) files, without using *
in the
command, it will run (N) separate commands in parallel.
Image-Dired
Dired can also be used as an image gallery, displaying thumbnails of image
files. Just mark the files you’re interested in172 and say C-t C-t
( image-dired-dired-toggle-marked-thumbs
); see Figure
28. If no files are marked, C-t C-t
will display the thumbnail
for the file at Point.
You can of course see any image full-size by visiting its file, which will
naturally come up in image-mode
, but doing this will eventually clutter your
Emacs with many image buffers. If you just want to view some images more
transiently, rather than RET
, use C-t i
( image-dired-dired-display-image
),
which will repeatedly use a single buffer called *image-dired-display-image*
;
within this buffer f
will full-size the image and s
will resize it back to the
window size. C-t x
( image-dired-dired-display-external
)
will display the image with an external image viewer, outside of Emacs.
A limitation of Dired is that it can only list files one per line, so you may
have to do a lot of scrolling. Instead of inline thumbnails you can pop up an
additional window containing a new buffer of thumbnails only. Again, mark the
files of interest (or all of them) but this time invoke C-t d
to display the
thumbnails buffer; see Figure 29.
In the thumbnails buffer, you can move around with the usual motion commands;
RET
pops up the *image-dired-display-image*
buffer with a view of the image
corresponding to the current thumbnail, and SPC
and DEL
page the display buffer
forward and backwards through the images. The Dired buffer is linked to your
motion through the thumbnails, so if you navigate to a thumbnail and then jump
to the Dired buffer, Point will be on the file corresponding to the thumbnail.
You can also mark, unmark, and flag files from the thumbnail buffer.
Tagging and Commenting Images
Images can be tagged and commented from the Dired buffer. The image files
themselves are not altered by this process; the tags and comments live in a
metadata file in your user-emacs-directory
. This allows
you to set Dired marks on all the files with a given tag; after you’ve done some
tagging perhaps C-t f cat
would mark all your cat images.
Key | Action |
---|---|
C-t t |
add a Tag to all the marked files |
C-t c |
add a Comment to all the marked files |
C-t e |
Edit both |
C-t r |
Remove the given tag from marked files |
C-t f |
mark all Files with given tag |
Remote Directories
In addition to opening a directory on your local disk, Dired can also open a
directory on a remote computer, perhaps your office desktop at work. I almost
didn’t think to mention this, because it’s in no way a special feature of Dired,
but just falls out of Emacs’s ability to manipulate remote files via Tramp. So
when you run Dired, if you name a directory using Tramp’s remote file syntax,
then naturally the Dired buffer is remote, and all the Dired operations—file
copies, renames, deletions, visits, even shell commands via
!
(dired-do-shell-command
)—run on the remote host. Just as
naturally, in a local Dired, you can copy or rename a file to a remote host:
when prompted for the target filename, just use Tramp syntax. This even works
with the mass name-changing functions, and works seamlessly in two-panel DWIM
mode. See Tramp for details.
More Dired Entry Points
Normally C-x d
(dired
) is invoked with a directory name, but
you can also invoke it with a glob pattern: C-x d *.el
will bring up a Dired
Buffer with all, and only, the Elisp files in the default directory.
And there are more ways to get a Dired buffer than just
C-x d
. C-x C-j
(dired-jump
) or
C-x 4 C-j
(dired-jump-other-window
) from within a file buffer
will open Dired on that file’s directory. M-x
find-name-dired
will
prompt you for a directory, and then for a filename, possibly containing Unix
wild cards (glob characters); it will generate a Dired buffer containing all
the matching files under the named directory, recursively. So you might want to
run Dired on all your Elisp source files under your source code directory with:
M-x find-name-dired RET ~/src RET *.el
This command is a convenient interface to the Unix find(1)
command;
find-dired
is a more full-featured version that let’s you
specify any find
options you like. find-grep-dired
is much the same, but limits
the files to those that contain a Regular Expression as for grep(1)
.
You can use find-name-dired
to find files from anywhere on your system if you
give /
(the top-level root directory) as the starting directory, but if you have
a large disk with many thousands of files, this can be slow.
M-x
locate
is the Emacs interface to the Unix locate(1)
command that
uses a database of filenames and so runs much faster.173
M-x
locate-with-filter
has an additional prompt for a Regular
Expression that’s used to filter (limit) the hits.
You shouldn’t try to quote any of the arguments to any of the find-
and locate-
commands—Emacs takes care of that for you—with the exception of find-dired
(because that one requires you to enter a raw find
command).
Many Major Modes provide custom entry points to Dired. For example,
doc-view-mode
can pop up a Dired on its cache directory, EMMS will open Dired
on the music files in your playlist, and Projectile will open Dired on your
current project.
Third-Party Directory Tools
There are some 60 packages in MELPA that provide
various enhancements to Dired, like fancy multi-panel layouts, sidebars,
displaying icons next to the files, cleaning up duplicate files, and more. One of the
most useful is Pierre Neidhardt’s disk-usage
package, which finds the files and
directories that are taking up the most space; see Figure 30.
References
- See “Dired” in the Emacs manual.
- Kremer, Sebastian and Free Software Foundation. 2022. Dired Extra. Cambridge, MA: Free Software Foundation..
Read in Emacs withM-x info-display-manual RET dired-x RET
.
Searching …
Searching is one of the most important Emacs skills. It’s pervasive: since it
works in (and across) your Buffers, it works, identically, not only within a
file you’re editing, but within the user interfaces (UIs) of Emacs and its many
subsystems—the Help system, Dired the file manager, the Emacs documentation,
your shells and terminals, your mail, your calendar and diary, your web browser,
your music player—everything. Imagine if you could explore and find your way
around the UI—the menus and toolbar—of a GUI application like your web
browser the same way you can search the text of one of its web pages. And to
top it off, Emacs’s search facility is far more powerful than that of any GUI
application.
Searching can be divided into two major flavors: incremental search style and
occurrences style. Incremental Search, which you may think of as “find as you
type” — a now common user interface feature invented in Emacs in the 1970s —
is probably the most important. It takes you hit-by-hit through all the match
locations in that Buffer (with highlighting).
Occurrences-style search works more like a web search engine: you type in your
query and Emacs pops up a new Buffer full of hits, from any of which you can
jump to the actual occurrence. There are many forms of this, exemplified by
M-x
occur
, which presents the matches from your current Buffer.
Occur also resembles the output of the Unix grep(1)
command (especially with the
--color
option turned on): the Buffer of hits is like the lines of grep
output,
except you typically can’t click on a hit in the terminal and be taken to that
line of the matching file. That is, unless you run grep
under Emacs; see Meet the Greps.
Incremental Search
Incremental Search (Isearch) is a commonly used way to move around when you’re
editing text: it’s so fast and easy, I’ll even use it just to move to a spot in
the same line. As befits one of the most heavily used features of Emacs,
Isearch is very powerful and thus very complex. But if you have an idea of
what’s possible, you can start out easy and add fancy features as you gain
experience. I would say I use most of these features, but not all, and a few
were surprises when I delved deep into the manual in order to write this
chapter.
The command C-s
(isearch-forward
) starts a search and prompts
in the Minibuffer for a search string:
I-search:
Suppose you’re looking for occurrences of the word “and”: just start typing it.
As soon as you type the letter “a”, all the “a”’s visible in the current window
will be highlighted a light blue, except the very next “a” after Point, which
will be violet-red174; in fact, Point has been moved to this location. Now the
prompt looks like:
Pending I-search: a
Add “n” to your search, and all the highlights will be updated: now only
occurrences of “an” will be highlighted, and if necessary, Point will be moved
ahead to the first match. Add your final “d” and now only “and”’s are
highlighted.
Pending I-search: and
If the first “and” after Point isn’t the one you want, just type C-s
again, and
Point will advance to the next “and”; you can keep C-s
’ing through the hits. If
the next hit is off-screen, the window will scroll. When you’ve reached the
“and” you wanted, just hit RET
to terminate the search; Point is now at the end
of the chosen “and”.
The whole point of the incremental part of Isearch is that you often don’t need
to type the entire string that you’re searching for: once Point reaches the
right spot, just hit RET
and you’re done. You can also start C-s
’ing ahead at
any point. If you’re searching for the word
“Pneumonoultramicroscopicsilicovolcanoconiosis” command, there’s a good chance
you’ll have found it after “pn”; at any rate, you probably won’t have to type in
all 45 characters.
Failing Searches and Making Corrections
If the string you’re searching for isn’t present in the Buffer, Emacs will beep
and you’ll see in the Minibuffer something like:
Failing char-fold I-search: zq
It’s likely that a prefix of your search string (here, “z”) is in the Buffer,
but the complete string (“zq”) is not. Perhaps you meant to search for “zap”:
just use DEL
(isearch-delete-char
) to delete the “q” and
make your correction.
If you’re typing quickly, you might get in a whole bunch of non-matching
characters at the prompt; that’s okay: you can delete them all one at a time
with DEL
, but hitting C-g
will delete all the non-matching characters in one
go.
When moving from hit to hit with additional C-s
’s, you may overshoot
the hit you want. DEL
will “correct” this mistake too, taking you back to the
previous hit.
If you hit the end of the Buffer during a search, Emacs will likewise beep and
indicate search failure; but if you hit another C-s
, your search will wrap
around to the beginning of the Buffer and continue searching from there. The word
“Wrapped” will appear in the prompt to indicate this; if you go all the way
around, returning to your starting point, and keep going, the prompt will change
to “Overwrapped” to make it clear that you’ve seen all these hits already, and
there are no more new ones.
Editing Your Search
Suppose you’ve started Isearching for the word “stolidity” and only then
noticed that you really meant “solidity”. You don’t have to do eight DEL
’s and
then type a “t” and then retype “olidity”: you can put your Isearch into edit
mode with M-e
(equivalently, M-s e
); now you can use all the usual editing
features of Emacs, as you usually can in the Minibuffer, to go back and just
delete that “t”. When your edit is done, restart your Isearch with any of RET
,
C-s
, or C-r
175 and continue from there.
Aborting Your Search
Because C-g
, usually keyboard-quit
, in Isearch has the
handy use of zapping non-matching search characters, you need to use two C-g
’s to
abort your search, leaving Point where you started.
Quick Search Exit
For the sake of editing speed, any other non-Isearch Emacs command will also end
the search successfully, and be immediately executed. You could exit with
M-f
(forward-word
), for example: C-s zap M-f
is equivalent to
C-s zap RET M-f
: both will leave Point at the end of the word following “zap”.
Scrolling
Scrolling commands normally terminate the search and then scroll, as per above,
but I like to be able to scroll the window in mid-search, to see what’s coming
up (or what’s behind me). This Init File snippet allows most scrolling commands
(like C-v
(scroll-up-command
),
M-v
(scroll-down-command
), and
C-l
(recenter-top-bottom
)) to work this way.
(setq isearch-allow-scroll t) ; scroll while searching
The Region is Set for Free
When you end a search successfully, you’ll notice this message in the Minibuffer:
Mark saved where search started
This means that the Region (though inactive) is now around the text, from where
you started the search to where you are now, and you can do whatever you like to
the region (kill, copy, or modify it). You can jump back to where you came from
with C-x C-x
(exchange-point-and-mark
) or C-u C-SPC
( set-mark-command
).
Changing Directions
If you know the string you’re looking for precedes Point, you can instead start
your search with C-r
(isearch-backward
). You can reverse
direction at any time with C-r
, and change back to going forwards again with a
C-s
, as needed. The commands M-s M-<
and
M-s M->
, which jump to the first match or last match
respectively, without terminating your search, can be useful for fine-tuning
your position before or after changing directions.
Restarting Your Last Search
Immediately after starting a search with C-s
, if you type another C-s
, it will
search for the last search string you used (the same is true if you start with
C-r
—an immediate C-r
reinvokes your previous search). Think of the sequence
C-s C-s
as “redo my last search” (same for C-r C-r
).
Isearch maintains a history of your last
16 search strings in the usual
ring structure. Just use M-p
and M-n
as usual to navigate through your
searches; when you’ve pulled up the one you want, you can edit it before
starting the search with another C-s
or C-r
. There are separate histories for
simple string search and for regular expression search.
Searching for Funny Characters
If you need to search for a non-printing character (which would normally
terminate your search), you can do so by quoting it with C-q
.176 So you can search
for a C-g
(ASCII 007) with C-s C-q C-g
. To include an explicit newline in your
search string, just use a simple C-j
(the ASCII linefeed or newline character),
which you don’t have to quote.
Case Sensitivity and Whitespace
Searches are case-insensitive177 by default, so “and” will also find “And”
and “AND”, etc. But if you include an uppercase letter anywhere in your search
string, then the search is performed case-sensitively.
Whitespace is treated abstractly: by default, a single space will match a
sequence of any whitespace characters (space, tab, formfeed, and newline in most
Major Modes). This is called lax space matching.
Varieties of Isearch
The cases just described are just defaults; you can toggle any of them on or off
in mid-search with the following special isearch-mode
commands, any of which
only affects the current search and doesn’t “stick” for future searches (but you
can set your preference of default for each in your Init File; see
“Special Isearch” in the Emacs manual).
M-s c
- Case Folding
Toggle case folding on and off; this command is also onM-c
. On by default. M-s SPC
- Lax Space Matching
Toggle lax space matching on and off; when off, one space character matches only
a single space and not a run of spaces or a combination of other whitespace
characters. On by default. M-s '
-
Diacritic Folding
Toggle diacritic folding178 on and off. (Mnemonic: the apostrophe'
is like an acute
accent.) When on, an unadorned letter will match that same letter with any
diacritical mark. So, searching for “cafe” will also find “café”. Off by
default. I recommend turning this on by default with this Init File snippet:(setq search-default-mode 'char-fold-to-regexp) ; cafe = café
M-s w
-
Word Search
Toggle word search on and off.
When on, the search string will only match complete words (so “an” will match
neither “any” nor “man” nor “pants”). Your search string can be a sequence of
space-separated words and those complete words will match with any amount or
combination of whitespace and punctuation between them. Off by default.M-s w
also has a global binding to isearch-forward-word
,
which initiates an incremental word search. M-s _
- Symbol Search
Toggle Symbol Search on and off. Symbol search is exactly like word search,
except it deals with symbols rather than words, according to the current Major
Mode. In programming language modes especially, Emacs symbols represent
variable and function names, which can contain punctuation characters which
aren’t typically allowed in Emacs words. An example is that most languages
allow_
in symbols, but_
is usually not considered part of a word.179
(Hence theM-s _
mnemonic.) Off by default. M-s i
-
Search Invisible Text
Emacs has the ability to make text invisible;
M-s i
toggles whether or not an
incremental search will match text that’s currently invisible. For example,
Outline Mode and Org Mode let you hide (“fold”) the text within nested subheadings, so
you can focus on the outer text; Selective Display hides indented text (say in
programming language modes) for the same reason. Off by default. M-s r
-
I’ve saved the best (perhaps) for last.
M-s r
(also onM-r
) toggles between
simple string search, which we’ve been discussing, and regexp search, which uses
the powerful pattern matching language of regular expressions. This is so
important and so heavily used that you can start out in a regexp search via the
global bindingsC-M-s
(isearch-forward-regexp
) and
C-M-r
(isearch-backward-regexp
). Off by default.Other than searching for complex patterns rather than simple strings,
incremental regexp search is almost identical to Isearch, supporting all the
features described in this section. The main exceptions are that lax spacing is
not on by default (you can toggle it on withM-s SPC
) and that diacritic folding
is not available.Why does Emacs have both simple string search and regular expression search? In
editors that only have regexp search, you have to do a lot of quoting of the
regexp metacharacters (like a simple.
or$
); on the other hand, if you only have string search you
can’t do powerful searching. So we have to have both, equally easy to use.
Nonincremental Search
Emacs’s incremental search is now the standard way to search; almost all
editors and many other applications (e.g. web browsers, shells) have adopted the idea180.
But I suppose you may occasionally want to do a non-incremental search, and you
can do that with C-s RET
or C-r RET
— in other words, begin your search by
hitting return and the prompt will change from I-search
to Search
, and now you
have to type your complete search string without seeing any intermediate
matches. When you’ve typed it in, hit RET
to do the search and you’ll be taken
to the first match. Period. Your search is over. To find the next hit, you
have to do C-s RET RET
, which will reuse the previous search string.
So disappointing. This is the way all searches used to work before the
invention of incremental search.
Why would you want to do this? I guess you can think of it as equivalent to C-s
followed by an immediate M-e
to edit the search string. Perhaps nonincremental
search is for people who haven’t yet learned how to yank.
Yanking Into the Search
Key | Action |
---|---|
C-w |
Yank next word from buffer |
C-M-w |
Yank next symbol from buffer |
M-s C-e |
Yank remainder of line from buffer |
C-M-z |
Yank string up to given character |
C-M-y |
Yank character at Point |
Frequently you want to search for some text that is right in front of you in
the current Buffer, and the properly lazy Emacser never wants to type in text
unnecessarily. Instead, you can yank text at Point right into your Isearch. You
can do this right after starting a search, or after you’ve typed part of your
search string. You can also yank in text from the Kill Ring in the usual
manner with C-y
and M-y
. See Table 21.
Transitioning to Other Search Types
Key | Action |
---|---|
M-r |
Switch to regexp search |
M-s o |
Switch to occur |
M-% |
Switch to query-replace |
M-s h r |
Terminate search, leave highlights |
You’ll find that Isearch is your goto-search—the one you automatically reach
for—but isearch-mode
provides shortcuts to transition to other searches, so
that you don’t have to abort your Isearch and start over.
You can switch from simple string search to regular expression search with
M-r
— perhaps your simple search isn’t finding enough matches; you may need to
use M-e
to convert your search string to a more complex regexp.
I use the M-s o
transition a lot: without terminating your Isearch, it pops up a
Buffer of hits, search-engine style, as if you had done M-x
occur
.
You might decide in the middle of your search that you want to convert all the
matches to something else; M-%
will switch to a query-replace
, using your
search string as the text to replace. If you’re doing a regexp search when you
hit M-%
, it will switch to query-replace-regexp
instead.
Finally, while it’s not really a transition to a different kind of search,
M-s h r
will terminate your search, leaving all the hits in the Buffer
highlighted in a color of your choice; see Highlighting.
Help
With isearch-mode
having 80-odd key bindings, you might have trouble remembering
them all, so just try to remember C-h C-h
, which will pop up a special Isearch
help Buffer. For another perspectives on all this, see
“Incremental Search” in the Emacs manual.
Occurrences
Incremental Search gives you an overview of the matches for your search string
(via colorization), but if your Buffer is large and your matches are spread out,
you won’t be able to see very many of them without stepping through them all
M-x
occur
(also on the global binding M-s o
) gives you a more compact
overview of the matches in a separate Buffer named *Occur*
. It might look like
this (partial view of the *Occur*
Buffer):
29 matches for "^#+name:" in buffer: use-emacs.org 125:#+NAME: info-nodes 209:#+name: age-in-years 4277:#+name: image-mode-scaling-commands 4290:#+name: image-mode-scroll-keys 4404:#+name: basic-dired 6218:#+NAME: shell-commands 6695:#+NAME: face-count
This is rather like a results page from a web search engine. It tells you how
many total matches there were, and each hit shows the complete line it occurred
on, preceded by its line number; you remain in the Buffer from which you issued
the occur
command.
This gives you a nice overview, and you can jump directly from match to match
with C-x `
(next-error
) or its more mnemonic binding, M-g M-n
(Go to Next hit).181 Each M-g M-n
moves Point to the next matching line in
the original Buffer—the Point in the *Occur*
Buffer follows along—so you can
step through all the hits.
(Why “next-error
”? These search hits don’t seem like errors! The reason is that
this is just one of many use cases for a command that originated to step through
the error messages from a compiler for a programming language; see Compiling Code.)
Instead of staying in the original Buffer and stepping though all the hits, you
can switch to the *Occur*
Buffer and navigate to the lines of interest, where
you can hit RET
to jump to that line in the original Buffer or C-o
to stay in
the *Occur*
Buffer but scroll the original Buffer to show that line in context.
Of course you might use an Isearch to navigate in the *Occur*
Buffer, and in a
big *Occur*
Buffer, I actually sometimes use… M-x occur
! Yes, an occur
within
an *Occur*
Buffer is a way to narrow the occurrences to a more precise list.
This all just works because, well, buffers are buffers and text is text, even
though *Occur*
is the user interface of the M-x occur
application!
Writable Occur, or occur-edit-mode
One of the more amazing features of occur
is occur-edit-mode
, bound to e
in the
*Occur*
Buffer. This one of Emacs’s Indirect Editing features. Normally, the
*Occur*
Buffer is read-only, but typing e
allows you to edit the Buffer. The
amazing part is that when you’re done editing, give the command C-c C-c
182
( occur-cease-edit
) and all your edits are applied to the
matching lines in the original Buffer! You can use any techniques to make these
changes: not just manual slogging, but things like
M-%
(query-replace
) or a Keyboard Macro.
Multi-Buffer Searching
With a long-running Emacs server, I typically have fifty or more buffers going
at any given time — files, shells, emails, web pages, directories, etc. How
on earth do you find anything?
The best way to search all of your Emacs is to say C-u
M-x
multi-occur-in-matching-buffers
. You’ll be prompted for a
regular expression to target the buffers you want to search; just hit return:183
List lines in buffers whose names match regexp:
Then you’ll be prompted for your search string (actually another regexp); we
should get lots of hits for “the”:
Collect strings matching regexp: the
Normally this command only searches buffers that are visiting files, and the
first regexp is matched against the buffer’s visited filename, but with the
prefix argument (C-u
), it searches all buffers, so that will include Dired
buffers, music player buffers, Help and Apropos buffers, shell and terminal
buffers: everything.
I just did such a search for the word “the”: in about one second, a new *Occur*
Buffer popped up showing “3518 matches in 2609 lines total across 108 buffers”.
The Buffer looks mostly like a normal *Occur*
, but the matches are
grouped by Buffer; here’s an incomplete, edited example (all the occurrences of
“the” will be colorized):
3518 matches in 2609 lines total for "the": 24 matches in 17 lines in buffer: sittin-on-the-dock-of-the-bay 1:{title:Sittin' On the Dock of the Bay} 6:[G]Sittin' in the mornin' [B]sun 7:I'll be [C]sittin' when the ev - [B]en - [Bb]in' [A]comes 6 matches in buffer: captain-beefheart 4:* The GREAT essential records 7:- Doc at the Radar Station (1980) 10:* The Good 13:- The Spotlight Kid (1972) 241 matches in 185 lines in buffer: texmf.cnf 9:% (Below, we use YYYY in place of the specific year.)
All the usual Occur commands work in this Buffer, including e
(occur-edit-mode
).
Instead of multi-occur-in-matching-buffers
, you can instead use plain old
M-x
multi-occur
, which prompts you, one at a time, for the set of
Buffers to search; you can use completion on the Buffer names.
You can also do a multi-incremental-search. Personally, I think this is more
awkward than Multi-Occur, but your mileage may vary. It’s just like a regular
Isearch except, when you hit the end of a Buffer, a C-s
, instead of wrapping
around to the beginning of that Buffer, advances to the next Buffer that
contains a match. M-s M-<
and M-s M->
are
especially useful here to skip over entire buffers and keep searching.
There are several entry points. In Table 22, “listed”
means you’ll be prompted to list the targets (buffers or files), and “regexp”
means you’ll enter a regular expression to match the targets.
Targets | String Search | Regexp Search |
---|---|---|
Buffers, listed | M-x multi-isearch-buffers |
M-x multi-isearch-buffers-regexp |
Buffers, regexp | C-u M-x multi-isearch-buffers |
C-u M-x multi-isearch-buffers-regexp |
Files, listed | M-x multi-isearch-files |
M-x multi-isearch-files-regexp |
Files, regexp | C-u M-x multi-isearch-files |
C-u M-x multi-isearch-files-regexp |
… and Replacing
One of the main reasons to search is in order to move to a new location. The
other is to replace text.
The most important find-and-replace command is
M-%
(query-replace
). It prompts for a string to replace
(we’ll use “vim”):
Query replace (default foo → bar): vim
and then the replacement text (we’ll use the obvious):
Query replace vim with: emacs
Emacs then finds the first match for “vim” after Point, highlighting it (and all
the upcoming matches) in the manner of Isearch, and then asks what to do with
this match:
Query replacing vim with emacs: (? for help)
Basically you type y
to do this replacement or n
not to do so, and Emacs then
jumps to the next match, and we repeat the process until we finish with the
final match in the Buffer.
To do the entire Buffer, first jump to the beginning with
M-<
(beginning-of-buffer
). With a negative prefix
argument184, the replacements can be done backwards from Point.
With a simple prefix arg—just C-u
—the search string is matched as a
whole-word as if for M-s w
( isearch-forward-word
).
There are many more valid answers to the replacement question than just yes and
no; see Table 23.185
Key | Action |
---|---|
SPC , y |
replace this match and proceed |
DEL , n |
skip this match and proceed |
! |
replace all remaining matches without asking |
^ |
jump back to previous match |
, |
replace this match but don’t proceed yet (stay here) |
u |
undo previous replacement |
U |
undo all replacements |
e , E |
edit the replacement string |
RET , q |
Quit without replacing this one |
. |
replace this match, then quit |
C-r |
enter Recursive Edit |
C-w |
delete match and enter Recursive Edit |
Most important is !
which replaces all the remaining matches in one go, no
questions asked. It’s typical that you intend to do all the replacements, but
want to see the first few in context before committing yourself with !
. Sometimes you
don’t have time to see the effect of the replacement because Emacs has jumped to
the next match and scrolled the replacement off-screen; in this case, just hit ^
to jump back to where you were and take a look (more ^
’s will step back through
more replacements). When you’re happy, just hit SPC
to continue replacing where
you left off.
If you’re not happy with the replacement you’ve just done (maybe you hit y
on
autopilot when you meant n
), you can undo it with u
; Point will jump back to
that spot, undo the change, and you can think again; any action is possible
here. You can even undo all the replacements you’ve done so far with U
, after
which you might want to edit your replacement text with E
and then start over,
all without quitting the query-replace
.
Sometimes you do want to quit early; q
or .
will do the job186: perhaps you only
wanted to do your query-replace
in the current paragraph.
Actually, in that case you’d be wiser to set the active region around the text
you want to replace within; if the Region is active, query-replace
will only
operate on matches within it, and so you can safely use the convenient !
without
affecting anything outside the Region.
Sometimes you’re stepping through replacements and find a spot where you want to
use a completely different replacement string—but just this once. You could
quit with q
, manually do the replacement, and then reinvoke M-%
from that
location to continue—Emacs helpfully offers your previous search string and
replacement as the default. The disadvantage of this is that you can no longer
use ^
to go back to locations from the preceding M-%
, since it was terminated;
nor will U
undo any of those changes. Not a big deal, but there’s a fancier
way: instead of quitting, use C-r
to enter a Recursive Edit, make your anomalous
change, and use the usual C-M-c
(exit-recursive-edit
) to exit
the Recursive Edit and continue your query-replace
session. C-w
is a handy
shortcut.
Once you’ve done a few Query Replaces, you’ll notice that it’s case-smart.
Firstly, if your search string is entered in all lowercase letters, it is
matched in a case-insensitive mode (just as with Isearch).
In our “vim” → “emacs” example, if
one of the vims in the Buffer is capitalized (“Vim”) then you’ll see this
prompt:
Query replacing vim with Emacs: (? for help)
Note that instead of replacing with “emacs”, it’s going to use “Emacs”,
to match the case of the “Vim”. Likewise, if there’s a “VIM” the replacement
will be “EMACS”.
If your search string contains any uppercase letters, the searches will be done
case-sensitively, and likewise your replacement text will be used without
modification. So M-%
“Vim” → “emacs” will only match “Vim” and will replace it
with your all-lowercase “emacs”. If your search string is all lowercase but
your replacement string contains any uppercase letters, the search is
case-insensitive but the replacement will be done exactly as given every time.
In Table 24, we summarize the three cases: the String column is the
text in your Buffer, and the Replacement column shows the result of responding
with y
; an empty Replacement means that the particular String wasn’t considered a
match.
Search | Replace | String | Replacement |
---|---|---|---|
vim |
emacs |
vim |
emacs |
Vim |
Emacs |
||
VIM |
EMACS |
||
Vim |
emacs |
vim |
|
Vim |
emacs |
||
VIM |
|||
vim |
Emacs |
vim |
Emacs |
Vim |
Emacs |
||
VIM |
Emacs |
You’ll notice in the initial prompt that there’s a default search and
replacement pair which is your previous invocation (in the example above, it’s
to replace “foo” with “bar”). Just hit RET
to accept it and begin the process.
Alternately, you can use the familiar M-p
and M-n
to cycle through your history
of Query Replace invocations. At any point you can edit either the search
string part or the replacement part.
Some other Emacs commands—such as Dired’s Q
command,
M-x
xref-query-replace-in-results
, or
M-x
tags-query-replace
— will invoke a Query Replace for you on
multiple buffers. In these multi-Buffer replacements, !
will do unconditional
replacement just in the current Buffer; use Y
(note the caps) to replace all of
the remaining matches in all the remaining buffers, or N
to skip to the next
Buffer without replacing the remaining matches in the current Buffer.
Query Replace with a Regular Expression
If Query Replace isn’t powerful enough for you, you can try
C-M-%
(query-replace-regexp
), where instead of a simple
search string, you use a Regular Expression. It works much like M-%
, but your
regexp search pattern can match much more flexibly. For example, we might want
to go beyond just replacing “vim” with “emacs” via this regexp:
<((neo)?vim|vi|ed|(vs)?code|sublime( *text)?|atom)>
which allows us to replace a whole collection of apostate editors with Emacs.
In addition to supporting a fancier search string, query-replace-regexp
also
supports special features in the replacement string. In order to start using
these very handy features, as long as you stick to letters, digits, and
whitespace—all of which, as regexps, work as you’d expect—you can start
using query-replace-regexp
without waiting to become an expert in Regular
Expressions. But if you want to use any other characters in your regexp, even
just the humble period (.
), you’ll have to learn how to escape them first.
If you include #
in the replacement text, that pair of characters is replaced
by the number of replacements that have already been performed, so if our Buffer
contains:
foo foo foo foo foo foo
and we execute C-M-% foo RET foo#
at the beginning of the Buffer, the resulting
Buffer is:187
foo0 foo1 foo2 foo3 foo4 foo5
The sequence ?
in the replacement text will result in a prompt for a string, so
that you can replace each ?
with whatever you like. Consider this command:
C-M-x foo RET foo?
. First you’ll need to decide whether or not to perform this
replacement, as usual, by responding y
or n
; if you choose to do the
replacement, you’ll now get an additional prompt:
Edit replacement string: foo
Now you can edit the replacement to be foobar
, barfoo
, antiparticle
, the empty
string (to delete the match), or anything else. For the next replacement, you’ll be
prompted anew, and can respond with a completely different string (or use M-p
’s
to pull up replacements from the history). You can use more than one ?
if you
like.
Almost the most powerful feature of query-replace-regexp
, though, is that you
can refer to the text matched by the regexp, and the text matched by any
capturing parentheses within it, in the replacement text via back references. In
the replacement string, &
stands for the entire match. Even if you aren’t
using any of the pattern-matching features of regexps, this can save you some
typing. C-M-% emacs RET the amazing & RET
replaces each “emacs” with “the
amazing emacs”; since “emacs” is all lowercase, this replacement is case-smart.
When your regexp matches more than just a literal string, then a back reference
is the only way to include the match in the replacement. Suppose you want to
put quotes around all the numbers in your Buffer. The regexp [0-9]+
matches any
number, so you can do this with C-M-% [0-9]+ RET "&" RET
.188
Capturing parentheses let you refer to just a part of the match. Suppose you
have a number of strings of the form “foo56”, “foo765”, “foo3” and the like, and
you need to change all the “foo”’s to “bar”’s, yielding “bar56”, “bar765”, and
“bar3”, but not change any standalone “foo”’s that don’t have an attached
number. You can do it this way: C-M-% foo([0-9]+) RET bar1 RET
. The 1
refers to the first parenthesized subexpression; if you have two sets of parens,
you can use 2
as well. This means you can change all numbers like “10K”, “542M”,
and “2.3G” to “10 K”, “542 M”, and “2.3 G” with C-M-% ([0-9.]+)([KMGTPEZY]) RET 1 2 RET
.
You could also change all the foo[0-9]+
matches to just plain “foo” with the
command C-M-% foo[0-9]+ RET foo RET
or in fact delete all trailing numbers
from any words with C-M-% ([a-z]+)[0-9]+ RET 1 RET
.
Because of back references and the other handy backslash-sequences, if you
actually want to include a backslash in your replacement, you’ll need to double
it. That is, \
is replaced with a single .
Regexp | Replacement | Example Match | Result |
---|---|---|---|
emacs |
the amazing & |
Emacs | The Amazing Emacs |
[0-9]+ |
"&" |
3645 | “3645” |
foo([0-9]+) |
bar1 |
foo765 | bar765 |
([0-9.]+)([KMGTPEZY]) |
1 2 |
10K | 10 K |
foo[0-9]+ |
foo |
foo765 | foo |
([a-z]+)[0-9]+ |
1 |
xyz123 | xyz |
Elisp Replacement Strings
Above, I said back references were almost the most powerful query-replace-regexp
feature. Undoubtedly the most powerful feature is the ability to apply an
arbitrary Elisp expression to the matched string and use the result as the
replacement: that is, to compute a replacement from each match. ,
(backslash-comma) followed by an Elisp expression can be used anywhere in the
replacement, including more than once. Within the expression, you can use all
the backslash sequences we’ve discussed above.
To use the feature you need to be pretty well-informed about both Regular
Expressions and Emacs Lisp, so I won’t go into this any further after giving a
trivial example. Note that the Elisp expression:
(1+ x)
where x
is some number, returns the successor of that number, so (1+ 6)
evaluates to 7
. Remember that #
can be used to number your replacements, but
that the numbering starts at zero. We can arrange for the numbering to start at
one with the replacement string:
foo,(1+ #)
so our example above would yield:
foo1 foo2 foo3 foo4 foo5 foo6
See Regular Expressions and Programming the Lisp Machine for more information.
Other Entry Points
There are two other string replacement commands that you can use:
M-x
replace-string
and M-x
replace-regexp
. They are
non-interactive versions of M-%
and C-M-%
respectively. They work exactly the
same, including their interpretation of prefix arguments and of replacement
strings, they just run in “batch mode”: they do all the replacements without
any questions. I literally never use these commands, because the interactive
versions are just as fast as soon as you decide it’s okay to hit !
, and I always
like to see the first one or two replacements before I commit. That said, a
single Undo will undo all the changes in one go (also true of the interactive
versions).
Meet the Greps
Emacs also has its own interfaces to grep(1)
for searching across files outside
of Emacs, whether (1) a set of specific files, (2) some or all of the files in some
directory, or (3) some or all of the files under some directory, recursively.
These searches pop up a *grep*
Buffer of clickable hits (each of which pulls up
the file and takes you to that location).
Before we explain how to invoke the Greps, let’s take a look at the workings of
the *grep*
Buffer; it works the same regardless of how it was invoked.
The *grep*
Buffer and Grep Mode
You can see from the screenshot above that a *grep*
Buffer looks just like an
*Occur*
Buffer—lines of hits prefixed with line numbers—except that the
*grep*
Buffer also includes file names; the format looks exactly like the output
of grep(1)
. Table 26 summarizes the buffer’s key bindings. It
shouldn’t be surprising that the Buffer’s Grep Mode has many key bindings and
actions in common with Occur Mode; for historical reasons, there are some
discrepancies in the key bindings, and Grep Mode also has some actions that
don’t make sense in Occur Mode. See Compilation Mode and its Many Descendants
for a side-by-side comparison.
Grep Mode is enabled in the hits Buffer (*grep*
) and some of its actions affect
one or more target buffers that it pops up for you.
Key | Action | |
---|---|---|
1 | RET , C-c C-c |
jump to hit in target file |
C-o |
display hit … | |
n |
jump to Next hit in target file | |
p |
… Previous … | |
2 | M-n , TAB |
move point to Next hit in *grep* |
M-p ,
|
… Previous hit … | |
} , M-} |
move point to next file in *grep* |
|
{ , M-{ |
… previous … | |
C-c C-f |
toggle next-error-follow-minor-mode Mode |
|
3 | SPC , S-SPC |
scroll target buffer up |
DEL |
scroll target buffer down | |
< |
scroll target buffer to top | |
> |
scroll target buffer to bottom | |
4 | g |
revert buffer |
C-c C-k |
Kill running grep |
|
C-c C-p |
writable grep |
|
5 | 0 … 9 |
digit argument |
q |
Quit hits buffer | |
h , ? |
help for mode |
The Grep Mode commands come in several groups:
- Commands that visit the file containing the hit at Point in a pop-up Window,
scroll the Window to the hit, and make this the selected Buffer so you’re
ready to edit. There’s also a display command,C-o
, to do all that but stay
in the*grep*
Buffer. - Commands that just move from hit to hit in the
*grep*
Buffer; you could of
course use plain oldC-n
(next-line
) and
C-p
(previous-line
), but depending on your search, a hit
might comprise more than one line. There are also handy commands to move
from file to file, and a command to togglenext-error-follow-minor-mode
. - Commands that scroll the target Buffer from within the
*grep*
Buffer; very
handy when you’ve usedC-o
. - Commands to revert the
*grep*
Buffer (to re-run thegrep
command and update
the Buffer); kill the runninggrep
command189; or do an Indirect Edit. - The usual Special Mode conveniences: easy digit arguments, Mode help, and a
quit command.
next-error
Integration
You can navigate from hit to hit from wherever you started your Grep without
switching to the *grep*
Buffer via
C-x `
(next-error
) 190 or equivalently
M-g M-n
(it also works inside the *grep*
Buffer). This works
even when the *grep*
Buffer is no longer visible.
Indirect Editing with Writable Grep
One of the Grep facility’s most amazing features is that you can edit the text
of the hits in the *grep*
Buffer and then, with a keystroke, write your edits
back to the original files. This “indirect editing” feature works the same way
as Writable Occur; unfortunately the keystroke to invoke it---C-c C-p
— from a
*grep*
Buffer isn’t the same as for an *Occur*
Buffer.191
This requires the optional wgrep
Package from the GNU repository. I recommend
this snippet for your Init File:
(unless (package-installed-p 'wgrep) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'wgrep)))
Plain Old M-x grep
How do we acquire one of these wonderful *grep*
Buffers? The fundamental way is
with M-x
grep
, which will prompt you for a grep
command line; so,
this obviously assumes you’re familiar with the Unix grep(1)
command, and
familiar with Regular Expressions (Regexps) as well. The default command line
(on Linux) is:
grep --color -nH --null -e
You’re expected to fill in your Regexp and the paths of the files you want to
search on the right. Don’t forget to quote both appropriately, just as in the shell. You’re
free to change the options (perhaps adding a -i
to do a case-insensitive
search), but see below for details. You can also use something fancier than a
single grep
command, like a pipeline of grep
’s, or anything else that meets the
output requirements of the *grep*
Buffer.
If you’re unfamiliar with Regexps, you can change grep
to fgrep
and do a plain
text search, but you still need to be familiar with Unix shell quoting; if you
aren’t, skip ahead to lgrep
.
With a prefix argument, M-x grep
will fill in the complete grep
command to
search for the Symbol at Point in the selected Buffer’s file, and of course
Emacs keeps a history of the grep
commands you’ve used in this session, which
you can access in the usual ways.
Local Directory Grep with M-x lgrep
M-x
lgrep
is a convenient front-end that composes a Grep command for
you that searches all the files in a given directory; it’s especially
convenient for Emacs users who aren’t yet au courant with Unix concepts like
Regexps, shell quoting, and file globbing. When invoked, it prompts you for
three things: a Regexp, a filename or glob pattern, and finally a directory, and
it constructs and immediately runs a grep
command for you. Let’s use M-x lgrep
to search for “foo” in all the files in our default directory. The Minibuffer
prompts look like this:
Search for: foo
Now specify the files to search in:
Search for "foo" in files matching wildcard (default all):
Just hit RET
for all (significant) files, but it’s also totally fine to enter
one or more filenames separated by spaces (your Completion system can help you),
or use one or more space-separated glob patterns (wildcards).
Finally we have to say which directory contains the files:
In directory:
Hit RET
to search the selected Buffer’s default directory.
This will be a case-insensitive search by default. Don’t try to quote any of
these values; lgrep
will quote them for you.
With a prefix argument, C-u M-x lgrep
, you’ll be able to edit the composed grep
command before
Emacs runs it; so you could change grep
to fgrep
here if you don’t want to use a
Regexp, for example. If you do this, you’ll see that the composed command is
very complex, because Emacs adds a boatload of options to ignore the types of
files you don’t usually want to include in a search (such as Emacs
backup and auto-save files).
lgrep
shares histories for each of the three prompts with rgrep
.
Recursive Grep with M-x rgrep
lgrep
does a flat search of files in one directory, but you can search an entire
directory hierarchy recursively with M-x
rgrep
. It has the same
three prompts as lgrep
and the only difference is it also searches the starting
directory’s subdirectories, and so on, recursively. You can for example search
your entire home directory by entering ~
as the starting directory.
M-x
rzgrep
is a variation that will search gzipped files192.
You can specify them at the “files matching wildcard” prompt with the glob
pattern *.gz
, or be more specific with something like *.org.gz
, or search both
compressed and uncompressed files with multiple space-separated glob patterns
(e.g., *.org *.org.gz
). This command requires that you have zgrep(1)
installed
on your system. Since rzgrep
is a confusing name, you can also invoke it by the
alias zrgrep
.
As for lgrep
, with a prefix argument, you’ll be able to edit the composed grep
command before Emacs runs it.
Just the Skeleton with M-x grep-find
rgrep
composes a complex shell command that uses find(1)
(the Unix directory
hierarchy tool) to run the appropriate grep
command for you. Like lgrep
, the
composed command ignores many files such as backup files. Occasionally you might
not want this assistance; C-u M-x rgrep
will let you edit the command, but it
can be annoying to have to delete most of the over 1,500 characters to customize
it. M-x
grep-find
gives the bare-bones, 57-character version of an
rgrep
command that you can edit to do precisely what you want. Needless to say,
you’ll need to be familiar with the very hairy (but essential) find(1)
command
for this.
Grep Files Aliases
When entering file names or glob patterns at the “files matching wildcard”
prompt for any of lgrep
, rgrep
, or rzgrep
, you can type any of a set of handy
aliases that stand for more or less complex glob patterns. You can customize
the variable grep-files-aliases
to add your own shortcuts.
Alias | Generated Glob Patterns |
all |
* .* |
asm |
*.[sS] |
c |
*.c |
cc |
*.cc *.cxx *.cpp *.C *.CC *.c++ |
cchh |
*.cc *.[ch]xx *.[ch]pp *.[CHh] *.CC *.HH *.[ch]++ |
ch |
*.[ch] |
el |
*.el |
h |
*.h |
hh |
*.hxx *.hpp *.[Hh] *.HH *.h++ |
l |
[Cc]hange[Ll]og* |
m |
[Mm]akefile* |
tex |
*.tex |
texi |
*.texi |
Grepping from Dired
You can enlist Dired’s help when you need to grep a very specific set of files
that can’t be specified by a compact glob pattern. Just mark the files via
Dired’s powerful marking commands, and then invoke
A
(dired-do-find-regexp
).193
Which grep
Is It, Really?
Any compatible program can be used with any of the Grep-family commands instead
of plain old grep
: in particular, you can use egrep
or fgrep
instead. What
exactly makes a compatible command?
For M-x grep
, where you specify the command invocation yourself, any command is compatible
if it produces the standard grep output format, i.e. lines that look like:
FILENAME:LN:text
where FILENAME
is the path to the file containing text
, and LN
is the number of
the matching line. grep(1)
, egrep(1)
, and fgrep(1)
are all capable of producing
this output format.194 Version control systems all support a grep
subcommand and have options to produce a compatible format, like git grep
or
hg grep
; these commands can be invoked via M-x grep
, though there are also
more specific ways to use them via third-party packages like Magit and
Projectile.
Some popular grep replacements like ag
, ripgrep
, ack
, and the like, can be used
as drop-in replacements, but they may be better used via third-party
packages specifically designed for them.
The lgrep
and rgrep
commands also require this output format, but they
additionally make assumptions about the availability of certain command line
options, which is much more complex; to customize which grep
program is used by
these commands, Customize the variable grep-template
.
Regular Expressions
Some people, when confronted with a problem, think “I know, I’ll use regular
expressions.” Now they have two problems. — Jamie Zawinski (comp.lang.emacs)
Regular Expressions (Regexps) have already come up several times in this book.
Much as I’ve tried to avoid mentioning them up to this point, the fact is that
they’re used everywhere in Emacs: in Incremental Search, Query Replace, Grep,
Dired, Apropos, and more.
If you’re a programmer, an apostate from any other programmer’s editor, or just
a Unix user familiar with the standard command line tools, you’ll already be
familiar with the concept, and can skip ahead to see how Emacs Regexps differ
from what you may be used to. If you’re keen to learn and add Regexps to your
tool kit (it’ll be worth it, never mind Zawinski’s cheeky remark), check out the
References at the end of the chapter. But here I’ll try to give an explanation
of what they even are, and the minimum you need to know to make use of some
Emacs Regexp-based commands.
Powerful Pattern Matching
The job of Regexps in Emacs is to enable more powerful searching and matching.
Regexps are a mini-language for expressing patterns that describe, or match, sets
of strings195. When you search for the word “Emacs” with the non-Regexp
C-s
(isearch-forward
), you’re actually using a pattern that
happens to only match exactly one string: “Emacs”. But you’ll recall that, due
to Case Folding, if you search for “emacs”, you’re using a pattern that matches
a larger set of strings, including not just “Emacs” but also “emacs”, “EMACS”,
“eMacS”, etc. Thanks to Lax Space Matching, if you search for “GNU Emacs”,
it will also match strings like “GNU Emacs” or “GNU”, a newline, and
“Emacs” at the beginning of the next line. But that’s about it for the pattern
language of Isearch.
You’re probably familiar with the common notation, or syntax, where a
*
-character or ?
is a wildcard, as in Unix shell file globbing patterns: you
might write *ing
to match files ending in “ing” or c?t
to
match files named “cat” or “cot”. This means that you can’t readily try to match
strings that include asterisks or question marks, because of their
interpretation as wildcards: they are not plain old characters, but what we call
metacharacters, because they’re functioning on a level above the literal.
Regexps are a much more powerful pattern language than that. They were
formalized in 1951 by the mathematician Stephen Kleene and were probably first
implemented in a text editor by Ken Thompson in QED sometime between 1967 and
1970196. From there they appeared in the original Unix editor ed(1)
circa 1973; then, because of their general utility, in other tools like
grep(1)
; and then spread rapidly into every editor that’s worthy of the name;
they were in GNU Emacs from the beginning.
Regexps let you write compact, expressive, patterns that specify matches in
terms of:
- beginnings and endings of lines
- beginnings and endings of words
- sets of characters (e.g. alphanumerics, vowels, whitespace)
- repetitions of Regexps (e.g. zero or more, between 3 and 12)
- grouping of sub-matches with the ability to refer back to them
In order to express these things, our notation needs to have eight
metacharacters; here are the first seven (the Regexp *
and ?
metacharacters do
not have the same meaning they have as glob metacharacters):
. * + ? [ ^ $
In your Regexp you may well need to match one of these metacharacters literally:
you can do this by quoting or escaping the metacharacter with the eighth
metacharacter: the backslash,
. So
*
is the Regexp that
matches an asterisk, and a backslash can be used to quote itself by doubling it.
But don’t use backslash to quote plain, non-metacharacters, like 1
, b
, or w
, for
example, where it may have a special interpretation; see Backslash Constructs below.
Knowing this, you can make use of Emacs commands that ask you to enter a Regexp,
many of which are useful with plain non-meta, characters: just add a backslash
to any of the eight metacharacters that you want to search for literally. Keep
in mind that all characters except the eight metacharacters stand for themselves
in a Regexp, so Emacs
is indeed the Regexp that matches “Emacs” and
*grep*
matches “*grep*”.
Here’s how to translate file globbing patterns into equivalent Regexps:
Glob | Regexp | Interpretation |
---|---|---|
* |
.* |
zero or more of any characters |
? |
. |
any single character |
[a-z] |
[a-z] |
any one of the characters from a to z |
{a,b,c} |
(a❘b❘c) |
either a or b or c |
Note that .
—I’ll call that “dot” for clarity— “matches any character” just
like ?
in file globbing, including punctuation and whitespace, for example.
Other handy Regexps for matching text include b
, which matches a word boundary
i.e. the beginning or the end of a word, and w
, which matches only word
constituents (typically alphanumerics, though it depends on the Major Mode). So
the Regexp to match words that start with an “e” and end with an “s” would be
bew*sb
, which will match “Emacs”, “editors”, “examples”, “es”, and many
others. That regexp translates to: match the strings which
- at a word boundary (
b
) - have an
e
- followed by zero or more word constituents (
w*
) - followed by an
s
- at another word boundary (
b
).
Unique Aspects of Emacs Regexps
If you’re familiar with Regexps from non-Emacs contexts, you probably already
know that there are several distinct Regexp syntaxes out there. Every
application and programming language seems to have its own flavor with subtle
differences from the others: there are the basic Regexps of grep(1)
, the
extended Regexps of egrep(1)
, the heavily enhanced Regexps of perl(1)
and the
PCRE library, and so on.
You’ve probably guessed that I’m going to tell you that Emacs’s Regexps are of
yet another flavor. In the fundamentals, Emacs Regexps are more like grep(1)
Regexps,
in that (
, |
, )
, {
, and }
and are ordinary characters and the backslashified
versions are metacharacters. So in Emacs you do grouping (which captures) with (
and
)
, alternation with |
, and counted repetition with {
and }
,
Emacs supports the non-greedy repetition operators *?
, +?
, and ??
, and the POSIX
character classes (such as [[:blank:]]
).
Emacs’s .
matches any character excepting a newline. To search for a newline,
insert one literally with C-j
(its ASCII value). You can also use the POSIX
space character class ([[:space:]]
) or the whitespace syntax class (s-
), when
appropriate.
Backslash Constructs
Our Regexp notation, like most others, also includes a lot of backslash
constructs, including many that are unique to Emacs, supporting purely Emacs
concepts like the Buffer, Point, syntax classes, character categories, and
symbols.
We have non-capturing (“shy”) groups with (?: ...)
and explicitly-numbered
groups with (?NUM: ...)
. sCODE
matches a character whose
syntax class is CODE
. So,
for example, s-
matches any whitespace character, while sw
matches a
word-character. SCODE
(note the uppercase “S”) matches any character whose
syntax class is NOT CODE
.
The point of s
and S
is that the characters that comprise a given syntax class
can differ from Major Mode to Major Mode197. So the word-class might
include the apostrophe or it might not. Syntax classes let you write Regexps
that work in any Mode. Table 27 lists the class codes.
CODE | Syntax Class |
---|---|
- |
Whitespace characters |
w |
Word constituents |
_ |
Symbol constituents |
. |
Punctuation characters |
( |
Open parenthesis characters |
) |
Close parenthesis characters |
" |
String quotes |
|
Escape-syntax characters |
/ |
Character quotes |
$ |
Paired delimiters |
' |
Expression prefixes |
< |
Comment starters |
> |
Comment enders |
@ |
Inherit standard syntax |
! |
Generic comment delimiters |
Some other unique Regexp metacharacters include `
and '
(that’s backtick and
apostrophe) to match at the beginning and end of the Buffer, respectively, and =
to match at Point. In addition to the common <
and >
to match the beginning
and end of words, we also have _<
and _>
to do the same for symbols.
References
- See “Regexps” in the Emacs manual.
- Friedl, Jeffrey E. F. 2002. Mastering Regular Expressions. Sebastopol, CA: O’Reilly..
Unlimited Undo with Redo
The ability to undo editing changes is fundamental. GNU Emacs had “unlimited”
undo when it was released in 1985, a time when most editors had at most the
ability to undo the single most recent change.
Just Undo It
It’s very simple to just undo the last thing you did — whether inserting,
modifying, or killing some text. Just hit C-/
(undo
), and
your change is undone. Point is always moved the location where the Undo
occurred (which is why people use Undo to move around). After undoing, just
continue with your editing.
If you invoke undo
several times in a row, you’ll see that it keeps undoing back
in time. You can undo all the way back to the first change you made to the
Buffer. If you visit a file, make changes, and then decide you don’t like any
of the editing you’ve done, you can Undo them all away (though this could be
tedious and you’d be better off reverting the Buffer instead). You can Undo
back through file saves, and you can even Undo your Undo’s (see Redo, below).
To make undoing less tedious, Emacs groups long sequences of uninterrupted
insertion into undoable chunks. So if you type “uninterrupted”, and then hit
C-/
, the whole word is undone in one step, rather than requiring 13 invocations
of C-/
, one for each letter. This is called amalgamation and by default the
chunk size is 20, so, if you type
“antidisestablishmentarianism” you’ll have to type two C-/
’s to undo it.
Emacs puts undo
on two additional keystrokes: C-_
and
C-x u
, and of course you could always say M-x undo
. C-_
is the
oldest of these key bindings (and is the one that’s hardwired into my brain),
but C-/
is admittedly easier to type (C-x u
is mnemonic, but highly
unfelicitous).
What, When, and Where Can You Undo?
If you delete a word (“foo”) in Buffer A, then delete a word (“bar”) in Buffer
B, and then, back in Buffer A, you hit C-/
, the word “foo” comes back, even though
the deletion in Buffer B was more recent. If you now change to Buffer B and
Undo, “bar” comes back: each Buffer’s undo history is independent.
Only changes to the contents of a Buffer are undoable. It doesn’t matter what
command caused a change: entering text by typing is undoable but so is any other
command that enters text: yanking from the Kill Ring, inserting the result of
running an external command with C-u
M-!
(shell-command
),
inserting a file with C-x i
(insert-file
): it’s all undoable.
Any command that kills Buffer text is undoable, as is any textual object kill
command like M-DEL
(backward-kill-word
). It makes no
difference if you killed text with a keystroke, a mouse action, or a
M-x
(execute-extended-command
) command.
All commands that modify text are undoable, like
M-t
(transpose-words
) or
C-x C-u
(upcase-region
). A command like
M-%
(query-replace
) that makes mass changes is also undoable.
The scale of any of the above changes has no effect on their undoability. If
you kill the entire Buffer contents with, say,
C-x h
(mark-whole-buffer
) followed by
C-w
(kill-region
), or change the whole Buffer to uppercase with
C-x C-u
198, or insert the contents of a 3-megabyte file, a single Undo will
happily undo the change.
It also doesn’t matter how long ago you made a change; if you made a change to a
Buffer a week ago, and your Emacs has been running all that time, you can still
undo it. However, once you’ve killed a Buffer, its undo history is gone, and
exiting Emacs of course kills all your Buffers.199
How Unlimited is Unlimited?
Actually, there are limits, changeable, to the Undo facility. The defaults are
so big that Undo is effectively unlimited.200
How far back you can Undo is controlled by two User Options; there’s also a hard
limit on the maximum size of any single change (see
undo-outer-limit
). You can Customize all of these. See
“Undo” in the Emacs manual for details.
Undo in the Region (Selective Undo)
The most amazing feature of Undo is that you can limit your Undoing to a subset
of the Buffer. Imagine that you’ve been editing for an hour, and then decide
that you don’t like the changes you made to one paragraph thirty minutes ago —
but you do like all the rest of your changes. It would be awful to have to Undo
everything you’ve done in the last twenty-nine minutes just to restore that one
paragraph.
No problem: all you need to do is set the Active Region around that paragraph
and start Undoing. None of the work you’ve done outside of that paragraph will
be Undone, and Undo will stop if you go all the way back to the first change you
made to that paragraph.
Redo, or Undo the Undos
It’s very easy to overshoot when you’re Undoing. You’re typing at speed, notice
a mistake, and hit a few C-/
’s to correct it. But you hit one too many! You
can’t just immediately type C-/
again: that would just Undo one step further.
What to do?
You just have to stop Undoing. Not for a length of time, but just by issuing
any Emacs command that isn’t undo
. You could invoke
C-f
(forward-char
), a nice harmless command, or
M-x
calendar
, or anything else, but
C-g
(keyboard-quit
) is a perfectly fine way to stop Undoing
(and by now it’s probably wired into your lizard brain as the “oops” command).
So after C-g
just Undo again with C-/
and it does the same thing as always:
undoes the last change to the Buffer, which happens to be your superfluous
Undo. The distinction between Undo and Redo may take a little getting used to,
so play around with it. (If you can’t get used to it, see undo-tree
.)
What Can’t You Undo?
You can’t Undo anything that’s not a change to the contents of a Buffer. So you
can’t Undo changes to the layout of your Windows, like a
C-x 0
(delete-window
) or a
C-x 2
(split-window-below
), or a switch from one window to
another. (But a recommended separate facility allows you to undo those changes.)
You also can’t Undo killing a Buffer, which is another reason Emacs is careful
to ask for confirmation if you try to kill an unsaved file-visiting
Buffer.201
Don’t confuse the contents of the Buffer with how it’s presented: if you
highlight a word with M-s h .
(highlight-symbol-at-point
),
changing it’s color to yellow, that doesn’t change the actual text at all, and
so is not undoable with the Undo facility (of course, you can “undo” the
highlight manually).
You can’t Undo the deletion of a file with M-x
delete-file
or
Dired’s D
(dired-do-delete
) command, or anything else like
that.
Certain Buffers don’t have Undo turned on; any Buffer whose name starts with a
space (see Hidden Buffers) has Undo turned off. You can turn Undo off in any
Buffer if you like, but why would you?
special-mode
Buffers (and Buffers in Modes that inherit from special-mode
),
which are read-only by default and usually implement applications, may or may
not implement Undo.
Finally, you can’t Undo non-Emacs actions that Emacs takes for you, like sending
an email, an instant message, or a tweet!
undo-tree
A fair number of people think that the way Undo works is one of the most
confusing things about Emacs, right up there with the workings of the Kill Ring.
And just like the latter, there are alternatives available (thanks to the
extensible nature of Emacs).
The undo-tree
package is the most popular alternative. Instead of a linear list
of changes that (confusingly?) includes undos, it organizes the undo history as
a branching tree, which makes it easier to understand. The author cheekily
asserts:
The only downside to this more advanced yet simpler undo system is that it was
inspired by Vim. — Toby Cubitt
It’s an impressive package and it can coexist with standard Undo (you can switch
back and forth, or set up separate key bindings) but I find it to be more
intrusive than the default Undo, especially if you turn on its visualizer and
integrated diff (which is what makes it especially easy to understand). See the
screenshot at the Emacs Wiki. Personally, I think with a little practice you
can get completely comfortable with standard Undo. But if you want undo-tree
just add the following snippet to your Init File:
(unless (package-installed-p 'undo-tree) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'undo-tree))) ;; to replace standard Undo everywhere (with-demoted-errors "%s" (global-undo-tree-mode))
Approaching Programming: Keyboard Macros
I believe I can state without the slightest hint of exaggeration that Emacs
keyboard macros are the coolest thing in the entire universe. — Steve Yegge
Thanks to its nature as a Lisp Machine, Emacs is probably the most completely
customizable and extensible piece of software in existence. Emacs is written in
Emacs Lisp (Elisp) running in a Lisp interpreter that you can modify in real
time, as it runs, to change almost anything, and any brand new code you write
can run immediately, and interact with all the rest of Emacs itself.
This is fantastic and amazingly powerful. The only problem is, you need to be
an Elisp programmer to do it! We’ll address the goal of becoming an Elisp
programmer in in Programming the Lisp Machine, but in this chapter, we’ll talk
about how you can do some programming with no Elisp skills.
Nothing is more tedious than manually making repetitious mass edits to a file or
files. M-x
query-replace
and especially
M-x
query-replace-regexp
can handle relatively simple cases,
especially if coupled with any of the Greps and Writable Grep, or Writable
Occur; Dired’s Q
(dired-do-find-regexp-and-replace
) command
is also available, and the Xref facility can do mass renames of identifiers in
your program source code.202
But some mass edits are too complicated for any of those solutions.
A Keyboard Macro (hereafter, a
Macro) is a shorthand way of re-executing a longer sequence of commands. A
function in a programming language (like Elisp) can be thought of in exactly the
same terms, but to write one you have to compose the function in a Buffer, and
evaluate it (assuming you know the syntax and semantics of the language).
Instead, a Macro is quickly defined at the point where it’s needed: you tell
Emacs to start recording, embark on a sequence of commands (key strokes) to
perform one instance of your task, and then stop recording. Now you can
immediately re-run those steps, whether once or twice or by telling Emacs to run
the Macro as many times as it takes to do all the repetitions. Then you just
forget about it.
Or instead, you might re-run the macro hours (or days) later, assuming you
haven’t exited Emacs, and if the Macro has turned out to be generally useful,
you can save it for future sessions, optionally giving it a name and possibly
binding it to a key. You can have several anonymous Macros defined in your
session and switch between them, and you can edit any of them to fix a bug or
make an enhancement.
Note that Macros are defined globally and are not Buffer-local. You can define
a Macro in one Buffer, and then switch to a different Buffer to execute it.
Your First Macro
Suppose you have a list of author names in inverted form and want to change them
all to a different format:
Brackett, Leigh Durrell, Gerald O'Brian, Patrick Ambler, Eric Fleming, Fergus Mundy, Talbot
Instead of “Brackett, Leigh” you want “Leigh BRACKETT”, and so on.
In order to make these changes with a Macro, you just have to do the first one
while recording, and then all rest can be done automatically.
Here’s my algorithm. I have to start by positioning Point at the beginning of
the list. Now I perform these steps:203
-
M-u
(upcase-word
) - giving “BRACKETT”
-
C-d
(delete-char
) - eliminating the comma
-
M-t
(transpose-words
) - flip the two parts
-
C-f
(forward-char
) - move to the beginning of the next line
To turn this algorithm into a Macro and apply it, you only need to learn three
things:
- how to start recording,
- how to stop recording, and
- how to invoke the Macro you just defined.
You start recording with C-x (
; you’ll
see the message “Defining kbd macro…” in the Echo Area and the indicator “Def”
will light-up in the Mode Line until you’re done. Now you perform the actions
that comprise your Macro, any sequence of commands of any length; now you’ve done
the first of presumably many repetitions of your task.
You stop recording with C-x )
; you’ll see
“Keyboard macro defined” and the “Def” indicator will go away.
Now you can invoke the macro with
C-x e
(kmacro-end-and-call-macro
): it re-executes your
sequence of commands. Since we ended the Macro by moving to the beginning of
the next line, we’re ready to invoke it immediately without having to move into
position. We’ll call C-x e
five more times, and the result will be:
Leigh BRACKETT Gerald DURRELL Patrick O'BRIAN Eric AMBLER Fergus FLEMING Talbot MUNDY
Repeating a Macro
Perhaps you noticed this message in the Echo Area after your first C-x e
:
(Type e to repeat macro)
After any C-x e
you can immediately rerun the Macro by just typing e
.
You can also have Emacs repeat the Macro for you. You can give C-x e
a numeric
argument, and Emacs will repeat it that many times. Occasionally it’s obvious
how many times you need to invoke a Macro, but it’s much more common that you
just know you need to invoke the Macro a lot. It’s very common to want to
reapply the Macro as many times as possible, all the way to the end of the
Buffer.
You can auto-repeat the Macro by giving C-x e
a numeric argument of zero
(standing for infinity) as in C-u 0 C-x e
. The Macro will just repeat over
and over until it gets an error (which will usually happen at the end of the
Buffer) or until interrupted with C-g
(keyboard-quit
).
If you want to apply a Macro to a big chunk of text, but not the whole Buffer,
just Narrow the Buffer with C-x n n
, go to the beginning of the
narrowed region and invoke the Macro infinity times. When it beeps,
having hit the end of the (narrowed) Buffer, you’re done, and you can widen it
again with C-x n w
.
It is possible to define a Macro that loops infinitely! A simple example is:
C-x ( foo C-x )
In other words, a Macro that just inserts “foo”. If you C-u 0 C-x e
this Macro,
it will just insert “foo ” forever, until you fill up all of memory and maybe
crash your Emacs — welcome to Computer Programming! Best only to use C-u 0
with a Macro that can fail (like a Macro that includes a search).
Aborting a Macro Definition
If you need to abort the definition of your Macro, perhaps because you realize
your algorithm isn’t exactly right, all you need to do is hit
C-g
(keyboard-quit
). This terminates the Macro definition
mode and discards all the steps you just recorded. It does not undo all the
commands you invoked however, so if you want to start your definition over from
scratch, you’ll have to Undo. If you want to pick up your aborted Macro
definition and fix it without having to redo the whole thing, see
C-x C-k l
(kmacro-edit-lossage
) below in Editing Your Macro.
Line-by-Line Macros
Many Macros, like our example, are intended to be applied to a line at a time;
that’s why we used C-f
at the end, to advance to the beginning of the next
line. But there’s a special command to simplify both the definition and
execution of this kind of Macro.
You just define your Macro, starting at the beginning of the first line, without
worrying about ending up at the beginning of the next line; then, definition
finished, you set the Region around any sequence of target lines, and invoke
C-x C-k r
(apply-macro-to-region-lines
). This invokes your
Macro exactly once on each line of the Region; it automatically positions Point
at the beginning of each line before each repetition. So with C-x C-k r
our
Macro could be as simple as M-u C-d M-t
.
What Happens If You Make a Mistake?
As you’re defining, if any command you invoke raises an error, the definition
will be aborted. The steps that comprise your Macro have to be error-free. By
far the most common such error must be searching for some text that doesn’t
actually exist.
Searches are a very common part of many Macros; often you use a search to get to
the next place in the Buffer that you want to change. The natural effect of
this is to terminate automatic repetitions of your Macro when there are no more
matches, so that kind of error is not only okay, but a key part of Macro
design. But often you’ll discover that your search is perhaps too specific and
the resulting error will blow up your Macro early; you’ll just have to come up
with a better search.
Remember that Undoing is just another Emacs command, so you if make a
non-error-raising mistake while defining, you might be able to just Undo it
rather than starting over! In our example above, what if instead of upcasing
the name I accidentally downcased it? Instead of aborting and starting over I
could just immediately Undo and then do the upcasing I intended. The Macro would
now be: M-l C-/ M-u C-d M-t C-f
, which is, I suppose, less efficient, but it
will work just as well.
Speaking of mistakes, while you can (technically) use the mouse in defining a
Macro, I think it’s a bad idea. The mouse is a very complex device, its effect
depending on exactly where the mouse cursor is at the moment, so replaying mouse
events is very unreliable.
Minibuffer Prompts
If in defining your Macro you invoke a command that prompts you for input via
the Minibuffer, then when the Macro is run, you will not be prompted again: the
command will use the same text you entered during definition. This is usually
what you want. For example, suppose your Macro is gathering text from the
current Buffer and saving it in another Buffer via
M-x
append-to-buffer
, which prompts you for the name of the other
Buffer: if you need to run that Macro a hundred times, you don’t want to have to
retype the Buffer name each time!
Because of this behavior, it’s also common to just define a Macro that invokes a
single M-x
command that you are about to use several times; defining:
C-x ( M-x append-to-buffer RET stuff RET C-x )
means you can just say C-x e
to gather some text, rather than the long-winded
M-x append-to-buffer
plus at least a M-p
to pull up the Buffer name you’re using.
There’s one thing to keep in mind though: in entering something like a Buffer
name, you should be conservative in exploiting the conveniences of your
Completion framework! In normal Emacsing, you might enter a Buffer name by
typing only a few letters and hitting return when Completion presents the right
name. If you do this in a Macro definition, the next time you run the Macro you
might get a different, unintended, Buffer name! This is most likely to happen
with a Macro that you run intermittently throughout a sesssion: perhaps your
Completion framework offers up matching Buffer names in a different order
depending on how recently you used them. It’s good Macro practice to type out
the whole name explicitly in this scenario.
The Keyboard Macro Map
Keystrokes | Category | Action |
---|---|---|
C-x ( |
Define | start defining a Macro |
C-x C-k s |
… the same | |
C-x C-k C-s |
… the same | |
|
… the same | |
C-x ) |
end Macro definition | |
|
… the same (if defining) | |
C-x e |
Execute | Execute latest Macro |
|
… the same (if not currently defining) | |
C-u |
execute latest Macro and append new commands | |
C-x C-k r |
apply Macro line-by-line in Region | |
C-x C-k C-n |
Ring | make earlier Macro the current Macro |
C-x C-k C-p |
… reverse direction | |
C-x C-k C-d |
Delete the current Macro from the Ring | |
C-x C-k C-v |
View current Macro definition | |
C-x q |
Query | Query the user |
C-x C-k q |
… the same | |
|
Count | Insert Macro counter value at Point |
C-x C-k C-i |
… the same | |
C-x C-k C-c |
set the Counter’s value | |
C-x C-k C-f |
define the counter’s Format | |
C-x C-k C-e |
Edit | Edit the current Macro definition |
C-x C-k RET |
… the same | |
C-x C-k e |
Edit a Macro by its name or binding | |
C-x C-k l |
turn the Last few commands into a Macro | |
C-x C-k SPC |
edit (debug) the current Macro step-by-step | |
C-x C-k b |
Bind | kmacro-bind-to-key |
C-x C-k n |
kmacro-name-last-macro | |
C-x C-k x |
kmacro-to-register |
There’s a whole family of Macro commands on the C-x C-k
prefix, and a few other
handy key bindings as well. In Table 28 I’ve gathered
them in several groups. Let’s take a look.
Macro Definition Commands
Instead of the C-x (
and C-x )
commands I’ve been using above, you should
probably use the quicker and cleverer
and
.204 These two commands
are context-sensitive.
begins a Macro definition just like C-x (
and
terminates a Macro definition just like C-x )
, but if you’re not in the middle of
defining a Macro,
instead executes the Macro like C-x e
does, and since
it’s a single keystroke, you can felicitously re-invoke it several times in row;
hence, it doesn’t need the “(Type e to repeat macro)” trick. So with these
keys, whipping up and executing a Macro is as simple as:
defining commands
.
If you give
a C-u
prefix i.e. C-u
, it allows you to extend the
definition of your current Macro: it executes the Macro once but then reenters
definition mode, allowing you to add more commands to the end of definition.
Terminate this extension with
as usual and the next time you execute it, your
added commands will be included.
This is a simple way of editing your Macro (for more elaborate editing see
Editing Your Macro below).
You can also think of it as allowing incremental definition: define your Macro
in stages. Going back to our author-name-reformatting Macro above, we could
have defined as before:
- start defining
M-u
- upcase last name
C-d
- delete comma
M-t
- transpose words
- done!
But now after trying it a couple times, we might decide that we really want to
add a “bullet” at the beginning of the line, so we can extend the definition:
C-u
- append commands to Macro definition
C-a
- go to beginning of line
+ SPC
- add a “bullet”205
- done!
Now our remaining author names will come out like this:
+ Lynda BARRY + Ian FLEMING
The Macro Ring
You can have any number of Macros defined simultaneously.206 They are
stored in a typical Emacs ring structure, so if you define a second Macro in
your session, it’s pushed onto the front of the Macro Ring, eclipsing your
previous definition. From now on, all Macro invocations via
and friends
execute the new one.
Unless you rotate the Macro Ring of course! To execute your previous Macro, do
C-x C-k C-n
(kmacro-cycle-ring-next
).207 The previous Macro’s
definition will be shown in the Echo Area; it’s a mite cryptic, but you should
be able to recognize it since you defined it recently! Here’s our extended
author-name-reformatting Macro appears:
Macro: M-u C-d SPC M-t C-a + SPC
Repeating C-x C-k C-n
will cycle around the Ring; just stop when you’ve found
the Macro you want and now
will execute that one instead, and keep
executing that one until you rotate again or define a newer one.
If you overshoot in your cycling,
C-x C-k C-p
(kmacro-cycle-ring-previous
) will reverse
direction. You can quickly delete the current Macro with
C-x C-k C-d
(kmacro-delete-ring-head
), and there are a few
more Macro Ring commands and a mechanism for shorthand keystrokes, but these are
for real professionals: I’ve never had a complex-enough set of Macros to have
needed them; see “Keyboard Macro Ring” in the Emacs manual.
You can review the Macros in the Ring with
C-x C-k C-v
(kmacro-view-macro-repeat
); it displays the
definition in the Echo Area without actually rotating the Ring; an immediate C-v
cycles to show the next. While you’re cycling, you can execute the
currently-displayed Macro by immediately typing C-k
, without having rotated it
to the front of the Ring.208
If you really need to use several different Macros at a time, you might find it
easier to just bind them explicitly to keys, or give them names; see Naming and
Binding Your Macros.
Macro Query
Keyboard Macros really are a programming language, but they do seem like they’re
not a Turing Complete one, since they’re lacking the necessary conditional
statement.209 However, the handy C-x q
(kbd-macro-query
)
command directly supports a limited amount of conditional or dynamic action
within your Macro.
The most basic function of C-x q
is to stop at a certain point and ask you if
you want to continue with the Macro. Suppose we’re about to define our
author-name-reformatting Macro, but we know in advance that we only want to
apply it to some of the lines in the Region. We could just live with not being
able to run it over the whole Buffer automatically (via
C-x C-k r
(apply-macro-to-region-lines
)) and invoke it
manually one line at a time. But we could instead begin the Macro with C-x q
i.e. C-x q M-u C-d M-t
.
Each time we run the Macro, C-x q
will ask in the Minibuffer:
Proceed with macro? (Y, N, RET, C-l, C-r)
and wait for a response, which can be any of the following:
Key | Action |
---|---|
Y |
Finish this iteration normally and continue with the next. |
N |
Skip the rest of this iteration, and start the next. |
RET |
Stop the macro entirely right now. |
C-l |
Redisplay the screen, then ask again. |
C-r |
Enter recursive edit; ask again when you exit from that. |
If we’re running the Macro with C-x C-k r
, We can respond Y
on the lines where
we want to apply the Macro, and N
where we don’t.
Most powerful is that we can enter a Recursive Edit, which would allow us to
make a local, manual, tweak in each execution.
Macro Counters
Every Macro has its own counter which you can use to number things while it
executes. Perhaps instead of a bullet list of reformatted authors, we want to
make a numbered list. All we need to do is use C-x C-k C-i
(or
, which is
equivalent when you’re already defining) at the appropriate spot in our
definition: C-x C-k C-i . SPC M-u C-d M-t
. Now when we run our Macro with C-x
the result is:
C-k r
0. Gerald DURRELL 1. Patrick O'BRIAN 2. Eric AMBLER 3. Fergus FLEMING 4. Talbot MUNDY
If you move around or do other things and then
your Macro again, it will
continue with number 5. You can reset the count with
C-x C-k C-c
(kmacro-set-counter
).210
I’m sure you’ve noticed that the Macro Counter starts at zero… That’s because
programmers count from zero. If you’re not a programmer, or you’re a programmer
who wants to act like a normal human at this moment, just set the Counter to 1
before you invoke the Macro for the first time: C-u 1 C-x C-k C-c
.
In addition to its Counter, each Macro also has it’s own Counter Format. You
can change it by calling C-x C-k C-f
(kmacro-set-format
) at
the beginning of your definition.211 This allows you to get leading zeros
or spaces for a fixed-width number column:
0013. Eric AMBLER
or even number your list in hexadecimal. If you’re a programmer, you’ll have
guessed that this uses a printf
format string; see
“Formatting Strings” in the Elisp manual.
Editing Your Macro
In the old days, it was inevitable that after (or during) the definition of an
elaborate Macro, you would discover a mistake; there was nothing to do but start
over from scratch. But we 21st century Emacsers have
C-x C-k C-e
(kmacro-edit-macro-repeat
) and can edit our
definition to correct it, or further enhance a working Macro.
We’ve seen C-u
, but that’s just a poor man’s approximation212 that
only allows you to append new commands to the end. C-x C-k C-e
pops up a
special Buffer *Edit Macro*
that displays the definition line-by-line with
explanatory comments, and you can delete steps, rearrange them, and add new commands
at will. Let’s edit our author-name-reformatting Macro. C-x C-k C-e
edits the
current Macro (at the front of the Ring), so if the one you want to edit isn’t
there, rotate the Ring appropriately,
;; Keyboard Macro Editor. Press C-c C-c to finish; press C-x k RET to cancel. ;; Original keys: C-x C-k C-i . SPC M-u C-d M-t Command: last-kbd-macro Key: none Macro: C-x C-k C-i ;; kmacro-start-macro-or-insert-counter . ;; self-insert-command SPC ;; self-insert-command M-u ;; upcase-word C-d ;; delete-char M-t ;; transpose-words
Note that there are several Elisp comments in this Buffer: everything from a
semicolon to the end of the line is a comment. These comments are insignificant
to your Macro editing; nothing you might change in a comment here (including
deleting it entirely) has any effect. In general, differences in whitespace are
also insignificant.
The defining parts of the Buffer are the non-whitespace characters following the
word Macro:
(and ignoring the comments). Each command in the definition
consists of the keystrokes used to invoke it, spelled the way Emacs spells them
when you use C-h c
(describe-key-briefly
) (which is the way
you see these keys spelled throughout this book). So SPC
for the Space key, RET
for Return, etc. Remember, amounts of whitespace (including line breaks) make no
difference: the definition could be all on one line like:
C-x C-k C-i . SPC M-u C-d M-t
the three keystrokes C-x C-k C-i
could be split across three lines, etc.
If you repeat a command several times in a row, you might see this format:
4*M-u ;; upcase-word
which means you typed four M-u
’s here; you can use this notation yourself.
Suppose you want to change your Macro to merely capitalize the author’s last
name instead of uppercasing all of it. Just change M-u
to
M-c
(capitalize-word
) and hit C-c C-c
to save your change.
Simple as that: now instead of “Eric AMBLER” you’ll get “Eric Ambler”.
Note that the Original keys
section at top preserves the original definition in
a comment; you can grab bits of it if needed. Additionally, the *Edit Macro*
Buffer is a Buffer like any other you might edit, so of course you can use Undo
within it. But if you do mess up or change your mind, you can always just bury
or kill the Buffer and your Macro remains unchanged.
If you’ve named or bound your Macro to a key (see below), you can edit it with
C-x C-k e
(edit-kbd-macro
). And you can also turn a sequence
of editing commands you just happened to type into a Macro after the fact with
C-x C-k l
(kmacro-edit-lossage
), which pops up an *Edit
Buffer loaded with the last 300 keystrokes you typed (you’ll almost
Macro*
certainly delete a lot of them).
Debugging Your Macro
Real programming languages have interactive debuggers to help you find bugs in
your programs213, typically by single-stepping through the code: that is,
running the program one instruction at a time so you can see the effect of each
one clearly and incrementally.
Surprisingly, Emacs also has a debugger for Macros!214 Position yourself
for the execution of your Macro but instead of
or C-x e
, run it with
C-x C-k SPC
(kmacro-step-edit-macro
), Emacs will pop up a
small Window showing the definition of your Macro, and give you a prompt. If
you type SPC
at the prompt, it will execute the first command of your Macro —
you’ll see the effect in the original Buffer — and prompt you again. If you
type SPC
for every command in the definition, you will have executed the Macro
just as if you had typed
: only much more slowly!
This slow stepwise execution can reveal to you a bug in your Macro, which you
could then fix with the Macro editor (C-x C-k e
). But at each step, you can
instead skip the current command, or insert a new series of commands before or
after it: any such changes you make are saved and become part of the Macro’s
definition, so this is also a more interactive and perhaps intuitive way of
editing your Macro. See “Keyboard Macro Step-Edit” in the Emacs manual for
detailed instructions.
Naming and Binding Your Macros
If the Macro Ring seems a little too ascetic to you, you can easily bind your
latest Macro to a key with C-x C-k b
(kmacro-bind-to-key
).
This cautious command will prompt you for a keystroke; if you choose one that’s
already in use, it will ask you if you’re sure you want to replace that binding
with your Macro.
Since there are something between 200 and 1,000 active key bindings in a typical
Emacs, you might have trouble coming up with an unused keystroke! As a
convenience, if you type any of the digits 0-9 or the capital letters A-Z, your
Macro will be bound to that key in the C-x C-k
keymap. So if you type C-x C-k b
and repond Q
, your Macro will be bound to C-x C-k Q
.
With C-x C-k n
(kmacro-name-last-macro
) you can instead, or
also, give your Macro a long name that you can use with
M-x
(execute-extended-command
).
Both of these binding commands only last until the end of this Emacs session.
If you want to save your Macro permanently, pull up your Init File, jump to the
end of it, and invoke M-x
insert-kbd-macro
; this command will prompt
for the name of your Macro215 and convert it to Elisp, which it will insert
into the current Buffer at Point. It might look a little cryptic; here’s one
possible form for our author-name-reformatting Macro:
(fset 'reformat-author-name
(kmacro-lambda-form [escape ?u ?C-d escape ?t] 0 "%d"))
If you gave your Macro a key binding as well as a name, you can use
C-u M-x insert-kbd-macro
instead, which will also save your key binding:
(fset 'reformat-author-name
(kmacro-lambda-form [escape ?u ?C-d escape ?t] 0 "%d"))
(global-set-key [24 11 81] 'reformat-author-name)
With this code in your Init File, your Macro will be available every time you
begin an Emacs session.
A Musical Example
Let’s finish up with one more example. I play the ukulele and guitar and have
hundreds of files of lead sheets. I usually write them out in this format:
song lyrics with the chords written above the lines, like so:216
A D A7 Gbdim And she said, "By the time that you open your eyes G D7 G There will not be a shoulder in sight."
This is convenient for editing, but when I’m done with a song, I want to convert
it into the de facto standard ChordPro format (which is harder to edit):
And she [A]said, "By the [D]time that you [A7]open your [Gbdim]eyes There will [G]not be a [D7]shoulder in [G]sight."
Obviously converting from the former to the latter calls for a Macro;
here’s the one I whipped up:
C-e ;; move-end-of-line M- ;; delete-horizontal-space C-u - ;; self-insert-command M-C-k ;; kill-sexp C-n ;; next-line [ ;; self-insert-command C-y ;; yank ] ;; self-insert-command C-p ;; previous-line
After using this for a while, I made some tweaks to it; then I turned it into an
Elisp function to make it more robust; and ultimately it grew into a Major Mode
for editing ChordPro files.
The Customize Facility
The simplest kind of Emacs customization is to change the value of any of the
2,910 User Options or Faces. While an Elisp
programmer might choose to do this via an Elisp expression in the Init File,
it’s very easy for the non-programmer to do via the interactive Customize
facility, which presents the variable’s default value, its current value, its
legal possible values, its documentation, links to related variables, and an easy
interactive way to modify the value.
One of the big advantages of Customize over customization via Elisp, even for
experienced Elisp programmers, is the amount of bookkeeping that Customize does
for you. It keeps track of what you’ve customized, allowing you to restore or
further tweak the value of something you changed and now regret.
Entry Points
The entry points to the Customize facility range from customizing one single
Variable or Face, up to high-level browsing of everything customizable;
Table 29 summarizes most of them.
M-x customize-variable |
Customize a single named User Option |
M-x customize-variable-other-window |
… in the other Window |
M-x customize-face |
Customize a single named Face |
M-x customize-face-other-window |
… in the other Window |
M-x customize-mode |
Customize all Variables related to a major or minor mode |
M-x customize-group |
Customize GROUP, which must be a customization group |
M-x customize-group-other-window |
… in the other window |
M-x customize |
Customize anything or everything |
M-x customize-browse |
… same, via a tree-structured interface |
M-x customize-apropos-options |
Customize all loaded Options matching a REGEXP |
M-x customize-apropos-faces |
Customize all loaded Faces matching a REGEXP |
M-x customize-apropos-groups |
Customize all loaded groups matching a REGEXP |
M-x customize-apropos |
Customize loaded Options, Faces and groups matching a PATTERN |
(customize-variable
also goes by the name customize-option
, and
customize-variable-other-window
is also known as customize-option-other-window
.)
To aid browsing and navigation, customization Variables are organized in groups;
often each Emacs package in the Package Manager defines its own group, but there
are also broader groups defined. M-x
customize-group
let’s you see
all the Variables and Faces for such a group; M-x customize-group RET isearch
will
show you everything you can change about Incremental Search, for example: around
40 Options
.
While you can discover the Customization groups via Completion on
M-x
customize-group
, if exploration is your goal you can use
M-x
customize
and navigate through all the groups and subgroups in a
leisurely manner.
You can also enter the facility via Apropos. Suppose you want to tweak the
options relating to how sentences are recognized, but you don’t know the name of
the appropriate group. M-x
customize-apropos
with the keyword
“sentence” will bring up five pertinent Variables.
Experiment Without Fear
You don’t have to worry very much about entering the Customize facility and
messing things up. All the changes you make happen in three steps: first
editing a value, then setting it (which causes it to take effect in this
session), and finally saving the change for future sessions. You can feel free
to edit a value just to see what it looks like: doing so won’t have any effect
unless you also set it. If you’ve edited a value and it looks undesirable to
you, you don’t even have to restore it if you haven’t set it yet. You can
simply kill the Buffer, or bury it and never come back; it will be as if you
were never there. And if you have set it, Customize remembers the previous
value and makes it easy to restore it. It’s even easy to find changes you’ve
saved for all future sessions and restore them, if it turns out you don’t like
something you’ve done.
Changing the Value of a Variable
Depending on which entry point you’ve chosen, the Customize Buffer will have one
or possibly many Variables or Faces you can change.
Let’s consider doing M-x customize-variable RET list-command-history-max
(see
The Minibuffer). In the Customize Buffer, we’ll see something like:
List Command History Max: [Value Menu] Integer: 32 [State] : STANDARD. If non-nil, maximum length of the listing produced by ‘list-command-history’.
We can see the name of the Variable217, its current value (here 32), its
customization state (here “STANDARD”), and its documentation.
You can change the value by editing the current value in the Buffer (just change
the 32 to something else) or by clicking218 the “Value Menu” button.
Some Variables are simple and only accept a single sort of value (say, a number
or a string), but others have more complex possibilities, and the Value button
gives you a way of unambiguously entering them: Boolean variables can toggled on
or off, for example, and it’s very common for Variables to allow an out-of-band
nil option that can be interpreted in a variety of ways (described in the
Variables’s documentation).
It’s also very common for a Variable to take a complex value, like a list of
things; in this case, there will be additional buttons to add or delete
individual elements of the list. See
“Changing a Variable” in the Emacs manual for complete details.
When you change the value, whether by clicking or editing, the State button will
change from “STANDARD” to “EDITED”. To actually apply your edit you need to set
the value. Click on the State button and you’ll see a menu of options:
Set for Current Session |
Save for Future Sessions |
Undo Edits |
Revert This Session’s Customization |
Erase Customization |
Add Comment |
The first two should be self-explanatory; “Undo Edits” restores this Variable to
the value it had when you entered the customization Buffer; “Revert” restores
the value to the last saved value (or restores the default Emacs value if you’ve
never saved it), and “Erase” restores the standard value (what the Option would
be if you started up an uncustomized Emacs). “Add Comment” let’s
you document your changes and saves a comment that will be displayed along with
this value in future Customize sessions.
Customizing Multiple Options
While customize-variable
and customize-face
present one value at a time, most of
the other Customize entry points let you view and change multiple values in one
go. So each Customize Buffer has three extra buttons at the top:
Operate on all settings in this buffer: [Revert...] [Apply] [Apply and Save]
These buttons let you finish up multiple edits in one stroke: “Apply” will set
all the Variables in this Buffer whose values you’ve changed; “Apply and Save”
also saves them for future sessions; and “Revert” will undo any sets you’ve done.
Customizing a Face
Customizing a Face is much the same as customizing a Variable; it’s mostly just
a little more colorful.
Let’s say you don’t like the look of string literals in your favorite
programming language. Just pull up a file, position Point on one of the
offending strings, and say M-x
customize-face
. The prompt will look
something like:
Customize face (default ‘font-lock-string-face’):
(The default Face is that of the character where point is.) Hit return and
you’ll be given a Customize form:
(This Face only defines a “Foreground” color so the other attributes aren’t
shown; click Show All Attributes
to change others.) If you click on the
“Choose” button, the colorful *Colors*
Buffer will pop up; browse it, and click
the color you like (you can instead just type a color name219 or RGB triplet
#RRGGBB
into the form where it says “LightSalmon”220).
Note that if you customize a Face this way starting from, say, a python-mode
Buffer, it will affect all Modes and Buffers that use this exact, named, Face.
A given Major Mode may define its own Faces, but font-lock-string-face
is a
standard Emacs Face and is used by many, perhaps most, Major Modes for
syntax-highlighting string literals. The good news is, if you hate that Face in
one Mode you probably hate it everywhere, so a sweeping change is appropriate! But if
you only hate it for strings in python-mode
, you’ll have to get fancier to only
change it there — I won’t go into this here, but such is the power of Emacs
that this is completely doable.
Customize Buffers Are Non-Modal
Like almost all of Emacs, Customize Buffers are not modal. That is, when
you fire up a Customize Buffer, you don’t have to commit to finishing the
job right now. Take your time. The Buffer keeps track of your state. You can
set one or more new values without saving them. This allows you to spend some
time seeing how you like the changes you made. If you like them, you can just
switch back to this Buffer later and then click “Apply and Save” (bound to
C-x C-s
in Customize Buffers). If you kill the Buffer after
“Apply” but later (in the same session) reinvoke Customize with the same
Variable or Face, you’ll see that Emacs has remembered your changes, and you can
now save them, revert them, or make further changes.
If you’re really casual about your customizations, you might forget to save the
ones you set for future sessions. I recommend this setting for your Init File,
which causes Emacs to check with you when you exit—you’ll be able to pull up a
special Customize Buffer that contains all the values you’ve set but haven’t yet
saved, and you can take care of it.
(add-hook 'kill-emacs-query-functions 'custom-prompt-customize-unsaved-options)
Long-Term Customization Management
There are some convenient commands for the long-term management of your
customizations. M-x
customize-unsaved
(also known as
M-x
customize-customized
) will pull up a Customize Buffer that
pulls together all the customizations you’ve made in this session but haven’t
yet saved, which makes it easy to review, possibly change, and then save them
all.
From an even longer-term perspective, M-x
customize-saved
will give
you a Customize Buffer containing all the customizations you’ve ever saved,
across all sessions; this is very handy if, after a month or so, you figure out
you’re unhappy with something you’ve changed, and want to undo or tweak it.
While we’re thinking in the long term… GNU Emacs has been around for
38 years already, and I’m confident that it will
be around for many more years to come; there have been 2.5 new Emacs releases
every year, on average. That means it won’t be long before your OS package manager
presents you with a fresh new Emacs in which some User Options will inevitably
have been changed. M-x
customize-changed
(a.k.a
M-x
customize-changed-options
) will present a Customize Buffer
containing all these changed variables for you to consider.
Finally, if, like me, you’ve changed some User Options directly via Elisp in
your Init File, M-x
customize-rogue
will let you see all of these in
a Customize Buffer.
Where Are Customizations Saved?
The Customize Facility saves your customizations at the end of your Init File in
two sections, one for User Options that looks like this:
(custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. ...)
and one for Faces:
(custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. ...)
As the warning indicates, you should avoid editing these special sections. If
you notice something there that you want to fix, do it via M-x
customize-saved
.
It’s also possible to tell Emacs to store these Customization sections in a
different file entirely; this is only necessary if you’re doing something fancy
with your Init File, like generating it programmatically for example.
Customizing Key Bindings
The one thing the Customize Facility doesn’t support is customizing your own key
bindings; you have to do that in Elisp; see Modifying Key
Bindings.
The Package Manager
Emacs organizes most of its 20,692 commands and functions into
474 libraries: groups of functions
related by purpose. When brand new functionality is added, as opposed to
existing functionality being merely enhanced, the new code is organized as a new
library; the libraries comprise 1,505 files of Emacs Lisp
source code that are shipped together with Emacs.
Rather than Emacs just forever acquiring more and more new functions, and
getting bigger and bigger all the time (which certainly still happens to some
extent), this scheme allows major chunks of code that perhaps not everybody
wants to use to be loaded into memory in a lazy fashion. If you’re not going to
be printing to a Postscript printer today, why bother loading the 226K ps-print
library? This lazy approach is called autoloading; you’ll see the
word when looking at the documentation for commands and functions via the Help
facility, as in:
ps-print-buffer is an autoloaded interactive Lisp function in ‘ps-print.el’.
Autoloading also speeds up start-up.
The next step up from library is package. A package is effectively a
library—that is, Elisp source files—together with data files, Info
documentation, and metadata (in the form of author information, a package
description, a version number, and typically a list of dependencies: other
packages that this package itself uses).
You can think of packages as plug-ins: software that adds new functionality to
Emacs. You can install and uninstall them in real-time, as you use Emacs,
without having to quit and restart.
Thanks to packages, third parties can write their own libraries and easily
contribute them to collections of packages (called repositories or repos), and
thanks to the metadata, these repositories are also searchable. The Free
Software Foundation maintains two repositories of contributed packages (called
GNU- and NonGNU-ELPA221), and there are two major community-maintained
repositories (MELPA and Marmalade), and probably more that I don’t know about.
I recommend the GNU and NonGNU repositories, with 583
packages between them, and MELPA with 5,374, but I don’t
recommend Marmalade; it moves at a more aggressive pace and when I used to use
it, packages could get updated several times a day and any one of those updates
might be (briefly) buggy. But your mileage may vary!
Configuration
Recent versions of Emacs come with the GNU and NonGNU ELPA repositories configured and ready
to use. This Init File snippet adds the MELPA repo as well, and also
assigns repo priorities that put a premium on stability (so, if a package
appears in both the carefully curated GNU repo and in MELPA, we prefer the GNU
version, all else being equal; you can change this if you prefer to live on the
bleeding edge).
(when (< emacs-major-version 24) ;; For important compatibility libraries like cl-lib (add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))) (when (version< emacs-version "26.3") ;; older emacsen < 26.3 may need this (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")) (with-eval-after-load 'package (dolist (arc '(("nongnu" . "https://elpa.nongnu.org/nongnu/") ("melpa-stable" . "https://stable.melpa.org/packages/") ("melpa" . "https://melpa.org/packages/"))) (add-to-list 'package-archives arc t)) (setq package-archive-priorities '(("gnu" . 10) ("nongnu" . 9) ("melpa-stable" . 8) ("melpa" . 7))))
Note that the MELPA repo comes in two flavors: the stable repo and the unstable
repo. I give the stable repo a higher priority than the unstable via the
package-archive-priorities
variable.
About Packages
How do you find out about these exciting additional packages? I mention several in
this book, and you can find out about many more by following various Emacs
mailing lists, blogs, and web forums. But mostly you find them by searching and
browsing in Emacs.
If you’ve got the name of a package to hand, perhaps Vertico, you can read it’s
description via C-h P
(describe-package
). This will pop up a
*Help*
Buffer showing at least the package metadata, like this:
Package vertico is available. Status: Available from gnu -- Install Archive: gnu Version: 0.20 Commit: 1bd5438da9c661e2df5e9516f36d9cbc6d100a34 Summary: VERTical Interactive COmpletion Requires: emacs-27.1 Homepage: https://github.com/minad/vertico Maintainer: Daniel MendlerAuthor: Daniel Mendler
The description may include extra text; the Vertico *Help*
Buffer has 700-odd
more lines of documentation.
Searching and Browsing
A quick way to find packages is via
C-h p
(finder-by-keyword
), which pops up a Buffer containing
a list of keywords—for example:
calendar calendar and time management tools languages specialized modes for editing programming languages mail email reading and posting matching searching, matching, and sorting
However, this list is limited to built-in packages that come with Emacs, and
those in the built-in repos.
Much better is to use M-x
list-packages
, which will download all the
package descriptions from all the repos you have configured (four, in the Init
File snippet above) and add them to the built-in packages. Here’s a tiny
excerpt from the thousands of entries in my *Packages*
Buffer:
Package Version Status Archive Description ace-jump-mode 2.0 available melpa-stable a quick cursor location minor mode for emacs afternoon-theme 0.1 available nongnu Dark color theme with a deep blue background vertico 0.20 available gnu VERTical Interactive COmpletion org 9.4.4 built-in Export Framework for Org Mode csv-mode 1.18 installed Major mode for editing comma/char separated values
The *Packages*
Buffer is called the Package Menu. Hitting RET
on any of these
lines pops up the same description that C-h P
would present. You can sort the
entries by clicking on the columns in the Header Line (typing
S
(tabulated-list-sort
) will sort on the column containing
Point), and of course use Incremental Search or Occur.
You can also filter the entries (rather like an in-Buffer Occur) by metadata
keyword with / k
(package-menu-filter-by-keyword
); / k
is exactly like selecting
calendarcalendar
from C-h p
, except it
includes all the packages in the repos you configured.
/ n
(package-menu-filter-by-name
) filters by package name,
and / /
(package-menu-clear-filter
) will restore all the
entries.
The *Packages*
Buffer is in fact your Emacs package manager, and you can do all
your package maintenance in this Buffer; see Package Maintenance below.
Installing Packages
You can install a package by name, from any Buffer, with
M-x
package-install
: the package will be downloaded if necessary,
compiled, and loaded: it’s now ready to use. Once installed, the package is
available in future sessions (though some packages require enabling, typically
done in your Init File, and configuration, typically done via
Customize).
Installed packages live in your User Emacs Directory (see
user-emacs-directory
, typically ~/.emacs.d/
) in a
subdirectory elpa
.
You can also install packages directly from your Init File, like this:
(unless (package-installed-p 'vertico) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'vertico))) (with-demoted-errors "%s" (vertico-mode 1))
This is a good way to make sure all the packages you like are installed in all
your different Emacsen on your different computers, assuming you synchronize
your Init File; if you only use Emacs on one computer, it’s simpler just to
install your packages manually (actually, that’s all I do even though I use
multiple Emacs installations: I’ll quickly notice if a package is missing in
some other installation as soon as I try to use it).
Probably the most common way to install packages is from within the Package
Menu.
Package Maintenance
Package maintenance consists of installing new packages you want to use,
deleting old ones you no longer use, and updating your packages to the latest
versions. All of these tasks are typically done in the Package Menu. Table
30 lists the most useful maintenance key bindings;
searching was described above, and navigation is similar to any other Special
Mode Buffer.
Key | Action |
---|---|
RET , ? |
describe the package |
i |
mark package for Installation (with an I ) |
U |
mark all packages with Upgrades (with a U ) |
d |
mark package for Deletion (with a D ) |
~ |
mark all obsolete packages for deletion (with a D ) |
u |
Unmark this package |
x |
eXecute all marks |
g , r |
Refresh buffer from repo |
The Package Menu works similarly to a Dired Buffer: you apply various marks to
different packages (marks appear in the leftmost column), unmark any (with u
) if
you’ve changed your mind, and, when you’re ready, execute all your marks with
x
(package-menu-execute
). Any packages you’ve marked for
installation will be downloaded, compiled, and activated, and those marked for
deletion will be deleted (you can always reinstall them again at a future date).
You should periodically use the
U
(package-menu-mark-upgrades
) command to check for packages
that have new, upgraded, versions available. It will compare all the versions
of your installed packages with the latest versions in the repos and mark any
upgradable package with a U
. (This can take a minute or two, depending on the
repo, and so runs in the background.) When it’s done, use x
to upgrade the
packages; after the new versions have been installed, it will offer to clean up
obsolete versions for you.
Should You Write Your Own Packages?
Creating a proper Emacs package is easier than any other language I’ve
used,222 but it still involves a few additional steps (e.g. writing
metadata) compared to just creating your own library (which just requires you to
create a file of Elisp somewhere in your load-path
).
There’s probably no need to go to the extra trouble of packaging if you’re going
to be the only user of your library.
But if you want to contribute your library to the Emacs community, then you’ll
need to package it; just follow the instructions in §41 of the Manual,
Preparing Lisp code for Distribution.
Security Issues
Every package manager—for a programming language, the app store on your phone,
or an application like a web browser—comes with security concerns, and Emacs is
no different. See Security for more information.
Updates and Bugs
Emacs Updates
I’ve mentioned before that there have been an average of 2.5 new Emacs releases
every year in GNU Emacs’s 38-year lifetime. That
means it won’t be long before your OS package manager presents you with a fresh
new Emacs.
Emacs’s backward compatibility is excellent, so it’s unlikely that you’ll
experience any breakage when you fire up your new Emacs: your Init File will
almost certainly still work perfectly, your key bindings will still be the same.
At most, some things may look slightly different: changes in default fonts or
colors for example, and you can always fix these if you’re unhappy. You may see
some deprecation warnings if you’re using functions that are being phased out;
the Emacs developers tend to give a lot of lead time for deprecated functions,
so there’s no need to panic.
However, it is likely that there will be new features that you will want to know
about. C-h C-n
(view-emacs-news
) will display the change
log, a very extensive list of all the user-visible changes in the version of
Emacs that you’re running: that is, everything that changed from the way it was
in the previous version. If only you could get this kind of information for all
the web services you depend on! If you invoke this command with a prefix
argument, C-u C-h C-n
, you can request the change log for any previous version
of Emacs, all the way back to version 1.1 (the text of which is very quaint!).
Emacs Bugs
What, does Emacs have bugs? Since all software does, I’m afraid so. One of the
unique things about a Lisp Machine is that you can actually fix many bugs
yourself, live, while your Emacs is running, without recompiling or even
restarting.
Assuming you’re a programmer that is. If you’re not, and you find a bug, you
should report it. But first, you should try to make sure that this really is an
Emacs bug, and not a problem stemming from some settings in your own
Customizations or Init File. This means firing up a fresh Emacs with the -Q
option, which avoids loading your init file and even some of the system-wide
initialization, thus giving you a really pristine Emacs:
emacs -Q
Now try to replicate your bug. You may need to manually load a package that
you require
in your Init File if you think it’s implicated in the bug; you can
typically use M-x
load-library
to load it. The point is to have as
few non-standard customizations and loads as possible.
The Manual contains an excellent chapter
on reporting bugs, and you should really read it before reporting one: after
all, you’re having a problem with free software that you didn’t have to pay for,
and asking people to help you with your problem for free. You can at least try
to make it as easy for them as possible.
If you can replicate your bug in this -Q
environment, you can report it. Just
say M-x
report-emacs-bug
and an email composition Buffer will pop
up, with some instructions in another window. The email will be populated with
up to several hundred lines of data about the current state of your Emacs:
exactly which version you’re running, how your Emacs was compiled, which
packages you currently have loaded—all the kinds of information needed to help
figure out your bug. (You can delete any personal info that you might be
uncomfortable sharing.) You need to add a description of the bug, ideally
including a step-by-step recipe showing how to make the bug happen. (“Put point
at the beginning of the second word of a line with at least five words in it,
and now…”)
If you’ve set up your Emacs to send mail, you can just use
C-c C-c
(message-send-and-exit
) and your bug report will be
emailed to the Emacs maintainers! (If you can’t send mail from within Emacs,
you can cut-and-paste the contents of the message into the mailer you use, as
explained in the help window.) There’s no guarantee that the Emacs maintainers
can fix your bug, of course: they may not even be able to reproduce it, if it
has something to do with your computer or operating system or the phase of the
moon.
Not Emacs’s Fault!
If you can’t replicate your bug in this -Q
environment, then it’s probably not a
bug in Emacs but in your Init File. You’ll have to fix this on your own.
Generally the way you do this is to comment out all of your Init File except for
the first line (really, the first complete s-expression, which might span
several lines), save it, and fire up a fresh Emacs normally. Now see if your
bug is fixed. If it is, you know the problem is not in that first line, but
rather in the part of your Init File that you commented out!
But where? Well, now uncomment (i.e. restore) the next complete s-expression and
repeat the process. Eventually you’ll have restored the line that contains the
bug and you’ll know because suddenly the bug occurs again. Now just fix the
offending line and uncomment all the rest of your Init File, and you’re done!
This process can be really tedious if you have a large Init File223. There
are much more efficient ways to do this: really, any programmer would use binary
search to find the bug, and there are tools in the Package Manager to do
this automatically (see bug-hunter
).
Helping Squash Bugs
If you’re a programmer, you can volunteer to help fix Emacs bugs; all reported
bugs are listed in the Emacs Bug Tracker. You can pick one out and see if you
can fix it; see “Contributing” in the Emacs manual for more information. There’s an
excellent interface to the bug tracker in the Package Manager called debbugs
that makes this even easier.
Exiting Emacs
All good things must come to an end, meaning you will occasionally have to exit
your Emacs. As you know, the usual command to use is
C-x C-c
(save-buffers-kill-terminal
). Note that if you are
in an emacsclient
instance, C-x C-c
only terminates that client, leaving the
server running. See Client / Server for details on how to terminate the Server.
If you have any modified Buffers (unsaved files) when you exit, Emacs will
ask if you want to save these files before exiting with a prompt like:
Save file emacs-tutorial/emacs-tutorial.org? (y, n, !, ., q, C-r, C-f, d or C-h)
This prompt is really from the function save-some-buffers
which C-x C-c
calls. Your options for each file are summarized in Table 31.
Key | Action |
---|---|
SPC , y |
save the prompted buffer |
! |
save all remaining unsaved buffers |
C-f |
switch to this File and stop exiting |
C-r |
peek at this buffer, Read-only |
d |
view a Diff of this buffer |
C-g |
cancel the whole exit command |
. |
save just the current buffer and exit |
DEL , n |
don’t save the prompted buffer |
RET , q |
don’t save this or any remaining buffers |
The C-r
and d
responses allow you to peek at the file in question to figure out
whether or not you want to save or abandon your modifications.
If, after this process, you still have modified Buffers because you answered n
or q
to one of the prompts, Emacs will ask:
Modified buffers exist; exit anyway? (yes or no)
(Emacs really wants to make sure you don’t lose your data!)
Additionally, if you have any running subprocesses, you’ll get a another
cautious prompt:
Active processes exist; kill them and exit anyway? (yes or no)
Along with this you’ll see a *Process List*
Buffer showing all your
subprocesses. The processes in question might be shells or terminals, or
long-running commands you’ve fired up with M-&
. Remember that if you kill
Emacs, which is the parent of these subprocesses, the subprocesses will
probably themselves die.224
It’s easy to type C-x C-c
by accident, and who wants to terminate their
long-running Server full of dozens of files? There’s no problem if you have any
modified file-visiting Buffers or subprocesses, thanks to the above prompts, but
I personally never want Emacs to exit unless I’m about to reboot. So I have
this snippet in my Init File:
(setq confirm-kill-emacs 'yes-or-no-p) ; exiting emacs is silly
which causes Emacs to ask me if I really mean it.
I highly recommend exiting Emacs explicitly when you terminate your login
session (this of course includes rebooting or powering-off your computer). This
assures that Emacs has a chance to save your files, and arrange for persistence
if you’re using the Desktop (see below). There’s no need to exit Emacs when you
sleep your computer, though if you’re the cautious sort225 you might do
C-x s
(save-some-buffers
) before sleeping (I do).
The Desktop: Persisting Your Buffers
You can easily have most of your file-visiting Buffers restored each time you
start up a fresh Emacs by turning on desktop-save-mode
and
I recommend this for your Init File:
(desktop-save-mode 1) ; restore files from previous session
Not only are your file Buffers restored: so is your location (Point) in each Buffer,
its Major Mode, and even your Frames226, their Window configurations, and
all your Frame parameters (like fonts and font sizes).
desktop-save-mode
also saves the Tabs in your Tab Bar, the contents of all your
Registers, your EWW web Buffers, and probably more (Emacs packages can readily
hook themselves into desktop-save-mode
).
By default, remote files loaded from other systems are excluded from being
restored (in order to speed up restoration; also, the network or certain remote
hosts might be unavailable when you restore). You can change this by
Customizing desktop-files-not-to-save
.
You can trash your saved Desktop configuration with
M-x
desktop-clear
—you might want to do this if it’s been such a long
time since you last ran Emacs227 that you’re no longer interested in any of
the files you were last editing and they’re just clutter now. desktop-clear
zaps the saved Desktop config and also kills all the Buffers that were
initialized from that config.
desktop-save-mode
definitely slows down your Emacs startup speed. Since I use
the Emacs Server, and only fire up Emacs at most once every few weeks, I don’t
mind this at all. But you can Customize
desktop-restore-eager
in order to make the restoration of
your Buffers happen lazily—that is, delayed in the background instead of
all at once—which can give you a responsive fresh Emacs immediately.
By default, there’s only one saved Desktop configuration, and you generally
don’t want another Emacs to use it: that will just cause conflicts! So the
Desktop config is locked by the first Emacs that restores it, and any
additional, newly fired-up Emacs will ask you if you really want to steal the
lock:
Warning: desktop file appears to be in use by process with PID 1004. Using it may cause conflicts if that process still runs. Use desktop file anyway? (y or n)
The only good reason to say yes is if the locking Emacs crashed, and was unable
to give up its lock, and isn’t actually running anymore228. Note that there’s no
desktop conflict when using emacsclient
, since it connects to the running
Emacs and its desktop.
If you want to fire up a nonce Emacs, perhaps just to test a change to your Init
File229, and don’t intend to steal an existing desktop, just add the
--no-desktop
option; see Starting Emacs!.
Starting Emacs!
Because I advocate using a long-running Emacs in Client / Server mode, I haven’t
talked much about the details of starting up a fresh new Emacs, which weirdly
makes this chapter the last thing in Part I of the book.
Emacs has a number of command-line options to vary the details of how it starts
up. Many of the options are very exotic and only useful to people doing really
fancy stuff—for these, you can read the man page or see
“Emacs Invocation” in the Emacs manual.
The rest of the options can be divided into two categories: those for scripting
Emacs, and those for occasional everyday use. Most any option in that latter
category that you find yourself using all the time can be better done in your
Init File. Of course, my definition of these two categories is just rhetorical:
there’s no real division in use.
File Arguments
As usual for Unix programs, all command-line arguments that don’t start with a
hyphen are taken as the names of files to visit. So this command:
emacs file1 file2 file3
has the same effect as firing up Emacs with no arguments and then using
C-x C-f
(find-file
) once for each file.
There’s one exception: an argument of the form +123
positions Point at line 123
of the first file named on the command line. The full form of this option is
+
LN:
CN where LN is a line number and the optional CN is a column number.
This old-fashioned option is used by certain programs to fire up Emacs at the
precise line where an error has occurred. vi(1)
supports the same option, for
example. In Emacs, we usually turn this inside-out by calling
M-x
compile
from inside our running Emacs, and using
C-x `
(next-error
) to load the files and jump to the error
location; see Compiling Code. The +
option might still occasionally be useful
to an Emacs user via emacsclient(1)
.
Occasional Options
Option | = Long Option | Action |
---|---|---|
-d DISPLAY |
--display=DISPLAY |
open Emacs on named X display |
-nw |
--no-window-system |
open Emacs in this terminal |
-daemon |
--daemon |
start the Emacs server |
--version |
display version and exit | |
-q |
--no-init-file |
don’t load user’s init file |
--no-desktop |
don’t load saved desktop | |
--debug-init |
debug your init file | |
-Q |
--quick |
don’t do any initialization |
Table 32 lists what I think are the most useful occasional
options.
-d
and -nw
let you choose between running this Emacs in Graphical mode versus
in a terminal. You’ll recall that I’m an advocate of using Graphical mode. If
you’re running Emacs in a graphical environment (e.g., a Unix system running X
windows, or under MS Windows or Mac OS), Emacs will default to Graphical mode;
-d
is mostly for X windows experts doing fancy things. If you’re on a system
that’s not running in Graphical mode (like some big server machines, or in the
console of your Unix desktop), you’ll get Terminal mode by default and won’t
need -nw
. -nw
is mostly needed for those who are running a Graphical system but
want to use Emacs in external terminals as if it were vim(1)
.
The -daemon
option is one of two ways of starting up the Emacs Server; see
Client / Server for details.
The final group of options are mostly used for testing and debugging your Emacs
configuration. -q
runs an Emacs without loading your Init File or
Customizations. It can be handy for a quick check of whether or not some recent
Init File tweak you made has broken something: if the suspected breakage doesn’t
occur with -q
, the problem has to be in your Init File. Since Desktop Save Mode
has to be enabled in your Init File, -q
implies --no-desktop
, which tells Emacs not to
load any saved Desktop; see The Desktop.
A certain happy category of bug that can occur in your Init File causes an
explicit error each time you start Emacs. I call this a “happy” bug because
it’s the easiest kind of Init File bug to detect and fix! It can be hard to tell from the
startup error where it is in your Init File, so just restart Emacs with
--debug-init
and Emacs will jump into the Elisp debugger when the error occurs,
and you’ll be able to tell exactly where the buggy code is.230
-Q
is a more extreme version of -q
that also doesn’t load any system-wide init
file or Elisp231, nor any X window system resources. This is the option to
use if you think you’ve found a bug in Emacs: replicating the suspected bug
under -Q
makes it very unlikely to be your fault; see Updates and Bugs.
Scripting Options
What does it mean to “script Emacs” when the whole idea of the Lisp Machine is
to do everything inside Emacs with a real programming language, Emacs Lisp?
Well, sometimes we have to exist briefly in the world outside of Emacs, and use
Emacs as if it were a tool like AWK or sed(1)
; after all, Elisp is a much more
powerful programming language than either of those. Additionally, you may want
to automate some of your Emacs tasks via a build automation tool like make(1)
; I
do that to automate the building of this book; see the Colophon. Table
33 lists some of the options useful for this sort of thing.
These options take effect in the order given, which can be significant.
Option | Long Option | Action |
---|---|---|
-batch |
--batch |
run in batch mode |
-l FILE |
--load=FILE |
Load an elisp file |
-L DIR |
--directory=DIR |
add DIR to load-path |
-f FUNC |
--funcall=FUNC |
call function named FUNC |
--eval=EXPR |
evaluate elisp expression | |
--script FILE |
run Elisp from FILE in batch mode | |
--kill |
exit Emacs unconditionally |
-batch
puts Emacs into batch mode, which means it won’t fire up any sort of
interactive display: it will just process the following command line options,
and then exit. It implies -q
and is usually used with some combination of -l
,
-f
, or --eval
.
The --eval
option evaluates an arbitrary Elisp expression. This example is a
homemade variation on the --version
option:
emacs -batch --eval '(message "%s" (emacs-version))'
Most Emacs functions aren’t designed for command-line use, though: they use
Buffers rather than simply printing text to the standard output. But it’s easy
to write Elisp functions suitable for the command-line: you might collect some
in a file that you can load with -l
and then invoke a function in it with -f
.
But if you’re going this far, you might as well write a proper Elisp script, for
which the --script
option is handy. Here’s a dumb Emacs script that counts
words in the files named on the command line:
#!/usr/bin/emacs --script (dolist (file argv) (with-temp-buffer (insert-file-contents file) (message "%s: %s words" file (count-words (point-min) (point-max)))))
ADDITIONAL TOPICS
Completion at Point
Up to now, when we’ve talked about completion we’ve been talking about it in the
Minibuffer. But we can also do completion in any buffer, at Point. This might
be familiar from the way IDEs complete keywords and symbols for various
programming languages, and Emacs Major Modes for programming languages do this
too; see Pop-up Menu Completion. But Emacs also does this for ordinary text in
any buffer, and it’s an amazing feature, called dynamic abbreviation expansion
or Dabbrev for short232.
Dynamic Abbrevs
As you begin typing a longish word that you know or just suspect you’ve typed
before, hit M-/
(dabbrev-expand
) after the first few
characters and the word will complete (or expand) in place. For example, I just
typed “char” and M-/
expanded it to characters — exactly what I wanted.
If that wasn’t the word I wanted, I would just have immediately hit M-/
again,
and it would have changed the completion to another word starting with “char”:
in my case, one of character, charts, or charlie. Why? Because those are all
the words that start with “char” that I’ve used in this book (up to this point).
More M-/
’s would cycle through all the words that match; I just stop when I get
to the one I want.
The completion candidates are selected from the preceding words in the buffer,
sorted so that the first one offered is the nearest preceding matching word; the
next would be the second-nearest, and so on.
If I keep cycling after rejecting the match that’s closest to the beginning of
the buffer, or if there’s no matching preceding word at all, then candidates
will be offered that are ahead of me in the buffer (again in the order of
closest to farthest).
Suppose my buffer contains just this one line; I’ve just typed “com” and Point
is indicated by |
:
completely completeness completer com| completes completest completing completion
What is the sequence of completions offered up by a repeated series of M-/
’s?
The first completion offered is completer, followed by completeness and
completely. We’ve hit the beginning of the buffer, so the next M-/
would offer
completes followed by completest, completing, and completion.
What happens if, having rejected the last match in the buffer, we hit yet
another M-/
? Aha! In that case, M-/
proceeds to look for matches in
other buffers! This almost makes it seem like M-/
can read your mind, and the
effect and usefulness of this increases the more buffers you have.
By default, M-/
will only examine other buffers that have the same Major Mode,
so that if you’re editing poetry in latex-mode
, say, it won’t offer you the
names of variables and functions from your buffers full of Elisp code. But if
these same-mode buffers don’t have any candidates, it will then consider all
types of buffers.
You can fine-tune this to make it behave exactly the way you like via
M-x
customize-group
RET dabbrev
; see “Dynamic” in the Emacs manual.
The tricky part of Dabbrevs is, how many characters do you type before hitting
M-/
? If you type too few, you could get so many candidates that it might take you
ten times as long to cycle to the one you want as it would to just retype the
word. But even one character could be okay if the word you want is long and you just
typed it a line or so ago. If you don’t seem to be getting what you want after
a few tries, just undo and either type the whole thing, or try C-M-/
.
Once you get used to M-/
, you’ll develop a sort of automatic ability to know
when to use it, and it will both dramatically speed up your typing, and reduce
the number of typos you enter.
You can also complete a sequence of words. Suppose you’re writing about your
favorite Czech composer and need to type his name again. You type “Le” and then
M-/
completes “Leoš”; now immediately type SPC M-/
and his last name, “Janáček”
appears (this is assuming that you have his full name, “Leoš Janáček”, somewhere
in your Emacs). You can keep typing SPC M-/
to add more words: in general, you
can complete an n-word sequence, possibly containing some very long words, in
about (n times 2) keystrokes via a long sequence of SPC M-/
’s, though frankly I’ve
probably never used this technique for more than two or three words.
Dabbrevs via the Minibuffer
There’s another command to do completion at Point sort of indirectly, via your
preferred completion framework. (I would say this is not worth using unless
you’ve set up an INF like Vertico or Ivy, or are happy using the mouse.)
Type a partial word but this time invoke
C-M-/
(dabbrev-completion
). Instead of instant completion at
Point with the first candidate, and the need to cycle through them, you’ll be
presented with a complete list of candidates using whatever interface your INF
uses (Ivy will use a pop-up menu, Selectrum the Minibuffer).
I don’t use this as often as M-/
but it’s sometimes handy.
Hippie Expand
If Dabbrev isn’t fancy enough for you, you can use Hippie Expand, which is like
Dabbrev on steroids. Hippie works exactly like
M-/
(dabbrev-expand
), except it chooses from a much wider range of sources of
candidates. One of the sources is simply dabbrev-expand
itself, but it can also
expand filenames, entire lines, parenthesized lists, kills from the kill ring,
etc. You can customize which sources you want to use and in what order. Most people that use Hippie just
bind it to M-/
in place of dabbrev-expand
, but you can use a different binding
in order to have access to both. (Hippie can’t expand sequences of words the
way Dabbrev can.)
The only problem with Hippie Expand is that there are so many candidates it can
offer, what you get can seem like a crap shoot. Really, I think it would be
more useful if it offered completions the way dabbrev-completion
does
(implementing that would be a fun project).
But it’s quite amazing, and I bind it to M-/
to replace dabbrev-expand
; try it
and see what you think!
Pop-up Menu Completion
This form of completion-at-Point is primarily for completing symbols—e.g., the
names of variables, functions, and the like—in programming language modes,
though it’s more general than that. There are two main frameworks to choose
from, and both need to be installed from the Package Manager: Company and Corfu.233
Candidates for completion can come from many sources, some built-in and most
from optional back-ends, so that besides symbols for a programming language, you
can complete email addresses, dictionary words, and Unicode math symbols and
emojis by name, among others.
Corfu is modern, clean, and “standards compliant”, meaning it uses the official
Emacs APIs to get its completion candidates, whereas Company instead uses its
own backends—but then, there are 74 of them in the
Package Manager. One disadvantage of Corfu is that it only works in a
graphical-mode Emacs.
Both work roughly the same way: as you type the name of a symbol, a menu of
completions pops up at Point, either automatically or upon a keystoke, as you
prefer; you scroll to the completion you want (with TAB
or some other key), and
hit RET
to accept and expand it at Point. For some symbols, a one-line
description will appear in the Minibuffer. You can see from Figure
35 and Figure 36 that they look similar: here I’m in Emacs
Lisp Mode and have started typing the name of function: at the point at which
I’d typed “with-s” and paused for a fraction of a second, I get the menu.
In my opinion, popup-menu completion doesn’t really do too much for you that
Minibuffer completion doesn’t—except for automatically insinuating itself as
you type, if you choose that mode of activation—assuming you’re using a good
Incremental Narrowing Framework, but your mileage may vary. Without popup
completion, you can just invoke M-TAB
(complete-symbol
)
(which is the same as C-M-i
) and complete the symbol in the Minibuffer; see
Figure 37.
Since you get to use all the narrowing features of your preferred Minibuffer
completion framework, I prefer plain old complete-symbol
to popup completion.
If you want to try popup completion, I guess I would recommend Company; just add
this snippet to your Init File:
(unless (package-installed-p 'company) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'company))) (add-hook 'prog-mode-hook (lambda () (with-demoted-errors "%s" (company-mode))))
Registers
When you’re working in Emacs, you might save a lengthy chunk of text in the Kill
Ring so that you can yank it back in several different places with a simple
C-y
(yank
). The Kill Ring can hold many distinct chunks, but
they’re all anonymous and get pushed deeper into the Ring with each new thing
you kill (and if you kill enough text, the oldest items will disappear from the
Kill Ring). It would be nice to be able to give certain chunks of text names so
that you can easily remember how to access each of them.
Almost every programming language has the notion of a named variable that you
can set to some value for convenient reuse, and you could use Emacs Lisp
variables for this purpose, but Elisp is verbose and you need to understand the
subtleties of the language to use it.
So Emacs offers Registers: special
purpose named variables that can hold not just text, but a variety of things
that you might want to hang on to and eventually get back. The name of a
Register is limited to a single character: any ASCII character except for *
or
C-d
(which have a special interpretation). Most people stick to letters
(Register a
is different from Register A
) and digits. (See below for naming tips.)
For each type of thing you can store, there’s a command to set the content of
the Register, and a command to get the content. There are only two getters:
C-x r i
(insert-register
) serves for Register types whose
content gets inserted in a Buffer, and
C-x r j
(jump-to-register
) serves for those types that hold
something that you in some sense jump to.
Type | Set | Get | Contents |
---|---|---|---|
Text | C-x r s |
C-x r i |
an arbitrary blob of text |
Number | C-x r n |
C-x r i |
a number |
Rectangle | C-x r r |
C-x r i |
a rectangle |
Position | C-x r SPC |
C-x r j |
location of Point in this Buffer |
Filename | C-x r C-f |
C-x r j |
a filename |
Window Config | C-x r w |
C-x r j |
Windows layout of the current Frame |
Frame Config | C-x r f |
C-x r j |
the layout of all your Frames |
Keyboard Macro | C-x C-k x |
C-x r j |
the most recent Keyboard Macro |
Register Preview and Contents
Whenever a Register command prompts you for a Register name, it displays a
transient Buffer that contains a preview of the contents of all defined
Registers, as an aide memoire. You can see this preview234 at any time with
M-x
list-registers
. Because a Register can contain a huge amount of
text, the content can be truncated in these previews. If you want to see the
entirety of a Register, use M-x
view-register
.
Registers are a global data structure (not Buffer Local), so that they can be used to
move things from one Buffer to another.
Text in Registers
The set command for text is C-x r s
(copy-to-register
) or its
alias C-x r x
. It prompts you for a Register name and then
stores the text between Point and Mark (i.e., the Region) in that Register. With
a prefix argument, it deletes the text from the Buffer after storing it (you can
think of this as moving the text from the Buffer into the Register).
The get command for text is C-x r i
(insert-register
) or its
alias C-x r g
; it inserts the value into the Buffer at Point.
You can append or prepend text to a Register with
M-x
append-to-register
and M-x
prepend-to-register
; see
“Text Registers” in the Emacs manual.
Numbers in Registers
There is a special set command for numbers because you can use a proper number in a
Register as a counter; C-x r +
(increment-register
) will add
(1) to the current value of the Register (or some other increment, if given as a
prefix argument). This can be useful for Keyboard Macros in which you need to
count more than the one thing that the built-in Macro Counter can count.
Buffer Positions in Registers
You can store the position of Point in the current Buffer in a Register, with
C-x r SPC
(point-to-register
), which has the aliases
C-x r C-SPC
and C-x r C-@
. The get command for
positions is C-x r j
(jump-to-register
), which takes you
directly to that saved location.
Filenames in Registers
You can also store a filename in a register, in which case C-x r j
will actually
do a find-file
for you (if the file is already in your
Emacs, it will jump to its Buffer). But strangely, there’s no set command to
store a filename in a Register235: the
Manual says to use Elisp. So
I’ve defined the missing function; I put it on C-x r C-f
.
(defun kw-filename-to-register (filename register) "Store a filename in a register. Interactively, if a prefix arg, prompt for FILENAME. With no prefix arg, use `ffap-file-at-point' to get the filename at point; if that fails, use the buffer file name; if there is none, prompt for the filename. Reads the REGISTER using ‘register-read-with-preview’." (interactive (list (setq filename (if current-prefix-arg (read-file-name "Filename: ") (or (progn (require 'ffap) (ffap-file-at-point)) (buffer-file-name) (read-file-name "Filename: ")))) (register-read-with-preview (format "Filename %s to register: " filename)))) (set-register register `(file . ,filename))) (global-set-key (kbd "C-x r C-f") 'kw-filename-to-register)
But if the idea of giving short names to a variety of files that you visit
frequently seems appealing, you should probably check out Bookmarks instead.
Keyboard Macros in Registers
You can save the most recently defined Keyboard Macro in a Register with
C-x C-k x
(kmacro-to-register
) and invoke it with C-x r j
.
Why would you do this when you can assign Macros to keys in the C-x C-k
keymap
with C-x C-k b
(kmacro-bind-to-key
)? The main advantage is
that desktop-save-mode
will save any Macros in Registers for future Emacs
sessions without any extra work on your part, while preserving C-x C-k b
bindings requires the extra steps described in Naming and Binding Your Macros.
Saving Your Registers
You can automatically save the contents of all your Registers for future
sessions with the highly recommended Desktop Save Mode.
I have many Registers that have each retained their contents for years and I use
them regularly; they all have mnemonic alphabetic names. But I regularly also
need transient Registers that I definitely don’t care about maintaining
forever. I need short-term mnemonic names but don’t want to accidentally
clobber one of my “permanent” Registers. What to do?
My solution is to use control characters for the names. So for example,
Register k
contains:
call_kb(key="http://www2.lib.uchicago.edu/",cmd="http://www2.lib.uchicago.edu/")
(a snippet of Org Mode code that I use in this book all the time), so when I
temporarily need a Register to hold a blob of text about, say, koalas, I might
use C-k
as the Register name.
Rectangles
Programmers and system administrators often need to edit files of rigidly
structured text, organized at least partially into columns. It can be very
useful to be able to add, delete, or modify a rectangular chunk of such text,
and indeed Emacs has a suite of commands to do so. But how do you indicate such
a chunk?
A Rectangle is just a special interpretation of the usual Region. Normally, the
Region is the linear sequence of characters (counting newlines as ordinary
characters) between Point and Mark, as in Figure 38.
But the Rectangle commands interpret the exact same Region rectangularly, as in
Figure 39.
Once we’ve defined a Rectangle we can easily do things to it, like say blank it
out with one keystroke (Figure 40).
To work with a Rectangular Region, just set the Mark at any of the four
potential corners of the Rectangle, then move Point to the diagonally
opposite corner. At this moment, the ordinary linear Region has been defined
and will look (if you activate it with the usual
C-x C-x
(exchange-point-and-mark
)) like Figure
38. To switch the interpretation to rectangular, do
C-x SPC
(rectangle-mark-mode
), and you’ll see something like
Figure 39. (Alternately, you can sweep out the Rectangular
Region with C-M-mouse-1
(mouse-drag-region-rectangle
).)
With the Rectangular Region activated, Point is fixed to one of the four
corners. You can grow or shrink the Rectangle in any of the four cardinal
directions with ordinary motion commands (such as
C-f
(forward-char
), M-b
(backward-word
),
(next-line
), or whatever). Whether the Rectangle
grows or shrinks depends on the direction of the motion relative to the location
of Point.
You can cycle Point around the corners with repeated invocations of
C-x C-x
, which, when the Rectangular Region is activated, is
rectangle-exchange-point-and-mark
. If Point is at the
upper- or lower-right corner, rightward motion will grow the Rectangle to the
right, and leftward motion will shrink it to the left, for example.
In addition to the motion commands, commands that kill or copy the Region, like
C-w
(kill-region
) and
M-w
(kill-ring-save
), will operate on the Rectangle, and so
will commands that modify the text in the Region, like
C-x C-u
(upcase-region
).
To deactivate the Rectangular Region, just use
C-g
(keyboard-quit
).
Inactive Rectangular Regions
The motion and Region-manipulating commands described above only have their
special Rectangular interpretation when the Rectangular Region is activated.
But as you know, if the Mark is set in your Buffer, there is a Region present,
even it isn’t activated. The same is true of the Rectangular Region: if there’s
a Mark, there’s an implied Rectangle, and there is a set of explicit Rectangle
commands (see Table 35) that will operate on it whether
you activate it with C-x SPC
or not (you might prefer to
activate it just so the precise extent of your Rectangle is more obvious).
Key | Action |
---|---|
C-x r c |
Clear rectangle (overwrite with spaces) |
C-x r d |
Delete rectangle |
C-x r k |
Kill rectangle |
C-x r y |
Yank previously killed rectangle |
C-x r o |
Open rectangle (shift rectangle right) |
C-x r t |
replace Text of rectangle |
C-x r N |
Number rectangle’s lines |
C-x r r |
copy rectangle to Register |
C-x r c
changes every character in the Rectangle to a space,
“clearing” it (as in Figure 40).
C-x r o
on the other hand opens up a new rectangular space where
you’ve marked your Rectangle, but preserves the original text of the Rectangle
by shifting it to the right (that includes all the text to the right of the
original Rectangle too).
Deleting or killing the Rectangle actually eliminates all the characters
contained in the Rectangle, rather than converting them to spaces as C-x r c
does, thus squashing the Rectangle out of existence and shifting all the text to
right of it leftward. If you use C-x r d
(delete-rectangle
),
the text of the Rectangle is gone forever236, but if you use
C-x r k
(kill-rectangle
) you can later yank the Rectangle
back with C-x r y
(yank-rectangle
).
C-x r t
is probably the Rectangle command I use the most: it
replaces the text of the Rectangle with new text: you’re prompted for a new
single line of text, and that line replaces the text of each of the Rectangle’s
lines. Consider this list of some of my favorite drummers:
+ Chris Cutler + Max Roach + Tatsuya Yoshida + Christian Vander
I can change all the plus signs to bullets by setting a one-character-wide
Rectangle containing the column of pluses, and then executing C-x r t •
.237 The
result will be:
• Chris Cutler • Max Roach • Tatsuya Yoshida • Christian Vander
The new text doesn’t have to be the exact same width as the Rectangle; if
instead I used the string “Drummer” the result would be:
Drummer Chris Cutler Drummer Max Roach Drummer Tatsuya Yoshida Drummer Christian Vander
Old- and New-School Rectangle Commands
The commands in Table 36 were necessary before the
invention of the Rectangular Region in 2014, and of course you can still use
them, but if you’re activating the Rectangular Region via
C-x SPC
you can use the easier commands discussed above.
Key | Inactive Rectangular Region | Active Rectangular Region |
---|---|---|
(Old School) | (New School) | |
C-x r k |
Kill rectangle | C-w |
C-x r d |
Delete rectangle (not yankable) | C-w (yankable) |
C-x r M-w |
copy rectangle to Kill Ring | M-w |
C-x r y |
Yank rectangle | C-y |
Empty Rectangles
If you set the Mark, and then move point directly downward say four lines with
C-n
(next-line
), you have created an empty Rectangle with a
width of zero columns which is four lines in height. Such empty Rectangles are very
useful! If you’ve typed in my list of drummers without any kind of bullet:
Chris Cutler Max Roach Tatsuya Yoshida Christian Vander
then you can add the bullets by defining an empty Rectangle extending vertically
from in front of the “C” of Chris Cutler down to the “C” of Christian Vander,
and then using C-x r t
to insert the bullets.
Yanking Rectangles is Subtle
When you yank back a previously killed Rectangle with
C-x r y
(yank-rectangle
), the lines of the Rectangle are
inserted into the Buffer with Point being the upper-left-hand corner of the
inserted text.
If I have previously killed a 3-line Rectangle consisting of hyphens, and I
position Point right before the space in the first line of this block of text:
XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
and then I say C-x r y
(yank-rectangle
), the result might
look like this:
XXXXXXXX----- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXX-----XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXX-----XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Note how yanking shoves the characters to the right, rather than replacing any
of them. To instead achieve this result:
----- ----- ----- XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
you would need to first, before yanking, open up three blank lines (perhaps with
C-u 3
C-o
(open-line
)) and insert eight spaces on the first
of them to position Point where you want it horizontally.
C-o
is very handy when yanking Rectangles. Rather than counting precisely,
you can often give it a big numeric argument to open more lines than you’d need,
say, with C-u C-u C-o
to get sixteen blank lines, yank your Rectangle, and then
close up the extraneous blank lines with a couple of
C-x C-o
(delete-blank-lines
)’s.
Bookmarks
Emacs Bookmarks are a sort of generalization of Filename Registers, but they
come with long names, some additional commands, and a Major Mode for browsing
and maintenance. Most of us have a set of files, located all over the file
system, that we visit on a regular basis: Bookmarks are the way to manage them,
and they automatically persist across Emacs sessions.
Bookmarks were probably originally designed as a way to save your position
in a file, just like a physical bookmark does in a physical book: they let you
open up a file at the exact point that you were last reading (or editing).
But for this aspect of Bookmarks, save-place-mode
works
better. If you enable it in your Init File (and I recommend you do), every time
you open any file, Point will be set to the position it had when you last saved
the file.
(save-place-mode 1) ; come back to where we were in that file
The main Bookmark commands share the C-x r
prefix with the Register and
Rectangle commands. and basic usage is quite straightforward:
Key | Action |
---|---|
C-x r m |
set or update a bookMark NAME here |
C-x r M |
set a new bookMark NAME |
C-x r b |
jump to Bookmark NAME |
C-x r l |
pop up List of all bookmarks |
M-x bookmark-insert |
insert contents of bookmarked file |
M-x bookmark-insert-location |
insert filename of bookmarked file |
When you set a Bookmark with C-x r m
you’ll be prompted for a name, which is an
arbitrary string (not just a single character like a Register); typing C-w
’s at
the prompt will slurp up words from Point to use as the name. The default name
will be the Buffer’s filename238. You can only bookmark files or
directories (C-x r m
will work in a Dired Buffer), so you’ll get an error if
you’re in a Buffer that’s not visiting a file. Note that you can bookmark
remote Tramp files and directories: extremely useful, and there’s special
support for bookmarking chapters of Info documentation.
Each Bookmark records not only the file, but the current location of Point.
You can have several Bookmarks pointing to different locations in the same file,
but you’ll want to give them distinct names so you can keep them straight.
If you have a Bookmark, and you invoke C-x r m
at a different location in the
same file, Emacs will update the Bookmark to reflect the new location of Point.
With a prefix arg C-u C-x r m
will update the Bookmark but rather than
discarding the old location, will shadow it: when you delete the Bookmark, the
previous location will be restored. Effectively, with C-u
you can push any
number of new locations on a stack and pop them off later.239
I say that a Bookmark records the value of Point, but actually it also stores
some of the file’s text before and after Point, so that if the file changes
slightly, Emacs can restore your location with more accuracy.
C-x r M
is just like its lowercase sibling, except that it will refuse to update
an existing Bookmark.
Jumping to a Bookmark is as easy as C-x r b
: just type the name and go. With a
good Completion enhancement like Marginalia you’ll get some useful extra
context.
With M-x
bookmark-insert
, you can also insert the complete contents
of a Bookmarked file into the current Buffer at Point; this is like
C-x i
(insert-file
) except you use the Bookmark name rather
than the complete filename. M-x
bookmark-insert-location
inserts
just the filename of the named Bookmark.
Bookmark Maintenance with the Bookmark Menu
C-x r l
(bookmark-bmenu-list
) pops up the Bookmark Menu
Buffer, a two-column listing of all your Bookmarks; it might look something like this:
% Bookmark File Inbox.org ~/notes/syncthing/Inbox.org Web Space /ssh:example.com:/home/login/web backdrops ~/images/backdrops/DB books ~/books/2022.db
This Buffer works much like Dired or Buffer Menu, so you can probably start
using it without any explanation: hit RET
on a line to jump to that Bookmark, d
to flag a Bookmark for deletion, and x
to execute your deletions.240 Here’s
a subset of the truly Bookmark-specific commands; as always, you can use
C-h m
(describe-mode
) to see the expected Special Mode
commands for scrolling, opening your Bookmarks in the usual Window and Frame
variants, marking lines to open several in one go, limiting to matching
Bookmark names, and the like.
Key | Action |
---|---|
r |
Rename this bookmark (same file, new name) |
R |
Relocate this bookmark (same name, new file) |
k |
Kill this bookmark immediately |
d |
flag (with D ) this bookmark to be Deleted |
x |
eXecute deletions of bookmarks marked with D |
a |
show the Annotation |
A |
show All annotations |
e |
Edit the annotation |
Bookmark Annotations
Bookmarks can have simple annotations attached to them; Bookmarks with
annotations are marked with an asterisk (*
) at the left. From the Bookmark
Menu, use the a
command to display this line’s annotation in a pop-up Window (A
will show all of them). To add or edit an annotation, use the e
command.
Since a Bookmark is specific to a particular location in a file, you could
theoretically annotate many lines by creating many Bookmarks, but practically
speaking, the Bookmark Menu interface isn’t really up to this task. There are
third-party packages that handle this properly.
Abbreviations
Most forms of completion are about making it easy for you to choose from a set
of candidates, but Emacs also has a system known as Abbrevs in which a short,
user-defined abbreviation, at the moment you type it, automatically expands to
something (usually) much longer.
The great thing about Abbrevs is that they happen instantaneously without your
having to type so much as a single extra keystroke to invoke a completion
command: they just magically expand as you’re typing! Suppose you’re writing
about Transylvanian cuisine and find yourself typing “Székelykáposzta” a lot.
You might like the Abbrev “sk” to expand to that word, properly capitalized, so
that when you type “Cooking sk is easy”, the Abbrev expands right after you type
“sk”, the result being “Cooking Székelykáposzta is easy”.
Of course there’s a flip-side. Unlike completion patterns, you have to define
the Abbrevs you want to use, and, since they expand magically, they might
occasionally expand when you don’t want them to.
Let’s try it. First, in some writable Buffer, you need to enable the Minor Mode
abbrev-mode
with M-x abbrev-mode
. This is a Buffer Local
Minor Mode, so it will only apply to the current Buffer.
Next, you have to define yourself an Abbrev. You might decide to do this after you’ve
typed some long or tricky-to-spell word enough times that you notice you’re sick of
doing it, so the expansion is right there in the buffer, to the left of Point. Before
typing any further, give the expansion an abbreviation with
C-x a l
(add-mode-abbrev
). This command defines an Abbrev
for the word immediately before Point. It prompts for the abbreviation:
Mode abbrev for "Székelykáposzta": sk
That’s it! Now “sk” will expand to Székelykáposzta in this Buffer.
Actually, as the name add-mode-abbrev
suggests, it will expand in all buffers
that are in the same Major Mode and in which you’ve turned on abbrev-mode
. If
this buffer is in Org Mode, then “sk” is “Székelykáposzta” in all your Org Mode
buffers, until you either change your mind and undefine it or until you end your
Emacs session.241
You can also define global abbrevs that work everywhere abbrev-mode
is enabled,
regardless of the Major Mode, with
C-x a g
(add-global-abbrev
).
The mnemonics for these keystrokes, then, are:
C-x a l
- Abbrev, Local (to Mode)
C-x a g
- Abbrev, Global
Both C-x a l
and C-x a g
take, as the expansion text, the text from Point
backwards to the beginning of the previous word. This means that if you type
the expansion “foo ”—note the space after the word and before Point—the
expansion will include the space, and also any trailing punctuation; this will
be clear from the prompt. For maximum flexibility you typically don’t want
trailing spaces or punctuation in your expansion text.
Multi-Word Expansions
What do you do if you want your expansion text to include multiple words? I
might want an Abbrev for the name of my workplace, The University of Chicago,
for example. With Point after Chicago, I can use a numeric argument of 4 like
so: C-u 4 C-x a l
. I could also put the Region around the expansion text and
use a numeric argument of zero: C-u 0 C-x a l
242 These numeric arguments work
identically for the global command C-x a g
.
You can also define Abbrevs backwards, by typing the Abbrev in the buffer and
then using either C-x a i l
(inverse-add-mode-abbrev
) or
C-x a i g
(inverse-add-global-abbrev
). This way you never
have to count the words in your expansion.
All these defining keystrokes seem to be designed for people who are constantly
adding Abbrevs on the fly as they type at speed, but for me this only happens very
occasionally. So I think the easiest way to define an Abbrev is with
M-x
define-mode-abbrev
and M-x
define-global-abbrev
.
These commands prompt you for both the expansion and the abbreviation in the
Minibuffer, so there’s no counting.
Abbrevs and Case
The case of the letters you use in typing an Abbrev control the case of the
letters in the expansion in a manner analogous to the way case works in Isearch.
If you’ve defined “wa” as an abbreviation for “wallabies”, typing “Wa” instead
of just “wa” will expand to “Wallabies” and “WA” will expand to “WALLABIES”.
Unexpanding Unhappy Expansions
What do you do if an Abbrev expands when you don’t want it to? First, you
should choose unlikely abbreviations to minimize this problem: if you write
primarily in English, maybe don’t chose “the” as your abbreviation for
“Transportable Helicopter Enclosure”. But there are certain circumstances when
even the unlikeliest of Abbrevs will expand when you don’t want them
to.243
When exactly do Abbrevs expand? When you’ve enabled abbrev-mode
, Abbrevs are
checked for every time you type a non-word-constituent character, that is, any
character that the current Major Mode doesn’t consider to be a part of words.
Typically that’s whitespace and punctuation. So when you type “The End.”, as
soon as you type the space, abbrev-mode
checks the preceding word (“The”) to see
if it’s an Abbrev, and if so it expands it. Then when you type the period after
“End”, it checks to see if “end” is an abbrev, and so on.
This means that you might get an unwanted expansion. This is especially common
when you’re briefly typing in a domain specific language in your otherwise
straight natural language prose. Suppose I need to type a URL in my Transylvanian
cooking text, and the URL includes an innocent “sk” between punctuation
characters, like https://example.com/d7/sk/45/d0/
— I would end up with
https://example.com/d7/Székelykáposzta/45/d0/
! This can also come up with
snippets of HTML, say, or examples from some programming language.
There are two solutions. One is, as soon as you see the unwanted expansion,
Undo it. This will lose you the punctuation character that caused the expansion
— a slash, above — so then add the slash back by quoting it with
C-q
(quoted-insert
) i.e. C-q /
. quoted-insert
prevents
abbrev-mode
from expanding the Abbrev. If you’re thinking ahead you can
obviously skip the Undo part.
Another solution is to use M-x
unexpand-abbrev
, which does just what
it says; you’ll still need to use quoted-insert
to get the punctuation back.
A real downside is that you might be typing quickly and not notice the
expansion! Now you have an error: this is the same reason your SMS text
messages are full of embarrassing typos, and is the reason I don’t really use
Abbrevs very much. I prefer Dynamic Abbrevs: if I’m typing Székelykáposzta
often enough, it’ll be sure to complete easily with M-/
.
Prefixed Abbrevs
The inverse of unwanted expansions is wanted expansions that don’t happen.
Suppose you’ve defined “bac” as an Abbrev for “bacterial”, and you expect that
when you type “antibac ” it will expand to “antibacterial”. But of course it
doesn’t, because the word preceding the space isn’t “bac”.
You can solve this with M-'
(abbrev-prefix-mark
). Just type
“anti” M-'
“bac” and then space; when you type M-'
Emacs will insert a hyphen,
but this is a magic hyphen, and when you hit the space, “anti-bac” will expand
to “antibacterial” (and the hyphen disappears).
Turning abbrev-mode
on in Your Init File
Unlike many modern Minor Modes, abbrev-mode
doesn’t have a global-abbrev-mode
version, so if you want it on in all the Major Modes you use, you’ll have to
enumerate them in your Init File. The easiest way is probably to use one or
both of these two hooks:
(add-hook 'text-mode-hook 'abbrev-mode) (add-hook 'prog-mode-hook 'abbrev-mode)
Most texty Major Modes inherit from text-mode
, just as most
programming language modes inherit from prog-mode
. If you
don’t want it everywhere, just add it to the hook for any Modes you want; see Hooks.
Listing and Editing Abbrevs
You can see all the Abbrevs that you’ve defined with
M-x
list-abbrevs
. They’re grouped by Major Mode and will
include a special entry for the Global Abbrev Table. Most definition lines will
look like:
"sk" 32 "Székelykáposzta"
You can edit any of these lines to tweak or add new Abbrevs. The number in the
middle is a count of how many times you’ve used that Abbrev, which can be
helpful if you decide to clean some of them up. You can also delete lines to
delete the definition. After making any such changes,
C-c C-c
(edit-abbrevs-redefine
) will update Emacs’s state to
reflect your changes. C-x C-s
will save the buffer in a file that Emacs will
automatically load each time you start a session.
Saving Your Abbrevs
If you’ve defined any Abbrevs in a session, Emacs will ask if you want to save
them when you run C-x s
(save-some-buffers
), or when you
exit. When prompted for a filename to save them in, the default will be a file
in your Emacs Directory; Abbrevs in this file will be loaded and defined for you
when you start up Emacs.
Recursive Edit
One of the more unusual Emacs capabilities is what we call Recursive Edit; it
refers to your ability to do full-on Emacs editing while you’re in the middle of
doing Emacs editing. What?
Suppose you’re doing a Query Replace, which is a very structured sort of
editing: you’re stepping from one match to the next and at each stage, answering
a yes-or-no-question (replace this one, or not). It’s possible that in the
middle of this, you might need to look at some other part of the buffer, or some
other Buffer entirely, in order to decide between yes or no for one of the
matches. You could quit the Query Replace, and then restart it, but the normal
Emacs thing to do is enter a Recursive Edit—which, in a Query Replace, you can
do by using C-r
.
The Recursive Edit is a way to leave the Query Replace frozen where you left it.
You can then do any Emacs editing you like: you’re no longer just answering yes
or no. You can scroll the Buffer, move to a different location, make a quick
edit, change Buffers, send an email, or play a game of Tetris. Take as much
time as you like, even days if you want (as long as you don’t exit Emacs).
It will seem as if you’ve quit out of the Query Replace, but really it’s just
waiting patiently for you to end your Recursive Edit, at which point your
windows will be restored to exactly what they looked like when you hit C-r
, and
it will be waiting for you to answer the exact same yes or no question it was
asking you before your excursion.
The word recursion implies self-reference and nesting something within itself,
as in the recursive acronym GNU, which stands for “GNU’s not Unix!”244.
This is exactly what’s happening with a Recursive Edit: in order to let you do
an arbitrary something in the middle of something else, rather then implementing
a half-assed temporary-escape feature, Emacs does the simplest possible thing:
it calls itself recursively to do the job. This simplest possible thing also
happens to be the most powerful thing.
The only way you can tell you’re in a Recursive Edit is by peeking at the Mode
Line. The section which displays Major and Minor Modes with parentheses will be
wrapped in square brackets, like this:
U:@--- *scratch* All L1 Hg:94daf [(Lisp Interaction ElDoc)]
when you exit the Recursive Edit, the brackets will go away.
Since you can do anything while you’re in a Recursive Edit, that includes entering
another Recursive Edit! If you do that, you’ll see another level of brackets in
the Mode Line. The number of pairs of brackets indicates how deeply nested you
are.
Besides Query Replace, you’ll find special key-bindings for Recursive Edit in
other highly-structured Emacs subsystems, like Keyboard Macros and the
Elisp debugger. But because Emacs is
very much a non-modal editor, there’s less call for special uses of this
powerful feature than you might think. If you’re doing file management in
Dired, or are the middle of editing a version control log message, you can just
switch Buffers, do something else, and come back later. This is even true when
you’re being prompted for information, as I described in The Minibuffer.
You can invoke a Recursive Edit manually whenever you want with
M-x
recursive-edit
, but I’m hard pressed to think of times when I’ve
wanted to do this.
Exiting a Recursive Edit
I encourage you to try a recursive excursion during your next Query Replace. But
before you do, you need to know how to exit the Recursive Edit! There are three
ways:
-
C-M-c
(exit-recursive-edit
) - exit the innermost Recursive
Edit and continue where you left off (perhaps back in your Query Replace) -
C-]
(abort-recursive-edit
) - same as above, but also abort
the command that gave you the Recursive Edit (perhaps your Query Replace) -
M-x
top-level
- abort all nested levels of Recursive Edit
If you ever happen to notice some square brackets around the mode information in
your Minibuffer, it might be because you accidentally entered a Recursive Edit,
or perhaps days ago you intentionally did so in a Query Replace but then changed
your mind entirely about it, and simply forgot to exit — you might even have
killed the Buffer in which you were doing the Query Replace! C-]
is appropriate
in these situations, but C-M-c
is the standard procedure.
A forgotten Recursive Edit rarely causes any problems — you could be working
for weeks in one without even noticing — but you might as well clean them up
when you discover them.
Visual Display and Color
Each character or span of characters in a Buffer can have any number of
properties that can be used to change its Face (font, colors, underlining,
slant, etc), the character set (encoding), directionality (left-to-right or
right-to-left), spacing and line-height, margins, visibility, modifiability, and
the like. Chunks of text of any size can have clickable actions or an entire
menu associated with them and can change what a keystroke does when the cursor
is at a particular location. Text can be displayed as glyphs (like emojis or
icons) or full-blown images. All of this is done without any modification to
the plain text of the Buffer’s visited file (if any) and so won’t interfere with
or confuse external programs.
These facilities are used to build Emacs applications such as the Customize facility
and Dired, and one generally needs to be an Elisp programmer to play with them,
but here we’ll discuss some of the user-level commands that enable
non-programmers to easily change the visual properties.
Fonts and Faces
Loosely speaking a computer font (hereafter, just “font”) is a packaging of a
particular typeface design (think Helvetica), including variations in size,
weight, slope, and the like. Your operating system probably comes with some
fonts predefined, and you may have added many more via your OS package manager.
More precisely, a font is one specific expression of a typeface, a weight, a
slant, etc, such as “Helvetica 14 Bold”. I have 786 fonts
installed on my system, which are all available to Emacs.
A Face is an Emacs concept: a combination of a font with any of the following
additional attributes: Underline, Overline, Strike-through, Box around text,
Inverse-video, Foreground (color), Background (color), or Stipple.245
Emacs predefines 150-odd different Faces, and packages can define and add many
more (my Emacs currently has 441). You can see a colorful listing
of all the currently defined Faces with M-x
list-faces-display
.
These Faces are used to present the typically colorful Emacs display of
mode-specific syntax highlighting, hypertext links: really, everything, because
in Emacs, all is text.
You don’t need to worry about specific Faces until you’re unhappy with one. If
some Face in some mode rubs you the wrong way, you can easily change it; see
Customize for more information.
Changing the Default Font
Most Faces are just customized versions of the default font246, and the
default font is what most of your text will look like. You may want to change
it from the default 10-point monospace font. As a programmer, I much prefer a
monospace (fixed-pitch) font, but I like a specific one best and specify it in
my Init File. You can do this yourself with something like this:247
(with-demoted-errors "%s" (add-to-list 'default-frame-alist '(font . "Helvetica 12"))
Changing Fonts on the Fly
The default font is Frame-specific; though there’s a default, you can change the
current Frame’s font on the fly with M-x
set-frame-font
; you can use
Completion to choose amongst all the fonts available on your system.
M-x
menu-set-font
provides a popup GUI dialog and changes the font
of all your existing and future frames (in the current Emacs session) in one go.
You can of course customize different fonts for different Major Modes and the
like, and there are a number of third-party packages for working with fonts as
well.
Text Scale: Changing the Font Size
Once you’ve chosen your default font, you probably won’t often feel the need to
change it on the fly, but you may well want to change the size from time to
time. You can increase the font size with
C-x C-+
(text-scale-adjust
), which immediately embiggens the
font by the factor in text-scale-mode-step
(default:
1.2), or decrease
the font size by the same factor with
C-x C--
(text-scale-adjust
);
C-x C-0
(text-scale-adjust
) will restore your default font
size.
You may have noticed that all these keystrokes are bound to the same function.
That’s because the text-scale-adjust
function bases its behavior on the
keystroke that invoked it. Additionally, after it’s invoked, if any of the next
keystrokes in unbroken sequence are 0
, +
, or -
,
ignoring any modifiers, the corresponding action is
invoked. In short, start with any of C-x C-0
, C-x C-+,
or C-x C--
and then you
can continue tweaking the font size with simple 0
, +
, or -
keystrokes until you get what
you want — terminate this with any key that doesn’t involve 0
, +
, or -
( C-g
(keyboard-quit
) is always there for you).
Since for me, the first adjustment is always to enlarge the font, I bind
text-scale-adjust
to the felicitous binding C-+
and start from there:
(global-set-key (kbd "C-+") 'text-scale-adjust) ; embiggen font
Themes and Colors
A theme is a named combination of
Faces248 that broadly determines the overall look of your Emacs, especially
the colors. Emacs predefines 16 Themes, and there are at least
295 more in the Package Manager, and many more on
Github and the like.
If you’d like to change your Theme, just call M-x
customize-themes
,
which will contain lines like:
[ ] wheatgrass -- High-contrast green/blue/brown faces on a black background. [ ] whiteboard -- Face colors similar to markers on a whiteboard. [ ] wombat -- Medium-contrast faces with a dark gray background.
Just check the box of the Theme you want and the Theme will be immediately
activated; check another box and it will switch to that theme; uncheck the box
to go back to Theme you were using before you started. Some Themes are subtle
and you might need to see them in a variety of different types of Buffers to
appreciate them. Third-party Themes you’ve installed from the Package Manager
will also be listed in this Buffer. After you’ve chosen the one Theme you like,
you can make it your default for future sessions: evaluate
C-x C-s
(custom-theme-save
) in the Customize Buffer.
Who creates all these Themes? Anybody, including you. If you want to try your
hand at it, run M-x
customize-create-theme
and answer “yes” to the
question:
Include basic face customizations in this theme? (y or n)
You’ll be taken to a special Customize Buffer where you can choose all the
colors, fonts, and faces you want in your very own Theme, which you can save,
make your default, and even give away to other Emacs users.
Colors
One of the most important parts of a Theme is its (presumably harmonious) color
choices. On my system, Emacs knows
752 named colors; you can
examine them via M-x
list-colors-display
(see Figure 42).
The Cursor
Every Window has a Point, which is indicated by a cursor. By default, the
cursor is a solid block in the currently selected Window, and a hollow block in
any other visible Windows. But you can change how the cursor is displayed if
you like. Customize the many aspects of the cursor with
M-x
customize-group
RET cursor
. See
“Cursor Display” in the Emacs manual for more information.
By default, the cursor blinks, which drives me crazy; I turn it off in my Init File:
Emphasizing the Cursor’s Line
When I’m reading text with long lines, I sometimes lose my focus as I scan the
lines from left to right; it’s also an issue for me vertically with very tall
windows. To solve this problem, I invoke M-x
hl-line-mode
, which
changes the background of the entire line containing Point (i.e. the cursor) to
make that line stand out. As you move the Point from line to line, the
background emphasis follows along.
I turn this on automatically in many Major Modes that display lists of
things, like package-menu-mode
,
occur-mode
, and dired-mode
via
Init File snippets like these:
(add-hook 'occur-mode-hook 'hl-line-mode) (add-hook 'dired-mode-hook 'hl-line-mode) (add-hook 'package-menu-mode-hook 'hl-line-mode)
Highlighting Text
By now you’ve noticed how colorful the typical Buffer is. Almost every Major
Mode does a certain amount of what we call fontification to apply Faces based on
the structure or syntax of the text. This is typically done by a Minor Mode
called font-lock-mode
, which is enabled globally by
default. If you’re looking at a colorful Buffer right now, try saying M-x
and you’ll be stunned to see all the colors disappear: you’ll be
font-lock-mode
staring at 100% monochrome text! This is what Emacs used to look like in the
70s. (Quick! Reinvoke that command to get your colors back!)
Fontification is mostly performed by Major or Minor Modes, so you have to be an
Elisp programmer and Regular Expression wizard to do it. But there is a small
collection of commands that allow you to fontify your text dynamically: we call
this on-the-fly fontification highlighting.
Hi-Lock Mode
hi-lock-mode
lets you highlight text that matches certain
patterns, to make occurrences of those patterns stand out dramatically. As a
programmer, I often use it to highlight the name of a function or variable in my
code so that all the uses jump out at me; you might also use it to highlight the
names of people or things in a document so that they stand out as you scroll
through. It looks rather like the highlighting of your search term that
Incremental Search does, but the Isearch highlights disappear as soon you
terminate your search: Hi-Lock highlighting sticks around until you turn it off.
In Figure 43, I’ve highlighted all occurrences of the variable node
in pink. All the occurrences in the Buffer are pink, not just the ones visible
in the Window: as I scroll the Buffer, any node
I see will be pink, and if I
type new text that contains node
, that new node
will immediately become pink as
well. In addition, I’ve highlighted a comment describing a bug in unmissable
yellow; all other comments that start with TODO BUG
will also be lit up this
way. I consider Hi-Lock Mode an essential feature and use it all day long.
Note that these highlights don’t modify your text in any way. If you save your
file, they won’t corrupt your program with hidden codes. On the other hand, if
you want them to come back the next time you edit your file, you have to say so.
The Hi-Lock commands all live on the M-s h
prefix; see Table
39.
Key | Action |
---|---|
M-s h . |
highlight symbol at Point |
M-s h p |
highlight-phrase |
M-s h r |
highlight-regexp |
M-s h l |
highlight-lines-matching-regexp |
M-s h u |
unhighlight-regexp |
M-s h f |
hi-lock-find-patterns |
M-s h w |
hi-lock-write-interactive-patterns |
The simplest command is M-s h .
(highlight-symbol-at-point
);
just invoke it and the symbol249 at Point, and all other occurrences of
that symbol in the Buffer, will be highlighted in yellow.
Actually, not always in yellow: the next Hi-Lock color will be used. Hi-Lock
has a default list of colors it uses; if you’ve already highlighted something
in yellow, it will use the next color to avoid a conflict. You can explicitly
choose your own color by giving M-s h .
a prefix arg.
And as a matter of fact, Hi-Lock doesn’t highlight with colors: it uses Faces.
You’ll recall that Emacs comes with 150 or so, and you can use any of them for
highlighting.
Instead of highlighting the symbol at Point,
M-s h p
(highlight-phrase
) prompts you for a phrase: that is,
a sequence of words, and highlights matches. It ignores case and whitespace
distinctions when looking for matches. Of course you can use a one-word phrase,
which is like highlighting a symbol which doesn’t happen to be right at Point.
M-s h r
(highlight-regexp
) prompts you for a Regular
Expression and a Face, and then highlights all the matches, and
M-s h l
(highlight-lines-matching-regexp
) works the same way
except it highlights the entirety of any lines that contain the matches. This
is what I used in Figure 43 to highlight the Regexp TODO BUG
.
Of course you can remove any of the highlighting you’ve applied, with
M-s h u
(unhighlight-regexp
). It will prompt you to select
one of the patterns you’ve used and it will eliminate that one. With a prefix
arg, it will remove all the patterns you’ve used in this Buffer.
I mostly use Hi-Lock transiently throughout the day. turning it on and off to
enhance my focus as I work, but you can also set up persistent highlighting for
a given file that will be automatically applied every time you visit the file.
Visualizing Whitespace
Whitespace—spaces, tabs, newlines, blank lines—is a big component of your
text, but it can be an annoying component, mostly because it can be hard to tell
these characters apart.250 Sometimes you don’t care about such subtle
distinctions, but sometimes, depending on what kind of program will be consuming
your text, you need to.
M-x
whitespace-mode
is a Minor Mode that can help by displaying the
various sorts of whitespace with a subtle (or not so subtle) differentiation.
In Figure 44 I’ve toggled it on.
Spaces are shown as a centered dot in a gray background, which makes the excess
spaces between “until” and “there” more noticeable; the space between “world”
and “will” is a non-breaking space, and is shown differently. Newlines are
shown as a gray dollar sign, and there’s a TAB character after the question mark
shown as a right-pointing guillemet.
These are all pretty subtle, so that whitespace-mode
isn’t too jarring to use.
But the trailing spaces on line 2 really stand out, as does the trailing blank
line at the end of the Buffer, since these are considered to be always
offensive.
You can use M-x
customize-group
whitespace RET
to change these Faces
if you want them to be more or less noticeable.
whitespace-mode
has a lot of options that you can customize, and you can also
interactively tweak them on and off in a given buffer with
M-x
whitespace-toggle-options
— type ?
at the prompt.
If you want whitespace-mode
on all the time in all your Buffers, you can use
M-x
customize-variable
global-whitespace-mode
. Personally I only
occasionally turn whitespace-mode
on, but it’s very handy when I need it.
However, I do want to always see trailing whitespace at the ends of lines, since
it annoys me and I want to clean it up. You don’t need whitespace-mode
for
this; just do M-x customize-variable show-trailing-whitespace
.
It’s easy to get rid of trailing whitespace when you notice it (as you will,
with this setting): M-x
delete-trailing-whitespace
will delete all
trailing whitespace in your Buffer, including all blank lines at the end of the
Buffer. If the Active Region is enabled, only the text in the Region is
processed. You could put this function in before-save-hook
so that these are cleaned up every time you save, but that’s a little too
helpful for my tastes.
Manipulating Plain Text
Emacs’s many modes and applications represent structured data as plain text. In
this chapter we’ll look at some commands that are useful for manipulating text
in a variety of domains and Modes. For other facilities that are most useful
for prose, see Emacs for Writers.
Mass Line Deletions
Data is often arranged in the form of lines, and a frequent operation is to
reduce it: either by deleting certain lines or by keeping only others (which
amounts to the same thing). You can delete all the lines after Point that match
a Regular Expression in one stroke with M-x
flush-lines
, or the
converse with M-x
keep-lines
. Complete lines are deleted (or kept)
regardless of how much text your Regexp matches: M-x flush-lines RET foo
deletes
all the lines that contain foo
anywhere in the line.
Both of these functions instead operate on the Region if it is Active.
Your Regexp can cross line boundaries like, say, foo[[:space:]]+bar
, which will
match foo
and bar
separated by whitespace, including newlines; in this case the
entirety of all the lines containing the match will be deleted.
Emacs makes a distinction between deleting and killing: text that’s deleted is
simply thrown away251, while text that’s killed is put on the Kill Ring and so can
be yanked back.
There’s a variation on flush-lines
called
M-x
kill-matching-lines
, which works in exactly the same way except
instead of deleting, it kills the lines, so they are pushed onto the Kill Ring
in one bunch. This makes it a good way of moving a bunch of discontiguous
lines, or even of copying them, if you immediately Undo after killing them.
M-x
delete-duplicate-lines
is a powerful function that deletes all
but the first of any identical lines in the Region. So if the Region contains
the eight lines in column one of Table 40, then after
M-x
delete-duplicate-lines
it will contain only the lines in column two.
Before | After |
---|---|
foo | foo |
bar | bar |
baz | baz |
bar | zap |
bar | |
zap | |
foo | |
baz |
You’ll note that the order of the remaining lines stays the same, so this
isn’t simply C-u M-| sort -u
….
Sorting Lines
Emacs has a powerful set of commands that sort lines, distinguished by how they
interpret the sort field.
The simplest is M-x
sort-lines
, which uses the entire line as the
sort field. M-x
sort-fields
sorts based on whitespace-separated
fields within the line; use a numeric argument to specify which field; the
default is 1. M-x
sort-numeric-fields
works the same way, but
interprets the contents of the sort fields numerically. In both cases, if you
specify a negative field number, it means to count the fields from the right, so
C-u -1
would sort on the last field in each line.
Here are some examples. In column one of Table 41, I generated 10
random words and paired them with 10 random numbers. Columns 2-4 illustrate
different sorts.
Random | sort-lines |
C-u 2 sort-fields |
sort-numeric-fields |
---|---|---|---|
sort-fields |
C-u 1 sort-numeric-fields |
||
C-u 1 sort-fields |
|||
16 honkers | 16 honkers | 34 France | 2 err |
39 oysters | 2 err | 5 Madge | 3 cuddling |
99 disheartening | 3 cuddling | 59 corny | 5 Madge |
5 Madge | 34 France | 45 cranks | 16 honkers |
2 err | 39 oysters | 3 cuddling | 34 France |
3 cuddling | 45 cranks | 99 disheartening | 39 oysters |
59 corny | 5 Madge | 2 err | 45 cranks |
57 huskiest | 57 huskiest | 16 honkers | 57 huskiest |
45 cranks | 59 corny | 57 huskiest | 59 corny |
34 France | 99 disheartening | 39 oysters | 99 disheartening |
Note that in this example, sort-lines
would happen to be the same as
sort-fields
, which is also the same as C-u 1 sort-fields
. In column 3, France
comes first because the sorting functions all work case-sensitively, and
upper-case letters precede lower-case letters. sort-numeric-fields
is the same
as C-u 1 sort-numeric-fields
.
All of these sorts are what programmers call stable sorts: that is, the
relative order of records with equal keys is maintained. This means you can
sort a Region again to achieve a sub-sort.
M-x
sort-columns
lets you indicate the sort field as a rigid range
of (single-character) columns. You do this by effectively defining the sort
fields via a Rectangle: the upper-left-hand corner of the rectangle determines
the starting column the sort field, the width of the Rectangle in characters
determines the its width, and the height of the Rectangle in lines determines
the range of lines to sort.
Consider this (slightly modified) excerpt from the table of contents of the
Emacs Manual. We want to sort these lines by the heading (e.g. “Basic Undo”),
ignoring the summary descriptions. We can’t use sort-lines
because the numbers
will result in no change to the order. We can’t use C-u 2 sort-fields
because
some of the headings are two words long and some aren’t: we want “Basic Help” to sort before
“Basic Undo”, but sort-fields
is sorting only on the second field, so all the
“Basic”’s will retain their relative order, due to the stability of the sort.
1 Erasing:: Deleting and killing text. 2 Basic Undo:: Undoing recent changes in the text. 3 Basic Help:: Asking what a character does. 4 Basic Files:: Visiting, creating, and saving files. 5 Blank Lines:: Making and deleting blank lines. 6 Position Info:: What line, row, or column is point on? 7 Arguments:: Numeric arguments for repeating a command N times. 8 Repeating:: Repeating the previous command quickly. 9 Continuation Lines:: How Emacs displays lines too wide for the screen.
The solution is to set the Mark in front of “Erasing” and Point in front of
“How” on line 9, defining a Rectangle that encompasses the entire width of the
columns we want to use as the sort field. Now M-x
sort-columns
will
sort the lines correctly, resulting in:
7 Arguments:: Numeric arguments for repeating a command N times. 4 Basic Files:: Visiting, creating, and saving files. 3 Basic Help:: Asking what a character does. 2 Basic Undo:: Undoing recent changes in the text. 5 Blank Lines:: Making and deleting blank lines. 9 Continuation Lines:: How Emacs displays lines too wide for the screen. 1 Erasing:: Deleting and killing text. 6 Position Info:: What line, row, or column is point on? 8 Repeating:: Repeating the previous command quickly.
Ignoring Case Distinctions
I mentioned that the sort commands are case-sensitive, which is why France comes
first in the C-u 2 sort-fields
example above. You can sort in a
case-insensitive manner as well, but it’s a little awkward: you have to change
the variable sort-fold-case
from its default of nil
to t
:
M-x set-variable RET sort-fold-case RET t
You’ll have to remember to change it back to nil
unless you’re happy with
case-insensitive sorting for the rest of your session. If you like, you could
make that variable Buffer Local before changing it, with
M-x
make-variable-buffer-local
.
Reversing Lines
You may have noticed that there seems to be no way to sort in reverse order, and
you’re right. But you can always just reverse the order of all the lines you
just sorted with M-x
reverse-region
. reverse-region
can of course
also be used on unsorted lines.
Numbering Lines
linum-mode
and global-linum-mode
display line numbers in the Fringe, but you may need to occasionally actually
insert line numbers into your text. We’ve already discussed two ways to do
this: using a counter in a Keyboard Macro, or using
C-x r N
(rectangle-number-lines
), which is usually easier:
see Rectangles.
Whitespace and Blank Lines
Whitespace and blank (empty) lines are a common feature of most Buffers.
Whitespace encompasses several distinct but easily confused characters, most
notably the space (ASCII 32 or #x20) and tab (C-i
, ASCII 9 or #x09). Those two
are confusing enough already without throwing in the formfeed (C-l
, ASCII 12 or
#x0C) and the little known vertical tab (C-k
, ASCII 11 or #x0B). The newline
(C-j
, ASCII 10 or #x0A) and carriage return (C-m
, ASCII 13 or #x0D), the two
possible line terminators, also count as whitespace in some contexts. And then
there are all the Unicode whitespace characters, like the en and em spaces, the
thin and hair spaces, and the whole family of non-breaking spaces!
The mere visibility of these characters and how to distinguish them on the
screen is its own topic.
It’s no wonder there are several commands for dealing with whitespace; see also
the related topic of Filling and Indenting.
Tabs vs. Spaces
Inserting a space is as simple as hitting the space bar (SPC
), but how do you
insert a tab character? It’s not as simple as hitting the tab key, because TAB
is typically bound to a special command for indenting lines; even in
fundamental-mode
it’s bound to
indent-for-tab-command
. The guaranteed way to insert a
single, actual, tab is via C-q
(quoted-insert
) followed by
the TAB
key (see Inserting Non-Printing Characters).
Probably more common than needing to insert a guaranteed tab is needing to
remove them. Tabs often cause problems in data files and source code for
languages that are especially picky about indentation252. Of course it’s
easy to change each tab to one space with
M-%
(query-replace
), but what if you want to preserve the
relative horizontal spacing? The M-x
untabify
command will replace
all the tabs in the region with one or more spaces, preserving the horizontal
spacing. That is, any given tab will display as one or more spaces to expand to
the next tab stop; untabify
reifies each tab into as many actual spaces as it
takes to reach the same tab stop.
If you’re confused, or just never understood that Silicon Valley episode, see
Jamie Zawinski’s explanation.
Horizontal Whitespace
Sometimes your Buffer will contain several horizontal whitespace characters in a
row, like 5 spaces or a space and a tab. There are two handy ways to get rid of
the excess. M-
eliminates all the
whitespace around Point, while M-SPC
(just-one-space
)
replaces it all with just one actual space character (with a numeric Arg, it
replaces them with exactly that many spaces). Note that these two commands only treat
in spaces and tabs, but not any of the more exotic whitespace characters like
formfeeds and non-breaking spaces.
If you’re like me and consider trailing whitespace—i.e., whitespace
characters following the last non-whitespace character on a line—to be, in
general, an intolerable offense, you can rid yourself of all of these within
the Region with M-x
delete-trailing-whitespace
. This command works
on all horizontal whitespace characters except formfeeds.253
Blank Lines
Blank lines and empty lines also have some handy commands. You can of course
create a new empty line by hitting RET
(newline
) a few times; this takes
the usual numeric Arg so you can insert, say, four new lines with C-u RET
or
seven with C-u 7 RET
. This leaves Point after the last newline. Sometimes you
want Point to be before the new newlines, which is what
C-o
(open-line
) is for. It’s especially useful for working
with Rectangles, Picture Mode, and Artist Mode, where you need a big block of
blank lines in which you can do two-dimensional things.
C-x C-o
(delete-blank-lines
) is the inverse of C-o
: when
Point is in the middle of a bunch of consecutive blank lines, C-x C-o
reduces
them to just one blank line; an additional C-x C-o
removes that remaining blank
line too.
What’s the difference between a blank line and an empty line, exactly? An empty
line is what you get when you have two newlines in a row: to be precise, two
newlines with an empty string between them. A blank line is two newlines with
nothing but zero or more whitespace characters between them. So a line full of
nothing but spaces and tabs is a blank line, but not an empty line.
There’s a variant of C-o
that splits a line in two, vertically rather than
linearly: C-M-o
(split-line
). Here Point is represented by |
:
Lorem ipsum dolor sit amet, |consectetuer adipiscing elit.
The result of a C-M-o
would be:
Lorem ipsum dolor sit amet, | consectetuer adipiscing elit.
M-^
(join-line
) (a.k.a. delete-indentation
) joins the current
line (containing Point) to the end of the previous line, regardless of Point’s
exact location in the current line. It ensures that there will be one space
between the joined lines; Point is positioned at that space (which you could
immediately eliminate with M-
).
This all means that if you repeatedly invoke M-^
, it will join together several
previous lines, going backwards. So if Point is in front of “baz”:
foo bar |baz
two M-^
’s will result in:
foo| bar baz
Indenting Lines
Indentation—that is, the presence or absence of whitespace at the beginning of a
line—is an annoyingly complex topic. Fortunately, it’s less complex than it
used to be decades ago, but Emacs of course still supports all the old-school
complexity. I think we can ignore most it!
Indentation is primarily a concern when you’re editing structured text:
programming languages, like Elisp or Python; data interchange languages, like
JSON; or markup languages, like HTML and Latex. Emacs has a Major Mode
for almost every such language you might need to work with, and these Modes
understand the indentation requirements or conventions and handle it for you.
Mostly, it boils down to this: just hit TAB
(wherever you may be
in the line) to indent the current line correctly.
The topic is most complex when you’re editing prose in a Major Mode like
text-mode
. But who edits plain text prose anymore?
Decades ago I used text-mode
all the time, but I probably haven’t used it for 10
or more years. Now I do all my prose in the amazing Org Mode, which uses a form
of structured text that makes straight prose more readable than text-mode
, and
yet lets me publish it as plain text, HTML or a PDF254 with a keystroke.
And as a structured text mode, Org handles indentation automatically: I just hit
TAB
.
So the only kind of indenting I’m going to discuss here is rigid indentation,
which you may occasionally need to do in any random mode. The main command is
C-x TAB
(indent-rigidly
): just set the Region around a bunch
of lines, and C-x TAB
will prompt you:
Indent region with, , S- , or S- .
You’re in a transient mode for as long as you hit any unbroken sequence of the
mentioned keystrokes; typing any other key will exit the mode (and do whatever
that other key is supposed to do).
and
will indent or dedent, respectively, the whole block of lines
one column at a time. The shifted versions will move in larger jumps of 8
columns at a time.255 With a positive or negative numeric argument, it will
increase or decrease the indentation by exactly that many characters. The
related command C-M-
( indent-region
),
with a numeric argument, will re-indent all the lines in the Region to the
column indicated by the argument: C-u 12 C-M-
will leave you with all the lines
indented 12 spaces from the left, regardless of how much each line was already
indented.
The command M-m
(back-to-indentation
) conveniently moves
Point to the first non-whitespace character on the line: it’s like a
C-a
for indented lines.
Tabs and Tab Stops
In many Major Modes, TAB
is bound to
indent-for-tab-command
, which typically256 causes Emacs to
insert enough whitespace to move Point to the next tab stop. A tab stop is one
of a set of specific column numbers or horizontal positions, the idea being to
use them to line your text up in columns.
If there are no explicit tab stops defined, the default is every 8
columns.257 You can define tab stops at arbitrary positions (for the
current Buffer) by invoking M-x
edit-tab-stops
.
Frankly, tab stops are not much used anymore, because, as mentioned above,
people tend to use markup languages instead of manually laying out plain text.
So I’ll say no more on this topic.
However, since TAB characters cause problems—they’re hard to distinguish from
runs of spaces, their displayed width varies depending on the tab stops so they
can seem to have different widths to different people, and their presence can
confuse certain programs—I recommend telling Emacs never to implicitly insert them, and
to always use runs of spaces instead; this Init File snippet does that. Because
EIPNIF, you can of course always insert a real tab with C-q TAB
.
(setq-default indent-tabs-mode nil) ; don't insert tabs
Since you might encounter tabs in a file authored by someone else, you can
readily convert all tabs in the Region to equivalent runs of spaces with
M-x
untabify
; the inverse (rarely needed) is M-x
tabify
.
Case Changing
There are three ways to change the case of your alphabetic text: converting it
to all-uppercase, to all-lowercase, and to capitalize the first letter of each
word. There are two modes of invoking these case changes: by word or by region.
Word | Region | |
---|---|---|
Upcase | M-u (upcase-word ) |
C-x C-u (upcase-region ) |
Downcase | M-l (dowcase-word ) |
C-x C-l (downcase-region ) |
Capitalize | M-c (capitalize-word ) |
M-x capitalize-region |
The by-word commands change the case of the next word (leaping over intervening
non-alphabetic characters), or with a prefix arg, the next (N) words (a negative
argument works backwards); Point moves across each converted word. So you can
upcase the next several words in a row with repeated invocations of M-u
, for example.
The by-region commands operate on the Region without moving Point. Note that
upcase-region
and downcase-region
are Disabled by default, just because
beginners, who aren’t comfortable with how easy it is to Undo changes, are often
disturbed when they accidentally change the text of their entire thesis to all
uppercase.
Tables
Emacs has a powerful set of commands for creating and editing plain-text
tables. Here’s a plain-text version of the Verlaines discography from Wikipedia:
+-------+------------+----------------+-------+-------------+--------+ |Date of|Title |Label |Charted|Certification|Catalog "http://www2.lib.uchicago.edu/"Release"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Number | +-------+------------+----------------+-------+-------------+--------+ |1985 |Hallelujah |Flying |- |- |FN040 / "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"All the |Nun/Homestead "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"HMS138 "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Way Home "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |1987 |Bird Dog |Flying |- |- |FN077 / "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Nun/Homestead "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"HMS095 | +-------+------------+----------------+-------+-------------+--------+ |1987 |Juvenilia |Flying Nun |- |- |FN COMP "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"02 | +-------+------------+----------------+-------+-------------+--------+ |1989 |Some |Flying |- |- |FN129 / "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Disenchanted|Nun/Homestead "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"HMS162 "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Evening "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |1991 |Ready to Fly|Slash |- |- |C30718 | +-------+------------+----------------+-------+-------------+--------+ |1993 |Way Out |Slash |- |- |D31032 "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Where "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |1996 |Over the |Columbia |- |- |486880.2"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Moon "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |2003 |You're Just |Flying Nun |- |- |FNCD476 "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Too Obscure "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"for Me "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |2007 |Pot Boiler |Flying Nun |- |- |FNCD501 | +-------+------------+----------------+-------+-------------+--------+ |2009 |Corporate |Dunedinmusic.com|- |- "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Moronic "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |2012 |Untimely |Flying Nun |- |- |FNCD524 "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Meditations "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+ |2020 |Dunedin |Schoolkids |- |- |SMR-060 "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"Spleen |Records "http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/"http://www2.lib.uchicago.edu/" +-------+------------+----------------+-------+-------------+--------+
I created this by simply cut-and-pasting the Wikipedia table from the web page,
which results, in my Buffer, in one line per row, with columns separated by tab
characters. I set the Region around this and invoked
M-x
table-capture
and got the result you see above.
There are commands to split, merge, enlarge, and shrink cells, edit easily
within a multi-line cell, justify cell contents, insert and delete rows and
columns: it’s very powerful.
The only question is, who needs attractive plain-text tables now that most
documents are “typeset” from a markup language like LaTeX or Org Mode? Org
Mode, in fact, has its own powerful markup for tables which in my opinion is
much nicer to use—it’s in many ways more powerful258, though these
plain-text tables are probably easier for multi-line cells.
The main use, nowadays, for this facility is probably for programmers who want
to insert plain-text tables into comments in programming language source code.
If you need these, see “Text Based Tables” in the Emacs manual.
Folding Text
It can be very useful to fold or collapse some of your text in order to
ignore or to focus on certain parts, or to get an outline-like high-level overview.
Emacs provides several subsystems to do this. They can be divided into two
categories: one in which you must explicitly impose an outline- or tree-like
markup to your text ahead of time, and the other which recognizes and folds text
based on its implicit structure.
Markup-Based Folding
Emacs has had markup-based folding since the very beginning in the form of
Outline Mode; it’s basically Text Mode plus extremely simple markup to express
your text in the form of an outline, which brings the ability to fold and unfold
the headlines of the outline.
Outline Mode has additional commands to navigate by headline, and move headlines
(and their folded components) up or down, or in and out (demoting or promoting
them, headline-wise).
It’s a big payoff for such a trivial amount of markup. But for most Emacsers,
Outline Mode has been rendered obsolete by Org Mode.
Org Mode is like Outline Mode on steroids: it does exactly what Outline Mode
does, with the same markup, but adds hundreds of additional features. If you
think Outline Mode sounds useful, just skip directly to Org Mode instead: it’ll
be an improvement even if you aren’t interested in its extra features.
Org Mode gets an entire chapter to itself; see Org Mode for details.
Implicit Folding
The problem with markup-based folding is of course the markup. But lots of text
has implicit structure that Emacs can exploit for folding without your having to
add any. Most programming languages, for example, have an implicit tree
structure eminently suitable for folding. But even simple indentation can be
used for folding purposes.
Hideshow Minor Mode
Hideshow Minor Mode is the high-level built-in mechanism for implicit folding.
When enabled, you can fold function definitions in the source code of many
programming languages. Consider this Python function from Wikipedia:
def qsort(L): if L == []: return [] pivot = L[0] return (qsort([x for x in L[1:] if x < pivot]) + [pivot] + qsort([x for x in L[1:] if x >= pivot]))
With Point anywhere in the definition, you can fold it with one keystroke into
this:
Note the ellipsis ...
at the end of the line, which indicates the presence of
hidden folded text under this line (the dots are just for display and are
not actually actually added to your text).
Motion commands will skip over the ellipsis as if it were one character wide.
As with all the Emacs text folding subsystems, the invisible text is still
there: you can search into it (which will unfold it), and if you copy a region
that includes the folded text, the copied text contains all the hidden text as
well; if you save the Buffer’s file when some of the text is folded, you are of
course saving all the hidden text as well, and there’s no indication in the file
that the text was folded (the next time you open the file, all your text will be
there, unfolded).
You can unfold anything you’ve folded, and you can also fold and unfold all the
top-level functions in one go. A Buffer consisting of hundreds of lines of
code, when completely folded, would look something like:
def writable(path):... def myurlopen(url, count = 0):... def httpopen(scheme, hostport, path, parms, query, frag, count = 0):... def snarf(url, clone):... # checkout a locked version from rcs def co(clone):... # checkin (ci -l) def ci(clone):...
Truth be told, I don’t like Hideshow. For one thing, the default keybindings
are just unusable. But this being Emacs, that’s easily fixed. The bigger
problem is that it doesn’t work very well. It seems to work fine in
python-mode
, but in c-mode
it does a
bad job of recognizing function definitions, and it doesn’t work at all for my
favorite (non-Lisp) programming language, OCaml (which has an admittedly very
free-form syntax). This is why I use the third-party library Yafolding instead;
see below.
See “Hideshow” in the Emacs manual for more information. If you want to use
it, try this Init File snippet that adds two usable key bindings for the most
commonly used commands:
;; Hideshow for folding in programming modes (add-hook 'prog-mode-hook 'hs-minor-mode) ;; from: Joseph Eydelnant (defvar ue-hs-hide nil "Current state of hideshow for toggling all.") (defun ue-toggle-hideshow-all () "Toggle hideshow all." (interactive) (setq ue-hs-hide (not ue-hs-hide)) (if ue-hs-hide (hs-hide-all) (hs-show-all))) ;; add usable key bindings (with-eval-after-load 'hideshow ;; toggle hiding this block (define-key hs-minor-mode-map (kbd "C-" ) 'hs-toggle-hiding) ;; toggle hiding all blocks in buffer (define-key hs-minor-mode-map (kbd "C-M-" ) 'ue-toggle-hideshow-all))
Yafolding Mode
Zeno Zeng’s Yafolding Mode is the package I prefer for folding text. It works
great in every programming language I’ve tried, including OCaml with its nested
function definitions expressed without any braces, because it just works based
on indentation, which almost all programmers use consistently.
I only use two of its commands:
C-
(yafolding-toggle-element
) to toggle the folding
of the “element” (typically a function definition) at Point, and
C-M-
(yafolding-toggle-all
) to toggle the folding of
every element in the Buffer. This Init File snippet will set it up:
(unless (package-installed-p 'yafolding) (with-demoted-errors "%s" (unless package-archive-contents (package-refresh-contents)) (package-install 'yafolding))) (add-hook 'prog-mode-hook (lambda () (with-demoted-errors "%s" (yafolding-mode +1))))
Selective Display
The simplest, but lowest level, text folding command is
C-x $
(set-selective-display
). It’s very old, and Yafolding
does the same thing in a much friendlier manner. But for reasons of historical
interest, here’s how Selective Display works.
Given a numeric argument of (N), C-x $
folds all lines that are indented more
than (N) spaces. Suppose your Buffer contains this simple outline-like text:
Folding Text Markup-Based Folding Outline Mode Org Mode Implicit Folding selective display Hide / Show Minor Mode 3rd-party yafolding
These lines are indented in steps of two, with the first line not indented at
all. So C-u 1 C-x $
would hide all lines but the first:
Folding Text...
To unfold and reveal all your text, invoke C-x $
without any argument.
Line-based motion commands like C-n
, C-p
,
, and
skip over the folded
text, but other commands will move into it, including searching. If you find
yourself lost in the folded text, just unfold it.
If you invoke C-u 3 C-x $
it will hide all the lines with indentation of 3 or
more spaces:
Folding Text Markup-Based Folding... Implicit Folding...
Having to count the spaces in the indentation is an awkward step. This
alternative function automates the process. If you like it, you can use it to
replace the standard command with:
(global-set-key [remap set-selective-display] 'ue-auto-selective-display)
but it’s really just a poor man’s Yafolding.
(defun ue-auto-selective-display (arg) "Hide lines with greater indentation than this one. With a prefix ARG, reveal all lines. This function simply sets `selective-display'." (interactive "P") (if arg (setq selective-display nil) (save-match-data (save-excursion (forward-line 0) (if (looking-at (rx (+ space))) (setq selective-display (1+ (length (match-string 0)))) (setq selective-display 1))))))
International Character Set Support
Emacs has very sophisticated support for international languages and the
character sets and encodings used to represent them. This is one of the more
complex Emacs topics: there are 23 pages devoted to it in the manual and I
won’t attempt to cover all of it here. I’ll describe the most useful facilities
for a mostly-monolingual Emacs user, from my perspective as an English speaker.
In the earliest days of computing, the only characters you could use were the
upper case Latin alphabetics, the base 10 digits, and a handful of punctuation
characters. Pretty quickly, non-English speakers and users of non-Latin
alphabets, syllabaries, and logographies—various scripts—defined their own
mutually incompatible character sets, and a Tower of Babel reigned.
You would think that, since the polyglot Unicode is now the standard, with its
support for 160-odd historical and modern scripts and over 150,000 characters,
symbols, and emojis, there would be no need to handle any other character sets,
but in addition to legacy data, Unicode is not yet completely dominant. In
particular, users of Chinese, Japanese, Korean, and Cyrillic scripts still use
non-Unicode character sets for various reasons. While most text editors support
Unicode, they may only support Unicode (and sometimes only Unicode’s UTF-8
encoding).
Emacs supports 1,071 character sets and
encodings, including Unicode and ISO-2022 (which allows you to switch between
different character sets in a given Buffer or File). It also handles
bidirectional text: that is, you can combine scripts that are written from right
to left (like Arabic or Hebrew) with text written from left to right (like
English). For a quick demonstration of all this, invoke
C-h h
(view-hello-file
).
Emacs also supports 212 input
methods, which are ways of entering characters that might not have keys on your
keyboard, including both natural language scripts and various types of symbols
(e.g. mathematical). You can see all of them via
M-x
list-input-methods
. The Package Manager has
17 additional input methods.
Language Environment
You can enter or view any kind of text in any script in any Buffer at any time.
That is, you can have, say, Latin, Cyrillic, Hebrew, and Tamil scripts all mixed
together; the buffer popped up by C-h h
is a perfect
example—see Figure 45.
But Emacs always has a notion of your default language environment. Normally,
your operating system defines this259 and Emacs inherits it. (If your OS
sets it wrong, or you just prefer a different one for Emacs, you can override
it; see “Language Environments” in the Emacs manual.) Your language
environment determines which character sets (Emacs calls them
coding systems) are assumed as
defaults for the files you create and edit, the script used to represent such
text (and therefore an appropriate font for that script), and a way of
interpreting your keyboard to enter the glyphs that comprise the script.
If your OS has declared your correct language environment and you have the
necessary fonts installed, everything in Emacs should work out of the box.
You can browse all the language environments with
C-h L
(describe-language-environment
); here’s what you’ll see
if you choose Czech:
Czech language environment This language environment is almost the same as Latin-2, but sets the default input method to "czech", and selects the Czech tutorial. Sample text: Přejeme vám hezký den! Input methods (default czech) czech ("CZ" in mode line) czech-prog-3 ("CZ" in mode line) czech-prog-2 ("CZ" in mode line) czech-prog-1 ("CZ" in mode line) czech-qwerty ("CZ" in mode line) Character sets: ascii: ASCII (ISO646 IRV) latin-iso8859-2: Right-Hand Part of ISO/IEC 8859/2 (Latin-2): ISO-IR-101 Coding systems: iso-8859-2 (‘2’ in mode line): ISO 2022 based 8-bit encoding for Latin-2 (MIME:ISO-8859-2). (alias: iso-latin-2 iso-8859-2 latin-2)
The most practically useful section of this information is the list of input
methods, which in this case are systematic ways for someone who works primarily
in Czech to enter characters from the Czech script.
Inserting the Occasional Funny Character
But first let’s discuss the non-systematic way to enter characters: that is,
characters that aren’t a normal part of your spoken language’s script, ones that
you only occasionally need to type. This includes typographical symbols like
the pilcrow or paragraph symbol ¶, the copyright symbol ©, emojis. and the odd
character from some other language with a different script. With no disrespect
to natural languages other than your own, I’ll call all of these funny
characters.
The easiest way to insert these characters is with
C-x 8 RET
(insert-char
), which uses Completion to prompt you
for the name of a Unicode character. Usually you can just narrow the enormous
list of 45,000-odd candidates by typing words from their official long Unicode
name—the word “paragraph” will narrow the list to 10 different paragraph
symbols, and you’ll see the Pilcrow you want near the elegant Ethiopic Paragraph
Separator. If you know the Unicode code-point (a hexadecimal number), you can
enter that instead.
The C-x 8
prefix has a whole slew (close to 200) of other convenient key
bindings to insert common funny characters. For example, C-x 8 C
inserts the
copyright symbol; C-x 8 [
and C-x 8 ]
insert the left- and right-curly single
quotation marks, etc. I don’t actually know any of these and just use C-x 8 RET
for
everything I need (my completion system puts the ones I use regularly at the top
of the list). To see the complete list of shortcuts, type C-x 8 C-h
(or
C-h b
(describe-bindings
) and search for “C-x 8” in that
Buffer).
Input Methods
If you’re typing in a language that uses a lot of diacritical marks. like Czech,
or a completely non-Latin script, like Ukrainian, you’ll be typing C-x 8
way too
much. Instead, you want to use an input method. An input method causes Emacs
to translate the ordinary ASCII characters of your keyboard into non-ASCII characters.
Broadly, there are two kinds of input methods. One kind remaps all (or many) of
your normal keyboard keys, often to match the typical hardware computer keyboard
that would be used by the user of a given language; the input method Emacs calls
ukrainian-computer
matches the Ukrainian keyboard in Figure
46.260
So to enter the Ukrainian φ character, you would just press the a
key, and to
enter the Ukrainian E
you press the T
key.
If Ukrainian is your default language environment, this input method will be
your default.
But perhaps you’re an English speaker with a default English language
environment who also speaks Ukrainian and therefore sometimes types large amounts
of Ukrainian text. To solve this problem, you can change the input method
associated with a given Buffer with
C-x RET C-
. After switching away from
your default like this, a simple C-
will toggle back and forth between the two; use C-u C-
to change to yet another
input method.
Another use for the broad type of input method is to use a non-standard keyboard
layout for your default language environment, like the well-known Dvorak
kayboard layout for English, regarded as superior to QWERTY by its partisans.
Just do C-x RET C-
and specify english-dvorak
.
The second, less broad, kind of input method only changes a few ASCII characters
and treats them as Prefix Keys that you can use to enter funny characters. For
example, there are several input methods for entering the characters of the
International Phonetic Alphabet (IPA) used by linguists, and by lexicographers to
indicate pronunciation in dictionaries, whereas the tex
input method changes only a few
characters (mostly ,
^
, and $
) into prefixes to enter close to 2,000 funny
characters, including many technical and mathematical ones, like exists
for
(exists) and lambda
for (lambda); you can use TAB
to complete these.261
I use latin-1-postfix
as my default transient input method (the one that C-
will switch to by default); this makes it easy for me to enter the occasional
foreign language262 proper noun by making all the ASCII characters that
are typically accented in Western European Latin-script languages into prefixes.
So after enabling latin-1-postfix
with C-
, I can more easily type the French
word déçût: when I typed “e” Emacs reminded me, in the Echo Area, of the
possible stand-ins for accents, displaying: e["http://www2.lib.uchicago.edu/"/^`]
—I then typed '
, the pair
of which became “é”—and when I typed “c” I saw the reminder c[,]
and added the
comma to get “ç”, etc.; see Table 41. Typing an e
followed
by some character other than any of the special e-accent stand-ins just gives
you a plain e
followed by that character—so et
for example comes out as
et
—, and if you need to type an e
followed by one of the stand-ins, you just
double the stand-in, so e^^
gives me e^
rather than ê
. It’s an easy to learn
system, even if you don’t use it much.
Keystroke | d |
e |
' |
c |
, |
u |
^ |
t |
Buffer Contents | d |
de |
dé |
déc |
déç |
déçu |
déçû |
déçût |
Echo Area | e["http://www2.lib.uchicago.edu/"/^`] |
c[,] |
u["http://www2.lib.uchicago.edu/"^`] |
Table 42 summarizes some of what the latin-1-postfix
Input
Method can do.
Accent | Postfix | Examples |
---|---|---|
acute | ' |
a' → á |
grave | ` |
a` → à |
circumflex | ^ |
a^ → â |
diaeresis | " |
a" → ä |
tilde | ~ |
a~ → ã |
cedilla | , |
c, → ç |
nordic | / |
d/ → ð ; t/ → þ ; a/ → å ; e/ → æ ; o/ → ø |
others | / |
s/ → ß ; ?/ → ¿ ; !/ → ¡ ; // → ° |
various | << → « ; >> → » ; o_ → º ; a_ → ª |
There’s also a latin-1-alt-postfix
Input Method that’s only slightly different
(thought by some to be more convenient), and a latin-1-prefix
Method in which
you type the activating punctuation mark before the letter. There are a couple
of dozen more -prefix
and -postfix
Input Methods suited to various other
combinations of scripts.
Coding Systems
Emacs supports 267 coding systems, but they only really
come into play when you read (visit) or write (save) a file, because data in
memory is represented in an internal format known only to Emacs; at the
transition between Emacs and the file system, Emacs has to translate to or from
a coding system.263
Emacs can recognize some coding systems automatically when you visit a file, or
when you save a file after editing, but some sequences of bytes in text are
inherently ambiguous. When this occurs, Emacs will choose based on an order
of preference if possible; otherwise you’ll be offered a list of compatible
coding systems and asked to identify the correct one. When Emacs chooses one for
you, you can find out which one it is with
M-x
describe-current-coding-system
, and if you disagree, you can
change it with C-x RET r
(revert-buffer-with-coding-system
).
You can force a persistent specific coding system for a particular file in two
ways: via a File-Local Variable or, more broadly, set it according to a file
extension. For example, to specify Chinese BIG5 via a File-Local Variable, you
could add this line to the top of the file:
-*- coding: big5; -*-
Or, if all your .txt
files are in BIG5, you could specify that in the
auto-coding-alist
variable. That variable is flexible
enough to specify a coding system for just one file, or all the files in a given
directory, regardless of their extension.
Line Endings
One final wrinkle concerns line endings: the way text encodes where lines break.
This is independent of the coding system and is indicated by control
characters. There are three different ways to indicate a line ending:264
- unix
- use a control-J (ASCII 10 = #x01 =
^J
) aka linefeed - mac
- use a control-M (ASCII 13 = #x0D =
^M
) aka carriage return - dos
- use a pair of carriage return followed by linefeed (
^M^J
) aka CRLF
As the names suggest, these three different line-endings are mandated
by the three major families of operating systems. If you are a
Windows user and receive a file created by a Macintosh user, you
might have trouble distinguishing the breaks between lines because
they are encoded differently. How massively annoying!
The good news is, the Unix operating systems265 have mostly won
this battle266. Apple switched from its carriage return line
endings after 2001, when they rewrote the Mac OS operating system and
based it on Unix, inheriting the linefeed. So the unix category above
includes Mac OS X, and the mac category only includes old
unconverted Classic Mac OS data.
Unfortunately, Microsoft Windows is still sticking to its CRLF line endings
(inherited from MS-DOS in 1985), by far the most awkward of the three.
As a result of all this, every one of the 267 coding
systems comes in all three flavors of line endings: so there’s utf-8-unix
,
utf-8-mac
, and utf-8-dos
; also big5-unix
, big5-mac
, and big5-dos
; and so on.
You don’t usually need to specify the full names of the coding system and can
just say utf-8
and big5
and the like—they will default to your operating
system’s line-ending type—and Emacs will typically figure out the line endings
automatically when you read in a foreign file. But when you occasionally need
to save a file for a Windows user, you can do so by spelling it out explicitly.
Remote File Editing with Tramp
One of Emacs’s killer features is its ability to transparently edit files over
the Internet on remote computers via the Tramp subsystem. Instead of logging-in
to a remote computer (with ssh
, say) and firing up Emacs on that computer to
edit a file, you just use C-x C-f
(find-file
) with special
remote-file syntax and edit the file in your local Emacs. This means that Emacs
doesn’t even need to be installed on the remote computer!
While other editors have added a version of this feature recently,
Emacs has been doing this since at least 1989267. I believe that
Tramp supports more remote file access protocols and features than any
other editor.
Every time that Emacs asks you for a filename, you can optionally use
Tramp’s remote file syntax268. So if your username on the host
myoffice.example.com
is mary
, you might edit your file ~/txt/project.org
on that computer with:
C-x C-f /ssh:mary@myoffice.example.com:txt/project.org
It will pop up a Buffer called project.org
and editing will work
exactly like editing a local file, at local speeds. You might notice
a few messages about the network connection flash past in the Echo
Area if you’re paying attention, but otherwise it’s hard to tell you’re
editing a remote file. Backup files and auto-save files work as you’d
expect. When you save your Buffer in any of the usual ways, your
edits are written out to the remote file. You don’t have to specially
shut-down a network connection: just kill the Buffer whenever you like
(or not).
Additionally, you can visit a remote directory with C-x C-f
or
C-x d
(dired
) and it will of course come up in a
Dired buffer! All the normal Dired file management commands work as
usual. Pop up another Dired Buffer—either on that remote host, or
on your local host, or on a second remote host—and you’ve got
two-panel file management and can easily copy or move files from one
host to another.
If you run M-x
pwd
you’ll see that this Buffer’s working
directory is /ssh:mary@myoffice.example.com:txt/
. This has
interesting implications. If you visit another file from this Buffer
with C-x C-f
(or anything else) from this Buffer, the default
directory will indeed be the remote directory revealed by pwd
, so it’s
easy to pull up more remote files; if you don’t want another remote
file. just delete the remote part of the filename in the prompt.
Probably the most amazing feature is that Emacs functions that run external
commands, like M-x
grep
, M-x
shell
,
M-x
compile
, Dired’s !
(dired-do-shell-command
)
and &
(dired-do-async-shell-command
) commands, and the like
all run on the remote host, due to the default-directory
being expressed in Tramp syntax. This means all the VC version control commands
work remotely too: pull up that remote file, make your edits, diff it against an
older version, and check in your changes with the same simple VC commands you
use on local files: Tramp makes them run remotely.
Getting Started
Let’s see if Tramp works for you out of the box! The full Tramp remote
file syntax looks like:
/method:user@host#port:/path/to/file
Assuming you’re using SSH, then method will be ssh
; user will be your
remote username (I’ll use mary
); and host will be the hostname of the
remote system you’re connecting to (I’ll use myoffice.example.com
for
your hostname). If your local username is also mary
, you can skip the
user@ part of the filename (it defaults to your local username). You
can use a relative hostname (e.g. just myoffice
) if your local host’s
DNS is set up appropriately (or if you have hostname patterns
configured in your SSH configuration). If the remote SSH server is
listening on the standard port (22), you can leave out the #port
component. You can also write the method as –
if the default method
in tramp-default-method
is the one you
want269. Finally, if the /path/to/file
is in your remote home
directory, you can use a relative path (e.g. just file
). So the
shortest remote filename might be: /–:myoffice:newfile
.
But let’s issue this command:
C-x C-f /ssh:mary@myoffice.example.com:newfile
If you’re using SSH public key encryption and are running
ssh-agent(1)
, there will be no need for you to type your passphrase,
but if otherwise, Tramp will prompt you. Tramp supports completion of
most components of a remote file name.
You’ll know it worked if you get a Buffer named newfile
and no errors!
But to confirm, do M-x
pwd
in this Buffer and make sure
the output looks something like:
Directory /ssh:myoffice.example.com:/home/mary/
Troubleshooting
When both the local and the remote host are running Unix, and you’re
already set up and happily using SSH for your logins outside of Emacs,
Tramp is easy to configure and use. With non-Unix operating systems
(like Windows) or less common login protocols (like, say, telnet
(heaven forbid!)), you may need to do a little light reading.
Fortunately, the 5,203-line
Tramp manual is very well written, and Tramp maintainer Michael
Albinus is one of the most responsive and helpful developers on the
help-gnu-emacs mailing list.
In my experience270, the most common problem encountered in using
Tramp is having an exotic remote (or local) shell prompt. Tramp needs be able to
recognize your shell prompt, and does a pretty good job at it, simply
assuming that your prompt ends with one of the characters #
, $
, %
, or
>
followed by a space, which matches the defaults of most shells. If
your prompt doesn’t fit this requirement, you can fix it by changing
the value of shell-prompt-pattern
.
If you use a fancy multiline shell prompt with right-hand end-of-line
components, lots of colors, or perhaps an ASCII-art talking cow, then you may
have trouble. This is fixable by hacking your shell’s rc file to turn off all
the sexiness (only when Tramp is controlling the shell—you can still have your
crazy prompt in your interactive shells).
If you’re a zsh(1)
or bash(1)
user, using one of these lines as the first line
of your ~/.zshrc
or ~/.bashrc
on hosts that you want to Tramp into should do the
job:
# for tramp [[ "$TERM" == "dumb" ]] && unsetopt zle && PS1='$ ' && return # zsh [[ "$TERM" == "dumb" ]] && PS1='$ ' && return # bash
You can set up your fancy cow prompt after this line and it’ll work for you as
usual in interactive shells.
For more information and other tips, see “Remote shell setup” in the Tramp manual.
Tramp Methods
While the ssh
method is probably the most commonly used Tramp remote
file access method (it is for me), there are actually
35 in total.
Ignoring four that are for obsolete and insecure protocols271 and
two for Kerberos users, we can divide the remainder into four main
groups: methods for accessing files on Unix systems, methods for
accessing local files under different permission schemes, methods for
accessing specialized file systems, and methods specific to Microsoft
Windows.
Orthogonal to these four classes are two different types of
connection: inline and external.
Inline methods maintain a persistent connection to a remote host, so
even if logging in to some remote happens to be slow, after the first
connection it will be speedier. These methods are good for frequently
editing relatively small remote files, but have relatively high
overhead that may slow down access to large files: if you know you’re
about to visit a large file, you might opt for the equivalent
external method.272
External methods effectively use an additional out-of-band channel to
transfer the data (possibly storing the data in a temporary file).
These can be slower due to the need to set up and tear down the
additional channel, but faster at transferring large amounts of data.
Unix Remote Access Methods
Unix users accessing remote Unix systems will typically be happy with
these three methods.273
Method | Type | Comments |
---|---|---|
ssh | inline | Great for small files |
scp | external | Great for large files |
rsync | external | Best for large files that exist on both hosts |
Local Permission Access
Sometimes you need to access a file on your local system as if you
were a different user. Tramp makes this situation look like a remote
file access.
The most common situation for Unix users on their own
desktop machine is the sudo
method, which lets you access a file or
directory as root via the sudo(8)
program. It also allows you run a
root shell in your Emacs by visiting a file or directory as root and then
running M-x
shell
within that Buffer.
Since this family of methods run on the local host, you just leave the
hostname part of the remote filename empty,
e.g. /sudo::/etc/resolv.conf
.
The sudoedit
method is a more paranoid version of sudo
that’s more
annoying to use.
su
is similar to sudo
but uses su(8)
and allows you to edit as non-root users;
of course you have to have the ability (i.e., permission) to use su(8)
outside of
Emacs for this to work.
doas(8)
is an alternative to sudo
that is the default on OpenBSD systems.
Finally, the sg
method uses sg(8)
to let you edit files under a different
group.
Method | Type | Comments |
---|---|---|
sudo | inline | Root access |
sudoedit | external | Paranoid root access |
su | inline | Access as a different user |
doas | inline | … via doas(8) |
sg | inline | Access as a different group |
Specialized File System Access
There are a number of “file systems” that aren’t real file systems, i.e. aren’t
simply organizations of bytes on a disk partition. Instead, they’re applications that
offer up files, masquerading as file systems. Tramp can handle several of
these. Note that all of them require external programs to be installed, and
these are all external methods.
Method | Comments |
---|---|
ftp | For FTP servers |
sftp | SSH FTP |
rclone | Many remote storage systems via rclone(1) |
sshfs | Remote files via the sshfs file system |
afp | Apple Filing Protocol |
dav | WebDAV |
davs | … via SSL |
gdrive | Google Drive |
nextcloud | NextCloud and OwnCloud systems |
mtp | Media devices like phones and cameras |
adb | Access a phone through the Android Debug Bridge |
Windows-Specific Access Methods
Microsoft Windows does things its own way. If you’re a Unix Emacs user that
needs to access files on a remote Windows machine, probably all you’ll need is
the smb
method. If you’re a Windows Emacs user that needs to access remote
hosts, whether remote Unix or remote Windows hosts, you may need to use the
other methods depending on how your Window system is set up. Frankly, as
someone who’s basically never used Windows, I can’t pretend to understand these
distinctions. As always, see the manual.
Method | Type | Comments |
---|---|---|
smb | external | Access files via Samba or SMB |
ssh | inline | … via SSH |
plink | inline | … via Putty |
plinkx | inline | |
scpx | external | … via SCP |
pscp | external | … via Putty |
psftp | external |
Multi-Hop Connections
Perhaps you’re at home and need to access a file on work machine
internal.example.com
that’s on a non-routable private network, like a host with
10.*.*.*
IP address. This would normally be impossible, but if this host is
accessible via ssh from your work desktop myoffice.example.com
, say, then you can use
that as a proxy. You can Tramp into the internal host via a multi-hop filename
like this: /ssh:myoffice.example.com|ssh:internal.example.com:/filename
. You
just separate the hops with vertical bars (|
). You can mix different methods
(e.g. ssh
to get to the proxy, but smb
to get to the internal host) and
different usernames for each hop.
This implies that you can edit a file on myoffice.example.com
as root
by adding a sudo
hop (/ssh:myoffice.example.com|sudo::/filename
) and
indeed that works fine. Very powerful.
Connection Cleanup
Occasionally you may find that your persistent Tramp connections are
hung. This is most likely to happen if a network connection gets
dropped—say, your WIFI connection gets dropped, or the remote host
is rebooted, or you slept your laptop. In some cases Tramp
automatically reconnects for you and you don’t even notice, but if
you’re getting Tramp errors, you can fix them by cleaning up your
connection and starting over.
The first command to try is M-x
tramp-cleanup-connection
,
which will offer all your remote connections for completion. Pick the
one that’s generating complaints, and now you can reconnect to that
host (say by revisiting the file with
C-x C-v
(find-alternate-file
) or
M-x
revert-buffer
. If you just like to keep things neat,
you can explicitly clean up connections when you know you’re done with
them.
In extreme cases, you can use M-x
tramp-cleanup-all-buffers
to clean up all your connections for a totally fresh start. See
“Cleanup remote connections” in the Tramp manual for more information.
References
Free Software Foundation. 2022. TRAMP User Manual. Cambridge, MA: Free Software Foundation..
Read in Emacs with M-x info-display-manual RET tramp RET
.
Client / Server
In this book I advocate living in Emacs the Lisp Machine: using pure Elisp
applications (like Calc for your calculator, EWW for your web browser, and
Dired for your file manager) and Emacs front-ends to the external applications
you need to use (like VC for your version control and Ediff for your diffing and
merging), But even if you work this way as much as possible, you’ll inevitably
need to occasionally run an application from a shell in a terminal, and some of
these applications will want to invoke “your editor”. For example, if you use
mutt(1)
as your mailer274, it will need to invoke your editor every time
you compose an email; if you run git(1)
in the terminal for version
control275 it will invoke your editor so you can edit a commit message.
Programs like this typically determine your preferred editor via the value of
the EDITOR
environment variable. Yes, you can set EDITOR=emacs
, but this isn’t
really right: Emacs is already running, and has been running since you booted
your computer, right? Every additional time Emacs is fired up, you’re divorced from
all the files and Buffers in your main Emacs instance: your state. Also, any
vim(1)
user will tell you that Emacs takes too long to start up (this isn’t
really true, but a large and insufficiently lazy Init File can make it so).
The solution to both of these problems—speed, and isolation from your
state—is to run the Server in your main Emacs instance, and set your EDITOR
to
be emacsclient
.
emacsclient(1)
is a separate program that installs alongside emacs(1)
. When you
run it, all it does is instantly connect to your running Server, where all your
state is, creating a new Buffer editing the file that was named on the
emacsclient
command line. When you’re done editing this file, you have Emacs
tell the emacsclient
that you’re done, and the Client then terminates.
And speaking of state, when you’re in an emacsclient
Buffer, you really are in
the Server Emacs: all your state is available: you can switch Buffers, split
Windows, edit other files or read some emails: anything you like. If you’ve
jumped around and have forgotten where your new client Buffer is, you can invoke
C-x #
(server-edit
) and it will take you back there.
A program like mutt
or git
will have invoked emacsclient
with the
name of a temporary file where you’ll edit your email or git
commit message: this
file gets visited in your Server Emacs like any other file. The external
program will be waiting for you to finish editing before it mails the email or
checks-in the commit message.
When you’re done with the edit, you’ll save the Buffer as usual, and then invoke
C-x #
. When you invoke this command in a client Buffer, it tells emacsclient
that you’re “done” with this edit: it kills the Buffer containing the temporary
file, and terminates, returning control to the program that invoked $EDITOR
.
Note that only the emacsclient
program, not your Emacs Server, terminates: the
Server keeps running, preserving all your state.
A subtlety for Unix users, at least: C-x #
tells the emacsclient
to exit
successfully (i.e. with a status of 0); on rare occasions you might want to tell
it explicitly to exit unsuccessfully (i.e. with a non-zero status) so that the
program that invoked the Client via $EDITOR
knows you’re unhappy with your
edit. So mutt
for example would not send your email276, and git
would abort your
commit. You can do this by invoking, instead of C-x #