M-x all-things-emacs

Bookmark Mania

March 22nd, 2007 by Rob Christie · 13 Comments

Bookmarks are one of those features that I have used, but have been on my list to learn more about. This week I decided to bump it off my list and pass along my notes. There are a number of different packages that can be used for bookmarking. I will discuss three.

bookmark.el

This package is part of the core emacs distribution. From the emacs info,

“Bookmarks” are somewhat like registers in that they record positions you can jump to. Unlike registers, they have long names, and they persist automatically from one Emacs session to the next. The prototypical use of bookmarks is to record “where you were reading” in various files.

Bookmarks are analogous to a web browsers bookmarking facility, although I think emacs bookmarks came first. Some of the useful commands to know are (yes, options also exist under the Edit menu, but why would you want to use that):

  • C-x r m – set a bookmark inside a file
  • C-x r b – jump to a bookmark (see also GraphicalBookmarkJump)
  • C-x r l – list all of your bookmarks
  • M-x bookmark-delete – delete a bookmark by name

The bookmark tool has the ability to store annotations about the bookmarked location. Additionally, there is a great wealth of information on bookmarks and bookmark customizations on the wiki. Two of the customizations that I have tried allow for iterating through your bookmarks and for utilizing iswitchb for jumping to a bookmark.

bm.el

bm.el provides a visible, buffer local bookmark, and the ability to jump forward and backward between the bookmarks. The author’s reason for creating this package was:

I missed the bookmarks from M$ Visual Studio in GNU Emacs. I think they provide an easy way to navigate in a buffer.

