Skip to content
 
 

Repository files navigation

Bookmark-X — Extended Bookmarks for GNU Emacs

Introduction

Bookmark-X is a fork of bookmark-plus. Its goal is to update it to recent emacs version (it requires emacs-30).

As bookmark-plus, its goal is to enhance built-in bookmarks.

Bookmark-X improves built-in bookmarks in three directions:

  1. Richer bookmarks. Bookmarks can carry tags, annotations, region information, visit counts, last-access timestamps, and arbitrary user data. They can be highlighted in the buffer they point to, and they remember where they were even when the file has been edited.
  2. More kinds of bookmarks. In addition to bookmarks that “go” to a location, Bookmark-X ships over 70 bookmark types: Dired buffers, Info nodes, Gnus articles, EWW/W3M pages, man pages, image files, URLs, desktops, keyboard macros, sets of variables, snippets of text, sequences of other bookmarks, whole bookmark files, and more. You can also create bookmarks that have no “destination” at all and are simply named persistent records.
  3. More to do with bookmarks. The *Bmkx List* buffer is significantly enhanced. You can mark, sort, filter, omit, search, query-replace, tag, retag, edit, clone, highlight, describe, and copy/move bookmarks across multiple bookmark files. You can save bookmark-list views, define your own jump commands and sort orders, and cycle through arbitrary sets of bookmarks (“the navigation list”).

