Bookmarks as Project Management
Time for another article in
my Emacs
for Professionals
series. This time I would like to
recommend a method of using
Emacs
Bookmarks as a form of project management.
In my experience, people tend to believe Emacs Bookmarks should be used in ways similar to web browser bookmarks. Though there is nothing wrong with using bookmarks in this way, I personally do not find it to be useful for this task. I can usually find a piece of documentation, or a file I have written, more quickly using the Info-mode search functionality, or using tools like Dired. When I have tried using Bookmarks for keeping track of files over long periods of time, I find I usually forget about the bookmarks and end up never using them.
In this article I will explain how to use the Emacs Bookmarks feature in a way that is more useful to me. I will also explain some of the limitations of the built-in Bookmarks functionality.
Just one caveat: personally, I use a workflow based
on Hyperbole
instead of the built-in Bookmarks functionality that I describe in
this article, because Hyperbole overcomes the limitations of
built-in Emacs Bookmarks. But for this article, I will focus on the
features of a vanilla
Emacs installation which anyone can
use, and talk about Hyperbole in
the next
article.
Navigating with tab completion
First lets think about how one usually navigates through the information on your computer in Emacs, without using bookmarks, so we can contrast this to how bookmarks could be used more effectively.
Emacs is already well designed to quickly gather a lot of
information into various buffers and allow you to switch between
these buffers easily. Most Emacs commands which require you to
select from a list of elements, such as {M-x switch-to-buffer}
(bound
to {C-x b}
), will prompt
you to select an item by name in
the minibuffer
and provide you
with tab
completion so you do not need to type the whole buffer name,
saving you a lot of time, and preventing some of the stress of
avoiding misspelling.
This ability to select a command and then perform tab completion
on anything relevant to that command is one of the most useful
features of Emacs. It can be made even more useful when you install
Emacs extensions that improve upon the tab completion user
interface.
Icomplete,
Vertico, and
Helm are all
Emacs extensions that improve the tab completion functionality by
displaying a list of recommended items that you can browse with the
arrow keys. You can also narrow
the list of results shown by
typing keyword patterns; any items that contain the keyword in them
are shown, all other items are not
shown.
Note: Icomplete is built-in, you can enable it with
{M-x icomplete-mode}
, or by writing the code(icomplete-mode 1)
into your Emacs configuration file.
Every Emacs command can provide it's own set of tab
completions. For example, when want to switch buffers
with {C-x b}
, tab
completion will only let you select from open buffers, as opposed to
selecting from unopened files or
directories. The M-x
find-file
(bound to {C-x
C-f}
) command and the dired
(bound to {C-x
d}
) command will select from files in the
current default-directory
. The M-x describe-function
(bound
to {C-h f}
) and
the M-x describe-variable
(bound to {C-h v}
)
commands will select only from functions or variables
(respectively). The {M-x}
command itself also provides
tab completion on commands.
Notice how every command has it's own set of completions that are presented for you. It would not be useful if you are searching for an Emacs command and were presented with a list of files to select from.
Why use Bookmarks?
What if you need to provide your own set of completions for a
list of related files? This is usually the case when you are working
on a particular project where the set of completions you want might
be spread across multiple project directories, or even multiple
servers if you are using TRAMP
to edit remote files.
This is
where Bookmarks
become useful. You can create your own arbitrary set of files
that you want to access quickly through tab completion.
How to use Bookmarks
1. Create some bookmarks
To begin using Bookmarks, navigate select any buffer
using {M-x switch-to-buffer}
(bound to {C-x
b}
), move the cursor to whatever position in the buffer is
most convenient, then use the {M-x bookmark-set}
command (bound
to {C-x r
m}
). (Mnemonic: R M
is for remember/record a
mark
).
You will be prompted for a label for this bookmark, the default
label will include the name of the buffer. Press {M-p}
in the minibuffer prompt to edit the default bookmark label.
It is a good idea to also include a keyword indicating the
project to which this bookmark should belong. For example, you might
have a file
on a book you
are working on about... (let's just say...) owls. If you
bookmark the table of contents, the file name table-of-contents.org
table of
contents
is not all that descriptive. So it is a good idea to
prepend the word owls
to the label. All of the files you are
working on which you bookmark for you owls book project should also
have the exact same word owls
in the label. If you also
happen to be working a programming project, for example a game, you
would bookmark the buffers related to your game with the name of the
game.
2. Navigate to bookmarks
The {M-x
bookmark-jump}
command (bound
to {C-x r b}
)
prompts you in the minibuffer for a bookmark to jump to. With a good
completion framework like
Icomplete,
Vertico,
or Helm, you can
use tab completion to find your bookmark with just a few
keystrokes.
This is where the usefulness of Bookmarks really begins to show. Instead of searching through all open buffers, or all files in a directory, or worrying about which directory to search through, you can simply search through your list of bookmarks. If you consciously keep your bookmark list up-to-date, regularly adding to the list buffers that you are working on, and deleting bookmarks you no longer need, it can become a very fast way to context switch between various buffers in which you are doing work.
3. Keep the bookmarks list up-to-date
Use the {M-x
list-bookmarks}
command (bound
to {C-x r l}
), this
will open a new buffer called *Bookmark List*
which has key bindings set
for easy search and navigation. If you have already created several
bookmarks, your *Bookmark
List*
would look something like this.
% Bookmark(emacs) Bookmarks (emacs) Buffers owls: table of contents owls: overview owls: life cycle game: main.el event loop game: main.el customize game: map-builder.el data structures
In the above example, the buffers marked
with (emacs)
are bookmarks into the Emacs user
reference manual, the chapters on Bookmarks
and Buffers
. I have three bookmarks for my project on owls,
and 3 bookmarks on my game project.
Now you can use the following keys for updating the bookmarks in
the *Bookmark List*
buffer:
/
— type the slash/
key and type a keyword, you are prompted in the minibuffer for a bookmark label to search for. As you type, the*Bookmark List*
is narrowed to include only items that contain the keyword you have typed. You can also simply use the usual{M-x isearch-forward}
{C-s}
to search as well. Unfortunately, there is no tab completion by default on bookmark search, there are packages discussed below that can help.n
,p
and the up/down arrows — you can navigate the bookmark list with the arrow keys.r — relabel the current bookmark. This will prompt you for a new label in the minibuffer. The
{M-p}
key chord will recall the current name so it can be modified.d
and{C-d}
— mark a bookmark for deletion.x — delete bookmarks that have been marked for deletion.
t — toggle display of the file paths on and off. When off, you only see the bookmark labels, this can sometimes make bookmarks easier to find by sight.
Enter — pressing enter selects the bookmark and jumps to the buffer and cursor position recorded in the current window.
{C-o}
— similar to enter, but jumps to the bookmark in the next window (O
is forother window
). This allows you to open two bookmarks quickly,{C-o}
for one bookmark andenter
for the next, putting the two buffers side by side.q
— hide the*Bookmark List*
buffer, returning to the buffer that was previously displayed in that window.
Good habits when using bookmarks
The method of using Emacs Bookmarks that I have proposed here is
to keep a list of files and directories between which you are often
switching in the present moment for the task you are currently
working on, and to use the {C-x r b}
to switch between buffers instead
of the ordinary {C-x
b}
. To this end, keep the following in mind:
Use
{C-x r m}
often. It is a good habit to set a bookmark every time you must do a context switch between content you are creating. When prompted for a label, use{M-p}
to quickly recall previously created labels.Have a habit of regularly using
{C-x r l}
and making sure you clear out bookmarks you do not need. Whenever you complete a task is a good time to do this.
What you cannot bookmark
Bookmarks must be associated with a file
path. This excludes several very useful buffer types that you might
want to bookmark. You may try to use the {C-x r m}
key in one of the following types of
buffer, and be dismayed to see an error message Buffer not
visiting a file or directory
instead of a prompt for a
bookmark label:
Shell command, and async shell command buffers
Grep, Find-Grep, and Occurs buffers
Any
comint
buffer: including Shell-mode, Eshell-mode, IELM, or any REPL for any programming language.Any
*scratch*
buffer or temporary bufferEWW browser buffers, (though EWW has it's own bookmarking mechanism.)
Lists constructed by
embark-collect
.
In the
next article, I will talk about how you can use the Hyperbole
package as an alternative to the built-in triad of Emacs Bookmarks
commands {M-x r
m}
, {M-x r
b}
, {M-x r l}
, and
be able to bookmark nearly any kind of buffer regardless of it's
content.
TODO: talk about related bookmarks extensions
(via Matthew Jorgensen)
BookmarkPlus adds lots to bookmarks like tags, bookmarking dired marked files, bookmaking partway through a file, etc...
org-bookmark-headings Bookmark to Org Headings, Should be part of emacs
ol-notmuch Notmuch support for Org Links
burly.el Save frame layouts into Bookmark
notmuch-bookmarks varios things may