This package supports persistent bookmarks (both across buffer kills and emacs sessions), annotations, and viewing a list of bookmarks for the current buffer. A snippet from my .emacs file is below. My settings are based on the description provided within the package.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(setq bm-restore-repository-on-load t)
(require 'bm)
(global-set-key (kbd "<M-f2>") 'bm-toggle)
(global-set-key (kbd "<f2>")   'bm-next)
(global-set-key (kbd "<S-f2>") 'bm-previous)
 
;; make bookmarks persistent as default
(setq-default bm-buffer-persistence t)
 
;; Loading the repository from file when on start up.
(add-hook' after-init-hook 'bm-repository-load)
 
;; Restoring bookmarks when on file find.
(add-hook 'find-file-hooks 'bm-buffer-restore)
 
;; Saving bookmark data on killing a buffer
(add-hook 'kill-buffer-hook 'bm-buffer-save)
 
;; Saving the repository to file when on exit.
;; kill-buffer-hook is not called when emacs is killed, so we
;; must save all bookmarks first.
(add-hook 'kill-emacs-hook '(lambda nil
                              (bm-buffer-save-all)
                              (bm-repository-save)))

linemark.el

linemark.el comes with the eieio (Enhanced Implementation of Emacs Interpreted Objects). Bookmarks are remembered when a buffer is killed, and are restored when you return to that buffer later. Although the marks are not remembered between emacs sessions. Assuming cedet is installed correctly, then the following snippet enables linemark functionality and binds it to the F2 key in the following way.

viss-bookmark-toggle – Toggle a bookmark on this line (bound to f2).
viss-bookmark-next-buffer – Move to the next bookmark (bound to S-f2).
viss-bookmark-prev-buffer – Move to the previous bookmark (bound to C-f2).
viss-bookmark-clear-all-buffer – Clear all bookmarks (bound to C-S-f2).

(load-library "linemark")
(enable-visual-studio-bookmarks)

The site notes that visual studio bookmarks are an example usage of the linemark package.

The reason this tool is useful is because cross-emacs overlay management can be a pain, and overlays are certainly needed for use with font-lock.

My Take

I see myself using the functionality of bm.el on a more frequent basis. Many days I am working on large code files, and I need to jump around between 3 or 4 locations. I think marking these locations using bm.el is more consistent with the way I work. I like the buffer local nature of the bookmarks in bm.el as compared to the bookmarks that come with emacs. I like the idea that I only need to iterate over the bookmarks for the current file, and not all bookmarks. My reason for choosing bm.el over linemark.el is that it has more functionality than the visual studio style bookmarks in linemark.el. bm.el supports persisting bookmarks across sessions and also supports annotating bookmarks.

Tags: reviews

13 responses so far ↓

  • 1 AdamG // Mar 22, 2007 at 1:57 pm

    You mispelled “eieio” :P

  • 2 Eric // Mar 22, 2007 at 2:26 pm

    Thanks for this post: I did not know bookmarks existed and they are incredibly useful!

    Actually, thanks for this whole blog as it’s making my Emacs experience so enjoyable. And I speak as a 20+ year user of Emacs!

  • 3 Ryan McGeary // Mar 22, 2007 at 2:50 pm

    @Adam, Thanks. Fixed. Keep us on our toes.

    @Eric, You’re very welcome. We’re learning a lot ourselves by just contributing. It’s win-win.

  • 4 Jeff Squires // Mar 22, 2007 at 5:50 pm

    I’ve been using bookmarks (bm.el) for a long time and find them essential. I even have them bound to my f5 and f6 keys:

    (global-set-key [f5] 'bm-toggle-bookmark)
    (global-set-key [C-f5] 'bm-delete-all)
    (global-set-key [f6] 'bm-goto-bookmark)
    (global-set-key [C-f6] 'bm-goto-bookmark-previous)
  • 5 Derek // Mar 22, 2007 at 6:24 pm

    I use bookmarks almost exclusively for pointers into infodoc (bookmark.el). I find that etags offers pretty good pseudo-bookmarking for source code. Thanks for pointers to the other options.

    When I need to jump between 3-4 locations I use registers. I love registers … such a simple little feature, but just so beautifully right when you need them. Magic, I tell you, magic.

  • 6 Nick Sieger // Mar 22, 2007 at 6:32 pm

    I’ve always just used set-mark-command with a prefix argument. The rationale is that I’m setting marks on the mark ring in places where I’m editing code, so hitting C-u C-@ a number of times will jump me back to those places.

    This is also useful in conjunction with M-, since those commands set the mark before moving point, so if I’m navigating to the top or bottom of the buffer but then need to get back to where I was before, C-u C-@.

    That said, maybe I’ll have to try bm.el sometime, thanks for the pointer.

  • 7 anupam // Apr 24, 2007 at 7:42 pm

    is it possible to kind of cycle through all the bookmarks in all the files ? when cycling through bookmarks, i seem to be restricted to the bookmarks defined in the current buffer only :o(

  • 8 Rob Christie // Apr 24, 2007 at 8:09 pm

    bookmark.el works like that but bm.el does not.

  • 9 anupam // Apr 25, 2007 at 3:02 am

    @rob, i am using bm.el. do i need to do anything specific to get this behavior ?

  • 10 Rob Christie // Apr 25, 2007 at 5:33 am

    @anupam – I don’t think there is a setting to get that behavior in bm.el. I think you will need to either build it yourself or request it from the maintainer of the package.

  • 11 Bill White // Aug 19, 2007 at 5:11 pm

    Like Derek, I use window registers to set bookmarks within a file, and also to set per-session bookmarks for buffers.

    C-x rwp for a project’s *p*lanner page
    C-x rwc for the main file I’m *c*oding in
    C-x rws for a windows with multiple *s*hells
    etc

    Cheers –

    bw

  • 12 Emacs Directory Aliases « A Curious Programmer // Feb 18, 2009 at 3:44 am

    [...] hadn’t heard of Bookmarks before I saw a a post on them recently. I use them in conjunction with directory [...]

  • 13 Jeff Squires // Sep 1, 2010 at 2:03 pm

    bm.el now supports cross-buffer ‘next’

    (setq bm-cycle-all-buffers t)