This package use mostly a maintenance version of the bookmark-plus by Drew Adams (https://www.emacswiki.org/emacs/BookmarkPlus)

Differences from built-in bookmark.el

The following table describes the main improvements over built-in bookmarks and bookmark-x: Note the bookmark-x stores bookmarks in the same format as built-in bookmarks, making both compatible with each other.

CapabilityBuilt-in bookmark.elBookmark-X
Named, persistent positions in files / buffersYesYes
Persistence across sessions (~/.emacs.d/bookmarks)YesYes
Auto-save (bookmark-save-flag)YesYes
Context-aware position (survives small edits)YesYes
Fringe mark at bookmarked lineYes (Emacs 28+)Yes
AnnotationsSingle stringMulti-line, with their own editing buffer
*Bmkx List* bufferBasic (mark, delete, rename, save, search)Filter, sort by many fields, mark by type/tag, copy/move across files, query-replace through marked, define commands from a view
Highlight destination on jumpNoYes (bmkx-highlight-on-jump-flag, default on)
Tags on bookmarksNoMulti-tag, tag-with-value, jump-by-tag, filter-by-tag
Multiple bookmark filesbookmark-write / bookmark-load onlyFirst-class: switch, merge, define new, bookmark-file bookmark type
Bookmark types beyond file positionsNone70+: Dired, Info, Gnus, EWW, man, URL, image, desktop, kbd-macro, snippet, region, variable list, sequence-of-bookmarks, bookmark-file, autonamed, non-invokable, …
Region bookmarks (start+end; region activates on jump)NoYes
Per-bookmark highlight in destination bufferNoYes
Auto-creation (bookmark every N idle seconds)NoYes (bmkx-automatic-bookmark-mode)
Temporary (non-persistent) bookmarksNoYes
Autonamed bookmarks (auto-generated names)NoYes
Visit counts and last-access timestampsNoYes
Save the *Bmkx List* view itself as a bookmarkNoYes (bookmark-list bookmark type)
Sequence bookmarks (composite of other bookmarks)NoYes
Custom jump function via bmkx-jump tagNoYes
Type-aware jump commands (C-x j i Info, C-x j d Dired, …)NoYes

Quick start

These commands cover the basic workflow. Standard C-x r m / C-x r b / C-x r l still run Emacs’s built-in bookmark-set / bmkx-jump / list-bookmarks unchanged. The bookmark-x commands have their own bmkx-* names and live under the C-x x prefix; bind them to the standard keys yourself if you prefer (see Binding bmkx commands to standard keys).

CommandKey (bmkx prefix)What it does
bmkx-bookmark-set-confirm-overwriteC-x x m, C-x x c mSet or update a bookmark (richer prompt; confirm on overwrite).
bmkx-jumpC-x j jJump to any bookmark (type-aware default, region support, pulse).
bmkx-listC-x x eOpen *Bmkx List* (the rich browse buffer).
bmkx-add-tagsC-x x t + bAdd tags to a bookmark.
bmkx-this-file/buffer-bmenu-listC-x x ,Show bookmarks for the current file or buffer.
bmkx-next-bookmark-this-file/buffer-repeatC-x x n, C-x x downCycle forward through bookmarks here.
bmkx-switch-bookmark-file-createC-x x LSwitch to another bookmark file.

Suggested first session:

  1. Create a bookmark with bmkx-bookmark-set-confirm-overwrite (C-x x m).
  2. Open *Bmkx List* with bmkx-list (C-x x e).
  3. Add tags with bmkx-add-tags (T + in *Bmkx List*, or C-x x t + b globally).
  4. Jump with bmkx-jump (C-x j j) or from the list with RET.
  5. Use bmkx-bmenu-show-all (.), sorting keys such as s s, and filtering keys such as T S to shape the list.

For interactive bookmark jumping, use bmkx-jump (C-x j j) directly — it has facilities that consult-bookmark does not (MRU sort, tag matching, multi-axis filter state; see Jumping with completion). Advising bookmark-jump is only worthwhile when a third-party caller you cannot edit (Org-mode bookmark links, programmatic callers in other packages) needs to route through Bookmark-X:

(advice-add 'bookmark-jump :override #'bmkx-jump)

This routes existing bookmark-jump calls through Bookmark-X but does not give those callers the extra UX bmkx-jump gives you in the minibuffer.

Table of contents

Installation

From a local checkout

Clone or copy the Bookmark-X files into a local directory, then load them with use-package:

(use-package bookmark-x
  :load-path "/path/to/bookmark-x"
  :demand t)

Replace "/path/to/bookmark-x" with the directory that contains bookmark-x.el and the other bookmark-x*.el files. The single use-package form loads every required Bookmark-X library.

Load order and bookmark-default-file

The value of bookmark-default-file is consulted when Bookmark-X loads, to initialize bmkx-last-as-first-bookmark-file and bmkx-current-bookmark-file. If you set bookmark-default-file in your init file, set it before loading Bookmark-X. In general, set bookmark-default-file once, then use bmkx-switch-bookmark-file-create (C-x x L) to switch the boookmarks file, if needed.

Back up your bookmark file

Bookmark-X writes backups when it saves your bookmark file (the built-in bookmark.el does not, due to bug #12507). For safety, set bookmark-version-control to t so numbered backups are kept, and delete-old-versions to t to suppress the prompt at save time.

Optional dependencies

For historical reasons there are some optional features that depend on whether you have loaded certain modules All are by Drew Adams (EmacsWiki, emacsmirror). info+ is probably the most useful.

LibraryAddsWorth installing?
info+.elInfo-persist-history-mode for persistent Info history.Yes if you read Info regularly — Emacs 30 has no built-in equivalent.
dired+.elM-b, C-M-b, C-+/- in Dired for bookmarking marked files.Probably not just for this — bookmark integration is a small slice of a large Dired overlay. Install if you want the rest of dired+.
highlight.elPer-file autofile highlighting in Dired (with dired+.el).Only with dired+ and heavy use of autofile bookmarks.
w32-browser.elOpens bookmarks via MS-Windows file associations.Windows only.
zones.elEnables the bmkx-set-izones-bookmark command.Only if you already use zones. Don’t install solely for this row.
font-lock+.elBookmark links keep the link face inside font-locked buffers.Edge case — only if you embed bookmark links in Org or other font-locked buffers and the wrong face bothers you.

zones.el must be loaded before Bookmark-X. bmkx-set-izones-bookmark is defined inside a (when (boundp 'zz-izones-var) …) guard that runs once at load time; if zones.el isn’t loaded yet, the command is silently absent.

Concepts: list, file, display

Three different things are commonly confused. Understanding them is the single most important thing for using Bookmark-X effectively.

  1. The bookmark list. The in-memory set of bookmarks. It is the value of internal variable bookmark-alist. Adding, renaming, deleting, or jumping to a bookmark updates this list.
  2. The bookmark file. An on-disk persistent record of a set of bookmarks. Its default location is bookmark-default-file (~/.emacs.bmk). Multiple bookmark files may exist; only one is current at a time.
  3. The bookmark-list display. Buffer *Bmkx List* (also known as the bookmark “menu list”). It is a snapshot view of the bookmark list, rendered with markings, sort order, filters, and so on.

These three can be out of sync. The list rules during an Emacs session. The file rules across sessions (it is all that survives when Emacs exits). In the display, bmkx-bmenu-refresh-menu-list (g) refreshes from the list; with a prefix argument (C-u g), it reloads from the file.

Tip. Use bmkx-list (C-x x e or C-x r l) to open *Bmkx List* as your “home page” for navigating files, projects, and notes. Bookmark-X restores the buffer’s previous state (sort order, filtering, marks) each time you open it.

Prefix keys and keymaps

Bookmark-X allocates dedicated prefix keys for bookmarking, separating them from the shared C-x r register prefix.

KeymapDefault keyPurpose
bookmark-mapC-x xGeneral bookmark commands.
bmkx-set-mapC-x x cCreate (set) new bookmarks.
bmkx-tags-mapC-x x tTag commands.
bmkx-annotate-mapC-x x aAnnotation commands.
bmkx-jump-mapC-x jJump (visit) bookmarks — same window.
bmkx-jump-other-window-mapC-x 4 jJump — other window.
Built-in other-frame jumpC-x 5 jJump — other frame.

The built-in C-x r m / C-x r b / C-x r l bindings still work — this fork no longer overrides them. They invoke the built-in bookmark-set / bmkx-jump / list-bookmarks. Users who want the standard keys to run the bookmark-x equivalents instead can do so with a few lines in their init file — see Binding bmkx commands to standard keys.

The prefixes are themselves customizable through three list-valued options:

  • bmkx-bookmark-map-prefix-keys (default "C-x x")
  • bmkx-jump-map-prefix-keys (default "C-x j")
  • bmkx-jump-other-window-map-prefix-keys (default "C-x 4 j")

Because they are lists, you can bind a keymap under several prefixes at once, e.g. both C-x x and <f9>. Re-binding is done by customizing these options — a setter function rebinds the keys for you.

Inside the *Bmkx List* buffer, single-letter keys take over: bmkx-list-this-window (J) mirrors bmkx-jump-map (C-x j), and the other-window jump prefix (j) mirrors bmkx-jump-other-window-map (C-x 4 j). See Key-binding tables for the full inventory.

Binding bmkx commands to standard keys

Bookmark-X is now an additive sibling of the built-in bookmark.el; loading it does not redefine any of the built-in’s commands. If you want C-x r m / C-x r b / C-x r l to run bmkx’s enhanced commands instead, add this to your init file:

(define-key bookmark-map "m" #'bmkx-bookmark-set-confirm-overwrite)
(define-key bookmark-map "b" #'bmkx-jump)
(define-key bookmark-map "l" #'bmkx-list)

For programmatic callers you cannot edit (consult-bookmark, helm-bookmark, Org-mode bookmark links, etc.), if you want them to route through Bookmark-X when they invoke bookmark-jump, add this advice:

(advice-add 'bookmark-jump :override #'bmkx-jump)

Note: this fixes lookup but not UX. Those callers still drive their own minibuffer reads — so consult-bookmark will keep showing its own type-narrow set, its own annotation, its own sort order; advising bookmark-jump does not graft Bookmark-X’s bmkx-jump-narrow, bmkx-jump-sort-by, or the multi-axis filter state (M-t / M-D / M-T) onto consult-bookmark’s prompt. For full power, call bmkx-jump directly; treat the advice as a fallback for external code paths you don’t own.

No helper command is required: bookmark-x does not ship an “install” wrapper for these. They are plain Emacs primitives; deleting the lines from your init file (or calling define-key with the original binding / advice-remove) reverses them.

Setting bookmarks

bmkx-bookmark-set-confirm-overwrite — enhanced bookmark-set

bmkx-bookmark-set-confirm-overwrite (C-x r m, with aliases C-x x c m and C-x x m) is an enhanced replacement for bookmark-set:

  • Completion candidates default to bookmarks in the current buffer (or all bookmarks if there are none) so you can easily update a nearby bookmark. A numeric prefix argument expands completion to all bookmarks.
  • Overwriting prompts for confirmation.
  • Existing tags and annotations are preserved when you re-set a bookmark (see bmkx-properties-to-keep).

Creation commands by type

The bmkx-set-map (default prefix C-x x c) groups commands that create specific kinds of bookmark:

CommandKeyCreates
bmkx-bookmark-set-confirm-overwriteC-x x c mA normal bookmark at point.
bmkx-autofile-setC-x x c aAn autofile bookmark for a file.
bmkx-file-target-setC-x x c fA file bookmark (file name at point).
bmkx-url-target-setC-x x c uA URL bookmark (URL at point).
bmkx-make-function-bookmarkC-x x c FA function (or last-kbd-macro) bookmark.
bmkx-set-desktop-bookmarkC-x x c KA desktop bookmark (current Emacs desktop).
bmkx-set-sequence-bookmarkC-x x c sA sequence (composite) bookmark.
bmkx-set-bookmark-file-bookmarkC-x x c yA bookmark-file bookmark.
bmkx-set-snippet-bookmarkC-x x M-wA snippet bookmark from the active region.
bmkx-wrap-bookmark-with-last-kbd-macroC-x x c C-kA sequence: a bookmark + last kbd macro.
bmkx-toggle-autonamed-bookmark-set/deleteC-x x c RETSets/deletes the autonamed bookmark here.

Additional, unbound by default but available: bmkx-set-autonamed-bookmark, bmkx-set-autonamed-bookmark-at-line, bmkx-set-autonamed-regexp-buffer, bmkx-set-autonamed-regexp-region, bmkx-set-variable-list-bookmark, bmkx-set-kmacro-bookmark, bmkx-set-kmacro-list-bookmark, bmkx-set-izones-bookmark.

Bookmarking without visiting

You can bookmark targets without first opening them:

  • A file or URL at point. bmkx-file-target-set (C-x x c f) and bmkx-url-target-set (C-x x c u) read a file or URL with the text at point as the default.
  • Compilation/grep/occur hits. In *compilation*, *grep*, *Occur*, and *Multi-Occur* buffers:
    • bmkx-compilation-target-set or bmkx-occur-target-set (C-c C-b) bookmarks the target of the hit at point.
    • bmkx-compilation-target-set-all or bmkx-occur-target-set-all (C-c C-M-b) bookmarks the target of every hit.
    • bmkx-occur-create-autonamed-bookmarks (C-c C-M-B in *Occur*) creates an autonamed bookmark per hit.
  • Marked files in Dired (requires dired+.el):
    • diredp-do-bookmark (M-b) bookmarks each marked file as an autofile.
    • The Dired+ C-M-B binding bookmarks each into a bookmark file you specify.
    • The Dired+ C-M-b binding does the same and also creates a bookmark-file bookmark for the resulting file.

    C-u C-u / C-u C-u C-u / C-u C-u C-u C-u as the prefix argument widens the scope from “marked” to “all files (no directories)” / “all files and dirs except . and ..” / “all files and all directories”.

Jumping and cycling

Jumping with completion

bmkx-jump (C-x j j) is the generic bookmark jump command; completion offers every bookmark. bmkx-jump-other-window (C-x 4 j j) is its other-window twin. Inside *Bmkx List*, bmkx-list-this-window (J) and the other-window jump prefix (j) jump same- / other-window.

Power features (with consult loaded)

When consult is on your load-path and bmkx-preview-use-consult-flag is non-nil (the default), bmkx-jump routes its read through consult--read and gains several facilities that are not available through consult-bookmark — even if you advice-add 'bookmark-jump :override #'bmkx-jump. These belong to bmkx-jump’s own minibuffer; the advice route only redirects lookup.

  • Live preview. Moving through candidates briefly displays the destination in another window without committing the jump (same mechanism consult-bookmark uses).
  • Tag-substring matching. Each candidate carries a hidden #tag1 #tag2 suffix. Typing emacs filters to bookmarks whose name or any tag contains “emacs”. No special syntax needed.
  • Type narrowing. Press , followed by a single char to narrow to a handler family — ,f file, ,d Dired, ,i Info, ,o Org heading, ,w Web, etc. Keys are configurable via bmkx-jump-narrow.
  • Multi-axis filter state. In the minibuffer:
    KeyEffect
    M-tAdd a tag filter (completing-read over every known tag).
    M-DPop the most recently added filter.
    M-TClear all active filters.

    Active filters appear bracketed in the prompt ([#emacs #work] Bookmark: =) and exclude non-matching candidates. The filter set is local to one =bmkx-jump invocation and stacks with the type narrow above.

  • Sort modes. bmkx-jump-sort-by controls order:
    • mru (default) — most recently jumped first.
    • visits — most-jumped first.
    • alpha — alphabetical by name.
  • Grouping. bmkx-jump-group-by controls grouping: nil (default, flat), type (handler family from bmkx-jump-narrow), or tag (each bookmark’s first tag). When grouping is on, candidates are clustered by group and the chosen sort applies within each group.
  • Annotation with tags column. The display shows an aligned tags column followed by marginalia’s standard type | file | location annotation.
  • Location display for non-file bookmarks. Marginalia prints - no file - in the file column for bookmarks with no file (URL, EWW, W3M, browse-URL, …). Bookmark-X substitutes the bookmark’s location property in place of that marker, so URL bookmarks show their URL. The substitution is governed by the defcustom bmkx-bookmark-location-function, which is called with the bookmark record and must return a string (substitute) or nil (leave marginalia’s output alone). The default, bmkx-bookmark-location-default, returns the location property. Override to format other types:
    (setq bmkx-bookmark-location-function
          (lambda (bmk)
            (or (bookmark-prop-get bmk 'location)
                (when (bmkx-info-bookmark-p bmk)
                  (format "info: %s" (bookmark-prop-get bmk 'info-node))))))
        
  • Candidate row format. The visible candidate line itself (the bookmark name + hidden, searchable #tag1 #tag2 suffix) is built by the function in bmkx-jump-candidate-format-function. The default, bmkx-jump-candidate-default, is the behavior described in the previous bullets. Override to show more inline – e.g. prepend the bookmark type, include visit counts, show tags visibly. The function receives the bookmark record and the narrow alist, and must return a string with the bmkx-bookmark-name and consult--type text properties applied (a helper, bmkx-jump-candidate-type-char, computes the narrow char from the record). Example – show tags inline:
    (setq bmkx-jump-candidate-format-function
          (lambda (bm narrow-alist)
            (let* ((name      (car bm))
                   (tags      (bookmark-prop-get name 'tags))
                   (type-char (bmkx-jump-candidate-type-char bm narrow-alist))
                   (visible   (if tags
                                  (format "%s   %s" name
                                          (mapconcat (lambda (tg)
                                                       (concat "#" (if (consp tg) (car tg) tg)))
                                                     tags " "))
                                name)))
              (propertize visible
                          'bmkx-bookmark-name name
                          'consult--type     type-char))))
        

In contrast, consult-bookmark — with or without the advice-add override above — ships only its own type-narrow (consult-bookmark-narrow), its built-in annotation (via Marginalia if loaded), and no filter state, no tag matching, no MRU sort. bmkx-jump is the recommended interactive jump command.

For specific types, type-specific jump commands offer only bookmarks of that type as completion candidates. They live on the bmkx-jump-map (default C-x j) and bmkx-jump-other-window-map (default C-x 4 j). Examples:

TypeSame-window command / keyOther-window command / key
Diredbmkx-dired-jump (C-x j d)bmkx-dired-jump-other-window (C-x 4 j d)
Filebmkx-file-jump (C-x j f)bmkx-file-jump-other-window (C-x 4 j f)
Local filebmkx-local-file-jump (C-x j l)bmkx-local-file-jump-other-window (C-x 4 j l)
Remote (network) filebmkx-remote-file-jump (C-x j n)bmkx-remote-file-jump-other-window (C-x 4 j n)
Autofilebmkx-autofile-jump (C-x j a)bmkx-autofile-jump-other-window (C-x 4 j a)
Non-file (buffer)bmkx-non-file-jump (C-x j b)bmkx-non-file-jump-other-window (C-x 4 j b)
Infobmkx-info-jump (C-x j i)bmkx-info-jump-other-window (C-x 4 j i)
man / woman pagebmkx-man-jump (C-x j m)bmkx-man-jump-other-window (C-x 4 j m)
Imagebmkx-image-jump (C-x j M-i)bmkx-image-jump-other-window (C-x 4 j M-i)
Regionbmkx-region-jump (C-x j r)bmkx-region-jump-other-window (C-x 4 j r)
URLbmkx-url-jump (C-x j u)bmkx-url-jump-other-window (C-x 4 j u)
W3M (legacy, opens in EWW)bmkx-w3m-jump (C-x j w)bmkx-w3m-jump-other-window (C-x 4 j w)
EWWbmkx-eww-jump (C-x j e)bmkx-eww-jump-other-window (C-x 4 j e)
Gnus articlebmkx-gnus-jump (C-x j g)bmkx-gnus-jump-other-window (C-x 4 j g)
Highlighted (lighted) bookmarkbmkx-lighted-jump (C-x j h)bmkx-lighted-jump-other-window (C-x 4 j h)
Temporarybmkx-temporary-jump (C-x j x)bmkx-temporary-jump-other-window (C-x 4 j x)
Variable-listbmkx-variable-list-jump (C-x j v)
Desktopbmkx-desktop-jump (C-x j K)bmkx-desktop-jump (C-x 4 j K)
Bookmark-filebmkx-bookmark-file-jump (C-x j y)
Bookmark-listbmkx-bookmark-list-jump (C-x j B)bmkx-bookmark-list-jump (C-x 4 j B)
Bookmark in current navlistbmkx-jump-in-navlist (C-x j N)bmkx-jump-in-navlist-other-window (C-x 4 j N)
Bookmark-list bookmarkbmkx-jump-to-list (C-x j C-j)
Snippetbmkx-snippet-to-kill-ring (C-x j M-w)bmkx-snippet-to-kill-ring (C-x 4 j M-w)
Autonamed bookmarkbmkx-autonamed-jump (C-x j #)bmkx-autonamed-jump-other-window (C-x 4 j #)
Autonamed bookmark herebmkx-autonamed-this-buffer-jump (C-x j , #)bmkx-autonamed-this-buffer-jump-other-window (C-x 4 j , #)
Bookmark in this bufferbmkx-this-buffer-jump (C-x j , ,)bmkx-this-buffer-jump-other-window (C-x 4 j , ,)
Bookmark for a specific filebmkx-specific-files-jump (C-x j = f)bmkx-specific-files-jump-other-window (C-x 4 j = f)
Bookmark for a specific bufferbmkx-specific-buffers-jump (C-x j = b)bmkx-specific-buffers-jump-other-window (C-x 4 j = b)
File bookmark in current dirbmkx-file-this-dir-jump (C-x j . f)bmkx-file-this-dir-jump-other-window (C-x 4 j . f)
Dired bookmark in current dirbmkx-dired-this-dir-jump (C-x j . d)bmkx-dired-this-dir-jump-other-window (C-x 4 j . d)
Other framebmkx-jump-other-frame (C-x j 5, same as C-x 5 B)

The generic “any type” command is bmkx-jump-to-type (C-x j :). It first asks for the type, then offers only bookmarks of that type as candidates — useful when you do not want to remember the type-specific keys.

find-file-style jumping

bmkx-find-file (C-x j C-f) and bmkx-find-file-other-window (C-x 4 j C-f) act like find-file, but obey bmkx-default-handlers-for-file-types — so HTML files open in browse-url, Word docs open in w32-browser, and so on (see Bookmark types below). With a prefix argument they also create an autofile bookmark for the file.

There is also a family of bmkx-find-file-...-tags commands (under C-x j t C-f ...) that filter by tags while reading a file name with read-file-name (so you can browse directories).

Mode-specific j keys

Several modes bind j to the corresponding type-specific jump:

Modej jumps to a …
InfoInfo bookmark.
Gnus summaryGnus bookmark.
man / womanman-page bookmark.
EWWEWW bookmark.
Buffer-menuNon-file (buffer) bookmark.
Dired (J used — j is dired-goto-file)Dired bookmark.
Dired (C-j)Dired bookmark whose dir = current dir.

Tag-based jumping

Tag-aware jump commands have key sequences that combine three ideas: which bookmark family (file, autofile, this-dir-file, find-file), how many tags must match (all = *, some/any = +), and whether the match is literal or against a regexp (% = regexp).

CommandKeyMeaning
bmkx-tag-jumpC-x j t TBookmark that has every given tag.
bmkx-some-tags-jumpC-x j t +Bookmark with at least one given tag.
bmkx-all-tags-jumpC-x j t *Bookmark whose tags are all in the set.
bmkx-all-tags-regexp-jumpC-x j t % *Bookmark whose every tag matches regexp.
bmkx-some-tags-regexp-jumpC-x j t % +Bookmark with some tag matching regexp.
bmkx-file-{all,some}-tags-{regexp-}jumpC-x j t f * / +/...File or directory bookmark.
bmkx-autofile-{all,some}-tags-{regexp-}jumpC-x j t a * / + /...Autofile bookmark.
bmkx-file-this-dir-{all,some}-tags-{regexp-}jumpC-x j t . * /...File bookmark in default-directory.
bmkx-find-file-{all,some}-tags-{regexp-}jumpC-x j t C-f * /...read-file-name version (browses dirs).

Each command has an -other-window twin under C-x 4 j t ....

Cycling: the navigation list

Bookmark-X lets you cycle through a set of bookmarks — like the “favorites” buttons on a TV remote. The set being cycled is the “navigation list” (navlist).

Define the navlist explicitly:

  • bmkx-choose-navlist-of-type (C-x x :) — all bookmarks of a given type.
  • bmkx-choose-navlist-from-bookmark-list (C-x x B) — bookmarks corresponding to a bookmark-list bookmark, or the current *Bmkx List* state.

If you do not define it, the first cycling key takes a snapshot of the current bookmarks (or of the bookmarks for the current file/buffer, for the file/buffer-specific cycling keys).

Cycle through the navlist (with wraparound):

CommandForward keyBackward key
bmkx-{next,previous}-bookmark-repeatC-x x f / C-f / rightC-x x b / C-b / left
bmkx-{next,previous}-bookmark-w32-repeatC-x x next (PageDown)C-x x prior (PageUp)

Cycle bookmarks in the current file/buffer (dynamic set, not a snapshot):

CommandForward keyBackward key
bmkx-{next,previous}-bookmark-this-file/buffer-repeatC-x x n / C-n / downC-x x p / C-p / up
bmkx-{next,previous}-lighted-this-buffer-repeatC-x x C-downC-x x C-up

After C-x x you can also rotate the mouse wheel to cycle (Emacs 23.3 or later).

Show *Bmkx List* filtered to the navigation list with bmkx-navlist-bmenu-list (C-x x N).

Bookmark types

A bookmark “type” is really just a handler: a function that “jumps” to (= acts on) the bookmark. Anything can be a bookmark type. Bookmark-X ships handlers for around 70 of them.

Run M-x bmkx-types-alist to list every type registered in your session. bmkx-jump-to-type (C-x j :) lets you pick a type interactively.

Predicates of the form bmkx-TYPE-bookmark-p recognize each type.

Location / file bookmarks

  • File / local file / remote file. Jumping visits the file. bmkx-jump-{file,local-file,remote-file}.
  • Directory. Like a file bookmark, but the destination is a directory.
  • Non-file (buffer). Like a file bookmark for a buffer that is not visiting a file — the buffer must exist when you jump.
  • Region. A bookmark with front-context-string, rear-context-string, plus an end-position property. Jumping activates the region. See bmkx-use-region for the activation policy (t, cycling-too, or nil). Use bmkx-region-jump-narrow-indirect-other-window (C-x 4 j R) to narrow the region in a cloned indirect buffer.

Type-aware file actions

bmkx-default-handlers-for-file-types is the “MIME map” of Bookmark-X. Each entry pairs a regexp matching a file name with a shell command (string) or Lisp function (symbol or lambda) that will be invoked on the file:

;; Example value:
(("\\.ps$"    . "gsview32.exe")
 ("\\.html?$" . browse-url)
 ("\\.doc$"   . w32-browser))

These mappings affect:

  • bmkx-bookmark-a-file (C-x x c a) and bmkx-autofile-set, which save the action as the bookmark’s file-handler property.
  • bmkx-find-file / bmkx-find-file-other-window (C-x j C-f / C-x 4 j C-f).

If bmkx-guess-default-handler-for-file-flag is non-nil and no mapping matches, Bookmark-X consults dired-guess-shell-alist-default and (Emacs 23+) mailcap entries.

On MS-Windows, M-RET / M-mouse-2 / M-o in *Bmkx List* open bookmarks via Windows file associations (requires w32-browser.el).

Autofile bookmarks

An autofile is a bookmark whose name is the non-directory part of its file name. bmkx-autofile-set (C-x x c a) creates one for a file. The bmkx-propertize-bookmark-names-flag option (non-nil by default on Emacs 21+) lets you have multiple autofiles with the same name in different directories. Combined with tags this gives you a kind of file-system-wide metadata layer. See also: bmkx-autofile-filecache (advise file-cache-add-file to also create autofiles), bmkx-autofile-access-invokes-bookmark-flag (make find-file also “visit” the autofile, updating its visit count).

Dired and Dired-tree bookmarks

A Dired bookmark records:

  • the Dired directory,
  • the ls switches,
  • which files are marked,
  • which subdirectories are inserted,
  • which subdirectories are hidden.

Jumping reproduces the Dired buffer with the same markings/inserted subdirs/hidden subdirs. A Dired tree bookmark is a sequence bookmark whose components are Dired bookmarks for a directory and its descendants. diredp-do-bookmark-dirs-recursive (from dired+.el) creates one for the current Dired buffer.

Info bookmarks

bmkx-info-jump (C-x j i or j in Info mode). Mode bmkx-info-auto-bookmark-mode automatically creates / updates an Info bookmark every time you visit a node. bmkx-info-auto-type picks update-only (the default) or create-or-replace; toggle with bmkx-toggle-info-auto-type.

Gnus, man, woman, EWW (and legacy W3M)

  • bmkx-gnus-jump bookmark of a Gnus article (group, article, message id).
  • bmkx-man-jump for man or woman pages.
  • bmkx-eww-jump for EWW URLs.
  • bmkx-w3m-jump still recognises legacy W3M bookmarks saved by earlier versions of Bookmark-X, but opens them in EWW. This fork does not create new W3M bookmarks.
  • EWW can be configured so that visiting a page records a bookmark, via bmkx-set-eww-bookmark-here and bmkx-eww-replace-keys-flag (rebinds built-in EWW bookmark keys to Bookmark-X’s).

Image bookmarks

When you bookmark an image-file target, Emacs’s image handler is used automatically. bmkx-image-jump (C-x j M-i) jumps to one; the description (C-h RET) shows the full EXIF metadata (Emacs 22+ with exiftool).

URL bookmarks

bmkx-url-target-set (C-x x c u) and bmkx-url-jump (C-x j u). The handler is typically browse-url or w32-browser.

Desktop bookmarks

bmkx-set-desktop-bookmark (C-x x K or C-x x c K or C-x r K) captures a desktop (from desktop.el). Jumping restores the saved desktop. Options:

  • bmkx-desktop-no-save-vars — variables to exclude.
  • bmkx-desktop-jump-save-before-flag — save current desktop before jumping if it was reached by jumping.
  • bmkx-desktop-save-as-last — add to kill-emacs-hook to remember the last jumped-to desktop.

Sequence (composite) bookmarks

A sequence bookmark invokes each member bookmark in turn. bmkx-set-sequence-bookmark (C-x x c s) prompts for a sequence name and the member bookmark names. bmkx-bmenu-make-sequence-from-marked turns the marked bookmarks (in their current order) into a sequence. Members may themselves be sequence bookmarks.

Function (and keyboard-macro) bookmarks

bmkx-make-function-bookmark (C-x x c F) records a function symbol or a lambda expression. With a prefix argument, it captures last-kbd-macro, giving you a persistent way to replay a keyboard macro. bmkx-wrap-bookmark-with-last-kbd-macro (C-x x c C-k) builds a sequence bookmark that first invokes another bookmark and then plays the macro.

A prefix argument given when jumping is passed to the function (or counts macro repetitions).

Variable-list bookmarks

bmkx-set-variable-list-bookmark records a set of variables and their current values. bmkx-jump-variable-list (C-x j v) restores them in the bookmark’s buffer. bmkx-set-izones-bookmark (needs zones.el) records a buffer’s zz-izones (ring of narrowings) for later restoration.

Snippet bookmarks

bmkx-set-snippet-bookmark (C-x x M-w or C-x x c M-w) saves the active region’s text under a bookmark name. At any time, in any Emacs session, bmkx-snippet-to-kill-ring (C-x j M-w / C-x 4 j M-w) yanks the saved snippet to the kill ring.

Bookmark-list bookmarks

A bookmark-list bookmark records the state of *Bmkx List* (sort order, filter, regexp pattern, title, omit list). Jumping to it restores that state. bmkx-bmenu-define-command (C-c C-c in *Bmkx List*) defines a command that does the same thing, without consuming a bookmark slot. bmkx-bmenu-define-full-snapshot-command (C-c C-S-c, aka C-c C-C) captures everything including marks — larger but complete.

Bookmark-file bookmarks

Created by bmkx-set-bookmark-file-bookmark (C-x x y / C-x x c y). “Jumping” to one loads the referenced bookmark file. With C-u, jumping switches to it.

Other built-in types

  • Lighter (highlight) override — per-bookmark style/face/condition for highlighting (see Highlighting).
  • Non-invokable — handler is ignore. Useful for using bookmarks just as named persistent records (e.g. Isearch filter predicate suites). Shown with the bmkx-no-jump face.

Defining your own types

Define a handler function and set bookmark-make-record-function (or pass a handler via your own bookmark setter). To register a new type so bmkx-jump-to-type recognizes it, provide a function bmkx-TYPE-alist-only and call (bmkx-define-history-variables). The macro bmkx-define-type-from-handler (in bookmark-x-mac.el) does both, plus it generates a predicate bmkx-TYPE-bookmark-p and a “show only” command bmkx-bmenu-show-only-TYPE-bookmarks via bmkx-define-show-only-command.

Tags

A bookmark tag is a string (or a string + Lisp value) attached to a bookmark. Tags are persistent; multiple bookmarks can share the same tag; one bookmark can have many. Tags define sets of bookmarks (“blue”, “vacation/2024/photos”, “todo”…) and most Bookmark-X commands can operate on those sets.

Adding / removing tags

CommandGlobal keyBmenu keyMeaning
bmkx-add-tagsC-x x t + bT +Add tags to a bookmark.
bmkx-remove-tagsC-x x t - bT -Remove tags from a bookmark.
bmkx-remove-all-tagsC-x x t 0T 0Remove all tags from a bookmark.
bmkx-tag-a-file (alias bmkx-autofile-add-tags)C-x x t + a(none)Tag a file (autofile creation).
bmkx-untag-a-fileC-x x t - a(none)Remove tags from a file (autofile).
bmkx-copy-tagsC-x x t c / M-wT c / T M-wCopy this bookmark’s tags.
bmkx-paste-add-tagsC-x x t p / C-x x t C-yT pPaste copied tags (additive).
bmkx-paste-replace-tagsC-x x t qT qPaste copied tags (replace).
bmkx-rename-tagC-x x t rT rRename a tag everywhere.
bmkx-remove-tags-from-allC-x x t dT dDelete a tag from all bookmarks.
bmkx-edit-tagsC-x x t eT eEdit a bookmark’s tags in a buffer.
bmkx-list-all-tagsC-x x t lT lList every defined tag.
bmkx-set-tag-valueC-x x t vT vGive a tag a value.
bmkx-set-tag-value-for-navlistC-x x t VT VSame for every bookmark in the navlist.

You can press RET RET at the tag prompt to accept the empty set (many commands treat that as “any tag at all”). Use C-q C-j to include a newline in a tag.

Tag-name completion candidates are controlled by bmkx-tags-for-completion (default: current = use the tags from the current bookmark list; you can also list specific tags or specific bookmark files).

If bmkx-prompt-for-tags-flag is non-nil, you are prompted for tags when you create or update any bookmark.

Marking by tag in *Bmkx List*

The tag-based mark and unmark commands all live under T m / T u:

CommandKeyMarks/unmarks bookmarks tagged …
bmkx-bmenu-mark-bookmarks-tagged-allT m *with all of the given tags.
bmkx-bmenu-mark-bookmarks-tagged-someT m +with some of the given tags.
bmkx-bmenu-mark-bookmarks-tagged-not-allT m ~ *not with all of them.
bmkx-bmenu-mark-bookmarks-tagged-noneT m ~ +with none of them.
bmkx-bmenu-mark-bookmarks-tagged-regexpT m %with a tag matching a regexp.
bmkx-bmenu-unmark-bookmarks-tagged-...T u * …=unmark variants.
bmkx-bmenu-show-only-tagged-bookmarksT Sshow only tagged bookmarks.
bmkx-bmenu-show-only-untagged-bookmarksT Ushow only untagged bookmarks.
bmkx-define-tags-sort-commandT sdefine a sort command keyed on tags.

Prefix argument flips “some” ↔ “not all” and “all” ↔ “none”.

Tag values

Use bmkx-set-tag-value (T v in *Bmkx List*, or C-x x t v globally) to give a tag any readable Lisp value: number, string, list, etc. A tag with a value is internally (NAME . VALUE). Most Bookmark-X commands ignore values; you can use them from your own Lisp.

A single predefined tag with special behaviour: bmkx-jump. If its value is a function, that function is called just after bookmark-after-jump-hook runs for the tagged bookmark.

Tag names prefixed with bmkx- are reserved.

Pseudo-hierarchical tags

A simple convention — tag names that look like paths (vacation/2024/winter/photos) — gives you a tree-shaped organization without any special syntax. Use completion (TAB) on partial prefixes to descend the “tree”.

Annotations

An annotation is free-text metadata attached to a bookmark.

  • bmkx-annotate-bookmark (C-x x a a) prompts for a bookmark and opens an annotation edit buffer. bookmark-edit-annotation is similar; without a prefix arg it lists only annotated bookmarks as candidates.
  • bookmark-show-annotation (C-x x a s) shows an annotation in read-only mode. C-x C-q toggles to edit mode.
  • bookmark-show-all-annotations (C-x x a S).
  • bmkx-annotate-bookmark-this-file/buffer (C-x x a b) and bmkx-annotate-all-bookmarks-this-file/buffer (C-x x a B).

In the edit buffer:

  • bookmark-send-edited-annotation saves (C-c C-c in most annotation buffers; C-c C-M-c when Org mode owns C-c C-c).
  • bookmark-kill-annotation (C-x C-k) discards changes.
  • C-x C-q toggles buffer modes.
  • The buffer’s major mode is controlled by bmkx-annotation-modes-inherit-from (default: org-mode).
  • bookmark-automatically-show-annotations — if non-nil, jumping to a bookmark pops up its annotation (edit to open in edit mode, anything else for read-only).

External annotations (“annotation forwards”)

You can keep the inline annotation short and “forward” to a file, URL, or another bookmark. Put one of these as the first non-blank line of the annotation:

bmkx-annot-url: "FILE"      ; opens with find-file-other-window
bmkx-annot-url: "URL"       ; opens with browse-url
bmkx-annot-url: "BOOKMARK"  ; jumps to the named bookmark

When you “show” the annotation, Bookmark-X follows the forward. When you edit it (a e), you still see the literal text and any extra lines after the forward.

In *Bmkx List*

CommandKeyMeaning
bmkx-list-show-annotationa aShow this line’s annotation.
bmkx-edit-annotationa eEdit this line’s annotation.
bmkx-show-all-annotationsa AShow all annotations.
bmkx-bmenu-edit-annotations-for-markeda >Edit annotations for all marked bookmarks.
bmkx-bmenu-show-this-annotation+move-{down,up}M-down/M-upMove + show annotation.

Bookmarks with annotations are flagged with a in the display.

The *Bmkx List* buffer

Open it with bmkx-list (C-x x e or C-x r l). It is the heart of Bookmark-X’s interactive workflow: filtering, marking, sorting, tagging, highlighting, editing — everything happens here.

Header

The header shows the current bookmark file and a title that describes the current filter (e.g. "File and Directory Bookmarks" or "All Bookmarks"). The mode line shows counts: marked (>), flagged for deletion (D), tagged (t), temporary (X), annotated (a), modified-unsaved (*), plus the sort order. Where a counter is split, N/M means “N up to and including the current line, of M total”.

Per-line flags:

MarkMeaning
>Marked (a-la Dired).
DFlagged for deletion.
aHas an annotation.
tHas at least one tag.
XTemporary — will not be saved.
*Modified since last save of the bookmark file.
pink one-character highlightHas a per-bookmark lighting override.

Marking

CommandKeyAction
bmkx-list-markmMark this bookmark.
bmkx-list-unmarkuUnmark this bookmark.
bmkx-bmenu-unmark-allM-DEL, UUnmark all (or only >, or only D).
bmkx-bmenu-toggle-markstSwap marked / unmarked.
bmkx-bmenu-mark-allM-mMark all.
bmkx-bmenu-regexp-mark% mMark by regexp on the bookmark line.
bmkx-bmenu-flag-for-deletiond, kFlag for deletion (D).
bmkx-bmenu-flag-for-deletion-backwardsC-dSame, moving up.
bmkx-bmenu-delete-markedDDelete all flagged/marked bookmarks.

The F M / I M / A M … family marks specific kinds (see “filtering by type” below).

Filtering

Three independent kinds of filtering:

  1. By type — show only bookmarks of one kind. Keys end in S (show).
    F S  - file/dir bookmarks       A S  - autofile bookmarks
    B S  - non-file bookmarks       Y S  - bookmark-file bookmarks
    R S  - region bookmarks         Z S  - bookmark-list bookmarks
    I S  - Info bookmarks           K S  - desktop bookmarks
    G S  - Gnus bookmarks           V S  - variable-list bookmarks
    M S  - man-page bookmarks       N S  - non-invokable bookmarks
    M-I M-S - image bookmarks       Q S  - function bookmarks
    W3 S - W3M bookmarks (legacy)
    WE S - EWW bookmarks            w S  - snippet bookmarks
    X S  - temporary bookmarks      O S  - orphaned local file bookmarks
    #S   - autonamed bookmarks      M-d M-s - Dired bookmarks
    T S  - tagged bookmarks         T U  - untagged bookmarks
    H S  - highlighted bookmarks    - S   - omitted bookmarks
        

    For each, the corresponding M key (e.g. F M, I M) marks bookmarks of that type instead of showing only them.

    The current type filter is remembered when you save a bookmark-list bookmark or use C-c C-c.

  2. Incremental matching — type P PREFIX REGEXP. As you type, only matching bookmarks remain visible. Hit a non-self-inserting key (e.g. RET) to commit.
    P B  - filter by bookmark name (incremental regexp)
    P F  - filter by file name
    P A  - filter by annotation
    P T  - filter by tag
        
  3. By mark — toggle “show only marked” (>) or “show only unmarked” (<). . shows all.

Use M-t to toggle showing file names (locations) for each bookmark.

Omitting (vs. filtering)

Omitting is a stronger form of hiding: omitted bookmarks are hidden from every view except the dedicated omit view.

CommandKeyMeaning
bmkx-bmenu-omit/unomit-marked- >Move marked bookmarks to/from omit.
bmkx-bmenu-show-only-omitted-bookmarks- SShow only the omitted ones.
bmkx-unomit-all- UUn-omit everything (can be called outside *Bmkx List*).

Component bookmarks of a new sequence bookmark are omitted by default.

Sorting

Repeat s s to cycle through every available sort order. Or pick one directly:

CommandKeySort by
bmkx-bmenu-sort-marked-before-unmarkeds >marked before unmarked
bmkx-bmenu-sort-modified-before-unmodifieds *modified before unmodified
bmkx-bmenu-sort-by-creation-times 0bookmark creation time
bmkx-bmenu-sort-annotated-before-unannotateds aannotated before unannotated
bmkx-bmenu-sort-by-last-buffer-or-file-accesss blast buffer/file access
bmkx-bmenu-sort-by-last-bookmark-accesss dlast bookmark access
bmkx-bmenu-sort-flagged-before-unflaggeds Dflagged-for-deletion first
bmkx-bmenu-sort-by-file-names f nfile name
bmkx-bmenu-sort-by-local-file-types f kfile kind
bmkx-bmenu-sort-by-local-file-sizes f sfile size
bmkx-bmenu-sort-by-last-local-file-accesss f dlast local-file access
bmkx-bmenu-sort-by-last-local-file-updates f ulast local-file update
bmkx-bmenu-sort-by-Gnus-threads gGnus thread (group, article, message)
bmkx-bmenu-sort-by-Info-node-names iInfo node name
bmkx-bmenu-sort-by-Info-positions IInfo position
bmkx-bmenu-sort-by-bookmark-types kbookmark type (kind)
bmkx-bmenu-sort-by-bookmark-names nbookmark name
bmkx-bmenu-sort-tagged-before-untaggeds ttagged before untagged
bmkx-bmenu-sort-by-urls uURL
bmkx-bmenu-sort-by-bookmark-visit-frequencys vvisit frequency
bmkx-reverse-sort-orders rreverse direction
bmkx-reverse-multi-sort-orders C-rreverse a composite multi-sort
bmkx-define-tags-sort-commandT stag set

The macro bmkx-define-sort-command lets you define your own. Sorting is governed by option bmkx-sort-comparer — the built-in bookmark-sort-flag is ignored.

Cycling list: bmkx-sort-orders-for-cycling-alist.

Editing

CommandKeyEdits
bmkx-bmenu-edit-bookmark-name-and-locationrName and target file name (in minibuffer).
bmkx-bmenu-edit-bookmark-recordeThe full bookmark record (Lisp sexp).
bmkx-bmenu-edit-markedERecords of all marked bookmarks.
bmkx-bmenu-clone-bookmarkM-nDuplicate; default name ends in “<2>”.
bmkx-bmenu-edit-tagsT eThis bookmark’s tags.

Outside *Bmkx List*, bmkx-edit-bookmark-name-and-location (C-x x r) edits name + location; bmkx-edit-bookmark-record (C-x x E) edits the full record; bmkx-clone-bookmark (C-x x 2) clones; bmkx-edit-tags (C-x x t e) edits tags.

Refresh, save, load, switch

CommandKeyMeaning
bmkx-bmenu-refresh-menu-listgRe-render from the in-memory list.
bmkx-bmenu-refresh-menu-list with prefixC-u gReload from the current bookmark file (revert).
bmkx-save (bookmark-save)SSave bookmarks to the current bookmark file.
bmkx-switch-bookmark-file-createLSwitch to a different bookmark file (replace).
bmkx-bmenu-load-marked-bookmark-file-bookmarksM-lLoad every marked bookmark-file bookmark.
bmkx-toggle-saving-bookmark-fileM-~Toggle bookmark-save-flag.
bmkx-toggle-saving-menu-list-stateC-M-~Toggle saving of the bookmark-list display state.
bmkx-temporary-bookmarking-modeM-LEnter temporary-bookmarking mode (see below).
bmkx-bmenu-quitqQuit (and save display state if enabled).

Acting on the marked bookmarks

  • bmkx-bmenu-delete-marked (D) deletes them.
  • bmkx-bmenu-dired-marked (M-d >) opens Dired on the local files among them (using absolute names).
  • bmkx-bmenu-query-replace-marked-bookmarks-regexp (M-q) query-replaces across their targets, in the current sort order.
  • bmkx-bmenu-search-marked-bookmarks-regexp (M-s a M-s) regexp-searches across their targets.
  • Isearch commands (M-s a C-s / M-s a M-C-s) search marked targets incrementally (Emacs 23+).
  • Tag commands (T > +/-) add or remove tags on the marked bookmarks.
  • Tag paste commands (T > p / q / C-y) paste tags (additive / replace / additive).
  • bmkx-bmenu-list-tags-of-marked (T > l) lists the union of tags of marked bookmarks.
  • bmkx-bmenu-set-tag-value-for-marked (T > v) sets a tag value on all marked.
  • Highlight commands (H > H / H > U) highlight or unhighlight marked bookmarks.
  • bmkx-bmenu-edit-annotations-for-marked (a >) edits annotations of marked bookmarks.
  • bmkx-bmenu-toggle-marked-temporary/savable (M-X) toggles temporary / savable on marked bookmarks.
  • Bookmark-file commands (Y > +/- /0) copy, move, or create a bookmark file with marked bookmarks (see Multiple bookmark files).
  • bmkx-bmenu-relocate-marked (M-R) relocates marked bookmarks.

Describe / inspect

CommandKeyShows
bmkx-bmenu-mode-status-help? / C-h mHelp, status, current file, legend.
bmkx-bmenu-describe-this-bookmarkC-h RETDetailed description of this bookmark.
bmkx-bmenu-describe-this-bookmark with prefixC-u C-h RETInternal Lisp form.
bmkx-bmenu-describe-markedC-h >Descriptions of all marked.
bmkx-bmenu-describe-this+move-{down,up}C-down / C-upMove + describe (browse).

Anywhere in Emacs, bmkx-describe-bookmark (C-x h M, the help prefix followed by M) describes any bookmark. On a highlighted bookmark, bmkx-describe-bookmark-lighted-here (C-x x ?) does the same, and hovering shows the description as a tooltip (the content function is bmkx-tooltip-content-function).

Defining commands and jump commands

CommandKeyDefines
bmkx-bmenu-define-commandC-c C-cA command that restores the current display state (sort/filter/etc.).
bmkx-bmenu-define-full-snapshot-commandC-c C-S-c (C-c C-C)A command that restores the full bookmark list.
bmkx-bmenu-define-jump-marked-commandC-c C-jA “type-specific” jump command whose candidates are the marked bookmarks.

Defined commands are appended to bmkx-bmenu-commands-file. That file is loaded on first opening *Bmkx List* in a session.

Mouse

  • mouse-3 — popup menu of actions for the bookmark under the pointer (bmkx-bmenu-mouse-3-menu).
  • The Bookmark-X menu (C-mouse-3).

Multiple bookmark files

A bookmark file is a physical file on disk containing complete bookmark records. Bookmark-X makes it easy to:

  • Switch to a different bookmark file (replacing the current in-memory set).
  • Accumulate bookmarks by loading additional files.
  • Save the current bookmarks to a different file with bookmark-write (C-x x w).
  • Create an empty bookmark file with bmkx-empty-file (C-x x 0).

Switching:

CommandKeyMeaning
bmkx-switch-bookmark-file-createC-x x L / LSwitch to another bookmark file.
bookmark-load (no prefix)C-x x lAdd bookmarks from a file to the current set.
bookmark-load (with prefix)C-u C-x x lEquivalent to L (switch).
bmkx-switch-to-bookmark-file-this-file/bufferC-x x C-lSwitch to a file containing only this buffer’s bookmarks.
bmkx-bmenu-load-marked-bookmark-file-bookmarksM-lLoad every marked bookmark-file bookmark.

Copying / moving / creating bookmark files from the marked bookmarks:

CommandKeyMeaning
bmkx-bmenu-copy-marked-to-bookmark-fileY > +Copy marked into another bookmark file.
bmkx-bmenu-move-marked-to-bookmark-fileY > -Move them.
bmkx-bmenu-create-bookmark-file-from-markedY > 0Make a new file containing them (with prefix arg also create a bookmark-file bookmark for it).

Persistent bookmark-file bookmarks — created with bmkx-set-bookmark-file-bookmark (C-x x y / C-x x c y) lets you “jump to” (= load) a particular bookmark file by name. C-u as a prefix argument switches to that file rather than accumulating it.

The default bookmark file for the next Emacs session is the one in use when you quit, controlled by bmkx-last-as-first-bookmark-file. Set this to nil to always start from bookmark-default-file instead.

Note that bookmark files are physical, not logical, groupings. Copying a bookmark from one to another duplicates it; the two copies are independent thereafter. To organize a single bookmark across files, move it (do not copy).

Autonamed bookmarks

An autonamed bookmark is a regular, persistent bookmark whose name is generated automatically from a buffer name + position (default form: "000058356 foo.el" — nine-digit position then buffer name). It records no region, only a position.

  • bmkx-toggle-autonamed-bookmark-set/delete (C-x x RET) toggles the autonamed bookmark at point. Setting one is one keystroke; deleting it is the same keystroke.
  • With a prefix argument, bmkx-toggle-autonamed-bookmark-set/delete (C-x x RET) deletes all autonamed bookmarks in the current buffer (after confirmation).
  • bmkx-delete-bookmarks (C-x x delete) deletes individual bookmarks under cursor or all bookmarks in the buffer (any type).

Other autonamed-set commands (not bound by default): bmkx-set-autonamed-bookmark-at-line, bmkx-set-autonamed-regexp-buffer (one bookmark per regexp match in buffer), bmkx-set-autonamed-regexp-region (same, in region), bmkx-occur-create-autonamed-bookmarks (C-c C-M-B in *Occur*).

If you do not want autonamed bookmarks to persist across sessions:

(add-hook 'kill-buffer-hook 'bmkx-delete-autonamed-this-buffer-no-confirm)
(add-hook 'kill-emacs-hook  'bmkx-delete-autonamed-no-confirm)

(Alternative: make autonamed bookmarks temporary via bmkx-autotemp-bookmark-predicates — the default — and they will not be saved. See Temporary bookmarks.)

Customize the name format with bmkx-autoname-format and bmkx-autoname-bookmark-function. The special spec %B refers to the buffer name within the format (%s works too if the name is unambiguous).

Temporary bookmarks

A temporary bookmark is one that will not be written to the bookmark file. It exists only for the current session (unless you explicitly save it).

Temporary-bookmarking mode

bmkx-temporary-bookmarking-mode (M-L in *Bmkx List*, or M-x bmkx-temporary-bookmarking-mode) turns on a minor mode that:

  1. Switches to an empty bookmark file.
  2. Turns off auto-saving (bookmark-save-flag).

Every bookmark you create in this mode is therefore session-local. The mode-line indicator changes to TEMPORARY Bookmarking.

Per-bookmark temporary flag

Even with normal bookmarking, you can mark individual bookmarks temporary:

CommandKeyMeaning
bmkx-toggle-temporary-bookmarkC-M-XToggle for this line’s bookmark.
bmkx-bmenu-toggle-marked-temporary/savableM-XToggle for the marked bookmarks.
Temporary mark/show commandsX M / X SMark / show only temporary bookmarks.
bmkx-toggle-autotemp-on-setC-x x xToggle: make every newly set bookmark temporary.

Outside the display, bmkx-make-bookmark-temporary and bmkx-make-bookmark-savable flip the flag for a named bookmark.

Autotemp predicates

bmkx-autotemp-bookmark-predicates is a list of predicates — typically type predicates such as bmkx-autonamed-bookmark-p — that decide which bookmarks become temporary automatically when created or updated. The default makes autonamed bookmarks temporary.

bmkx-delete-all-temporary-bookmarks removes them all from the current list at once.

Temporary bookmarks are flagged with X in *Bmkx List* (replacing the annotation flag).

Coverage across the built-in API

The autotemp predicates and the temp filter at save are honored on both the bookmark-x save path (bmkx-set / bmkx-save) and the built-in bookmark.el save path (bookmark-set / bookmark-save, triggered automatically by bookmark-save-flag). This matters when third-party packages create bookmarks via the built-in API — org-capture, for instance, calls bookmark-set directly to maintain org-capture-last-stored, and the built-in autosave fires whenever bookmark-save-flag is non-nil.

Coverage is controlled by bmkx-extend-temp-to-builtin-flag (default t). When non-nil, bookmark-x installs:

  • :after advice on bookmark-store so the autotemp predicates fire for any caller, not just bmkx-set.
  • :around advice on bookmark-write-file so the built-in save skips bmkx-temp records, just as bmkx-write-file does.

Toggling the option through Customize (or with setopt) installs or removes both advices immediately.

Automatic bookmarking

On a hook

Add bmkx-set-automatic-bookmark to any hook to create a bookmark whenever that hook runs. Example:

(add-hook 'imenu-after-jump-hook #'bmkx-set-automatic-bookmark)

The bookmark created is an autonamed bookmark.

Idle-period bookmarking

bmkx-automatic-bookmark-mode is a local minor mode that sets an autonamed bookmark whenever Emacs has been idle for bmkx-automatic-bookmark-mode-delay seconds in the current buffer. bmkx-global-automatic-bookmark-mode turns it on everywhere (a bookmark is still only created for the currently selected buffer).

Tuning options:

  • bmkx-automatic-bookmark-mode-lighter — mode-line lighter (default Auto-Bmk; set to =”” to hide).
  • bmkx-automatic-bookmark-min-distance — minimum distance (in characters) from the nearest existing automatic bookmark. nil removes the limit (still at most one per position).
  • bmkx-automatic-bookmark-set-function — which command to use (default bmkx-set-autonamed-bookmark-at-line).

To highlight automatic bookmarks, set bmkx-auto-light-when-set (e.g. to autonamed-bookmark).

Automatic Info bookmarking

Enable global minor mode bmkx-info-auto-bookmark-mode and every Info node you visit either creates or updates a bookmark named (MANUAL) NODE. bmkx-info-auto-type chooses between update-only (default) and create-or-replace. bmkx-toggle-info-auto-type flips it.

This gives you a persistent “what I have read recently in the Elisp / Emacs / … manuals” log. Sort by s d (last access) or s v (visit count) in *Bmkx List*.

Following file and directory renames

Global minor mode bmkx-file-rename-track-mode keeps bookmark filenames in sync when you rename files or directories from inside Emacs. It is enabled by default on Bookmark-X load; turn it off with (bmkx-file-rename-track-mode -1) if you would rather manage this yourself.

When on, Bookmark-X installs :after advice on rename-file. Any call — from Dired’s R, M-x rename-visited-file, or Lisp — triggers a sweep of bookmark-alist:

  • A bookmark whose filename equals the renamed path is rewritten to the new path (file rename).
  • A bookmark whose filename lives under the renamed path is rewritten with the new prefix (directory rename). So renaming /foo/bar/ to /foo/baz/ updates every bookmark whose file is inside it.
  • URL / EWW / Info / other non-file bookmarks (identified by the bmkx-non-file-filename sentinel) are left untouched.
  • Any bookmark record that raises an error during the sweep is skipped with a warning; sibling records still get updated.

The advice is bullet-proofed to never signal back to the caller: even if the sweep body errors, rename-file still returns successfully, so a bug in Bookmark-X cannot break your rename.

Not covered: renames performed outside Emacs (shell, Finder, git mv, sync clients). Emacs does not see those events; only a file-notify watch would, and Bookmark-X does not install one.

Highlighting bookmark locations

Bookmark-X can draw a persistent highlight at the position (or region, or line, or fringe) of a bookmark in its buffer.

Styles

StyleEffect
RegionHighlight the recorded region.
LineHighlight the bookmark’s line.
PositionHighlight the character at the bookmark position.
Line BeginningHighlight the first character on the line.
Left FringeBitmap in the left fringe.
Left Fringe + LineBoth.
Right FringeBitmap in the right fringe.
Right Fringe + LineBoth.

Default style and face per kind:

OptionDefault
bmkx-light-style-autonamedline+lfringe
bmkx-light-style-non-autonamedline+rfringe
bmkx-light-style-autonamed-regionregion
bmkx-light-style-non-autonamed-regionregion
bmkx-light-autonamed (face)distinct color
bmkx-light-non-autonamed (face)distinct color
bmkx-light-autonamed-region (face)distinct color
bmkx-light-non-autonamed-region (face)distinct color
bmkx-light-left-fringe-bitmapleft-triangle
bmkx-light-right-fringe-bitmapright-triangle
bmkx-light-prioritiesoverlay z-order
bmkx-light-threshold100000 (max bookmarks to highlight)

Per-bookmark overrides

In *Bmkx List*:

CommandKeyMeaning
bmkx-bmenu-set-lightingH +Set highlighting for this bookmark.
bmkx-bmenu-set-lighting-for-markedH > +Set for the marked bookmarks.
bmkx-bmenu-lightH HHighlight this bookmark.
bmkx-bmenu-light-markedH > HHighlight all marked.
bmkx-bmenu-unlightH UUnhighlight this bookmark.
bmkx-bmenu-unlight-markedH > UUnhighlight all marked.
bmkx-bmenu-mark-lighted-bookmarksH MMark highlighted bookmarks.
bmkx-bmenu-show-only-lighted-bookmarksH SShow only highlighted.

Each setter command prompts for a style and face, and for a condition — an Emacs-Lisp sexp evaluated whenever the bookmark is about to be highlighted. Returning :no-light suppresses the highlight. The sexp may refer to free variables this-bookmark and this-bookmark-name. Example:

(or (y-or-n-p (format "Highlight `%s' " this-bookmark-name))
    :no-light)

Globally, M-x bmkx-set-lighting-for-bookmark does the same thing without using the display.

Global highlighting keys

CommandKey
bmkx-light-bookmark-this-buffer (with prompt)C-x x h
bmkx-unlight-bookmark-this-bufferC-x x u
bmkx-light-bookmarksC-x x H
bmkx-unlight-bookmarksC-x x U
bmkx-unlight-bookmark-hereC-x x C-u
bmkx-bookmarks-lighted-at-pointC-x x =
bmkx-lighted-jumpC-x j h
bmkx-lighted-jump-other-windowC-x 4 j h

Automatic highlighting

  • bmkx-auto-light-when-set — highlight automatically whenever a bookmark is created.
  • bmkx-auto-light-when-jump — highlight automatically when you jump.
  • bmkx-use-region-flag-for-highlighting — for point-style highlights, decide whether to highlight the recorded or the relocated position.

Both bmkx-auto-light-when-* options accept the values: autonamed-bookmark, non-autonamed-bookmark, any-bookmark, autonamed-in-buffer, non-autonamed-in-buffer, all-in-buffer, nil (off).

Pulse highlight on jump

If bmkx-highlight-on-jump-flag is non-nil (default), jumping to a bookmark that has no region briefly pulse-highlights the landing line via the built-in pulse.el so you can find it at a glance.

Bookmark links

bmkx-insert-bookmark-link inserts a text-property link in any buffer that, when you hit RET or click mouse-2, jumps to the bookmark. ? or double-click on the link describes the bookmark.

The link’s display text is the active region’s text (if any), otherwise text you type at the prompt (default: the bookmark name). Link text uses the link face; with font-lock+.el, the face survives font-locking.

These links are not persistent (re-create them with Lisp if you need to). For persistent links, use Org-mode (next section).

Org-mode integration

Storing Org links to bookmarks

  • In *Bmkx List*, the standard Org command org-store-link (C-c l) stores a link to the bookmark on the current line. Also available from the mouse-3 popup as “Store Org Link”.
  • Anywhere else, bmkx-store-org-link stores a link to any bookmark; you are prompted for the name. It is also on the Bookmarks menu as “Store Org Link To…”.

A numeric prefix argument stores a link that jumps in the same window (default: other window).

Insert with the usual org-insert-link. Follow with the usual Org keys (in Org-mode) or with org-open-at-point-global.

Bookmarking Org targets

You can use the normal bmkx-bookmark-set-confirm-overwrite in an Org buffer to bookmark a heading. Annotations themselves edit in Org-mode by default (see Annotations).

Menus

Bookmark-X menu (in *Bmkx List*)

A full menu-bar menu with submenus: Jump To, Mark, Omit, Show, Sort, Tags, Highlight (if bookmark-x-lit.el is loaded), Define Command. Also available on C-mouse-3.

mouse-3 popup (in *Bmkx List*)

Click mouse-3 on a bookmark for a menu of actions on that bookmark.

Built-in Bookmarks menu (under Edit)

Bookmark-X adds several items to the standard Bookmarks menu: Jump To submenu, Tags submenu, Highlight submenu, plus items like Clone a Bookmark, Rename or Relocate, Edit Bookmark Record (Lisp), Show Bookmark List, Set Navlist… , Empty Bookmark File…, Send Bug Report.

Edit menu additions

Two items are added: Save Region as Bookmark and Jump to a Snippet Bookmark (which copies its text to the kill ring).

Bookmarks Here submenu

When bmkx-add-bookmarks-here-menu-flag is non-nil, several modes get a Bookmarks Here submenu (Info, Buffer-menu; Dired with dired+.el). Items let you cycle, list, describe, annotate, highlight, or open *Bmkx List* filtered to the current file/buffer. If you use imenu+.el, an Imenu “Bookmarks Here” submenu also lists every bookmark in the file/buffer for direct jumping (controlled by imenup-show-bookmarks-flag).

The reason the option defaults to nil: computing the menu has a small but real cost.

Use with modern completion frameworks

This fork of Bookmark-X uses the built-in completing-read for every prompt and ships no completion-framework integrations of its own. That keeps it composable with whatever completion stack you already use — vertico, ivy, helm, ido, or plain Emacs.

For the closest thing to a single-key “browse and jump” experience, the consult package’s consult-bookmark reads a bookmark with live preview-while-jumping — bind it over C-x r b for the convenience. With vertico + marginalia + orderless, every Bookmark-X jump command (bmkx-info-jump, bmkx-dired-jump, bmkx-tagged-jump, bmkx-eww-jump, etc.) gets vertical completion, fuzzy matching, and annotations for free.

For acting on the selected bookmark, embark’s embark-act pairs naturally: bind it inside completing-read and you can rename, delete, or describe the candidate without leaving the minibuffer.

The *Bmkx List* buffer is unchanged by any of this — it is its own tabulated UI, independent of how you select bookmarks from the minibuffer.

Customization

Run M-x customize-group RET bookmark-plus for the full interface — it links to the commentary file and to documentation pages. This section enumerates the most commonly tweaked options.

Prefix keys

  • bmkx-bookmark-map-prefix-keys — prefix keys for bookmark-map (default C-x x).
  • bmkx-jump-map-prefix-keys — for bmkx-jump-map (default C-x j).
  • bmkx-jump-other-window-map-prefix-keys — for bmkx-jump-other-window-map (default C-x 4 j).

Bookmark name and properties

  • bmkx-new-bookmark-default-names — functions consulted to generate the default name for a new bookmark.
  • bmkx-default-bookmark-name — which bookmark is offered as default at jump prompts.
  • bmkx-properties-to-keep — properties preserved when you overwrite a bookmark (default: tags, annotation).
  • bmkx-propertize-bookmark-names-flag — if non-nil (default for Emacs 21+), bookmarks may have the same name; see Compatibility.
  • bmkx-count-multi-mods-as-one-flag — if non-nil (default), count all the modifications a single command makes as one for bookmark-save-flag purposes.
  • bmkx-save-new-location-flag — if non-nil, update the recorded position to the actual destination after a relocated jump.

Tags

  • bmkx-prompt-for-tags-flag — prompt for tags whenever a bookmark is created or updated.
  • bmkx-tags-for-completion — which tags are completion candidates (current, all, a list of specific tags or bookmark files).

Annotations

  • bookmark-automatically-show-annotations — pop up annotation when jumping. Value edit opens in edit mode; anything else non-nil opens read-only.
  • bmkx-annotation-modes-inherit-from — major mode for the annotation edit buffer (default org-mode).

Sorting and filtering

  • bmkx-sort-comparer — the active sort order (bookmark-sort-flag is ignored).
  • bmkx-sort-orders-for-cycling-alist — the orders cycled by s s.

*Bmkx List* state

  • bmkx-bmenu-state-file — where the display state is saved (nil disables the feature).
  • bmkx-bmenu-commands-file — where defined commands are appended (C-c C-c, C-c C-S-c, C-c C-j).
  • bmkx-add-bookmarks-here-menu-flag — enable the Bookmarks Here submenu in supported modes.

Bookmark files

  • bmkx-last-as-first-bookmark-file — start each Emacs session with the last bookmark file used. Set to nil to always start with bookmark-default-file.
  • bookmark-save-flag (built-in) — when to auto-save the current bookmark file (nil = never, t = on every change, integer = after that many modifications).
  • bookmark-version-control and delete-old-versions (built-in) — recommended t so Bookmark-X’s save-time backups accumulate cleanly.

Cycling

  • bmkx-use-regiont activates region on jump, cycling-too also during cycling, nil never.
  • bmkx-this-file/buffer-cycle-sort-comparer — sort order used by C-x x n / C-x x p / arrow-key cycling.

Files without Emacs

  • bmkx-default-handlers-for-file-types — file-name-regexp → action map.
  • bmkx-guess-default-handler-for-file-flag — fall back to dired-guess-shell-alist-default / mailcap when the map has no match.
  • bmkx-autofile-filecache — advise file-cache-add-file to also create autofiles.
  • bmkx-autofile-access-invokes-bookmark-flagfind-file also invokes the autofile bookmark.

Automatic bookmarking

  • bmkx-automatic-bookmark-mode-delay, bmkx-automatic-bookmark-set-function, bmkx-automatic-bookmark-min-distance, bmkx-automatic-bookmark-mode-lighter.
  • bmkx-autotemp-bookmark-predicates — which kinds become temporary automatically.
  • bmkx-info-auto-type.

Desktop bookmarks

  • bmkx-desktop-no-save-vars, bmkx-desktop-jump-save-before-flag, bmkx-desktop-default-file (varies).

Highlighting

  • bmkx-light-style-{autonamed,non-autonamed,autonamed-region,non-autonamed-region}.
  • bmkx-light-{left,right}-fringe-bitmap.
  • bmkx-light-priorities, bmkx-light-threshold.
  • bmkx-auto-light-when-set, bmkx-auto-light-when-jump.
  • bmkx-use-region-flag-for-highlighting.
  • Faces: bmkx-light-autonamed, bmkx-light-non-autonamed, bmkx-light-autonamed-region, bmkx-light-non-autonamed-region, bmkx-light-mark.
  • bmkx-tooltip-content-function — function returning the tooltip body for hovered highlighted bookmarks (default bmkx-bookmark-description; an alternative is bmkx-annotation-or-bookmark-description).
  • bmkx-highlight-on-jump-flag — pulse-highlight the landing line after a jump (uses built-in pulse.el).

Faces (*Bmkx List*)

Type faces (used to color bookmark names in the display):

bmkx-bookmark-file, bmkx-bookmark-list, bmkx-buffer, bmkx-desktop, bmkx-file-handler, bmkx-function, bmkx-gnus, bmkx-info, bmkx-local-directory, bmkx-local-file-without-region, bmkx-local-file-with-region, bmkx-man, bmkx-non-file, bmkx-remote-file, bmkx-sequence, bmkx-snippet, bmkx-su-or-sudo, bmkx-url, bmkx-variable-list, bmkx-no-jump (non-invokable), bmkx-no-local (orphaned local file).

Marker faces: bmkx->-mark (>), bmkx-D-mark (D), bmkx-*-mark (*), bmkx-X-mark (X), bmkx-t-mark (t), bmkx-a-mark (a), bmkx-bad-bookmark (invalid bookmark line), bmkx-heading (the title line).

Compatibility with built-in bookmark.el

Bookmark files written by Bookmark-X can be read by the built-in bookmark.el, with one important caveat: if the same bookmark file is going to be saved by the built-in bookmark.el (not just read), set bmkx-propertize-bookmark-names-flag to nil before saving with Bookmark-X.

bmkx-propertize-bookmark-names-flag (non-nil by default) makes Bookmark-X store bookmark records as circular Lisp structures (the name has the full record as a text property). That layout is readable by the built-in bookmark.el, but if the built-in then saves the file, the resulting file is unreadable — the built-in does not bind print-circle when writing.

If you use only Bookmark-X, leave the option at its default. It enables conveniences such as multiple bookmarks with the same name, which are especially useful for autofiles.

Built-in documentation and help

WhereHow
Bookmark file formatC-h v bookmark-alist
Describe a single bookmark, anywhereC-x h M (bmkx-describe-bookmark) — prefix C-u shows full internal form.
Describe a highlighted bookmarkC-x x ? (same prefix-arg behavior)
In *Bmkx List*? or C-h m — status + general help (links to Doc in Commentary, Doc on the Web, Customize).
Describe one bookmark in *Bmkx List*C-h RET (with C-u, full internal form).
Describe all marked, in current sort orderC-h >
The complete in-tree manualThe big comment in bookmark-x-doc.el (4385 lines).
Online manualhttps://www.emacswiki.org/emacs/BookmarkPlus
Change logbookmark-x-chg.el
Customize groupM-x customize-group RET bookmark-plus
Report a bugBookmark-X menu → Send Bug Report, or M-x bmkx-send-bug-report

Command reference

The command reference has moved to doc/reference.org. It is kept separate from this README so the overview remains readable while command lookup stays available.

Notes

This README is a user-facing summary of features and commands that are documented in detail in bookmark-x-doc.el (the in-tree manual) and on the Emacs Wiki at https://www.emacswiki.org/emacs/BookmarkPlus. When the two disagree, the in-tree manual is authoritative. For absolute authority, inspect the source.

Copyright © 2000–2024 Drew Adams, for the Bookmark-X libraries. This README is provided as user documentation; it is not part of the official Bookmark-X distribution.

About

Bookmark+: extensions to standard library `bookmark.el'

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages